[LLVMdev] alias analysis on llvm internal globals
Xin Tong
trent.tong at gmail.com
Sat Apr 25 16:32:05 PDT 2015
Hi
I have this program in which fooBuf can only take on NULL or the
address of local_fooBuf, and fooBuf and local_fooBuf have scope of the
foo function.
Therefore there is no way for the fooPtr argument to alias with
fooBuf. However, LLVM basicaa and globalsmodref-aa say the 2 pointers
may alias.
I am thinking whether i should implement a limited form of point-to
alias on the fooBuf pointer in basicaa, i.e. looking at all stores to
it and computing what addresses it can take on and then compare with
fooPtr which can not point to local_fooBuf as it has a function
scope.
Also, LLVM global variables do not have seem to have scope
information. where can i get that information ?
Thanks,
Xin
int foo(int *fooPtr,int aconst)
{
int i;
int sum;
int *fooOffsetPtr;
static int init = 1;
static int *fooBuf = NULL;
static int local_fooBuf[512*4] = {};
if (init == 1) {
fooBuf = local_fooBuf;
init = 0;
}
fooOffsetPtr = &fooBuf[aconst/2];
#pragma nounroll
for (i=0;i<aconst;++i) {
/// fooPtr can not point to the same memory location as fooOffsetPtr.
fooPtr[i] = i; /// <------- HERE.
/// should not this be moved out of the loop. at least, should not
/// load fooOffsetPtr[0] be moved out of the loop. /// <------- HERE.
sum += fooOffsetPtr[0];
}
return sum;
}
////////////////////////////////////////// opt -globalsmodref-aa -O3
ptr.ll -S //////////////////////////////////////////
@foo.init = internal unnamed_addr global i1 false
@foo.fooBuf = internal unnamed_addr global i32* null, align 8
@foo.local_fooBuf = internal global [2048 x i32] zeroinitializer, align 16
; Function Attrs: nounwind uwtable
define i32 @foo(i32* nocapture %fooPtr, i32 %aconst) #0 {
entry:
%.b = load i1, i1* @foo.init, align 1
br i1 %.b, label %entry.if.end_crit_edge, label %if.then
entry.if.end_crit_edge: ; preds = %entry
%.pre = load i32*, i32** @foo.fooBuf, align 8, !tbaa !1
br label %if.end
if.then: ; preds = %entry
store i32* getelementptr inbounds ([2048 x i32]* @foo.local_fooBuf,
i64 0, i64 0), i32** @foo.fooBuf, align 8, !tbaa !1
store i1 true, i1* @foo.init, align 1
br label %if.end
if.end: ; preds =
%entry.if.end_crit_edge, %if.then
%0 = phi i32* [ %.pre, %entry.if.end_crit_edge ], [ getelementptr
inbounds ([2048 x i32]* @foo.local_fooBuf, i64 0, i64 0), %if.then ]
%div = sdiv i32 %aconst, 2
%idxprom = sext i32 %div to i64
%arrayidx = getelementptr inbounds i32, i32* %0, i64 %idxprom
%cmp110 = icmp sgt i32 %aconst, 0
br i1 %cmp110, label %for.body.preheader, label %for.end, !llvm.loop !5
for.body.preheader: ; preds = %if.end
br label %for.body
for.body: ; preds =
%for.body.preheader, %for.body
%indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0,
%for.body.preheader ]
%sum.011 = phi i32 [ %add, %for.body ], [ undef, %for.body.preheader ]
%arrayidx3 = getelementptr inbounds i32, i32* %fooPtr, i64 %indvars.iv
%1 = trunc i64 %indvars.iv to i32
store i32 %1, i32* %arrayidx3, align 4, !tbaa !7
%2 = load i32, i32* %arrayidx, align 4, !tbaa !7
%add = add nsw i32 %2, %sum.011
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
%lftr.wideiv = trunc i64 %indvars.iv.next to i32
%exitcond = icmp eq i32 %lftr.wideiv, %aconst
br i1 %exitcond, label %for.end.loopexit, label %for.body, !llvm.loop !5
for.end.loopexit: ; preds = %for.body
%add.lcssa = phi i32 [ %add, %for.body ]
br label %for.end
for.end: ; preds =
%for.end.loopexit, %if.end
%sum.0.lcssa = phi i32 [ undef, %if.end ], [ %add.lcssa, %for.end.loopexit ]
ret i32 %sum.0.lcssa
}
More information about the llvm-dev
mailing list