Skip to content

Commit dd2ef0a

Browse files
committed
[LCSSA] Handle case with single new PHI faster.
If there is only a single available value, all uses must be dominated by the single value and there is no need to search for a reaching definition. This drastically speeds up LCSSA in some cases. For the test case from PR37202, it speeds up LCSSA construction by 4 times. Time-passes without this patch for test case from PR37202: Total Execution Time: 29.9285 seconds (29.9276 wall clock) ---User Time--- --System Time-- --User+System-- ---Wall Time--- --- Name --- 5.2786 ( 17.7%) 0.0021 ( 1.2%) 5.2806 ( 17.6%) 5.2808 ( 17.6%) Unswitch loops 4.3739 ( 14.7%) 0.0303 ( 18.1%) 4.4042 ( 14.7%) 4.4042 ( 14.7%) Loop-Closed SSA Form Pass 4.2658 ( 14.3%) 0.0192 ( 11.5%) 4.2850 ( 14.3%) 4.2851 ( 14.3%) Loop-Closed SSA Form Pass #2 2.2307 ( 7.5%) 0.0013 ( 0.8%) 2.2320 ( 7.5%) 2.2318 ( 7.5%) Loop Invariant Code Motion 2.0888 ( 7.0%) 0.0012 ( 0.7%) 2.0900 ( 7.0%) 2.0897 ( 7.0%) Unroll loops 1.6761 ( 5.6%) 0.0013 ( 0.8%) 1.6774 ( 5.6%) 1.6774 ( 5.6%) Value Propagation 1.3686 ( 4.6%) 0.0029 ( 1.8%) 1.3716 ( 4.6%) 1.3714 ( 4.6%) Induction Variable Simplification 1.1457 ( 3.8%) 0.0010 ( 0.6%) 1.1468 ( 3.8%) 1.1468 ( 3.8%) Loop-Closed SSA Form Pass #4 1.1384 ( 3.8%) 0.0005 ( 0.3%) 1.1389 ( 3.8%) 1.1389 ( 3.8%) Loop-Closed SSA Form Pass #6 1.1360 ( 3.8%) 0.0027 ( 1.6%) 1.1387 ( 3.8%) 1.1387 ( 3.8%) Loop-Closed SSA Form Pass #5 1.1331 ( 3.8%) 0.0010 ( 0.6%) 1.1341 ( 3.8%) 1.1340 ( 3.8%) Loop-Closed SSA Form Pass #3 Time passes with this patch Total Execution Time: 19.2802 seconds (19.2813 wall clock) ---User Time--- --System Time-- --User+System-- ---Wall Time--- --- Name --- 4.4234 ( 23.2%) 0.0038 ( 2.0%) 4.4272 ( 23.0%) 4.4273 ( 23.0%) Unswitch loops 2.3828 ( 12.5%) 0.0020 ( 1.1%) 2.3848 ( 12.4%) 2.3847 ( 12.4%) Unroll loops 1.8714 ( 9.8%) 0.0020 ( 1.1%) 1.8734 ( 9.7%) 1.8735 ( 9.7%) Loop Invariant Code Motion 1.7973 ( 9.4%) 0.0022 ( 1.2%) 1.7995 ( 9.3%) 1.8003 ( 9.3%) Value Propagation 1.4010 ( 7.3%) 0.0033 ( 1.8%) 1.4043 ( 7.3%) 1.4044 ( 7.3%) Induction Variable Simplification 0.9978 ( 5.2%) 0.0244 ( 13.1%) 1.0222 ( 5.3%) 1.0224 ( 5.3%) Loop-Closed SSA Form Pass #2 0.9611 ( 5.0%) 0.0257 ( 13.8%) 0.9868 ( 5.1%) 0.9868 ( 5.1%) Loop-Closed SSA Form Pass 0.5856 ( 3.1%) 0.0015 ( 0.8%) 0.5871 ( 3.0%) 0.5869 ( 3.0%) Unroll loops #2 0.4132 ( 2.2%) 0.0012 ( 0.7%) 0.4145 ( 2.1%) 0.4143 ( 2.1%) Loop Invariant Code Motion #3 Reviewers: efriedma, davide, mzolotukhin Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D57033 llvm-svn: 352960
1 parent ffe93a1 commit dd2ef0a

File tree

2 files changed

+117
-35
lines changed

2 files changed

+117
-35
lines changed

llvm/lib/Transforms/Utils/LCSSA.cpp

+17-3
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,17 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
197197
continue;
198198
}
199199

