Merge remote-tracking branch 'origin/GP-4582_SwitchGotoLoop' into patch

(Closes #6282)
This commit is contained in:
Ryan Kurtz 2024-06-12 11:12:01 -04:00
commit 6ede2b498f
3 changed files with 38 additions and 16 deletions

View File

@ -1674,13 +1674,20 @@ BlockMultiGoto *BlockGraph::newBlockMultiGoto(FlowBlock *bl,int4 outedge)
}
else {
ret = new BlockMultiGoto(bl);
int4 origSizeOut = bl->sizeOut();
vector<FlowBlock *> nodes;
nodes.push_back(bl);
identifyInternal(ret,nodes);
addBlock(ret);
ret->addEdge(targetbl);
if (targetbl != bl) // If the target is itself, edge is already removed by identifyInternal
removeEdge(ret,targetbl);
if (targetbl != bl) {
if (ret->sizeOut() != origSizeOut) { // If there are less out edges after identifyInternal
// it must have collapsed a self edge (switch out edges are already deduped)
ret->forceOutputNum(ret->sizeOut()+1); // preserve the self edge (it is not the goto edge)
}
removeEdge(ret,targetbl); // Remove the edge to the goto target
}
// else -- the goto edge is a self edge and will get removed by identifyInternal
if (isdefaultedge)
ret->setDefaultGoto();
}

View File

@ -84,12 +84,14 @@ void LoopBody::extendToContainer(const LoopBody &container,vector<FlowBlock *> &
}
}
/// This updates the \b head and \b tail nodes to FlowBlock in the current collapsed graph.
/// This returns the first \b tail and passes back the head.
/// \param top is where \b head is passed back
/// This updates the \b head node to the FlowBlock in the current collapsed graph.
/// The \b tail nodes are also updated until one is found that has not collapsed into \b head.
/// This first updated \b tail is returned. The loop may still exist as a \b head node with an
/// out edge back into itself, in which case \b head is returned as the active \b tail.
/// If the loop has been completely collapsed, null is returned.
/// \param graph is the containing control-flow structure
/// \return the current loop \b head
FlowBlock *LoopBody::getCurrentBounds(FlowBlock **top,FlowBlock *graph)
/// \return the current loop \b tail or null
FlowBlock *LoopBody::update(FlowBlock *graph)
{
while(head->getParent() != graph)
@ -101,10 +103,13 @@ FlowBlock *LoopBody::getCurrentBounds(FlowBlock **top,FlowBlock *graph)
bottom = bottom->getParent();
tails[i] = bottom;
if (bottom != head) { // If the loop hasn't been fully collapsed yet
*top = head;
return bottom;
}
}
for(int4 i=head->sizeOut()-1;i>=0;--i) {
if (head->getOut(i) == head) // Check for head looping with itself
return head;
}
return (FlowBlock *)0;
}
@ -391,17 +396,17 @@ void LoopBody::emitLikelyEdges(list<FloatingEdge> &likely,FlowBlock *graph)
break;
}
}
likely.push_back(FloatingEdge(inbl,outbl));
likely.emplace_back(inbl,outbl);
}
for(int4 i=tails.size()-1;i>=0;--i) { // Go in reverse order, to put out less preferred back-edges first
if ((holdin!=(FlowBlock *)0)&&(i==0))
likely.push_back(FloatingEdge(holdin,holdout)); // Put in delayed exit, right before final backedge
likely.emplace_back(holdin,holdout); // Put in delayed exit, right before final backedge
FlowBlock *tail = tails[i];
int4 sizeout = tail->sizeOut();
for(int4 j=0;j<sizeout;++j) {
FlowBlock *bl = tail->getOut(j);
if (bl == head) // If out edge to head (back-edge for this loop)
likely.push_back(FloatingEdge(tail,head)); // emit it
likely.emplace_back(tail,head); // emit it
}
}
}
@ -652,7 +657,7 @@ void TraceDAG::removeTrace(BlockTrace *trace)
{
// Record that we should now treat this edge like goto
likelygoto.push_back(FloatingEdge(trace->bottom,trace->destnode)); // Create goto record
likelygoto.emplace_back(trace->bottom,trace->destnode); // Create goto record
trace->destnode->setVisitCount( trace->destnode->getVisitCount() + trace->edgelump ); // Ignore edge(s)
BranchPoint *parentbp = trace->top;
@ -1194,11 +1199,21 @@ bool CollapseStructure::updateLoopBody(void)
FlowBlock *loopbottom = (FlowBlock *)0;
FlowBlock *looptop = (FlowBlock *)0;
while (loopbodyiter != loopbody.end()) { // Last innermost loop
loopbottom = (*loopbodyiter).getCurrentBounds(&looptop,&graph);
LoopBody &curBody( *loopbodyiter );
loopbottom = curBody.update(&graph);
if (loopbottom != (FlowBlock *)0) {
if ((!likelylistfull) ||
(likelyiter != likelygoto.end())) // Reaching here means, we removed edges but loop still didn't collapse
looptop = curBody.getHead();
if (loopbottom == looptop) { // Check for single node looping back to itself
// If sizeout is 1 or 2, the loop would have collapsed, so the node is likely a switch.
likelygoto.clear();
likelygoto.emplace_back(looptop,looptop); // Mark the loop edge as a goto
likelyiter = likelygoto.begin();
likelylistfull = true;
return true;
}
if (!likelylistfull || likelyiter != likelygoto.end()) {
break; // Loop still exists
}
}
++loopbodyiter;
likelylistfull = false; // Need to generate likely list for new loopbody (or no loopbody)

View File

@ -55,7 +55,7 @@ class LoopBody {
public:
LoopBody(FlowBlock *h) { head=h; immed_container = (LoopBody *)0; depth=0; } ///< Construct with a loop head
FlowBlock *getHead(void) const { return head; } ///< Return the head FlowBlock of the loop
FlowBlock *getCurrentBounds(FlowBlock **top,FlowBlock *graph); ///< Return current loop bounds (\b head and \b bottom).
FlowBlock *update(FlowBlock *graph); ///< Update loop body to current view
void addTail(FlowBlock *bl) { tails.push_back(bl); } ///< Add a \e tail to the loop
FlowBlock *getExitBlock(void) const { return exitblock; } ///< Get the exit FlowBlock or NULL
void findBase(vector<FlowBlock *> &body); ///< Mark the body FlowBlocks of \b this loop