@@ -411,7 +411,7 @@ class SPIRVStructurizer : public FunctionPass {
411411 }
412412
413413 // Splits the given edges by recreating proxy nodes so that the destination
414- // OpPhi instruction can still be viable .
414+ // has unique incoming edges from this region .
415415 //
416416 // clang-format off
417417 //
@@ -424,13 +424,12 @@ class SPIRVStructurizer : public FunctionPass {
424424 // A -> D -> C
425425 // B -> D -> C
426426 //
427- // But if C had a phi node, adding such proxy-block breaks it. In such case, we must add 1 new block per
428- // exit, and patchup the phi node:
427+ // This is fine (assuming C has no PHI nodes), but requires handling the merge instruction here.
428+ // By adding a proxy node, we create a regular divergent shape which can easily be regularized later on.
429429 // A -> D -> D1 -> C
430430 // B -> D -> D2 -> C
431431 //
432- // A, B, D belongs to the construct. D is the exit. D1 and D2 are empty, just used as
433- // source operands for C's phi node.
432+ // A, B, D belongs to the construct. D is the exit. D1 and D2 are empty.
434433 //
435434 // clang-format on
436435 std::vector<Edge>
@@ -469,11 +468,7 @@ class SPIRVStructurizer : public FunctionPass {
469468 // |Edges|, creates a new single exit node, fixing up those edges.
470469 BasicBlock *createSingleExitNode (BasicBlock *Header,
471470 std::vector<Edge> &Edges) {
472- // Given 2 edges: Src1 -> Dst, Src2 -> Dst:
473- // If Dst has an PHI node, and Src1 and Src2 are both operands, both Src1
474- // and Src2 cannot be hidden by NewExit. Create 2 new nodes: Alias1,
475- // Alias2 to which NewExit will branch before going to Dst. Then, patchup
476- // Dst PHI node to look for Alias1 and Alias2.
471+
477472 std::vector<Edge> FixedEdges = createAliasBlocksForComplexEdges (Edges);
478473
479474 std::vector<BasicBlock *> Dsts;
@@ -1012,17 +1007,8 @@ class SPIRVStructurizer : public FunctionPass {
10121007 return Modified;
10131008 }
10141009
1015- bool IsRequiredForPhiNode (BasicBlock *BB) {
1016- for (BasicBlock *Successor : successors (BB)) {
1017- for (PHINode &Phi : Successor->phis ()) {
1018- if (Phi.getBasicBlockIndex (BB) != -1 )
1019- return true ;
1020- }
1021- }
1022-
1023- return false ;
1024- }
1025-
1010+ // Removes blocks not contributing to any structured CFG. This assumes there
1011+ // is no PHI nodes.
10261012 bool removeUselessBlocks (Function &F) {
10271013 std::vector<BasicBlock *> ToRemove;
10281014
@@ -1039,9 +1025,6 @@ class SPIRVStructurizer : public FunctionPass {
10391025 if (MergeBlocks.count (&BB) != 0 || ContinueBlocks.count (&BB) != 0 )
10401026 continue ;
10411027
1042- if (IsRequiredForPhiNode (&BB))
1043- continue ;
1044-
10451028 if (BB.getUniqueSuccessor () == nullptr )
10461029 continue ;
10471030
0 commit comments