llvm.org GIT mirror llvm / 3659b8a
Analyze recursive PHI nodes in BasicAA Summary: This patch allows phi nodes like %x = phi [ %incptr, ... ] [ %var, ... ] %incptr = getelementptr %x, 1 to be analyzed by BasicAliasAnalysis. In aliasPHI, we can detect incoming values that are recursive GEPs with a constant offset. Instead of trying to analyze a recursive GEP (and failing), we now ignore it and instead set the size of the memory referenced by the PHINode to UnknownSize. This represents all the possible memory locations the pointer represented by the PHINode could be advanced to by the GEP. For now, this new behavior is turned off by default to allow debugging of performance degradations seen with SPEC/x86 and Hexagon benchmarks. The flag -basicaa-recphi turns it on. Reviewers: hfinkel, sanjoy Subscribers: tobiasvk_caf, sanjoy, llvm-commits Differential Revision: http://reviews.llvm.org/D10368 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242320 91177308-0d34-0410-b5e6-96231b3b80d8 Tobias Edler von Koch 5 years ago
2 changed file(s) with 101 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
4040 #include "llvm/Support/ErrorHandling.h"
4141 #include
4242 using namespace llvm;
43
44 /// Enable analysis of recursive PHI nodes.
45 static cl::opt EnableRecPhiAnalysis("basicaa-recphi",
46 cl::Hidden, cl::init(false));
4347
4448 /// Cutoff after which to stop analysing a set of phi nodes potentially involved
4549 /// in a cycle. Because we are analysing 'through' phi nodes we need to be
12961300
12971301 SmallPtrSet UniqueSrc;
12981302 SmallVector V1Srcs;
1303 bool isRecursive = false;
12991304 for (Value *PV1 : PN->incoming_values()) {
13001305 if (isa(PV1))
13011306 // If any of the source itself is a PHI, return MayAlias conservatively
13031308 // sides are PHI nodes. In which case, this is O(m x n) time where 'm'
13041309 // and 'n' are the number of PHI sources.
13051310 return MayAlias;
1311
1312 if (EnableRecPhiAnalysis)
1313 if (GEPOperator *PV1GEP = dyn_cast(PV1)) {
1314 // Check whether the incoming value is a GEP that advances the pointer
1315 // result of this PHI node (e.g. in a loop). If this is the case, we
1316 // would recurse and always get a MayAlias. Handle this case specially
1317 // below.
1318 if (PV1GEP->getPointerOperand() == PN && PV1GEP->getNumIndices() == 1 &&
1319 isa(PV1GEP->idx_begin())) {
1320 isRecursive = true;
1321 continue;
1322 }
1323 }
1324
13061325 if (UniqueSrc.insert(PV1).second)
13071326 V1Srcs.push_back(PV1);
13081327 }
13091328
1329 // If this PHI node is recursive, set the size of the accessed memory to
1330 // unknown to represent all the possible values the GEP could advance the
1331 // pointer to.
1332 if (isRecursive)
1333 PNSize = MemoryLocation::UnknownSize;
1334
13101335 AliasResult Alias = aliasCheck(V2, V2Size, V2AAInfo,
13111336 V1Srcs[0], PNSize, PNAAInfo);
1337
13121338 // Early exit if the check of the first PHI source against V2 is MayAlias.
13131339 // Other results are not possible.
13141340 if (Alias == MayAlias)
0 ; RUN: opt < %s -basicaa -basicaa-recphi=1 -gvn -S | FileCheck %s
1 ;
2 ; Check that section->word_ofs doesn't get reloaded in every iteration of the
3 ; for loop.
4 ;
5 ; Code:
6 ;
7 ; typedef struct {
8 ; unsigned num_words;
9 ; unsigned word_ofs;
10 ; const unsigned *data;
11 ; } section_t;
12 ;
13 ;
14 ; void test2(const section_t * restrict section, unsigned * restrict dst) {;
15 ; while (section->data != NULL) {
16 ; const unsigned *src = section->data;
17 ; for (unsigned i=0; i < section->num_words; ++i) {
18 ; dst[section->word_ofs + i] = src[i];
19 ; }
20 ;
21 ; ++section;
22 ; }
23 ; }
24 ;
25
26 ; CHECK-LABEL: for.body:
27 ; CHECK-NOT: load i32, i32* %word_ofs
28
29 %struct.section_t = type { i32, i32, i32* }
30
31 define void @test2(%struct.section_t* noalias nocapture readonly %section, i32* noalias nocapture %dst) {
32 entry:
33 %data13 = getelementptr inbounds %struct.section_t, %struct.section_t* %section, i32 0, i32 2
34 %0 = load i32*, i32** %data13, align 4
35 %cmp14 = icmp eq i32* %0, null
36 br i1 %cmp14, label %while.end, label %for.cond.preheader
37
38 for.cond.preheader: ; preds = %entry, %for.end
39 %1 = phi i32* [ %6, %for.end ], [ %0, %entry ]
40 %section.addr.015 = phi %struct.section_t* [ %incdec.ptr, %for.end ], [ %section, %entry ]
41 %num_words = getelementptr inbounds %struct.section_t, %struct.section_t* %section.addr.015, i32 0, i32 0
42 %2 = load i32, i32* %num_words, align 4
43 %cmp211 = icmp eq i32 %2, 0
44 br i1 %cmp211, label %for.end, label %for.body.lr.ph
45
46 for.body.lr.ph: ; preds = %for.cond.preheader
47 %word_ofs = getelementptr inbounds %struct.section_t, %struct.section_t* %section.addr.015, i32 0, i32 1
48 br label %for.body
49
50 for.body: ; preds = %for.body.lr.ph, %for.body
51 %arrayidx.phi = phi i32* [ %1, %for.body.lr.ph ], [ %arrayidx.inc, %for.body ]
52 %i.012 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
53 %3 = load i32, i32* %arrayidx.phi, align 4
54 %4 = load i32, i32* %word_ofs, align 4
55 %add = add i32 %4, %i.012
56 %arrayidx3 = getelementptr inbounds i32, i32* %dst, i32 %add
57 store i32 %3, i32* %arrayidx3, align 4
58 %inc = add i32 %i.012, 1
59 %5 = load i32, i32* %num_words, align 4
60 %cmp2 = icmp ult i32 %inc, %5
61 %arrayidx.inc = getelementptr i32, i32* %arrayidx.phi, i32 1
62 br i1 %cmp2, label %for.body, label %for.end
63
64 for.end: ; preds = %for.body, %for.cond.preheader
65 %incdec.ptr = getelementptr inbounds %struct.section_t, %struct.section_t* %section.addr.015, i32 1
66 %data = getelementptr inbounds %struct.section_t, %struct.section_t* %section.addr.015, i32 1, i32 2
67 %6 = load i32*, i32** %data, align 4
68 %cmp = icmp eq i32* %6, null
69 br i1 %cmp, label %while.end, label %for.cond.preheader
70
71 while.end: ; preds = %for.end, %entry
72 ret void
73 }
74