Skip to content

Commit de1a204

Browse files
authored
JIT: revise inlinee block numbering, enable synthesis for inlinees (#83610)
Start numbering inlinee blocks from 1 instead of 1 + the root compiler's max BB num. Update inlinee block bbNums when they are inserted into the root compiler's graph. Adjust computations in various places that knew about the old approach and looked from inlinee compiler to root compiler for bitset, epochs and the like. Enable synthesis for inlinees, now that regular bitsets on inlinee compiler instances behave sensibly. There is still some messiness around inlinees inheriting root compiler EH info which requires special checks. I will clean this up separately. Fixes #82755. Contributes to #82964.
1 parent eacb2f3 commit de1a204

10 files changed

+136
-155
lines changed

src/coreclr/jit/block.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ void BasicBlock::dspSuccs(Compiler* compiler)
571571
{
572572
// Create a set with all the successors. Don't use BlockSet, so we don't need to worry
573573
// about the BlockSet epoch.
574-
unsigned bbNumMax = compiler->impInlineRoot()->fgBBNumMax;
574+
unsigned bbNumMax = compiler->fgBBNumMax;
575575
BitVecTraits bitVecTraits(bbNumMax + 1, compiler);
576576
BitVec uniqueSuccBlocks(BitVecOps::MakeEmpty(&bitVecTraits));
577577
for (BasicBlock* const bTarget : SwitchTargets())
@@ -1431,16 +1431,7 @@ BasicBlock* Compiler::bbNewBasicBlock(BBjumpKinds jumpKind)
14311431
/* Give the block a number, set the ancestor count and weight */
14321432

14331433
++fgBBcount;
1434-
1435-
if (compIsForInlining())
1436-
{
1437-
block->bbNum = ++impInlineInfo->InlinerCompiler->fgBBNumMax;
1438-
fgBBNumMax = block->bbNum;
1439-
}
1440-
else
1441-
{
1442-
block->bbNum = ++fgBBNumMax;
1443-
}
1434+
block->bbNum = ++fgBBNumMax;
14441435

14451436
if (compRationalIRForm)
14461437
{

src/coreclr/jit/compiler.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4402,7 +4402,6 @@ class Compiler
44024402
unsigned fgBBcountAtCodegen; // # of BBs in the method at the start of codegen
44034403
jitstd::vector<BasicBlock*>* fgBBOrder; // ordered vector of BBs
44044404
#endif
4405-
unsigned fgBBNumMin; // The min bbNum that has been assigned to basic blocks
44064405
unsigned fgBBNumMax; // The max bbNum that has been assigned to basic blocks
44074406
unsigned fgDomBBcount; // # of BBs for which we have dominator and reachability information
44084407
BasicBlock** fgBBReversePostorder; // Blocks in reverse postorder

src/coreclr/jit/fgbasic.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ void Compiler::fgInit()
6262
fgBBOrder = nullptr;
6363
#endif // DEBUG
6464

65-
fgBBNumMin = compIsForInlining() ? impInlineRoot()->fgBBNumMax + 1 : 1;
6665
fgBBNumMax = 0;
6766
fgEdgeCount = 0;
6867
fgDomBBcount = 0;
@@ -5440,7 +5439,7 @@ bool Compiler::fgRenumberBlocks()
54405439

54415440
bool renumbered = false;
54425441
bool newMaxBBNum = false;
5443-
unsigned num = fgBBNumMin;
5442+
unsigned num = 1;
54445443

54455444
for (BasicBlock* block : Blocks())
54465445
{
@@ -5456,7 +5455,7 @@ bool Compiler::fgRenumberBlocks()
54565455
if (block->bbNext == nullptr)
54575456
{
54585457
fgLastBB = block;
5459-
fgBBcount = num - fgBBNumMin + 1;
5458+
fgBBcount = num;
54605459
if (fgBBNumMax != num)
54615460
{
54625461
fgBBNumMax = num;

src/coreclr/jit/fgdiagnostic.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase, PhasePosition pos)
874874
// that size, even though it means allocating a block map possibly much bigger than what's required for just
875875
// the inlinee blocks.
876876

877-
unsigned blkMapSize = 1 + impInlineRoot()->fgBBNumMax;
877+
unsigned blkMapSize = 1 + fgBBNumMax;
878878
unsigned blockOrdinal = 1;
879879
unsigned* blkMap = new (this, CMK_DebugOnly) unsigned[blkMapSize];
880880
memset(blkMap, 0, sizeof(unsigned) * blkMapSize);
@@ -1830,7 +1830,7 @@ void Compiler::fgDispDoms()
18301830
void Compiler::fgTableDispBasicBlock(BasicBlock* block, int ibcColWidth /* = 0 */)
18311831
{
18321832
const unsigned __int64 flags = block->bbFlags;
1833-
unsigned bbNumMax = impInlineRoot()->fgBBNumMax;
1833+
unsigned bbNumMax = fgBBNumMax;
18341834
int maxBlockNumWidth = CountDigits(bbNumMax);
18351835
maxBlockNumWidth = max(maxBlockNumWidth, 2);
18361836
int blockNumWidth = CountDigits(block->bbNum);
@@ -2261,7 +2261,7 @@ void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock, BasicBlock* lastBlock,
22612261
ibcColWidth = max(ibcColWidth, 3) + 1; // + 1 for the leading space
22622262
}
22632263

2264-
unsigned bbNumMax = impInlineRoot()->fgBBNumMax;
2264+
unsigned bbNumMax = fgBBNumMax;
22652265
int maxBlockNumWidth = CountDigits(bbNumMax);
22662266
maxBlockNumWidth = max(maxBlockNumWidth, 2);
22672267
int padWidth = maxBlockNumWidth - 2; // Account for functions with a large number of blocks.
@@ -3635,7 +3635,7 @@ void Compiler::fgDebugCheckBlockLinks()
36353635
{
36363636
// Create a set with all the successors. Don't use BlockSet, so we don't need to worry
36373637
// about the BlockSet epoch.
3638-
BitVecTraits bitVecTraits(impInlineRoot()->fgBBNumMax + 1, this);
3638+
BitVecTraits bitVecTraits(fgBBNumMax + 1, this);
36393639
BitVec succBlocks(BitVecOps::MakeEmpty(&bitVecTraits));
36403640
for (BasicBlock* const bTarget : block->SwitchTargets())
36413641
{
@@ -4362,7 +4362,7 @@ void Compiler::fgDebugCheckLoopTable()
43624362
// `blockNumMap[bbNum] == 0` if the `bbNum` block was deleted and blocks haven't been renumbered since
43634363
// the deletion.
43644364

4365-
unsigned bbNumMax = impInlineRoot()->fgBBNumMax;
4365+
unsigned bbNumMax = fgBBNumMax;
43664366

43674367
// blockNumMap[old block number] => new block number
43684368
size_t blockNumBytes = (bbNumMax + 1) * sizeof(unsigned);

src/coreclr/jit/fgflow.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -519,8 +519,7 @@ Compiler::SwitchUniqueSuccSet Compiler::GetDescriptorForSwitch(BasicBlock* switc
519519
// can create a new epoch, thus invalidating all existing BlockSet objects, such as
520520
// reachability information stored in the blocks. To avoid that, we just use a local BitVec.
521521

522-
unsigned bbNumMax = impInlineRoot()->fgBBNumMax;
523-
BitVecTraits blockVecTraits(bbNumMax + 1, this);
522+
BitVecTraits blockVecTraits(fgBBNumMax + 1, this);
524523
BitVec uniqueSuccBlocks(BitVecOps::MakeEmpty(&blockVecTraits));
525524
for (BasicBlock* const targ : switchBlk->SwitchTargets())
526525
{

src/coreclr/jit/fginline.cpp

Lines changed: 60 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,8 +1305,9 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
13051305
}
13061306
#endif // DEBUG
13071307

1308-
BasicBlock* topBlock = iciBlock;
1309-
BasicBlock* bottomBlock = nullptr;
1308+
BasicBlock* topBlock = iciBlock;
1309+
BasicBlock* bottomBlock = nullptr;
1310+
bool insertInlineeBlocks = true;
13101311

13111312
if (InlineeCompiler->fgBBcount == 1)
13121313
{
@@ -1356,85 +1357,85 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
13561357

13571358
// Append statements to null out gc ref locals, if necessary.
13581359
fgInlineAppendStatements(pInlineInfo, iciBlock, stmtAfter);
1359-
1360-
goto _Done;
1360+
insertInlineeBlocks = false;
13611361
}
13621362
}
13631363

13641364
//
13651365
// ======= Inserting inlinee's basic blocks ===============
13661366
//
1367-
bottomBlock = fgSplitBlockAfterStatement(topBlock, stmtAfter);
1368-
1369-
//
1370-
// Set the try and handler index and fix the jump types of inlinee's blocks.
1371-
//
1372-
for (BasicBlock* const block : InlineeCompiler->Blocks())
1367+
if (insertInlineeBlocks)
13731368
{
1374-
noway_assert(!block->hasTryIndex());
1375-
noway_assert(!block->hasHndIndex());
1376-
block->copyEHRegion(iciBlock);
1377-
block->bbFlags |= iciBlock->bbFlags & BBF_BACKWARD_JUMP;
1369+
bottomBlock = fgSplitBlockAfterStatement(topBlock, stmtAfter);
1370+
unsigned const baseBBNum = fgBBNumMax;
13781371

1379-
DebugInfo di = iciStmt->GetDebugInfo().GetRoot();
1380-
if (di.IsValid())
1381-
{
1382-
block->bbCodeOffs = di.GetLocation().GetOffset();
1383-
block->bbCodeOffsEnd = block->bbCodeOffs + 1; // TODO: is code size of 1 some magic number for inlining?
1384-
}
1385-
else
1372+
//
1373+
// Set the try and handler index and fix the jump types of inlinee's blocks.
1374+
//
1375+
for (BasicBlock* const block : InlineeCompiler->Blocks())
13861376
{
1387-
block->bbCodeOffs = 0; // TODO: why not BAD_IL_OFFSET?
1388-
block->bbCodeOffsEnd = 0;
1389-
block->bbFlags |= BBF_INTERNAL;
1390-
}
1377+
noway_assert(!block->hasTryIndex());
1378+
noway_assert(!block->hasHndIndex());
1379+
block->copyEHRegion(iciBlock);
1380+
block->bbFlags |= iciBlock->bbFlags & BBF_BACKWARD_JUMP;
13911381

1392-
if (block->bbJumpKind == BBJ_RETURN)
1393-
{
1394-
noway_assert((block->bbFlags & BBF_HAS_JMP) == 0);
1395-
if (block->bbNext)
1382+
// Update block nums appropriately
1383+
//
1384+
block->bbNum += baseBBNum;
1385+
fgBBNumMax = max(block->bbNum, fgBBNumMax);
1386+
1387+
DebugInfo di = iciStmt->GetDebugInfo().GetRoot();
1388+
if (di.IsValid())
13961389
{
1397-
JITDUMP("\nConvert bbJumpKind of " FMT_BB " to BBJ_ALWAYS to bottomBlock " FMT_BB "\n", block->bbNum,
1398-
bottomBlock->bbNum);
1399-
block->bbJumpKind = BBJ_ALWAYS;
1400-
block->bbJumpDest = bottomBlock;
1390+
block->bbCodeOffs = di.GetLocation().GetOffset();
1391+
block->bbCodeOffsEnd = block->bbCodeOffs + 1; // TODO: is code size of 1 some magic number for inlining?
14011392
}
14021393
else
14031394
{
1404-
JITDUMP("\nConvert bbJumpKind of " FMT_BB " to BBJ_NONE\n", block->bbNum);
1405-
block->bbJumpKind = BBJ_NONE;
1395+
block->bbCodeOffs = 0; // TODO: why not BAD_IL_OFFSET?
1396+
block->bbCodeOffsEnd = 0;
1397+
block->bbFlags |= BBF_INTERNAL;
14061398
}
14071399

1408-
fgAddRefPred(bottomBlock, block);
1409-
}
1410-
}
1400+
if (block->bbJumpKind == BBJ_RETURN)
1401+
{
1402+
noway_assert((block->bbFlags & BBF_HAS_JMP) == 0);
1403+
if (block->bbNext)
1404+
{
1405+
JITDUMP("\nConvert bbJumpKind of " FMT_BB " to BBJ_ALWAYS to bottomBlock " FMT_BB "\n",
1406+
block->bbNum, bottomBlock->bbNum);
1407+
block->bbJumpKind = BBJ_ALWAYS;
1408+
block->bbJumpDest = bottomBlock;
1409+
}
1410+
else
1411+
{
1412+
JITDUMP("\nConvert bbJumpKind of " FMT_BB " to BBJ_NONE\n", block->bbNum);
1413+
block->bbJumpKind = BBJ_NONE;
1414+
}
14111415

1412-
// Inlinee's top block will have an artificial ref count. Remove.
1413-
assert(InlineeCompiler->fgFirstBB->bbRefs > 0);
1414-
InlineeCompiler->fgFirstBB->bbRefs--;
1416+
fgAddRefPred(bottomBlock, block);
1417+
}
1418+
}
14151419

1416-
// Insert inlinee's blocks into inliner's block list.
1417-
topBlock->setNext(InlineeCompiler->fgFirstBB);
1418-
fgRemoveRefPred(bottomBlock, topBlock);
1419-
fgAddRefPred(InlineeCompiler->fgFirstBB, topBlock);
1420-
InlineeCompiler->fgLastBB->setNext(bottomBlock);
1420+
// Inlinee's top block will have an artificial ref count. Remove.
1421+
assert(InlineeCompiler->fgFirstBB->bbRefs > 0);
1422+
InlineeCompiler->fgFirstBB->bbRefs--;
14211423

1422-
//
1423-
// Add inlinee's block count to inliner's.
1424-
//
1425-
fgBBcount += InlineeCompiler->fgBBcount;
1424+
// Insert inlinee's blocks into inliner's block list.
1425+
topBlock->setNext(InlineeCompiler->fgFirstBB);
1426+
fgRemoveRefPred(bottomBlock, topBlock);
1427+
fgAddRefPred(InlineeCompiler->fgFirstBB, topBlock);
1428+
InlineeCompiler->fgLastBB->setNext(bottomBlock);
14261429

1427-
// Append statements to null out gc ref locals, if necessary.
1428-
fgInlineAppendStatements(pInlineInfo, bottomBlock, nullptr);
1430+
//
1431+
// Add inlinee's block count to inliner's.
1432+
//
1433+
fgBBcount += InlineeCompiler->fgBBcount;
14291434

1430-
#ifdef DEBUG
1431-
if (verbose)
1432-
{
1433-
fgDispBasicBlocks(InlineeCompiler->fgFirstBB, InlineeCompiler->fgLastBB, true);
1435+
// Append statements to null out gc ref locals, if necessary.
1436+
fgInlineAppendStatements(pInlineInfo, bottomBlock, nullptr);
1437+
JITDUMPEXEC(fgDispBasicBlocks(InlineeCompiler->fgFirstBB, InlineeCompiler->fgLastBB, true));
14341438
}
1435-
#endif // DEBUG
1436-
1437-
_Done:
14381439

14391440
//
14401441
// At this point, we have successully inserted inlinee's code.

src/coreclr/jit/fgopt.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -363,13 +363,16 @@ void Compiler::fgComputeEnterBlocksSet()
363363
assert(fgFirstBB->bbNum == 1);
364364

365365
/* Also 'or' in the handler basic blocks */
366-
for (EHblkDsc* const HBtab : EHClauses(this))
366+
if (!compIsForInlining())
367367
{
368-
if (HBtab->HasFilter())
368+
for (EHblkDsc* const HBtab : EHClauses(this))
369369
{
370-
BlockSetOps::AddElemD(this, fgEnterBlks, HBtab->ebdFilter->bbNum);
370+
if (HBtab->HasFilter())
371+
{
372+
BlockSetOps::AddElemD(this, fgEnterBlks, HBtab->ebdFilter->bbNum);
373+
}
374+
BlockSetOps::AddElemD(this, fgEnterBlks, HBtab->ebdHndBeg->bbNum);
371375
}
372-
BlockSetOps::AddElemD(this, fgEnterBlks, HBtab->ebdHndBeg->bbNum);
373376
}
374377

375378
#if defined(FEATURE_EH_FUNCLETS) && defined(TARGET_ARM)

0 commit comments

Comments
 (0)