[Patch] Use address-taken to disambiguate global var and indirect accesses

Shuxin Yang shuxin.llvm at gmail.com
Mon Oct 21 15:10:02 PDT 2013


Hi, Even:

     Thank you for your feedback. Yes, I should put the comment on the code.

      These statement embody this rule:

    Suppose mem1 and mem2 are two memory accesses,  and O1 and O2 are 
corresponding
objects (obtained via getUnderlyingObject()).  mem1 and mem2 are 
disjointed if:

     o. O1 (or O2) is a global variable without address taken, and
     o. O2 ! = O1 (this is condition enclosing these statement)

    We can prove this way: Let O1 be a global variable without address 
taken, O2 is another
object. O2 could be a named variable, or an anonymous, imaginary "memory 
location" accessed
via indirect load/store.

     In the first case, O1 and O2 will not alias (O1 and O2 are distinct 
variable); for
the 2nd case, since O1 dose not has its address taken, it cannot be 
indirectly accessed,
hence O1 and O2 are disjointed.

     One might asked what if the global variable is volatile? The answer 
is we will not mark a volatile
variable "not-address-taken".

Thanks
Shuxin

On 10/21/13 2:29 PM, Evan Cheng wrote:
> Hi Shuxin,
>
> This needs some comments:
>
> +    if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(O1))
> +      if (GV->notAddressTaken())
> +        return NoAlias;
> +
> +    if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(O2))
> +      if (GV->notAddressTaken())
> +        return NoAlias;
>
> Evan
>
> On Oct 21, 2013, at 11:27 AM, Shuxin Yang <shuxin.llvm at gmail.com 
> <mailto:shuxin.llvm at gmail.com>> wrote:
>
>> Ping.
>>
>> (add testing cases. Forget attaching testing case in my previous mail).
>> Thanks
>> Shuxin
>>
>>
>> -------- Original Message --------
>> Subject: 	[Patch] Use address-taken to disambiguate global var and 
>> indirect accesses
>> Date: 	Tue, 15 Oct 2013 14:39:51 -0700
>> From: 	Shuxin Yang <shuxin.llvm at gmail.com>
>> To: 	Commit Messages and Patches for LLVM <llvm-commits at cs.uiuc.edu>
>>
>>
>>
>> Hi,
>>
>>       The attached patch is to take advantage of address-taken to
>> disambiguate global
>>    variable and indirect memory accesses.
>>
>>    The motivation
>>    ===========
>>        I was asked to investigate the problem where the static variable
>> is not hoisted as
>> loop invariant:
>>
>>       ---------------
>>        static int xyz;
>>        void foo(int *p) {
>>            for (int i = 0; i < xyz; i++)
>>               *p++ = ....
>>        }
>>      -----------------
>>
>>      The compiler dose have a concept call "addr-capture". However, I
>> don't think it can
>> be used for disambiguate global variable and indirect access. The
>> reasons is that
>> a variable dose not have its address *CAPTURED*, dose not necessarily
>> mean this variable
>> cannot be indirectly accessed.
>>
>>      So, I rely on "address taken"
>>
>>    How it works
>>    ========
>>         1. In globalopt, when a global var is identified as
>> not-addr-taken, cache the result
>>             to GlobalVariable::notAddrTaken.
>>
>>         2. In alias-analyzer, supposed the mem-op involved are m1 and m2.
>> Let o1 and o2
>>             be the "object" (obtained via get_underlying_object() of m1
>> and m2 respectively.
>>
>>            if O1 != O2 && one of the them are global-variable without
>> address taken,
>>            then m1 and m2 are disjointed access.
>>
>>    Misc:
>>    =========
>>         Note that I *cache* the result of not-addr-taken. Unlike
>> function, it is far more expensive
>> to figure out if a globalvar has its address taken or not. So, it is not
>> appropriate to analyze
>> the address-taken on the fly.
>>
>>        On the other hand,  I personally think not-addr-taken flag is
>> almost maintenance free.
>> (FIXME) Only few optimizer could make a not-addr-taken variable become
>> addr-taken (say, outlining),
>> and I don't think currently we have such passes (FIXME again!).  In case
>> such rare cases take place,
>> it is up to the pass the to reset the not-addr-taken flags.
>>
>>       Of course, a variable previously considered addr-taken may later on
>> proved to be not-addr-taken.
>> In that case, compiler dose not have to update it -- it is
>> conservatively correct.
>>
>>    Performance impact
>> =============
>>     Measured on an oldish Mac Tower with 2x 2.26Ghz Quad-Core Xeon. Both
>> base-line and
>> the change are measured for couple of times.  I did take a look of why
>> Olden/power is sped up --
>> the loads of static variable "P" and "Q" are promoted in many places.  I
>> have not yet got chance
>> to investigate why the speedup to pairlocalalign with O3 disappear in
>> O3+LTO.
>>
>>
>> o. test-suite w/ O3:
>> -------------------
>> Benchmarks/Olden/power/power                  1.6129 1.354
>> -16.0518321036642
>> Benchmarks/mafft/pairlocalalign               31.4211 26.5794
>> -15.4090722476298
>> Benchmarks/Ptrdist/yacr2/yacr2                0.881 0.804
>> -8.74006810442678
>>
>> o. test-suite w/ O3 + LTO
>> -------------------------
>> Benchmarks/Olden/power/power  1.6143      1.3419 -16.8741869540978
>> Applications/spiff/spiff      2.9203      2.849 -2.44152997979659
>>
>> o. spec2kint w/ O3+LTO
>> ----------------------
>> bzip2  75.02 73.92 -1.4
>>
>>
>> Thanks
>> Shuxin
>>
>>
>>
>>
>>
>> <addrtaken.patch><addrtaken.test.patch>_______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu <mailto:llvm-commits at cs.uiuc.edu>
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131021/26525628/attachment.html>


More information about the llvm-commits mailing list