Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2011-11

Alignment question

9 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Sergei Gorelkin

Hello,

Is it possible to declare a (SSE friendly) record or array type, so that local variables of this type get aligned to e.g. 16 bytes? Target is x86_64 with aligned stack. The {$codealign localmin=16} directive seems to work, but it is an ugly solution because:
- it must be effective at all places where variables of the given type are declared,
- it aligns all other local variables that do not need to be aligned.

Regards,
Sergei

Reply by email

Jonas Maebe
to Sergei Gorelkin
Sergei Gorelkin wrote
Is it possible to declare a (SSE friendly) record or array type, so that local variables of this type get aligned to e.g. 16 bytes?

I don't think so. For this, we'd probably need a separate vector type (possibly using a modifier for array types, or with a new keyword). All ABIs for architectures supporting vector processing also treat vectors as distinct types. Such functionality is also required to finish the high level code generator in the JVM branch for native targets (it has to be to distinguish vectors from arrays at the tdef level).

Jonas

Reply by email

Jonas Maebe
to Sergei Gorelkin: 19.11.2011 14:14, Jonas Maebe пишет: Hm, that looks like two separate tasks: one is…
Sergei Gorelkin wrote
Hm, that looks like two separate tasks: one is distinct vector type for ABIs, another one is alignment of arbitrary types. The issue I've stumbled into is the TContext record (CPU context), which contains only word and qword members, but has to be 16 byte aligned because it is used by SSE instructions. In SDK it has a __declspec(align(16)) attribute, I guess we need something like that too.

You could emulate this with a variant record containing a vector element, but a modifier or directive would be of course be more convenient (and easier to implement). To avoid having to add alignment information to all symbols, I would limit this functionality to recorddefs and objectdefs though (there we already keep track of the alignment requirements via the tabstractrecordsymtable(symtable).recordalignment field).

Jonas

Reply by email

Sergei Gorelkin
to Jonas Maebe: I don't think so. For this, we'd probably need a separate vector type (possibly using a…

19.11.2011 14:14, Jonas Maebe пишет:

Show quoted text 7 lines
On 19 Nov 2011, at 11:31, Sergei Gorelkin wrote: > Is it possible to declare a (SSE friendly) record or array type, so that local variables of this type get aligned to e.g. 16 bytes? I don't think so. For this, we'd probably need a separate vector type (possibly using a modifier for array types, or with a new keyword). All ABIs for architectures supporting vector processing also treat vectors as distinct types. Such functionality is also required to finish the high level code generator in the JVM branch for native targets (it has to be to distinguish vectors from arrays at the tdef level).

Hm, that looks like two separate tasks: one is distinct vector type for ABIs, another one is alignment of arbitrary types. The issue I've stumbled into is the TContext record (CPU context), which contains only word and qword members, but has to be 16 byte aligned because it is used by SSE instructions. In SDK it has a __declspec(align(16)) attribute, I guess we need something like that too.

Sergei

Reply by email

Florian Klämpfl
to Sergei Gorelkin: Is it possible to declare a (SSE friendly) record or array type, so that local variables…
Sergei Gorelkin wrote 9 lines
Hello, Is it possible to declare a (SSE friendly) record or array type, so that local variables of this type get aligned to e.g. 16 bytes? Target is x86_64 with aligned stack. The {$codealign localmin=16} directive seems to work, but it is an ugly solution because: - it must be effective at all places where variables of the given type are declared,

Isn't the alignment sticky to the type?

So declaring the type once with the right recordaligmax should be sufficient?

Show quoted text 8 lines
- it aligns all other local variables that do not need to be aligned. Regards, Sergei _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Jonas Maebe
Florian Klämpfl wrote
So declaring the type once with the right recordaligmax should be sufficient?

recordalignmax does not mean that a type will be aligned to a multiple of that value. It only means that it will be aligned to that value *if* it contains any fields that need such an alignment. E.g., if you are on a system where double is defined as preferring 8-byte alignment and a record contains a double field, then recordalignmax=4 will result in that record nevertheless getting aligned to 4 bytes, but recordalignmax=8 or recordalignmax=16 or any other value >= 8 means that it will be aligned to 8 bytes.

Jonas

Reply by email

Florian Klämpfl
to Jonas Maebe
Jonas Maebe wrote 14 lines
On 20 Nov 2011, at 21:04, Florian Klämpfl wrote: > So declaring the type once with the right recordaligmax should be > sufficient? recordalignmax does not mean that a type will be aligned to a multiple of that value. It only means that it will be aligned to that value *if* it contains any fields that need such an alignment. E.g., if you are on a system where double is defined as preferring 8-byte alignment and a record contains a double field, then recordalignmax=4 will result in that record nevertheless getting aligned to 4 bytes, but recordalignmax=8 or recordalignmax=16 or any other value >= 8 means that it will be aligned to 8 bytes.

Sorry, I meant recordalignmin.

Reply by email

Sergei Gorelkin
to Jonas Maebe

20.11.2011 23:38, Jonas Maebe пишет:

Show quoted text 8 lines
On 20 Nov 2011, at 21:18, Florian Klämpfl wrote: > Sorry, I meant recordalignmin. And I didn't think of that setting. Yes, that should indeed work.

It doesn't, {$codealign recordnmin} changes only alignment of fields within the record, not alignment of the record itself. In the following example:

{$mode objfpc}{$h+}
unit a;
interface
{$codealign recordmin=16}
type
   arr=record x,y: int64 end;
   t=record
     a1: arr;
     a2: word;
   end;
implementation
end.

you get sizeof(arr)=24, sizeof(t)=40, while recordalignment of t stays equal to 8.

Regards,
Sergei

Reply by email