@@ -449,6 +449,7 @@ class SPIRVStructurizer : public FunctionPass {
449
449
createAliasBlocksForComplexEdges (std::vector<Edge> Edges) {
450
450
std::unordered_map<BasicBlock *, BasicBlock *> Seen;
451
451
std::vector<Edge> Output;
452
+ Output.reserve (Edges.size ());
452
453
453
454
for (auto &[Src, Dst] : Edges) {
454
455
auto [iterator, inserted] = Seen.insert ({Src, Dst});
@@ -613,6 +614,8 @@ class SPIRVStructurizer : public FunctionPass {
613
614
// adding an unreachable merge block.
614
615
if (Merge == nullptr ) {
615
616
BranchInst *Br = cast<BranchInst>(BB.getTerminator ());
617
+ assert (Br &&
618
+ " This assumes the branch is not a switch. Maybe that's wrong?" );
616
619
assert (cast<BranchInst>(BB.getTerminator ())->isUnconditional ());
617
620
618
621
Merge = CreateUnreachable (F);
@@ -864,20 +867,21 @@ class SPIRVStructurizer : public FunctionPass {
864
867
865
868
// Fixup the construct |Node| to respect a set of rules defined by the SPIR-V
866
869
// spec.
867
- void fixupConstruct (Splitter &S, DivergentConstruct *Node) {
870
+ bool fixupConstruct (Splitter &S, DivergentConstruct *Node) {
871
+ bool Modified = false ;
868
872
for (auto &Child : Node->Children )
869
- fixupConstruct (S, Child.get ());
873
+ Modified |= fixupConstruct (S, Child.get ());
870
874
871
875
// This construct is the root construct. Does not represent any real
872
876
// construct, just a way to access the first level of the forest.
873
877
if (Node->Parent == nullptr )
874
- return ;
878
+ return Modified ;
875
879
876
880
// This node's parent is the root. Meaning this is a top-level construct.
877
881
// There can be multiple exists, but all are guaranteed to exit at most 1
878
882
// construct since we are at first level.
879
883
if (Node->Parent ->Header == nullptr )
880
- return ;
884
+ return Modified ;
881
885
882
886
// Health check for the structure.
883
887
assert (Node->Header && Node->Merge );
@@ -888,7 +892,7 @@ class SPIRVStructurizer : public FunctionPass {
888
892
889
893
// No edges exiting the construct.
890
894
if (Edges.size () < 1 )
891
- return ;
895
+ return Modified ;
892
896
893
897
bool HasBadEdge = Node->Merge == Node->Parent ->Merge ||
894
898
Node->Merge == Node->Parent ->Continue ;
@@ -914,7 +918,7 @@ class SPIRVStructurizer : public FunctionPass {
914
918
}
915
919
916
920
if (!HasBadEdge)
917
- return ;
921
+ return Modified ;
918
922
919
923
// Create a single exit node gathering all exit edges.
920
924
BasicBlock *NewExit = S.createSingleExitNode (Node->Header , Edges);
@@ -940,6 +944,7 @@ class SPIRVStructurizer : public FunctionPass {
940
944
Node->Merge = NewExit;
941
945
// Regenerate the dom trees.
942
946
S.invalidate ();
947
+ return true ;
943
948
}
944
949
945
950
bool splitCriticalEdges (Function &F) {
@@ -949,9 +954,7 @@ class SPIRVStructurizer : public FunctionPass {
949
954
DivergentConstruct Root;
950
955
BlockSet Visited;
951
956
constructDivergentConstruct (Visited, S, &*F.begin (), &Root);
952
- fixupConstruct (S, &Root);
953
-
954
- return true ;
957
+ return fixupConstruct (S, &Root);
955
958
}
956
959
957
960
// Simplify branches when possible:
@@ -1170,7 +1173,7 @@ class SPIRVStructurizer : public FunctionPass {
1170
1173
1171
1174
// STEP 3:
1172
1175
// Sort selection merge, the largest construct goes first.
1173
- // This simpligies the next step.
1176
+ // This simplifies the next step.
1174
1177
Modified |= sortSelectionMergeHeaders (F);
1175
1178
1176
1179
// STEP 4: As this stage, we can have a single basic block with multiple
0 commit comments