Overhauling Attributes Problem ====== LTO needs a way to pass options through to different parts of the compiler. In particular, we need to pass code generation options to the back-end. The way we want to do this is via the LLVM Attributes class. In order to do that, we need to overhaul the Attributes class. The Attributes class right now isn't very extensible. After considering several different options, we decided it was best to extend the Attributes class to support *all* code generation options, even target-specific ones. It already supports some of them (like SSP), but it isn't very extensible because it is a fixed size bitfield. The size restriction also makes supporting options with values very difficult. As the number of options grow, we will soon have run out of space entirely. Target-Specific Attributes in IR =============================== I propose that the target-specific attributes would be organized into groups. Those groups would then be referenced by the functions directly. Here is an example of what that could look like: attrgroup #1 = { "long-calls", "cpu=cortex-a8", "thumb" } define void @func() noinline ssp attrgroup(#1) { ret void } Each target would know which options it can handle and how to parse them correctly. Code generation would use the attribute group referenced by the function to guide what code it emits. First Step ========= The first step of making a major change to attributes is to change the interface for creating them into something that works with different designs. This will allow the implementation to be swapped out independently of all the clients changing. It would then expose a very simple predicate interface. Building attributes for LLVM objects will be done with simple 'add*' methods: An example syntax could be: // Building an Attribute Attributes A; A.addAlignAttr(4) .addNoUnwindAttr() .addStackProtectorAttr() .addUnwindTableAttr() .addReadNoneAttr(); // Querying an Attribute if (!A.hasStackProtector() || A.hasAlign(4)) ... The Attributes class will be expanded in the future to support code generation and target-specific options. But it won't require a massive rewrite of the compiler to do so. The bit-wise operations on the Attributes class will need to be removed. This is because the internals of the Attributes class may no longer be a bitfield. Summary ====== The Attributes class is going to change in some seriously fundamental ways, but it will result in a much more extensible and flexible class. The changes to the code base will be mostly mechanical in nature. The transition is easily serialized, so any problems can be caught early on.
I love it in principle. As you get closer to finalizing the syntax, etc. I might have some more detailed comments, but nothing really substantive. Minor API comment as that seems more immediate: On Wed, Sep 19, 2012 at 3:25 PM, Bill Wendling <wendling at apple.com> wrote:> An example syntax could be: > > // Building an Attribute > > Attributes A; > A.addAlignAttr(4) > .addNoUnwindAttr() > .addStackProtectorAttr() > .addUnwindTableAttr() > .addReadNoneAttr(); >Personally, I would prefer to make the Attributes class be immutable, and the building happen in a helper. One possible interface would end up looking like: Attributes Base = ...; Attributes A = Attributes::Builder(Base).addNoUnwind() .addStackProtector() .addAlign(4);> > // Querying an Attribute > > if (!A.hasStackProtector() || A.hasAlign(4)) > ... > > The Attributes class will be expanded in the future to support code > generation > and target-specific options. But it won't require a massive rewrite of the > compiler to do so. > > The bit-wise operations on the Attributes class will need to be removed. > This is > because the internals of the Attributes class may no longer be a bitfield. > > Summary > ======> > The Attributes class is going to change in some seriously fundamental > ways, but > it will result in a much more extensible and flexible class. The changes > to the > code base will be mostly mechanical in nature. The transition is easily > serialized, so any problems can be caught early on. > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120919/50378706/attachment.html>
On Sep 19, 2012, at 4:09 PM, Chandler Carruth <chandlerc at google.com> wrote:> I love it in principle. As you get closer to finalizing the syntax, etc. I might have some more detailed comments, but nothing really substantive. >Yeah. I have a notion of what I'd like the syntax to look like, but that's not what this proposal is for. This is basically a "heads up!" that I'm about to change the Attributes class.> Minor API comment as that seems more immediate: > > On Wed, Sep 19, 2012 at 3:25 PM, Bill Wendling <wendling at apple.com> wrote: > An example syntax could be: > > // Building an Attribute > > Attributes A; > A.addAlignAttr(4) > .addNoUnwindAttr() > .addStackProtectorAttr() > .addUnwindTableAttr() > .addReadNoneAttr(); > > Personally, I would prefer to make the Attributes class be immutable, and the building happen in a helper. One possible interface would end up looking like: > > Attributes Base = ...; > > Attributes A = Attributes::Builder(Base).addNoUnwind() > .addStackProtector() > .addAlign(4); > >I would like that too. Hmm...This has potential. Though I'll need to see how it plays out in practice. A lot of uses look like they assume a mutable object... -bw
If you make syntax changes please send patches to Pygments so that our Sphinx docs remain pretty. Sphinx handles failures to lex in an extremely non-graceful way; basically, it's policy is that if the code it is asked to format as a particular language doesn't match it's lexer, then it just gives up and leaves the entire block of code unhighlighted :( Even so much as using a keyword it doesn't recognize will cause it to bail out immediately and leave the `.. code-block::` completely unhighlighted. The relevant part of Pygments is <https://bitbucket.org/birkenfeld/pygments-main/src/e97df81b39c7/pygments/lexers/asm.py#cl-193>; it's pretty self-explanatory. ...aside... When I was attempting to Sphinxify LangRef, I actually ran into a couple such instances where new keywords had been introduced. I never finished that attempt since I eventually realized that LangRef is 8000 lines of HTML: some kind of automated conversion is going to be necessary (even with fancy vim macros and stuff my ETA was still unreasonable). --Sean Silva On Wed, Sep 19, 2012 at 6:25 PM, Bill Wendling <wendling at apple.com> wrote:> Overhauling Attributes > > Problem > ======> > LTO needs a way to pass options through to different parts of the compiler. In > particular, we need to pass code generation options to the back-end. The way we > want to do this is via the LLVM Attributes class. In order to do that, we need > to overhaul the Attributes class. > > The Attributes class right now isn't very extensible. After considering several > different options, we decided it was best to extend the Attributes class to > support *all* code generation options, even target-specific ones. It already > supports some of them (like SSP), but it isn't very extensible because it is a > fixed size bitfield. The size restriction also makes supporting options with > values very difficult. As the number of options grow, we will soon have run out > of space entirely. > > Target-Specific Attributes in IR > ===============================> > I propose that the target-specific attributes would be organized into groups. > Those groups would then be referenced by the functions directly. Here is an > example of what that could look like: > > attrgroup #1 = { "long-calls", "cpu=cortex-a8", "thumb" } > > define void @func() noinline ssp attrgroup(#1) { > ret void > } > > Each target would know which options it can handle and how to parse them > correctly. Code generation would use the attribute group referenced by the > function to guide what code it emits. > > First Step > =========> > The first step of making a major change to attributes is to change the interface > for creating them into something that works with different designs. This will > allow the implementation to be swapped out independently of all the clients > changing. It would then expose a very simple predicate interface. Building > attributes for LLVM objects will be done with simple 'add*' methods: > > An example syntax could be: > > // Building an Attribute > > Attributes A; > A.addAlignAttr(4) > .addNoUnwindAttr() > .addStackProtectorAttr() > .addUnwindTableAttr() > .addReadNoneAttr(); > > // Querying an Attribute > > if (!A.hasStackProtector() || A.hasAlign(4)) > ... > > The Attributes class will be expanded in the future to support code generation > and target-specific options. But it won't require a massive rewrite of the > compiler to do so. > > The bit-wise operations on the Attributes class will need to be removed. This is > because the internals of the Attributes class may no longer be a bitfield. > > Summary > ======> > The Attributes class is going to change in some seriously fundamental ways, but > it will result in a much more extensible and flexible class. The changes to the > code base will be mostly mechanical in nature. The transition is easily > serialized, so any problems can be caught early on. > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
On Sep 19, 2012, at 4:09 PM, Chandler Carruth <chandlerc at google.com> wrote:> // Building an Attribute > > Attributes A; > A.addAlignAttr(4) > .addNoUnwindAttr() > .addStackProtectorAttr() > .addUnwindTableAttr() > .addReadNoneAttr(); > > Personally, I would prefer to make the Attributes class be immutable, and the building happen in a helper.Yep, that's the goal. Eventually "Attributes" will be a pointer to a uniqued (and thus, immutable) object managed by llvmcontext. Having a mutable builder is really important, because you don't want to be re-uniquing for each additional attribute crammed on in a chain. -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120919/93e8a523/attachment.html>
Hi Bill,> Problem > ======> > LTO needs a way to pass options through to different parts of the compiler. In > particular, we need to pass code generation options to the back-end. The way we > want to do this is via the LLVM Attributes class. In order to do that, we need > to overhaul the Attributes class. > > The Attributes class right now isn't very extensible. After considering several > different options, we decided it was best to extend the Attributes class to > support *all* code generation options, even target-specific ones. It already > supports some of them (like SSP), but it isn't very extensible because it is a > fixed size bitfield. The size restriction also makes supporting options with > values very difficult. As the number of options grow, we will soon have run out > of space entirely. > > Target-Specific Attributes in IR > ===============================> > I propose that the target-specific attributes would be organized into groups. > Those groups would then be referenced by the functions directly. Here is an > example of what that could look like: > > attrgroup #1 = { "long-calls", "cpu=cortex-a8", "thumb" } > > define void @func() noinline ssp attrgroup(#1) { > ret void > }does this mean you would like attributes to form a tree structure? This sounds a lot like metadata, only metadata that can't be thrown away - do you think it feasible to have this and metadata share code, eg each be derived from some common parent class? Allowing values for attributes would also be great for implementing something Chris suggested in one of his notes: getting rid of the "zext" attribute, which means that some (eg) i16 parameter is magically zext'd to an unspecified larger type like i32, and instead having the larger type i32 be the parameter type with a "zexted from i16" attribute on it. This could be done as "zexted=i16" with your system I guess. Ciao, Duncan.> > Each target would know which options it can handle and how to parse them > correctly. Code generation would use the attribute group referenced by the > function to guide what code it emits. > > First Step > =========> > The first step of making a major change to attributes is to change the interface > for creating them into something that works with different designs. This will > allow the implementation to be swapped out independently of all the clients > changing. It would then expose a very simple predicate interface. Building > attributes for LLVM objects will be done with simple 'add*' methods: > > An example syntax could be: > > // Building an Attribute > > Attributes A; > A.addAlignAttr(4) > .addNoUnwindAttr() > .addStackProtectorAttr() > .addUnwindTableAttr() > .addReadNoneAttr(); > > // Querying an Attribute > > if (!A.hasStackProtector() || A.hasAlign(4)) > ... > > The Attributes class will be expanded in the future to support code generation > and target-specific options. But it won't require a massive rewrite of the > compiler to do so. > > The bit-wise operations on the Attributes class will need to be removed. This is > because the internals of the Attributes class may no longer be a bitfield. > > Summary > ======> > The Attributes class is going to change in some seriously fundamental ways, but > it will result in a much more extensible and flexible class. The changes to the > code base will be mostly mechanical in nature. The transition is easily > serialized, so any problems can be caught early on. > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
On Sep 20, 2012, at 2:08 AM, Duncan Sands <baldrick at free.fr> wrote:> Hi Bill, > >> Problem >> ======>> >> LTO needs a way to pass options through to different parts of the compiler. In >> particular, we need to pass code generation options to the back-end. The way we >> want to do this is via the LLVM Attributes class. In order to do that, we need >> to overhaul the Attributes class. >> >> The Attributes class right now isn't very extensible. After considering several >> different options, we decided it was best to extend the Attributes class to >> support *all* code generation options, even target-specific ones. It already >> supports some of them (like SSP), but it isn't very extensible because it is a >> fixed size bitfield. The size restriction also makes supporting options with >> values very difficult. As the number of options grow, we will soon have run out >> of space entirely. >> >> Target-Specific Attributes in IR >> ===============================>> >> I propose that the target-specific attributes would be organized into groups. >> Those groups would then be referenced by the functions directly. Here is an >> example of what that could look like: >> >> attrgroup #1 = { "long-calls", "cpu=cortex-a8", "thumb" } >> >> define void @func() noinline ssp attrgroup(#1) { >> ret void >> } > > does this mean you would like attributes to form a tree structure? This sounds > a lot like metadata, only metadata that can't be thrown away - do you think it > feasible to have this and metadata share code, eg each be derived from some > common parent class? >Not really. I want this to be separate from metadata. I don't expect that attribute groups will reference each other. And I want to keep the attributes that are stored as light weight as possible. However, I haven't come up with the complete proposal just yet.> Allowing values for attributes would also be great for implementing something > Chris suggested in one of his notes: getting rid of the "zext" attribute, which > means that some (eg) i16 parameter is magically zext'd to an unspecified larger > type like i32, and instead having the larger type i32 be the parameter type > with a "zexted from i16" attribute on it. This could be done as "zexted=i16" > with your system I guess. >Yeah, something like that. I'll look at Chris's note and see if I can incorporate it into the final design. :) -bw
> attrgroup #1 = { "long-calls", "cpu=cortex-a8", "thumb" } > > define void @func() noinline ssp attrgroup(#1) { > ret void > } >I like the general idea. Just one clarification: In the above example, are the attributes taken from a list specified in the language ref (like current attributes) or can they be arbitrary "strings" (like metadata)? Cheers, Rafael
Hi Rafael, Sorry, I forgot to respond to this. They can be arbitrary strings that are known only to the specific back-end. It may be beneficial to define them inside of the LangRef document though. -bw On Oct 4, 2012, at 7:47 PM, Rafael EspĂndola <rafael.espindola at gmail.com> wrote:>> attrgroup #1 = { "long-calls", "cpu=cortex-a8", "thumb" } >> >> define void @func() noinline ssp attrgroup(#1) { >> ret void >> } >> > > I like the general idea. Just one clarification: In the above example, > are the attributes taken from a list specified in the language ref > (like current attributes) or can they be arbitrary "strings" (like > metadata)? > > Cheers, > Rafael