200+
// If we added a single PHI, it must dominate all uses and we can directly
201+
// rename it.
202+
if (AddedPHIs.size() == 1) {
203+
// Tell the VHs that the uses changed. This updates SCEV's caches.
204+
// We might call ValueIsRAUWd multiple times for the same value.
205+
if (UseToRewrite->get()->hasValueHandle())
206+
ValueHandleBase::ValueIsRAUWd(*UseToRewrite, AddedPHIs[0]);
207+
UseToRewrite->set(AddedPHIs[0]);
208+
continue;
209+
}
210+
200211
// Otherwise, do full PHI insertion.
201212
SSAUpdate.RewriteUse(*UseToRewrite);
202213
}
@@ -210,9 +221,12 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
210221
BasicBlock *UserBB = DVI->getParent();
211222
if (InstBB == UserBB || L->contains(UserBB))
212223
continue;
213-
// We currently only handle debug values residing in blocks where we have
214-
// inserted a PHI instruction.
215-
if (Value *V = SSAUpdate.FindValueForBlock(UserBB))
224+
// We currently only handle debug values residing in blocks that were
225+
// traversed while rewriting the uses. If we inserted just a single PHI,
226+
// we will handle all relevant debug values.
227+
Value *V = AddedPHIs.size() == 1 ? AddedPHIs[0]
228+
: SSAUpdate.FindValueForBlock(UserBB);
229+
if (V)
216230
DVI->setOperand(0, MetadataAsValue::get(Ctx, ValueAsMetadata::get(V)));
217231
}
218232

Original file line numberDiff line numberDiff line change
@@ -1,54 +1,118 @@
11
; RUN: opt -S -lcssa < %s | FileCheck %s
22

3-
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4-
target triple = "x86_64-unknown-linux-gnu"
5-
63
; Reproducer for PR39019.
74
;
8-
; Verify that the llvm.dbg.value in the %for.cond.cleanup2 block is rewritten
9-
; to use the PHI node for %add that is created by LCSSA.
5+
; Verify that the llvm.dbg.values are updated to use the PHI nodes inserted by
6+
; LCSSA.
107

11-
; CHECK-LABEL: for.cond.cleanup2:
12-
; CHECK-NEXT: [[PN:%[^ ]*]] = phi i32 [ %add.lcssa, %for.cond.cleanup1 ]
13-
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[PN]], metadata [[VAR:![0-9]+]], metadata !DIExpression())
14-
; CHECK-NEXT: call void @bar(i32 [[PN]])
8+
; For the test case @single_exit, we can rewrite all llvm.dbg.value calls
9+
; to use the inserted PHI.
1510

16-
; CHECK-LABEL: for.body:
11+
; CHECK-LABEL: @single_exit(
12+
13+
; CHECK-LABEL: inner.body:
1714
; CHECK: %add = add nsw i32 0, 2
18-
; CHECK: call void @llvm.dbg.value(metadata i32 %add, metadata [[VAR]], metadata !DIExpression())
15+
; CHECK: call void @llvm.dbg.value(metadata i32 %add, metadata [[VAR:![0-9]+]], metadata !DIExpression())
1916

20-
; CHECK: [[VAR]] = !DILocalVariable(name: "sum",
2117

22-
; Function Attrs: nounwind
23-
define void @foo() #0 !dbg !6 {
18+
; CHECK-LABEL: outer.exit:
19+
; CHECK-NEXT: [[PN:%[^ ]*]] = phi i32 [ %add.lcssa, %outer.latch ]
20+
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[PN]], metadata [[VAR]], metadata !DIExpression())
21+
; CHECK-NEXT: call void @bar(i32 [[PN]])
22+
23+
; CHECK-LABEL: exit:
24+
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[PN]], metadata [[VAR]], metadata !DIExpression())
25+
26+
define void @single_exit() !dbg !6 {
2427
entry:
25-
br label %for.cond.preheader, !dbg !12
28+
br label %outer.header, !dbg !12
2629

27-
for.cond.preheader: ; preds = %for.cond.cleanup1, %entry
28-
br label %for.body, !dbg !12
30+
outer.header: ; preds = %outer.latch, %entry
31+
br label %inner.body, !dbg !12
2932

30-
for.cond.cleanup2: ; preds = %for.cond.cleanup1
33+
inner.body: ; preds = %inner.body, %outer.header
34+
%add = add nsw i32 0, 2, !dbg !12
3135
call void @llvm.dbg.value(metadata i32 %add, metadata !9, metadata !DIExpression()), !dbg !12
32-
tail call void @bar(i32 %add) #0, !dbg !12
33-
ret void, !dbg !12
36+
br i1 false, label %inner.body, label %inner.exit, !dbg !12
3437

35-
for.cond.cleanup1: ; preds = %for.body
36-
br i1 false, label %for.cond.preheader, label %for.cond.cleanup2, !dbg !12
38+
inner.exit: ; preds = %inner.body
39+
br label %outer.latch
3740

38-
for.body: ; preds = %for.body, %for.cond.preheader
39-
%add = add nsw i32 0, 2, !dbg !12
41+
outer.latch: ; preds = %inner.exit
42+
br i1 false, label %outer.header, label %outer.exit, !dbg !12
43+
44+
outer.exit: ; preds = %outer.latch
45+
call void @llvm.dbg.value(metadata i32 %add, metadata !9, metadata !DIExpression()), !dbg !12
46+
tail call void @bar(i32 %add), !dbg !12
47+
br label %exit
48+
49+
exit: ; preds = %outer.exit
4050
call void @llvm.dbg.value(metadata i32 %add, metadata !9, metadata !DIExpression()), !dbg !12
41-
br i1 false, label %for.body, label %for.cond.cleanup1, !dbg !12
51+
ret void, !dbg !12
4252
}
4353

