[LLVMdev] Add a 'notrap' function attribute?
Hal Finkel
hfinkel at anl.gov
Fri Nov 1 15:13:24 PDT 2013
----- Original Message -----
>
>
>
> On Nov 1, 2013, at 4:48 AM, Hal Finkel < hfinkel at anl.gov > wrote:
>
>
> 3. Represent the control dependencies explicitly in the metadata.
> Andy, Arnold (CC'd) and I have been discussing this in a
> slightly-different context, and briefly, this means adding all of
> the relevant conditional branch inputs to the metadata, and ensuring
> dominance before the metadata is respected. For example:
>
> if (i1 %c = call z_is_never_zero()) {
> %x = %y / %z !notrap !{ %c }
> ...
> }
>
> and so if we run across this situation:
>
> %x = %y / %z !notrap !{ %c }
> if (i1 %c = call z_is_never_zero()) {
> ...
> }
>
> we can test that the %c does not dominate %x, and so the metadata
> needs to be ignored. The complication here is that you may need to
> encode all conditional branch inputs along all paths from the entry
> to the value, and the scheme also needs to deal with maythrow
> functions.
>
>
>
> This does not need to be resolved to move forward with Pekka’s
> proposal, but since we’re talking about it...
>
*If* we're going to introduce metadata with implied control dependencies, then we need to figure this out. Otherwise, yes.
>
> - The control dependent metadata looks like it could work, I like the
> idea (although we’re lacking a strong motivation)
>
>
> - I’m not sure why divide-by-zero would motivate this (probably just
> missing something). LLVM doesn’t model it as a trap currently. And
> if it did, an explicit nonzero-divisor check would be easy to reason
> about without any metadata.
I think that the proposal is meant to be more general, also covering things like ensuring that loads/stores don't trap. Specifically being able to indicate that certain loads (and perhaps stores) are safe to speculatively execute is my primary interest in this.
>
>
> - The semantics should be that control dependent metadata is
> guaranteed if only the encoded conditions can be proven to hold,
> independent of surrounding control flow. So we would never use this
> if we needed to encode all branch conditions from entry to home
> block. e.g. only a single nonzero divisor check is sufficient.
Sounds good (I've not thought of a counter-example).
>
>
> - We would need to encode the sense of the condition (true or false).
Good point. More generally, it would need to encode which branch index we need (in the case of a switch instruction).
> The metadata is still valid if we can see that the condition
> controls a branch, and the corresponding branch target
> (non-critical-edge) dominates the operation. This is cool because
> optimizations can be totally oblivious, but the information will
> still be preserved most of the time.
>
>
>
>
>
> and the scheme also needs to deal with maythrow functions.
I think that you misunderstood what I meant. If we have:
check_something();
%x = load %ptr, !notrap
Then it could be that %ptr will never trap because check_something() will throw in all cases where the load will trap. As a result, we also need to encode a dependency between all functions that may throw (or longjmp or whatever) and the notrap metadata.
Thanks again,
Hal
>
>
> I guess maythrow is implicitly the inverse of nounwind. notrap is
> similar but actually makes much more sense to me as an attribute. (I
> always thought that maythrow should be modeled with an invoke).
> longjmp isn’t clean but could be modeled as writing all memory and
> maybe-trapping.
>
>
> Adding a flag for every subtle behavior gets pedantic, as seen in
> this thread:
> http://llvm.1065342.n5.nabble.com/Does-nounwind-have-semantics-td59631.html
>
>
> The much more interesting question to me is what are the semantics of
> traps? Conservatively, we now assume they are well defined calls to
> abort(). I think that is way too conservative for most uses. It
> would be great to have another flavor of trap that can be reordered
> with certain side effects, particularly other “floating traps". Nuno
> Lopes ran into this problem with bounds check elimination. I don’t
> have a link to the discussion.
>
>
>
>
> Given that the common use case for this seems like it will be for
> some language frontend to add !notrap to *all* instances of some
> kind of instruction (divisions, load, etc.), I think that adding a
> new flag (like the nsw flag) may be more appropriate for efficiency
> reasons. Even easier, add some more fine-grained function attributes
> (as you had suggested).
>
>
>
> Good point. Seems like a future optimization though.
>
>
> Also, I think that being able to tag a memory access as no trapping
> could be a big win for C++ too, because we could tag all
> loads/stores that come from C++ reference types as not trapping.
> Because of the way that iterators are defined, I suspect this would
> have a lot of positive benefits in terms of LICM and other
> optimizations.
>
>
> I didn’t follow this, but obviously it would be a huge benefit type
> checked languages. Teaching optimizations about it would be
> nontrivial work though.
>
>
> -Andy
--
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory
More information about the llvm-dev
mailing list