[RFC] Passing Options to Different Parts of the Compiler Using Attributes

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

[RFC] Passing Options to Different Parts of the Compiler Using Attributes

Bill Wendling-2
Hi!

This is a proposal to expand the Attributes class to support many different options that will be accessible by all parts of the compiler. Please read and give any feedback you may have.

Thanks!
-bw

             Passing Options to Different Parts of the Compiler

Problem
=======

There is a growing need to pass information from the front-end to different parts
of the compiler, especially code generation. LTO, for instance, needs to encode
within the .o files the options it was compiled with. Otherwise, the code generator
could generate code that is unexpected -- e.g., generating SSE instructions when
the programmer used the `-mno-sse' flag to compile that module. 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.


Proposal
========

We will expand the Attriutes class to support all of the attributes that the
compiler may care about. Anything that affects code transformations and code
generation will be specified inside of the Attributes class. This allows for a
cleaner interface for the front-ends, since they won't have to fill in a
target-specific structure to pass along this information. It also allows for LTO
to merge files that were compiled with different options. It can determine if
it's possible to inline one function into another based upon the options with
which it was compiled. And finally, it's necessary for correctness. LTO
currently ignores the command line options with which a file was compiled.

There are two classes of attributes: those that are target-independent (e.g.,
'noinline'), and those that are target-dependent (e.g., 'thumb' and
'cpu=cortex-a8'). The target-dependent options are stored as strings inside of
the Attributes class. The target's back-end is responsible for interpreting
target-dependent attributes.

Attributes should be documented in the language reference document.

IR Changes
----------

The attributes will be specified within the IR. This allows us to generate code
that the user wants. This also has the advantage that it will no longer be
necessary to specify all of the command line options when compiling the bit code
(via 'llc' or 'clang'). E.g., '-mcpu=cortex-a8' will be an attribute and won't
be required on llc's command line. However, explicit flags (like `-mcpu') on the
llc command line will override flags specified in the module.

The core of this proposal is the idea of an "attribute group". As the name
implies, it's a group of attributes that are then referenced by objects within
the IR. An attribute group is a module-level object. The BNF of the syntax is:

 attribute_group := attrgroup <attrgroup_id> = { <attribute_list> }
 attrgroup_id    := #<number>
 attribute_list  := <attribute> (, <attribute>)*
 attribute       := <name> (= <value>)?

To use an attribute group, an object references the attribute group's ID:

 attribute_group_ref := attrgroup(<attrgroup_id>)

