Skip to content
Open
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
19 changes: 19 additions & 0 deletions src/coreclr/jit/codegenwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2652,6 +2652,12 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree)

genConsumeAddress(tree->Addr());

if ((tree->gtFlags & GTF_IND_NONFAULTING) == 0)
{
regNumber addrReg = GetMultiUseOperandReg(tree->Addr());
genEmitNullCheck(addrReg);
}

// TODO-WASM: Memory barriers

GetEmitter()->emitIns_I(ins, emitActualTypeSize(type), 0);
Expand Down Expand Up @@ -3587,6 +3593,19 @@ void CodeGen::genCallFinally(BasicBlock* block)
{
GetEmitter()->emitIns(INS_end);
}

return;
}

// Branch to the continuation block if it's not the next block.
assert(block->isBBCallFinallyPair());
BasicBlock* const callFinallyRet = block->Next();
assert(callFinallyRet->KindIs(BBJ_CALLFINALLYRET));
BasicBlock* const continuation = callFinallyRet->GetTarget();

if (continuation != callFinallyRet->Next())
{
inst_JMP(EJ_jmp, continuation);
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/jit/lowerwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,11 @@ void Lowering::ContainCheckIndir(GenTreeIndir* indirNode)
return;
}

if (indirNode->OperIs(GT_IND) && ((indirNode->gtFlags & GTF_IND_NONFAULTING) == 0))
{
SetMultiplyUsed(indirNode->Addr() DEBUGARG("ContainCheckIndir faulting load Addr"));
}

// TODO-WASM-CQ: contain suitable LEAs here. Take note of the fact that for this to be correct we must prove the
// LEA doesn't overflow. It will involve creating a new frontend node to represent "nuw" (offset) addition.
}
Expand Down
11 changes: 6 additions & 5 deletions src/coreclr/jit/regallocwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,8 +486,9 @@ void WasmRegAlloc::CollectReferencesForNode(GenTree* node)
CollectReferencesForBinop(node->AsOp());
break;

case GT_IND:
case GT_STOREIND:
CollectReferencesForStoreInd(node->AsStoreInd());
CollectReferencesForIndir(node->AsIndir());
break;

case GT_STORE_BLK:
Expand Down Expand Up @@ -648,15 +649,15 @@ void WasmRegAlloc::CollectReferencesForBinop(GenTreeOp* binopNode)
}

//------------------------------------------------------------------------
// CollectReferencesForStoreInd: Collect virtual register references for an indirect store
// CollectReferencesForIndir: Collect virtual register references for an indirection.
//
// Arguments:
// node - The GT_STOREIND node
// node - The indirection node.
//
void WasmRegAlloc::CollectReferencesForStoreInd(GenTreeStoreInd* node)
void WasmRegAlloc::CollectReferencesForIndir(GenTreeIndir* node)
{
GenTree* const addr = node->Addr();
ConsumeTemporaryRegForOperand(addr DEBUGARG("storeind null check"));
ConsumeTemporaryRegForOperand(addr DEBUGARG("indirection address"));
}

//------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/regallocwasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ class WasmRegAlloc : public RegAllocInterface
void CollectReferencesForCall(GenTreeCall* callNode);
void CollectReferencesForCast(GenTreeOp* castNode);
void CollectReferencesForBinop(GenTreeOp* binOpNode);
void CollectReferencesForStoreInd(GenTreeStoreInd* node);
void CollectReferencesForIndir(GenTreeIndir* node);
void CollectReferencesForBlockStore(GenTreeBlk* node);
void CollectReferencesForLclVar(GenTreeLclVar* lclVar);
void CollectReferencesForIndexAddr(GenTreeIndexAddr* indexAddrNode);
Expand Down
40 changes: 38 additions & 2 deletions src/coreclr/jit/stacklevelsetter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ void StackLevelSetter::ProcessBlock(BasicBlock* block)

if (checkForHelpers)
{
if (((node->gtFlags & GTF_EXCEPT) != 0) && node->OperMayThrow(m_compiler))
if (MayUseThrowHelperBlock(node))
{
SetThrowHelperBlocks(node, block);
}
Expand All @@ -199,6 +199,42 @@ void StackLevelSetter::ProcessBlock(BasicBlock* block)
assert(currentStackLevel == 0);
}

//------------------------------------------------------------------------
// MayUseThrowHelperBlock: Check whether codegen may branch to a throw helper block.
//
// Arguments:
// node - The node to process.
//
// Return Value:
// True if the node may branch to a throw helper block.
//
bool StackLevelSetter::MayUseThrowHelperBlock(GenTree* node)
{
if (((node->gtFlags & GTF_EXCEPT) != 0) && node->OperMayThrow(m_compiler))
{
return true;
}

#if defined(TARGET_WASM)
switch (node->OperGet())
{
case GT_NULLCHECK:
case GT_IND:
case GT_STORE_BLK:
case GT_STOREIND:
return (node->gtFlags & GTF_IND_NONFAULTING) == 0;

case GT_CALL:
return node->AsCall()->NeedsNullCheck();

default:
break;
}
#endif // defined(TARGET_WASM)

return false;
}

//------------------------------------------------------------------------
// SetThrowHelperBlocks: Set throw helper blocks incoming stack levels targeted
// from the node.
Expand All @@ -213,7 +249,7 @@ void StackLevelSetter::ProcessBlock(BasicBlock* block)
//
void StackLevelSetter::SetThrowHelperBlocks(GenTree* node, BasicBlock* block)
{
assert(node->OperMayThrow(m_compiler));
assert(MayUseThrowHelperBlock(node));

// Check that it uses throw block, find its kind, find the block, set level.
switch (node->OperGet())
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/stacklevelsetter.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class StackLevelSetter final : public Phase
void ProcessBlocks();
void ProcessBlock(BasicBlock* block);

bool MayUseThrowHelperBlock(GenTree* node);
void SetThrowHelperBlocks(GenTree* node, BasicBlock* block);
void SetThrowHelperBlock(SpecialCodeKind kind, BasicBlock* block);

Expand Down
Loading