summaryrefslogtreecommitdiffstats
path: root/source/slang/ir-constexpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/ir-constexpr.cpp')
-rw-r--r--source/slang/ir-constexpr.cpp80
1 files changed, 55 insertions, 25 deletions
diff --git a/source/slang/ir-constexpr.cpp b/source/slang/ir-constexpr.cpp
index ca64f5f04..0cd35161d 100644
--- a/source/slang/ir-constexpr.cpp
+++ b/source/slang/ir-constexpr.cpp
@@ -26,12 +26,12 @@ struct PropagateConstExprContext
DiagnosticSink* getSink() { return sink; }
};
-bool isConstExpr(Type* type)
+bool isConstExpr(IRType* fullType)
{
- if( auto rateQualifiedType = type->As<RateQualifiedType>() )
+ if( auto rateQualifiedType = as<IRRateQualifiedType>(fullType))
{
- auto rate = rateQualifiedType->rate;
- if(auto constExprRate = rate->As<ConstExprRate>())
+ auto rate = rateQualifiedType->getRate();
+ if(auto constExprRate = as<IRConstExprRate>(rate))
return true;
}
@@ -101,7 +101,7 @@ void markConstExpr(
PropagateConstExprContext* context,
IRInst* value)
{
- Slang::markConstExpr(context->getSession(), value);
+ Slang::markConstExpr(context->getBuilder(), value);
}
@@ -285,49 +285,79 @@ bool propagateConstExprBackward(
UInt callArgCount = operandCount - firstCallArg;
auto callee = callInst->getOperand(0);
- while( callee->op == kIROp_specialize )
+
+ // If we are calling a generic operation, then
+ // try to follow through the `specialize` chain
+ // and find the callee.
+ //
+ // TODO: This probably shouldn't be required,
+ // since we can hopefully use the type of the
+ // callee in all cases.
+ //
+ while(auto specInst = as<IRSpecialize>(callee))
{
- callee = ((IRSpecialize*) callee)->getOperand(0);
+ auto genericInst = as<IRGeneric>(specInst->getBase());
+ if(!genericInst)
+ break;
+
+ auto returnVal = findGenericReturnVal(genericInst);
+ if(!returnVal)
+ break;
+
+ callee = returnVal;
}
- if( callee->op == kIROp_Func )
+
+ auto calleeFunc = as<IRFunc>(callee);
+ if(calleeFunc && isDefinition(calleeFunc))
{
- auto calleeFunc = (IRFunc*) callee;
- auto calleeFuncType = calleeFunc->getType();
+ // We have an IR-level function definition we are calling,
+ // and thus we can propagate `constexpr` information
+ // through its `IRParam`s.
+
+ auto calleeFuncType = calleeFunc->getDataType();
UInt callParamCount = calleeFuncType->getParamCount();
SLANG_RELEASE_ASSERT(callParamCount == callArgCount);
// If the callee has a definition, then we can read `constexpr`
// information off of the parameters of its first IR block.
- if( auto calleeFirstBlock = calleeFunc->getFirstBlock() )
+ if(auto calleeFirstBlock = calleeFunc->getFirstBlock())
{
UInt paramCounter = 0;
- for( auto pp = calleeFirstBlock->getFirstParam(); pp; pp = pp->getNextParam() )
+ for(auto pp = calleeFirstBlock->getFirstParam(); pp; pp = pp->getNextParam())
{
UInt paramIndex = paramCounter++;
auto param = pp;
auto arg = callInst->getOperand(firstCallArg + paramIndex);
- if( isConstExpr(param) )
+ if(isConstExpr(param))
{
- if( maybeMarkConstExpr(context, arg) )
+ if(maybeMarkConstExpr(context, arg))
{
changedThisIteration = true;
}
}
}
}
- else
+ }
+ else
+ {
+ // If we don't have a concrete callee function
+ // definition, then we need to extract the
+ // type of the callee instruction, and try to work
+ // with that.
+ //
+ // Note that this does not allow us to propagate
+ // `constexpr` information from the body of a callee
+ // back to call sites.
+ auto calleeType = callee->getDataType();
+ if(auto caleeFuncType = as<IRFuncType>(calleeType))
{
- // If we don't have the definition/body for the callee,
- // then we have to glean `constexpr` information from its
- // type instead.
- auto calleeType = calleeFunc->getType();
- auto paramCount = calleeType->getParamCount();
+ auto paramCount = caleeFuncType->getParamCount();
for( UInt pp = 0; pp < paramCount; ++pp )
{
- auto paramType = calleeType->getParamType(pp);
+ auto paramType = caleeFuncType->getParamType(pp);
auto arg = callInst->getOperand(firstCallArg + pp);
if( isConstExpr(paramType) )
{
@@ -474,8 +504,8 @@ void propagateConstExpr(
break;
case kIROp_Func:
- case kIROp_global_var:
- case kIROp_global_constant:
+ case kIROp_GlobalVar:
+ case kIROp_GlobalConstant:
{
IRGlobalValueWithCode* code = (IRGlobalValueWithCode*) gv;
@@ -511,8 +541,8 @@ void propagateConstExpr(
break;
case kIROp_Func:
- case kIROp_global_var:
- case kIROp_global_constant:
+ case kIROp_GlobalVar:
+ case kIROp_GlobalConstant:
{
IRGlobalValueWithCode* code = (IRGlobalValueWithCode*) ii;
validateConstExpr(&context, code);