diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index 8472dfe8c0233d..6b2ca6af8484d4 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -332,8 +332,11 @@ class CodeGen final : public CodeGenInterface // Prolog functions and data (there are a few exceptions for more generally used things) // - void genEstablishFramePointer(int delta, bool reportUnwindData); - void genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed); + void genEstablishFramePointer(int delta, bool reportUnwindData); + void genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed); +#ifdef TARGET_WASM + void genHomeRegisterParamsOutsideProlog(); +#endif regMaskTP genGetParameterHomingTempRegisterCandidates(); var_types genParamStackType(LclVarDsc* dsc, const ABIPassingSegment& seg); diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index 7823547e9edbe2..2be7f9c272edad 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -410,6 +410,16 @@ void CodeGen::genCodeForBBlist() } #endif +#ifdef TARGET_WASM + // genHomeRegisterParams can generate arbitrary amounts of code on Wasm, so + // we have moved it out of the prolog to the first basic block in order to + // work around the restriction that the prolog can only be one insGroup. + if (block->IsFirst()) + { + genHomeRegisterParamsOutsideProlog(); + } +#endif + #ifndef TARGET_WASM // TODO-WASM: enable genPoisonFrame // Emit poisoning into the init BB that comes right after prolog. // We cannot emit this code in the prolog as it might make the prolog too large. diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index 4dc8af8418ac9b..32f5ef4cdb950b 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -121,6 +121,22 @@ void CodeGen::genEnregisterOSRArgsAndLocals() //------------------------------------------------------------------------ // genHomeRegisterParams: place register arguments into their RA-assigned locations. // +// We can't actually do this task here because the prolog will overflow. Instead, we +// do this later on and inject all the relevant code into the first basic block. +// See genHomeRegisterParamsOutsideProlog, below. +// +// Arguments: +// initReg - Unused +// initRegStillZeroed - Unused +// +void CodeGen::genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed) +{ + // Intentionally empty +} + +//------------------------------------------------------------------------ +// genHomeRegisterParamsOutsideProlog: place register arguments into their RA-assigned locations. +// // For the WASM RA, we have a much simplified (compared to LSRA) contract of: // - If an argument is live on entry in a set of registers, then the RA will // assign those registers to that argument on entry. @@ -129,14 +145,9 @@ void CodeGen::genEnregisterOSRArgsAndLocals() // The main motivation for this (along with the obvious CQ implications) is // obviating the need to adapt the general "RegGraph"-based algorithm to // !HAS_FIXED_REGISTER_SET constraints (no reg masks). -// -// Arguments: -// initReg - Unused -// initRegStillZeroed - Unused -// -void CodeGen::genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed) +void CodeGen::genHomeRegisterParamsOutsideProlog() { - JITDUMP("*************** In genHomeRegisterParams()\n"); + JITDUMP("*************** In genHomeRegisterParamsOutsideProlog()\n"); auto spillParam = [this](unsigned lclNum, unsigned offset, unsigned paramLclNum, const ABIPassingSegment& segment) { assert(segment.IsPassedInRegister()); diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 3eafb5c5bc9344..e620d149ca10b6 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -9765,7 +9765,8 @@ insGroup* emitter::emitAllocIG() ig = (insGroup*)emitGetMem(sz); #ifdef DEBUG - ig->igSelf = ig; + ig->igSelf = ig; + ig->igDataSize = 0; #endif #if EMITTER_STATS @@ -9832,6 +9833,8 @@ void emitter::emitInitIG(insGroup* ig) // Explicitly call init, since IGs don't actually have a constructor. ig->igBlocks.jitstd::list::init(m_compiler->getAllocator(CMK_DebugOnly)); #endif + + ig->igData = nullptr; } /*****************************************************************************