Skip to content

Commit 5776938

Browse files
committed
[MemorySSA] Small fix for the clobber limit.
Summary: After introducing the limit for clobber walking, `walkToPhiOrClobber` would assert that the limit is at least 1 on entry. The test included triggered that assert. The callsite in `tryOptimizePhi` making the calls to `walkToPhiOrClobber` is structured like this: ``` while (true) { if (getBlockingAccess()) { // calls walkToPhiOrClobber } for (...) { walkToPhiOrClobber(); } } ``` The cleanest fix is to check if the limit was reached inside `walkToPhiOrClobber`, and give an allowence of 1. This approach not make any alias() calls (no calls to instructionClobbersQuery), so the performance condition is enforced. The limit is set back to 0 if not used, as this provides info on the fact that we stopped before reaching a true clobber. Reviewers: george.burgess.iv Subscribers: jlebar, Prazek, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D60479 llvm-svn: 358303
1 parent 11bbb58 commit 5776938

File tree

2 files changed

+143
-4
lines changed

2 files changed

+143
-4
lines changed

llvm/lib/Analysis/MemorySSA.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -544,10 +544,15 @@ template <class AliasAnalysisType> class ClobberWalker {
544544
const MemoryAccess *SkipStopAt = nullptr) const {
545545
assert(!isa<MemoryUse>(Desc.Last) && "Uses don't exist in my world");
546546
assert(UpwardWalkLimit && "Need a valid walk limit");
547-
// This will not do any alias() calls. It returns in the first iteration in
548-
// the loop below.
549-
if (*UpwardWalkLimit == 0)
550-
(*UpwardWalkLimit)++;
547+
bool LimitAlreadyReached = false;
548+
// (*UpwardWalkLimit) may be 0 here, due to the loop in tryOptimizePhi. Set
549+
// it to 1. This will not do any alias() calls. It either returns in the
550+
// first iteration in the loop below, or is set back to 0 if all def chains
551+
// are free of MemoryDefs.
552+
if (!*UpwardWalkLimit) {
553+
*UpwardWalkLimit = 1;
554+
LimitAlreadyReached = true;
555+
}
551556

552557
for (MemoryAccess *Current : def_chain(Desc.Last)) {
553558
Desc.Last = Current;
@@ -568,6 +573,9 @@ template <class AliasAnalysisType> class ClobberWalker {
568573
}
569574
}
570575

576+
if (LimitAlreadyReached)
577+
*UpwardWalkLimit = 0;
578+
571579
assert(isa<MemoryPhi>(Desc.Last) &&
572580
"Ended at a non-clobber that's not a phi?");
573581
return {Desc.Last, false, MayAlias};
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
; RUN: opt -S -memoryssa %s | FileCheck %s
2+
; REQUIRES: asserts
3+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4+
target triple = "x86_64-unknown-linux-gnu"
5+
6+
; CHECK-LABEL: @func()
7+
; Function Attrs: noinline
8+
define dso_local void @func() unnamed_addr #0 align 2 {
9+
entry:
10+
%NoFinalize.addr = alloca i8, align 1
11+
call void @blah()
12+
call void @blah()
13+
call void @blah()
14+
call void @blah()
15+
call void @blah()
16+
call void @blah()
17+
%call8 = call zeroext i1 @foo()
18+
br i1 %call8, label %if.then9, label %while.cond
19+
20+
if.then9: ; preds = %entry
21+
call void @blah()
22+
call void @blah()
23+
call void @blah()
24+
call void @blah()
25+
call void @blah()
26+
call void @blah()
27+
call void @blah()
28+
br label %while.cond
29+
30+
while.cond: ; preds = %cleanup, %if.then9, %entry
31+
%call34 = call zeroext i1 @foo()
32+
call void @blah()
33+
br i1 %call34, label %while.body, label %while.end
34+
35+
while.body: ; preds = %while.cond
36+
%call35 = call zeroext i1 @foo()
37+
br i1 %call35, label %if.end37, label %if.then36
38+
39+
if.then36: ; preds = %while.body
40+
store i32 2, i32* undef, align 4
41+
br label %cleanup
42+
43+
if.end37: ; preds = %while.body
44+
%call38 = call zeroext i1 @foo()
45+
br i1 %call38, label %if.end46, label %land.lhs.true
46+
47+
land.lhs.true: ; preds = %if.end37
48+
call void @blah()
49+
%call41 = call zeroext i1 @foo()
50+
br i1 %call41, label %if.then42, label %if.end46
51+
52+
if.then42: ; preds = %land.lhs.true
53+
call void @blah()
54+
br label %if.end46
55+
56+
if.end46: ; preds = %if.then42, %land.lhs.true, %if.end37
57+
call void @blah()
58+
call void @blah()
59+
call void @blah()
60+
call void @blah()
61+
br label %cleanup
62+
63+
cleanup: ; preds = %if.end46, %if.then36
64+
call void @blah()
65+
br label %while.cond
66+
67+
while.end: ; preds = %while.cond
68+
call void @blah()
69+
call void @blah()
70+
call void @blah()
71+
call void @blah()
72+
call void @blah()
73+
call void @blah()
74+
call void @blah()
75+
call void @blah()
76+
call void @blah()
77+
call void @blah()
78+
call void @blah()
79+
call void @blah()
80+
call void @blah()
81+
call void @blah()
82+
call void @blah()
83+
%call93 = call zeroext i1 @foo()
84+
br i1 %call93, label %if.end120, label %if.then94
85+
86+
if.then94: ; preds = %while.end
87+
store i32 0, i32* undef, align 4
88+
call void @blah()
89+
call void @blah()
90+
call void @blah()
91+
call void @blah()
92+
call void @blah()
93+
call void @blah()
94+
call void @blah()
95+
call void @blah()
96+
call void @blah()
97+
br label %for.cond
98+
99+
for.cond: ; preds = %for.body, %if.then94
100+
br i1 undef, label %for.body, label %if.end120
101+
102+
for.body: ; preds = %for.cond
103+
call void @blah()
104+
call void @blah()
105+
call void @blah()
106+
call void @blah()
107+
call void @blah()
108+
call void @blah()
109+
call void @blah()
110+
call void @blah()
111+
call void @blah()
112+
call void @blah()
113+
call void @blah()
114+
call void @blah()
115+
call void @blah()
116+
call void @blah()
117+
br label %for.cond
118+
119+
if.end120: ; preds = %for.cond, %while.end
120+
%val = load i8, i8* %NoFinalize.addr, align 1
121+
ret void
122+
}
123+
124+
; Function Attrs: noinline
125+
declare hidden void @blah() unnamed_addr #0 align 2
126+
127+
; Function Attrs: noinline
128+
declare hidden i1 @foo() local_unnamed_addr #0 align 2
129+
130+
attributes #0 = { noinline }
131+

0 commit comments

Comments
 (0)