diff options
| -rw-r--r-- | .gitignore | 5 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 242 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.h | 38 | ||||
| -rw-r--r-- | source/slang/slang-emit-cpp.cpp | 50 | ||||
| -rw-r--r-- | source/slang/slang-emit-cpp.h | 8 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.cpp | 36 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.h | 4 | ||||
| -rw-r--r-- | source/slang/slang-emit-hlsl.cpp | 6 | ||||
| -rw-r--r-- | source/slang/slang-emit-hlsl.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-constexpr.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-inst-defs.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-ir-insts.h | 22 | ||||
| -rw-r--r-- | source/slang/slang-ir-legalize-types.cpp | 62 | ||||
| -rw-r--r-- | source/slang/slang-ir-link.cpp | 24 | ||||
| -rw-r--r-- | source/slang/slang-ir-ssa.cpp | 1 | ||||
| -rw-r--r-- | source/slang/slang-ir.cpp | 15 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 130 | ||||
| -rw-r--r-- | tests/compute/type-legalize-global-with-init.slang | 39 | ||||
| -rw-r--r-- | tests/compute/type-legalize-global-with-init.slang.expected.txt | 4 |
19 files changed, 298 insertions, 395 deletions
diff --git a/.gitignore b/.gitignore index 09133cdf1..0a20ce4b2 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,11 @@ build.*/ *.actual.png *.actual.txt +tests/**/*.exp +tests/**/*.lib +tests/**/*.dll +tests/**/*.cpp + # Files generated by other shader compilers *.spv 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<IRModuleInst>(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<IRVoidType>(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<IRUniformParameterGroupType>(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<IRUniformParameterGroupType>(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<IRUniformParameterGroupType>(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<IRSwizzledStore>(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<IRCall*>(inst), irFunc, mode, inOuterPrec); + emitIntrinsicCallExpr(static_cast<IRCall*>(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<IRMatrixType>(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<IRGlobalVar>(inst)); - case kIROp_GlobalConstant: - return legalizeGlobalConstant(context, cast<IRGlobalConstant>(inst)); - case kIROp_GlobalParam: return legalizeGlobalParam(context, cast<IRGlobalParam>(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<IRGlobalVar>(originalInst), originalValues); - case kIROp_GlobalConstant: - return cloneGlobalConstantImpl(context, builder, cast<IRGlobalConstant>(originalInst), originalValues); - case kIROp_GlobalParam: return cloneGlobalParamImpl(context, builder, cast<IRGlobalParam>(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<IRGlobalConstant>( - 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<DeclLoweringVisitor, LoweredValInfo> // 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<DeclLoweringVisitor, LoweredValInfo> // 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<DeclLoweringVisitor, LoweredValInfo> 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<HLSLStaticModifier>() && decl->HasModifier<ConstModifier>()) + { + 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<HLSLStaticModifier>() && decl->HasModifier<ConstModifier>()) - { - 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<DeclLoweringVisitor, LoweredValInfo> } IRBuilder* getBuilder() { return &subBuilderStorage; } - IRGenContext* getContet() { return &subContextStorage; } + IRGenContext* getContext() { return &subContextStorage; } }; LoweredValInfo lowerFunctionStaticConstVarDecl( @@ -4659,37 +4713,11 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> // 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<DeclLoweringVisitor, LoweredValInfo> // 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<DeclLoweringVisitor, LoweredValInfo> // 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<DeclLoweringVisitor, LoweredValInfo> 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<DeclLoweringVisitor, LoweredValInfo> // 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<DeclLoweringVisitor, LoweredValInfo> 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<DeclLoweringVisitor, LoweredValInfo> // 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<DeclLoweringVisitor, LoweredValInfo> // 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` diff --git a/tests/compute/type-legalize-global-with-init.slang b/tests/compute/type-legalize-global-with-init.slang new file mode 100644 index 000000000..0763fd897 --- /dev/null +++ b/tests/compute/type-legalize-global-with-init.slang @@ -0,0 +1,39 @@ +// type-legalize-global-with-init.slang +// +// Confirm that type legalization can handle a global constant +// with a resource type or a type that recursively contains +// resources. +// +//TEST(compute):COMPARE_COMPUTE: +// +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out +RWStructuredBuffer<uint> outputBuffer; + +//TEST_INPUT:ubuffer(data=[1 2 3 4 5 6 7 8], stride=4):dxbinding(1),glbinding(0) +RWStructuredBuffer<uint> inputBuffer; + +static const RWStructuredBuffer<uint> gBuffer = inputBuffer; + +struct Stuff +{ + RWStructuredBuffer<uint> a; + RWStructuredBuffer<uint> b; +} + +static const Stuff gStuff = { inputBuffer, inputBuffer }; + +uint test(uint x) +{ + return gBuffer[x] + + gStuff.a[x + 1] * 16 + + gStuff.b[x + 2] * 256; +} + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + let tid = dispatchThreadID.x; + let inVal = tid; + let outVal = test(inVal); + outputBuffer[tid] = outVal; +} diff --git a/tests/compute/type-legalize-global-with-init.slang.expected.txt b/tests/compute/type-legalize-global-with-init.slang.expected.txt new file mode 100644 index 000000000..893b7d009 --- /dev/null +++ b/tests/compute/type-legalize-global-with-init.slang.expected.txt @@ -0,0 +1,4 @@ +321 +432 +543 +654 |
