summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-ir-specialize.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-ir-specialize.cpp')
-rw-r--r--source/slang/slang-ir-specialize.cpp54
1 files changed, 42 insertions, 12 deletions
diff --git a/source/slang/slang-ir-specialize.cpp b/source/slang/slang-ir-specialize.cpp
index 9522dbeca..b1da92ff1 100644
--- a/source/slang/slang-ir-specialize.cpp
+++ b/source/slang/slang-ir-specialize.cpp
@@ -1102,6 +1102,47 @@ struct SpecializationContext
return false;
}
+ // Test if a type is compile time constant.
+ static bool isCompileTimeConstantType(IRInst* inst)
+ {
+ // TODO: We probably need/want a more robust test here.
+ // For now we are just look into the dependency graph of the inst and
+ // see if there are any opcodes that are causing problems.
+ List<IRInst*> localWorkList;
+ HashSet<IRInst*> processedInsts;
+ localWorkList.add(inst);
+ processedInsts.Add(inst);
+
+ while (localWorkList.getCount() != 0)
+ {
+ IRInst* curInst = localWorkList.getLast();
+
+ localWorkList.removeLast();
+ processedInsts.Remove(curInst);
+
+ switch (curInst->getOp())
+ {
+ case kIROp_Load:
+ case kIROp_Call:
+ case kIROp_ExtractExistentialType:
+ case kIROp_CreateExistentialObject:
+ return false;
+ default:
+ break;
+ }
+
+ for (UInt i = 0; i < curInst->getOperandCount(); ++i)
+ {
+ auto operand = curInst->getOperand(i);
+ if (processedInsts.Add(operand))
+ {
+ localWorkList.add(operand);
+ }
+ }
+ }
+ return true;
+ }
+
// Similarly, we want to be able to test whether an instruction
// used as an argument for an existential-type parameter is
// suitable for use in specialization.
@@ -1127,18 +1168,7 @@ struct SpecializationContext
auto concreteVal = makeExistential->getWrappedValue();
auto concreteType = concreteVal->getDataType();
- // TODO: We probably need/want a more robust test here.
- // For now we are just listing the single opcode that is
- // causing problems.
- //
- // TODO: eventually this check would become unnecessary because
- // we can simply check if the `concreteType` is a compile-time
- // constant value.
- //
- if(concreteType->getOp() == kIROp_ExtractExistentialType)
- return false;
-
- return true;
+ return isCompileTimeConstantType(concreteType);
}
// A `wrapExistential(v, T0,w0, T1, w1, ...)` instruction