forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[SimplifyCFG] Avoid increasing too many phi entries when removing emp…
…ty blocks (llvm#104887) Now in the simplifycfg and jumpthreading passes, we will remove the empty blocks (blocks only have phis and an unconditional branch). However, in some cases, this will increase size of the IR and slow down the compile of other passes dramatically. For example, we have the following CFG: 1. BB1 has 100 predecessors, and unconditionally branches to BB2 (does not have any other instructions). 2. BB2 has 100 phis. Then in this case, if we remove BB1, for every phi in BB2, we need to increase 99 entries (replace the incoming edge from BB1 with 100 edges from its predecessors). Then in total, we will increase 9900 phi entries, which can slow down the compile time for many other passes. Therefore, in this change, we add a check to see whether removing the empty blocks will increase lots of phi entries. Now, the threshold is 1000 (can be controlled by the command line option `max-phi-entries-increase-after-removing-empty-block`), which means that we will not remove an empty block if it will increase the total number of phi entries by 1000. This threshold is conservative and for most of the cases, we will not have such a large phi. So, this will only be triggered in some unusual IRs.
- Loading branch information
1 parent
4210efc
commit 476e028
Showing
2 changed files
with
198 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 | ||
; RUN: opt < %s -max-phi-entries-increase-after-removing-empty-block=12 -passes=simplifycfg -S | FileCheck --check-prefixes=CHECK-12 %s | ||
; RUN: opt < %s -max-phi-entries-increase-after-removing-empty-block=11 -passes=simplifycfg -S | FileCheck --check-prefixes=CHECK-11 %s | ||
; RUN: opt < %s -max-phi-entries-increase-after-removing-empty-block=4 -passes=simplifycfg -S | FileCheck --check-prefixes=CHECK-4 %s | ||
; | ||
; This test has the following CFG: | ||
; 1. entry has a switch to 4 blocks: B1 - B4 | ||
; 2. For B1 and B2, it branches to B5 and B6 | ||
; 3. For B3 and B4, it branches to B5 and B7 | ||
; 4. In B5, %val is defined as phi taking values from B1 to B4 | ||
; 5. B5, B6, B7 branch to block Merge unconditionally | ||
; 6. Block Merge has 5 phis(%x1 - %x4 and %val_merge). | ||
; | ||
; If we remove B5, %x1 - %x4 will increase the number of phi entries by (4 - 1) * 4 = 12. For %val_merge, since the value taking from B5 | ||
; is defined in B5, it will not increase the number of phi entries (it can be considered as move the entries from %val to | ||
; %val_merge). Therefore, removing B5 will increase the number of phi entries by 12 (not (4 - 1) * 5 = 15). | ||
; | ||
; If we remove B6 / B7, it will increase the number of phi entries by (2 - 1) * 5 = 5. | ||
; | ||
; In the first test, max-phi-entries-increase-after-removing-empty-block is set to be 12, then B5 will be removed. | ||
; In the second test, max-phi-entries-increase-after-removing-empty-block is set to be 11, then B5 should not be removed, | ||
; but B6 and B7 can be removed. | ||
; In the third test, max-phi-entries-increase-after-removing-empty-block is set to be 4, then no BB can be removed. | ||
; | ||
define void @foo(i32 %a, i32 %val1, i32 %val2, i32 %val3, i32 %val4) { | ||
; CHECK-12-LABEL: define void @foo( | ||
; CHECK-12-SAME: i32 [[A:%.*]], i32 [[VAL1:%.*]], i32 [[VAL2:%.*]], i32 [[VAL3:%.*]], i32 [[VAL4:%.*]]) { | ||
; CHECK-12-NEXT: [[ENTRY:.*:]] | ||
; CHECK-12-NEXT: switch i32 [[A]], label %[[B1:.*]] [ | ||
; CHECK-12-NEXT: i32 4, label %[[B4:.*]] | ||
; CHECK-12-NEXT: i32 2, label %[[B2:.*]] | ||
; CHECK-12-NEXT: i32 3, label %[[B3:.*]] | ||
; CHECK-12-NEXT: ] | ||
; CHECK-12: [[B1]]: | ||
; CHECK-12-NEXT: [[CMP1:%.*]] = icmp eq i32 [[VAL1]], 1 | ||
; CHECK-12-NEXT: br i1 [[CMP1]], label %[[B6:.*]], label %[[MERGE:.*]] | ||
; CHECK-12: [[B2]]: | ||
; CHECK-12-NEXT: [[CMP2:%.*]] = icmp eq i32 [[VAL2]], 2 | ||
; CHECK-12-NEXT: br i1 [[CMP2]], label %[[B6]], label %[[MERGE]] | ||
; CHECK-12: [[B3]]: | ||
; CHECK-12-NEXT: [[CMP3:%.*]] = icmp eq i32 [[VAL3]], 3 | ||
; CHECK-12-NEXT: br i1 [[CMP3]], label %[[B7:.*]], label %[[MERGE]] | ||
; CHECK-12: [[B4]]: | ||
; CHECK-12-NEXT: [[CMP4:%.*]] = icmp eq i32 [[VAL4]], 4 | ||
; CHECK-12-NEXT: br i1 [[CMP4]], label %[[B7]], label %[[MERGE]] | ||
; CHECK-12: [[B6]]: | ||
; CHECK-12-NEXT: br label %[[MERGE]] | ||
; CHECK-12: [[B7]]: | ||
; CHECK-12-NEXT: br label %[[MERGE]] | ||
; CHECK-12: [[MERGE]]: | ||
; CHECK-12-NEXT: [[X1:%.*]] = phi i16 [ 0, %[[B6]] ], [ 2, %[[B7]] ], [ 1, %[[B4]] ], [ 1, %[[B3]] ], [ 1, %[[B2]] ], [ 1, %[[B1]] ] | ||
; CHECK-12-NEXT: [[X2:%.*]] = phi i16 [ 0, %[[B6]] ], [ 2, %[[B7]] ], [ 2, %[[B4]] ], [ 2, %[[B3]] ], [ 2, %[[B2]] ], [ 2, %[[B1]] ] | ||
; CHECK-12-NEXT: [[X3:%.*]] = phi i16 [ 0, %[[B6]] ], [ 2, %[[B7]] ], [ 3, %[[B4]] ], [ 3, %[[B3]] ], [ 3, %[[B2]] ], [ 3, %[[B1]] ] | ||
; CHECK-12-NEXT: [[X4:%.*]] = phi i16 [ 0, %[[B6]] ], [ 2, %[[B7]] ], [ 4, %[[B4]] ], [ 4, %[[B3]] ], [ 4, %[[B2]] ], [ 4, %[[B1]] ] | ||
; CHECK-12-NEXT: [[VAL_MERGE:%.*]] = phi i32 [ 0, %[[B6]] ], [ 2, %[[B7]] ], [ [[VAL1]], %[[B1]] ], [ [[VAL2]], %[[B2]] ], [ [[VAL3]], %[[B3]] ], [ [[VAL4]], %[[B4]] ] | ||
; CHECK-12-NEXT: ret void | ||
; | ||
; CHECK-11-LABEL: define void @foo( | ||
; CHECK-11-SAME: i32 [[A:%.*]], i32 [[VAL1:%.*]], i32 [[VAL2:%.*]], i32 [[VAL3:%.*]], i32 [[VAL4:%.*]]) { | ||
; CHECK-11-NEXT: [[ENTRY:.*:]] | ||
; CHECK-11-NEXT: switch i32 [[A]], label %[[B1:.*]] [ | ||
; CHECK-11-NEXT: i32 4, label %[[B4:.*]] | ||
; CHECK-11-NEXT: i32 2, label %[[B2:.*]] | ||
; CHECK-11-NEXT: i32 3, label %[[B3:.*]] | ||
; CHECK-11-NEXT: ] | ||
; CHECK-11: [[B1]]: | ||
; CHECK-11-NEXT: [[CMP1:%.*]] = icmp eq i32 [[VAL1]], 1 | ||
; CHECK-11-NEXT: br i1 [[CMP1]], label %[[MERGE:.*]], label %[[B5:.*]] | ||
; CHECK-11: [[B2]]: | ||
; CHECK-11-NEXT: [[CMP2:%.*]] = icmp eq i32 [[VAL2]], 2 | ||
; CHECK-11-NEXT: br i1 [[CMP2]], label %[[MERGE]], label %[[B5]] | ||
; CHECK-11: [[B3]]: | ||
; CHECK-11-NEXT: [[CMP3:%.*]] = icmp eq i32 [[VAL3]], 3 | ||
; CHECK-11-NEXT: br i1 [[CMP3]], label %[[MERGE]], label %[[B5]] | ||
; CHECK-11: [[B4]]: | ||
; CHECK-11-NEXT: [[CMP4:%.*]] = icmp eq i32 [[VAL4]], 4 | ||
; CHECK-11-NEXT: br i1 [[CMP4]], label %[[MERGE]], label %[[B5]] | ||
; CHECK-11: [[B5]]: | ||
; CHECK-11-NEXT: [[VAL:%.*]] = phi i32 [ [[VAL1]], %[[B1]] ], [ [[VAL2]], %[[B2]] ], [ [[VAL3]], %[[B3]] ], [ [[VAL4]], %[[B4]] ] | ||
; CHECK-11-NEXT: br label %[[MERGE]] | ||
; CHECK-11: [[MERGE]]: | ||
; CHECK-11-NEXT: [[X1:%.*]] = phi i16 [ 1, %[[B5]] ], [ 0, %[[B2]] ], [ 0, %[[B1]] ], [ 2, %[[B4]] ], [ 2, %[[B3]] ] | ||
; CHECK-11-NEXT: [[X2:%.*]] = phi i16 [ 2, %[[B5]] ], [ 0, %[[B2]] ], [ 0, %[[B1]] ], [ 2, %[[B4]] ], [ 2, %[[B3]] ] | ||
; CHECK-11-NEXT: [[X3:%.*]] = phi i16 [ 3, %[[B5]] ], [ 0, %[[B2]] ], [ 0, %[[B1]] ], [ 2, %[[B4]] ], [ 2, %[[B3]] ] | ||
; CHECK-11-NEXT: [[X4:%.*]] = phi i16 [ 4, %[[B5]] ], [ 0, %[[B2]] ], [ 0, %[[B1]] ], [ 2, %[[B4]] ], [ 2, %[[B3]] ] | ||
; CHECK-11-NEXT: [[VAL_MERGE:%.*]] = phi i32 [ [[VAL]], %[[B5]] ], [ 0, %[[B2]] ], [ 0, %[[B1]] ], [ 2, %[[B4]] ], [ 2, %[[B3]] ] | ||
; CHECK-11-NEXT: ret void | ||
; | ||
; CHECK-4-LABEL: define void @foo( | ||
; CHECK-4-SAME: i32 [[A:%.*]], i32 [[VAL1:%.*]], i32 [[VAL2:%.*]], i32 [[VAL3:%.*]], i32 [[VAL4:%.*]]) { | ||
; CHECK-4-NEXT: [[ENTRY:.*:]] | ||
; CHECK-4-NEXT: switch i32 [[A]], label %[[B1:.*]] [ | ||
; CHECK-4-NEXT: i32 4, label %[[B4:.*]] | ||
; CHECK-4-NEXT: i32 2, label %[[B2:.*]] | ||
; CHECK-4-NEXT: i32 3, label %[[B3:.*]] | ||
; CHECK-4-NEXT: ] | ||
; CHECK-4: [[B1]]: | ||
; CHECK-4-NEXT: [[CMP1:%.*]] = icmp eq i32 [[VAL1]], 1 | ||
; CHECK-4-NEXT: br i1 [[CMP1]], label %[[B6:.*]], label %[[B5:.*]] | ||
; CHECK-4: [[B2]]: | ||
; CHECK-4-NEXT: [[CMP2:%.*]] = icmp eq i32 [[VAL2]], 2 | ||
; CHECK-4-NEXT: br i1 [[CMP2]], label %[[B6]], label %[[B5]] | ||
; CHECK-4: [[B3]]: | ||
; CHECK-4-NEXT: [[CMP3:%.*]] = icmp eq i32 [[VAL3]], 3 | ||
; CHECK-4-NEXT: br i1 [[CMP3]], label %[[B7:.*]], label %[[B5]] | ||
; CHECK-4: [[B4]]: | ||
; CHECK-4-NEXT: [[CMP4:%.*]] = icmp eq i32 [[VAL4]], 4 | ||
; CHECK-4-NEXT: br i1 [[CMP4]], label %[[B7]], label %[[B5]] | ||
; CHECK-4: [[B5]]: | ||
; CHECK-4-NEXT: [[VAL:%.*]] = phi i32 [ [[VAL1]], %[[B1]] ], [ [[VAL2]], %[[B2]] ], [ [[VAL3]], %[[B3]] ], [ [[VAL4]], %[[B4]] ] | ||
; CHECK-4-NEXT: br label %[[MERGE:.*]] | ||
; CHECK-4: [[B6]]: | ||
; CHECK-4-NEXT: br label %[[MERGE]] | ||
; CHECK-4: [[B7]]: | ||
; CHECK-4-NEXT: br label %[[MERGE]] | ||
; CHECK-4: [[MERGE]]: | ||
; CHECK-4-NEXT: [[X1:%.*]] = phi i16 [ 1, %[[B5]] ], [ 0, %[[B6]] ], [ 2, %[[B7]] ] | ||
; CHECK-4-NEXT: [[X2:%.*]] = phi i16 [ 2, %[[B5]] ], [ 0, %[[B6]] ], [ 2, %[[B7]] ] | ||
; CHECK-4-NEXT: [[X3:%.*]] = phi i16 [ 3, %[[B5]] ], [ 0, %[[B6]] ], [ 2, %[[B7]] ] | ||
; CHECK-4-NEXT: [[X4:%.*]] = phi i16 [ 4, %[[B5]] ], [ 0, %[[B6]] ], [ 2, %[[B7]] ] | ||
; CHECK-4-NEXT: [[VAL_MERGE:%.*]] = phi i32 [ [[VAL]], %[[B5]] ], [ 0, %[[B6]] ], [ 2, %[[B7]] ] | ||
; CHECK-4-NEXT: ret void | ||
; | ||
entry: | ||
switch i32 %a, label %B1 [ | ||
i32 4, label %B4 | ||
i32 2, label %B2 | ||
i32 3, label %B3 | ||
] | ||
|
||
B1: ; preds = %entry | ||
%cmp1 = icmp eq i32 %val1, 1 | ||
br i1 %cmp1, label %B6, label %B5 | ||
|
||
B2: ; preds = %entry | ||
%cmp2 = icmp eq i32 %val2, 2 | ||
br i1 %cmp2, label %B6, label %B5 | ||
|
||
B3: ; preds = %entry | ||
%cmp3 = icmp eq i32 %val3, 3 | ||
br i1 %cmp3, label %B7, label %B5 | ||
|
||
B4: ; preds = %entry | ||
%cmp4 = icmp eq i32 %val4, 4 | ||
br i1 %cmp4, label %B7, label %B5 | ||
|
||
B5: ; preds = %B4, %B3, %B2, %B1 | ||
%val = phi i32 [ %val1, %B1 ], [ %val2, %B2 ], [ %val3, %B3 ], [ %val4, %B4 ] | ||
br label %Merge | ||
|
||
B6: ; preds = %B2, %B1 | ||
br label %Merge | ||
|
||
B7: ; preds = %B4, %B3 | ||
br label %Merge | ||
|
||
Merge: ; preds = %B7, %B6, %B5 | ||
%x1 = phi i16 [ 1, %B5 ], [ 0, %B6 ], [ 2, %B7 ] | ||
%x2 = phi i16 [ 2, %B5 ], [ 0, %B6 ], [ 2, %B7 ] | ||
%x3 = phi i16 [ 3, %B5 ], [ 0, %B6 ], [ 2, %B7 ] | ||
%x4 = phi i16 [ 4, %B5 ], [ 0, %B6 ], [ 2, %B7 ] | ||
%val_merge = phi i32 [ %val, %B5 ], [ 0, %B6 ], [ 2, %B7 ] | ||
ret void | ||
} |