diff options
Diffstat (limited to 'source/slang/emit.cpp')
| -rw-r--r-- | source/slang/emit.cpp | 64 |
1 files changed, 49 insertions, 15 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 312e8c0b3..03c788ddb 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -2353,14 +2353,6 @@ struct EmitVisitor case kIROp_Param: return false; - // HACK: don't fold these in because we currently lower - // them to initializer lists, which aren't allowed in - // general expression contexts. - // - case kIROp_makeStruct: - case kIROp_makeArray: - return false; - // Always fold these in, because they are trivial // case kIROp_IntLit: @@ -2387,6 +2379,25 @@ struct EmitVisitor if (mode == IREmitMode::GlobalConstant) return true; + switch( inst->op ) + { + default: + break; + + // HACK: don't fold these in because we currently lower + // 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; + + } + // Instructions with specific result *types* will usually // want to be folded in, because they aren't allowed as types // for temporary variables. @@ -2539,9 +2550,25 @@ struct EmitVisitor { if( shouldFoldIRInstIntoUseSites(ctx, inst, mode) ) { - emit("("); - emitIRInstExpr(ctx, inst, mode); - emit(")"); + // HACK: Don't emit parentheses for cases that will + // wrap themsevles in `{}` to begin with. + // + // TODO: This shouldn't be needed once we are more + // systematic about not emitting redundant parentheses. + // + switch(inst->op) + { + case kIROp_makeArray: + case kIROp_makeStruct: + emitIRInstExpr(ctx, inst, mode); + break; + + default: + emit("("); + emitIRInstExpr(ctx, inst, mode); + emit(")"); + break; + } return; } @@ -5884,10 +5911,17 @@ struct EmitVisitor auto returnInst = (IRReturnVal*) block->getLastInst(); SLANG_RELEASE_ASSERT(returnInst->op == kIROp_ReturnVal); - // Now we want to emit the expression form of - // the value being returned, and force any - // sub-expressions to be included. - emitIRInstExpr(ctx, returnInst->getVal(), IREmitMode::GlobalConstant); + // 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). + // + emitIROperand(ctx, returnInst->getVal(), IREmitMode::GlobalConstant); } void emitIRGlobalConstant( |
