From 7c6faf62158eed309f01bbef8a7b88e0c36459c7 Mon Sep 17 00:00:00 2001 From: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> Date: Fri, 7 Jun 2024 09:48:24 -0400 Subject: Precompute UIntSet from individual capabilities inside generator (#4269) * fixes: #4163 Precompute UIntSet from individual capabilities inside generator (removes intermediate form of capabilities). note: 1. I still expand capabilities which are missing `target` and `stage` atoms. * fix compile warning<->error with clang * address review preallocate the pregenerated UIntSet's * disable incorrect warning of 'unreachable code' The warning is wrong since, when `out` has 0 elements (does not start `for` loop), the `return` is reached. * fix clang warnings 1. use unsigned long for the buffer serializer 2. braces around scalar init * address review added work around to avoid warning with `for(...) return; return;` pattern `else if constexpr` addition instead of cascading blocks * push fix for use of `_BitScanForward` * cleanup * move around assert for proper checking * syntax error * use SLANG_ASSERT instead of assert * test for why SLANG_ASSERT caused CI to fail with linux-arm builds * test if `SLANG_ASSERT` really is causing a build issue for linux-arm --- .../capability-generator-main.cpp | 130 +++++++++++---------- 1 file changed, 71 insertions(+), 59 deletions(-) (limited to 'tools') diff --git a/tools/slang-capability-generator/capability-generator-main.cpp b/tools/slang-capability-generator/capability-generator-main.cpp index e31822e05..b08496e35 100644 --- a/tools/slang-capability-generator/capability-generator-main.cpp +++ b/tools/slang-capability-generator/capability-generator-main.cpp @@ -657,22 +657,36 @@ void calcCanonicalRepresentations(DiagnosticSink* sink, List& atomSet) +{ + UIntSet set{}; + // Last element is generally a larger number. Start from there to minimize reallocations. + for (Index i = atomSet.getCount()-1; i >= 0; i--) + set.add(atomSet[i]->enumValue); + return set; } SlangResult generateDefinitions(DiagnosticSink* sink, List>& defs, StringBuilder& sbHeader, StringBuilder& sbCpp) @@ -755,50 +769,56 @@ SlangResult generateDefinitions(DiagnosticSink* sink, List anyStageAtomSet.add(def->enumValue); } } - outputUIntSetAsBufferValues("kAnyTargetUIntSetBuffer", anyTargetUIntSetHash, anyTargetAtomSet); - outputUIntSetAsBufferValues("kAnyStageUIntSetBuffer", anyStageUIntSetHash, anyStageAtomSet); - + outputUIntSetGenerator("generatorOf_kAnyTargetUIntSetBuffer", anyTargetUIntSetHash, anyTargetAtomSet); + anyTargetUIntSetHash << "const static CapabilityAtomSet kAnyTargetUIntSetBuffer = generatorOf_kAnyTargetUIntSetBuffer();\n"; + sbCpp << anyTargetUIntSetHash; + + outputUIntSetGenerator("generatorOf_kAnyStageUIntSetBuffer", anyStageUIntSetHash, anyStageAtomSet); + anyStageUIntSetHash << "const static CapabilityAtomSet kAnyStageUIntSetBuffer = generatorOf_kAnyStageUIntSetBuffer();\n"; + sbCpp << anyStageUIntSetHash; + sbHeader << "\nenum {\n"; sbHeader << " kCapabilityTargetCount = " << targetCount << ",\n"; sbHeader << " kCapabilityStageCount = " << stageCount << ",\n"; sbHeader << "};\n\n"; calcCanonicalRepresentations(sink, defs, mapEnumValueToDef); - List capabiltiyNameArray; - List serializedCapabilityArrays; - List serializedAtomDisjunctions; - auto serializeConjunction = [&](const List& capabilities) -> SerializedArrayView + struct SerializedConjunction + { + SerializedConjunction() + { + } + SerializedConjunction(const String& initFunctionName, UIntSet& data) : + m_initFunctionName(initFunctionName), m_data(data) + { + } + String m_initFunctionName; + UIntSet m_data; + }; + List serializedCapabilitesCache; + + List serializedAtomDisjunctions; + auto serializeConjunction = [&](const List& capabilities, CapabilityDef* parentDef, Index conjunctionNumber) -> Index { + auto capabilitiesAsUIntSet = atomSetToUIntSet(capabilities); // Do we already have a serialized capability array that is the same the one we are trying to serialize? - for (auto existingArray : serializedCapabilityArrays) + for (Index i = 0; i < serializedCapabilitesCache.getCount(); i++) { - if (existingArray.count == capabilities.getCount()) + auto& existingSet = serializedCapabilitesCache[i].m_data; + if (existingSet == capabilitiesAsUIntSet) { - bool match = true; - for (Index i = 0; i < capabilities.getCount(); i++) - { - if (capabiltiyNameArray[existingArray.first+i] != capabilities[i]->name) - { - match = false; - break; - } - } - if (match) - return existingArray; + return i; } } - SerializedArrayView result; - result.first = capabiltiyNameArray.getCount(); - for (auto capability : capabilities) - { - capabiltiyNameArray.add(capability->name); - } - result.count = capabilities.getCount(); - serializedCapabilityArrays.add(result); + auto initName = "generatorOf_" + parentDef->name + "_conjunction"+String(conjunctionNumber); + outputUIntSetGenerator(initName, sbCpp, capabilitiesAsUIntSet); + + auto result = serializedCapabilitesCache.getCount(); + serializedCapabilitesCache.add(SerializedConjunction(initName + "()", capabilitiesAsUIntSet)); return result; }; - auto serializeDisjunction = [&](const List& conjunctions) -> SerializedArrayView + auto serializeDisjunction = [&](const List& conjunctions) -> SerializedArrayView { SerializedArrayView result; result.first = serializedAtomDisjunctions.getCount(); @@ -811,35 +831,23 @@ SlangResult generateDefinitions(DiagnosticSink* sink, List }; for (auto def : defs) { - List conjunctions; + List conjunctions; for (auto& c : def->canonicalRepresentation) - conjunctions.add(serializeConjunction(c)); + conjunctions.add(serializeConjunction(c, def, conjunctions.getCount())); def->serializedCanonicalRepresentation = serializeDisjunction(conjunctions); } - sbCpp << anyTargetUIntSetHash; - sbCpp << anyStageUIntSetHash; - - sbCpp << "static CapabilityName kCapabilityArray[] = {\n"; + sbCpp << "static CapabilityAtomSet kCapabilityArray[] = {\n"; Index arrayIndex = 0; - sbCpp << " /* [0] @0: */ "; - for (Index i = 0; i < capabiltiyNameArray.getCount(); ++i) + for (Index i = 0; i < serializedCapabilitesCache.getCount(); ++i) { - sbCpp << " CapabilityName::" << capabiltiyNameArray[i] << ","; - if (i + 1 == serializedCapabilityArrays[arrayIndex].first + serializedCapabilityArrays[arrayIndex].count) - { - arrayIndex++; - if (arrayIndex == serializedCapabilityArrays.getCount()) - sbCpp << "\n"; - else - sbCpp << "\n /* [" << arrayIndex << "] @" << serializedCapabilityArrays[arrayIndex].first <<": */ "; - } + sbCpp << " " << serializedCapabilitesCache[i].m_initFunctionName << ",\n"; } sbCpp << "};\n"; - sbCpp << "static ArrayView kCapabilityConjunctions[] = {\n"; + sbCpp << "static CapabilityAtomSet* kCapabilityConjunctions[] = {\n"; for (auto c : serializedAtomDisjunctions) { - sbCpp << " { kCapabilityArray + " << c.first << ", " << c.count << " },\n"; + sbCpp << " kCapabilityArray + " << c << ", \n"; } sbCpp << "};\n"; @@ -882,8 +890,12 @@ SlangResult generateDefinitions(DiagnosticSink* sink, List } sbCpp << ", "; + // rank + sbCpp << def->rank; + sbCpp << ", "; + // canonnical representation. - sbCpp << def->rank << ", { kCapabilityConjunctions + " << def->serializedCanonicalRepresentation.first << ", " << def->serializedCanonicalRepresentation.count << "} },\n"; + sbCpp << "{ kCapabilityConjunctions + " << def->serializedCanonicalRepresentation.first << ", " << def->serializedCanonicalRepresentation.count << "} },\n"; } sbCpp << "};\n"; -- cgit v1.2.3