diff options
| author | Ellie Hermaszewska <ellieh@nvidia.com> | 2024-10-29 14:49:26 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-29 14:49:26 +0800 |
| commit | f65d756bff8d4c5cbc15bd0322a2ae8e6b896a21 (patch) | |
| tree | ea1d61342cd29368e19135000ec2948813096205 /source/slang/slang-ir-specialize-target-switch.cpp | |
| parent | a729c15e9dce9f5116a38afc66329ab2ca4cea54 (diff) | |
format
* format
* Minor test fixes
* enable checking cpp format in ci
Diffstat (limited to 'source/slang/slang-ir-specialize-target-switch.cpp')
| -rw-r--r-- | source/slang/slang-ir-specialize-target-switch.cpp | 149 |
1 files changed, 81 insertions, 68 deletions
diff --git a/source/slang/slang-ir-specialize-target-switch.cpp b/source/slang/slang-ir-specialize-target-switch.cpp index c501cdab5..defcb7e87 100644 --- a/source/slang/slang-ir-specialize-target-switch.cpp +++ b/source/slang/slang-ir-specialize-target-switch.cpp @@ -1,93 +1,106 @@ #include "slang-ir-specialize-target-switch.h" -#include "slang-ir.h" -#include "slang-ir-insts.h" -#include "slang-compiler.h" + #include "slang-capability.h" +#include "slang-compiler.h" #include "slang-ir-dce.h" +#include "slang-ir-insts.h" +#include "slang-ir.h" namespace Slang { - void specializeTargetSwitch(TargetRequest* target, IRGlobalValueWithCode* code, DiagnosticSink* sink) +void specializeTargetSwitch( + TargetRequest* target, + IRGlobalValueWithCode* code, + DiagnosticSink* sink) +{ + if (auto gen = as<IRGeneric>(code)) { - if (auto gen = as<IRGeneric>(code)) + auto retVal = findGenericReturnVal(gen); + if (auto innerCode = as<IRGlobalValueWithCode>(retVal)) { - auto retVal = findGenericReturnVal(gen); - if (auto innerCode = as<IRGlobalValueWithCode>(retVal)) - { - specializeTargetSwitch(target, innerCode, sink); - return; - } + specializeTargetSwitch(target, innerCode, sink); + return; } + } - bool changed = false; - for (auto block : code->getBlocks()) + bool changed = false; + for (auto block : code->getBlocks()) + { + bool failedImplies = false; + if (auto targetSwitch = as<IRTargetSwitch>(block->getTerminator())) { - bool failedImplies = false; - if (auto targetSwitch = as<IRTargetSwitch>(block->getTerminator())) + bool isEqual; + CapabilitySet bestCapSet = CapabilitySet::makeInvalid(); + IRBlock* targetBlock = nullptr; + CapabilitySet::ImpliesReturnFlags impliesReturnType = + CapabilitySet::ImpliesReturnFlags::NotImplied; + for (UInt i = 0; i < targetSwitch->getCaseCount(); i++) { - bool isEqual; - CapabilitySet bestCapSet = CapabilitySet::makeInvalid(); - IRBlock* targetBlock = nullptr; - CapabilitySet::ImpliesReturnFlags impliesReturnType = CapabilitySet::ImpliesReturnFlags::NotImplied; - for (UInt i = 0; i < targetSwitch->getCaseCount(); i++) + auto cap = (CapabilityName)getIntVal(targetSwitch->getCaseValue(i)); + if (target->getTargetCaps().isIncompatibleWith(cap)) + continue; + CapabilitySet capSet; + if (cap == CapabilityName::Invalid) // `default` case + capSet = CapabilitySet::makeEmpty(); + else + capSet = CapabilitySet(cap); + bool isBetterForTarget = + capSet.isBetterForTarget(bestCapSet, target->getTargetCaps(), isEqual); + if (isBetterForTarget) { - auto cap = (CapabilityName)getIntVal(targetSwitch->getCaseValue(i)); - if (target->getTargetCaps().isIncompatibleWith(cap)) - continue; - CapabilitySet capSet; - if (cap == CapabilityName::Invalid) // `default` case - capSet = CapabilitySet::makeEmpty(); - else - capSet = CapabilitySet(cap); - bool isBetterForTarget = capSet.isBetterForTarget(bestCapSet, target->getTargetCaps(), isEqual); - if (isBetterForTarget) + impliesReturnType = target->getTargetCaps().atLeastOneSetImpliedInOther(capSet); + bool targetImpliesCapSet = + ((int)impliesReturnType & (int)CapabilitySet::ImpliesReturnFlags::Implied || + capSet.isEmpty()); + if (targetImpliesCapSet) { - impliesReturnType = target->getTargetCaps().atLeastOneSetImpliedInOther(capSet); - bool targetImpliesCapSet = ((int)impliesReturnType & (int)CapabilitySet::ImpliesReturnFlags::Implied || capSet.isEmpty()); - if (targetImpliesCapSet) - { - // Now check if bestCapSet contains targetCaps. If it does not then this is an invalid target - targetBlock = targetSwitch->getCaseBlock(i); - bestCapSet = capSet; - } - else - failedImplies = true; + // Now check if bestCapSet contains targetCaps. If it does not then this is + // an invalid target + targetBlock = targetSwitch->getCaseBlock(i); + bestCapSet = capSet; } + else + failedImplies = true; } - IRBuilder builder(targetSwitch); - builder.setInsertBefore(targetSwitch); - if (targetBlock) - { - builder.emitBranch(targetBlock); - } - else - { - // only error if we have the chance of setting a valid target switch, but did not due to incompatability within same `target` atom. - // Otherwise we will have an issue when we process a `__target_switch() { case metal: return; }` for glsl targets. - if(failedImplies) - sink->diagnose(targetSwitch->sourceLoc, Diagnostics::profileIncompatibleWithTargetSwitch, target->getTargetCaps()); - builder.emitMissingReturn(); - } - targetSwitch->removeAndDeallocate(); - changed = true; } - } - if (changed) - { - // Remove unreachable blocks after specialization. - eliminateDeadCode(code); + IRBuilder builder(targetSwitch); + builder.setInsertBefore(targetSwitch); + if (targetBlock) + { + builder.emitBranch(targetBlock); + } + else + { + // only error if we have the chance of setting a valid target switch, but did not + // due to incompatability within same `target` atom. Otherwise we will have an issue + // when we process a `__target_switch() { case metal: return; }` for glsl targets. + if (failedImplies) + sink->diagnose( + targetSwitch->sourceLoc, + Diagnostics::profileIncompatibleWithTargetSwitch, + target->getTargetCaps()); + builder.emitMissingReturn(); + } + targetSwitch->removeAndDeallocate(); + changed = true; } } + if (changed) + { + // Remove unreachable blocks after specialization. + eliminateDeadCode(code); + } +} - void specializeTargetSwitch(TargetRequest* target, IRModule* module, DiagnosticSink* sink) +void specializeTargetSwitch(TargetRequest* target, IRModule* module, DiagnosticSink* sink) +{ + for (auto globalInst : module->getGlobalInsts()) { - for (auto globalInst : module->getGlobalInsts()) + if (auto code = as<IRGlobalValueWithCode>(globalInst)) { - if (auto code = as<IRGlobalValueWithCode>(globalInst)) - { - specializeTargetSwitch(target, code, sink); - } + specializeTargetSwitch(target, code, sink); } } - } + +} // namespace Slang |
