[LLVMdev] alias analysis on llvm internal globals

Xin Tong trent.tong at gmail.com
Wed Apr 29 18:37:06 PDT 2015


On Sat, Apr 25, 2015 at 9:52 PM, Xinliang David Li <xinliangli at gmail.com> wrote:
> You need to have a pass to prove those static local's addresses do not
> escape the function scope (i.e passed to calls, or stored to globals or
> other escaped memory locations). With that information available, the
> aliaser can then disambiguate accesses to them from argument pointers.
>
> David

Yea. for static variables with function scope. LLVM translates it into
an internal global variable. but the scope information seems to be
lost. where can i recover that information or maybe should i implement
a pass to figure out that information before inlining and attache a
metadata to that static variable.

Thanks,
Xin
>
> On Sat, Apr 25, 2015 at 4:32 PM, Xin Tong <trent.tong at gmail.com> wrote:
>>
>> 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
>> }
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>



More information about the llvm-dev mailing list