[llvm-dev] RFC: token arguments and operand bundles

Joseph Tremoulet via llvm-dev llvm-dev at lists.llvm.org
Mon Nov 18 10:36:20 PST 2019


> redefine token something like this...
> The other characteristics of tokens...

FWIW, I'd flip those.  In my mind, the defining property of tokens is that they are def/use links which compiler transformations are not allowed to obscure.  That's the part that defies typical expectations about values in the IR, and that absolutely is needed for their use cases.

[and I tend to think of constants as something outside of def/use-land, but I can appreciate that in LLVM they do get def/use links hooked up, so maybe what you're proposing isn't as unnatural in that context as it sounds to me...]

Another point that may be helpful to consider is, assuming that over time the set of things we want to model like this grows, whether one or the other representation would lend itself better to managing that.  So e.g. to keep separate the constants for rounding-mode vs fp-exception vs funclet, do we want literal enums, or some sort of "TokenKind", or predicates like `isRoundingMode(ConstantToken tok)`, or just conventions in the names ... and does the choice of using tokens or not for these make any of that easier or harder?

Related, experimental intrinsics are supposed to be the lightest-weight way to extend the IR, I think that would be a good thing to preserve.  I get that the use of tokens would be opt-in so anybody is still free to make experimental intrinsics that don't use them, but regardless of whether it's tokens or immediates, if there were a way to opt into this that could be more declarative and not require changing the parsers/emitters and IR type hierarchies, that could be valuable.

-Joseph

From: Kaylor, Andrew <andrew.kaylor at intel.com>
Sent: Friday, November 15, 2019 5:30 PM
To: Joseph Tremoulet <jotrem at microsoft.com>
Cc: llvm-dev <llvm-dev at lists.llvm.org>
Subject: RE: RFC: token arguments and operand bundles

Hi Joseph,

Thanks for the feedback. Ulrich Weigand raised the same concern about tokens in my Phabricator review. As I said there, I see the point. I'm definitely proposing a new use for the token type. For my use to be valid, I'd need to redefine token something like this: "a compiler-generated pseudo-value that is not intended to be represented in memory or register during program execution and can only be used by compiler-specific intrinsics and instructions." I think that covers the existing uses correctly. It is a new definition, but not one that would require any changes to implement.

The other characteristics of tokens, such as not being allowed in PHI or select instructions, are exactly what I'm after. I want a type of value that means what the optimizer says it means and nothing else. However, I will admit that what I want is more like an immediate operand that can only have one of the small set of existing values. Unlike the tokens used by Windows exception handling and coroutine intrinsics, I don't want these values to be part of a use-def chain, though perhaps Jameson does want that.

Anyway, I agree with your assessment that the operand bundle part of my proposal is on more solid ground than the token part.

Thanks,
Andy



From: Joseph Tremoulet <jotrem at microsoft.com<mailto:jotrem at microsoft.com>>
Sent: Friday, November 15, 2019 1:07 PM
To: Kaylor, Andrew <andrew.kaylor at intel.com<mailto:andrew.kaylor at intel.com>>
Cc: llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>>
Subject: RE: RFC: token arguments and operand bundles

As I recall, tokens were added largely as a mechanism to constrain particular users to particular single-entry regions of the CFG, and to do so in a way that guaranteed that later phases would be able to determine to which region any given use was tied.  That sounds pretty different to me than the use here of wanting something that's less string-y than metadata but prints as something less obtuse than an integer constant.  I think it would functionally work to do what you're proposing, but it strikes me as mixing unrelated concepts (one of which is already fairly esoteric) in a way that I for one would caution against.  Your issue here strikes me as similar to what 'immArg' addresses, and I'd imagine that having a way to constrain particular 'immArg' arguments to particular known enumerations of values in a way that prints legibly is something that could have other uses as well and involve less conceptual gymnastics.  I'll also note that with the CFG-centric view of tokens, it makes sense that the only constant token is 'None' - you only need one way to indicate "not tied to any region".


Bundles strike me as a better fit.  What strikes me as a bit odd there is that bundles tend (or at least originally tended) to be used to communicate things orthogonal to the semantics of the call itself (or the operation represented by the call) - the ambient state of the virtual machine, the GC values that happen to be live across the call, the EH region that happens to contain the call.  In this new case, the bundle is communicating something relevant to the semantics of the operation that the call represents... but it's also true that, like the other examples, it's communicating something about the context or ambient state at the point of the call, and that it (IIUC) would be applied consistently across the different fp operations... so that one passes my sniff test, for whatever that's worth.


I'm also wondering if "named metadata" could help with the readability issue.


-Joseph


From: llvm-dev <llvm-dev-bounces at lists.llvm.org<mailto:llvm-dev-bounces at lists.llvm.org>> On Behalf Of Kaylor, Andrew via llvm-dev
Sent: Thursday, November 14, 2019 2:40 PM
To: LLVM Developers Mailing List <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>>
Subject: [llvm-dev] RFC: token arguments and operand bundles

Hello everyone,

I've just uploaded a patch (https://reviews.llvm.org/D70261<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Freviews.llvm.org%2FD70261&data=02%7C01%7Cjotrem%40microsoft.com%7C4f89d13e662746fc160b08d76a1b6aa3%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637094538297457493&sdata=mjXzixNTGqMytNI8x%2BMk90tuFeL2JsYMe6vshMYG7aE%3D&reserved=0>) to introduce a could of new token types to be used with constrained floating point intrinsics and, optionally, vector predicated intrinsics. These intrinsics may not be of interest to many of you, but I have a more general question.

I would like some general feedback on the way I am proposing to use token arguments and operand bundles. I have an incomplete understanding of how these are intended to be used, and I want to make sure what I have in mind is consistent with the philosophy behind them.

Currently, the constrained floating point intrinsics require string metadata arguments to describe the rounding mode and exception semantics. These "arguments" are really providing information to the optimizer about what it can and cannot assume when acting on these intrinsics. The rounding mode argument potentially overrides the default optimizer assumption that the "to nearest" rounding mode is in use, and the exception behavior argument overrides the default optimizer assumption that floating point operations have no side effects. I've never liked the use of strings here, and the fact that these arguments are not actually inputs to the operation represented by the intrinsic seems vaguely wrong.

A typical call to a current intrinsic looks like this:

%sum = call double @llvm.experimental.constrained.fadd(double %x,
                                                       double %y,
                                                       Metadata "fpround.dynamic",
                                                       Metadata "fpexcept.strict")

The idea I am pursuing in my patch is to replace these metadata arguments with optional operand bundles, "fpround" and "fpexcept". If the operand bundles are present, they would mean what the arguments currently mean. If not, the default assumption is allowed. A typical call to a constrained intrinsic would look like this:

%sum = call double @llvm.experimental2.constrained.fadd(double %x,
                                                        double %y) [ "fpround"(token rmDynamic),
                                                                     "fpexcept"(token ebStrict) ]

Does that seem like a valid use of tokens and operand bundles? Does it seem better than the current approach?

Thanks,
Andy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191118/2156991e/attachment.html>


More information about the llvm-dev mailing list