This is an example of an attribute group for a function that should always be
inlined, has stack alignment of 4, and doesn't unwind:

 attrgroup #1 = { alwaysinline, nounwind, alignstack=4 }

 void @foo() attrgroup(#1) { ret void }

An object may refer to more than one attribute group. In that situation, the
attributes are merged.

Attribute groups are important for keeping `.ll' files readable, because a lot
of functions will use the same attributes. In the degenerative case of a `.ll'
file that corresponds to a single `.c' file, the single `attrgroup' will capture
the command line flags used to build that file.

Target-Dependent Attributes in IR
---------------------------------

The front-end is responsible for knowing which target-dependent options are
interesting to the target. Target-dependent attributes are specified as strings,
which are understood by the target's back-end. E.g.:

 attrgroup #0 = { "long-calls", "cpu=cortex-a8", "thumb" }

 define void @func() attrgroup(#0) { ret void }

The ARM back-end is the only target that knows about these options and what to
do with them.

Some of the `cl::opt' options in the backend could move into attribute groups.
This will clean up the compiler.

Updating IR
-----------

The current attributes that are specified on functions will be moved into an
attribute group. The LLVM assembly reader will still honor those but when the
assembly file is emitted, those attributes will be output as an attribute group
by the assembly writer. As usual, LLVM 3.3 will be able to read and auto-upgrade
previous bitcode and `.ll' files.

Querying
--------

The attributes are attached to the function. It's therefore trivial to access
the attributes within the middle- and the back-ends. Here's an example of how
attributes are queried:

 Attributes &A = F.getAttributes();

 // Target-independent attribute query.
 A.hasAttribute(Attributes::NoInline);

 // Target-dependent attribute query.
 A.hasAttribute("no-sse");

 // Retrieving value of a target-independent attribute.
 int Alignment = A.getIntValue(Attributes::Alignment);

 // Retrieving value of a target-dependent attribute.
 StringRef CPU = A.getStringValue("cpu");


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Justin Holewinski-2
Couple of quick questions:

First, what are the valid types for <value>?  Are they always strings which the target must interpret, or will numeric literals and booleans also be supported?  Also, in the proposal, attributes are sometimes quoted and sometimes they are not.  I know this is nit-picking, but what is the preferred syntax?

Second, would it make sense to fold the calling convention into this set of attributes?  For correctness, attributes cannot be stripped from the IR anyway (as I understand it).  The existing calling convention API could be implemented using the new attributes.  The old way of specifying calling conventions (before the function name instead of after) would need to be supported until the next break in IR compatibility, but this doesn't seem like a big issue.  Perhaps throw an error if both are present and conflict.  This may also mean the calling convention specifier at the call site needs to go away, but is this really needed?

On Tue, Nov 13, 2012 at 1:20 AM, Bill Wendling <[hidden email]> wrote:
Hi!

This is a proposal to expand the Attributes class to support many different options that will be accessible by all parts of the compiler. Please read and give any feedback you may have.

Thanks!
-bw

             Passing Options to Different Parts of the Compiler

Problem
=======

There is a growing need to pass information from the front-end to different parts
of the compiler, especially code generation. LTO, for instance, needs to encode
within the .o files the options it was compiled with. Otherwise, the code generator
could generate code that is unexpected -- e.g., generating SSE instructions when
the programmer used the `-mno-sse' flag to compile that module. 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.


Proposal
========

We will expand the Attriutes class to support all of the attributes that the
compiler may care about. Anything that affects code transformations and code
generation will be specified inside of the Attributes class. This allows for a
cleaner interface for the front-ends, since they won't have to fill in a
target-specific structure to pass along this information. It also allows for LTO
to merge files that were compiled with different options. It can determine if
it's possible to inline one function into another based upon the options with
which it was compiled. And finally, it's necessary for correctness. LTO
currently ignores the command line options with which a file was compiled.

There are two classes of attributes: those that are target-independent (e.g.,
'noinline'), and those that are target-dependent (e.g., 'thumb' and
'cpu=cortex-a8'). The target-dependent options are stored as strings inside of
the Attributes class. The target's back-end is responsible for interpreting
target-dependent attributes.

Attributes should be documented in the language reference document.

IR Changes
----------

The attributes will be specified within the IR. This allows us to generate code
that the user wants. This also has the advantage that it will no longer be
necessary to specify all of the command line options when compiling the bit code
(via 'llc' or 'clang'). E.g., '-mcpu=cortex-a8' will be an attribute and won't
be required on llc's command line. However, explicit flags (like `-mcpu') on the
llc command line will override flags specified in the module.

The core of this proposal is the idea of an "attribute group". As the name
implies, it's a group of attributes that are then referenced by objects within
the IR. An attribute group is a module-level object. The BNF of the syntax is:

 attribute_group := attrgroup <attrgroup_id> = { <attribute_list> }
 attrgroup_id    := #<number>
 attribute_list  := <attribute> (, <attribute>)*
 attribute       := <name> (= <value>)?

To use an attribute group, an object references the attribute group's ID:

 attribute_group_ref := attrgroup(<attrgroup_id>)

This is an example of an attribute group for a function that should always be
inlined, has stack alignment of 4, and doesn't unwind:

 attrgroup #1 = { alwaysinline, nounwind, alignstack=4 }

 void @foo() attrgroup(#1) { ret void }

An object may refer to more than one attribute group. In that situation, the
attributes are merged.

Attribute groups are important for keeping `.ll' files readable, because a lot
of functions will use the same attributes. In the degenerative case of a `.ll'
file that corresponds to a single `.c' file, the single `attrgroup' will capture
the command line flags used to build that file.

Target-Dependent Attributes in IR
---------------------------------

The front-end is responsible for knowing which target-dependent options are
interesting to the target. Target-dependent attributes are specified as strings,
which are understood by the target's back-end. E.g.:

 attrgroup #0 = { "long-calls", "cpu=cortex-a8", "thumb" }

 define void @func() attrgroup(#0) { ret void }

The ARM back-end is the only target that knows about these options and what to
do with them.

Some of the `cl::opt' options in the backend could move into attribute groups.
This will clean up the compiler.

Updating IR
-----------

The current attributes that are specified on functions will be moved into an
attribute group. The LLVM assembly reader will still honor those but when the
assembly file is emitted, those attributes will be output as an attribute group
by the assembly writer. As usual, LLVM 3.3 will be able to read and auto-upgrade
previous bitcode and `.ll' files.

Querying
--------

The attributes are attached to the function. It's therefore trivial to access
the attributes within the middle- and the back-ends. Here's an example of how
attributes are queried:

 Attributes &A = F.getAttributes();

 // Target-independent attribute query.
 A.hasAttribute(Attributes::NoInline);

 // Target-dependent attribute query.
 A.hasAttribute("no-sse");

 // Retrieving value of a target-independent attribute.
 int Alignment = A.getIntValue(Attributes::Alignment);

 // Retrieving value of a target-dependent attribute.
 StringRef CPU = A.getStringValue("cpu");


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev



--

Thanks,

Justin Holewinski


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Chris Lattner-2

On Nov 13, 2012, at 7:43 AM, Justin Holewinski <[hidden email]> wrote:

> Couple of quick questions:
>
> First, what are the valid types for <value>?  Are they always strings which the target must interpret, or will numeric literals and booleans also be supported?  Also, in the proposal, attributes are sometimes quoted and sometimes they are not.  I know this is nit-picking, but what is the preferred syntax?
>
> Second, would it make sense to fold the calling convention into this set of attributes?  For correctness, attributes cannot be stripped from the IR anyway (as I understand it).  The existing calling convention API could be implemented using the new attributes.  The old way of specifying calling conventions (before the function name instead of after) would need to be supported until the next break in IR compatibility, but this doesn't seem like a big issue.  Perhaps throw an error if both are present and conflict.  This may also mean the calling convention specifier at the call site needs to go away, but is this really needed?

That's a very interesting idea, and might be a great extension after the basic pieces Bill is proposing goes in and settles!

-Chris

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Bill Wendling-2
In reply to this post by Justin Holewinski-2
On Nov 13, 2012, at 7:43 AM, Justin Holewinski <[hidden email]> wrote:

> Couple of quick questions:
>
> First, what are the valid types for <value>?  Are they always strings which the target must interpret, or will numeric literals and booleans also be supported?

We should be able to support all types of values: strings, integers, boolean, etc.

> Also, in the proposal, attributes are sometimes quoted and sometimes they are not.  I know this is nit-picking, but what is the preferred syntax?

I made a distinction (perhaps artificial) between target independent and target dependent attributes. The independent ones need no quotes while the dependent ones do. This reflects how they are stored and accessed via the Attributes class. I said "perhaps artificial" because there's no real reason why the target dependent options cannot be specified via the attributes enum in the Attributes class. Except, perhaps, to avoid placing target dependent cruft in a general class. :) I'm open to arguments against the original design.

> Second, would it make sense to fold the calling convention into this set of attributes?  For correctness, attributes cannot be stripped from the IR anyway (as I understand it).  The existing calling convention API could be implemented using the new attributes.  The old way of specifying calling conventions (before the function name instead of after) would need to be supported until the next break in IR compatibility, but this doesn't seem like a big issue.  Perhaps throw an error if both are present and conflict.  This may also mean the calling convention specifier at the call site needs to go away, but is this really needed?
>
As Chris mentioned, this sounds like a good idea. We can explore that after the initial implementation. :)

-bw


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Eric Christopher
In reply to this post by Bill Wendling-2


Querying
--------

The attributes are attached to the function. It's therefore trivial to access
the attributes within the middle- and the back-ends. Here's an example of how
attributes are queried:

Just had a thought, what about compile options that change alignment/layout/section placement of globals etc? For example the -G <num> option in gcc that the mips guys will want to support some day (there are probably better options but this was the first the came to mind).

"-G num
Put definitions of externally-visible data in a small data section if that data is no bigger than num bytes. GCC can then access the data more efficiently; see -mgpopt for details."

So we'll probably want to put attributes on all top level entities and not just functions.

-eric

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Meador Inge-2
In reply to this post by Bill Wendling-2

On Nov 13, 2012, at 12:20 AM, Bill Wendling wrote:

> IR Changes
> ----------
>
> The attributes will be specified within the IR. This allows us to generate code
> that the user wants. This also has the advantage that it will no longer be
> necessary to specify all of the command line options when compiling the bit code
> (via 'llc' or 'clang'). E.g., '-mcpu=cortex-a8' will be an attribute and won't
> be required on llc's command line. However, explicit flags (like `-mcpu') on the
> llc command line will override flags specified in the module.
>
> The core of this proposal is the idea of an "attribute group". As the name
> implies, it's a group of attributes that are then referenced by objects within
> the IR. An attribute group is a module-level object. The BNF of the syntax is:
>
> attribute_group := attrgroup <attrgroup_id> = { <attribute_list> }
> attrgroup_id    := #<number>
> attribute_list  := <attribute> (, <attribute>)*
> attribute       := <name> (= <value>)?
>
> To use an attribute group, an object references the attribute group's ID:
>
> attribute_group_ref := attrgroup(<attrgroup_id>)
>
> This is an example of an attribute group for a function that should always be
> inlined, has stack alignment of 4, and doesn't unwind:
>
> attrgroup #1 = { alwaysinline, nounwind, alignstack=4 }
>
> void @foo() attrgroup(#1) { ret void }
>
> An object may refer to more than one attribute group. In that situation, the
> attributes are merged.
>
> Attribute groups are important for keeping `.ll' files readable, because a lot
> of functions will use the same attributes. In the degenerative case of a `.ll'
> file that corresponds to a single `.c' file, the single `attrgroup' will capture
> the command line flags used to build that file.

A few comments on the new syntax:

   1. I think most folks will understand what 'attrgroup' means, but it is a little cryptic.
      How about just 'attributes'?  The following reads easier to my eyes:

         attributes #1 = { alwaysinline, nounwind, alignstack=4 }
         void @foo() attributes(#1) { ret void }

   2. Are group references allowed in all attribute contexts (parameter, return value, function)?
      I think the answer should be yes.  Also, it might be worth considering using the same attribute
      list syntax in the current context and the new attribute group definition (i.e. comma-separated
      v.s. space-separated).  This way we have a consistent syntax for groups of attributes and the
      main addition this proposal adds is to give a name to those attributes for later reference.
     
   3. Can attribute groups and single attributes be inter-mixed?
      For example:
     
         void @foo attrgroup(#1) alwaysinline attrgroup(#2) nounwind

   4. Do we really want the attribute references limited to a number?  Code will be more readable
      if you can use actual names that indicate the intent.  For example:

         attrgroup #compile_options = { … }
         void @foo attrgroup(#compile_options)

   5. Can attributes be nested?  For example:

         attrgroup #1 = { foo, bar }
         attrgroup #2 = { #1, baz }

      Might be nice.

   6. Do we really need to specify the attrgroup keyword twice? (Once in the group definition and once in the use)
      ISTM, that the hash-mark is enough to announce a group reference in the use.  For example:

         void @foo #1 alwaysinline #2 no unwind

In other words, I think something like the following might be nicer:

attribute_group := attributes <attrgroup_id> = { <attribute_list> }
attrgroup_id    := #<id>
attribute_list  := <attribute> ( <attribute>)*
attribute       := <name> (= <value>)?
                 | <attribuge_id>



function_def    := <attribute_list> <result_type> @<id> ([argument_list]) <attribute_list>


> Target-Dependent Attributes in IR
> ---------------------------------
>
> The front-end is responsible for knowing which target-dependent options are
> interesting to the target. Target-dependent attributes are specified as strings,
> which are understood by the target's back-end. E.g.:
>
> attrgroup #0 = { "long-calls", "cpu=cortex-a8", "thumb" }
>
> define void @func() attrgroup(#0) { ret void }
>
> The ARM back-end is the only target that knows about these options and what to
> do with them.
>
> Some of the `cl::opt' options in the backend could move into attribute groups.
> This will clean up the compiler.
>

Isn't calling these "target-dependent" a little artificial?  Surely there are many uses
for string attributes one of which is for target-specific data.  I think organizing the
proposal to add these new arbitrary string attributes and using the target-specific bits
as examples will be clearer.

> Updating IR
> -----------
>
> The current attributes that are specified on functions will be moved into an
> attribute group. The LLVM assembly reader will still honor those but when the
> assembly file is emitted, those attributes will be output as an attribute group
> by the assembly writer. As usual, LLVM 3.3 will be able to read and auto-upgrade
> previous bitcode and `.ll' files.
>
> Querying
> --------
>
> The attributes are attached to the function. It's therefore trivial to access
> the attributes within the middle- and the back-ends. Here's an example of how
> attributes are queried:
>
> Attributes &A = F.getAttributes();
>
> // Target-independent attribute query.
> A.hasAttribute(Attributes::NoInline);
>
> // Target-dependent attribute query.
> A.hasAttribute("no-sse");
>
> // Retrieving value of a target-independent attribute.
> int Alignment = A.getIntValue(Attributes::Alignment);
>
> // Retrieving value of a target-dependent attribute.
> StringRef CPU = A.getStringValue("cpu");

Maybe some set attribute examples too?


Overall, I think this is a nice addition!

--
Meador Inge
CodeSourcery / Mentor Embedded
http://www.mentor.com/embedded-software


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Richard Smith-33
On Tue, Nov 20, 2012 at 11:03 AM, Meador Inge <[hidden email]> wrote:

>
> On Nov 13, 2012, at 12:20 AM, Bill Wendling wrote:
>
>> IR Changes
>> ----------
>>
>> The attributes will be specified within the IR. This allows us to generate code
>> that the user wants. This also has the advantage that it will no longer be
>> necessary to specify all of the command line options when compiling the bit code
>> (via 'llc' or 'clang'). E.g., '-mcpu=cortex-a8' will be an attribute and won't
>> be required on llc's command line. However, explicit flags (like `-mcpu') on the
>> llc command line will override flags specified in the module.
>>
>> The core of this proposal is the idea of an "attribute group". As the name
>> implies, it's a group of attributes that are then referenced by objects within
>> the IR. An attribute group is a module-level object. The BNF of the syntax is:
>>
>> attribute_group := attrgroup <attrgroup_id> = { <attribute_list> }
>> attrgroup_id    := #<number>
>> attribute_list  := <attribute> (, <attribute>)*
>> attribute       := <name> (= <value>)?
>>
>> To use an attribute group, an object references the attribute group's ID:
>>
>> attribute_group_ref := attrgroup(<attrgroup_id>)
>>
>> This is an example of an attribute group for a function that should always be
>> inlined, has stack alignment of 4, and doesn't unwind:
>>
>> attrgroup #1 = { alwaysinline, nounwind, alignstack=4 }
>>
>> void @foo() attrgroup(#1) { ret void }
>>
>> An object may refer to more than one attribute group. In that situation, the
>> attributes are merged.
>>
>> Attribute groups are important for keeping `.ll' files readable, because a lot
>> of functions will use the same attributes. In the degenerative case of a `.ll'
>> file that corresponds to a single `.c' file, the single `attrgroup' will capture
>> the command line flags used to build that file.
>
> A few comments on the new syntax:
>
>    1. I think most folks will understand what 'attrgroup' means, but it is a little cryptic.
>       How about just 'attributes'?  The following reads easier to my eyes:
>
>          attributes #1 = { alwaysinline, nounwind, alignstack=4 }
>          void @foo() attributes(#1) { ret void }
>
>    2. Are group references allowed in all attribute contexts (parameter, return value, function)?
>       I think the answer should be yes.  Also, it might be worth considering using the same attribute
>       list syntax in the current context and the new attribute group definition (i.e. comma-separated
>       v.s. space-separated).  This way we have a consistent syntax for groups of attributes and the
>       main addition this proposal adds is to give a name to those attributes for later reference.
>
>    3. Can attribute groups and single attributes be inter-mixed?
>       For example:
>
>          void @foo attrgroup(#1) alwaysinline attrgroup(#2) nounwind
>
>    4. Do we really want the attribute references limited to a number?  Code will be more readable
>       if you can use actual names that indicate the intent.  For example:
>
>          attrgroup #compile_options = { … }
>          void @foo attrgroup(#compile_options)
>
>    5. Can attributes be nested?  For example:
>
>          attrgroup #1 = { foo, bar }
>          attrgroup #2 = { #1, baz }
>
>       Might be nice.
>
>    6. Do we really need to specify the attrgroup keyword twice? (Once in the group definition and once in the use)
>       ISTM, that the hash-mark is enough to announce a group reference in the use.  For example:
>
>          void @foo #1 alwaysinline #2 no unwind
>
> In other words, I think something like the following might be nicer:
>
> attribute_group := attributes <attrgroup_id> = { <attribute_list> }

Well, if we're picking paints for this bikeshed, are the braces here
necessary? We don't have braces for the other places we have
<attribute_list>s.

attributes #attrs = nounwind alwaysinline noreturn
i8 @foo() #attrs

... as a synonym for ...

i8 @foo() nounwind alwaysinline noreturn

... seems quite clean to me.

> attrgroup_id    := #<id>
> attribute_list  := <attribute> ( <attribute>)*
> attribute       := <name> (= <value>)?
>                  | <attribuge_id>
>
> …
>
> function_def    := <attribute_list> <result_type> @<id> ([argument_list]) <attribute_list>
>
>
>> Target-Dependent Attributes in IR
>> ---------------------------------
>>
>> The front-end is responsible for knowing which target-dependent options are
>> interesting to the target. Target-dependent attributes are specified as strings,
>> which are understood by the target's back-end. E.g.:
>>
>> attrgroup #0 = { "long-calls", "cpu=cortex-a8", "thumb" }
>>
>> define void @func() attrgroup(#0) { ret void }
>>
>> The ARM back-end is the only target that knows about these options and what to
>> do with them.
>>
>> Some of the `cl::opt' options in the backend could move into attribute groups.
>> This will clean up the compiler.
>>
>
> Isn't calling these "target-dependent" a little artificial?  Surely there are many uses
> for string attributes one of which is for target-specific data.  I think organizing the
> proposal to add these new arbitrary string attributes and using the target-specific bits
> as examples will be clearer.
>
>> Updating IR
>> -----------
>>
>> The current attributes that are specified on functions will be moved into an
>> attribute group. The LLVM assembly reader will still honor those but when the
>> assembly file is emitted, those attributes will be output as an attribute group
>> by the assembly writer. As usual, LLVM 3.3 will be able to read and auto-upgrade
>> previous bitcode and `.ll' files.
>>
>> Querying
>> --------
>>
>> The attributes are attached to the function. It's therefore trivial to access
>> the attributes within the middle- and the back-ends. Here's an example of how
>> attributes are queried:
>>
>> Attributes &A = F.getAttributes();
>>
>> // Target-independent attribute query.
>> A.hasAttribute(Attributes::NoInline);
>>
>> // Target-dependent attribute query.
>> A.hasAttribute("no-sse");
>>
>> // Retrieving value of a target-independent attribute.
>> int Alignment = A.getIntValue(Attributes::Alignment);
>>
>> // Retrieving value of a target-dependent attribute.
>> StringRef CPU = A.getStringValue("cpu");
>
> Maybe some set attribute examples too?
>
>
> Overall, I think this is a nice addition!
>
> --
> Meador Inge
> CodeSourcery / Mentor Embedded
> http://www.mentor.com/embedded-software
>
>
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Chris Lattner-2
In reply to this post by Eric Christopher

On Nov 19, 2012, at 1:49 PM, Eric Christopher <[hidden email]> wrote:



Querying
--------

The attributes are attached to the function. It's therefore trivial to access
the attributes within the middle- and the back-ends. Here's an example of how
attributes are queried:

Just had a thought, what about compile options that change alignment/layout/section placement of globals etc? For example the -G <num> option in gcc that the mips guys will want to support some day (there are probably better options but this was the first the came to mind).

All of those can be directly represented in LLVM IR today, but if there were a good reason to, I can see extending attributes to work on globals someday.

-Chris


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Justin Holewinski-2
On Thu, Nov 22, 2012 at 11:24 AM, Chris Lattner <[hidden email]> wrote:

On Nov 19, 2012, at 1:49 PM, Eric Christopher <[hidden email]> wrote:



Querying
--------

The attributes are attached to the function. It's therefore trivial to access
the attributes within the middle- and the back-ends. Here's an example of how
attributes are queried:

Just had a thought, what about compile options that change alignment/layout/section placement of globals etc? For example the -G <num> option in gcc that the mips guys will want to support some day (there are probably better options but this was the first the came to mind).

All of those can be directly represented in LLVM IR today, but if there were a good reason to, I can see extending attributes to work on globals someday.

I'm a bit worried about this creating an arbitrary line between annotations that are defined as attributes and annotations that are first-class keywords in the IR language.  It may become a source of confusion for people.  If attributes are only applied to functions, the obvious questions for users is "why do I need to do things differently for functions vs. globals?"  I'm not saying it's a big issue, but it does seem a bit inconsistent.  If we're implementing these attributes anyway, why not unify the handling of annotations on functions and global variables?

 

-Chris


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev




--

Thanks,

Justin Holewinski


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Chris Lattner-2

On Nov 22, 2012, at 8:53 AM, Justin Holewinski <[hidden email]> wrote:

On Thu, Nov 22, 2012 at 11:24 AM, Chris Lattner <[hidden email]> wrote:

On Nov 19, 2012, at 1:49 PM, Eric Christopher <[hidden email]> wrote:



Querying
--------

The attributes are attached to the function. It's therefore trivial to access
the attributes within the middle- and the back-ends. Here's an example of how
attributes are queried:

Just had a thought, what about compile options that change alignment/layout/section placement of globals etc? For example the -G <num> option in gcc that the mips guys will want to support some day (there are probably better options but this was the first the came to mind).

All of those can be directly represented in LLVM IR today, but if there were a good reason to, I can see extending attributes to work on globals someday.

I'm a bit worried about this creating an arbitrary line between annotations that are defined as attributes and annotations that are first-class keywords in the IR language.  It may become a source of confusion for people.  If attributes are only applied to functions, the obvious questions for users is "why do I need to do things differently for functions vs. globals?"  I'm not saying it's a big issue, but it does seem a bit inconsistent.  If we're implementing these attributes anyway, why not unify the handling of annotations on functions and global variables?

I'm not saying I'm opposed to it - I'm saying that it is a completely different topic than what Bill is proposing.

-Chris


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Eric Christopher
In reply to this post by Chris Lattner-2

Querying
--------

The attributes are attached to the function. It's therefore trivial to access
the attributes within the middle- and the back-ends. Here's an example of how
attributes are queried:

Just had a thought, what about compile options that change alignment/layout/section placement of globals etc? For example the -G <num> option in gcc that the mips guys will want to support some day (there are probably better options but this was the first the came to mind).

All of those can be directly represented in LLVM IR today, but if there were a good reason to, I can see extending attributes to work on globals someday.


Right, I couldn't think of anything that wasn't handled already, but I wasn't sure if we wanted this to be a single way of encapsulating information for globals. No opinion either way :)

-eric
 

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Bill Wendling-2
In reply to this post by Eric Christopher
On Nov 19, 2012, at 1:49 PM, Eric Christopher <[hidden email]> wrote:

> Querying
> --------
>
> The attributes are attached to the function. It's therefore trivial to access
> the attributes within the middle- and the back-ends. Here's an example of how
> attributes are queried:
>
> Just had a thought, what about compile options that change alignment/layout/section placement of globals etc? For example the -G <num> option in gcc that the mips guys will want to support some day (there are probably better options but this was the first the came to mind).
>
> "-G num
> Put definitions of externally-visible data in a small data section if that data is no bigger than num bytes. GCC can then access the data more efficiently; see -mgpopt for details."
>
> So we'll probably want to put attributes on all top level entities and not just functions.
>
That's not a bad idea. It may be better to have that as a future expansion, though. Just to get the more incremental development done... But on the whole, I don't see anything wrong with it though.

-bw


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Bill Wendling-2
In reply to this post by Meador Inge-2
On Nov 20, 2012, at 11:03 AM, Meador Inge <[hidden email]> wrote:

> On Nov 13, 2012, at 12:20 AM, Bill Wendling wrote:
>
>> IR Changes
>> ----------
>>
>> The attributes will be specified within the IR. This allows us to generate code
>> that the user wants. This also has the advantage that it will no longer be
>> necessary to specify all of the command line options when compiling the bit code
>> (via 'llc' or 'clang'). E.g., '-mcpu=cortex-a8' will be an attribute and won't
>> be required on llc's command line. However, explicit flags (like `-mcpu') on the
>> llc command line will override flags specified in the module.
>>
>> The core of this proposal is the idea of an "attribute group". As the name
>> implies, it's a group of attributes that are then referenced by objects within
>> the IR. An attribute group is a module-level object. The BNF of the syntax is:
>>
>> attribute_group := attrgroup <attrgroup_id> = { <attribute_list> }
>> attrgroup_id    := #<number>
>> attribute_list  := <attribute> (, <attribute>)*
>> attribute       := <name> (= <value>)?
>>
>> To use an attribute group, an object references the attribute group's ID:
>>
>> attribute_group_ref := attrgroup(<attrgroup_id>)
>>
>> This is an example of an attribute group for a function that should always be
>> inlined, has stack alignment of 4, and doesn't unwind:
>>
>> attrgroup #1 = { alwaysinline, nounwind, alignstack=4 }
>>
>> void @foo() attrgroup(#1) { ret void }
>>
>> An object may refer to more than one attribute group. In that situation, the
>> attributes are merged.
>>
>> Attribute groups are important for keeping `.ll' files readable, because a lot
>> of functions will use the same attributes. In the degenerative case of a `.ll'
>> file that corresponds to a single `.c' file, the single `attrgroup' will capture
>> the command line flags used to build that file.
>
> A few comments on the new syntax:
>
>   1. I think most folks will understand what 'attrgroup' means, but it is a little cryptic.
>      How about just 'attributes'?  The following reads easier to my eyes:
>
>         attributes #1 = { alwaysinline, nounwind, alignstack=4 }
>         void @foo() attributes(#1) { ret void }
>
I don't have a very strong opinion on this.

>   2. Are group references allowed in all attribute contexts (parameter, return value, function)?
>      I think the answer should be yes.

It would seem a natural expansion of the attribute groups concept. But I want to make these changes incrementally. So at the beginning this won't happen.

> Also, it might be worth considering using the same attribute
>      list syntax in the current context and the new attribute group definition (i.e. comma-separated
>      v.s. space-separated).  This way we have a consistent syntax for groups of attributes and the
>      main addition this proposal adds is to give a name to those attributes for later reference.
>
I also prefer comma separated lists of things. But this could cause some confusion if we expand the concept to parameter attributes. But see below for a potential alternative syntax for the attribute groups.

>   3. Can attribute groups and single attributes be inter-mixed?
>      For example:
>
>         void @foo attrgroup(#1) alwaysinline attrgroup(#2) nounwind
>
This will be necessary for backwards compatibility. However, running this through this sequence:

        $ llvm-as < foo.ll | llvm-dis

would produce:

        attrgroup #1 = { ... }
        attrgroup #2 = { ... }
        attrgroup #3 = { alwaysinline, nounwind }

        void @foo() attrgroup(#1) attrgroup(#2) attrgroup(#3)

This is because of how the attributes will be represented internally to LLVM. Let me know if you have strong objections to this.

>   4. Do we really want the attribute references limited to a number?  Code will be more readable
>      if you can use actual names that indicate the intent.  For example:
>
>         attrgroup #compile_options = { … }
>         void @foo attrgroup(#compile_options)
>
The problem with this is it limits the number of attribute groups to a specific set -- compile options, non-compile options, etc.. There could be many different attribute groups involved, especially during LTO. I realize that the names will be uniqued. But that just adds a number to the existing name. I also want to avoid partitioning of the attributes into arbitrary groups -- i.e., groups with specific names which imply their usage or type.

>   5. Can attributes be nested?  For example:
>
>         attrgroup #1 = { foo, bar }
>         attrgroup #2 = { #1, baz }
>
>      Might be nice.
>
I'm not a big fan of this idea. This could open it up to circular attribute groups:

        attrgroup #1 = { foo, #2 }
        attrgroup #2 = { #1, bar }

which I'm opposed to on moral groups. ;-) A less compelling (but IMHO valid) argument is that it makes the internal representation of attributes that much more complex.

>   6. Do we really need to specify the attrgroup keyword twice? (Once in the group definition and once in the use)
>      ISTM, that the hash-mark is enough to announce a group reference in the use.  For example:
>
>         void @foo #1 alwaysinline #2 no unwind
>
Looking at my example above, my syntax can get a bit wordy. How about this alternative representation?

        define void @foo() attrgroup(#1, #2, #3) { ret void }

I don't have a strong opinion though. You're correct that the hash-number combo unambiguously defines an attribute group's use. If others are amenable to this, I can drop the keyword here.

> In other words, I think something like the following might be nicer:
>
> attribute_group := attributes <attrgroup_id> = { <attribute_list> }
> attrgroup_id    := #<id>
> attribute_list  := <attribute> ( <attribute>)*
> attribute       := <name> (= <value>)?
>                 | <attribuge_id>
>
> …
>
> function_def    := <attribute_list> <result_type> @<id> ([argument_list]) <attribute_list>
>
So something like this (no references inside of the 'attributes' statement allowed, cf. above)?

        attributes #1 = { noinline, alignstack=4 }
        attributes #2 = { "no-sse" }

        define void @foo() #1 #2 { ret void }

This seems reasonable to me.

>> Target-Dependent Attributes in IR
>> ---------------------------------
>>
>> The front-end is responsible for knowing which target-dependent options are
>> interesting to the target. Target-dependent attributes are specified as strings,
>> which are understood by the target's back-end. E.g.:
>>
>> attrgroup #0 = { "long-calls", "cpu=cortex-a8", "thumb" }
>>
>> define void @func() attrgroup(#0) { ret void }
>>
>> The ARM back-end is the only target that knows about these options and what to
>> do with them.
>>
>> Some of the `cl::opt' options in the backend could move into attribute groups.
>> This will clean up the compiler.
>>
>
> Isn't calling these "target-dependent" a little artificial?  Surely there are many uses
> for string attributes one of which is for target-specific data.  I think organizing the
> proposal to add these new arbitrary string attributes and using the target-specific bits
> as examples will be clearer.
>
It's a bit artificial. I basically want to make a small distinction here where anything not target-specific will be defined inside of LangRef.html. So anything that could be used by all targets should be defined there.

>> Updating IR
>> -----------
>>
>> The current attributes that are specified on functions will be moved into an
>> attribute group. The LLVM assembly reader will still honor those but when the
>> assembly file is emitted, those attributes will be output as an attribute group
>> by the assembly writer. As usual, LLVM 3.3 will be able to read and auto-upgrade
>> previous bitcode and `.ll' files.
>>
>> Querying
>> --------
>>
>> The attributes are attached to the function. It's therefore trivial to access
>> the attributes within the middle- and the back-ends. Here's an example of how
>> attributes are queried:
>>
>> Attributes &A = F.getAttributes();
>>
>> // Target-independent attribute query.
>> A.hasAttribute(Attributes::NoInline);
>>
>> // Target-dependent attribute query.
>> A.hasAttribute("no-sse");
>>
>> // Retrieving value of a target-independent attribute.
>> int Alignment = A.getIntValue(Attributes::Alignment);
>>
>> // Retrieving value of a target-dependent attribute.
>> StringRef CPU = A.getStringValue("cpu");
>
> Maybe some set attribute examples too?
>
That would be done through the current AttrBuilder class:

        AttrBuilder B;

        // Add a target-independent attribute.
        B.addAttribute(Attributes::NoInline);

        // Add a target-dependent attribute.
        B.addAttribute("no-sse");

        // Create the attribute object.
        Attributes A = Attributes::get(Context, B);

> Overall, I think this is a nice addition!
>
Thanks!

-bw



_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Bill Wendling-2
In reply to this post by Richard Smith-33

On Nov 20, 2012, at 4:31 PM, Richard Smith <[hidden email]> wrote:

> On Tue, Nov 20, 2012 at 11:03 AM, Meador Inge <[hidden email]> wrote:
>>
>> On Nov 13, 2012, at 12:20 AM, Bill Wendling wrote:
>>
>>> IR Changes
>>> ----------
>>>
>>> The attributes will be specified within the IR. This allows us to generate code
>>> that the user wants. This also has the advantage that it will no longer be
>>> necessary to specify all of the command line options when compiling the bit code
>>> (via 'llc' or 'clang'). E.g., '-mcpu=cortex-a8' will be an attribute and won't
>>> be required on llc's command line. However, explicit flags (like `-mcpu') on the
>>> llc command line will override flags specified in the module.
>>>
>>> The core of this proposal is the idea of an "attribute group". As the name
>>> implies, it's a group of attributes that are then referenced by objects within
>>> the IR. An attribute group is a module-level object. The BNF of the syntax is:
>>>
>>> attribute_group := attrgroup <attrgroup_id> = { <attribute_list> }
>>> attrgroup_id    := #<number>
>>> attribute_list  := <attribute> (, <attribute>)*
>>> attribute       := <name> (= <value>)?
>>>
>>> To use an attribute group, an object references the attribute group's ID:
>>>
>>> attribute_group_ref := attrgroup(<attrgroup_id>)
>>>
>>> This is an example of an attribute group for a function that should always be
>>> inlined, has stack alignment of 4, and doesn't unwind:
>>>
>>> attrgroup #1 = { alwaysinline, nounwind, alignstack=4 }
>>>
>>> void @foo() attrgroup(#1) { ret void }
>>>
>>> An object may refer to more than one attribute group. In that situation, the
>>> attributes are merged.
>>>
>>> Attribute groups are important for keeping `.ll' files readable, because a lot
>>> of functions will use the same attributes. In the degenerative case of a `.ll'
>>> file that corresponds to a single `.c' file, the single `attrgroup' will capture
>>> the command line flags used to build that file.
>>
>> A few comments on the new syntax:
>>
>>   1. I think most folks will understand what 'attrgroup' means, but it is a little cryptic.
>>      How about just 'attributes'?  The following reads easier to my eyes:
>>
>>         attributes #1 = { alwaysinline, nounwind, alignstack=4 }
>>         void @foo() attributes(#1) { ret void }
>>
>>   2. Are group references allowed in all attribute contexts (parameter, return value, function)?
>>      I think the answer should be yes.  Also, it might be worth considering using the same attribute
>>      list syntax in the current context and the new attribute group definition (i.e. comma-separated
>>      v.s. space-separated).  This way we have a consistent syntax for groups of attributes and the
>>      main addition this proposal adds is to give a name to those attributes for later reference.
>>
>>   3. Can attribute groups and single attributes be inter-mixed?
>>      For example:
>>
>>         void @foo attrgroup(#1) alwaysinline attrgroup(#2) nounwind
>>
>>   4. Do we really want the attribute references limited to a number?  Code will be more readable
>>      if you can use actual names that indicate the intent.  For example:
>>
>>         attrgroup #compile_options = { … }
>>         void @foo attrgroup(#compile_options)
>>
>>   5. Can attributes be nested?  For example:
>>
>>         attrgroup #1 = { foo, bar }
>>         attrgroup #2 = { #1, baz }
>>
>>      Might be nice.
>>
>>   6. Do we really need to specify the attrgroup keyword twice? (Once in the group definition and once in the use)
>>      ISTM, that the hash-mark is enough to announce a group reference in the use.  For example:
>>
>>         void @foo #1 alwaysinline #2 no unwind
>>
>> In other words, I think something like the following might be nicer:
>>
>> attribute_group := attributes <attrgroup_id> = { <attribute_list> }
>
> Well, if we're picking paints for this bikeshed, are the braces here
> necessary? We don't have braces for the other places we have
> <attribute_list>s.
>
> attributes #attrs = nounwind alwaysinline noreturn
> i8 @foo() #attrs
>
> ... as a synonym for ...
>
> i8 @foo() nounwind alwaysinline noreturn
>
> ... seems quite clean to me.
>

I prefer them, because it makes it clearer (to me) which attributes are added to the group. It's possible that the list could get long.

-bw



_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Bill Wendling-2
In reply to this post by Bill Wendling-2
On Nov 26, 2012, at 1:20 PM, Bill Wendling <[hidden email]> wrote:

> On Nov 20, 2012, at 11:03 AM, Meador Inge <[hidden email]> wrote:
>
>>  3. Can attribute groups and single attributes be inter-mixed?
>>     For example:
>>
>>        void @foo attrgroup(#1) alwaysinline attrgroup(#2) nounwind
>>
> This will be necessary for backwards compatibility. However, running this through this sequence:
>
> $ llvm-as < foo.ll | llvm-dis
>
> would produce:
>
> attrgroup #1 = { ... }
> attrgroup #2 = { ... }
> attrgroup #3 = { alwaysinline, nounwind }
>
> void @foo() attrgroup(#1) attrgroup(#2) attrgroup(#3)
>
> This is because of how the attributes will be represented internally to LLVM. Let me know if you have strong objections to this.
>
Now that I think about it, this isn't the output. Here's what it would look like:

a.ll:
        attributes #1 = { "no-sse" }
        attributes #2 = { noredzone }

        define void @foo() #1 #2 alwaysinline nounwind { ret void }

Here's the output:

        $ llvm-as < a.ll | llvm-dis

        attributes #1 = { "no-sse" }
        attributes #2 = { noredzone }
        attributes #3 = { "no-sse", noredzone, alwaysinline, nounwind }

        define void @foo() #3 { ret void }

This is because all of the attribute groups that a function references will be merged into one attribute object. When we output the attribute object, we don't know that the original function referred to two attribute groups and had a couple of extra attributes defined.

In practice, I expect this to happen rarely in non-LTO mode.

-bw

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Meador Inge-2
In reply to this post by Bill Wendling-2

On Nov 26, 2012, at 3:20 PM, Bill Wendling wrote:

>>  4. Do we really want the attribute references limited to a number?  Code will be more readable
>>     if you can use actual names that indicate the intent.  For example:
>>
>>        attrgroup #compile_options = { … }
>>        void @foo attrgroup(#compile_options)
>>
> The problem with this is it limits the number of attribute groups to a specific set -- compile options, non-compile options, etc.. There could be many different attribute groups involved, especially during LTO. I realize that the names will be uniqued. But that just adds a number to the existing name. I also want to avoid partitioning of the attributes into arbitrary groups -- i.e., groups with specific names which imply their usage or type.

My main concern is that I see no reason to limit the id to just numbers in the *language definition*.
That doesn't mean you can't always generate #<number> (in the same way that we do for variable names).
This way it leaves open the possibility of hand-writing nice names.

>>  5. Can attributes be nested?  For example:
>>
>>        attrgroup #1 = { foo, bar }
>>        attrgroup #2 = { #1, baz }
>>
>>     Might be nice.
>>
> I'm not a big fan of this idea. This could open it up to circular attribute groups:
>
> attrgroup #1 = { foo, #2 }
> attrgroup #2 = { #1, bar }
>
> which I'm opposed to on moral groups. ;-) A less compelling (but IMHO valid) argument is that it makes the internal representation of attributes that much more complex.

Fair enough.

>> In other words, I think something like the following might be nicer:
>>
>> attribute_group := attributes <attrgroup_id> = { <attribute_list> }
>> attrgroup_id    := #<id>
>> attribute_list  := <attribute> ( <attribute>)*
>> attribute       := <name> (= <value>)?
>>                | <attribuge_id>
>>
>> …
>>
>> function_def    := <attribute_list> <result_type> @<id> ([argument_list]) <attribute_list>
>>
> So something like this (no references inside of the 'attributes' statement allowed, cf. above)?
>
> attributes #1 = { noinline, alignstack=4 }
> attributes #2 = { "no-sse" }
>
> define void @foo() #1 #2 { ret void }
>
> This seems reasonable to me.

Me too.  This seem pretty close to what was implemented in the patches posted on
llvm-commits.  I review those in a bit.

--
Meador Inge
CodeSourcery / Mentor Embedded


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Passing Options to Different Parts of the Compiler Using Attributes

Bill Wendling-2
On Dec 4, 2012, at 8:12 PM, Meador Inge <[hidden email]> wrote:

> On Nov 26, 2012, at 3:20 PM, Bill Wendling wrote:
>
>>> 4. Do we really want the attribute references limited to a number?  Code will be more readable
>>>    if you can use actual names that indicate the intent.  For example:
>>>
>>>       attrgroup #compile_options = { … }
>>>       void @foo attrgroup(#compile_options)
>>>
>> The problem with this is it limits the number of attribute groups to a specific set -- compile options, non-compile options, etc.. There could be many different attribute groups involved, especially during LTO. I realize that the names will be uniqued. But that just adds a number to the existing name. I also want to avoid partitioning of the attributes into arbitrary groups -- i.e., groups with specific names which imply their usage or type.
>
> My main concern is that I see no reason to limit the id to just numbers in the *language definition*.
> That doesn't mean you can't always generate #<number> (in the same way that we do for variable names).
> This way it leaves open the possibility of hand-writing nice names.
>
Okay. It shouldn't be too difficult to do that.

>>> In other words, I think something like the following might be nicer:
>>>
>>> attribute_group := attributes <attrgroup_id> = { <attribute_list> }
>>> attrgroup_id    := #<id>
>>> attribute_list  := <attribute> ( <attribute>)*
>>> attribute       := <name> (= <value>)?
>>>               | <attribuge_id>
>>>
>>> …
>>>
>>> function_def    := <attribute_list> <result_type> @<id> ([argument_list]) <attribute_list>
>>>
>> So something like this (no references inside of the 'attributes' statement allowed, cf. above)?
>>
>> attributes #1 = { noinline, alignstack=4 }
>> attributes #2 = { "no-sse" }
>>
>> define void @foo() #1 #2 { ret void }
>>
>> This seems reasonable to me.
>
> Me too.  This seem pretty close to what was implemented in the patches posted on
> llvm-commits.  I review those in a bit.
>
I made one change. I made the attributes in the attribute groups non-comma separated. Otherwise, it's pretty much the same.

-bw


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev