Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/coreclr/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ CodeGenInterface::CodeGenInterface(Compiler* theCompiler)
#endif // HAS_FIXED_REGISTER_SET
, m_compiler(theCompiler)
, treeLifeUpdater(nullptr)
#ifdef TARGET_WASM
, WasmLocalsDecls(theCompiler->getAllocator(CMK_Codegen))
#endif
{
}

Expand Down
10 changes: 10 additions & 0 deletions src/coreclr/jit/codegeninterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,16 @@ class CodeGenInterface

#endif // !DOUBLE_ALIGN

#ifdef TARGET_WASM
struct WasmLocalsDecl
{
WasmValueType Type;
unsigned Count;
};

jitstd::vector<WasmLocalsDecl> WasmLocalsDecls;
#endif

#ifdef DEBUG
// The following is used to make sure the value of 'GetInterruptible()' isn't
// changed after it's been used by any logic that depends on its value.
Expand Down
13 changes: 9 additions & 4 deletions src/coreclr/jit/codegenwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#endif

#include "codegen.h"
#include "regallocwasm.h"
#include "fgwasm.h"

#ifdef TARGET_64BIT
Expand All @@ -32,11 +33,15 @@ void CodeGen::genMarkLabelsForCodegen()
//------------------------------------------------------------------------
// genBeginFnProlog: generate wasm local declarations
//
// TODO-WASM: pre-declare all "register" locals
void CodeGen::genBeginFnProlog()
{
// TODO-WASM: proper local count, local declarations, and shadow stack maintenance
GetEmitter()->emitIns_I(INS_local_cnt, EA_8BYTE, 0);
unsigned localsCount = 0;
GetEmitter()->emitIns_I(INS_local_cnt, EA_8BYTE, WasmLocalsDecls.size());
for (WasmLocalsDecl& decl : WasmLocalsDecls)
{
GetEmitter()->emitIns_I_Ty(INS_local_decl, decl.Count, decl.Type, localsCount);
localsCount += decl.Count;
}
}

//------------------------------------------------------------------------
Expand Down Expand Up @@ -67,7 +72,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni

// TODO-WASM: reverse pinvoke frame allocation
//
if (m_compiler->lvaWasmSpArg == BAD_VAR_NUM)
if (!m_compiler->lvaGetDesc(m_compiler->lvaWasmSpArg)->lvIsParam)
{
NYI_WASM("alloc local frame for reverse pinvoke");
}
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -4131,7 +4131,8 @@ class Compiler
void lvaInitAsyncContinuation(unsigned* curVarNum);

#if defined(TARGET_WASM)
void lvaInitWasmStackPtr(unsigned* curVarNum);
void lvaInitWasmStackPtrArg(unsigned* curVarNum);
void lvaAllocWasmStackPtr();
void lvaInitWasmPortableEntryPtr(unsigned* curVarNum);
#endif // defined(TARGET_WASM)

Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -638,8 +638,9 @@ class emitter
bool idCatchRet; // Instruction is for a catch 'return'
CORINFO_SIG_INFO* idCallSig; // Used to report native call site signatures to the EE
BasicBlock* idTargetBlock; // Target block for branches

#ifdef TARGET_WASM
int lclOffset; // Base index of the WASM locals being declared
int lclBaseIndex; // Base index of the WASM locals being declared
#endif
};

Expand Down
34 changes: 30 additions & 4 deletions src/coreclr/jit/emitwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,31 @@ void emitter::emitIns_Call(const EmitCallParams& params)

dispIns(id);
appendToCurIG(id);
// emitLastMemBarrier = nullptr; // Cannot optimize away future memory barriers
}

//------------------------------------------------------------------------
// GetWasmArgsCount: Get WASM argument count for the root method.
//
// Arguments:
// compiler - The compiler object
//
// Return Value:
// The number of arguments in the WASM signature of the method being compiled.
//
static unsigned GetWasmArgsCount(Compiler* compiler)
{
assert(compiler->funCurrentFunc()->funKind == FUNC_ROOT);

unsigned count = 0;
for (unsigned argLclNum = 0; argLclNum < compiler->info.compArgsCount; argLclNum++)
{
const ABIPassingInformation& abiInfo = compiler->lvaGetParameterABIInfo(argLclNum);
for (const ABIPassingSegment& segment : abiInfo.Segments())
{
count = max(count, WasmRegToIndex(segment.GetRegister()) + 1);
}
}
return count;
}

