summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-peephole.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-06-21 14:55:59 -0700
committerGitHub <noreply@github.com>2022-06-21 14:55:59 -0700
commite5a75563a1ba2e378353af8b937b8b7bb0fe2c2b (patch)
tree0f31040b408a66f49dc5cd2354c8424e5ff2e279 /source/slang/slang-ir-peephole.cpp
parentea3800e115d4ad1ce06ec07689152616f47a0e3d (diff)
Lower throwing COM interface method. (#2282)
* Lower throwing COM interface method. * Fix. * Fix warnings. Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-ir-peephole.cpp')
-rw-r--r--source/slang/slang-ir-peephole.cpp110
1 files changed, 110 insertions, 0 deletions
diff --git a/source/slang/slang-ir-peephole.cpp b/source/slang/slang-ir-peephole.cpp
new file mode 100644
index 000000000..6cb5d2971
--- /dev/null
+++ b/source/slang/slang-ir-peephole.cpp
@@ -0,0 +1,110 @@
+#include "slang-ir-peephole.h"
+#include "slang-ir-inst-pass-base.h"
+
+namespace Slang
+{
+struct PeepholeContext : InstPassBase
+{
+ PeepholeContext(IRModule* inModule)
+ : InstPassBase(inModule)
+ {}
+
+ bool changed = false;
+
+ void processInst(IRInst* inst)
+ {
+ switch (inst->getOp())
+ {
+ case kIROp_GetResultError:
+ if (inst->getOperand(0)->getOp() == kIROp_MakeResultError)
+ {
+ inst->replaceUsesWith(inst->getOperand(0)->getOperand(0));
+ changed = true;
+ }
+ break;
+ case kIROp_GetResultValue:
+ if (inst->getOperand(0)->getOp() == kIROp_MakeResultValue)
+ {
+ inst->replaceUsesWith(inst->getOperand(0)->getOperand(0));
+ inst->removeAndDeallocate();
+ changed = true;
+ }
+ break;
+ case kIROp_IsResultError:
+ if (inst->getOperand(0)->getOp() == kIROp_MakeResultError)
+ {
+ IRBuilder builder(&sharedBuilderStorage);
+ inst->replaceUsesWith(builder.getBoolValue(true));
+ inst->removeAndDeallocate();
+ changed = true;
+ }
+ else if (inst->getOperand(0)->getOp() == kIROp_MakeResultValue)
+ {
+ IRBuilder builder(&sharedBuilderStorage);
+ inst->replaceUsesWith(builder.getBoolValue(false));
+ inst->removeAndDeallocate();
+ changed = true;
+ }
+ break;
+ case kIROp_GetTupleElement:
+ if (inst->getOperand(0)->getOp() == kIROp_MakeTuple)
+ {
+ auto element = inst->getOperand(1);
+ if (auto intLit = as<IRIntLit>(element))
+ {
+ inst->replaceUsesWith(inst->getOperand(0)->getOperand((UInt)intLit->value.intVal));
+ inst->removeAndDeallocate();
+ changed = true;
+ }
+ }
+ break;
+ case kIROp_FieldExtract:
+ if (inst->getOperand(0)->getOp() == kIROp_makeStruct)
+ {
+ auto field = as<IRFieldExtract>(inst)->field.get();
+ Index fieldIndex = -1;
+ auto structType = as<IRStructType>(inst->getOperand(0)->getDataType());
+ if (structType)
+ {
+ Index i = 0;
+ for (auto sfield : structType->getFields())
+ {
+ if (sfield == field)
+ {
+ fieldIndex = i;
+ break;
+ }
+ i++;
+ }
+ if (fieldIndex != -1 && fieldIndex < (Index)inst->getOperand(0)->getOperandCount())
+ {
+ inst->replaceUsesWith(inst->getOperand(0)->getOperand((UInt)fieldIndex));
+ inst->removeAndDeallocate();
+ changed = true;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ bool processModule()
+ {
+ SharedIRBuilder* sharedBuilder = &sharedBuilderStorage;
+ sharedBuilder->init(module);
+
+ changed = false;
+ processAllInsts([this](IRInst* inst) { processInst(inst); });
+ return changed;
+ }
+};
+
+bool peepholeOptimize(IRModule* module)
+{
+ PeepholeContext context = PeepholeContext(module);
+ return context.processModule();
+}
+
+} // namespace Slang