44-
; Function Attrs: nounwind
45-
declare void @bar(i32) #0
54+
; For the test case @multi_exit, we cannot update the llvm.dbg.value call in exit,
55+
; because LCSSA did not insert a PHI node in %exit, as there is no non-debug
56+
; use.
57+
58+
; CHECK-LABEL: @multi_exit()
59+
60+
; CHECK-LABEL: for.header:
61+
; CHECK-NEXT: %add = add nsw i32 0, 2
62+
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 %add, metadata [[VAR2:![0-9]+]], metadata !DIExpression())
63+
64+
; CHECK-LABEL: for.exit1:
65+
; CHECK-NEXT: [[PN1:%[^ ]*]] = phi i32 [ %add, %for.header ]
66+
; CHECK-NEXT: br label %for.exit1.succ
67+
68+
; CHECK-LABEL: for.exit1.succ:
69+
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[PN1]], metadata [[VAR2]], metadata !DIExpression())
70+
; CHECK-NEXT: call void @bar(i32 [[PN1]])
71+
72+
; CHECK-LABEL: for.exit2:
73+
; CHECK-NEXT: [[PN2:%[^ ]*]] = phi i32 [ %add, %for.latch ]
74+
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[PN2]], metadata [[VAR2]], metadata !DIExpression())
75+
; CHECK-NEXT: call void @bar(i32 [[PN2]])
76+
77+
; CHECK-LABEL: exit:
78+
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 %add, metadata [[VAR2]], metadata !DIExpression())
79+
80+
define void @multi_exit() !dbg !13 {
81+
entry:
82+
br label %for.header, !dbg !14
83+
84+
for.header: ; preds = %for.latch, %entry
85+
%add = add nsw i32 0, 2, !dbg !14
86+
call void @llvm.dbg.value(metadata i32 %add, metadata !16, metadata !DIExpression()), !dbg !14
87+
br i1 false, label %for.latch, label %for.exit1, !dbg !14
88+
89+
for.latch: ; preds = %for.header
90+
br i1 false, label %for.header, label %for.exit2, !dbg !14
91+
92+
for.exit1: ; preds = %for.header
93+
br label %for.exit1.succ
94+
95+
for.exit1.succ: ; preds = %for.exit1
96+
call void @llvm.dbg.value(metadata i32 %add, metadata !16, metadata !DIExpression()), !dbg !14
97+
tail call void @bar(i32 %add), !dbg !14
98+
br label %exit
99+
100+
for.exit2: ; preds = %for.latch
101+
call void @llvm.dbg.value(metadata i32 %add, metadata !16, metadata !DIExpression()), !dbg !14
102+
tail call void @bar(i32 %add), !dbg !14
103+
br label %exit
104+
105+
exit: ; preds = %for.exit2, %for.exit1.succ
106+
call void @llvm.dbg.value(metadata i32 %add, metadata !16, metadata !DIExpression()), !dbg !14
107+
ret void, !dbg !14
108+
}
109+
110+
; CHECK: [[VAR]] = !DILocalVariable(name: "sum",
111+
; CHECK: [[VAR2]] = !DILocalVariable(name: "sum2",
46112

47-
; Function Attrs: nounwind readnone speculatable
48-
declare void @llvm.dbg.value(metadata, metadata, metadata) #1
113+
declare void @bar(i32)
49114

50-
attributes #0 = { nounwind }
51-
attributes #1 = { nounwind readnone speculatable }
115+
declare void @llvm.dbg.value(metadata, metadata, metadata)
52116

53117
!llvm.dbg.cu = !{!0}
54118
!llvm.module.flags = !{!3, !4}
@@ -60,10 +124,14 @@ attributes #1 = { nounwind readnone speculatable }
60124
!3 = !{i32 2, !"Dwarf Version", i32 4}
61125
!4 = !{i32 2, !"Debug Info Version", i32 3}
62126
!5 = !{!"clang version 8.0.0"}
63-
!6 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 10, type: !7, isLocal: false, isDefinition: true, scopeLine: 10, isOptimized: true, unit: !0, retainedNodes: !8)
127+
!6 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 10, type: !7, scopeLine: 10, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
64128
!7 = !DISubroutineType(types: !2)
65129
!8 = !{!9}
66130
!9 = !DILocalVariable(name: "sum", scope: !10, file: !1, line: 11, type: !11)
67131
!10 = !DILexicalBlockFile(scope: !6, file: !1, discriminator: 0)
68132
!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
69133
!12 = !DILocation(line: 0, scope: !10)
134+
!13 = distinct !DISubprogram(name: "multi_exit", scope: !1, file: !1, line: 10, type: !7, scopeLine: 10, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
135+
!14 = !DILocation(line: 0, scope: !15)
136+
!15 = !DILexicalBlockFile(scope: !13, file: !1, discriminator: 0)
137+
!16 = !DILocalVariable(name: "sum2", scope: !15, file: !1, line: 11, type: !11)

0 commit comments

Comments
 (0)