[llvm-dev] [RFC] Adding a globalmemonly attribute for functions that only access global memory

Philip Reames via llvm-dev llvm-dev at lists.llvm.org
Tue Sep 14 11:03:39 PDT 2021


On 9/14/21 9:50 AM, Johannes Doerfert via llvm-dev wrote:
> Hi Nicolai,
>
> On 9/13/21 11:59 AM, Nicolai Hähnle via llvm-dev wrote:
>> Hi Mugilan,
>>
>> I think this is an interesting direction. I've recently put some thought
>> into the memory attributes you mention for unrelated reasons, and found
>> that the various XYZonly attributes don't compose well, while noXYZ
>> attributes compose better.The reason is simple. With what you're 
>> proposing,
>> we end up with:
>>
>> * argmemonly
>> * inaccessiblememonly
>> * inaccessibleorargmemonly
>> * globalmemonly
>>
>> There are 4 attributes talking about 3 types of memory. Clearly, 
>> there are
>> orthogonality issues. First of all, glancing at your patch, your new
>> attribute should really be called inaccessibleorglobalmemonly. What if
>> somebody wants argorglobalmemonly? Do they add yet another attribute? 
>> That
>> way lies madness.
>
> Agreed. We actually wanted to use this to make the point that we
> need to switch up the scheme :)
>
> That said, I think the handling of globalmemonly should be discussed
> and merged (after refinement) as it will be reused whatever the later
> scheme will be.
>
>
>> If we instead take a step back, we can recognize that there are 
>> different
>> "paths" of accessing memory:
>>
>> * arg
>> * global
>> * inaccessible
>> * indirect (i.e., via a pointer loaded from memory)
>> * other (e.g., pointer returned by black box function)
>>
>> These could map very nicely onto noXYZ attributes. You end up 5 
>> attributes:
>> noargmem, noglobalmem, noinaccessiblemem, noindirectmem, noothermem. 
>> Nicely
>> composable, in particular today's attribute are mapped as follows:
>>
>> * argmemonly -> noglobalmem noinaccessiblemem noindirectmem noothermem
>> * inaccessiblememonly -> noargmem noglobalmem noindirectmem noothermem
>> * inaccessibleorargmemonly -> noglobalmem noindirectmem noothermem
>> * globalmemonly -> noargmem noindirectmem noothermem (remember, you 
>> seem to
>> want to allow access to inaccessible memory here)
>>
>> More importantly, the 5 attributes can express any future desired
>> combination, e.g. a function that accesses memory through argument
>> pointers, and through pointers loaded from there (transitively) is:
>> noglobalmem noinaccessiblemem noothermem
>>
>> Thoughts?
>
> I was thinking we go with a bitfield but otherwise I'm with you. This
> is the Attributor AAMemoryLocation encoding:
>
> ```
>     /// Encoding of different locations that could be accessed by a 
> memory
>     /// access.
>     enum {
>      ALL_LOCATIONS = 0,
>      NO_LOCAL_MEM = 1 << 0,
>      NO_CONST_MEM = 1 << 1,
>      NO_GLOBAL_INTERNAL_MEM = 1 << 2,
>      NO_GLOBAL_EXTERNAL_MEM = 1 << 3,
>      NO_GLOBAL_MEM = NO_GLOBAL_INTERNAL_MEM | NO_GLOBAL_EXTERNAL_MEM,
>      NO_ARGUMENT_MEM = 1 << 4,
>      NO_INACCESSIBLE_MEM = 1 << 5,
>      NO_MALLOCED_MEM = 1 << 6,
>      NO_UNKOWN_MEM = 1 << 7,
>      NO_LOCATIONS = NO_LOCAL_MEM | NO_CONST_MEM | 
> NO_GLOBAL_INTERNAL_MEM |
>                     NO_GLOBAL_EXTERNAL_MEM | NO_ARGUMENT_MEM |
>                     NO_INACCESSIBLE_MEM | NO_MALLOCED_MEM | 
> NO_UNKOWN_MEM,
>     }
> ```
>
> I was thinking to use this, or a variation of that, as the argument of 
> an attribute. Thus,
>   `access_locations(~(NO_GLOBAL_MEM | NO_ARGUMENT_MEM))`
> to express argument and global memory is potentially accessed.
>
> That said, I *also* want us to allow to use this interface for 
> "special memory locations".
> What I mean is for example a special "location" for things like 
> intrinsics:
>   `llvm.assume` writes only to bit "LLVM_ASSUME_MEM"
>   `llvm.launder.invariant.group` writes only to bit 
> "LLVM_LAUNDER_INVARIANT_GROUP" (D109548)
>   ...
> This way they stop to interfere with each other and other effects.

