From ddf3d5550f06d19606e5d148edca308f852dbe03 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Wed, 17 Jul 2019 14:38:55 -0700 Subject: Change how global-scope constants are handled (#1001) Before this change, global and function-scope `static const` declarations were represented as instructions of type `IRGlobalConstant`, which was represented similarly to an `IRGlobalVar`: with a "body" block of instructions that compute/return the initial value. This representation inhibited optimizations (because a reference to a global constant would not in general be replaced with a reference to its value), and also caused problems for resource type legalization because the logic for type legalization did not (and still does not) handle initializers on globals (so global *variables* that contain resource types are still unsupported). The change here is simple at the high level: we get rid of `IRGlobalConstant` and instead handle global-scope constants as "ordinary" instructions at the global scope. E.g., if we have a declaration like: static const int a[] = { ... } that will be represented in the IR as a `makeArray` instruction at the global scope, referencing other global-scope instructions that represent the values in the array. This simple choice addresses both of the main limitations. A `static const` variable of integer/float/whatever type is now represented as just a reference to the given IR value and thus enables all the same optimizations. When a `static const` variable uses a type with resources, the existing legalization logic (which can handle most of the "ordinary" instructions already) applies. Another secondary benefit of this approach is that the hacky `IREmitMode` enumeration is no longer needed to help us special-case source code emit for `static const` variables. Beyond just removing `IRGlobalConstant`, and updating the lowering logic to use the initializer direclty, the main change here is to the emit logic to make it properly handle "ordinary" instructions that might appear at global scope. One open issue with this change, that could be addressed in a follow-up change, is that "extern" global constants that need to be imported from another module (but which might not have a known value when the current module is compiled) aren't supported - we don't have a way to put a linkage decoration on them. A future change might re-introduce global constants as a distinct IR instruction type that just references the value as an operand (if it is available). We would then need to replace references to an IR constant with references to its value right after linking. --- source/slang/slang-emit-c-like.cpp | 242 ++++++++++++------------------- source/slang/slang-emit-c-like.h | 38 ++--- source/slang/slang-emit-cpp.cpp | 50 +++---- source/slang/slang-emit-cpp.h | 8 +- source/slang/slang-emit-glsl.cpp | 36 ++--- source/slang/slang-emit-glsl.h | 4 +- source/slang/slang-emit-hlsl.cpp | 6 +- source/slang/slang-emit-hlsl.h | 2 +- source/slang/slang-ir-constexpr.cpp | 2 - source/slang/slang-ir-inst-defs.h | 3 +- source/slang/slang-ir-insts.h | 22 +-- source/slang/slang-ir-legalize-types.cpp | 62 -------- source/slang/slang-ir-link.cpp | 24 --- source/slang/slang-ir-ssa.cpp | 1 - source/slang/slang-ir.cpp | 15 -- source/slang/slang-lower-to-ir.cpp | 130 ++++++++++------- 16 files changed, 250 insertions(+), 395 deletions(-) (limited to 'source') diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 4f718f884..a7a427f4a 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -401,7 +401,7 @@ void CLikeSourceEmitter::emitVal(IRInst* val, EmitOpInfo const& outerPrec) } else { - emitInstExpr(val, IREmitMode::Default, outerPrec); + emitInstExpr(val, outerPrec); } } @@ -699,7 +699,7 @@ void CLikeSourceEmitter::emitDeclarator(IRDeclaratorInfo* declarator) case IRDeclaratorInfo::Flavor::Array: emitDeclarator(declarator->next); m_writer->emit("["); - emitOperand(declarator->elementCount, IREmitMode::Default, getInfo(EmitOp::General)); + emitOperand(declarator->elementCount, getInfo(EmitOp::General)); m_writer->emit("]"); break; } @@ -731,7 +731,7 @@ void CLikeSourceEmitter::emitSimpleValue(IRInst* inst) } -bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst, IREmitMode mode) +bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst) { // Certain opcodes should never/always be folded in switch( inst->op ) @@ -743,7 +743,6 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst, IREmitMode mod // case kIROp_Var: case kIROp_GlobalVar: - case kIROp_GlobalConstant: case kIROp_GlobalParam: case kIROp_Param: case kIROp_Func: @@ -770,10 +769,6 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst, IREmitMode mod return true; } - // Always fold when we are inside a global constant initializer - if (mode == IREmitMode::GlobalConstant) - return true; - switch( inst->op ) { default: @@ -783,10 +778,6 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst, IREmitMode mod // them to initializer lists, which aren't allowed in // general expression contexts. // - // Note: we are doing this check *after* the check for `GlobalConstant` - // mode, because otherwise we'd fail to emit initializer lists in - // the main place where we want/need them. - // case kIROp_makeStruct: case kIROp_makeArray: return false; @@ -935,11 +926,11 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst, IREmitMode mod return true; } -void CLikeSourceEmitter::emitOperand(IRInst* inst, IREmitMode mode, EmitOpInfo const& outerPrec) +void CLikeSourceEmitter::emitOperand(IRInst* inst, EmitOpInfo const& outerPrec) { - if( shouldFoldInstIntoUseSites(inst, mode) ) + if( shouldFoldInstIntoUseSites(inst) ) { - emitInstExpr(inst, mode, outerPrec); + emitInstExpr(inst, outerPrec); return; } @@ -952,7 +943,7 @@ void CLikeSourceEmitter::emitOperand(IRInst* inst, IREmitMode mode, EmitOpInfo c } } -void CLikeSourceEmitter::emitArgs(IRInst* inst, IREmitMode mode) +void CLikeSourceEmitter::emitArgs(IRInst* inst) { UInt argCount = inst->getOperandCount(); IRUse* args = inst->getOperands(); @@ -961,7 +952,7 @@ void CLikeSourceEmitter::emitArgs(IRInst* inst, IREmitMode mode) for(UInt aa = 0; aa < argCount; ++aa) { if(aa != 0) m_writer->emit(", "); - emitOperand(args[aa].get(), mode, getInfo(EmitOp::General)); + emitOperand(args[aa].get(), getInfo(EmitOp::General)); } m_writer->emit(")"); } @@ -987,6 +978,12 @@ void CLikeSourceEmitter::emitInstResultDecl(IRInst* inst) emitRateQualifiers(inst); + if(as(inst->getParent())) + { + // "Ordinary" instructions at module scope are constants + m_writer->emit("static const "); + } + emitType(type, getName(inst)); m_writer->emit(" = "); } @@ -1027,8 +1024,7 @@ void CLikeSourceEmitter::emitTargetIntrinsicCallExpr( IRCall* inst, IRFunc* /* func */, IRTargetIntrinsicDecoration* targetIntrinsic, - IREmitMode mode, - EmitOpInfo const& inOuterPrec) + EmitOpInfo const& inOuterPrec) { auto outerPrec = inOuterPrec; @@ -1052,7 +1048,7 @@ void CLikeSourceEmitter::emitTargetIntrinsicCallExpr( for (Index aa = 0; aa < argCount; ++aa) { if (aa != 0) m_writer->emit(", "); - emitOperand(args[aa].get(), mode, getInfo(EmitOp::General)); + emitOperand(args[aa].get(), getInfo(EmitOp::General)); } m_writer->emit(")"); @@ -1099,7 +1095,7 @@ void CLikeSourceEmitter::emitTargetIntrinsicCallExpr( Index argIndex = d - '0'; SLANG_RELEASE_ASSERT((0 <= argIndex) && (argIndex < argCount)); m_writer->emit("("); - emitOperand(args[argIndex].get(), mode, getInfo(EmitOp::General)); + emitOperand(args[argIndex].get(), getInfo(EmitOp::General)); m_writer->emit(")"); } break; @@ -1127,9 +1123,9 @@ void CLikeSourceEmitter::emitTargetIntrinsicCallExpr( } m_writer->emit("("); - emitOperand(textureArg, mode, getInfo(EmitOp::General)); + emitOperand(textureArg, getInfo(EmitOp::General)); m_writer->emit(","); - emitOperand(samplerArg, mode, getInfo(EmitOp::General)); + emitOperand(samplerArg, getInfo(EmitOp::General)); m_writer->emit(")"); } else @@ -1258,7 +1254,7 @@ void CLikeSourceEmitter::emitTargetIntrinsicCallExpr( { // In the simple case, the operand is already a 4-vector, // so we can just emit it as-is. - emitOperand(arg, mode, getInfo(EmitOp::General)); + emitOperand(arg, getInfo(EmitOp::General)); } else { @@ -1268,7 +1264,7 @@ void CLikeSourceEmitter::emitTargetIntrinsicCallExpr( // emitVectorTypeName(elementType, 4); m_writer->emit("("); - emitOperand(arg, mode, getInfo(EmitOp::General)); + emitOperand(arg, getInfo(EmitOp::General)); for(IRIntegerValue ii = elementCount; ii < 4; ++ii) { m_writer->emit(", "); @@ -1338,7 +1334,7 @@ void CLikeSourceEmitter::emitTargetIntrinsicCallExpr( // to be broken out into its own argument. // m_writer->emit("("); - emitOperand(arg->getOperand(0), mode, getInfo(EmitOp::General)); + emitOperand(arg->getOperand(0), getInfo(EmitOp::General)); m_writer->emit("), "); // The coordinate argument will have been computed @@ -1373,20 +1369,20 @@ void CLikeSourceEmitter::emitTargetIntrinsicCallExpr( } m_writer->emit("("); - emitOperand(arg->getOperand(1), mode, getInfo(EmitOp::General)); + emitOperand(arg->getOperand(1), getInfo(EmitOp::General)); m_writer->emit(")"); } else { m_writer->emit("("); - emitOperand(arg, mode, getInfo(EmitOp::General)); + emitOperand(arg, getInfo(EmitOp::General)); m_writer->emit(")"); } } else { m_writer->emit("("); - emitOperand(arg, mode, getInfo(EmitOp::General)); + emitOperand(arg, getInfo(EmitOp::General)); m_writer->emit(")"); } } @@ -1475,10 +1471,9 @@ void CLikeSourceEmitter::emitTargetIntrinsicCallExpr( } void CLikeSourceEmitter::emitIntrinsicCallExpr( - IRCall* inst, - IRFunc* func, - IREmitMode mode, - EmitOpInfo const& inOuterPrec) + IRCall* inst, + IRFunc* func, + EmitOpInfo const& inOuterPrec) { auto outerPrec = inOuterPrec; bool needClose = false; @@ -1498,7 +1493,6 @@ void CLikeSourceEmitter::emitIntrinsicCallExpr( inst, func, targetIntrinsicDecoration, - mode, outerPrec); return; } @@ -1557,15 +1551,15 @@ void CLikeSourceEmitter::emitIntrinsicCallExpr( auto prec = getInfo(EmitOp::Postfix); needClose = maybeEmitParens(outerPrec, prec); - emitOperand(inst->getOperand(operandIndex++), mode, leftSide(outerPrec, prec)); + emitOperand(inst->getOperand(operandIndex++), leftSide(outerPrec, prec)); m_writer->emit("["); - emitOperand(inst->getOperand(operandIndex++), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(operandIndex++), getInfo(EmitOp::General)); m_writer->emit("]"); if(operandIndex < operandCount) { m_writer->emit(" = "); - emitOperand(inst->getOperand(operandIndex++), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(operandIndex++), getInfo(EmitOp::General)); } maybeCloseParens(needClose); @@ -1585,7 +1579,7 @@ void CLikeSourceEmitter::emitIntrinsicCallExpr( if(argCount != paramCount) { // Looks like a member function call - emitOperand(inst->getOperand(operandIndex), mode, leftSide(outerPrec, prec)); + emitOperand(inst->getOperand(operandIndex), leftSide(outerPrec, prec)); m_writer->emit("."); operandIndex++; } @@ -1612,7 +1606,7 @@ void CLikeSourceEmitter::emitIntrinsicCallExpr( for(; operandIndex < operandCount; ++operandIndex ) { if(!first) m_writer->emit(", "); - emitOperand(inst->getOperand(operandIndex), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(operandIndex), getInfo(EmitOp::General)); first = false; } m_writer->emit(")"); @@ -1621,7 +1615,7 @@ void CLikeSourceEmitter::emitIntrinsicCallExpr( maybeCloseParens(needClose); } -void CLikeSourceEmitter::emitCallExpr(IRCall* inst, IREmitMode mode, EmitOpInfo outerPrec) +void CLikeSourceEmitter::emitCallExpr(IRCall* inst, EmitOpInfo outerPrec) { auto funcValue = inst->getOperand(0); @@ -1632,14 +1626,14 @@ void CLikeSourceEmitter::emitCallExpr(IRCall* inst, IREmitMode mode, EmitOpInfo // that we can emit it directly without mangling, etc. if(auto irFunc = asTargetIntrinsic(funcValue)) { - emitIntrinsicCallExpr(inst, irFunc, mode, outerPrec); + emitIntrinsicCallExpr(inst, irFunc, outerPrec); } else { auto prec = getInfo(EmitOp::Postfix); bool needClose = maybeEmitParens(outerPrec, prec); - emitOperand(funcValue, mode, leftSide(outerPrec, prec)); + emitOperand(funcValue, leftSide(outerPrec, prec)); m_writer->emit("("); UInt argCount = inst->getOperandCount(); for( UInt aa = 1; aa < argCount; ++aa ) @@ -1648,7 +1642,7 @@ void CLikeSourceEmitter::emitCallExpr(IRCall* inst, IREmitMode mode, EmitOpInfo if (as(operand->getDataType())) continue; if(aa != 1) m_writer->emit(", "); - emitOperand(inst->getOperand(aa), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(aa), getInfo(EmitOp::General)); } m_writer->emit(")"); @@ -1656,17 +1650,17 @@ void CLikeSourceEmitter::emitCallExpr(IRCall* inst, IREmitMode mode, EmitOpInfo } } -void CLikeSourceEmitter::emitInstExpr(IRInst* inst, IREmitMode mode, const EmitOpInfo& inOuterPrec) +void CLikeSourceEmitter::emitInstExpr(IRInst* inst, const EmitOpInfo& inOuterPrec) { // Try target specific impl first - if (tryEmitInstExprImpl(inst, mode, inOuterPrec)) + if (tryEmitInstExprImpl(inst, inOuterPrec)) { return; } - defaultEmitInstExpr(inst, mode, inOuterPrec); + defaultEmitInstExpr(inst, inOuterPrec); } -void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, const EmitOpInfo& inOuterPrec) +void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inOuterPrec) { EmitOpInfo outerPrec = inOuterPrec; bool needClose = false; @@ -1683,7 +1677,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons case kIROp_MakeMatrix: // Simple constructor call emitType(inst->getDataType()); - emitArgs(inst, mode); + emitArgs(inst); break; case kIROp_constructVectorFromScalar: @@ -1696,7 +1690,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons emitType(inst->getDataType()); m_writer->emit(")"); - emitOperand(inst->getOperand(0), mode, rightSide(outerPrec,prec)); + emitOperand(inst->getOperand(0), rightSide(outerPrec,prec)); break; } case kIROp_FieldExtract: @@ -1708,7 +1702,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons needClose = maybeEmitParens(outerPrec, prec); auto base = fieldExtract->getBase(); - emitOperand(base, mode, leftSide(outerPrec, prec)); + emitOperand(base, leftSide(outerPrec, prec)); m_writer->emit("."); if(getSourceStyle() == SourceStyle::GLSL && as(base->getDataType())) @@ -1728,7 +1722,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons needClose = maybeEmitParens(outerPrec, prec); auto base = ii->getBase(); - emitOperand(base, mode, leftSide(outerPrec, prec)); + emitOperand(base, leftSide(outerPrec, prec)); m_writer->emit("."); if(getSourceStyle() == SourceStyle::GLSL && as(base->getDataType())) @@ -1752,11 +1746,11 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons auto prec = getInfo(emitOp); needClose = maybeEmitParens(outerPrec, prec); - emitOperand(inst->getOperand(0), mode, leftSide(outerPrec, prec)); + emitOperand(inst->getOperand(0), leftSide(outerPrec, prec)); m_writer->emit(" "); m_writer->emit(prec.op); m_writer->emit(" "); - emitOperand(inst->getOperand(1), mode, rightSide(outerPrec, prec)); + emitOperand(inst->getOperand(1), rightSide(outerPrec, prec)); break; } @@ -1778,11 +1772,11 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons const auto info = getInfo(emitOp); needClose = maybeEmitParens(outerPrec, info); - emitOperand(inst->getOperand(0), mode, leftSide(outerPrec, info)); + emitOperand(inst->getOperand(0), leftSide(outerPrec, info)); m_writer->emit(" "); m_writer->emit(info.op); m_writer->emit(" "); - emitOperand(inst->getOperand(1), mode, rightSide(outerPrec, info)); + emitOperand(inst->getOperand(1), rightSide(outerPrec, info)); break; } // Unary @@ -1807,13 +1801,13 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons m_writer->emit(prec.op); } - emitOperand(operand, mode, rightSide(prec, outerPrec)); + emitOperand(operand, rightSide(prec, outerPrec)); break; } case kIROp_Load: { auto base = inst->getOperand(0); - emitOperand(base, mode, outerPrec); + emitOperand(base, outerPrec); if(getSourceStyle() == SourceStyle::GLSL && as(base->getDataType())) { @@ -1827,15 +1821,15 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons auto prec = getInfo(EmitOp::Assign); needClose = maybeEmitParens(outerPrec, prec); - emitOperand(inst->getOperand(0), mode, leftSide(outerPrec, prec)); + emitOperand(inst->getOperand(0), leftSide(outerPrec, prec)); m_writer->emit(" = "); - emitOperand(inst->getOperand(1), mode, rightSide(prec, outerPrec)); + emitOperand(inst->getOperand(1), rightSide(prec, outerPrec)); } break; case kIROp_Call: { - emitCallExpr((IRCall*)inst, mode, outerPrec); + emitCallExpr((IRCall*)inst, outerPrec); } break; @@ -1854,9 +1848,9 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons m_writer->emit(decoration->getOuterArrayName()); m_writer->emit("["); - emitOperand(inst->getOperand(1), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(1), getInfo(EmitOp::General)); m_writer->emit("]."); - emitOperand(inst->getOperand(0), mode, rightSide(prec, outerPrec)); + emitOperand(inst->getOperand(0), rightSide(prec, outerPrec)); break; } else @@ -1864,9 +1858,9 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons auto prec = getInfo(EmitOp::Postfix); needClose = maybeEmitParens(outerPrec, prec); - emitOperand( inst->getOperand(0), mode, leftSide(outerPrec, prec)); + emitOperand( inst->getOperand(0), leftSide(outerPrec, prec)); m_writer->emit("["); - emitOperand(inst->getOperand(1), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(1), getInfo(EmitOp::General)); m_writer->emit("]"); } break; @@ -1876,9 +1870,9 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons case kIROp_Mul_Matrix_Matrix: // Default impl m_writer->emit("mul("); - emitOperand(inst->getOperand(0), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(0), getInfo(EmitOp::General)); m_writer->emit(", "); - emitOperand(inst->getOperand(1), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(1), getInfo(EmitOp::General)); m_writer->emit(")"); break; @@ -1888,7 +1882,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons needClose = maybeEmitParens(outerPrec, prec); auto ii = (IRSwizzle*)inst; - emitOperand(ii->getBase(), mode, leftSide(outerPrec, prec)); + emitOperand(ii->getBase(), leftSide(outerPrec, prec)); m_writer->emit("."); const Index elementCount = Index(ii->getElementCount()); for (Index ee = 0; ee < elementCount; ++ee) @@ -1908,7 +1902,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons case kIROp_Specialize: { - emitOperand(inst->getOperand(0), mode, outerPrec); + emitOperand(inst->getOperand(0), outerPrec); } break; @@ -1918,11 +1912,11 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons auto prec = getInfo(EmitOp::Conditional); needClose = maybeEmitParens(outerPrec, prec); - emitOperand(inst->getOperand(0), mode, leftSide(outerPrec, prec)); + emitOperand(inst->getOperand(0), leftSide(outerPrec, prec)); m_writer->emit(" ? "); - emitOperand(inst->getOperand(1), mode, prec); + emitOperand(inst->getOperand(1), prec); m_writer->emit(" : "); - emitOperand(inst->getOperand(2), mode, rightSide(prec, outerPrec)); + emitOperand(inst->getOperand(2), rightSide(prec, outerPrec)); } break; @@ -1942,7 +1936,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons for (UInt aa = 0; aa < argCount; ++aa) { if (aa != 0) m_writer->emit(", "); - emitOperand(inst->getOperand(aa), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(aa), getInfo(EmitOp::General)); } m_writer->emit(" }"); } @@ -1961,7 +1955,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, cons // auto fromType = extractBaseType(inst->getOperand(0)->getDataType()); m_writer->emit("("); - emitOperand(inst->getOperand(0), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(0), getInfo(EmitOp::General)); m_writer->emit(")"); } break; @@ -1994,11 +1988,11 @@ BaseType CLikeSourceEmitter::extractBaseType(IRType* inType) } } -void CLikeSourceEmitter::emitInst(IRInst* inst, IREmitMode mode) +void CLikeSourceEmitter::emitInst(IRInst* inst) { try { - _emitInst(inst, mode); + _emitInst(inst); } // Don't emit any context message for an explicit `AbortCompilationException` // because it should only happen when an error is already emitted. @@ -2010,9 +2004,9 @@ void CLikeSourceEmitter::emitInst(IRInst* inst, IREmitMode mode) } } -void CLikeSourceEmitter::_emitInst(IRInst* inst, IREmitMode mode) +void CLikeSourceEmitter::_emitInst(IRInst* inst) { - if (shouldFoldInstIntoUseSites(inst, mode)) + if (shouldFoldInstIntoUseSites(inst)) { return; } @@ -2023,7 +2017,7 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst, IREmitMode mode) { default: emitInstResultDecl(inst); - emitInstExpr(inst, mode, getInfo(EmitOp::General)); + emitInstExpr(inst, getInfo(EmitOp::General)); m_writer->emit(";\n"); break; @@ -2062,7 +2056,7 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst, IREmitMode mode) case kIROp_ReturnVal: m_writer->emit("return "); - emitOperand(((IRReturnVal*) inst)->getVal(), mode, getInfo(EmitOp::General)); + emitOperand(((IRReturnVal*) inst)->getVal(), getInfo(EmitOp::General)); m_writer->emit(";\n"); break; @@ -2074,14 +2068,14 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst, IREmitMode mode) { auto ii = (IRSwizzleSet*)inst; emitInstResultDecl(inst); - emitOperand(inst->getOperand(0), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(0), getInfo(EmitOp::General)); m_writer->emit(";\n"); auto subscriptOuter = getInfo(EmitOp::General); auto subscriptPrec = getInfo(EmitOp::Postfix); bool needCloseSubscript = maybeEmitParens(subscriptOuter, subscriptPrec); - emitOperand(inst, mode, leftSide(subscriptOuter, subscriptPrec)); + emitOperand(inst, leftSide(subscriptOuter, subscriptPrec)); m_writer->emit("."); UInt elementCount = ii->getElementCount(); for (UInt ee = 0; ee < elementCount; ++ee) @@ -2099,7 +2093,7 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst, IREmitMode mode) maybeCloseParens(needCloseSubscript); m_writer->emit(" = "); - emitOperand(inst->getOperand(1), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(1), getInfo(EmitOp::General)); m_writer->emit(";\n"); } break; @@ -2112,7 +2106,7 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst, IREmitMode mode) auto ii = cast(inst); - emitOperand(ii->getDest(), mode, leftSide(subscriptOuter, subscriptPrec)); + emitOperand(ii->getDest(), leftSide(subscriptOuter, subscriptPrec)); m_writer->emit("."); UInt elementCount = ii->getElementCount(); for (UInt ee = 0; ee < elementCount; ++ee) @@ -2130,7 +2124,7 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst, IREmitMode mode) maybeCloseParens(needCloseSubscript); m_writer->emit(" = "); - emitOperand(ii->getSource(), mode, getInfo(EmitOp::General)); + emitOperand(ii->getSource(), getInfo(EmitOp::General)); m_writer->emit(";\n"); } break; @@ -2187,9 +2181,9 @@ void CLikeSourceEmitter::emitPhiVarAssignments(UInt argCount, IRUse* args, IRBlo auto outerPrec = getInfo(EmitOp::General); auto prec = getInfo(EmitOp::Assign); - emitOperand(pp, IREmitMode::Default, leftSide(outerPrec, prec)); + emitOperand(pp, leftSide(outerPrec, prec)); m_writer->emit(" = "); - emitOperand(arg, IREmitMode::Default, rightSide(prec, outerPrec)); + emitOperand(arg, rightSide(prec, outerPrec)); m_writer->emit(";\n"); } } @@ -2219,7 +2213,7 @@ void CLikeSourceEmitter::emitRegion(Region* inRegion) auto terminator = block->getTerminator(); for (auto inst = block->getFirstInst(); inst != terminator; inst = inst->getNextInst()) { - emitInst(inst, IREmitMode::Default); + emitInst(inst); } // Next we have to deal with the terminator instruction @@ -2242,7 +2236,7 @@ void CLikeSourceEmitter::emitRegion(Region* inRegion) // For extremely simple terminators, we just handle // them here, so that we don't have to allocate // separate `Region`s for them. - emitInst(terminator, IREmitMode::Default); + emitInst(terminator); break; // We will also handle any unconditional branches @@ -2315,7 +2309,7 @@ void CLikeSourceEmitter::emitRegion(Region* inRegion) // instead of the current `if(condition) {} else { elseRegion }` m_writer->emit("if("); - emitOperand(ifRegion->condition, IREmitMode::Default, getInfo(EmitOp::General)); + emitOperand(ifRegion->condition, getInfo(EmitOp::General)); m_writer->emit(")\n{\n"); m_writer->indent(); emitRegion(ifRegion->thenRegion); @@ -2389,7 +2383,7 @@ void CLikeSourceEmitter::emitRegion(Region* inRegion) // Emit the start of our statement. m_writer->emit("switch("); - emitOperand(switchRegion->condition, IREmitMode::Default, getInfo(EmitOp::General)); + emitOperand(switchRegion->condition, getInfo(EmitOp::General)); m_writer->emit(")\n{\n"); auto defaultCase = switchRegion->defaultCase; @@ -2398,7 +2392,7 @@ void CLikeSourceEmitter::emitRegion(Region* inRegion) for(auto caseVal : currentCase->values) { m_writer->emit("case "); - emitOperand(caseVal, IREmitMode::Default, getInfo(EmitOp::General)); + emitOperand(caseVal, getInfo(EmitOp::General)); m_writer->emit(":\n"); } if(currentCase.Ptr() == defaultCase) @@ -3074,60 +3068,6 @@ void CLikeSourceEmitter::emitGlobalParam(IRGlobalParam* varDecl) m_writer->emit(";\n\n"); } - -void CLikeSourceEmitter::emitGlobalConstantInitializer(IRGlobalConstant* valDecl) -{ - // We expect to see only a single block - auto block = valDecl->getFirstBlock(); - SLANG_RELEASE_ASSERT(block); - SLANG_RELEASE_ASSERT(!block->getNextBlock()); - - // We expect the terminator to be a `return` - // instruction with a value. - auto returnInst = (IRReturnVal*) block->getLastDecorationOrChild(); - SLANG_RELEASE_ASSERT(returnInst->op == kIROp_ReturnVal); - - // We will emit the value in the `GlobalConstant` mode, which - // more or less says to fold all instructions into their use - // sites, so that we end up with a single expression tree even - // in cases that would otherwise trip up our analysis. - // - // Note: We are emitting the value as an *operand* here instead - // of directly calling `emitIRInstExpr` because we need to handle - // cases where the value might *need* to emit as a named referenced - // (e.g., when it names another constant directly). - // - emitOperand(returnInst->getVal(), IREmitMode::GlobalConstant, getInfo(EmitOp::General)); -} - -void CLikeSourceEmitter::emitGlobalConstant(IRGlobalConstant* valDecl) -{ - auto valType = valDecl->getDataType(); - - if( getSourceStyle() != SourceStyle::GLSL ) - { - m_writer->emit("static "); - } - m_writer->emit("const "); - emitRateQualifiers(valDecl); - emitType(valType, getName(valDecl)); - - if (valDecl->getFirstBlock()) - { - // There is an initializer (which we expect for - // any global constant...). - - m_writer->emit(" = "); - - // We need to emit the entire initializer as - // a single expression. - emitGlobalConstantInitializer(valDecl); - } - - - m_writer->emit(";\n"); -} - void CLikeSourceEmitter::emitGlobalInst(IRInst* inst) { m_writer->advanceToSourceLocation(inst->sourceLoc); @@ -3146,10 +3086,6 @@ void CLikeSourceEmitter::emitGlobalInst(IRInst* inst) emitGlobalParam((IRGlobalParam*) inst); break; - case kIROp_GlobalConstant: - emitGlobalConstant((IRGlobalConstant*) inst); - break; - case kIROp_Var: emitVar((IRVar*) inst); break; @@ -3159,6 +3095,14 @@ void CLikeSourceEmitter::emitGlobalInst(IRInst* inst) break; default: + // We have an "ordinary" instruction at the global + // scope, and we should therefore emit it using the + // rules for other ordinary instructions. + // + // Such an instruction represents (part of) the value + // for a global constants. + // + emitInst(inst); break; } } diff --git a/source/slang/slang-emit-c-like.h b/source/slang/slang-emit-c-like.h index e33b704a9..926a67e31 100644 --- a/source/slang/slang-emit-c-like.h +++ b/source/slang/slang-emit-c-like.h @@ -63,13 +63,6 @@ public: kESemanticMask_Default = kESemanticMask_NoPackOffset, }; - // Hack to allow IR emit for global constant to override behavior - enum class IREmitMode - { - Default, - GlobalConstant, - }; - struct IRDeclaratorInfo; struct EDeclarator; struct ComputeEmitActionsContext; @@ -184,11 +177,11 @@ public: void emitDeclarator(IRDeclaratorInfo* declarator); void emitSimpleValue(IRInst* inst); - bool shouldFoldInstIntoUseSites(IRInst* inst, IREmitMode mode); + bool shouldFoldInstIntoUseSites(IRInst* inst); - void emitOperand(IRInst* inst, IREmitMode mode, EmitOpInfo const& outerPrec); + void emitOperand(IRInst* inst, EmitOpInfo const& outerPrec); - void emitArgs(IRInst* inst, IREmitMode mode); + void emitArgs(IRInst* inst); void emitRateQualifiers(IRInst* value); @@ -206,23 +199,21 @@ public: IRCall* inst, IRFunc* /* func */, IRTargetIntrinsicDecoration* targetIntrinsic, - IREmitMode mode, - EmitOpInfo const& inOuterPrec); + EmitOpInfo const& inOuterPrec); void emitIntrinsicCallExpr( - IRCall* inst, - IRFunc* func, - IREmitMode mode, - EmitOpInfo const& inOuterPrec); + IRCall* inst, + IRFunc* func, + EmitOpInfo const& inOuterPrec); - void emitCallExpr(IRCall* inst, IREmitMode mode, EmitOpInfo outerPrec); + void emitCallExpr(IRCall* inst, EmitOpInfo outerPrec); - void emitInstExpr(IRInst* inst, IREmitMode mode, EmitOpInfo const& inOuterPrec); - void defaultEmitInstExpr(IRInst* inst, IREmitMode mode, EmitOpInfo const& inOuterPrec); + void emitInstExpr(IRInst* inst, EmitOpInfo const& inOuterPrec); + void defaultEmitInstExpr(IRInst* inst, EmitOpInfo const& inOuterPrec); BaseType extractBaseType(IRType* inType); - void emitInst(IRInst* inst, IREmitMode mode); + void emitInst(IRInst* inst); void emitSemantics(VarLayout* varLayout); void emitSemantics(IRInst* inst); @@ -302,9 +293,6 @@ public: void emitGlobalVar(IRGlobalVar* varDecl); void emitGlobalParam(IRGlobalParam* varDecl); - void emitGlobalConstantInitializer(IRGlobalConstant* valDecl); - - void emitGlobalConstant(IRGlobalConstant* valDecl); void emitGlobalInst(IRInst* inst); @@ -356,12 +344,12 @@ public: virtual void handleCallExprDecorationsImpl(IRInst* funcValue) { SLANG_UNUSED(funcValue); } virtual bool tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* varType) { SLANG_UNUSED(varDecl); SLANG_UNUSED(varType); return false; } - virtual bool tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const EmitOpInfo& inOuterPrec) { SLANG_UNUSED(inst); SLANG_UNUSED(mode); SLANG_UNUSED(inOuterPrec); return false; } + virtual bool tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) { SLANG_UNUSED(inst); SLANG_UNUSED(inOuterPrec); return false; } void _emitArrayType(IRArrayType* arrayType, EDeclarator* declarator); void _emitUnsizedArrayType(IRUnsizedArrayType* arrayType, EDeclarator* declarator); void _emitType(IRType* type, EDeclarator* declarator); - void _emitInst(IRInst* inst, IREmitMode mode); + void _emitInst(IRInst* inst); BackEndCompileRequest* m_compileRequest = nullptr; diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index 354a2d856..d039715e3 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -1076,7 +1076,7 @@ CPPSourceEmitter::SpecializedIntrinsic CPPSourceEmitter::getSpecializedOperation return specOp; } -void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst, const IRUse* operands, int numOperands, CLikeSourceEmitter::IREmitMode mode, const EmitOpInfo& inOuterPrec) +void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst, const IRUse* operands, int numOperands, const EmitOpInfo& inOuterPrec) { SLANG_UNUSED(inOuterPrec); SourceWriter* writer = getSourceWriter(); @@ -1107,7 +1107,7 @@ void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst { writer->emit(", "); } - emitOperand(operands[i].get(), mode, getInfo(EmitOp::General)); + emitOperand(operands[i].get(), getInfo(EmitOp::General)); } writer->emitChar('}'); @@ -1131,7 +1131,7 @@ void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst { writer->emit(", "); } - emitOperand(operands[j].get(), mode, getInfo(EmitOp::General)); + emitOperand(operands[j].get(), getInfo(EmitOp::General)); } writer->emitChar('}'); @@ -1146,7 +1146,7 @@ void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst writer->emit(getBuiltinTypeName(retType->op)); writer->emitChar('('); - emitOperand(operands[0].get(), mode, getInfo(EmitOp::General)); + emitOperand(operands[0].get(), getInfo(EmitOp::General)); writer->emitChar(')'); break; @@ -1166,7 +1166,7 @@ void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst if (elementCount == 1) { - defaultEmitInstExpr(inst, mode, inOuterPrec); + defaultEmitInstExpr(inst, inOuterPrec); } else { @@ -1185,7 +1185,7 @@ void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst auto outerPrec = getInfo(EmitOp::General); auto prec = getInfo(EmitOp::Postfix); - emitOperand(swizzleInst->getBase(), mode, leftSide(outerPrec, prec)); + emitOperand(swizzleInst->getBase(), leftSide(outerPrec, prec)); writer->emit("."); @@ -1217,7 +1217,7 @@ void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst if (isOperator) { // Just do the default output - defaultEmitInstExpr(inst, mode, inOuterPrec); + defaultEmitInstExpr(inst, inOuterPrec); } else { @@ -1230,7 +1230,7 @@ void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst { writer->emit(", "); } - emitOperand(operands[i].get(), mode, getInfo(EmitOp::General)); + emitOperand(operands[i].get(), getInfo(EmitOp::General)); } writer->emitChar(')'); @@ -1290,7 +1290,7 @@ StringSlicePool::Handle CPPSourceEmitter::_calcFuncName(const SpecializedIntrins } } -void CPPSourceEmitter::emitOperationCall(IntrinsicOp op, IRInst* inst, IRUse* operands, int operandCount, IRType* retType, CLikeSourceEmitter::IREmitMode mode, const EmitOpInfo& inOuterPrec) +void CPPSourceEmitter::emitOperationCall(IntrinsicOp op, IRInst* inst, IRUse* operands, int operandCount, IRType* retType, const EmitOpInfo& inOuterPrec) { if (operandCount > 8) { @@ -1302,7 +1302,7 @@ void CPPSourceEmitter::emitOperationCall(IntrinsicOp op, IRInst* inst, IRUse* op argTypes[i] = operands[i].get()->getDataType(); } SpecializedIntrinsic specOp = getSpecializedOperation(op, argTypes.getBuffer(), operandCount, retType); - emitCall(specOp, inst, operands, operandCount, mode, inOuterPrec); + emitCall(specOp, inst, operands, operandCount, inOuterPrec); } else { @@ -1313,7 +1313,7 @@ void CPPSourceEmitter::emitOperationCall(IntrinsicOp op, IRInst* inst, IRUse* op argTypes[i] = operands[i].get()->getDataType(); } SpecializedIntrinsic specOp = getSpecializedOperation(op, argTypes, operandCount, retType); - emitCall(specOp, inst, operands, operandCount, mode, inOuterPrec); + emitCall(specOp, inst, operands, operandCount, inOuterPrec); } } @@ -1426,7 +1426,7 @@ void CPPSourceEmitter::emitTypeImpl(IRType* type, const StringSliceLoc* nameLoc) } } -void CPPSourceEmitter::emitIntrinsicCallExpr(IRCall* inst, IRFunc* func, IREmitMode mode, EmitOpInfo const& inOuterPrec) +void CPPSourceEmitter::emitIntrinsicCallExpr(IRCall* inst, IRFunc* func, EmitOpInfo const& inOuterPrec) { auto outerPrec = inOuterPrec; bool needClose = false; @@ -1492,15 +1492,15 @@ void CPPSourceEmitter::emitIntrinsicCallExpr(IRCall* inst, IRFunc* func, IREmitM auto prec = getInfo(EmitOp::Postfix); needClose = maybeEmitParens(outerPrec, prec); - emitOperand(inst->getOperand(operandIndex++), mode, leftSide(outerPrec, prec)); + emitOperand(inst->getOperand(operandIndex++), leftSide(outerPrec, prec)); m_writer->emit("["); - emitOperand(inst->getOperand(operandIndex++), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(operandIndex++), getInfo(EmitOp::General)); m_writer->emit("]"); if (operandIndex < operandCount) { m_writer->emit(" = "); - emitOperand(inst->getOperand(operandIndex++), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(operandIndex++), getInfo(EmitOp::General)); } maybeCloseParens(needClose); @@ -1520,7 +1520,7 @@ void CPPSourceEmitter::emitIntrinsicCallExpr(IRCall* inst, IRFunc* func, IREmitM if (argCount != paramCount) { // Looks like a member function call - emitOperand(inst->getOperand(operandIndex), mode, leftSide(outerPrec, prec)); + emitOperand(inst->getOperand(operandIndex), leftSide(outerPrec, prec)); m_writer->emit("."); operandIndex++; } @@ -1530,7 +1530,7 @@ void CPPSourceEmitter::emitIntrinsicCallExpr(IRCall* inst, IRFunc* func, IREmitM if (op != IntrinsicOp::Invalid) { IRUse* operands = inst->getOperands() + operandIndex; - emitOperationCall(op, inst, operands, int(operandCount - operandIndex), inst->getDataType(), mode, inOuterPrec); + emitOperationCall(op, inst, operands, int(operandCount - operandIndex), inst->getDataType(), inOuterPrec); return; } } @@ -1541,14 +1541,14 @@ void CPPSourceEmitter::emitIntrinsicCallExpr(IRCall* inst, IRFunc* func, IREmitM for (; operandIndex < operandCount; ++operandIndex) { if (!first) m_writer->emit(", "); - emitOperand(inst->getOperand(operandIndex), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(operandIndex), getInfo(EmitOp::General)); first = false; } m_writer->emit(")"); maybeCloseParens(needClose); } -bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const EmitOpInfo& inOuterPrec) +bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) { SLANG_UNUSED(inOuterPrec); @@ -1558,24 +1558,24 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const case kIROp_makeVector: case kIROp_MakeMatrix: { - emitOperationCall(IntrinsicOp::Init, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), mode, inOuterPrec); + emitOperationCall(IntrinsicOp::Init, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), inOuterPrec); return true; } case kIROp_Mul_Matrix_Matrix: case kIROp_Mul_Matrix_Vector: case kIROp_Mul_Vector_Matrix: { - emitOperationCall(IntrinsicOp::VecMatMul, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), mode, inOuterPrec); + emitOperationCall(IntrinsicOp::VecMatMul, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), inOuterPrec); return true; } case kIROp_Dot: { - emitOperationCall(IntrinsicOp::Dot, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), mode, inOuterPrec); + emitOperationCall(IntrinsicOp::Dot, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), inOuterPrec); return true; } case kIROp_swizzle: { - emitOperationCall(IntrinsicOp::Swizzle, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), mode, inOuterPrec); + emitOperationCall(IntrinsicOp::Swizzle, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), inOuterPrec); return true; } case kIROp_Call: @@ -1589,7 +1589,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const // that we can emit it directly without mangling, etc. if (auto irFunc = asTargetIntrinsic(funcValue)) { - emitIntrinsicCallExpr(static_cast(inst), irFunc, mode, inOuterPrec); + emitIntrinsicCallExpr(static_cast(inst), irFunc, inOuterPrec); return true; } @@ -1600,7 +1600,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const IntrinsicOp op = getOperation(inst->op); if (op != IntrinsicOp::Invalid) { - emitOperationCall(op, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), mode, inOuterPrec); + emitOperationCall(op, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), inOuterPrec); return true; } return false; diff --git a/source/slang/slang-emit-cpp.h b/source/slang/slang-emit-cpp.h index cd33dc431..ea793ee95 100644 --- a/source/slang/slang-emit-cpp.h +++ b/source/slang/slang-emit-cpp.h @@ -153,11 +153,11 @@ public: virtual SpecializedIntrinsic getSpecializedOperation(IntrinsicOp op, IRType*const* argTypes, int argTypesCount, IRType* retType); virtual void useType(IRType* type); - virtual void emitCall(const SpecializedIntrinsic& specOp, IRInst* inst, const IRUse* operands, int numOperands, CLikeSourceEmitter::IREmitMode mode, const EmitOpInfo& inOuterPrec); + virtual void emitCall(const SpecializedIntrinsic& specOp, IRInst* inst, const IRUse* operands, int numOperands, const EmitOpInfo& inOuterPrec); virtual void emitTypeDefinition(IRType* type); virtual void emitSpecializedOperationDefinition(const SpecializedIntrinsic& specOp); - void emitOperationCall(IntrinsicOp op, IRInst* inst, IRUse* operands, int operandCount, IRType* retType, CLikeSourceEmitter::IREmitMode mode, const EmitOpInfo& inOuterPrec); + void emitOperationCall(IntrinsicOp op, IRInst* inst, IRUse* operands, int operandCount, IRType* retType, const EmitOpInfo& inOuterPrec); static UnownedStringSlice getBuiltinTypeName(IROp op); @@ -179,10 +179,10 @@ protected: virtual void emitSimpleTypeImpl(IRType* type) SLANG_OVERRIDE; virtual void emitTypeImpl(IRType* type, const StringSliceLoc* nameLoc) SLANG_OVERRIDE; virtual void emitVectorTypeNameImpl(IRType* elementType, IRIntegerValue elementCount) SLANG_OVERRIDE; - virtual bool tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE; + virtual bool tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE; virtual void emitPreprocessorDirectivesImpl() SLANG_OVERRIDE; - void emitIntrinsicCallExpr(IRCall* inst, IRFunc* func, IREmitMode mode, EmitOpInfo const& inOuterPrec); + void emitIntrinsicCallExpr(IRCall* inst, IRFunc* func, EmitOpInfo const& inOuterPrec); void _emitVecMatMulDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp); diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index 85b0400eb..3b9023703 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -948,7 +948,7 @@ static const char* _getGLSLVectorCompareFunctionName(IROp op) } } -void GLSLSourceEmitter::_maybeEmitGLSLCast(IRType* castType, IRInst* inst, IREmitMode mode) +void GLSLSourceEmitter::_maybeEmitGLSLCast(IRType* castType, IRInst* inst) { // Wrap in cast if a cast type is specified if (castType) @@ -957,18 +957,18 @@ void GLSLSourceEmitter::_maybeEmitGLSLCast(IRType* castType, IRInst* inst, IREmi m_writer->emit("("); // Emit the operand - emitOperand(inst, mode, getInfo(EmitOp::General)); + emitOperand(inst, getInfo(EmitOp::General)); m_writer->emit(")"); } else { // Emit the operand - emitOperand(inst, mode, getInfo(EmitOp::General)); + emitOperand(inst, getInfo(EmitOp::General)); } } -bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const EmitOpInfo& inOuterPrec) +bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) { switch (inst->op) { @@ -983,7 +983,7 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const emitType(inst->getDataType()); m_writer->emit("("); - emitOperand(inst->getOperand(0), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(0), getInfo(EmitOp::General)); m_writer->emit(")"); maybeCloseParens(needClose); @@ -1001,9 +1001,9 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const && as(inst->getOperand(1)->getDataType())) { m_writer->emit("matrixCompMult("); - emitOperand(inst->getOperand(0), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(0), getInfo(EmitOp::General)); m_writer->emit(", "); - emitOperand(inst->getOperand(1), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(1), getInfo(EmitOp::General)); m_writer->emit(")"); return true; } @@ -1027,9 +1027,9 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const auto prec = getInfo(EmitOp::Mul); needClose = maybeEmitParens(outerPrec, prec); - emitOperand(inst->getOperand(1), mode, leftSide(outerPrec, prec)); + emitOperand(inst->getOperand(1), leftSide(outerPrec, prec)); m_writer->emit(" * "); - emitOperand(inst->getOperand(0), mode, rightSide(prec, outerPrec)); + emitOperand(inst->getOperand(0), rightSide(prec, outerPrec)); maybeCloseParens(needClose); return true; @@ -1040,11 +1040,11 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const { // For GLSL, emit a call to `mix` if condition is a vector m_writer->emit("mix("); - emitOperand(inst->getOperand(2), mode, leftSide(getInfo(EmitOp::General), getInfo(EmitOp::General))); + emitOperand(inst->getOperand(2), leftSide(getInfo(EmitOp::General), getInfo(EmitOp::General))); m_writer->emit(", "); - emitOperand(inst->getOperand(1), mode, leftSide(getInfo(EmitOp::General), getInfo(EmitOp::General))); + emitOperand(inst->getOperand(1), leftSide(getInfo(EmitOp::General), getInfo(EmitOp::General))); m_writer->emit(", "); - emitOperand(inst->getOperand(0), mode, leftSide(getInfo(EmitOp::General), getInfo(EmitOp::General))); + emitOperand(inst->getOperand(0), leftSide(getInfo(EmitOp::General), getInfo(EmitOp::General))); m_writer->emit(")"); return true; } @@ -1072,7 +1072,7 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const } m_writer->emit("("); - emitOperand(inst->getOperand(0), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(0), getInfo(EmitOp::General)); m_writer->emit(")"); return true; @@ -1090,7 +1090,7 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const needClose = maybeEmitParens(outerPrec, prec); m_writer->emit("not("); - emitOperand(operand, mode, getInfo(EmitOp::General)); + emitOperand(operand, getInfo(EmitOp::General)); m_writer->emit(")"); maybeCloseParens(needClose); @@ -1116,9 +1116,9 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const // TODO: handle a bitwise Or of a vector of bools by casting to // a uvec and performing the bitwise operation - emitOperand(inst->getOperand(0), mode, leftSide(outerPrec, prec)); + emitOperand(inst->getOperand(0), leftSide(outerPrec, prec)); m_writer->emit(prec.op); - emitOperand(inst->getOperand(1), mode, rightSide(outerPrec, prec)); + emitOperand(inst->getOperand(1), rightSide(outerPrec, prec)); maybeCloseParens(needClose); return true; @@ -1158,9 +1158,9 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const m_writer->emit(funcName); m_writer->emit("("); - _maybeEmitGLSLCast((leftVectorType ? nullptr : vecType), left, mode); + _maybeEmitGLSLCast((leftVectorType ? nullptr : vecType), left); m_writer->emit(","); - _maybeEmitGLSLCast((rightVectorType ? nullptr : vecType), right, mode); + _maybeEmitGLSLCast((rightVectorType ? nullptr : vecType), right); m_writer->emit(")"); maybeCloseParens(needClose); diff --git a/source/slang/slang-emit-glsl.h b/source/slang/slang-emit-glsl.h index 6bcfd6c02..0451ec0b9 100644 --- a/source/slang/slang-emit-glsl.h +++ b/source/slang/slang-emit-glsl.h @@ -38,7 +38,7 @@ protected: virtual void handleCallExprDecorationsImpl(IRInst* funcValue) SLANG_OVERRIDE; virtual bool tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* varType) SLANG_OVERRIDE; - virtual bool tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE; + virtual bool tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE; void _emitGLSLTextureOrTextureSamplerType(IRTextureTypeBase* type, char const* baseName); void _emitGLSLStructuredBuffer(IRGlobalParam* varDecl, IRHLSLStructuredBufferTypeBase* structuredBufferType); @@ -63,7 +63,7 @@ protected: void _maybeEmitGLSLFlatModifier(IRType* valueType); void _requireHalf(); - void _maybeEmitGLSLCast(IRType* castType, IRInst* inst, IREmitMode mode); + void _maybeEmitGLSLCast(IRType* castType, IRInst* inst); }; } diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp index b4cebd3a3..9c0f7f02b 100644 --- a/source/slang/slang-emit-hlsl.cpp +++ b/source/slang/slang-emit-hlsl.cpp @@ -460,7 +460,7 @@ void HLSLSourceEmitter::emitEntryPointAttributesImpl(IRFunc* irFunc, EntryPointL _emitHLSLEntryPointAttributes(irFunc, entryPointLayout); } -bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const EmitOpInfo& inOuterPrec) +bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) { switch (inst->op) { @@ -480,7 +480,7 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const m_writer->emit("("); emitType(inst->getDataType()); m_writer->emit(") "); - emitOperand(inst->getOperand(0), mode, rightSide(outerPrec, prec)); + emitOperand(inst->getOperand(0), rightSide(outerPrec, prec)); maybeCloseParens(needClose); // Handled @@ -509,7 +509,7 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const } m_writer->emit("("); - emitOperand(inst->getOperand(0), mode, getInfo(EmitOp::General)); + emitOperand(inst->getOperand(0), getInfo(EmitOp::General)); m_writer->emit(")"); return true; } diff --git a/source/slang/slang-emit-hlsl.h b/source/slang/slang-emit-hlsl.h index 437ff57fd..6b4dfaa5c 100644 --- a/source/slang/slang-emit-hlsl.h +++ b/source/slang/slang-emit-hlsl.h @@ -31,7 +31,7 @@ protected: virtual void emitVarDecorationsImpl(IRInst* varDecl) SLANG_OVERRIDE; virtual void emitMatrixLayoutModifiersImpl(VarLayout* layout) SLANG_OVERRIDE; - virtual bool tryEmitInstExprImpl(IRInst* inst, IREmitMode mode, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE; + virtual bool tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE; // Emit a single `register` semantic, as appropriate for a given resource-type-specific layout info // Keyword to use in the uniform case (`register` for globals, `packoffset` inside a `cbuffer`) diff --git a/source/slang/slang-ir-constexpr.cpp b/source/slang/slang-ir-constexpr.cpp index f041d7ae6..d903ff880 100644 --- a/source/slang/slang-ir-constexpr.cpp +++ b/source/slang/slang-ir-constexpr.cpp @@ -502,7 +502,6 @@ void propagateConstExpr( case kIROp_Func: case kIROp_GlobalVar: - case kIROp_GlobalConstant: { IRGlobalValueWithCode* code = (IRGlobalValueWithCode*) gv; @@ -539,7 +538,6 @@ void propagateConstExpr( case kIROp_Func: case kIROp_GlobalVar: - case kIROp_GlobalConstant: { IRGlobalValueWithCode* code = (IRGlobalValueWithCode*) ii; validateConstExpr(&context, code); diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index abd677979..ed8bfeaa3 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -179,8 +179,7 @@ INST_RANGE(Type, VoidType, InterfaceType) INST_RANGE(GlobalValueWithParams, Func, Generic) INST(GlobalVar, global_var, 0, 0) - INST(GlobalConstant, global_constant, 0, 0) -INST_RANGE(GlobalValueWithCode, Func, GlobalConstant) +INST_RANGE(GlobalValueWithCode, Func, GlobalVar) INST(GlobalParam, global_param, 0, 0) diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index 4983bb97c..4704bb5a3 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -562,16 +562,18 @@ struct IRGlobalVar : IRGlobalValueWithCode } }; -/// @brief A global constant. +/// @brief A global shader parameter. +/// +/// Represents a uniform (as opposed to varying) shader parameter +/// passed at the global scope (entry-point `uniform` parameters +/// are encoded as ordinary function parameters. +/// +/// Note that an `IRGlobalParam` directly represents the value of +/// the parameter, unlike an `IRGlobalVar`, which represents the +/// *address* of the value. As a result, global parameters are +/// immutable, and subject to various SSA simplifications that +/// do not work for global variables. /// -/// Represents a global-scope constant value in the IR. -/// The initializer for the constant is represented by -/// the code in the basic block(s) nested in this value. -struct IRGlobalConstant : IRGlobalValueWithCode -{ - IR_LEAF_ISA(GlobalConstant) -}; - struct IRGlobalParam : IRInst { IR_LEAF_ISA(GlobalParam) @@ -957,8 +959,6 @@ struct IRBuilder IRFunc* createFunc(); IRGlobalVar* createGlobalVar( IRType* valueType); - IRGlobalConstant* createGlobalConstant( - IRType* valueType); IRGlobalParam* createGlobalParam( IRType* valueType); IRWitnessTable* createWitnessTable(); diff --git a/source/slang/slang-ir-legalize-types.cpp b/source/slang/slang-ir-legalize-types.cpp index 815afea72..8fab0fd09 100644 --- a/source/slang/slang-ir-legalize-types.cpp +++ b/source/slang/slang-ir-legalize-types.cpp @@ -1363,10 +1363,6 @@ static LegalVal legalizeGlobalVar( IRTypeLegalizationContext* context, IRGlobalVar* irGlobalVar); -static LegalVal legalizeGlobalConstant( - IRTypeLegalizationContext* context, - IRGlobalConstant* irGlobalConstant); - static LegalVal legalizeGlobalParam( IRTypeLegalizationContext* context, IRGlobalParam* irGlobalParam); @@ -1400,9 +1396,6 @@ static LegalVal legalizeInst( case kIROp_GlobalVar: return legalizeGlobalVar(context, cast(inst)); - case kIROp_GlobalConstant: - return legalizeGlobalConstant(context, cast(inst)); - case kIROp_GlobalParam: return legalizeGlobalParam(context, cast(inst)); @@ -1617,17 +1610,6 @@ static LegalVal declareSimpleVar( } break; - case kIROp_GlobalConstant: - { - auto globalConst = builder->createGlobalConstant(type); - globalConst->removeFromParent(); - globalConst->insertBefore(context->insertBeforeGlobal); - - irVar = globalConst; - legalVarVal = LegalVal::simple(globalConst); - } - break; - case kIROp_GlobalParam: { auto globalParam = builder->createGlobalParam(type); @@ -2412,50 +2394,6 @@ static LegalVal legalizeGlobalVar( } } -static LegalVal legalizeGlobalConstant( - IRTypeLegalizationContext* context, - IRGlobalConstant* irGlobalConstant) -{ - // Legalize the type for the variable's value - auto legalValueType = legalizeType( - context, - irGlobalConstant->getFullType()); - - switch (legalValueType.flavor) - { - case LegalType::Flavor::simple: - // Easy case: the type is usable as-is, and we - // should just do that. - irGlobalConstant->setFullType(legalValueType.getSimple()); - return LegalVal::simple(irGlobalConstant); - - default: - { - context->insertBeforeGlobal = irGlobalConstant->getNextInst(); - - IRGlobalNameInfo globalNameInfo; - globalNameInfo.globalVar = irGlobalConstant; - globalNameInfo.counter = 0; - - // TODO: need to handle initializer here! - - UnownedStringSlice nameHint = findNameHint(irGlobalConstant); - context->builder->setInsertBefore(irGlobalConstant); - LegalVal newVal = declareVars(context, kIROp_GlobalConstant, legalValueType, nullptr, LegalVarChain(), nameHint, irGlobalConstant, &globalNameInfo, context->isSpecialType(irGlobalConstant->getDataType())); - - // Register the new value as the replacement for the old - registerLegalizedValue(context, irGlobalConstant, newVal); - - // Remove the old global from the module. - irGlobalConstant->removeFromParent(); - context->replacedInstructions.add(irGlobalConstant); - - return newVal; - } - break; - } -} - static LegalVal legalizeGlobalParam( IRTypeLegalizationContext* context, IRGlobalParam* irGlobalParam) diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp index 07135c148..0ee068993 100644 --- a/source/slang/slang-ir-link.cpp +++ b/source/slang/slang-ir-link.cpp @@ -228,7 +228,6 @@ IRInst* IRSpecContext::maybeCloneValue(IRInst* originalValue) case kIROp_Func: case kIROp_Generic: case kIROp_GlobalVar: - case kIROp_GlobalConstant: case kIROp_GlobalParam: case kIROp_StructKey: case kIROp_GlobalGenericParam: @@ -388,26 +387,6 @@ IRGlobalVar* cloneGlobalVarImpl( return clonedVar; } -IRGlobalConstant* cloneGlobalConstantImpl( - IRSpecContextBase* context, - IRBuilder* builder, - IRGlobalConstant* originalVal, - IROriginalValuesForClone const& originalValues) -{ - auto clonedVal = builder->createGlobalConstant( - cloneType(context, originalVal->getFullType())); - registerClonedValue(context, clonedVal, originalValues); - - // Clone any code in the body of the constant, since this - // represents the initializer. - cloneGlobalValueWithCodeCommon( - context, - clonedVal, - originalVal); - - return clonedVal; -} - void cloneSimpleGlobalValueImpl( IRSpecContextBase* context, IRInst* originalInst, @@ -966,9 +945,6 @@ IRInst* cloneInst( case kIROp_GlobalVar: return cloneGlobalVarImpl(context, builder, cast(originalInst), originalValues); - case kIROp_GlobalConstant: - return cloneGlobalConstantImpl(context, builder, cast(originalInst), originalValues); - case kIROp_GlobalParam: return cloneGlobalParamImpl(context, builder, cast(originalInst), originalValues); diff --git a/source/slang/slang-ir-ssa.cpp b/source/slang/slang-ir-ssa.cpp index 9390b1e69..5f42702ce 100644 --- a/source/slang/slang-ir-ssa.cpp +++ b/source/slang/slang-ir-ssa.cpp @@ -1140,7 +1140,6 @@ void constructSSA(IRModule* module, IRInst* globalVal) { case kIROp_Func: case kIROp_GlobalVar: - case kIROp_GlobalConstant: constructSSA(module, (IRGlobalValueWithCode*)globalVal); default: diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index c5dd5d530..a718470ff 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -2258,18 +2258,6 @@ namespace Slang return globalVar; } - IRGlobalConstant* IRBuilder::createGlobalConstant( - IRType* valueType) - { - IRGlobalConstant* globalConstant = createInst( - this, - kIROp_GlobalConstant, - valueType); - maybeSetSourceLoc(this, globalConstant); - addGlobalValue(this, globalConstant); - return globalConstant; - } - IRGlobalParam* IRBuilder::createGlobalParam( IRType* valueType) { @@ -3712,7 +3700,6 @@ namespace Slang { case kIROp_Func: case kIROp_GlobalVar: - case kIROp_GlobalConstant: case kIROp_Generic: dumpIRGlobalValueWithCode(context, (IRGlobalValueWithCode*)inst); return; @@ -4298,7 +4285,6 @@ namespace Slang case kIROp_Func: case kIROp_Generic: case kIROp_GlobalVar: - case kIROp_GlobalConstant: case kIROp_GlobalParam: case kIROp_StructKey: case kIROp_GlobalGenericParam: @@ -4469,7 +4455,6 @@ namespace Slang switch (val->op) { case kIROp_WitnessTable: - case kIROp_GlobalConstant: case kIROp_Func: case kIROp_Generic: return val->getFirstChild() != nullptr; diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 8425b9664..5387688b6 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -4122,7 +4122,7 @@ struct DeclLoweringVisitor : DeclVisitor // NestedContext nested(this); auto subBuilder = nested.getBuilder(); - auto subContext = nested.getContet(); + auto subContext = nested.getContext(); IRGeneric* outerGeneric = emitOuterGenerics(subContext, decl, decl); // TODO: if a type alias declaration can have linkage, @@ -4323,7 +4323,7 @@ struct DeclLoweringVisitor : DeclVisitor // NestedContext nested(this); auto subBuilder = nested.getBuilder(); - auto subContext = nested.getContet(); + auto subContext = nested.getContext(); emitOuterGenerics(subContext, inheritanceDecl, inheritanceDecl); // Lower the super-type to force its declaration to be lowered. @@ -4461,31 +4461,85 @@ struct DeclLoweringVisitor : DeclVisitor return paramVal; } + LoweredValInfo lowerConstantDeclCommon(VarDeclBase* decl, IRGenContext* subContext) + { + auto initExpr = decl->initExpr; + if(!initExpr) + { + // TODO: what to do in this case? + return LoweredValInfo(); + } + + LoweredValInfo initVal = lowerRValueExpr(subContext, decl->initExpr); + + switch(initVal.flavor) + { + case LoweredValInfo::Flavor::Simple: + case LoweredValInfo::Flavor::Subscript: + { + // If the lowered value is a full instruction, + // then we will attach whatever extended information + // from the declaration that we can. + // + // TODO: We might want to introduce a distinct + // IR node to represent the constant, just with + // an operand for the value, and then simplify + // it away in later passes rather than handle + // things this way. + // + auto irInst = initVal.val; + addLinkageDecoration(context, irInst, decl); + addNameHint(context, irInst, decl); + addVarDecorations(context, irInst, decl); + getBuilder()->addHighLevelDeclDecoration(irInst, decl); + } + break; + + default: + break; + } + + // Register the value that was emitted as the value + // for any references to the constant from elsewhere + // in the code. + // + setGlobalValue(context, decl, initVal); + + return initVal; + } + + LoweredValInfo lowerGlobalConstantDecl(VarDecl* decl) + { + return lowerConstantDeclCommon(decl, context); + } + LoweredValInfo lowerGlobalVarDecl(VarDecl* decl) { + // A non-`static` global is actually a shader parameter in HLSL. + // + // TODO: We should probably make that case distinct at the AST + // level as well, since global shader parameters are fairly + // different from global variables. + // if(isGlobalShaderParameter(decl)) { return lowerGlobalShaderParam(decl); } + // A `static const` global is actually a compile-time constant. + // + if (decl->HasModifier() && decl->HasModifier()) + { + return lowerGlobalConstantDecl(decl); + } + IRType* varType = lowerType(context, decl->getType()); auto builder = getBuilder(); - IRGlobalValueWithCode* irGlobal = nullptr; - LoweredValInfo globalVal; + IRGlobalValueWithCode* irGlobal = builder->createGlobalVar(varType); + LoweredValInfo globalVal = LoweredValInfo::ptr(irGlobal); - // a `static const` global is actually a compile-time constant - if (decl->HasModifier() && decl->HasModifier()) - { - irGlobal = builder->createGlobalConstant(varType); - globalVal = LoweredValInfo::simple(irGlobal); - } - else - { - irGlobal = builder->createGlobalVar(varType); - globalVal = LoweredValInfo::ptr(irGlobal); - } addLinkageDecoration(context, irGlobal, decl); addNameHint(context, irGlobal, decl); @@ -4646,7 +4700,7 @@ struct DeclLoweringVisitor : DeclVisitor } IRBuilder* getBuilder() { return &subBuilderStorage; } - IRGenContext* getContet() { return &subContextStorage; } + IRGenContext* getContext() { return &subContextStorage; } }; LoweredValInfo lowerFunctionStaticConstVarDecl( @@ -4659,37 +4713,11 @@ struct DeclLoweringVisitor : DeclVisitor // NestedContext nestedContext(this); auto subBuilder = nestedContext.getBuilder(); - auto subContext = nestedContext.getContet(); + auto subContext = nestedContext.getContext(); subBuilder->setInsertInto(subBuilder->getFunc()->getParent()); - IRType* subVarType = lowerType(subContext, decl->getType()); - - IRGlobalConstant* irConstant = subBuilder->createGlobalConstant(subVarType); - addVarDecorations(subContext, irConstant, decl); - addNameHint(context, irConstant, decl); - maybeSetRate(context, irConstant, decl); - subBuilder->addHighLevelDeclDecoration(irConstant, decl); - - LoweredValInfo constantVal = LoweredValInfo::ptr(irConstant); - setValue(context, decl, constantVal); - - if( auto initExpr = decl->initExpr ) - { - NestedContext nestedInitContext(this); - auto initBuilder = nestedInitContext.getBuilder(); - auto initContext = nestedInitContext.getContet(); - - initBuilder->setInsertInto(irConstant); - - IRBlock* entryBlock = initBuilder->emitBlock(); - initBuilder->setInsertInto(entryBlock); - - LoweredValInfo initVal = lowerRValueExpr(initContext, initExpr); - initBuilder->emitReturn(getSimpleVal(initContext, initVal)); - } - - return constantVal; + return lowerConstantDeclCommon(decl, subContext); } LoweredValInfo lowerFunctionStaticVarDecl( @@ -4703,7 +4731,7 @@ struct DeclLoweringVisitor : DeclVisitor // of the outer declarations is generic. NestedContext nestedContext(this); auto subBuilder = nestedContext.getBuilder(); - auto subContext = nestedContext.getContet(); + auto subContext = nestedContext.getContext(); subBuilder->setInsertInto(subBuilder->getModule()->getModuleInst()); emitOuterGenerics(subContext, decl, decl); @@ -4773,7 +4801,7 @@ struct DeclLoweringVisitor : DeclVisitor // variable need to be generic as well! NestedContext nestedBoolContext(this); auto boolBuilder = nestedBoolContext.getBuilder(); - auto boolContext = nestedBoolContext.getContet(); + auto boolContext = nestedBoolContext.getContext(); boolBuilder->setInsertInto(boolBuilder->getModule()->getModuleInst()); emitOuterGenerics(boolContext, decl, decl); @@ -4909,7 +4937,7 @@ struct DeclLoweringVisitor : DeclVisitor NestedContext nestedContext(this); auto subBuilder = nestedContext.getBuilder(); - auto subContext = nestedContext.getContet(); + auto subContext = nestedContext.getContext(); // Emit any generics that should wrap the actual type. emitOuterGenerics(subContext, decl, decl); @@ -4940,7 +4968,7 @@ struct DeclLoweringVisitor : DeclVisitor // a function that constructs the value given arguments. // NestedContext nestedContext(this); - auto subContext = nestedContext.getContet(); + auto subContext = nestedContext.getContext(); // Emit any generics that should wrap the actual type. emitOuterGenerics(subContext, decl, decl); @@ -4960,7 +4988,7 @@ struct DeclLoweringVisitor : DeclVisitor NestedContext nestedContext(this); auto subBuilder = nestedContext.getBuilder(); - auto subContext = nestedContext.getContet(); + auto subContext = nestedContext.getContext(); emitOuterGenerics(subContext, decl, decl); // An `enum` declaration will currently lower directly to its "tag" @@ -4997,7 +5025,7 @@ struct DeclLoweringVisitor : DeclVisitor // NestedContext nestedContext(this); auto subBuilder = nestedContext.getBuilder(); - auto subContext = nestedContext.getContet(); + auto subContext = nestedContext.getContext(); // Emit any generics that should wrap the actual type. emitOuterGenerics(subContext, decl, decl); @@ -5527,7 +5555,7 @@ struct DeclLoweringVisitor : DeclVisitor // NestedContext nestedContext(this); auto subBuilder = nestedContext.getBuilder(); - auto subContext = nestedContext.getContet(); + auto subContext = nestedContext.getContext(); // The actual `IRFunction` that we emit needs to be nested // inside of one `IRGeneric` for every outer `GenericDecl` -- cgit v1.2.3