[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