From bd6306cdaa4a49344658bd026721b6532e103d09 Mon Sep 17 00:00:00 2001 From: Yong He Date: Fri, 24 Feb 2023 10:01:47 -0800 Subject: 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 --- source/slang/slang-ir-util.cpp | 75 +++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 11 deletions(-) (limited to 'source/slang/slang-ir-util.cpp') 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(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(findOuterGeneric(value)); @@ -402,8 +428,7 @@ bool canInstHaveSideEffectAtAddress(IRGlobalValueWithCode* func, IRInst* inst, I { auto callee = call->getCallee(); if (callee && - callee->findDecoration() && - callee->findDecoration()) + callee->findDecoration()) { // 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(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: @@ -519,21 +575,18 @@ bool isPureFunctionalCall(IRCall* call) { auto callee = getResolvedInstForDecorations(call->getCallee()); if (callee->findDecoration()) - { - return true; - } - if (callee->findDecoration()) { // 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(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; } -- cgit v1.2.3