Global variables marked with "unnamed_addr" have the following property: "...unnamed_addr indicates that the address is not significant, only the content".
One potential use of "unnamed_addr" by front-ends is to emit "unnamed_addr constant" globals holding pointer initialisers to other global variables. For instance, this can be used if the front-end wishes to compute and store information against a location with a symbol pointer but doesn't care about its address. A more concrete example follows:
@foo = global i32 42
@proxy = unnamed_addr constant i32* @foo
@delta = global i32 trunc (i64 sub (i64 ptrtoint (i32** @proxy to i64),
i64 ptrtoint (i32* @delta to i64)) to i32)
Here, @delta holds a data "PC"-relative offset to a pointer of @foo. The darwin/x86-64 assembly output for this follows:
.globl _foo
_foo:
.long 42
.globl _proxy
_proxy:
.quad _foo
.globl _delta
_delta:
.long _proxy-_delta
I propose a minor optimisation for such cases: given target specific support, replace pc-relative accesses to such unnamed_addr global constants by a PC relative access to the GOT entry of the final symbol instead. Therefore, "delta" would contain a pc relative relocation to foo's GOT entry and we avoid the emission of "proxy", yielding the assembly code below:
.globl _foo
_foo:
.long 42
.globl _delta
_delta:
.long _foo@GOTPCREL+4
There are a couple of advantages of doing this:
- In situations where all that’s required is that there be some way to get the address of an external symbol we save space by not emitting "proxy" globals. Front-ends that need to emit a great deal of data containing pointers could benefit from this.
- As a side effect, such IR constructs combined with the proposed opt opens a way to represent GOT pcrel relocations by solely using the LLVM IR, which is something we currently have no way to express.
Also, this is not MachO specific and can also benefit ELF targets. I've attached a patch implementing this simple feature for x86-64/darwin but mostly changes are target independent.
Thanks,
-Bruno
Proxy seems like a new term.
I would probably go with *GOT*. GOTEquivalent maybe?