Hal Finkel via llvm-dev
2015-Dec-11 21:51 UTC
[llvm-dev] RFC: New function attribute HasInaccessibleState
----- Original Message -----> From: "Joseph Tremoulet" <jotrem at microsoft.com> > To: "Hal Finkel" <hfinkel at anl.gov>, "Mehdi Amini" <mehdi.amini at apple.com> > Cc: "llvm-dev" <llvm-dev at lists.llvm.org> > Sent: Friday, December 11, 2015 3:35:38 PM > Subject: RE: [llvm-dev] RFC: New function attribute HasInaccessibleState > > Yeah, I'd agree (rewording slightly) that "state which is only > modified by external code" is well-defined (and likely to be in the > "other" bucket of any individual analysis). I do, as other have, > find it odd to redefine readonly and argmemonly in terms of this and > require its propagation up the call graph, as opposed to introducing > new "writes only external" and "writes only arg and external" > attributes.As I stated in some other e-mail, I'm against adding this as a "subtractive" attribute. We need to add these as new attributes, not as an attribute that makes readonly a little less read only. I believe we're in agreement on this point. -Hal> > Thanks > -Joseph > > -----Original Message----- > From: Hal Finkel [mailto:hfinkel at anl.gov] > Sent: Friday, December 11, 2015 4:00 PM > To: Mehdi Amini <mehdi.amini at apple.com> > Cc: llvm-dev <llvm-dev at lists.llvm.org>; Joseph Tremoulet > <jotrem at microsoft.com> > Subject: Re: [llvm-dev] RFC: New function attribute > HasInaccessibleState > > ----- Original Message ----- > > From: "Mehdi Amini" <mehdi.amini at apple.com> > > To: "Joseph Tremoulet" <jotrem at microsoft.com> > > Cc: "Hal Finkel" <hfinkel at anl.gov>, "llvm-dev" > > <llvm-dev at lists.llvm.org> > > Sent: Friday, December 11, 2015 1:28:05 PM > > Subject: Re: [llvm-dev] RFC: New function attribute > > HasInaccessibleState > > > > > > > On Dec 11, 2015, at 11:16 AM, Joseph Tremoulet > > > <jotrem at microsoft.com> wrote: > > > > > > <<< > > > I may misunderstand, but it seems to me that this solves only > > > query > > > for aliasing with a pointer known to be pointing only to globals > > > defined in the current compilation unit. > > > For any pointer which "may point somewhere else”, you won’t be > > > able > > > to resolve the non-aliasing with the “internal state” for > > > malloc/free, right? > > > > > > To take the original example in this thread: > > > > > > int *x = malloc(4); > > > *x = 2; > > > int *y = malloc(4); > > > *y = 4; > > > > > > A pointer analysis can solve this case, but I’m not sure it scale > > > inter procedurally and will have a limited impact outside of LTO > > > anyway. > > >>>> > > > > > > I think you're understanding correctly, but I don't understand > > > what > > > you're saying will go badly with the malloc example. Quoting the > > > start of the thread: > > > > > > <<< > > > The intention behind introducing this attribute is to relax the > > > conditions in GlobalsAA as below: > > > (this code is in GlobalsAAResult::AnalyzeCallGraph) > > > if (F->isDeclaration()) { > > > // Try to get mod/ref behaviour from function attributes. > > > - if (F->doesNotAccessMemory()) { > > > + if (F->doesNotAccessMemory() || > > > F->onlyAccessesArgMemory()) { > > > // Can't do better than that! > > > } else if (F->onlyReadsMemory()) { > > > FunctionEffect |= Ref; > > > if (!F->isIntrinsic()) > > > // This function might call back into the module and > > > read a global - > > > // consider every global as possibly being read by > > > this > > > function. > > > FR.MayReadAnyGlobal = true; > > > } else { > > > FunctionEffect |= ModRef; > > > // Can't say anything useful unless it's an intrinsic - > > > they don't > > > // read or write global variables of the kind > > > considered > > > here. > > > KnowNothing = !F->isIntrinsic(); > > > } > > > continue; > > > } > > > This relaxation allows functions that (transitively) call library > > > functions (such as printf/malloc) to still maintain and propagate > > > GlobalsAA info. In general, this adds more precision to the > > > description of these functions. > > > Concerns regarding impact on other optimizations (I'm repeating a > > > few examples that Hal mentioned earlier). > > > > > > 1. > > >> A readnone function is one whose output is a function only of > > >> its > > >> inputs, and if you have this: > > >> > > >> int *x = malloc(4); > > >> *x = 2; > > >> int *y = malloc(4); > > >> *y = 4; > > >> you certainly don't want EarlyCSE to replace the second call to > > >> malloc with the result of the first (which it will happily do if > > >> you mark malloc as readnone). > > >>>> > > > > > > It sounded like improving GlobalsAA (and thus disambiguation > > > against > > > globals) was the explicit goal, and that the concern with the > > > malloc > > > case was that you don't want EarlyCSE to start combining those > > > two > > > calls; I may be misunderstanding the code, but I wouldn't expect > > > EarlyCSE to start combining those calls just because they have a > > > new > > > meaningful-only-to-GlobalsAA "almost-readnone" attribute. > > > > Sure, my point is not that your solution would enable CSE where we > > don’t want, but rather that it is not as powerful as what the > > attribute “HasInaccessibleState” would model, which I saw as "this > > function might access globals, but none of these globals can alias > > with any memory location accessible from the IR being optimized”. > > This is also, essentially, what I had in mind. I think it is > sufficiently well defined in this form. > > -Hal > > > For instance: > > > > void foo(int *x) { > > int *y = malloc(4); > > *x = 2; > > } > > > > If you don’t know anything about x, can you execute the write to *x > > before the call to malloc? > > This is something that the HasInaccessibleState would allow, but I > > don’t believe would be possible with your categorization. > > > > I’m don’t know how much it matters in practice, but I’d rather be > > sure > > we’re on the same track about the various tradeoff. > > > > — > > Mehdi > > > > > > > > > > > > > > > To the larger point of whether there are other similar cases that > > > extending GlobalsAA wouldn't allow us to optimize -- yes, > > > certainly. > > > I'm just saying that I think that the notion of "external state" > > > is > > > much easier to define in the context of a particular analysis > > > than > > > the IR as a whole, and that I'd expect that coordinating the > > > notion > > > across analyses would require methods on the analysis API > > > explicitly > > > for that coordination. > > > > > > > > > > > > — > > > Mehdi > > > > > > > > > -- > Hal Finkel > Assistant Computational Scientist > Leadership Computing Facility > Argonne National Laboratory >-- Hal Finkel Assistant Computational Scientist Leadership Computing Facility Argonne National Laboratory
Vaivaswatha Nagaraj via llvm-dev
2015-Dec-14 03:50 UTC
[llvm-dev] RFC: New function attribute HasInaccessibleState
>I'm against adding this as a "subtractive" attribute. We need to add theseas new attributes, not as an attribute that makes readonly a little less read only. I believe we're in agreement on this point. Just to make sure I understood right, below are the things that need to be done: (Approach A) 1. We define a new a attribute "HasInaccessibleState" to denote "this function might access globals, but none of these globals can alias with any memory location accessible from the IR being optimized". 2. Mark malloc/free as (HasInaccessibleState, ReadNone) and printf as (HasInaccessibleState, ArgMemOnly) ... (similarly other libc functions). 3. Any function whose definition is not available needs to be marked with "HasInaccessibleState" (conservatively). 4. Propagate the flag "HasInaccessibleState" upwards in the call graph. (Do this in FunctionAttrs.cpp?). 5. Since ReadNone and ArgMemOnly has now been redfined, all optimizations that rely on these flags for safety now also need to check the new "HasInaccessibleState" flag and make sure it isn't present. 6. GlobalsAA will be modified according to the diff in the first mail in this email thread. The alternative approach that was discussed would involve the following changes: (Approach B) 1. Define new attributes AlmostReadNone and AlmostArgMemOnly, (with the "Almost" part denoting that the function may accesses globals that are not part of the IR). 2. malloc/free would have AlmostReadNone set and printf would have AlmostArgMemOnly set ... (and similarly other libc calls). 3. In the diff I originally posted for GlobalsAA, the code would check for AlmostReadNone or AlmostArgMemOnly too (along with ReadNone or ArgMemOnly). Approach B seems simpler to me, but I understand the concern about having a "subtractive" attribute which is new to the framework. If there is a consensus on which of these two approaches is the way to go, I can submit a quick prototype patch for further review/discussion. Thanks, - Vaivaswatha On Sat, Dec 12, 2015 at 3:21 AM, Hal Finkel via llvm-dev < llvm-dev at lists.llvm.org> wrote:> ----- Original Message ----- > > From: "Joseph Tremoulet" <jotrem at microsoft.com> > > To: "Hal Finkel" <hfinkel at anl.gov>, "Mehdi Amini" <mehdi.amini at apple.com > > > > Cc: "llvm-dev" <llvm-dev at lists.llvm.org> > > Sent: Friday, December 11, 2015 3:35:38 PM > > Subject: RE: [llvm-dev] RFC: New function attribute HasInaccessibleState > > > > Yeah, I'd agree (rewording slightly) that "state which is only > > modified by external code" is well-defined (and likely to be in the > > "other" bucket of any individual analysis). I do, as other have, > > find it odd to redefine readonly and argmemonly in terms of this and > > require its propagation up the call graph, as opposed to introducing > > new "writes only external" and "writes only arg and external" > > attributes. > > As I stated in some other e-mail, I'm against adding this as a > "subtractive" attribute. We need to add these as new attributes, not as an > attribute that makes readonly a little less read only. I believe we're in > agreement on this point. > > -Hal > > > > > Thanks > > -Joseph > > > > -----Original Message----- > > From: Hal Finkel [mailto:hfinkel at anl.gov] > > Sent: Friday, December 11, 2015 4:00 PM > > To: Mehdi Amini <mehdi.amini at apple.com> > > Cc: llvm-dev <llvm-dev at lists.llvm.org>; Joseph Tremoulet > > <jotrem at microsoft.com> > > Subject: Re: [llvm-dev] RFC: New function attribute > > HasInaccessibleState > > > > ----- Original Message ----- > > > From: "Mehdi Amini" <mehdi.amini at apple.com> > > > To: "Joseph Tremoulet" <jotrem at microsoft.com> > > > Cc: "Hal Finkel" <hfinkel at anl.gov>, "llvm-dev" > > > <llvm-dev at lists.llvm.org> > > > Sent: Friday, December 11, 2015 1:28:05 PM > > > Subject: Re: [llvm-dev] RFC: New function attribute > > > HasInaccessibleState > > > > > > > > > > On Dec 11, 2015, at 11:16 AM, Joseph Tremoulet > > > > <jotrem at microsoft.com> wrote: > > > > > > > > <<< > > > > I may misunderstand, but it seems to me that this solves only > > > > query > > > > for aliasing with a pointer known to be pointing only to globals > > > > defined in the current compilation unit. > > > > For any pointer which "may point somewhere else”, you won’t be > > > > able > > > > to resolve the non-aliasing with the “internal state” for > > > > malloc/free, right? > > > > > > > > To take the original example in this thread: > > > > > > > > int *x = malloc(4); > > > > *x = 2; > > > > int *y = malloc(4); > > > > *y = 4; > > > > > > > > A pointer analysis can solve this case, but I’m not sure it scale > > > > inter procedurally and will have a limited impact outside of LTO > > > > anyway. > > > >>>> > > > > > > > > I think you're understanding correctly, but I don't understand > > > > what > > > > you're saying will go badly with the malloc example. Quoting the > > > > start of the thread: > > > > > > > > <<< > > > > The intention behind introducing this attribute is to relax the > > > > conditions in GlobalsAA as below: > > > > (this code is in GlobalsAAResult::AnalyzeCallGraph) > > > > if (F->isDeclaration()) { > > > > // Try to get mod/ref behaviour from function attributes. > > > > - if (F->doesNotAccessMemory()) { > > > > + if (F->doesNotAccessMemory() || > > > > F->onlyAccessesArgMemory()) { > > > > // Can't do better than that! > > > > } else if (F->onlyReadsMemory()) { > > > > FunctionEffect |= Ref; > > > > if (!F->isIntrinsic()) > > > > // This function might call back into the module and > > > > read a global - > > > > // consider every global as possibly being read by > > > > this > > > > function. > > > > FR.MayReadAnyGlobal = true; > > > > } else { > > > > FunctionEffect |= ModRef; > > > > // Can't say anything useful unless it's an intrinsic - > > > > they don't > > > > // read or write global variables of the kind > > > > considered > > > > here. > > > > KnowNothing = !F->isIntrinsic(); > > > > } > > > > continue; > > > > } > > > > This relaxation allows functions that (transitively) call library > > > > functions (such as printf/malloc) to still maintain and propagate > > > > GlobalsAA info. In general, this adds more precision to the > > > > description of these functions. > > > > Concerns regarding impact on other optimizations (I'm repeating a > > > > few examples that Hal mentioned earlier). > > > > > > > > 1. > > > >> A readnone function is one whose output is a function only of > > > >> its > > > >> inputs, and if you have this: > > > >> > > > >> int *x = malloc(4); > > > >> *x = 2; > > > >> int *y = malloc(4); > > > >> *y = 4; > > > >> you certainly don't want EarlyCSE to replace the second call to > > > >> malloc with the result of the first (which it will happily do if > > > >> you mark malloc as readnone). > > > >>>> > > > > > > > > It sounded like improving GlobalsAA (and thus disambiguation > > > > against > > > > globals) was the explicit goal, and that the concern with the > > > > malloc > > > > case was that you don't want EarlyCSE to start combining those > > > > two > > > > calls; I may be misunderstanding the code, but I wouldn't expect > > > > EarlyCSE to start combining those calls just because they have a > > > > new > > > > meaningful-only-to-GlobalsAA "almost-readnone" attribute. > > > > > > Sure, my point is not that your solution would enable CSE where we > > > don’t want, but rather that it is not as powerful as what the > > > attribute “HasInaccessibleState” would model, which I saw as "this > > > function might access globals, but none of these globals can alias > > > with any memory location accessible from the IR being optimized”. > > > > This is also, essentially, what I had in mind. I think it is > > sufficiently well defined in this form. > > > > -Hal > > > > > For instance: > > > > > > void foo(int *x) { > > > int *y = malloc(4); > > > *x = 2; > > > } > > > > > > If you don’t know anything about x, can you execute the write to *x > > > before the call to malloc? > > > This is something that the HasInaccessibleState would allow, but I > > > don’t believe would be possible with your categorization. > > > > > > I’m don’t know how much it matters in practice, but I’d rather be > > > sure > > > we’re on the same track about the various tradeoff. > > > > > > — > > > Mehdi > > > > > > > > > > > > > > > > > > > > > To the larger point of whether there are other similar cases that > > > > extending GlobalsAA wouldn't allow us to optimize -- yes, > > > > certainly. > > > > I'm just saying that I think that the notion of "external state" > > > > is > > > > much easier to define in the context of a particular analysis > > > > than > > > > the IR as a whole, and that I'd expect that coordinating the > > > > notion > > > > across analyses would require methods on the analysis API > > > > explicitly > > > > for that coordination. > > > > > > > > > > > > > > > > — > > > > Mehdi > > > > > > > > > > > > > > -- > > Hal Finkel > > Assistant Computational Scientist > > Leadership Computing Facility > > Argonne National Laboratory > > > > -- > Hal Finkel > Assistant Computational Scientist > Leadership Computing Facility > Argonne National Laboratory > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151214/564638b0/attachment.html>
Sanjoy Das via llvm-dev
2015-Dec-14 05:29 UTC
[llvm-dev] RFC: New function attribute HasInaccessibleState
Vaivaswatha Nagaraj via llvm-dev wrote: > >I'm against adding this as a "subtractive" attribute. We need to add these as new attributes, not as an attribute that > makes readonly a little less read only. I believe we're in agreement on this point. > Just to make sure I understood right, below are the things that need to be done: > (Approach A) > 1. We define a new a attribute "HasInaccessibleState" to denote "this function might access globals, but none of these > globals can alias with any memory location accessible from the IR being optimized". > 2. Mark malloc/free as (HasInaccessibleState, ReadNone) and printf as (HasInaccessibleState, ArgMemOnly) ... (similarly > other libc functions). You'll have to mark free as argmemonly + read-write, since the following transform needs to be illegal: val = *ptr free(ptr) => free(ptr) val = *ptr In fact, I think you can mark @free as argmemonly *today* without any problems. There is a theoretical issue on whether a "write" can make a location no longer dereferenceable, but that's not new. > 3. Any function whose definition is not available needs to be marked with "HasInaccessibleState" (conservatively). > 4. Propagate the flag "HasInaccessibleState" upwards in the call graph. (Do this in FunctionAttrs.cpp?). > 5. Since ReadNone and ArgMemOnly has now been redfined, all optimizations that rely on these flags for safety now also > need to check the new "HasInaccessibleState" flag and make sure it isn't present. > 6. GlobalsAA will be modified according to the diff in the first mail in this email thread. > > The alternative approach that was discussed would involve the following changes: > (Approach B) > 1. Define new attributes AlmostReadNone and AlmostArgMemOnly, (with the "Almost" part denoting that the function may > accesses globals that are not part of the IR). > 2. malloc/free would have AlmostReadNone set and printf would have AlmostArgMemOnly set ... (and similarly other libc > calls). > 3. In the diff I originally posted for GlobalsAA, the code would check for AlmostReadNone or AlmostArgMemOnly too (along > with ReadNone or ArgMemOnly). > > Approach B seems simpler to me, but I understand the concern about having a "subtractive" attribute which is new to the > framework. If there is a consensus on which of these two approaches is the way to go, I can submit a quick prototype > patch for further review/discussion. A third approach is to extend the noalias metadata [1] (I mentioned this earlier in the thread, but did not do a good job on expanding on it). Currently noalias metadata can be used to specify that a certain call or invoke does not read / modify memory locations belonging to certain *specific* alias domains. We could generalize this mechanism and specify a new kind of alias domain called (say) !ir-mem. Calls to @malloc and @printf could be marked with "!noalias !ir-mem" [2], and we could specify (as an axiom) that no loads and stores visible at the IR level alias with the !ir-mem domain. The advantage of this approach is that we won't have to introduce any fundamentally new first class concepts to LLVM IR (though it would still be a fair amount of work). [1]: http://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata [2]: We'll also have to introduce an "NoAliasIRMem" attribute, that can be used denote that all calls to the marked function are !noalias !ir-mem. -- Sanjoy > > Thanks, > > > - Vaivaswatha > > On Sat, Dec 12, 2015 at 3:21 AM, Hal Finkel via llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: > > ----- Original Message ----- > > From: "Joseph Tremoulet" <jotrem at microsoft.com <mailto:jotrem at microsoft.com>> > > To: "Hal Finkel" <hfinkel at anl.gov <mailto:hfinkel at anl.gov>>, "Mehdi Amini" <mehdi.amini at apple.com > <mailto:mehdi.amini at apple.com>> > > Cc: "llvm-dev" <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> > > Sent: Friday, December 11, 2015 3:35:38 PM > > Subject: RE: [llvm-dev] RFC: New function attribute HasInaccessibleState > > > > Yeah, I'd agree (rewording slightly) that "state which is only > > modified by external code" is well-defined (and likely to be in the > > "other" bucket of any individual analysis). I do, as other have, > > find it odd to redefine readonly and argmemonly in terms of this and > > require its propagation up the call graph, as opposed to introducing > > new "writes only external" and "writes only arg and external" > > attributes. > > As I stated in some other e-mail, I'm against adding this as a "subtractive" attribute. We need to add these as new > attributes, not as an attribute that makes readonly a little less read only. I believe we're in agreement on this point. > > -Hal > > > > > Thanks > > -Joseph > > > > -----Original Message----- > > From: Hal Finkel [mailto:hfinkel at anl.gov <mailto:hfinkel at anl.gov>] > > Sent: Friday, December 11, 2015 4:00 PM > > To: Mehdi Amini <mehdi.amini at apple.com <mailto:mehdi.amini at apple.com>> > > Cc: llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>>; Joseph Tremoulet > > <jotrem at microsoft.com <mailto:jotrem at microsoft.com>> > > Subject: Re: [llvm-dev] RFC: New function attribute > > HasInaccessibleState > > > > ----- Original Message ----- > > > From: "Mehdi Amini" <mehdi.amini at apple.com <mailto:mehdi.amini at apple.com>> > > > To: "Joseph Tremoulet" <jotrem at microsoft.com <mailto:jotrem at microsoft.com>> > > > Cc: "Hal Finkel" <hfinkel at anl.gov <mailto:hfinkel at anl.gov>>, "llvm-dev" > > > <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> > > > Sent: Friday, December 11, 2015 1:28:05 PM > > > Subject: Re: [llvm-dev] RFC: New function attribute > > > HasInaccessibleState > > > > > > > > > > On Dec 11, 2015, at 11:16 AM, Joseph Tremoulet > > > > <jotrem at microsoft.com <mailto:jotrem at microsoft.com>> wrote: > > > > > > > > <<< > > > > I may misunderstand, but it seems to me that this solves only > > > > query > > > > for aliasing with a pointer known to be pointing only to globals > > > > defined in the current compilation unit. > > > > For any pointer which "may point somewhere else”, you won’t be > > > > able > > > > to resolve the non-aliasing with the “internal state” for > > > > malloc/free, right? > > > > > > > > To take the original example in this thread: > > > > > > > > int *x = malloc(4); > > > > *x = 2; > > > > int *y = malloc(4); > > > > *y = 4; > > > > > > > > A pointer analysis can solve this case, but I’m not sure it scale > > > > inter procedurally and will have a limited impact outside of LTO > > > > anyway. > > > >>>> > > > > > > > > I think you're understanding correctly, but I don't understand > > > > what > > > > you're saying will go badly with the malloc example. Quoting the > > > > start of the thread: > > > > > > > > <<< > > > > The intention behind introducing this attribute is to relax the > > > > conditions in GlobalsAA as below: > > > > (this code is in GlobalsAAResult::AnalyzeCallGraph) > > > > if (F->isDeclaration()) { > > > > // Try to get mod/ref behaviour from function attributes. > > > > - if (F->doesNotAccessMemory()) { > > > > + if (F->doesNotAccessMemory() || > > > > F->onlyAccessesArgMemory()) { > > > > // Can't do better than that! > > > > } else if (F->onlyReadsMemory()) { > > > > FunctionEffect |= Ref; > > > > if (!F->isIntrinsic()) > > > > // This function might call back into the module and > > > > read a global - > > > > // consider every global as possibly being read by > > > > this > > > > function. > > > > FR.MayReadAnyGlobal = true; > > > > } else { > > > > FunctionEffect |= ModRef; > > > > // Can't say anything useful unless it's an intrinsic - > > > > they don't > > > > // read or write global variables of the kind > > > > considered > > > > here. > > > > KnowNothing = !F->isIntrinsic(); > > > > } > > > > continue; > > > > } > > > > This relaxation allows functions that (transitively) call library > > > > functions (such as printf/malloc) to still maintain and propagate > > > > GlobalsAA info. In general, this adds more precision to the > > > > description of these functions. > > > > Concerns regarding impact on other optimizations (I'm repeating a > > > > few examples that Hal mentioned earlier). > > > > > > > > 1. > > > >> A readnone function is one whose output is a function only of > > > >> its > > > >> inputs, and if you have this: > > > >> > > > >> int *x = malloc(4); > > > >> *x = 2; > > > >> int *y = malloc(4); > > > >> *y = 4; > > > >> you certainly don't want EarlyCSE to replace the second call to > > > >> malloc with the result of the first (which it will happily do if > > > >> you mark malloc as readnone). > > > >>>> > > > > > > > > It sounded like improving GlobalsAA (and thus disambiguation > > > > against > > > > globals) was the explicit goal, and that the concern with the > > > > malloc > > > > case was that you don't want EarlyCSE to start combining those > > > > two > > > > calls; I may be misunderstanding the code, but I wouldn't expect > > > > EarlyCSE to start combining those calls just because they have a > > > > new > > > > meaningful-only-to-GlobalsAA "almost-readnone" attribute. > > > > > > Sure, my point is not that your solution would enable CSE where we > > > don’t want, but rather that it is not as powerful as what the > > > attribute “HasInaccessibleState” would model, which I saw as "this > > > function might access globals, but none of these globals can alias > > > with any memory location accessible from the IR being optimized”. > > > > This is also, essentially, what I had in mind. I think it is > > sufficiently well defined in this form. > > > > -Hal > > > > > For instance: > > > > > > void foo(int *x) { > > > int *y = malloc(4); > > > *x = 2; > > > } > > > > > > If you don’t know anything about x, can you execute the write to *x > > > before the call to malloc? > > > This is something that the HasInaccessibleState would allow, but I > > > don’t believe would be possible with your categorization. > > > > > > I’m don’t know how much it matters in practice, but I’d rather be > > > sure > > > we’re on the same track about the various tradeoff. > > > > > > — > > > Mehdi > > > > > > > > > > > > > > > > > > > > > To the larger point of whether there are other similar cases that > > > > extending GlobalsAA wouldn't allow us to optimize -- yes, > > > > certainly. > > > > I'm just saying that I think that the notion of "external state" > > > > is > > > > much easier to define in the context of a particular analysis > > > > than > > > > the IR as a whole, and that I'd expect that coordinating the > > > > notion > > > > across analyses would require methods on the analysis API > > > > explicitly > > > > for that coordination. > > > > > > > > > > > > > > > > — > > > > Mehdi > > > > > > > > > > > > > > -- > > Hal Finkel > > Assistant Computational Scientist > > Leadership Computing Facility > > Argonne National Laboratory > > > > -- > Hal Finkel > Assistant Computational Scientist > Leadership Computing Facility > Argonne National Laboratory > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Hal Finkel via llvm-dev
2015-Dec-14 08:06 UTC
[llvm-dev] RFC: New function attribute HasInaccessibleState
----- Original Message -----> From: "Vaivaswatha Nagaraj" <vn at compilertree.com> > To: "Hal Finkel" <hfinkel at anl.gov> > Cc: "Joseph Tremoulet" <jotrem at microsoft.com>, "llvm-dev" > <llvm-dev at lists.llvm.org> > Sent: Sunday, December 13, 2015 9:50:25 PM > Subject: Re: [llvm-dev] RFC: New function attribute > HasInaccessibleState> >I'm against adding this as a "subtractive" attribute. We need to add > >these as new attributes, not as an attribute that makes readonly a > >little less read only. I believe we're in agreement on this point. > Just to make sure I understood right, below are the things that need > to be done:> (Approach A)> 1. We define a new a attribute "HasInaccessibleState" to denote "this > function might access globals, but none of these globals can alias > with any memory location accessible from the IR being optimized". > 2. Mark malloc/free as (HasInaccessibleState, ReadNone) and printf as > (HasInaccessibleState, ArgMemOnly) ... (similarly other libc > functions). > 3. Any function whose definition is not available needs to be marked > with "HasInaccessibleState" (conservatively). > 4. Propagate the flag "HasInaccessibleState" upwards in the call > graph. (Do this in FunctionAttrs.cpp?). > 5. Since ReadNone and ArgMemOnly has now been redfined, all > optimizations that rely on these flags for safety now also need to > check the new "HasInaccessibleState" flag and make sure it isn't > present. > 6. GlobalsAA will be modified according to the diff in the first mail > in this email thread.> The alternative approach that was discussed would involve the > following changes:> (Approach B) > 1. Define new attributes AlmostReadNone and AlmostArgMemOnly, (with > the "Almost" part denoting that the function may accesses globals > that are not part of the IR). > 2. malloc/free would have AlmostReadNone set and printf would have > AlmostArgMemOnly set ... (and similarly other libc calls). > 3. In the diff I originally posted for GlobalsAA, the code would > check for AlmostReadNone or AlmostArgMemOnly too (along with > ReadNone or ArgMemOnly).> Approach B seems simpler to me, but I understand the concern about > having a "subtractive" attribute which is new to the framework.No, you have my concern reversed. Approach A is the "subtractive" one, because (HasInaccessibleState, ReadNone) "subtracts" from the meaning of ReadNone. This I am against. I am in favor of approach B (although perhaps with different names). Thanks again, Hal> If > there is a consensus on which of these two approaches is the way to > go, I can submit a quick prototype patch for further > review/discussion.> Thanks,> - Vaivaswatha> On Sat, Dec 12, 2015 at 3:21 AM, Hal Finkel via llvm-dev < > llvm-dev at lists.llvm.org > wrote:> > ----- Original Message ----- >> > > From: "Joseph Tremoulet" < jotrem at microsoft.com > > > > > To: "Hal Finkel" < hfinkel at anl.gov >, "Mehdi Amini" < > > > mehdi.amini at apple.com > > > > > Cc: "llvm-dev" < llvm-dev at lists.llvm.org > > > > > Sent: Friday, December 11, 2015 3:35:38 PM > > > > Subject: RE: [llvm-dev] RFC: New function attribute > > > HasInaccessibleState > > > > > > > > Yeah, I'd agree (rewording slightly) that "state which is only > > > > modified by external code" is well-defined (and likely to be in > > > the > > > > "other" bucket of any individual analysis). I do, as other have, > > > > find it odd to redefine readonly and argmemonly in terms of this > > > and > > > > require its propagation up the call graph, as opposed to > > > introducing > > > > new "writes only external" and "writes only arg and external" > > > > attributes. >> > As I stated in some other e-mail, I'm against adding this as a > > "subtractive" attribute. We need to add these as new attributes, > > not > > as an attribute that makes readonly a little less read only. I > > believe we're in agreement on this point. >> > -Hal >> > > > > > > Thanks > > > > -Joseph > > > > > > > > -----Original Message----- > > > > From: Hal Finkel [mailto: hfinkel at anl.gov ] > > > > Sent: Friday, December 11, 2015 4:00 PM > > > > To: Mehdi Amini < mehdi.amini at apple.com > > > > > Cc: llvm-dev < llvm-dev at lists.llvm.org >; Joseph Tremoulet > > > > < jotrem at microsoft.com > > > > > Subject: Re: [llvm-dev] RFC: New function attribute > > > > HasInaccessibleState > > > > > > > > ----- Original Message ----- > > > > > From: "Mehdi Amini" < mehdi.amini at apple.com > > > > > > To: "Joseph Tremoulet" < jotrem at microsoft.com > > > > > > Cc: "Hal Finkel" < hfinkel at anl.gov >, "llvm-dev" > > > > > < llvm-dev at lists.llvm.org > > > > > > Sent: Friday, December 11, 2015 1:28:05 PM > > > > > Subject: Re: [llvm-dev] RFC: New function attribute > > > > > HasInaccessibleState > > > > > > > > > > > > > > > > On Dec 11, 2015, at 11:16 AM, Joseph Tremoulet > > > > > > < jotrem at microsoft.com > wrote: > > > > > > > > > > > > <<< > > > > > > I may misunderstand, but it seems to me that this solves only > > > > > > query > > > > > > for aliasing with a pointer known to be pointing only to > > > > > globals > > > > > > defined in the current compilation unit. > > > > > > For any pointer which "may point somewhere else”, you won’t > > > > > be > > > > > > able > > > > > > to resolve the non-aliasing with the “internal state” for > > > > > > malloc/free, right? > > > > > > > > > > > > To take the original example in this thread: > > > > > > > > > > > > int *x = malloc(4); > > > > > > *x = 2; > > > > > > int *y = malloc(4); > > > > > > *y = 4; > > > > > > > > > > > > A pointer analysis can solve this case, but I’m not sure it > > > > > scale > > > > > > inter procedurally and will have a limited impact outside of > > > > > LTO > > > > > > anyway. > > > > > >>>> > > > > > > > > > > > > I think you're understanding correctly, but I don't > > > > > understand > > > > > > what > > > > > > you're saying will go badly with the malloc example. Quoting > > > > > the > > > > > > start of the thread: > > > > > > > > > > > > <<< > > > > > > The intention behind introducing this attribute is to relax > > > > > the > > > > > > conditions in GlobalsAA as below: > > > > > > (this code is in GlobalsAAResult::AnalyzeCallGraph) > > > > > > if (F->isDeclaration()) { > > > > > > // Try to get mod/ref behaviour from function attributes. > > > > > > - if (F->doesNotAccessMemory()) { > > > > > > + if (F->doesNotAccessMemory() || > > > > > > F->onlyAccessesArgMemory()) { > > > > > > // Can't do better than that! > > > > > > } else if (F->onlyReadsMemory()) { > > > > > > FunctionEffect |= Ref; > > > > > > if (!F->isIntrinsic()) > > > > > > // This function might call back into the module and > > > > > > read a global - > > > > > > // consider every global as possibly being read by > > > > > > this > > > > > > function. > > > > > > FR.MayReadAnyGlobal = true; > > > > > > } else { > > > > > > FunctionEffect |= ModRef; > > > > > > // Can't say anything useful unless it's an intrinsic - > > > > > > they don't > > > > > > // read or write global variables of the kind > > > > > > considered > > > > > > here. > > > > > > KnowNothing = !F->isIntrinsic(); > > > > > > } > > > > > > continue; > > > > > > } > > > > > > This relaxation allows functions that (transitively) call > > > > > library > > > > > > functions (such as printf/malloc) to still maintain and > > > > > propagate > > > > > > GlobalsAA info. In general, this adds more precision to the > > > > > > description of these functions. > > > > > > Concerns regarding impact on other optimizations (I'm > > > > > repeating > > > > > a > > > > > > few examples that Hal mentioned earlier). > > > > > > > > > > > > 1. > > > > > >> A readnone function is one whose output is a function only > > > > >> of > > > > > >> its > > > > > >> inputs, and if you have this: > > > > > >> > > > > > >> int *x = malloc(4); > > > > > >> *x = 2; > > > > > >> int *y = malloc(4); > > > > > >> *y = 4; > > > > > >> you certainly don't want EarlyCSE to replace the second call > > > > >> to > > > > > >> malloc with the result of the first (which it will happily > > > > >> do > > > > >> if > > > > > >> you mark malloc as readnone). > > > > > >>>> > > > > > > > > > > > > It sounded like improving GlobalsAA (and thus disambiguation > > > > > > against > > > > > > globals) was the explicit goal, and that the concern with the > > > > > > malloc > > > > > > case was that you don't want EarlyCSE to start combining > > > > > those > > > > > > two > > > > > > calls; I may be misunderstanding the code, but I wouldn't > > > > > expect > > > > > > EarlyCSE to start combining those calls just because they > > > > > have > > > > > a > > > > > > new > > > > > > meaningful-only-to-GlobalsAA "almost-readnone" attribute. > > > > > > > > > > Sure, my point is not that your solution would enable CSE where > > > > we > > > > > don’t want, but rather that it is not as powerful as what the > > > > > attribute “HasInaccessibleState” would model, which I saw as > > > > "this > > > > > function might access globals, but none of these globals can > > > > alias > > > > > with any memory location accessible from the IR being > > > > optimized”. > > > > > > > > This is also, essentially, what I had in mind. I think it is > > > > sufficiently well defined in this form. > > > > > > > > -Hal > > > > > > > > > For instance: > > > > > > > > > > void foo(int *x) { > > > > > int *y = malloc(4); > > > > > *x = 2; > > > > > } > > > > > > > > > > If you don’t know anything about x, can you execute the write > > > > to > > > > *x > > > > > before the call to malloc? > > > > > This is something that the HasInaccessibleState would allow, > > > > but > > > > I > > > > > don’t believe would be possible with your categorization. > > > > > > > > > > I’m don’t know how much it matters in practice, but I’d rather > > > > be > > > > > sure > > > > > we’re on the same track about the various tradeoff. > > > > > > > > > > — > > > > > Mehdi > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > To the larger point of whether there are other similar cases > > > > > that > > > > > > extending GlobalsAA wouldn't allow us to optimize -- yes, > > > > > > certainly. > > > > > > I'm just saying that I think that the notion of "external > > > > > state" > > > > > > is > > > > > > much easier to define in the context of a particular analysis > > > > > > than > > > > > > the IR as a whole, and that I'd expect that coordinating the > > > > > > notion > > > > > > across analyses would require methods on the analysis API > > > > > > explicitly > > > > > > for that coordination. > > > > > > > > > > > > > > > > > > > > > > > > — > > > > > > Mehdi > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > Hal Finkel > > > > Assistant Computational Scientist > > > > Leadership Computing Facility > > > > Argonne National Laboratory > > > > >> > -- > > > Hal Finkel > > > Assistant Computational Scientist > > > Leadership Computing Facility > > > Argonne National Laboratory > > > _______________________________________________ > > > LLVM Developers mailing list > > > llvm-dev at lists.llvm.org > > > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-- -- Hal Finkel Assistant Computational Scientist Leadership Computing Facility Argonne National Laboratory