[LLVMdev] Build Attributes Proposal

Renato Golin renato.golin at arm.com
Fri Nov 12 07:04:10 PST 2010


Hi all,

So, after long rounds to define how the build attributes are going to
be represented in IR, and after Jason has implemented build attributes
in MC, I have a proposal on how to represent this in IR.

First, we need to distinguish between target dependent and independent
attributes. Generic things like optimization level, specific
optimizations, use of vector instructions, use of exceptions,
floating-point compatibility can all go in to the generic list of
attributes. Local attributes like use ARM or Thumb, interoperability,
extensions, CPU name and architecture go into a target-specific
section.

Following the current rule in IR for specific attributes that are not
directly represented, and Chris' suggestion, I propose to use global
variables to represent them.


Representation:

The type has an identifier (Enum somewhere in LLVM) and a description or value:

%llvm.attribute = type { i32, i8* }

The generic attribute list can have, for instance, the optimization level used:

// suppose 1 is the key to "optimization level"
@llvm.attributes = appending global [2 x %llvm.attribute]
[%llvm.attribute { i32 1, i8* getelementptr inbounds ([3 x i8]* @.str,
i32 0, i32 0) }, %llvm.attribute zeroinitializer], align 4
@.str = private constant [3 x i8] c"O3\00"

And the target-specific has something like the CPU name and whether
it's using R9 as SB:

// 5 is CPU_name in ARM ABI, 14 is ABI_PCS_R9_use
@llvm.arm.attributes = appending global [2 x %llvm.attribute]
[%llvm.attribute { i32 5, i8* getelementptr inbounds ([10 x i8]*
@.str1, i32 0, i32 0) }, %llvm.attribute { i32 14, i8* null }], align
4
@.str1 = private constant [10 x i8] c"ARM946E-S\00"


Documentation:

It'd be good to have a list of all options, generic or otherwise. The
attributes enum could have a few lines explaining the options, but the
accepted values is more difficult to find in the code, so a
documentation (not LangRef) would be good, especially for the generic
part. The ARM options are already explained in the ABI documents and I
believe for other platforms as well.


Front-end/Back-End:

The front-end should be responsible for validating the
build-attributes, both for the generic and the specific parts, to make
sure at least that the identifiers are valid and their values in the
correct range (or in a given set of acceptable strings). The front-end
should not generate attributes that were not required, directly or
indirectly, but the user. Default behaviours should be already covered
by the back-end already, so no need to restate the obvious.

The back-end, and especially the linker, is free to assume whatever
they want to make the objects link without breaking any user requests.
The final executable should have only the build attributes necessary
to compile and link correctly.

I don't know how the back-end will get this, but there should be no
difference from the current implementation of other @llvm. globals.
There is already a place holder for ARM build attributes which will
have to be hooked to this values.


Use:

So, the biggest problem we have today in the LLVM back-end is that it
assumes too much.

If given ARMv7A, it assumes A8+NEON, which is not always true. Even if
given Cortex-A8 or A9 specifically, it still assumes NEON, which
again, is not 1 to 1. For instance, the new Tegra2 boards sport an A9
without NEON. LLVM generated code would probably break on them. While
putting a special case for Tegra2 would work, in ARM world, there are
more exceptions than rules, so that's not the optimal solution.

The ARM back-end doesn't print ".fpu" in the ASM file. GAS assumes
that you want NEON support if it sees NEON instructions in the code,
but not all linkers assume that much. The NEON instruction could be a
bug in the code generation pass, and you'd never notice if the linker
wouldn't complain about it.

These are the things that come to my mind now (as I've dealt with them
recently) but the number of examples are to great to list them here. I
hope to have conveyed the idea. ;)

In the case of lack of build attributes, the back-end is free to
assume whatever it wants, but it should *always* honour the attributes
to give the user most flexibility.


Please let me know your thoughts so I can start looking into plugging
the ARM part in the ARM back-end.

-- 
cheers,
--renato



More information about the llvm-dev mailing list