Skip to content

Commit 3115a9c

Browse files
JIT: Remove most fgConnectFallThrough calls (#97488)
Part of #93020. This change adds back in most of #97191 and #96609, except for any significant changes to the flowgraph optimization passes to reduce churn. With this change, the false target of a BBJ_COND can diverge from the next block until Compiler::optOptimizeLayout, in which we reestablish implicit fall-through with fgConnectFallThrough to preserve the existing block reordering behavior. Note that the deferral of these fall-through fixups causes diffs in the edge weights, which can alter the behavior of fgReorderBlocks, hence some of the size regressions
1 parent 8a0b3f3 commit 3115a9c

23 files changed

+276
-305
lines changed

src/coreclr/jit/block.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -301,18 +301,20 @@ bool BasicBlock::CanRemoveJumpToNext(Compiler* compiler) const
301301
}
302302

303303
//------------------------------------------------------------------------
304-
// CanRemoveJumpToFalseTarget: determine if jump to false target can be omitted
304+
// CanRemoveJumpToTarget: determine if jump to target can be omitted
305305
//
306306
// Arguments:
307+
// target - true/false target of the BBJ_COND block
307308
// compiler - current compiler instance
308309
//
309310
// Returns:
310-
// true if block is a BBJ_COND that can fall into its false target
311+
// true if block is a BBJ_COND that can fall into target
311312
//
312-
bool BasicBlock::CanRemoveJumpToFalseTarget(Compiler* compiler) const
313+
bool BasicBlock::CanRemoveJumpToTarget(BasicBlock* target, Compiler* compiler) const
313314
{
314315
assert(KindIs(BBJ_COND));
315-
return NextIs(bbFalseTarget) && !hasAlign() && !compiler->fgInDifferentRegions(this, bbFalseTarget);
316+
assert(TrueTargetIs(target) || FalseTargetIs(target));
317+
return NextIs(target) && !compiler->fgInDifferentRegions(this, target);
316318
}
317319

318320
//------------------------------------------------------------------------
@@ -855,8 +857,7 @@ void BasicBlock::CopyTarget(Compiler* compiler, const BasicBlock* from)
855857
SetEhf(new (compiler, CMK_BasicBlock) BBehfDesc(compiler, from->GetEhfTargets()));
856858
break;
857859
case BBJ_COND:
858-
// TODO-NoFallThrough: Copy false target, too?
859-
SetCond(from->GetTrueTarget(), Next());
860+
SetCond(from->GetTrueTarget(), from->GetFalseTarget());
860861
break;
861862
case BBJ_ALWAYS:
862863
SetKindAndTarget(from->GetKind(), from->GetTarget());
@@ -897,8 +898,7 @@ void BasicBlock::TransferTarget(BasicBlock* from)
897898
from->bbEhfTargets = nullptr; // Make sure nobody uses the descriptor after this.
898899
break;
899900
case BBJ_COND:
900-
// TODO-NoFallThrough: Copy false target, too?
901-
SetCond(from->GetTrueTarget(), Next());
901+
SetCond(from->GetTrueTarget(), from->GetFalseTarget());
902902
break;
903903
case BBJ_ALWAYS:
904904
SetKindAndTarget(from->GetKind(), from->GetTarget());
@@ -1183,7 +1183,7 @@ unsigned BasicBlock::NumSucc() const
11831183
return 1;
11841184

11851185
case BBJ_COND:
1186-
if (bbTarget == bbNext)
1186+
if (bbTrueTarget == bbFalseTarget)
11871187
{
11881188
return 1;
11891189
}
@@ -1308,7 +1308,7 @@ unsigned BasicBlock::NumSucc(Compiler* comp)
13081308
return 1;
13091309

13101310
case BBJ_COND:
1311-
if (bbTarget == bbNext)
1311+
if (bbTrueTarget == bbFalseTarget)
13121312
{
13131313
return 1;
13141314
}

src/coreclr/jit/block.h

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ struct BasicBlock : private LIR::Range
610610

611611
bool CanRemoveJumpToNext(Compiler* compiler) const;
612612

613-
bool CanRemoveJumpToFalseTarget(Compiler* compiler) const;
613+
bool CanRemoveJumpToTarget(BasicBlock* target, Compiler* compiler) const;
614614

