file://docs/LangRef.html#globalvars
The section describing the definition of global vars discusses that you can specify an alignment and can also specify a section. Could someone provide an example that works in gccas in release 1.9 for both defining which section the var is assigned to and defining the variables alignment?
Also, is there another document that describes how you define sections and their attributes?
file://docs/LangRef.html#globalvars
The section describing the definition of global vars discusses that you
can specify an alignment and can also specify a section. Could someone
provide an example that works in gccas in release 1.9 for both defining
which section the var is assigned to and defining the variables
alignment?
They are just comma separated:
%G = constant float 1.000000e+00, section "foo", align 4
Also, is there another document that describes how you define sections
and their attributes?
sections are target-specific, usually defined by the linker.
-Chris
Does anyone have any good ideas to verify that the layout of a struct
from the front end (field offsets and alignment) exactly match LLVM's
interpretation of that struct? I want to support packing of structs and
pragmas/attributes for alignment and validate that the front end and
back end match. [ This is a different front end (ie. Not GNU based). ]
For example:
__packed struct S1 {
char c;
double d;
};
If I wanted c at byte offset 0 and d at byte offset 1, how would I
communicate that to LLVM? If the user applied another pragma/attribute
which aligned d at offset 2, how would I communicate that and validate
it? The assumption here is that the user could declare a struct type
whose layout doesn't match the default layout from LLVM.
Perhaps I could extend llvm-as to accept additional annotations in type
declarations?
%S1 = type align 1 { sbyte at 0, double at 2 }
I don't see anything like this in the 1.9 grammar.
I added packed structures after 1.9. They are in CVS head, and
documented in the language guide. The cfe doesn't support them yet,
but that isn't a problem for you I guess. (There is a patch floating
around for llvm-gcc, but it hasn't been applied)
You can say:
<{ sbyte, double }> to get an sbyte at offset 0 and a double at offset
1. In packed mode, a structure has no padding and an alignment of 1.
If you want padding, you must insert the necessary buffering into the
structure in your frontend.
So for you example, you would say:
<{sbyte, sbyte, double}> where the middle sbyte is inserted by the
front end to get the padding for the double to be at 2.
Codegen of packed structures is mildly tested on x86.
Andrew
int %nlz10(uint %param.x) {
%.t3 = shr uint %param.x, ubyte 1 ; <uint>
[#uses=1]
%.t4 = or uint %.t3, %param.x ; <uint> [#uses=2]
%.t7 = shr uint %.t4, ubyte 2 ; <uint> [#uses=1]
%.t8 = or uint %.t7, %.t4 ; <uint> [#uses=2]
%.t11 = shr uint %.t8, ubyte 4 ; <uint> [#uses=1]
%.t12 = or uint %.t11, %.t8 ; <uint> [#uses=2]
%.t15 = shr uint %.t12, ubyte 8 ; <uint> [#uses=1]
%.t16 = or uint %.t15, %.t12 ; <uint> [#uses=2]
%.t19 = shr uint %.t16, ubyte 16 ; <uint>
[#uses=1]
%.t20 = or uint %.t19, %.t16 ; <uint> [#uses=1]
%.t22 = mul uint %.t20, 116069625 ; <uint>
[#uses=1]
%.t25 = shr uint %.t22, ubyte 26 ; <uint>
[#uses=1]
%.t28 = getelementptr [64 x ubyte]* %table, int 0, uint %.t25
; <ubyte*> [#uses=1]
%.t28 = load ubyte* %.t28 ; <ubyte> [#uses=1]
%.t31 = cast ubyte %.t28 to int ; <int> [#uses=1]
ret int %.t31
}
This is the disassembled output after running the optimizer. How can
%.t28 be written to twice? That isn't my understanding of SSA.
Here's another similar situation:
%x.2.i73 = cast uint %x.2.i73 to int ; <int>
[#uses=1]
Why are we not assigning to a different ssa var?
In the version of llvm you are using, names are only unique with
respect to their type. There can be two %x if they have different
types. Thus a variable isn't identified by name, but by <name, type>.
This has changed in CVS.
Andrew
Hi Mark,
int %nlz10(uint %param.x) {
%.t3 = shr uint %param.x, ubyte 1 ; <uint>
[#uses=1]
%.t4 = or uint %.t3, %param.x ; <uint> [#uses=2]
%.t7 = shr uint %.t4, ubyte 2 ; <uint> [#uses=1]
%.t8 = or uint %.t7, %.t4 ; <uint> [#uses=2]
%.t11 = shr uint %.t8, ubyte 4 ; <uint> [#uses=1]
%.t12 = or uint %.t11, %.t8 ; <uint> [#uses=2]
%.t15 = shr uint %.t12, ubyte 8 ; <uint> [#uses=1]
%.t16 = or uint %.t15, %.t12 ; <uint> [#uses=2]
%.t19 = shr uint %.t16, ubyte 16 ; <uint>
[#uses=1]
%.t20 = or uint %.t19, %.t16 ; <uint> [#uses=1]
%.t22 = mul uint %.t20, 116069625 ; <uint>
[#uses=1]
%.t25 = shr uint %.t22, ubyte 26 ; <uint>
[#uses=1]
%.t28 = getelementptr [64 x ubyte]* %table, int 0, uint %.t25
; <ubyte*> [#uses=1]
%.t28 = load ubyte* %.t28 ; <ubyte> [#uses=1]
%.t31 = cast ubyte %.t28 to int ; <int> [#uses=1]
ret int %.t31
}
This is the disassembled output after running the optimizer. How can
%.t28 be written to twice? That isn't my understanding of SSA.
We have corrected this in the most recent version of LLVM (CVS HEAD).
The reason it was allowed previously is because of "type planes". That
is, the names only needed to be unique for a given type. So, %.t28
resulting from the GEP is of type ubyte* while %.t28 resulting from the
LOAD is of type ubyte. Thus, no conflict.
However, many people have found this confusing so we did away with type
planes. It is now illegal to reuse a name, of any type, in a function.
Here's another similar situation:
%x.2.i73 = cast uint %x.2.i73 to int ; <int>
[#uses=1]
Why are we not assigning to a different ssa var?
It is a different SSA var, just happens to have the same name.