diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-04-11 16:18:29 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-04-11 16:18:29 -0700 |
| commit | baf194e7456ba4568dcf11249896af35b3ce18cc (patch) | |
| tree | f75e20db450100d41bfa9c384a8bab0fdc28a749 /source/slang/ir-constexpr.cpp | |
| parent | 6322983fa4dc84ef1e9dd8fad54d4c1580436e67 (diff) | |
Introduce an IR-level type system (#481)
* Introduce an IR-level type system
Up to this point, the Slang IR has used the front-end type system to represent types in the IR.
As a result (but ultimately more importantly) the IR representation of generics and specialization has used AST-level concepts embedded in the IR.
For example, to express the specialization of `vector<T,N>` to a concrete type `float` for `T`, we needed an IR operation that could represent the specialization, with operands that somehow represented the type argument `float`.
The whole thing was very complicated.
The big idea of this change is to introduce a new representation in which types in the IR are just ordinary instructions, so that using them as operands makes sense. The hierarchy of IR types closely mirrors the AST-side hierarchy for now, and that will probably be something we should maintain going forward.
In order to make these changes work, though, I also had to do major overhauls of things like the way substitutions are performed, how we check interface conformances, the way lookup through interface types is done, etc. etc. This is a big change, and unfortunately any attempt to summarize it in the commit message wouldn't do it justice.
* Fix 64-bit build warning
* Fix up some clang warnings/errors
Diffstat (limited to 'source/slang/ir-constexpr.cpp')
| -rw-r--r-- | source/slang/ir-constexpr.cpp | 80 |
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); |
