Joan Lluch via llvm-dev
2019-May-13 06:53 UTC
[llvm-dev] How to change CLang struct alignment behaviour?
Hi Tim, Thanks for your reply. That’s what I was afraid of. I will try on the cfe-list as you suggest though. The reason I want structs to be aligned/padded to 2 bytes is because my architecture only has 16 bit operations. I can read (sign and zero extended) and write (truncated) 8 bit data from/to memory, but all intermediate operations in registers are performed in 16 bit registers. This causes LLVM to generate odd tricks such as shifts and byte-swaps, when trying to replace struct ‘memcpy’s by word sized load/store instructions. For 16 bit aligned structs the ‘memcpy’ replacement code is much cleaner. That’s the reason I would want structs to be always 16 bit aligned/padded. Joan Lluch Puigsacalm, 7 17458 - Fornells de la Selva Girona Tel: 620 28 45 13> On 13 May 2019, at 08:36, Tim Northover <t.p.northover at gmail.com> wrote: > > Hi Joan, > > On Sun, 12 May 2019 at 21:02, Joan Lluch via llvm-dev > <llvm-dev at lists.llvm.org> wrote: >> How do I change that behaviour to get structs always (at least) 2 byte aligned ? > > I don't think there's a feature you can toggle for this (except, > maybe, making the alignment of every basic type 2 bytes; but that > would obviously affect arrays and even normal variables too). So you > probably have to modify lib/AST/RecordLayoutBuilder.cpp directly. > > Might be worth asking this on the cfe-dev mailing list though. That's > where most of the Clang experts live. > > Cheers. > > Tim.-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190513/98d04ef9/attachment.html>
Tim Northover via llvm-dev
2019-May-13 07:33 UTC
[llvm-dev] How to change CLang struct alignment behaviour?
Hi Joan, On Mon, 13 May 2019 at 07:53, Joan Lluch <joan.lluch at icloud.com> wrote:> The reason I want structs to be aligned/padded to 2 bytes is because my architecture only has 16 bit operations. I can read (sign and zero extended) and write (truncated) 8 bit data from/to memory, but all intermediate operations in registers are performed in 16 bit registers.This is very normal. Mostly it's at 32-bits rather than 16, but it applies to basically every RISC architecture so LLVM should handle it well without adjusting the alignment requirements of types.> This causes LLVM to generate odd tricks such as shifts and byte-swaps, when trying to replace struct ‘memcpy’s by word sized load/store instructions.That sounds odd, as if you've not taught the backend to use those 8-bit loads and stores so it's trying to emulate them with word-sized ones (early Alpha chips genuinely didn't have byte access so had to do that kind of thing). You can (and should) probably fix that. Also, there are a few customization points where you can control how memcpy is implemented. The function "findOptimalMemOpLowering" lets you control the type used for the loads and stores, and MaxStoresPerMemcpy controls when LLVM will call the real memcpy. If you want even more control you can implement EmitTargetCodeForMemcpy to do the whole thing. Cheers. Tim.
Joan Lluch via llvm-dev
2019-May-13 09:17 UTC
[llvm-dev] How to change CLang struct alignment behaviour?
I had already adjusted MaxStoresPerMemcpy to my preferred value, and this works great but for the cases where load/stores are used on non-size aligned structs the odd behaviour still happens. For my 3-char, 3-byte struct test, the memcpy replacement appears to consist on a single byte load and store of the last char (this is correct), followed by a 16 bit move of the first two chars, this is also correct, but the odd thing is that the 16 bit move is performed by picking bytes separately from the source struct, then combining them into 16 bit values by means of shifts, swap, and or, then moved as words to the destination. I don’t know why simple 16 bit load and stores are used instead. Will try to track findOptimalMemOpLowering with the debugger to see if I see some light. So thanks for pointing that out to me. John Tel: 620 28 45 13> On 13 May 2019, at 09:33, Tim Northover <t.p.northover at gmail.com> wrote: > > Hi Joan, > > On Mon, 13 May 2019 at 07:53, Joan Lluch <joan.lluch at icloud.com> wrote: >> The reason I want structs to be aligned/padded to 2 bytes is because my architecture only has 16 bit operations. I can read (sign and zero extended) and write (truncated) 8 bit data from/to memory, but all intermediate operations in registers are performed in 16 bit registers. > > This is very normal. Mostly it's at 32-bits rather than 16, but it > applies to basically every RISC architecture so LLVM should handle it > well without adjusting the alignment requirements of types. > >> This causes LLVM to generate odd tricks such as shifts and byte-swaps, when trying to replace struct ‘memcpy’s by word sized load/store instructions. > > That sounds odd, as if you've not taught the backend to use those > 8-bit loads and stores so it's trying to emulate them with word-sized > ones (early Alpha chips genuinely didn't have byte access so had to do > that kind of thing). You can (and should) probably fix that. > > Also, there are a few customization points where you can control how > memcpy is implemented. The function "findOptimalMemOpLowering" lets > you control the type used for the loads and stores, and > MaxStoresPerMemcpy controls when LLVM will call the real memcpy. If > you want even more control you can implement EmitTargetCodeForMemcpy > to do the whole thing. > > Cheers. > > Tim.-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190513/17263825/attachment.html>