Johannes Doerfert via llvm-dev
2021-Sep-14 16:50 UTC
[llvm-dev] [RFC] Adding a globalmemonly attribute for functions that only access global memory
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. 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
Philip Reames via llvm-dev
2021-Sep-14 18:03 UTC
[llvm-dev] [RFC] Adding a globalmemonly attribute for functions that only access global memory
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