diff options
| author | Yong He <yonghe@outlook.com> | 2018-02-20 23:55:51 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-02-20 23:55:51 -0500 |
| commit | 01c4134d33cea3a4f98fad9248584278fd4bc452 (patch) | |
| tree | 8ca6b0f7e844fbf56cb1991284aff3ebbcc8aa89 | |
| parent | 51cdcad24b5271ac8c0f816174c6a760e264ed9e (diff) | |
| parent | 4cf46e5c8b2af8a4ea4db15cd402aae4145a614c (diff) | |
Merge pull request #417 from csyonghe/leakfix
Fix IR memory leaks.
| -rw-r--r-- | slang.h | 1 | ||||
| -rw-r--r-- | source/core/smart-pointer.h | 14 | ||||
| -rw-r--r-- | source/slang/compiler.h | 8 | ||||
| -rw-r--r-- | source/slang/emit.cpp | 23 | ||||
| -rw-r--r-- | source/slang/ir-insts.h | 47 | ||||
| -rw-r--r-- | source/slang/ir.cpp | 85 | ||||
| -rw-r--r-- | source/slang/ir.h | 42 | ||||
| -rw-r--r-- | source/slang/lower-to-ir.cpp | 1 | ||||
| -rw-r--r-- | source/slang/memory_pool.cpp | 52 | ||||
| -rw-r--r-- | source/slang/memory_pool.h | 19 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 24 | ||||
| -rw-r--r-- | source/slang/slang.vcxproj | 2 | ||||
| -rw-r--r-- | source/slang/slang.vcxproj.filters | 2 | ||||
| -rw-r--r-- | source/slang/syntax-base-defs.h | 4 | ||||
| -rw-r--r-- | source/slang/syntax.cpp | 42 | ||||
| -rw-r--r-- | source/slang/type-defs.h | 24 | ||||
| -rw-r--r-- | tools/render-test/slang-support.cpp | 3 |
17 files changed, 282 insertions, 111 deletions
@@ -1237,6 +1237,7 @@ namespace slang #include "source/slang/dxc-support.cpp" #include "source/slang/emit.cpp" #include "source/slang/ir.cpp" +#include "source/slang/memory_pool.cpp" #include "source/slang/ir-legalize-types.cpp" #include "source/slang/ir-ssa.cpp" #include "source/slang/legalize-types.cpp" diff --git a/source/core/smart-pointer.h b/source/core/smart-pointer.h index 17d6caaa4..bc1683a5b 100644 --- a/source/core/smart-pointer.h +++ b/source/core/smart-pointer.h @@ -35,6 +35,11 @@ namespace Slang referenceCount++; } + void decreaseReference() + { + --referenceCount; + } + void releaseReference() { SLANG_ASSERT(referenceCount != 0); @@ -192,6 +197,15 @@ namespace Slang return pointer; } + T* detach() + { + if (pointer) + dynamic_cast<RefObject*>(pointer)->decreaseReference(); + auto rs = pointer; + pointer = nullptr; + return rs; + } + private: T* pointer; diff --git a/source/slang/compiler.h b/source/slang/compiler.h index fab1e19c8..845de5c81 100644 --- a/source/slang/compiler.h +++ b/source/slang/compiler.h @@ -179,7 +179,7 @@ namespace Slang // This will only be valid/non-null after semantic // checking and IR generation are complete, so it // is not safe to use this field without testing for NULL. - IRModule* irModule; + RefPtr<IRModule> irModule; }; // A request to generate output in some target format @@ -225,7 +225,7 @@ namespace Slang RefPtr<ModuleDecl> moduleDecl; // The IR for the module - IRModule* irModule = nullptr; + RefPtr<IRModule> irModule = nullptr; }; class Session; @@ -313,6 +313,8 @@ namespace Slang // Map from the logical name of a module to its definition Dictionary<Name*, RefPtr<LoadedModule>> mapNameToLoadedModules; + // The resulting specialized IR module for each entry point request + List<RefPtr<IRModule>> compiledModules; CompileRequest(Session* session); @@ -450,7 +452,6 @@ namespace Slang Dictionary<int, RefPtr<Type>> builtinTypes; Dictionary<String, Decl*> magicDecls; - List<RefPtr<Type>> canonicalTypes; void initializeTypes(); @@ -505,6 +506,7 @@ namespace Slang RefPtr<Scope> const& scope, String const& path, String const& source); + ~Session(); }; } diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 672798359..d2ed1c7c3 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -8084,17 +8084,17 @@ String emitEntryPoint( EmitVisitor visitor(&context); + // We are going to create a fresh IR module that we will use to + // clone any code needed by the user's entry point. + IRSpecializationState* irSpecializationState = createIRSpecializationState( + entryPoint, + programLayout, + target, + targetRequest); { TypeLegalizationContext typeLegalizationContext; typeLegalizationContext.session = entryPoint->compileRequest->mSession; - // We are going to create a fresh IR module that we will use to - // clone any code needed by the user's entry point. - IRSpecializationState* irSpecializationState = createIRSpecializationState( - entryPoint, - programLayout, - target, - targetRequest); IRModule* irModule = getIRModule(irSpecializationState); typeLegalizationContext.irModule = irModule; @@ -8158,7 +8158,12 @@ String emitEntryPoint( // TODO: do we want to emit directly from IR, or translate the // IR back into AST for emission? visitor.emitIRModule(&context, irModule); + + // retain the specialized ir module, because the current + // GlobalGenericParamSubstitution implementation may reference ir objects + targetRequest->compileRequest->compiledModules.Add(irModule); } + destroyIRSpecializationState(irSpecializationState); String code = sharedContext.sb.ProduceString(); sharedContext.sb.Clear(); @@ -8166,8 +8171,6 @@ String emitEntryPoint( // Now that we've emitted the code for all the declaratiosn in the file, // it is time to stich together the final output. - - // There may be global-scope modifiers that we should emit now visitor.emitGLSLPreprocessorDirectives(translationUnitSyntax); String prefix = sharedContext.sb.ProduceString(); @@ -8189,7 +8192,7 @@ String emitEntryPoint( finalResultBuilder << code; String finalResult = finalResultBuilder.ProduceString(); - + return finalResult; } diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h index e2c1c2e03..aaebb9973 100644 --- a/source/slang/ir-insts.h +++ b/source/slang/ir-insts.h @@ -33,6 +33,11 @@ struct IRLayoutDecoration : IRDecoration enum { kDecorationOp = kIRDecorationOp_Layout }; RefPtr<Layout> layout; + virtual void dispose() override + { + IRDecoration::dispose(); + layout = nullptr; + } }; enum IRLoopControl @@ -52,6 +57,11 @@ struct IRTargetSpecificDecoration : IRDecoration { // TODO: have a more structured representation of target specifiers String targetName; + virtual void dispose()override + { + IRDecoration::dispose(); + targetName = String(); + } }; struct IRTargetDecoration : IRTargetSpecificDecoration @@ -64,6 +74,11 @@ struct IRTargetIntrinsicDecoration : IRTargetSpecificDecoration enum { kDecorationOp = kIRDecorationOp_TargetIntrinsic }; String definition; + virtual void dispose()override + { + IRTargetSpecificDecoration::dispose(); + definition = String(); + } }; // @@ -73,6 +88,11 @@ struct IRTargetIntrinsicDecoration : IRTargetSpecificDecoration struct IRDeclRef : IRValue { DeclRef<Decl> declRef; + virtual void dispose() override + { + IRValue::dispose(); + declRef = decltype(declRef)(); + } }; // An instruction that specializes another IR value @@ -333,6 +353,13 @@ struct IRWitnessTable : IRGlobalValue RefPtr<GenericDecl> genericDecl; DeclRef<Decl> subTypeDeclRef, supTypeDeclRef; IRValueList<IRWitnessTableEntry> entries; + virtual void dispose() override + { + IRGlobalValue::dispose(); + genericDecl = decltype(genericDecl)(); + subTypeDeclRef = decltype(subTypeDeclRef)(); + supTypeDeclRef = decltype(supTypeDeclRef)(); + } }; // An instruction that yields an undefined value. @@ -610,22 +637,26 @@ struct IRBuilder UInt caseArgCount, IRValue* const* caseArgs); - - IRDecoration* addDecorationImpl( - IRValue* value, - UInt decorationSize, - IRDecorationOp op); - template<typename T> T* addDecoration(IRValue* value, IRDecorationOp op) { - return (T*) addDecorationImpl(value, sizeof(T), op); + assert(getModule()); + auto decorationSize = sizeof(T); + auto decoration = (T*)getModule()->memoryPool.allocZero(decorationSize); + new(decoration)T(); + + decoration->op = op; + + decoration->next = value->firstDecoration; + value->firstDecoration = decoration; + getModule()->irObjectsToFree.Add(decoration); + return decoration; } template<typename T> T* addDecoration(IRValue* value) { - return (T*) addDecorationImpl(value, sizeof(T), IRDecorationOp(T::kDecorationOp)); + return addDecoration<T>(value, IRDecorationOp(T::kDecorationOp)); } IRHighLevelDeclDecoration* addHighLevelDeclDecoration(IRValue* value, Decl* decl); diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp index 441db09a6..65f792577 100644 --- a/source/slang/ir.cpp +++ b/source/slang/ir.cpp @@ -543,26 +543,19 @@ namespace Slang value->sourceLoc = sourceLocInfo->sourceLoc; } - static IRValue* createValueImpl( - IRBuilder* /*builder*/, - UInt size, - IROp op, - IRType* type) - { - IRValue* value = (IRValue*) malloc(size); - memset(value, 0, size); - value->op = op; - value->type = type; - return value; - } - template<typename T> static T* createValue( IRBuilder* builder, IROp op, IRType* type) { - return (T*) createValueImpl(builder, sizeof(T), op, type); + assert(builder->getModule()); + T* value = (T*)builder->getModule()->memoryPool.allocZero(sizeof(T)); + new(value)T(); + value->op = op; + value->type = type; + builder->getModule()->irObjectsToFree.Add(value); + return value; } @@ -571,7 +564,8 @@ namespace Slang // In this case `argCount` and `args` represnt the // arguments *after* the type (which is a mandatory // argument for all instructions). - static IRInst* createInstImpl( + template<typename T> + static T* createInstImpl( IRBuilder* builder, UInt size, IROp op, @@ -581,8 +575,9 @@ namespace Slang UInt varArgCount = 0, IRValue* const* varArgs = nullptr) { - IRInst* inst = (IRInst*) malloc(size); - memset(inst, 0, size); + assert(builder->getModule()); + T* inst = (T*)builder->getModule()->memoryPool.allocZero(size); + new(inst)T(); inst->argCount = (uint32_t)(fixedArgCount + varArgCount); @@ -611,7 +606,7 @@ namespace Slang } operand++; } - + builder->getModule()->irObjectsToFree.Add(inst); return inst; } @@ -623,7 +618,7 @@ namespace Slang UInt argCount, IRValue* const* args) { - return (T*)createInstImpl( + return createInstImpl<T>( builder, sizeof(T), op, @@ -638,7 +633,7 @@ namespace Slang IROp op, IRType* type) { - return (T*)createInstImpl( + return createInstImpl<T>( builder, sizeof(T), op, @@ -654,7 +649,7 @@ namespace Slang IRType* type, IRValue* arg) { - return (T*)createInstImpl( + return createInstImpl<T>( builder, sizeof(T), op, @@ -672,7 +667,7 @@ namespace Slang IRValue* arg2) { IRValue* args[] = { arg1, arg2 }; - return (T*)createInstImpl( + return createInstImpl<T>( builder, sizeof(T), op, @@ -689,7 +684,7 @@ namespace Slang UInt argCount, IRValue* const* args) { - return (T*)createInstImpl( + return createInstImpl<T>( builder, sizeof(T) + argCount * sizeof(IRUse), op, @@ -708,7 +703,7 @@ namespace Slang UInt varArgCount, IRValue* const* varArgs) { - return (T*)createInstImpl( + return createInstImpl<T>( builder, sizeof(T) + varArgCount * sizeof(IRUse), op, @@ -731,7 +726,7 @@ namespace Slang IRValue* fixedArgs[] = { arg1 }; UInt fixedArgCount = sizeof(fixedArgs) / sizeof(fixedArgs[0]); - return (T*)createInstImpl( + return createInstImpl<T>( builder, sizeof(T) + varArgCount * sizeof(IRUse), op, @@ -1705,22 +1700,6 @@ namespace Slang return inst; } - IRDecoration* IRBuilder::addDecorationImpl( - IRValue* inst, - UInt decorationSize, - IRDecorationOp op) - { - auto decoration = (IRDecoration*) malloc(decorationSize); - memset(decoration, 0, decorationSize); - - decoration->op = op; - - decoration->next = inst->firstDecoration; - inst->firstDecoration = decoration; - - return decoration; - } - IRHighLevelDeclDecoration* IRBuilder::addHighLevelDeclDecoration(IRValue* inst, Decl* decl) { auto decoration = addDecoration<IRHighLevelDeclDecoration>(inst, kIRDecorationOp_HighLevelDecl); @@ -2666,12 +2645,15 @@ namespace Slang #else // Run destructor to be sure... this->~IRValue(); - - // And then free the memory - free((void*) this); #endif } + void IRValue::dispose() + { + IRObject::dispose(); + type = decltype(type)(); + } + // Insert this instruction into the same basic block // as `other`, right before it. void IRInst::insertBefore(IRInst* other) @@ -3729,7 +3711,7 @@ namespace Slang CodeGenTarget target; // The specialized module we are building - IRModule* module; + RefPtr<IRModule> module; // The original, unspecialized module we are copying IRModule* originalModule; @@ -4763,9 +4745,9 @@ namespace Slang if( !module ) { module = builder->createModule(); - sharedBuilder->module = module; } + sharedBuilder->module = module; sharedContext->module = module; sharedContext->originalModule = originalModule; sharedContext->target = target; @@ -4801,6 +4783,12 @@ namespace Slang IRSharedSpecContext* getSharedContext() { return &sharedContextStorage; } IRSpecContext* getContext() { return &contextStorage; } + ~IRSpecializationState() + { + newProgramLayout = nullptr; + contextStorage = IRSpecContext(); + sharedContextStorage = IRSharedSpecContext(); + } }; IRSpecializationState* createIRSpecializationState( @@ -4840,7 +4828,6 @@ namespace Slang auto context = state->getContext(); context->shared = sharedContext; context->builder = &sharedContext->builderStorage; - // Create the GlobalGenericParamSubstitution for substituting global generic types // into user-provided type arguments auto globalParamSubst = createGlobalGenericParamSubstitution(entryPointRequest, programLayout, context, originalIRModule); @@ -5726,11 +5713,9 @@ namespace Slang for (auto workItem : witnessTablesToSpecailize) { int diff = 0; - specializeWitnessTable(context->shared, workItem.srcTable, + specializeWitnessTable(context->shared, workItem.srcTable, workItem.specDeclRef.SubstituteImpl(SubstitutionSet(nullptr, nullptr, globalParamSubst), &diff), workItem.dstTable); } return globalParamSubst; } - - } diff --git a/source/slang/ir.h b/source/slang/ir.h index 0dc9daa9a..fdca73a83 100644 --- a/source/slang/ir.h +++ b/source/slang/ir.h @@ -10,6 +10,7 @@ #include "../core/basic.h" #include "source-loc.h" +#include "memory_pool.h" namespace Slang { @@ -114,10 +115,24 @@ enum IRDecorationOp : uint16_t kIRDecorationOp_TargetIntrinsic, }; +// represents an object allocated in an IR memory pool +struct IRObject +{ + bool isDestroyed = false; + virtual void dispose() + { + isDestroyed = true; + } + virtual ~IRObject() + { + isDestroyed = true; + } +}; + // A "decoration" that gets applied to an instruction. // These usually don't affect semantics, but are useful // for preserving high-level source information. -struct IRDecoration +struct IRDecoration : public IRObject { // Next decoration attached to the same instruction IRDecoration* next; @@ -132,7 +147,7 @@ typedef Type IRType; struct IRBlock; // Base class for values in the IR -struct IRValue +struct IRValue : public IRObject { // The operation that this value represents IROp op; @@ -169,6 +184,8 @@ struct IRValue // Free a value (which needs to have been removed // from its parent, had its uses eliminated, etc.) void deallocate(); + + virtual void dispose() override; }; // Values that are contained in a doubly-linked @@ -480,6 +497,11 @@ struct IRGlobalValue : IRValue void removeFromParent(); void moveToEnd(); + virtual void dispose() override + { + IRValue::dispose(); + mangledName = String(); + } }; /// @brief A global value that potentially holds executable code. @@ -529,6 +551,12 @@ struct IRFunc : IRGlobalValueWithCode // which are actually the parameters of the first // block. IRParam* getFirstParam(); + + virtual void dispose() override + { + IRGlobalValueWithCode::dispose(); + genericDecls = decltype(genericDecls)(); + } }; // A module is a parent to functions, global variables, types, etc. @@ -536,6 +564,8 @@ struct IRModule : RefObject { // The compilation session in use. Session* session; + MemoryPool memoryPool; + List<IRObject*> irObjectsToFree; // list of ir objects to run destructor upon destruction // A list of all the functions and other // global values declared in this module. @@ -544,6 +574,14 @@ struct IRModule : RefObject IRGlobalValue* getFirstGlobalValue() { return firstGlobalValue; } IRGlobalValue* getlastGlobalValue() { return lastGlobalValue; } + + ~IRModule() + { + for (auto val : irObjectsToFree) + if (!val->isDestroyed) + val->dispose(); + irObjectsToFree = List<IRObject*>(); + } }; void printSlangIRAssembly(StringBuilder& builder, IRModule* module); diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp index 53cb2e772..b99e2713f 100644 --- a/source/slang/lower-to-ir.cpp +++ b/source/slang/lower-to-ir.cpp @@ -2870,6 +2870,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> if (parentDecl->ParentDecl) witnessTable->genericDecl = dynamic_cast<GenericDecl*>(parentDecl->ParentDecl); witnessTable->subTypeDeclRef = makeDeclRef(parentDecl); + witnessTable->subTypeDeclRef.substitutions = createDefaultSubstitutions(context->getSession(), parentDecl); witnessTable->supTypeDeclRef = inheritanceDecl->base.type->AsDeclRefType()->declRef; // Register the value now, rather than later, to avoid diff --git a/source/slang/memory_pool.cpp b/source/slang/memory_pool.cpp new file mode 100644 index 000000000..884c9cfe4 --- /dev/null +++ b/source/slang/memory_pool.cpp @@ -0,0 +1,52 @@ +#include "memory_pool.h" + +namespace Slang +{ + const size_t kPoolSegmentSize = 4 << 20; // use 4MB segments + + struct MemoryPoolSegment + { + unsigned char* data = nullptr; + size_t allocPtr = 0; + MemoryPoolSegment* nextSegment = nullptr; + }; + + MemoryPool::~MemoryPool() + { + while (curSegment) + { + auto nxtSegment = curSegment->nextSegment; + free(curSegment->data); + delete curSegment; + curSegment = nxtSegment; + } + } + + void newSegment(MemoryPool* pool) + { + auto seg = new MemoryPoolSegment(); + seg->nextSegment = pool->curSegment; + seg->data = (unsigned char*)malloc(kPoolSegmentSize); + pool->curSegment = seg; + } + + void * MemoryPool::alloc(size_t size) + { + assert(size < kPoolSegmentSize); + // ensure there is a segment available + if (!curSegment) + newSegment(this); + if (curSegment->allocPtr + size > kPoolSegmentSize) + newSegment(this); + // alloc memory from current segment + void* rs = curSegment->data + curSegment->allocPtr; + curSegment->allocPtr += size; + return rs; + } + void * MemoryPool::allocZero(size_t size) + { + auto rs = alloc(size); + memset(rs, 0, size); + return rs; + } +} diff --git a/source/slang/memory_pool.h b/source/slang/memory_pool.h new file mode 100644 index 000000000..ee3ee1aa3 --- /dev/null +++ b/source/slang/memory_pool.h @@ -0,0 +1,19 @@ +#ifndef SLANG_MEMORY_POOL_H +#define SLANG_MEMORY_POOL_H + +#include "../core/basic.h" + +namespace Slang +{ + struct MemoryPoolSegment; + + struct MemoryPool : public RefObject + { + MemoryPoolSegment* curSegment = nullptr; + ~MemoryPool(); + void* alloc(size_t size); + void* allocZero(size_t size); + }; +} + +#endif
\ No newline at end of file diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 4238681f3..42e412438 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -123,7 +123,13 @@ CompileRequest::CompileRequest(Session* session) } CompileRequest::~CompileRequest() -{} +{ + // delete things that may reference IR objects first + targets = decltype(targets)(); + translationUnits = decltype(translationUnits)(); + entryPoints = decltype(entryPoints)(); + types = decltype(types)(); +} RefPtr<Expr> CompileRequest::parseTypeString(TranslationUnitRequest * translationUnit, String typeStr, RefPtr<Scope> scope) @@ -734,6 +740,19 @@ void Session::addBuiltinSource( loadedModuleCode.Add(syntax); } +Session::~Session() +{ + // free all built-in types first + errorType = nullptr; + initializerListType = nullptr; + overloadedType = nullptr; + irBasicBlockType = nullptr; + + builtinTypes = decltype(builtinTypes)(); + // destroy modules next + loadedModuleCode = decltype(loadedModuleCode)(); +} + } // implementation of C interface @@ -751,6 +770,9 @@ SLANG_API void spDestroySession( { if(!session) return; delete SESSION(session); +#ifdef _MSC_VER + _CrtDumpMemoryLeaks(); +#endif } SLANG_API void spAddBuiltins( diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj index 1ff88020f..0154dd98f 100644 --- a/source/slang/slang.vcxproj +++ b/source/slang/slang.vcxproj @@ -186,6 +186,7 @@ <ClInclude Include="lookup.h" /> <ClInclude Include="lower-to-ir.h" /> <ClInclude Include="mangle.h" /> + <ClInclude Include="memory_pool.h" /> <ClInclude Include="modifier-defs.h" /> <ClInclude Include="name.h" /> <ClInclude Include="object-meta-begin.h" /> @@ -225,6 +226,7 @@ <ClCompile Include="lookup.cpp" /> <ClCompile Include="lower-to-ir.cpp" /> <ClCompile Include="mangle.cpp" /> + <ClCompile Include="memory_pool.cpp" /> <ClCompile Include="name.cpp" /> <ClCompile Include="options.cpp" /> <ClCompile Include="parameter-binding.cpp" /> diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters index e0bf59025..e64721f6d 100644 --- a/source/slang/slang.vcxproj.filters +++ b/source/slang/slang.vcxproj.filters @@ -45,6 +45,7 @@ <ClInclude Include="mangle.h" /> <ClInclude Include="legalize-types.h" /> <ClInclude Include="ir-ssa.h" /> + <ClInclude Include="memory_pool.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="check.cpp" /> @@ -75,6 +76,7 @@ <ClCompile Include="ir-legalize-types.cpp" /> <ClCompile Include="legalize-types.cpp" /> <ClCompile Include="ir-ssa.cpp" /> + <ClCompile Include="memory_pool.cpp" /> </ItemGroup> <ItemGroup> <CustomBuild Include="core.meta.slang" /> diff --git a/source/slang/syntax-base-defs.h b/source/slang/syntax-base-defs.h index 2eb130863..2c15f7215 100644 --- a/source/slang/syntax-base-defs.h +++ b/source/slang/syntax-base-defs.h @@ -119,7 +119,7 @@ public: protected: virtual bool EqualsImpl(Type * type) = 0; - virtual Type* CreateCanonicalType() = 0; + virtual RefPtr<Type> CreateCanonicalType() = 0; Type* canonicalType = nullptr; RefPtr<Type> canonicalTypeRefPtr; @@ -227,7 +227,7 @@ RAW( return rs; } typedef List<KeyValuePair<RefPtr<Type>, RefPtr<Val>>> WitnessTableLookupTable; -) + ) // The witness tables for each interface this actual type implements SYNTAX_FIELD(WitnessTableLookupTable, witnessTables) END_SYNTAX_CLASS() diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index e050fc977..62e467a44 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -18,7 +18,7 @@ namespace Slang return basicType->baseType == this->baseType; } - Type* BasicExpressionType::CreateCanonicalType() + RefPtr<Type> BasicExpressionType::CreateCanonicalType() { // A basic type is already canonical, in our setup return this; @@ -194,9 +194,12 @@ void Type::accept(IValVisitor* visitor, void* extra) if (!et->canonicalType) { // TODO(tfoley): worry about thread safety here? - et->canonicalType = et->CreateCanonicalType(); + auto canType = et->CreateCanonicalType(); + et->canonicalType = canType; if (dynamic_cast<Type*>(et->canonicalType) != this) - et->canonicalTypeRefPtr = et->canonicalType; + et->canonicalTypeRefPtr = canType; + else + canType.detach(); SLANG_ASSERT(et->canonicalType); } return et->canonicalType; @@ -318,10 +321,10 @@ void Type::accept(IValVisitor* visitor, void* extra) substitutions->args.Add(valueType); auto declRef = DeclRef<Decl>(typeDecl.Ptr(), substitutions); - - return DeclRefType::Create( + auto rsType = DeclRefType::Create( this, - declRef)->As<PtrTypeBase>(); + declRef); + return rsType->As<PtrTypeBase>(); } RefPtr<ArrayExpressionType> Session::getArrayType( @@ -381,13 +384,12 @@ void Type::accept(IValVisitor* visitor, void* extra) return this; } - Type* ArrayExpressionType::CreateCanonicalType() + RefPtr<Type> ArrayExpressionType::CreateCanonicalType() { auto canonicalElementType = baseType->GetCanonicalType(); auto canonicalArrayType = getArrayType( canonicalElementType, ArrayLength); - session->canonicalTypes.Add(canonicalArrayType); return canonicalArrayType; } int ArrayExpressionType::GetHashCode() @@ -420,11 +422,10 @@ void Type::accept(IValVisitor* visitor, void* extra) return valueType->Equals(t->valueType); } - Type* GroupSharedType::CreateCanonicalType() + RefPtr<Type> GroupSharedType::CreateCanonicalType() { auto canonicalValueType = valueType->GetCanonicalType(); auto canonicalGroupSharedType = getSession()->getGroupSharedType(canonicalValueType); - session->canonicalTypes.Add(canonicalGroupSharedType); return canonicalGroupSharedType; } @@ -456,7 +457,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return false; } - Type* DeclRefType::CreateCanonicalType() + RefPtr<Type> DeclRefType::CreateCanonicalType() { // A declaration reference is already canonical return this; @@ -792,7 +793,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return false; } - Type* OverloadGroupType::CreateCanonicalType() + RefPtr<Type> OverloadGroupType::CreateCanonicalType() { return this; } @@ -814,7 +815,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return false; } - Type* IRBasicBlockType::CreateCanonicalType() + RefPtr<Type> IRBasicBlockType::CreateCanonicalType() { return this; } @@ -836,7 +837,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return false; } - Type* InitializerListType::CreateCanonicalType() + RefPtr<Type> InitializerListType::CreateCanonicalType() { return this; } @@ -860,7 +861,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return false; } - Type* ErrorType::CreateCanonicalType() + RefPtr<Type> ErrorType::CreateCanonicalType() { return this; } @@ -889,7 +890,7 @@ void Type::accept(IValVisitor* visitor, void* extra) UNREACHABLE_RETURN(false); } - Type* NamedExpressionType::CreateCanonicalType() + RefPtr<Type> NamedExpressionType::CreateCanonicalType() { if (!innerType) innerType = GetType(declRef); @@ -981,7 +982,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return substType; } - Type* FuncType::CreateCanonicalType() + RefPtr<Type> FuncType::CreateCanonicalType() { // result type RefPtr<Type> canResultType = resultType->GetCanonicalType(); @@ -998,8 +999,6 @@ void Type::accept(IValVisitor* visitor, void* extra) canType->resultType = resultType; canType->paramTypes = canParamTypes; - session->canonicalTypes.Add(canType); - return canType; } @@ -1035,10 +1034,9 @@ void Type::accept(IValVisitor* visitor, void* extra) return false; } - Type* TypeType::CreateCanonicalType() + RefPtr<Type> TypeType::CreateCanonicalType() { auto canType = getTypeType(type->GetCanonicalType()); - session->canonicalTypes.Add(canType); return canType; } @@ -1070,7 +1068,7 @@ void Type::accept(IValVisitor* visitor, void* extra) return declRef.GetHashCode(); } - Type* GenericDeclRefType::CreateCanonicalType() + RefPtr<Type> GenericDeclRefType::CreateCanonicalType() { return this; } diff --git a/source/slang/type-defs.h b/source/slang/type-defs.h index a5b9cd659..14e99caf9 100644 --- a/source/slang/type-defs.h +++ b/source/slang/type-defs.h @@ -10,7 +10,7 @@ public: protected: virtual bool EqualsImpl(Type * type) override; - virtual Type* CreateCanonicalType() override; + virtual RefPtr<Type> CreateCanonicalType() override; virtual int GetHashCode() override; ) END_SYNTAX_CLASS() @@ -23,7 +23,7 @@ RAW( protected: virtual bool EqualsImpl(Type * type) override; - virtual Type* CreateCanonicalType() override; + virtual RefPtr<Type> CreateCanonicalType() override; virtual int GetHashCode() override; ) END_SYNTAX_CLASS() @@ -37,7 +37,7 @@ public: protected: virtual bool EqualsImpl(Type * type) override; virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; - virtual Type* CreateCanonicalType() override; + virtual RefPtr<Type> CreateCanonicalType() override; virtual int GetHashCode() override; ) END_SYNTAX_CLASS() @@ -51,7 +51,7 @@ public: protected: virtual bool EqualsImpl(Type * type) override; - virtual Type* CreateCanonicalType() override; + virtual RefPtr<Type> CreateCanonicalType() override; virtual int GetHashCode() override; ) END_SYNTAX_CLASS() @@ -77,7 +77,7 @@ RAW( protected: virtual int GetHashCode() override; virtual bool EqualsImpl(Type * type) override; - virtual Type* CreateCanonicalType() override; + virtual RefPtr<Type> CreateCanonicalType() override; ) END_SYNTAX_CLASS() @@ -103,7 +103,7 @@ RAW( protected: virtual BasicExpressionType* GetScalarType() override; virtual bool EqualsImpl(Type * type) override; - virtual Type* CreateCanonicalType() override; + virtual RefPtr<Type> CreateCanonicalType() override; ) END_SYNTAX_CLASS() @@ -312,7 +312,7 @@ RAW( protected: virtual bool EqualsImpl(Type * type) override; - virtual Type* CreateCanonicalType() override; + virtual RefPtr<Type> CreateCanonicalType() override; virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; virtual int GetHashCode() override; ) @@ -331,7 +331,7 @@ RAW( protected: virtual bool EqualsImpl(Type * type) override; - virtual Type* CreateCanonicalType() override; + virtual RefPtr<Type> CreateCanonicalType() override; virtual int GetHashCode() override; ) @@ -356,7 +356,7 @@ public: protected: virtual bool EqualsImpl(Type * type) override; - virtual Type* CreateCanonicalType() override; + virtual RefPtr<Type> CreateCanonicalType() override; virtual int GetHashCode() override; ) END_SYNTAX_CLASS() @@ -440,7 +440,7 @@ RAW( protected: virtual bool EqualsImpl(Type * type) override; - virtual Type* CreateCanonicalType() override; + virtual RefPtr<Type> CreateCanonicalType() override; virtual int GetHashCode() override; ) END_SYNTAX_CLASS() @@ -469,7 +469,7 @@ RAW( protected: virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override; virtual bool EqualsImpl(Type * type) override; - virtual Type* CreateCanonicalType() override; + virtual RefPtr<Type> CreateCanonicalType() override; virtual int GetHashCode() override; ) END_SYNTAX_CLASS() @@ -495,6 +495,6 @@ SYNTAX_CLASS(GenericDeclRefType, Type) protected: virtual bool EqualsImpl(Type * type) override; virtual int GetHashCode() override; - virtual Type* CreateCanonicalType() override; + virtual RefPtr<Type> CreateCanonicalType() override; ) END_SYNTAX_CLASS() diff --git a/tools/render-test/slang-support.cpp b/tools/render-test/slang-support.cpp index 2a6401d5b..5599a3396 100644 --- a/tools/render-test/slang-support.cpp +++ b/tools/render-test/slang-support.cpp @@ -99,8 +99,9 @@ struct SlangShaderCompilerWrapper : public ShaderCompiler spFindProfile(slangSession, request.computeShader.profile), (int)rawTypeNames.Count(), rawTypeNames.Buffer()); - int compileErr = spCompile(slangRequest); + spSetLineDirectiveMode(slangRequest, SLANG_LINE_DIRECTIVE_MODE_NONE); + int compileErr = spCompile(slangRequest); if (auto diagnostics = spGetDiagnosticOutput(slangRequest)) { fprintf(stderr, "%s", diagnostics); |
