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
7 changes: 5 additions & 2 deletions src/coreclr/jit/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,15 +214,18 @@ class CodeGen final : public CodeGenInterface
void genCodeForBlock(BasicBlock* block);

#if defined(TARGET_WASM)
ArrayStack<WasmInterval*>* wasmControlFlowStack = nullptr;
unsigned wasmCursor = 0;
ArrayStack<WasmInterval*>* wasmControlFlowStack = nullptr;
unsigned wasmCursor = 0;
unsigned wasmExtraControlFlowDepth = 0;
unsigned findTargetDepth(BasicBlock* target);
void WasmProduceReg(GenTree* node);
regNumber GetMultiUseOperandReg(GenTree* operand);
void genEmitNullCheck(regNumber reg);
unsigned GetStackPointerRegIndex() const;
unsigned GetFramePointerRegIndex() const;
void ensureCurrentFuncIsUnwindable();
void genEmitIf(WasmValueType blockType = WasmValueType::Invalid);
void genEmitEndIf();
#endif

void genEmitStartBlock(BasicBlock* block);
Expand Down
57 changes: 47 additions & 10 deletions src/coreclr/jit/codegenwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,7 @@ void CodeGen::genCodeForBinaryOverflow(GenTreeOp* treeNode)
// TODO-WASM-CQ: consider branchless alternative here (and for sub)
GetEmitter()->emitIns_I(is64BitOp ? INS_i64_const : INS_i32_const, emitActualTypeSize(treeNode), 0);
GetEmitter()->emitIns(is64BitOp ? INS_i64_ge_s : INS_i32_ge_s);
GetEmitter()->emitIns(INS_if);
genEmitIf();
{
// Operands have the same sign. If the sum has a different sign, then the add overflowed.
GetEmitter()->emitIns_I(INS_local_get, emitActualTypeSize(treeNode), WasmRegToIndex(resultReg));
Expand All @@ -1469,7 +1469,7 @@ void CodeGen::genCodeForBinaryOverflow(GenTreeOp* treeNode)
GetEmitter()->emitIns(is64BitOp ? INS_i64_lt_s : INS_i32_lt_s);
genJumpToThrowHlpBlk(SCK_OVERFLOW);
}
GetEmitter()->emitIns(INS_end);
genEmitEndIf();
GetEmitter()->emitIns_I(INS_local_get, emitActualTypeSize(treeNode), WasmRegToIndex(resultReg));
break;
}
Expand All @@ -1490,7 +1490,7 @@ void CodeGen::genCodeForBinaryOverflow(GenTreeOp* treeNode)
GetEmitter()->emitIns(is64BitOp ? INS_i64_xor : INS_i32_xor);
GetEmitter()->emitIns_I(is64BitOp ? INS_i64_const : INS_i32_const, emitActualTypeSize(treeNode), 0);
GetEmitter()->emitIns(is64BitOp ? INS_i64_lt_s : INS_i32_lt_s);
GetEmitter()->emitIns(INS_if);
genEmitIf();
{
// Operands have different signs. If the difference has a different sign than op1, then the subtraction
// overflowed.
Expand All @@ -1501,7 +1501,7 @@ void CodeGen::genCodeForBinaryOverflow(GenTreeOp* treeNode)
GetEmitter()->emitIns(is64BitOp ? INS_i64_lt_s : INS_i32_lt_s);
genJumpToThrowHlpBlk(SCK_OVERFLOW);
}
GetEmitter()->emitIns(INS_end);
genEmitEndIf();
GetEmitter()->emitIns_I(INS_local_get, emitActualTypeSize(treeNode), WasmRegToIndex(resultReg));
break;
}
Expand Down Expand Up @@ -1915,11 +1915,11 @@ void CodeGen::genJumpToThrowHlpBlk(SpecialCodeKind codeKind)
}
else
{
GetEmitter()->emitIns_BlockTy(INS_if);
genEmitIf();
// Throw helpers are managed so we need to push the stack pointer before genEmitHelperCall.
GetEmitter()->emitIns_I(INS_local_get, EA_PTRSIZE, GetStackPointerRegIndex());
genEmitHelperCall(m_compiler->acdHelper(codeKind), 0, EA_UNKNOWN);
GetEmitter()->emitIns(INS_end);
genEmitEndIf();
}
}

