Skip to content

Commit 22d034f

Browse files
JIT: Make BasicBlock::bbPrev and bbNext private (#93032)
Follow-up to #92908, and next step for #93020.
1 parent 211bc24 commit 22d034f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+730
-674
lines changed

src/coreclr/jit/assertionprop.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5268,7 +5268,7 @@ class AssertionPropFlowCallback
52685268
{
52695269
// Scenario where next block and conditional block, both point to the same block.
52705270
// In such case, intersect the assertions present on both the out edges of predBlock.
5271-
assert(predBlock->bbNext == block);
5271+
assert(predBlock->NextIs(block));
52725272
BitVecOps::IntersectionD(apTraits, pAssertionOut, predBlock->bbAssertionOut);
52735273

52745274
if (VerboseDataflow())

src/coreclr/jit/block.cpp

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ FlowEdge* Compiler::BlockPredsWithEH(BasicBlock* blk)
133133
// these cannot cause transfer to the handler...)
134134
// TODO-Throughput: It would be nice if we could iterate just over the blocks in the try, via
135135
// something like:
136-
// for (BasicBlock* bb = ehblk->ebdTryBeg; bb != ehblk->ebdTryLast->bbNext; bb = bb->bbNext)
136+
// for (BasicBlock* bb = ehblk->ebdTryBeg; bb != ehblk->ebdTryLast->Next(); bb = bb->Next())
137137
// (plus adding in any filter blocks outside the try whose exceptions are handled here).
138138
// That doesn't work, however: funclets have caused us to sometimes split the body of a try into
139139
// more than one sequence of contiguous blocks. We need to find a better way to do this.
@@ -160,7 +160,7 @@ FlowEdge* Compiler::BlockPredsWithEH(BasicBlock* blk)
160160
if (enclosingDsc->HasFilter())
161161
{
162162
for (BasicBlock* filterBlk = enclosingDsc->ebdFilter; filterBlk != enclosingDsc->ebdHndBeg;
163-
filterBlk = filterBlk->bbNext)
163+
filterBlk = filterBlk->Next())
164164
{
165165
res = new (this, CMK_FlowEdge) FlowEdge(filterBlk, res);
166166

@@ -186,6 +186,36 @@ FlowEdge* Compiler::BlockPredsWithEH(BasicBlock* blk)
186186
return res;
187187
}
188188

189+
//------------------------------------------------------------------------
190+
// IsLastHotBlock: see if this is the last block before the cold section
191+
//
192+
// Arguments:
193+
// compiler - current compiler instance
194+
//
195+
// Returns:
196+
// true if the next block is fgFirstColdBlock
197+
// (if fgFirstColdBlock is null, this call is equivalent to IsLast())
198+
//
199+
bool BasicBlock::IsLastHotBlock(Compiler* compiler) const
200+
{
201+
return (bbNext == compiler->fgFirstColdBlock);
202+
}
203+
204+
//------------------------------------------------------------------------
205+
// IsFirstColdBlock: see if this is the first block in the cold section
206+
//
207+
// Arguments:
208+
// compiler - current compiler instance
209+
//
210+
// Returns:
211+
// true if this is fgFirstColdBlock
212+
// (fgFirstColdBlock is null if there is no cold code)
213+
//
214+
bool BasicBlock::IsFirstColdBlock(Compiler* compiler) const
215+
{
216+
return (this == compiler->fgFirstColdBlock);
217+
}
218+
189219
//------------------------------------------------------------------------
190220
// checkPredListOrder: see if pred list is properly ordered
191221
//
@@ -1509,10 +1539,10 @@ bool BasicBlock::isBBCallAlwaysPair() const
15091539
assert(!(this->bbFlags & BBF_RETLESS_CALL));
15101540
#endif
15111541
// Some asserts that the next block is a BBJ_ALWAYS of the proper form.
1512-
assert(this->bbNext != nullptr);
1513-
assert(this->bbNext->KindIs(BBJ_ALWAYS));
1514-
assert(this->bbNext->bbFlags & BBF_KEEP_BBJ_ALWAYS);
1515-
assert(this->bbNext->isEmpty());
1542+
assert(!this->IsLast());
1543+
assert(this->Next()->KindIs(BBJ_ALWAYS));
1544+
assert(this->Next()->bbFlags & BBF_KEEP_BBJ_ALWAYS);
1545+
assert(this->Next()->isEmpty());
15161546

15171547
return true;
15181548
}

src/coreclr/jit/block.h

Lines changed: 78 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -508,10 +508,49 @@ struct BasicBlock : private LIR::Range
508508
{
509509
friend class LIR;
510510

511+
private:
511512
BasicBlock* bbNext; // next BB in ascending PC offset order
512513
BasicBlock* bbPrev;
513514

514-
void setNext(BasicBlock* next)
515+
BBjumpKinds bbJumpKind; // jump (if any) at the end of this block
516+
517+
public:
518+
BBjumpKinds GetBBJumpKind() const
519+
{
520+
return bbJumpKind;
521+
}
522+
523+
void SetBBJumpKind(BBjumpKinds kind DEBUG_ARG(Compiler* compiler))
524+
{
525+
#ifdef DEBUG
526+
// BBJ_NONE should only be assigned when optimizing jumps in Compiler::optOptimizeLayout
527+
// TODO: Change assert to check if compiler is in appropriate optimization phase to use BBJ_NONE
528+
// (right now, this assertion does the null check to avoid unused variable warnings)
529+
assert((kind != BBJ_NONE) || (compiler != nullptr));
530+
#endif // DEBUG
531+
bbJumpKind = kind;
532+
}
533+
534+
BasicBlock* Prev() const
535+
{
536+
return bbPrev;
537+
}
538+
539+
void SetPrev(BasicBlock* prev)
540+
{
541+
bbPrev = prev;
542+
if (prev)
543+
{
544+
prev->bbNext = this;
545+
}
546+
}
547+
548+
BasicBlock* Next() const
549+
{
550+
return bbNext;
551+
}
552+
553+
void SetNext(BasicBlock* next)
515554
{
516555
bbNext = next;
517556
if (next)
@@ -520,6 +559,37 @@ struct BasicBlock : private LIR::Range
520559
}
521560
}
522561

562+
bool IsFirst() const
563+
{
564+
return (bbPrev == nullptr);
565+
}
566+
567+
bool IsLast() const
568+
{
569+
return (bbNext == nullptr);
570+
}
571+
572+
bool PrevIs(BasicBlock* block) const
573+
{
574+
return (bbPrev == block);
575+
}
576+
577+
bool NextIs(BasicBlock* block) const
578+
{
579+
return (bbNext == block);
580+
}
581+
582+
bool IsLastHotBlock(Compiler* compiler) const;
583+
584+
bool IsFirstColdBlock(Compiler* compiler) const;
585+
586+
/* The following union describes the jump target(s) of this block */
587+
union {
588+
unsigned bbJumpOffs; // PC offset (temporary only)
589+
BasicBlock* bbJumpDest; // basic block
590+
BBswtDesc* bbJumpSwt; // switch descriptor
591+
};
592+
523593
BasicBlockFlags bbFlags;
524594

525595
static_assert_no_msg((BBF_SPLIT_NONEXIST & BBF_SPLIT_LOST) == 0);
@@ -702,33 +772,6 @@ struct BasicBlock : private LIR::Range
702772
// a block corresponding to an exit from the try of a try/finally.
703773
bool isBBCallAlwaysPairTail() const;
704774

705-
private:
706-
BBjumpKinds bbJumpKind; // jump (if any) at the end of this block
707-
708-
public:
709-
BBjumpKinds GetBBJumpKind() const
710-
{
711-
return bbJumpKind;
712-
}
713-
714-
void SetBBJumpKind(BBjumpKinds kind DEBUG_ARG(Compiler* comp))
715-
{
716-
#ifdef DEBUG
717-
// BBJ_NONE should only be assigned when optimizing jumps in Compiler::optOptimizeLayout
718-
// TODO: Change assert to check if comp is in appropriate optimization phase to use BBJ_NONE
719-
// (right now, this assertion does the null check to avoid unused variable warnings)
720-
assert((kind != BBJ_NONE) || (comp != nullptr));
721-
#endif // DEBUG
722-
bbJumpKind = kind;
723-
}
724-
725-
/* The following union describes the jump target(s) of this block */
726-
union {
727-
unsigned bbJumpOffs; // PC offset (temporary only)
728-
BasicBlock* bbJumpDest; // basic block
729-
BBswtDesc* bbJumpSwt; // switch descriptor
730-
};
731-
732775
bool KindIs(BBjumpKinds kind) const
733776
{
734777
return bbJumpKind == kind;
@@ -1435,10 +1478,10 @@ class BasicBlockIterator
14351478
{
14361479
assert(m_block != nullptr);
14371480
// Check that we haven't been spliced out of the list.
1438-
assert((m_block->bbNext == nullptr) || (m_block->bbNext->bbPrev == m_block));
1439-
assert((m_block->bbPrev == nullptr) || (m_block->bbPrev->bbNext == m_block));
1481+
assert(m_block->IsLast() || m_block->Next()->PrevIs(m_block));
1482+
assert(m_block->IsFirst() || m_block->Prev()->NextIs(m_block));
14401483

1441-
m_block = m_block->bbNext;
1484+
m_block = m_block->Next();
14421485
return *this;
14431486
}
14441487

@@ -1501,7 +1544,7 @@ class BasicBlockRangeList
15011544

15021545
BasicBlockIterator end() const
15031546
{
1504-
return BasicBlockIterator(m_end->bbNext); // walk until we see the block *following* the `m_end` block
1547+
return BasicBlockIterator(m_end->Next()); // walk until we see the block *following* the `m_end` block
15051548
}
15061549
};
15071550

@@ -1596,18 +1639,18 @@ inline BasicBlock::BBSuccList::BBSuccList(const BasicBlock* block)
15961639
break;
15971640

15981641
case BBJ_NONE:
1599-
m_succs[0] = block->bbNext;
1642+
m_succs[0] = block->Next();
16001643
m_begin = &m_succs[0];
16011644
m_end = &m_succs[1];
16021645
break;
16031646

16041647
case BBJ_COND:
1605-
m_succs[0] = block->bbNext;
1648+
m_succs[0] = block->Next();
16061649
m_begin = &m_succs[0];
16071650

16081651
// If both fall-through and branch successors are identical, then only include
16091652
// them once in the iteration (this is the same behavior as NumSucc()/GetSucc()).
1610-
if (block->bbJumpDest == block->bbNext)
1653+
if (block->NextIs(block->bbJumpDest))
16111654
{
16121655
m_end = &m_succs[1];
16131656
}

src/coreclr/jit/clrjit.natvis

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ Documentation for VS debugger format specifiers: https://docs.microsoft.com/en-u
105105
<Exec>varIndex++</Exec>
106106
<Exec>bbLiveInMap = bbLiveInMap >> 1</Exec>
107107
</Loop>
108-
<Exec>block = block->bbNext</Exec>
108+
<Exec>block = block->Next()</Exec>
109109
</Loop>
110110
</CustomListItems>
111111
<Item Name="outVarToRegMaps">"OutVarToRegMaps"</Item>
@@ -124,7 +124,7 @@ Documentation for VS debugger format specifiers: https://docs.microsoft.com/en-u
124124
<Exec>varIndex++</Exec>
125125
<Exec>bbLiveInMap = bbLiveInMap >> 1</Exec>
126126
</Loop>
127-
<Exec>block = block->bbNext</Exec>
127+
<Exec>block = block->Next()</Exec>
128128
</Loop>
129129
</CustomListItems>
130130
<Item Name="AvailableRegs mask">this-&gt;m_AvailableRegs</Item>

src/coreclr/jit/codegenarm.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,12 @@ BasicBlock* CodeGen::genCallFinally(BasicBlock* block)
123123
// we would have otherwise created retless calls.
124124
assert(block->isBBCallAlwaysPair());
125125

126-
assert(block->bbNext != NULL);
127-
assert(block->bbNext->KindIs(BBJ_ALWAYS));
128-
assert(block->bbNext->bbJumpDest != NULL);
129-
assert(block->bbNext->bbJumpDest->bbFlags & BBF_FINALLY_TARGET);
126+
assert(!block->IsLast());
127+
assert(block->Next()->KindIs(BBJ_ALWAYS));
128+
assert(block->Next()->bbJumpDest != NULL);
129+
assert(block->Next()->bbJumpDest->bbFlags & BBF_FINALLY_TARGET);
130130

131-
bbFinallyRet = block->bbNext->bbJumpDest;
131+
bbFinallyRet = block->Next()->bbJumpDest;
132132

133133
// Load the address where the finally funclet should return into LR.
134134
// The funclet prolog/epilog will do "push {lr}" / "pop {pc}" to do the return.
@@ -143,7 +143,7 @@ BasicBlock* CodeGen::genCallFinally(BasicBlock* block)
143143
// block is RETLESS.
144144
assert(!(block->bbFlags & BBF_RETLESS_CALL));
145145
assert(block->isBBCallAlwaysPair());
146-
return block->bbNext;
146+
return block->Next();
147147
}
148148

