diff options
| -rw-r--r-- | source/slang/slang-ast-support-types.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 31 | ||||
| -rw-r--r-- | source/slang/slang-check-impl.h | 11 | ||||
| -rw-r--r-- | source/slang/slang-hlsl-intrinsic-set.cpp | 11 | ||||
| -rw-r--r-- | source/slang/slang-hlsl-intrinsic-set.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-ir-link.cpp | 11 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-syntax.cpp | 14 |
8 files changed, 50 insertions, 36 deletions
diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h index 39932ea4e..99ced8187 100644 --- a/source/slang/slang-ast-support-types.h +++ b/source/slang/slang-ast-support-types.h @@ -1318,8 +1318,11 @@ namespace Slang struct WitnessTable : RefObject { + List<KeyValuePair<Decl*, RequirementWitness>> requirementList; RequirementDictionary requirementDictionary; + void add(Decl* decl, RequirementWitness const& witness); + // The type that the witness table witnesses conformance to (e.g. an Interface) Type* baseType; diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 4fa5fff17..79d9e4bd7 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -1271,7 +1271,7 @@ namespace Slang // TODO: actually implement matching here. For now we'll // just pretend that things are satisfied in order to make progress.. - witnessTable->requirementDictionary.Add( + witnessTable->add( requiredMemberDeclRef.getDecl(), RequirementWitness(satisfyingMemberDeclRef)); return true; @@ -1361,7 +1361,7 @@ namespace Slang // for( auto p : mapRequiredToSatisfyingAccessorDeclRef ) { - witnessTable->requirementDictionary.Add( + witnessTable->add( p.Key, RequirementWitness(p.Value)); } @@ -1378,7 +1378,7 @@ namespace Slang // represents a witness value that is only needed by the front-end, // and that can be ignored by IR and emit logic. // - witnessTable->requirementDictionary.Add( + witnessTable->add( requiredMemberDeclRef.getDecl(), RequirementWitness(satisfyingMemberDeclRef)); return true; @@ -1465,7 +1465,7 @@ namespace Slang { // If a subtype witness was found, then the conformance // appears to hold, and we can satisfy that requirement. - witnessTable->requirementDictionary.Add(requiredConstraintDeclRef, RequirementWitness(witness)); + witnessTable->add(requiredConstraintDeclRef, RequirementWitness(witness)); } else { @@ -1482,7 +1482,7 @@ namespace Slang { // If all the constraints were satisfied, then the chosen // type can indeed satisfy the interface requirement. - witnessTable->requirementDictionary.Add( + witnessTable->add( requiredAssociatedTypeDeclRef.getDecl(), RequirementWitness(satisfyingType)); } @@ -1871,7 +1871,7 @@ namespace Slang // difference between our synthetic method and a hand-written // one with the same behavior. // - witnessTable->requirementDictionary.Add(requiredMemberDeclRef, + witnessTable->add(requiredMemberDeclRef, RequirementWitness(makeDeclRef(synFuncDecl))); return true; } @@ -2210,9 +2210,9 @@ namespace Slang // for(auto p : mapRequiredAccessorToSynAccessor) { - witnessTable->requirementDictionary.Add(p.Key, RequirementWitness(makeDeclRef(p.Value))); + witnessTable->add(p.Key, RequirementWitness(makeDeclRef(p.Value))); } - witnessTable->requirementDictionary.Add(requiredMemberDeclRef, + witnessTable->add(requiredMemberDeclRef, RequirementWitness(makeDeclRef(synPropertyDecl))); return true; } @@ -2319,7 +2319,7 @@ namespace Slang if(!satisfyingWitnessTable) return false; - witnessTable->requirementDictionary.Add( + witnessTable->add( requiredInheritanceDeclRef.getDecl(), RequirementWitness(satisfyingWitnessTable)); return true; @@ -3047,7 +3047,7 @@ namespace Slang } // Okay, add the conformance witness for `__Tag` being satisfied by `tagType` - witnessTable->requirementDictionary.Add(tagAssociatedTypeDecl, RequirementWitness(tagType)); + witnessTable->add(tagAssociatedTypeDecl, RequirementWitness(tagType)); // TODO: we actually also need to synthesize a witness for the conformance of `tagType` // to the `__BuiltinIntegerType` interface, because that is a constraint on the @@ -4553,12 +4553,15 @@ namespace Slang { // If we've imported this one already, then // skip the step where we modify the current scope. - auto& importedModules = getShared()->importedModules; - if (importedModules.Contains(moduleDecl)) + auto& importedModulesList = getShared()->importedModulesList; + auto& importedModulesSet = getShared()->importedModulesSet; + if (importedModulesSet.Contains(moduleDecl)) { return; } - importedModules.Add(moduleDecl); + importedModulesList.add(moduleDecl); + importedModulesSet.Add(moduleDecl); + // Create a new sub-scope to wire the module @@ -4746,7 +4749,7 @@ namespace Slang // member on the `SharedSemanticsContext` is accurate in this case. // _addCandidateExtensionsFromModule(m_module->getModuleDecl()); - for( auto moduleDecl : this->importedModules ) + for( auto moduleDecl : this->importedModulesList ) { _addCandidateExtensionsFromModule(moduleDecl); } diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h index a9f861d3d..b3c5e46f9 100644 --- a/source/slang/slang-check-impl.h +++ b/source/slang/slang-check-impl.h @@ -211,12 +211,13 @@ namespace Slang return m_sink; } - // We need to track what has been `import`ed, - // to avoid importing the same thing more than once + // We need to track what has been `import`ed into + // the scope of this semantic checking session, + // and also to avoid importing the same thing more + // than once. // - // TODO: a smarter approach might be to filter - // out duplicate references during lookup. - HashSet<ModuleDecl*> importedModules; + List<ModuleDecl*> importedModulesList; + HashSet<ModuleDecl*> importedModulesSet; public: SharedSemanticsContext( diff --git a/source/slang/slang-hlsl-intrinsic-set.cpp b/source/slang/slang-hlsl-intrinsic-set.cpp index 27871141d..b73aa4e8e 100644 --- a/source/slang/slang-hlsl-intrinsic-set.cpp +++ b/source/slang/slang-hlsl-intrinsic-set.cpp @@ -400,9 +400,9 @@ SlangResult HLSLIntrinsicSet::makeIntrinsic(IRInst* inst, HLSLIntrinsic& out) void HLSLIntrinsicSet::getIntrinsics(List<const HLSLIntrinsic*>& out) const { - for (auto& pair : m_intrinsics) + for (auto& intrinsic : m_intrinsicsList) { - out.add(pair.Value); + out.add(intrinsic); } } @@ -414,13 +414,18 @@ HLSLIntrinsic* HLSLIntrinsicSet::add(const HLSLIntrinsic& intrinsic) HLSLIntrinsic* copy = (HLSLIntrinsic*)m_intrinsicFreeList.allocate(); *copy = intrinsic; HLSLIntrinsicRef ref(copy); - HLSLIntrinsic** found = m_intrinsics.TryGetValueOrAdd(ref, copy); + HLSLIntrinsic** found = m_intrinsicsDict.TryGetValueOrAdd(ref, copy); if (found) { // If we have found an intrinsic, we can free the copy m_intrinsicFreeList.deallocate(copy); return *found; } + + // If we are adding an intrinsic for the first time, + // it should be added to the deduplicated list + m_intrinsicsList.add(copy); + return copy; } diff --git a/source/slang/slang-hlsl-intrinsic-set.h b/source/slang/slang-hlsl-intrinsic-set.h index c19ab3a7c..6682e848e 100644 --- a/source/slang/slang-hlsl-intrinsic-set.h +++ b/source/slang/slang-hlsl-intrinsic-set.h @@ -215,7 +215,8 @@ protected: // NOTE that this function must only be called with unique types (ie from the m_typeSet) void _calcIntrinsic(HLSLIntrinsic::Op op, IRType* returnType, IRType*const* inArgs, Index argsCount, HLSLIntrinsic& out); - Dictionary<HLSLIntrinsicRef, HLSLIntrinsic*> m_intrinsics; + List<HLSLIntrinsic*> m_intrinsicsList; + Dictionary<HLSLIntrinsicRef, HLSLIntrinsic*> m_intrinsicsDict; FreeList m_intrinsicFreeList; ///< the storage for the intrinsics when they are in the map diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp index 274fbf6d9..1008c94a1 100644 --- a/source/slang/slang-ir-link.cpp +++ b/source/slang/slang-ir-link.cpp @@ -1425,17 +1425,6 @@ LinkedIR linkIR( context->builder->setInsertInto(context->getModule()->getModuleInst()); - // for now, clone all unreferenced witness tables - // - // TODO: This step should *not* be needed with the current IR - // specialization approach, so we should consider removing it. - // - for (auto sym : context->getSymbols()) - { - if (sym.Value->irGlobalValue->op == kIROp_WitnessTable) - cloneGlobalValue(context, (IRWitnessTable*)sym.Value->irGlobalValue); - } - // Next, we make sure to clone the global value for // the entry point function itself, and rely on // this step to recursively copy over anything else diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index f7c71adf9..539027e74 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -5170,7 +5170,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> { auto subBuilder = subContext->irBuilder; - for(auto entry : astWitnessTable->requirementDictionary) + for(auto entry : astWitnessTable->requirementList) { auto requiredMemberDecl = entry.Key; auto satisfyingWitness = entry.Value; diff --git a/source/slang/slang-syntax.cpp b/source/slang/slang-syntax.cpp index aa11b1b0f..ea17ad1d1 100644 --- a/source/slang/slang-syntax.cpp +++ b/source/slang/slang-syntax.cpp @@ -322,7 +322,19 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt return RequirementWitness(); } - + // + // WitnessTable + // + + void WitnessTable::add(Decl* decl, RequirementWitness const& witness) + { + SLANG_ASSERT(!requirementDictionary.ContainsKey(decl)); + + requirementDictionary.Add(decl, witness); + requirementList.add(KeyValuePair<Decl*, RequirementWitness>(decl, witness)); + } + + // static Type* ExtractGenericArgType(Val* val) { |