615615
unsigned GetTargetOffs() const
616616
{
@@ -663,19 +663,13 @@ struct BasicBlock : private LIR::Range
663663
{
664664
assert(KindIs(BBJ_COND));
665665
assert(bbTrueTarget != nullptr);
666-
assert(target != nullptr);
667666
return (bbTrueTarget == target);
668667
}
669668

670669
BasicBlock* GetFalseTarget() const
671670
{
672671
assert(KindIs(BBJ_COND));
673-
674-
// So long as bbFalseTarget tracks bbNext in SetNext(), it is possible for bbFalseTarget to be null
675-
// if this block is unlinked from the block list.
676-
// So check bbNext before triggering the assert if bbFalseTarget is null.
677-
// TODO-NoFallThrough: Remove IsLast() check once bbFalseTarget isn't hard-coded to bbNext
678-
assert((bbFalseTarget != nullptr) || IsLast());
672+
assert(bbFalseTarget != nullptr);
679673
return bbFalseTarget;
680674
}
681675

@@ -690,15 +684,12 @@ struct BasicBlock : private LIR::Range
690684
{
691685
assert(KindIs(BBJ_COND));
692686
assert(bbFalseTarget != nullptr);
693-
assert(target != nullptr);
694687
return (bbFalseTarget == target);
695688
}
696689

697690
void SetCond(BasicBlock* trueTarget, BasicBlock* falseTarget)
698691
{
699692
assert(trueTarget != nullptr);
700-
// TODO-NoFallThrough: Allow falseTarget to diverge from bbNext
701-
assert(falseTarget == bbNext);
702693
bbKind = BBJ_COND;
703694
bbTrueTarget = trueTarget;
704695
bbFalseTarget = falseTarget;

src/coreclr/jit/codegenarm.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,13 @@ void CodeGen::genCodeForJTrue(GenTreeOp* jtrue)
13171317
regNumber reg = genConsumeReg(op);
13181318
inst_RV_RV(INS_tst, reg, reg, genActualType(op));
13191319
inst_JMP(EJ_ne, compiler->compCurBB->GetTrueTarget());
1320+
1321+
// If we cannot fall into the false target, emit a jump to it
1322+
BasicBlock* falseTarget = compiler->compCurBB->GetFalseTarget();
1323+
if (!compiler->compCurBB->CanRemoveJumpToTarget(falseTarget, compiler))
1324+
{
1325+
inst_JMP(EJ_jmp, falseTarget);
1326+
}
13201327
}
13211328

13221329
//------------------------------------------------------------------------

src/coreclr/jit/codegenarm64.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4708,6 +4708,13 @@ void CodeGen::genCodeForJTrue(GenTreeOp* jtrue)
47084708
GenTree* op = jtrue->gtGetOp1();
47094709
regNumber reg = genConsumeReg(op);
47104710
GetEmitter()->emitIns_J_R(INS_cbnz, emitActualTypeSize(op), compiler->compCurBB->GetTrueTarget(), reg);
4711+
4712+
// If we cannot fall into the false target, emit a jump to it
4713+
BasicBlock* falseTarget = compiler->compCurBB->GetFalseTarget();
4714+
if (!compiler->compCurBB->CanRemoveJumpToTarget(falseTarget, compiler))
4715+
{
4716+
inst_JMP(EJ_jmp, falseTarget);
4717+
}
47114718
}
47124719

47134720
//------------------------------------------------------------------------
@@ -4935,6 +4942,13 @@ void CodeGen::genCodeForJumpCompare(GenTreeOpCC* tree)
49354942

49364943
GetEmitter()->emitIns_J_R(ins, attr, compiler->compCurBB->GetTrueTarget(), reg);
49374944
}
4945+
4946+
// If we cannot fall into the false target, emit a jump to it
4947+
BasicBlock* falseTarget = compiler->compCurBB->GetFalseTarget();
4948+
if (!compiler->compCurBB->CanRemoveJumpToTarget(falseTarget, compiler))
4949+
{
4950+
inst_JMP(EJ_jmp, falseTarget);
4951+
}
49384952
}
49394953

49404954
//---------------------------------------------------------------------

src/coreclr/jit/codegencommon.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ void CodeGen::genMarkLabelsForCodegen()
396396
block->GetTrueTarget()->SetFlags(BBF_HAS_LABEL);
397397

398398
// If we need a jump to the false target, give it a label
399-
if (!block->CanRemoveJumpToFalseTarget(compiler))
399+
if (!block->CanRemoveJumpToTarget(block->GetFalseTarget(), compiler))
400400
{
401401
JITDUMP(" " FMT_BB " : branch target\n", block->GetFalseTarget()->bbNum);
402402
block->GetFalseTarget()->SetFlags(BBF_HAS_LABEL);

src/coreclr/jit/codegenlinear.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2643,9 +2643,10 @@ void CodeGen::genCodeForJcc(GenTreeCC* jcc)
26432643
inst_JCC(jcc->gtCondition, compiler->compCurBB->GetTrueTarget());
26442644

26452645
// If we cannot fall into the false target, emit a jump to it
2646-
if (!compiler->compCurBB->CanRemoveJumpToFalseTarget(compiler))
2646+
BasicBlock* falseTarget = compiler->compCurBB->GetFalseTarget();
2647+
if (!compiler->compCurBB->CanRemoveJumpToTarget(falseTarget, compiler))
26472648
{
2648-
inst_JMP(EJ_jmp, compiler->compCurBB->GetFalseTarget());
2649+
inst_JMP(EJ_jmp, falseTarget);
26492650
}
26502651
}
26512652