149149
//------------------------------------------------------------------------

src/coreclr/jit/codegenarm64.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2160,7 +2160,7 @@ BasicBlock* CodeGen::genCallFinally(BasicBlock* block)
21602160
}
21612161
GetEmitter()->emitIns_J(INS_bl_local, block->bbJumpDest);
21622162

2163-
BasicBlock* const nextBlock = block->bbNext;
2163+
BasicBlock* const nextBlock = block->Next();
21642164

21652165
if (block->bbFlags & BBF_RETLESS_CALL)
21662166
{
@@ -2184,7 +2184,7 @@ BasicBlock* CodeGen::genCallFinally(BasicBlock* block)
21842184
BasicBlock* const jumpDest = nextBlock->bbJumpDest;
21852185

21862186
// Now go to where the finally funclet needs to return to.
2187-
if ((jumpDest == nextBlock->bbNext) && !compiler->fgInDifferentRegions(nextBlock, jumpDest))
2187+
if (nextBlock->NextIs(jumpDest) && !compiler->fgInDifferentRegions(nextBlock, jumpDest))
21882188
{
21892189
// Fall-through.
21902190
// TODO-ARM64-CQ: Can we get rid of this instruction, and just have the call return directly

src/coreclr/jit/codegenarmarch.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3338,8 +3338,8 @@ void CodeGen::genCall(GenTreeCall* call)
33383338
#ifdef FEATURE_READYTORUN
33393339
else if (call->IsR2ROrVirtualStubRelativeIndir())
33403340
{
3341-
assert(((call->IsR2RRelativeIndir()) && (call->gtEntryPoint.accessType == IAT_PVALUE)) ||
3342-
((call->IsVirtualStubRelativeIndir()) && (call->gtEntryPoint.accessType == IAT_VALUE)));
3341+
assert((call->IsR2RRelativeIndir() && (call->gtEntryPoint.accessType == IAT_PVALUE)) ||
3342+
(call->IsVirtualStubRelativeIndir() && (call->gtEntryPoint.accessType == IAT_VALUE)));
33433343
assert(call->gtControlExpr == nullptr);
33443344

33453345
regNumber tmpReg = call->GetSingleTempReg();

0 commit comments

Comments
 (0)