//-----------------------------------------------------------------------------
Expand All @@ -206,7 +230,7 @@ emitter::instrDesc* emitter::emitNewInstrLclVarDecl(emitAttr attr,

if (m_debugInfoSize > 0)
{
id->idDebugOnlyInfo()->lclOffset = lclOffset;
id->idDebugOnlyInfo()->lclBaseIndex = GetWasmArgsCount(m_compiler) + lclOffset;
}

return id;
Expand All @@ -221,7 +245,9 @@ emitter::instrDesc* emitter::emitNewInstrLclVarDecl(emitAttr attr,
// ins - instruction to emit
// imm - immediate value (local count)
// valType - value type of the local variable
// offs - local variable offset (= count of preceding locals) for debug info
// offs - local variable offset (= count of preceding locals) for debug info,
// only includes locals declared explicitly (not args)
//
void emitter::emitIns_I_Ty(instruction ins, unsigned int imm, WasmValueType valType, int offs)
{
instrDesc* id = emitNewInstrLclVarDecl(EA_8BYTE, imm, valType, offs);
Expand Down Expand Up @@ -700,7 +726,7 @@ void emitter::emitDispIns(
if (m_debugInfoSize > 0)
{
// With debug info: print the local offsets being declared
int offs = id->idDebugOnlyInfo()->lclOffset;
int offs = id->idDebugOnlyInfo()->lclBaseIndex;
if (count > 1)
{
printf("[%u..%u] type=%s", offs, offs + count - 1, WasmValueTypeName(valType));
Expand Down
24 changes: 21 additions & 3 deletions src/coreclr/jit/lclvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,10 @@ void Compiler::lvaInitTypeRef()
// emitter when the varNum is greater that 32767 (see emitLclVarAddr::initLclVarAddr)
lvaAllocOutgoingArgSpaceVar();

#ifdef TARGET_WASM
lvaAllocWasmStackPtr();
#endif

#ifdef DEBUG
if (verbose)
{
Expand Down Expand Up @@ -351,7 +355,7 @@ void Compiler::lvaInitArgs(bool hasRetBuffArg)
if (!opts.IsReversePInvoke())
{
// Wasm stack pointer is first arg
lvaInitWasmStackPtr(&varNum);
lvaInitWasmStackPtrArg(&varNum);
}
#endif

Expand Down Expand Up @@ -502,7 +506,7 @@ void Compiler::lvaInitRetBuffArg(unsigned* curVarNum, bool useFixedRetBufReg)
// Notes:
// The managed calling convention for Wasm passes the stack pointer as the first arg.
//
void Compiler::lvaInitWasmStackPtr(unsigned* curVarNum)
void Compiler::lvaInitWasmStackPtrArg(unsigned* curVarNum)
{
LclVarDsc* varDsc = lvaGetDesc(*curVarNum);
varDsc->lvType = TYP_I_IMPL;
Expand All @@ -512,6 +516,20 @@ void Compiler::lvaInitWasmStackPtr(unsigned* curVarNum)
(*curVarNum)++;
}

//-----------------------------------------------------------------------------
// lvaInitWasmStackPtr: set up the wasm stack pointer variable
//
// Allocates the stack pointer for methods where it is not an argument (RPI).
//
void Compiler::lvaAllocWasmStackPtr()
{
if (lvaWasmSpArg == BAD_VAR_NUM)
{
lvaWasmSpArg = lvaGrabTemp(false DEBUGARG("SP"));
lvaGetDesc(lvaWasmSpArg)->lvType = TYP_I_IMPL;
}
}

//-----------------------------------------------------------------------------
// lvaInitWasmPortableEntryPtr: set up the wasm portable entry pointer argument
//
Expand Down Expand Up @@ -2951,7 +2969,7 @@ var_types LclVarDsc::GetRegisterType() const
{
if (!TypeIs(TYP_STRUCT))
{
#if !defined(TARGET_64BIT)
#if LOWER_DECOMPOSE_LONGS
if (TypeIs(TYP_LONG))
{
return TYP_UNDEF;
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/regalloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,14 +339,14 @@ bool RegAllocImpl::isRegCandidate(LclVarDsc* varDsc)
return false;
}

#if !defined(TARGET_64BIT)
#if LOWER_DECOMPOSE_LONGS
if (varDsc->lvType == TYP_LONG)
{
// Long variables should not be register candidates.
// Lowering will have split any candidate lclVars into lo/hi vars.
return false;
}
#endif // !defined(TARGET_64BIT)
#endif // LOWER_DECOMPOSE_LONGS

// If we have JMP, reg args must be put on the stack

Expand Down
Loading
Loading