diff options
| author | ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> | 2024-06-07 09:48:24 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-07 09:48:24 -0400 |
| commit | 7c6faf62158eed309f01bbef8a7b88e0c36459c7 (patch) | |
| tree | ae0e87295bad2b45dd80dfac125b37d59bcda588 /tools/slang-capability-generator/capability-generator-main.cpp | |
| parent | 004fe27a52b7952111ad7e749397aeff499de7ed (diff) | |
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
Diffstat (limited to 'tools/slang-capability-generator/capability-generator-main.cpp')
| -rw-r--r-- | tools/slang-capability-generator/capability-generator-main.cpp | 130 |
1 files changed, 71 insertions, 59 deletions
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<RefPtr<CapabilityDe calcCanonicalRepresentation(sink, def, mapEnumValueToDef); } -void outputUIntSetAsBufferValues(const String& nameOfBuffer, StringBuilder& resultBuilder, UIntSet& set) +// Create a local UIntSet with data +void outputLocalUIntSetBuffer(const String& nameOfBuffer, StringBuilder& resultBuilder, UIntSet& set) { - // store UIntSet::Element as uint8_t to stay sizeof(UIntSet::Element) independent. - // underlying type may change, bits stay the same. - resultBuilder << "inline static CapabilityAtomSet generate_" << nameOfBuffer << "()\n"; - resultBuilder << "{\n"; - resultBuilder << " CapabilityAtomSet generatedSet;\n"; - + resultBuilder << " CapabilityAtomSet " << nameOfBuffer << ";\n"; + resultBuilder << " " << nameOfBuffer << ".resizeBackingBufferDirectly(" << set.getBuffer().getCount() << ");\n"; for (Index i = 0; i < set.getBuffer().getCount(); i++) { - resultBuilder << " generatedSet.addRawElement(UIntSet::Element(" << set.getBuffer()[i] << "UL), " << i << ");\n"; + resultBuilder << " " << nameOfBuffer << ".addRawElement(UIntSet::Element(" << set.getBuffer()[i] << "UL), " << i << "); \n"; } - resultBuilder << " return generatedSet;\n"; +} + +// Create function to generate a UIntSet with initial data +void outputUIntSetGenerator(const String& nameOfGenerator, StringBuilder & resultBuilder, UIntSet & set) +{ + resultBuilder << "inline static CapabilityAtomSet " << nameOfGenerator << "()\n"; + resultBuilder << "{\n"; + auto nameOfBackingData = nameOfGenerator + "_data"; + outputLocalUIntSetBuffer(nameOfBackingData, resultBuilder, set); + resultBuilder << " return " << nameOfBackingData << ";\n"; resultBuilder << "}\n"; +} - resultBuilder << "const static CapabilityAtomSet " << nameOfBuffer << " = generate_" << nameOfBuffer << "();\n"; + +UIntSet atomSetToUIntSet(const List<CapabilityDef*>& 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<RefPtr<CapabilityDef>>& defs, StringBuilder& sbHeader, StringBuilder& sbCpp) @@ -755,50 +769,56 @@ SlangResult generateDefinitions(DiagnosticSink* sink, List<RefPtr<CapabilityDef> 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<String> capabiltiyNameArray; - List<SerializedArrayView> serializedCapabilityArrays; - List<SerializedArrayView> serializedAtomDisjunctions; - auto serializeConjunction = [&](const List<CapabilityDef*>& capabilities) -> SerializedArrayView + struct SerializedConjunction + { + SerializedConjunction() + { + } + SerializedConjunction(const String& initFunctionName, UIntSet& data) : + m_initFunctionName(initFunctionName), m_data(data) + { + } + String m_initFunctionName; + UIntSet m_data; + }; + List<SerializedConjunction> serializedCapabilitesCache; + + List<Index> serializedAtomDisjunctions; + auto serializeConjunction = [&](const List<CapabilityDef*>& 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<SerializedArrayView>& conjunctions) -> SerializedArrayView + auto serializeDisjunction = [&](const List<Index>& conjunctions) -> SerializedArrayView { SerializedArrayView result; result.first = serializedAtomDisjunctions.getCount(); @@ -811,35 +831,23 @@ SlangResult generateDefinitions(DiagnosticSink* sink, List<RefPtr<CapabilityDef> }; for (auto def : defs) { - List<SerializedArrayView> conjunctions; + List<Index> 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<CapabilityName> 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<RefPtr<CapabilityDef> } 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"; |
