Skip to content

Commit

Permalink
JIT: Add successor edge iterators; remove old fgReplacePred (#99097)
Browse files Browse the repository at this point in the history
Part of #93020. We already have successor block iterators, but being able to iterate by successor edge grants us easy access to the edges themselves (i.e. no fgGetPredForBlock required). This also allows us to get rid of the old version of fgReplacePred, which had to look up the successor edge.

To reduce code duplication between the successor block/edge iterators, I moved the members of BBSuccList into an abstract class so the corresponding edge iterator type can inherit from it.
  • Loading branch information
amanasifkhalid authored Feb 29, 2024
1 parent f75c972 commit d112020
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 140 deletions.
61 changes: 45 additions & 16 deletions src/coreclr/jit/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1203,15 +1203,15 @@ unsigned BasicBlock::NumSucc() const
}

//------------------------------------------------------------------------
// GetSucc: Returns the requested block successor. See the declaration comment for details.
// GetSucc: Returns the requested successor edge. See the declaration comment for details.
//
// Arguments:
// i - index of successor to return. 0 <= i <= NumSucc().
//
// Return Value:
// Requested successor block
// Requested successor edge
//
BasicBlock* BasicBlock::GetSucc(unsigned i) const
FlowEdge* BasicBlock::GetSuccEdge(unsigned i) const
{
assert(i < NumSucc()); // Index bounds check.
switch (bbKind)
Expand All @@ -1222,31 +1222,45 @@ BasicBlock* BasicBlock::GetSucc(unsigned i) const
case BBJ_EHCATCHRET:
case BBJ_EHFILTERRET:
case BBJ_LEAVE:
return GetTarget();
return GetTargetEdge();

case BBJ_COND:
if (i == 0)
{
return GetFalseTarget();
return GetFalseEdge();
}
else
{
assert(i == 1);
assert(bbTrueEdge != bbFalseEdge);
return GetTrueTarget();
return GetTrueEdge();
}

case BBJ_EHFINALLYRET:
return bbEhfTargets->bbeSuccs[i]->getDestinationBlock();
return bbEhfTargets->bbeSuccs[i];

case BBJ_SWITCH:
return bbSwtTargets->bbsDstTab[i]->getDestinationBlock();
return bbSwtTargets->bbsDstTab[i];

default:
unreached();
}
}

//------------------------------------------------------------------------
// GetSucc: Returns the requested block successor. See the declaration comment for details.
//
// Arguments:
// i - index of successor to return. 0 <= i <= NumSucc().
//
// Return Value:
// Requested successor block
//
BasicBlock* BasicBlock::GetSucc(unsigned i) const
{
return GetSuccEdge(i)->getDestinationBlock();
}

//------------------------------------------------------------------------
// NumSucc: Returns the count of block successors. See the declaration comment for details.
//
Expand Down Expand Up @@ -1314,16 +1328,16 @@ unsigned BasicBlock::NumSucc(Compiler* comp)
}

//------------------------------------------------------------------------
// GetSucc: Returns the requested block successor. See the declaration comment for details.
// GetSucc: Returns the requested successor edge. See the declaration comment for details.
//
// Arguments:
// i - index of successor to return. 0 <= i <= NumSucc(comp).
// comp - Compiler instance
//
// Return Value:
// Requested successor block
// Requested successor edge
//
BasicBlock* BasicBlock::GetSucc(unsigned i, Compiler* comp)
FlowEdge* BasicBlock::GetSuccEdge(unsigned i, Compiler* comp)
{
assert(comp != nullptr);

Expand All @@ -1333,30 +1347,30 @@ BasicBlock* BasicBlock::GetSucc(unsigned i, Compiler* comp)
case BBJ_EHFILTERRET:
// Handler is the (sole) normal successor of the filter.
assert(comp->fgFirstBlockOfHandler(this) == GetTarget());
return GetTarget();
return GetTargetEdge();

case BBJ_EHFINALLYRET:
assert(bbEhfTargets != nullptr);
assert(i < bbEhfTargets->bbeCount);
return bbEhfTargets->bbeSuccs[i]->getDestinationBlock();
return bbEhfTargets->bbeSuccs[i];

case BBJ_CALLFINALLY:
case BBJ_CALLFINALLYRET:
case BBJ_ALWAYS:
case BBJ_EHCATCHRET:
case BBJ_LEAVE:
return GetTarget();
return GetTargetEdge();

case BBJ_COND:
if (i == 0)
{
return GetFalseTarget();
return GetFalseEdge();
}
else
{
assert(i == 1);
assert(bbTrueEdge != bbFalseEdge);
return GetTrueTarget();
return GetTrueEdge();
}

case BBJ_SWITCH:
Expand All @@ -1371,6 +1385,21 @@ BasicBlock* BasicBlock::GetSucc(unsigned i, Compiler* comp)
}
}

//------------------------------------------------------------------------
// GetSucc: Returns the requested block successor. See the declaration comment for details.
//
// Arguments:
// i - index of successor to return. 0 <= i <= NumSucc(comp).
// comp - Compiler instance
//
// Return Value:
// Requested successor block
//
BasicBlock* BasicBlock::GetSucc(unsigned i, Compiler* comp)
{
return GetSuccEdge(i, comp)->getDestinationBlock();
}

void BasicBlock::InitVarSets(Compiler* comp)
{
VarSetOps::AssignNoCopy(comp, bbVarUse, VarSetOps::MakeEmpty(comp));
Expand Down
Loading

0 comments on commit d112020

Please sign in to comment.