summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-specialize-target-switch.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-08-28 21:24:49 -0700
committerGitHub <noreply@github.com>2023-08-28 21:24:49 -0700
commitc787c4b82ba76f87069911f203eb192060b5264f (patch)
tree2aa98326ce8d4c9f2011d79ee9f6d34db14716e7 /source/slang/slang-ir-specialize-target-switch.cpp
parentaf363c02bf0fa2502c14f454965adff87170ff15 (diff)
Add `target_switch` and `intrinsic_asm` statement. (#3154)
* Add `target_switch` and `__intrinsic_asm` statement. * Cleanup. * WaveGetActiveMask, WaveGetActiveMask, WaveCountBits. * WaveIsFirstLane. * More wave intrinsics. * wave intrinsics. * merge fix. * Fix. * Fix. * Update test. * update test. * Fix. --------- Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-ir-specialize-target-switch.cpp')
-rw-r--r--source/slang/slang-ir-specialize-target-switch.cpp67
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);
+ }
+ }
+ }
+ }
+ }
+
+}