summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-util.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-02-24 10:01:47 -0800
committerGitHub <noreply@github.com>2023-02-24 10:01:47 -0800
commitbd6306cdaa4a49344658bd026721b6532e103d09 (patch)
treebb7f666d426e6cfc7777a3ccac0a1d628588eb39 /source/slang/slang-ir-util.cpp
parente8c08e7ecb1124f115a1d1042277776193122b57 (diff)
More control flow simplifications. (#2673)
* More control flow and Phi param simplifications. * Fix. * Fix gcc error. * Fix. * More IR cleanup. * Fix bug in phi param dce + ifelse simplify. * Propagate and DCE side-effect-free functions. * Enhance CFG simplifcation to remove loops with no side effects. * Fix. * Fixes. * Fix tests. Add [__AlwaysFoldIntoUseSite] for rayPayloadLocation. * More cleanup. * Fixes. * Fix. --------- Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-ir-util.cpp')
-rw-r--r--source/slang/slang-ir-util.cpp75
1 files changed, 64 insertions, 11 deletions
diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp
index 3db036a8d..339521f41 100644
--- a/source/slang/slang-ir-util.cpp
+++ b/source/slang/slang-ir-util.cpp
@@ -157,6 +157,32 @@ IRInst* maybeSpecializeWithGeneric(IRBuilder& builder, IRInst* genericToSpecaili
return genericToSpecailize;
}
+bool isValueType(IRInst* dataType)
+{
+ dataType = getResolvedInstForDecorations(unwrapAttributedType(dataType));
+ if (as<IRBasicType>(dataType))
+ return true;
+ switch (dataType->getOp())
+ {
+ case kIROp_StructType:
+ case kIROp_InterfaceType:
+ case kIROp_ClassType:
+ case kIROp_VectorType:
+ case kIROp_MatrixType:
+ case kIROp_TupleType:
+ case kIROp_ResultType:
+ case kIROp_OptionalType:
+ case kIROp_DifferentialPairType:
+ case kIROp_DynamicType:
+ case kIROp_AnyValueType:
+ case kIROp_ArrayType:
+ case kIROp_FuncType:
+ return true;
+ default:
+ return false;
+ }
+}
+
IRInst* hoistValueFromGeneric(IRBuilder& inBuilder, IRInst* value, IRInst*& outSpecializedVal, bool replaceExistingValue)
{
auto outerGeneric = as<IRGeneric>(findOuterGeneric(value));
@@ -402,8 +428,7 @@ bool canInstHaveSideEffectAtAddress(IRGlobalValueWithCode* func, IRInst* inst, I
{
auto callee = call->getCallee();
if (callee &&
- callee->findDecoration<IRReadNoneDecoration>() &&
- callee->findDecoration<IRNoSideEffectDecoration>())
+ callee->findDecoration<IRReadNoneDecoration>())
{
// An exception is if the callee is side-effect free and is not reading from
// memory.
@@ -423,6 +448,32 @@ bool canInstHaveSideEffectAtAddress(IRGlobalValueWithCode* func, IRInst* inst, I
if (canAddressesPotentiallyAlias(func, call->getArg(i), addr))
return true;
}
+ else if (!isValueType(call->getArg(i)->getDataType()))
+ {
+ // This is some unknown handle type, we assume it can have any side effects.
+ return true;
+ }
+ }
+ }
+ break;
+ case kIROp_unconditionalBranch:
+ case kIROp_loop:
+ {
+ auto branch = as<IRUnconditionalBranch>(inst);
+ // If any pointer typed argument of the branch inst may overlap addr, return true.
+ for (UInt i = 0; i < branch->getArgCount(); i++)
+ {
+ SLANG_RELEASE_ASSERT(branch->getArg(i)->getDataType());
+ if (isPtrLikeOrHandleType(branch->getArg(i)->getDataType()))
+ {
+ if (canAddressesPotentiallyAlias(func, branch->getArg(i), addr))
+ return true;
+ }
+ else if (!isValueType(branch->getArg(i)->getDataType()))
+ {
+ // This is some unknown handle type, we assume it can have any side effects.
+ return true;
+ }
}
}
break;
@@ -434,6 +485,11 @@ bool canInstHaveSideEffectAtAddress(IRGlobalValueWithCode* func, IRInst* inst, I
if (isPtrLikeOrHandleType(inst->getOperand(0)->getDataType()) &&
canAddressesPotentiallyAlias(func, inst->getOperand(0), addr))
return true;
+ else if (!isValueType(inst->getOperand(0)->getDataType()))
+ {
+ // This is some unknown handle type, we assume it can have any side effects.
+ return true;
+ }
}
break;
default:
@@ -520,20 +576,17 @@ bool isPureFunctionalCall(IRCall* call)
auto callee = getResolvedInstForDecorations(call->getCallee());
if (callee->findDecoration<IRReadNoneDecoration>())
{
- return true;
- }
- if (callee->findDecoration<IRNoSideEffectDecoration>())
- {
// If the function has no side effect and is not writing to any outputs,
// we can safely treat the call as a normal inst.
bool hasOutArg = false;
for (UInt i = 0; i < call->getArgCount(); i++)
{
- if (as<IRPtrTypeBase>(call->getArg(i)->getDataType()))
- {
- hasOutArg = true;
- break;
- }
+ if (isValueType(call->getArg(i)->getDataType()))
+ continue;
+ // If the argument type is not a known value type,
+ // assume it is a pointer or handle through which side effect can take place.
+ hasOutArg = true;
+ break;
}
return !hasOutArg;
}