[llvm-dev] Allocating global variables to physical registers

442 views
Skip to first unread message

Dobby HouseElf via llvm-dev

unread,
Jan 29, 2021, 8:34:16 PM1/29/21
to llvm...@lists.llvm.org
Hello all,

Is it possible to assign specific physical register(s) to a 'special' global variable at the time of code generation phase in LLVM?

Details: I have a Mips-like target and following Cpu0 tutorial, I added my custom backend to LLVM. I have a global variable that I want to use in many places in the program. I define a global variable in the program like, 'test.cpp' - 'int special;'
I want to assign / allocate a specific physical register in my backend to this special global variable.

Current status: Using 'llc -debug', I see that during the register allocation (greedy), the address of 'special' variable goes to a general purpose register and then it loads in a random general purpose register. 

I don't know if it is possible what I am trying to do? At which compilation stage should I try?
I read somewhere that using 'register' keyword is not good idea.

Thank you very much.
Excuse my English.
Please help!


David Spickett via llvm-dev

unread,
Feb 1, 2021, 4:42:57 AM2/1/21
to Dobby HouseElf, llvm...@lists.llvm.org
Sounds like "Global Named Register Variables". E.g.
clang ... -ffixed-r3 ...
register unsigned arm_r3 __asm("r3");

I know these are supported for Arm. See:
https://reviews.llvm.org/D3797
https://reviews.llvm.org/D68862 (includes test files that'll show you
how to use it from C)

I don't know whether that will "just work" for your backend (I assume
you need some option to mark the reserved register) but it should give
you a starting point.

Thanks,
David Spickett.

> _______________________________________________
> LLVM Developers mailing list
> llvm...@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

David Chisnall via llvm-dev

unread,
Feb 1, 2021, 5:45:45 AM2/1/21
to llvm...@lists.llvm.org
If you want to do this with a real (programmer-visible) global, David's
suggestion is exactly right.

If your global is sufficiently special, then you might instead want to
look at how things like the global pointer and thread pointer are
handled in different back ends. These are generally registers that are
reserved but contains a value that is used in CodeGen. There are a few
variants:

- Initialised somewhere else, used throughout CodeGen. The thread
pointer is in this category (e.g. HWR 25 on MIPS, FS/GS base on x86).
These are sometimes not even writeable in userspace and must be set by
the kernel.

- Initialised by rtld stub code on cross-library calls, may or may not
be preserved on cross-library calls. I believe the global pointer works
like this on some PowerPC ABIs with function descriptors and on the o32
MIPS ABI.

- Set up in the function prolog but then guaranteed to be there for
the rest of codegen. $gp on MIPS 'new' ABIs works like this. MIPS
(prior to r6) does not have PC-relative addressing and so the ABI
requires callers to use $t9 ($25) as the register that they jump to,
allowing the callee to guarantee that $t9 contains the PC on function
entry. It then does a fixed relocation of the distance from the
function entry to the __gp variable to load the address of the GOT into
$gp. Functions that are not exported or address taken may be able to
optimise this setup away, if all of their callers will have set up $gp.

David

Reply all
Reply to author
Forward
0 new messages