@@ -909,7 +909,7 @@ ANode *ANode::getChildANode(ANode *parent)
909909//
910910// changed to
911911// goto L0
912- // L0:
912+ // L0: (new empty BB)
913913// L1:
914914// goto L1
915915// 2) avoid a fall-thru BB of a backward goto BB is the target BB of another
@@ -921,62 +921,99 @@ ANode *ANode::getChildANode(ANode *parent)
921921// changed to
922922// L0:
923923// (p0) goto L0
924- // L :
924+ // L : (new empty BB)
925925// L1 :
926926// (p1) goto L1
927+ // 3) make sure the last BB's pred is its physical predecessor.
928+ // In another word, if there is a case:
929+ // B0 : goto L1
930+ // ...
931+ // L0:
932+ // ...
933+ // B1: goto L0
934+ // L1:
935+ // ret
936+ // changed to
937+ // B0 : goto L
938+ // ...
939+ // L0:
940+ // ...
941+ // B1: goto L0
942+ // L: (new empty BB)
943+ // L1:
944+ // ret
945+ // This case is to guarantee that the last HG has its valid, non-null exit BB
946+ // except Basic block ANode. (Without this, the last HG isn't handled completely
947+ // with the current algo.)
927948void CFGStructurizer::preProcess ()
928949{
929950 bool CFGChanged = false ;
930951 for (BB_LIST_ITER BI = CFG->begin (), BE = CFG->end ();
931952 BI != BE; ++BI)
932953 {
954+ bool insertEmptyBBBefore = false ;
955+ bool isLastBB = (std::next (BI) == BE);
933956 G4_BB *B = *BI;
934- if (B->Preds .size () < 2 )
935- {
936- continue ;
937- }
938-
939- // Check if this B is a successor of both backward and forward branches.
940- bool isForwardTarget = false ;
941- bool isBackwardTarget = false ;
942- bool isFallThruOfBackwardGotoBB = false ;
943957 BB_LIST_ITER IT, IE;
944- for (IT = B-> Preds . begin (), IE = B-> Preds . end (); IT != IE; IT++ )
958+ if (isLastBB )
945959 {
946- G4_BB* P = *IT;
947- if (P-> getId () >= B-> getId () )
960+ // case 3
961+ if (B-> Preds . size () >= 2 )
948962 {
949- isBackwardTarget = true ;
950- continue ;
963+ // Maybe too conservative, but shouldn't cause any perf change!
964+ insertEmptyBBBefore = true ;
965+ }
966+ else if (B->Preds .size () == 1 )
967+ {
968+ G4_BB* phyPred = B->getPhysicalPred ();
969+ G4_BB* pred = B->Preds .back ();
970+ insertEmptyBBBefore = (phyPred != pred);
951971 }
952- // P is a BB before B
953- G4_INST *gotoInst = getGotoInst (B);
954- G4_INST* gotoInstP = getGotoInst (P);
955- if (gotoInst && P->getPhysicalSucc () != B)
972+ }
973+
974+ if (!insertEmptyBBBefore && B->Preds .size () >= 2 )
975+ {
976+ // case 1 & 2
977+ // Check if this B is a successor of both backward and forward branches.
978+ bool isForwardTarget = false ;
979+ bool isBackwardTarget = false ;
980+ bool isFallThruOfBackwardGotoBB = false ;
981+ for (IT = B->Preds .begin (), IE = B->Preds .end (); IT != IE; IT++)
956982 {
957- isForwardTarget = true ;
983+ G4_BB* P = *IT;
984+ if (P->getId () >= B->getId ())
985+ {
986+ isBackwardTarget = true ;
987+ continue ;
988+ }
989+ // P is a BB before B
990+ G4_INST* gotoInstP = getGotoInst (P);
991+ if (gotoInstP && P->getPhysicalSucc () != B)
992+ {
993+ isForwardTarget = true ;
994+ }
995+ else if (gotoInstP
996+ && P->getPhysicalSucc () == B
997+ && gotoInstP->asCFInst ()->isBackward ())
998+ {
999+ isFallThruOfBackwardGotoBB = true ;
1000+ }
9581001 }
959- else if (gotoInstP
960- && P-> getPhysicalSucc () == B
961- && gotoInstP-> asCFInst ()-> isBackward ())
1002+
1003+ if ( (isBackwardTarget && isForwardTarget) // case 1
1004+ || (isBackwardTarget && isFallThruOfBackwardGotoBB)) // case 2
9621005 {
963- isFallThruOfBackwardGotoBB = true ;
1006+ insertEmptyBBBefore = true ;
9641007 }
9651008 }
9661009
967- if ( !(isBackwardTarget && isForwardTarget) // case 1
968- && !(isBackwardTarget && isFallThruOfBackwardGotoBB)) // case 2
1010+ if (!insertEmptyBBBefore)
9691011 {
970- // not candidate
9711012 continue ;
9721013 }
9731014
974- // "B" is the target of both forward and backward branching, or is the
975- // target of a backward branching and also the fall-thru of another
976- // backward goto BB.
977- //
978- // Create an empty BB right before "B", and adjust all forward
979- // branching to this new BB.
1015+ // Now, create an empty BB right before "B", and adjust all forward
1016+ // branching to this new BB and leave all backward branching unchanged.
9801017 G4_BB *newBB = createBBWithLabel ();
9811018 G4_Label *newLabel = newBB->getLabel ();
9821019
@@ -2534,7 +2571,9 @@ void CFGStructurizer::constructPST(BB_LIST_ITER IB, BB_LIST_ITER IE)
25342571 G4_BB *bb = *II;
25352572 ANodeBB *ndbb = getANodeBB (bb);
25362573
2537- // Do the following cases in order:
2574+ // Do the following cases in order. (Note that bb should be part of
2575+ // the current pending ANode (top of ANStack), although it could
2576+ // be the beginning node of the new inner ANode.)
25382577 //
25392578 // 1: If bb is the target of some gotos, that is, the end of
25402579 // some CGs, merge the current bb into ANStack nodes of
@@ -2548,15 +2587,16 @@ void CFGStructurizer::constructPST(BB_LIST_ITER IB, BB_LIST_ITER IE)
25482587 // cg that is associated with a backward goto, a forward
25492588 // conditional goto, and the root (first) forward unconditional
25502589 // goto. No new HG is created for a non-root unconditional
2551- // goto (see details in code).
2590+ // goto (see details in code). This is where an inner HG is formed.)
25522591 //
25532592 // 3: Add bb into this node as it is part of node. If bb can
25542593 // be merged with its pred, merge it. The new node's type
25552594 // must be type AN_SEQUENCE.
25562595 //
25572596 // 4: Check if bb is the end of the node. If it is, finalize the
2558- // node. If it is not, go on to process the next BB and continue
2559- // the next iteration.
2597+ // node. If it is not, go on to process the next BB in the next
2598+ // iteration (This implies that if the next BB should be part
2599+ // of the current pending HG in ANStack).
25602600 //
25612601
25622602 // case 1.
0 commit comments