<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" dir="ltr" style="font-size:12pt; color:rgb(0,0,0); font-family:Calibri,Helvetica,sans-serif,"EmojiFont","Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Segoe UI Symbol","Android Emoji",EmojiSymbols">
<p style="margin-top:0; margin-bottom:0"></p>
<div>
<div>Hi all,<br>
<br>
This is a RFC on support for Global Register Variables in the Arm backend.<br>
<br>
Whilst there has been some prior discussion about whether or not LLVM should (or even needs to) support global register variables,<br>
today there seems to be a good measure of support for this in both Clang+LLVM (although it is currently limited to SP).<br>
When most of this support landed there was some concern expressed around the difficulty of extending it to cover allocatable registers.<br>
We have been looking at building atop of this current support to provide that ability to reserve allocatable registers.<br>
<br>
Our primary (bare-metal) use-cases for such support are:<br>
<br>
    1. Holding pointers for frequently-accessed data.<br>
    2. Placement of secure values (e.g. checksums) in specific registers to prevent them from being written out to main memory.<br>
<br>
This proposal aims to provide support for using r4-r11 as global register variables. This involves adding them to the reserved register set<br>
and preventing them from being callee-saved. We have deliberately tried to avoid registers that have a distinct ABI/AAPCS use,<br>
such as call-clobbered registers, LR and PC etc. Naturally the current support for the stack-pointer remains.<br>
<br>
r7, r11 and r9 at least are special cases, and are mentioned in more detail below.<br>
<br>
Clang Changes<br>
<span>----------------------</span><br>
The main proposed functional change to Clang is the tracking of global register variable declarations via module flags.<br>
Each declaration in a translation unit such as "register unsigned int foo __asm("r4");", will be mapped by the front-end to a module flag.<br>
<br>
e.g.<br>
---<br>
!{i32 1, !"fixed_reg.foo", !"r4"}<br>
---<br>
<br>
This is achieved via a modification to CodeGenModule::EmitGlobal. In addition, there are some changes relating<br>
to specifying valid global registers (by adding an Arm override for isValidGlobalRegister),<br>
<br>
Draft Patch: <a href="https://reviews.llvm.org/D56003" target="_blank" rel="noopener noreferrer" class="x_OWAAutoLink">
https://reviews.llvm.org/D56003</a><br>
<br>
LLVM Changes<br>
----------------------<br>
In the LLVM backend we can then use the module flags to add any (valid) specified global registers to the<br>
reserved reg list (getReservedRegs). In addition, to satisfy the second use-case*, we use the flags to remove<br>
any (valid) global registers from the list of callee registers to be saved (determineCalleeSaves).<br>
This shouldn't have any negative impact on a register that is already reserved for use.<br>
<br>
GCC seems to exhibit similar behaviour: <br>
<br>
    "If the register is a call-saved register, call ABI is affected: the register will not be restored in function epilogue sequences after the variable has been assigned."<br>
        See: https://gcc.gnu.org/onlinedocs/gcc/Global-Register-Variables.html#Global-Register-Variables<br>
<br>
Draft Patch: <a href="https://reviews.llvm.org/D56005" target="_blank" rel="noopener noreferrer" class="x_OWAAutoLink">
https://reviews.llvm.org/D56005</a><br>
<br>
A Note on r7, r11 and r9<br>
<span>----------------------</span>------------<br>
Whilst generally considered allocatable, these registers can on occasion be reserved for other purposes.<br>
As frame pointers, in the case of r7, and r11, and via -ffixed-r9 (or -frwpi), in the case of r9.<br>
<br>
The attached patches do not currently provide any mitigations against these cases.<br>
Options could range from disallowing these registers entirely, to throwing warnings or<br>
trying to catch and error in the correct scenarios (e.g. usage -ffixed-r9 when r9 is declared as a global reg variable).<br>
<br>
GCC's behaviour for many registers (at least notably, the call-clobbered registers, e.g. r0-r3), is to throw a warning, rather than an error.<br>
<br>
Other Notes<br>
<span>----------------------</span><br>
- It's worth noting that we may also look into extending this to cover AArch64 as well, in the near future.<br>
- Extending this proposal to work with a -ffixed-reg option should be feasible (if desired).<br>
- GCC warns when two global variables refer to the same register - this implementation silently accepts it.<br>
<br>
Previous Patches/Discussion<br>
-------------------------------<span>-----------</span><br>
- https://reviews.llvm.org/D3261<br>
- https://reviews.llvm.org/D3797<br>
- http://lists.llvm.org/pipermail/llvm-dev/2014-March/071472.html</div>
</div>
<p></p>
</div>
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose,
 or store or copy the information in any medium. Thank you.
</body>
</html>