diff options
Diffstat (limited to 'source/slang/slang-ir-specialize-target-switch.cpp')
| -rw-r--r-- | source/slang/slang-ir-specialize-target-switch.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/source/slang/slang-ir-specialize-target-switch.cpp b/source/slang/slang-ir-specialize-target-switch.cpp new file mode 100644 index 000000000..2593389b1 --- /dev/null +++ b/source/slang/slang-ir-specialize-target-switch.cpp @@ -0,0 +1,67 @@ +#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-ir-dce.h" + +namespace Slang +{ + void specializeTargetSwitch(TargetRequest* target, IRGlobalValueWithCode* code) + { + bool changed = false; + for (auto block : code->getBlocks()) + { + if (auto targetSwitch = as<IRTargetSwitch>(block->getTerminator())) + { + CapabilitySet bestCapSet = CapabilitySet::makeInvalid(); + IRBlock* targetBlock = nullptr; + for (UInt i = 0; i < targetSwitch->getCaseCount(); i++) + { + auto cap = (CapabilityAtom)getIntVal(targetSwitch->getCaseValue(i)); + CapabilitySet capSet; + if (cap == CapabilityAtom::Invalid) + capSet = CapabilitySet::makeEmpty(); + else + capSet = CapabilitySet(cap); + if (capSet.isBetterForTarget(bestCapSet, target->getTargetCaps())) + { + targetBlock = targetSwitch->getCaseBlock(i); + bestCapSet = capSet; + } + } + SLANG_ASSERT(targetBlock); + IRBuilder builder(targetSwitch); + builder.setInsertBefore(targetSwitch); + builder.emitBranch(targetBlock); + targetSwitch->removeAndDeallocate(); + changed = true; + } + } + if (changed) + { + // Remove unreachable blocks after specialization. + eliminateDeadCode(code); + } + } + + void specializeTargetSwitch(TargetRequest* target, IRModule* module) + { + for (auto globalInst : module->getGlobalInsts()) + { + if (auto code = as<IRGlobalValueWithCode>(globalInst)) + { + specializeTargetSwitch(target, code); + if (auto gen = as<IRGeneric>(code)) + { + auto retVal = findGenericReturnVal(gen); + if (auto innerCode = as<IRGlobalValueWithCode>(retVal)) + { + specializeTargetSwitch(target, innerCode); + } + } + } + } + } + +} |
