I am working towards a more complete solution for large constants in mips 16 (ala Arm constant islands and such). That is part of why I'm busy expanding all macros being emitted in the mips 16 compiler (almost done).
I'm wondering if there is a poor mans approach for large constants that can be done very simply that I can add just for now.
Gcc mips 16 places them after the function in the text section.
Mips 16 , unlike mips32, has a pc relative load.
I'm wondering if there is already some mechanism where I can assign literals to the text section and get a label for where it has been stored.
I'm wondering if there is already some mechanism where I can assign literals
to the text section and get a label for where it has been stored.
I think putting them in the text section is reasonably simple, though
doesn't have a generic "pleasePutConstantsAfterFunctions()" call in
A good place to start would be the reverse of my recent patch to
AArch64 which removed the entire ConstantIslands thing. It looks like
the key points are creating a "CONSTPOOL_ENTRY" "instruction" which is
emitted in the AsmPrinter. A relatively simple pass should be able to
convert constpool entries as LLVM sees them into such instructions
Most of the complexity is in moving the constants around so that
they're accessible from the instructions that use them, but for a
first approximation that's not needed (beware, PlumHall's ch7_22 is a
prime candidate for exercising this ability even with a 1MB range).
Why did you take out the constant island code for Arm 64?
Just did not need it?
Why did you take out the constant island code for Arm 64? Just did not need it?
It was more a case of there not being any strong evidence that we
*did* need it. That pass is extremely big and took me at least two
attempts to get correct, and that was basing my work on a copy/paste
from the 32-bit ARM code.
Jim Grosbach thought (and internal enquiries didn't refute) that there
could be microarchitectural implications to embedding arbitrary data
into code sequences (branch predictors and alignment constraints have
been mentioned as possible fallout). On the other hand, removing it
means that any litpool access goes from:
ldr w0, litpool
adrp x0, litpool
ldr w0, [x0, #:lo12:litpool]
I decided that since even the most optimistic load takes a few cycles
on modern hardware, it wasn't worth worrying about that extra (fairly
trivial) arithmetic instruction unless there was good evidence it
improved performance. I didn't have such evidence. Of course MIPS16
could very easily lie on the other side of any performance decision
like that; it may be obvious that the work is worthwhile in your
So basically, it's resting on AArch64. If evidence comes in that it
really does help I'll go back to my original plan of resurrecting it
and merging the AArch32/AArch64 versions into a target-independent
pass with hooks for different backends. Meanwhile, I don't have to
maintain it or worry about it being a source of bugs.
The other major annoyance from my perspecive is that it's fused with
the branch fixup pass. They're two different jobs that affect one
another far too much for my liking. Not that I have a (efficient)
solution to that problem.