This last piece reads like a separate change to me.  I wouldn't want to 
tie the inversion with this extension.  Having said that, let me bike 
shed your separate proposal.  :)

If we had an attribute which allowed a specific list of globals 
potentially aliased, and introduced a set of predefined symbolic global 
names, we could solve this use case and also handle the more general 
"but this function has a known aliasing set!" use case as well.  In 
pseudo IR, consider:

@G = external global i32

declare void @restricted() globalmayalias(@G, @llvm.assume_control)

In fact, the original motivation for the globalmemonly proposal could be 
alternatively solved with:

@errno = external global i32

declare void @mathfunc(float, float) globalmayalias(@errno)

>
> I hope this makes some sense.
>
> ~ Johannes
>
>
>
>>
>> Cheers,
>> Nicolai
>>
>> On Sat, Sep 11, 2021 at 9:16 PM Mugilan Ganesan via llvm-dev <
>> llvm-dev at lists.llvm.org> wrote:
>>
>>> Hello everyone,
>>>
>>> We propose the addition of a GlobalMemOnly attribute to LLVM.
>>>
>>> Definition:
>>>
>>> This attribute indicates that the only memory accessed inside a 
>>> function,
>>> that is visible to the callee, is global memory. If the function 
>>> reads or
>>> writes other memory that is visible to the callee, the behavior is
>>> undefined.
>>>
>>> Motivation:
>>>
>>> Memory attributes already exist for specifying the memory locations
>>> accessed by a function, such as ArgMemOnly and InacessibleMemOnly.
>>> Similarly, there are attributes for describing memory behaviour, 
>>> such as
>>> ReadOnly and WriteOnly.
>>>
>>> However, no attributes exist for differentiating the types of memory
>>> objects that functions can access, such as global objects and objects
>>> created by alloca. We would like to start by introducing an 
>>> attribute to
>>> deal with functions that only access global objects.
>>>
>>> The addition of the GlobalMemOnly attribute can benefit LLVM as 
>>> follows:
>>>
>>> 1. Improves Alias Analysis, since this information can be used to 
>>> improve
>>> the determination of aliasing between functions and memory locations 
>>> that
>>> point to global objects.
>>>
>>> 2. Provides Transforms with greater information: many math lib calls 
>>> only
>>> modify the global variable errno. Unnecessary loads of the call 
>>> arguments
>>> can therefore be removed, since the calls will have no side-effects 
>>> on them.
>>>
>>> Patches Overview:
>>>
>>> 1. Definition of GlobalMemOnly in the AsmParser, IR, and LLVM 
>>> Bitcode. It
>>> is also defined in the LangRef.
>>>
>>> https://reviews.llvm.org/D109644
>>>
>>> 2. Support is added to Alias Analysis. If a function is 
>>> GlobalMemOnly and
>>> a memory location does not point to a global object, getModRefInfo can
>>> infer that no aliasing between the function and the location can occur.
>>> This patch also adds a regression test for BasicAA.
>>>
>>> https://reviews.llvm.org/D109647
>>>
>>> 3. Certain math lib calls are assigned GlobalMemOnly, since they only
>>> modify the global variable errno. These calls include common functions,
>>> such as atan, exp, and log.
>>>
>>> https://reviews.llvm.org/D109648
>>>
>>> Please let us know of any thoughts you may have regarding this 
>>> attribute’s
>>> implementation and use cases. We believe that it can strengthen LLVM’s
>>> alias analysis and optimization passes if added.
>>>
>>> Thanks,
>>> Mugilan
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> llvm-dev at lists.llvm.org
>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>
>>
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev


More information about the llvm-dev mailing list