[llvm-commits] [Review] Attributes Documentation

Bill Wendling wendling at apple.com
Wed Dec 5 18:01:55 PST 2012


On Dec 5, 2012, at 1:50 AM, Renato Golin <rengolin at systemcall.org> wrote:

> On 5 December 2012 08:56, James Molloy <James.Molloy at arm.com> wrote:
>> How does uniquing work?
>> 
>> attributes #0 = { noinline optsize }
>> attributes #1 = { noinline optsize }
> 
> I was wondering about the same thing. Luckily, this is easily worked
> around, like commoning up types, provided the order is forced, ie. it
> should not be possible to have:
> 
> attributes #0 = { noinline optsize }
> attributes #1 = { optsize noinline }
> 
> Making the attributes as classes / enum objects is one way to do it.
> It loses the flexibility of adding new attributes, but shouldn't be
> too hard to add a new item on an enum (or a new small class) on a
> common header.
> 
Attributes are already uniqued today. It's done with enums and such. :)

> However, a much worse problem is packing. The number of possible
> combinations is huge, and simplifying them is an np-complete problem.
> 
> attributes #0 = { noinline optsize }
> attributes #1 = { no-sse alignstack=4 }
> 
> define void @f() #0 #1 { ... }
> 
> // Here, if I want optsize + alignstack=4, I need to create another
> 
> attributes #2 = { optsize alignstack=4 }
> 
> define void @f2() #2 { ... }
> 
> // What if I want no-sse AND noinline?
> 
> attributes #3 = { no-sse noinline }
> 
> define void @f3() #3 { ... }
> 
> // Now, I want a combination of { noinline optsize alignstack=4 },
> which do I use?
> 
> define void @f4() #0 #2 { ... } // is the answer, but how computers find this?
> 
> The problem is, for every new function, you'll have to search the
> whole space for the best match among all combinations of all declared
> attributes, or just create a new one if there isn't any *exactly* as
> you want.
> 
> The first solution is np-complete, the second will bloat code. I
> believe, the whole point of this change is to reduce IR footprint.
> 
> 
> 
> I personally think that having the attributes on the functions is
> *much* better, on the textual form, than having to check them
> somewhere else in the IR.
> 
This becomes very unwieldy once you start expanding the number of attributes you have. It leads to a very hard to read function signature.

> So, my humble opinion is that this should be a pass only executed in
> binary form, *after* IR has been formed (with attributes on
> functions), and the pass gathers all possible attributes, generates a
> group of the common cases and replace attributes list with a pointer
> to the list, which is commoned up somewhere else. No need for changing
> the textual form, that is mainly directed to humans, not computers.
> 
In practice, there won't be a large number of differences between functions. The attributes come about in only a few ways:

	- through command line options
	- via '__attribute__' declarations

So most functions within a TU will have the same set of attributes. A handful will be different, but it shouldn't result in a combinatorial explosion of attribute groups. In fact, the uniquing and allowing a function to reference multiple attribute groups is meant to alleviate the number of attribute groups that are generated. For what it's worth, these two attribute groups are equivalent:

	attributes #foo = { noinline no-sse }
	attributes #bar = { no-sse noinline }

-bw




More information about the llvm-commits mailing list