Pointer alignments in the type system?
bearophile
bearophileHUGS at lycos.com
Fri Jul 12 16:56:17 PDT 2013
> This is the LL code generated using the -output-ll switch of
> ldc2 (it's a kind of nearly universal bytecode for llvm):
>
> @_D5test51ayG16i = global [16 x i32] [i32 1, i32 2, i32 3, i32
> 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12,
> i32 13, i32 14, i32 15, i32 16]
> @_D5test51byG16i = global [16 x i32] [i32 16, i32 15, i32 14,
> i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32
> 5, i32 4, i32 3, i32 2, i32 1]
> @_D5test51cG16i = global [16 x i32] zeroinitializer
>
>
> If I add a "align(16)" annotation to a, b, c it adds the align
> 16 annotation in the LL code too:
>
> @_D5test51ayG16i = global [16 x i32] [i32 1, i32 2, i32 3, i32
> 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12,
> i32 13, i32 14, i32 15, i32 16], align 16
> @_D5test51byG16i = global [16 x i32] [i32 16, i32 15, i32 14,
> i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32
> 5, i32 4, i32 3, i32 2, i32 1], align 16
> @_D5test51cG16i = global [16 x i32] zeroinitializer, align 16
I didn't think to also take a look at the asm produced. Even if I
don't add align(16) in the code, and even if the LLVM IR doesn't
have an alignment annotation, the data in the asm has such
alignment:
.data
.globl __D4test1ayG16i
.align 16
__D4test1ayG16i:
.long 1
.long 2
.long 3
.long 4
.long 5
.long 6
.long 7
.long 8
.long 9
.long 10
.long 11
.long 12
.long 13
.long 14
.long 15
.long 16
.globl __D4test1byG16i
.align 16
__D4test1byG16i:
.long 16
.long 15
.long 14
.long 13
.long 12
.long 11
.long 10
.long 9
.long 8
.long 7
.long 6
.long 5
.long 4
.long 3
.long 2
.long 1
Regarding adding the alignment to the D type system, to assure
sliced data is aligned, a possible first step is to support:
void foo(align(16) double[] a1,
align(16) double[] a2) {}
That annotation is dynamically tested at entry point. So it's
similar to this:
void foo(double[] a1, double[] a2)
in {
assert(isAligned(a1, 16) && isAligned(a2, 16));
} body {}
But inside the body of foo() the compiler is allowed to use
aligned SIMD instructions (in theory this should be true for the
version with asserts too).
A more elegant (and maybe better) solution is to verify the
alignment statically. This means foo() accepts only 16-aligned
arrays. Array cast(), new array, dup, idup, and little else is
statically known to produce/return aligned arrays. And for the
other slices you need something like makeAligned!N() that returns
a statically known alignment.
Bye,
bearophile
More information about the Digitalmars-d
mailing list