Expand Down Expand Up @@ -2975,7 +2975,6 @@ void CodeGen::genLclHeap(GenTree* tree)
}
else
{
bool const is64Bit = (TARGET_POINTER_SIZE == 8);
genConsumeReg(size);

// Extend size to pointer size, if necessary
Expand All @@ -2996,7 +2995,7 @@ void CodeGen::genLclHeap(GenTree* tree)

// Check for zero-sized requests
GetEmitter()->emitIns(INS_I_eqz);
GetEmitter()->emitIns_BlockTy(INS_if, is64Bit ? WasmValueType::I64 : WasmValueType::I32);
genEmitIf(WasmValueType::I);
{
// If size is zero, leave a zero on the stack
GetEmitter()->emitIns_I(INS_I_const, EA_PTRSIZE, 0);
Expand Down Expand Up @@ -3053,7 +3052,7 @@ void CodeGen::genLclHeap(GenTree* tree)
}

// end if
GetEmitter()->emitIns(INS_end);
genEmitEndIf();
}

WasmProduceReg(tree);
Expand Down Expand Up @@ -3372,6 +3371,44 @@ void CodeGen::genLoadLocalIntoReg(regNumber targetReg, unsigned lclNum)
GetEmitter()->emitIns_I(INS_local_set, emitTypeSize(type), WasmRegToIndex(targetReg));
}

//------------------------------------------------------------------------
// genEmitIf: Emit an 'if' instruction
//
// Arguments:
// blockType - simple type for the block, or invalid if none
//
// Notes:
// This emits an `if` instruction and adds a new label to the control flow stack that is not
// modelled by the wasmControlFlowStack. Since we won't explicitly branch to the end
// of the `if` we just need to understand that the stack is now deeper.
//
void CodeGen::genEmitIf(WasmValueType blockType)
{
wasmExtraControlFlowDepth++;

if (blockType != WasmValueType::Invalid)
{
GetEmitter()->emitIns_BlockTy(INS_if, blockType);
}
else
{
GetEmitter()->emitIns(INS_if);
}
}

//------------------------------------------------------------------------
// genEmitEndIf: Emit an 'end' instruction closing an 'if' block
//
// Notes:
// Removes the added stack depth from genEmitIf.
//
void CodeGen::genEmitEndIf()
{
assert(wasmExtraControlFlowDepth > 0);
wasmExtraControlFlowDepth--;
GetEmitter()->emitIns(INS_end);
}

//------------------------------------------------------------------------
// inst_JMP: Emit a jump instruction.
//
Expand All @@ -3382,7 +3419,7 @@ void CodeGen::genLoadLocalIntoReg(regNumber targetReg, unsigned lclNum)
void CodeGen::inst_JMP(emitJumpKind jmp, BasicBlock* tgtBlock)
{
instruction instr = emitter::emitJumpKindToIns(jmp);
unsigned const depth = findTargetDepth(tgtBlock);
unsigned const depth = findTargetDepth(tgtBlock) + wasmExtraControlFlowDepth;
GetEmitter()->emitIns_J(instr, EA_4BYTE, depth, tgtBlock);
}

Expand Down
12 changes: 10 additions & 2 deletions src/coreclr/jit/lowerwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,18 @@ void Lowering::LowerPEPCall(GenTreeCall* call)
DISPTREE(call);

JITDUMP("Rewrite PEP call's control expression to indirect through the new local variable\n");

// Rewrite the call's control expression to have an additional load from the PEP local
// This must happen just before the call.
//
GenTree* controlExpr = call->gtControlExpr;
GenTree* target = Ind(controlExpr);
BlockRange().InsertAfter(controlExpr, target);
assert(controlExpr->OperIs(GT_LCL_VAR));

BlockRange().Remove(controlExpr);
BlockRange().InsertBefore(call, controlExpr);
GenTree* target = Ind(controlExpr);
BlockRange().InsertBefore(call, target);
Comment thread
AndyAyersMS marked this conversation as resolved.

call->gtControlExpr = target;

JITDUMP("Finished lowering PEP call\n");
Expand Down
Loading