src/coreclr/jit/codegenloongarch64.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4330,6 +4330,13 @@ void CodeGen::genCodeForJumpCompare(GenTreeOpCC* tree)
43304330
assert(regs != 0);
43314331

43324332
emit->emitIns_J(ins, compiler->compCurBB->GetTrueTarget(), regs); // 5-bits;
4333+
4334+
// If we cannot fall into the false target, emit a jump to it
4335+
BasicBlock* falseTarget = compiler->compCurBB->GetFalseTarget();
4336+
if (!compiler->compCurBB->CanRemoveJumpToTarget(falseTarget, compiler))
4337+
{
4338+
inst_JMP(EJ_jmp, falseTarget);
4339+
}
43334340
}
43344341

43354342
//---------------------------------------------------------------------
@@ -4884,6 +4891,16 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
48844891
assert(jcc->gtCondition.Is(GenCondition::EQ, GenCondition::NE));
48854892
instruction ins = jcc->gtCondition.Is(GenCondition::EQ) ? INS_bceqz : INS_bcnez;
48864893
emit->emitIns_J(ins, tgtBlock, (int)1 /* cc */);
4894+
4895+
if (compiler->compCurBB->KindIs(BBJ_COND))
4896+
{
4897+
// If we cannot fall into the false target, emit a jump to it
4898+
BasicBlock* falseTarget = compiler->compCurBB->GetFalseTarget();
4899+
if (!compiler->compCurBB->CanRemoveJumpToTarget(falseTarget, compiler))
4900+
{
4901+
inst_JMP(EJ_jmp, falseTarget);
4902+
}
4903+
}
48874904
}
48884905
break;
48894906

src/coreclr/jit/codegenriscv64.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4243,6 +4243,13 @@ void CodeGen::genCodeForJumpCompare(GenTreeOpCC* tree)
42434243
assert(regs != 0);
42444244

42454245
emit->emitIns_J(ins, compiler->compCurBB->GetTrueTarget(), regs); // 5-bits;
4246+
4247+
// If we cannot fall into the false target, emit a jump to it
4248+
BasicBlock* falseTarget = compiler->compCurBB->GetFalseTarget();
4249+
if (!compiler->compCurBB->CanRemoveJumpToTarget(falseTarget, compiler))
4250+
{
4251+
inst_JMP(EJ_jmp, falseTarget);
4252+
}
42464253
}
42474254

42484255
//---------------------------------------------------------------------

src/coreclr/jit/codegenxarch.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,13 @@ void CodeGen::genCodeForJTrue(GenTreeOp* jtrue)
14791479
regNumber reg = genConsumeReg(op);
14801480
inst_RV_RV(INS_test, reg, reg, genActualType(op));
14811481
inst_JMP(EJ_jne, compiler->compCurBB->GetTrueTarget());
1482+
1483+
// If we cannot fall into the false target, emit a jump to it
1484+
BasicBlock* falseTarget = compiler->compCurBB->GetFalseTarget();
1485+
if (!compiler->compCurBB->CanRemoveJumpToTarget(falseTarget, compiler))
1486+
{
1487+
inst_JMP(EJ_jmp, falseTarget);
1488+
}
14821489
}
14831490

14841491
//------------------------------------------------------------------------

src/coreclr/jit/compiler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,7 +2189,7 @@ class FlowGraphNaturalLoop
21892189
bool HasDef(unsigned lclNum);
21902190

21912191
bool CanDuplicate(INDEBUG(const char** reason));
2192-
void Duplicate(BasicBlock** insertAfter, BlockToBlockMap* map, weight_t weightScale, bool bottomNeedsRedirection);
2192+
void Duplicate(BasicBlock** insertAfter, BlockToBlockMap* map, weight_t weightScale);
21932193

21942194
#ifdef DEBUG
21952195
static void Dump(FlowGraphNaturalLoop* loop);
@@ -6783,7 +6783,7 @@ class Compiler
67836783
bool optCompactLoop(FlowGraphNaturalLoop* loop);
67846784
BasicBlock* optFindLoopCompactionInsertionPoint(FlowGraphNaturalLoop* loop, BasicBlock* top);
67856785
BasicBlock* optTryAdvanceLoopCompactionInsertionPoint(FlowGraphNaturalLoop* loop, BasicBlock* insertionPoint, BasicBlock* top, BasicBlock* bottom);
6786-
bool optLoopCompactionFixupFallThrough(BasicBlock* block, BasicBlock* oldNext, BasicBlock* newNext);
6786+
bool optLoopCompactionFixupFallThrough(BasicBlock* block, BasicBlock* newNext);
67876787
bool optCreatePreheader(FlowGraphNaturalLoop* loop);
67886788
void optSetPreheaderWeight(FlowGraphNaturalLoop* loop, BasicBlock* preheader);
67896789

0 commit comments

Comments
 (0)