@@ -411,7 +411,7 @@ class SPIRVStructurizer : public FunctionPass {
411
411
}
412
412
413
413
// 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 .
415
415
//
416
416
// clang-format off
417
417
//
@@ -424,13 +424,12 @@ class SPIRVStructurizer : public FunctionPass {
424
424
// A -> D -> C
425
425
// B -> D -> C
426
426
//
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.
429
429
// A -> D -> D1 -> C
430
430
// B -> D -> D2 -> C
431
431
//
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.
434
433
//
435
434
// clang-format on
436
435
std::vector<Edge>
@@ -469,11 +468,7 @@ class SPIRVStructurizer : public FunctionPass {
469
468
// |Edges|, creates a new single exit node, fixing up those edges.
470
469
BasicBlock *createSingleExitNode (BasicBlock *Header,
471
470
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
+
477
472
std::vector<Edge> FixedEdges = createAliasBlocksForComplexEdges (Edges);
478
473
479
474
std::vector<BasicBlock *> Dsts;
@@ -1012,17 +1007,8 @@ class SPIRVStructurizer : public FunctionPass {
1012
1007
return Modified;
1013
1008
}
1014
1009
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.
1026
1012
bool removeUselessBlocks (Function &F) {
1027
1013
std::vector<BasicBlock *> ToRemove;
1028
1014
@@ -1039,9 +1025,6 @@ class SPIRVStructurizer : public FunctionPass {
1039
1025
if (MergeBlocks.count (&BB) != 0 || ContinueBlocks.count (&BB) != 0 )
1040
1026
continue ;
1041
1027
1042
- if (IsRequiredForPhiNode (&BB))
1043
- continue ;
1044
-
1045
1028
if (BB.getUniqueSuccessor () == nullptr )
1046
1029
continue ;
1047
1030
0 commit comments