Skip to content
Merged
1 change: 1 addition & 0 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -9917,6 +9917,7 @@ class Compiler
void funSetCurrentFunc(unsigned funcIdx);
FuncInfoDsc* funGetFunc(unsigned funcIdx);
unsigned int funGetFuncIdx(BasicBlock* block);
bool bbIsInSameFunclet(BasicBlock* block1, BasicBlock* block2);

// LIVENESS

Expand Down
32 changes: 32 additions & 0 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,38 @@ inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
return funcIdx;
}

/*****************************************************************************
* Are two blocks physically contained in the same function region (funclet)?
* The main method is region 0. Unlike funGetFuncIdx, this works for an
* arbitrary block (not just a funclet entry), distinguishing a filter
* funclet (FUNC_FILTER) from its filter-handler. Only valid after funclets
* are created.
*
*/
inline bool Compiler::bbIsInSameFunclet(BasicBlock* block1, BasicBlock* block2)
{
assert(fgFuncletsCreated);

auto funcRegionOf = [this](BasicBlock* blk) -> unsigned {
if (!blk->hasHndIndex())
{
return 0;
}

EHblkDsc* const eh = ehGetDsc(blk->getHndIndex());
unsigned funcIdx = eh->ebdFuncIndex;

if (eh->HasFilter() && eh->InFilterRegionBBRange(blk))
{
// The filter is the funclet immediately preceding its filter-handler.
funcIdx--;
}

return funcIdx;
};

return funcRegionOf(block1) == funcRegionOf(block2);
}
#if HAS_FIXED_REGISTER_SET
//------------------------------------------------------------------------------
// genRegNumFromMask : Maps a single register mask to a register number.
Expand Down
13 changes: 12 additions & 1 deletion src/coreclr/jit/fgwasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,18 @@ BasicBlockVisit FgWasm::VisitWasmSuccs(Compiler* comp, BasicBlock* block, TFunc
//
if (acd->acdUsed)
{
RETURN_ON_ABORT(func(acd->acdDstBlk));
// bbThrowIndex / bbInTryRegions are purely lexical tests, so a match can
// name a throw helper that lives in a different function region (funclet)
// than this side-entry -- e.g. a main-method helper for an outer try whose
// handler funclet merely nests inside that try. Attaching it here would pull
// the helper into this funclet's layout, interleaving it with funclet blocks
// and corrupting the emitted wasm. Only attach when the helper and the
// side-entry share the same function region.
//
if (comp->bbIsInSameFunclet(block, acd->acdDstBlk))
{
RETURN_ON_ABORT(func(acd->acdDstBlk));
}
}
}
}
Expand Down
Loading