[LLVMdev] LLVM GHC Backend: Tables Next To Code
James.Molloy at arm.com
Wed Feb 15 14:08:35 PST 2012
> This is starting to look very similar to how ARM constant islands work, without the extra ugliness from how small the ARM immediate displacements are.
Would there be any reason that this couldn't be seen as an opportunity to move the constant islands pass out of the ARM backend and make the target-independent constant pools (which ARM bypasses completely) more generic?
From: llvmdev-bounces at cs.uiuc.edu [llvmdev-bounces at cs.uiuc.edu] On Behalf Of Jim Grosbach [grosbach at apple.com]
Sent: 15 February 2012 21:59
To: Chris Lattner
Cc: Simon Marlow; Sergiu Ivanov; llvmdev at cs.uiuc.edu; cvs-ghc; Gabor Greif
Subject: Re: [LLVMdev] LLVM GHC Backend: Tables Next To Code
On Feb 15, 2012, at 12:16 PM, Chris Lattner <clattner at apple.com> wrote:
> On Feb 14, 2012, at 10:30 AM, David Terei wrote:
>> Hmm writing a blog post about TNTC is beyond the time I have right now.
> Sure, understandable. I'm surprised someone else hasn't already :)
>> Here is some high level documentation of the layout of Heap objects in GHC:
>> With TNTC enabled we generate code for closures of this form:
>> .align 8
>> .long Main_main1_srt-(Main_main1_info)+0
>> .long 0
>> .quad 4294967299
>> .quad 0
>> .quad 270582939663
>> .globl Main_main1_info
>> .type Main_main1_info, @object
>> leaq -8(%rbp),%rax
>> cmpq %r15,%rax
>> jb .Lc1Dh
> Ok. I'd strongly recommend the approach of generating the table inside the prolog of the function. This means you'd get something like this:
This is starting to look very similar to how ARM constant islands work, without the extra ugliness from how small the ARM immediate displacements are.
> .align 8
> .globl Main_main1_info
> .type Main_main1_info, @object
> jmp .Ltmp
> .long Main_main1_srt-(Main_main1_info)+0
> .long 0
> .quad 4294967299
> .quad 0
> .quad 270582939663
> leaq -8(%rbp),%rax
> cmpq %r15,%rax
> jb .Lc1Dh
> Since the jmp is a fixed 2 bytes (0xEB, tablesize), all references to the table can still be done with trivial pc/RIP-relative addressing within the closure, and you just need one pointer for both the table and the closure data.
> If you want to get extra special and tricky, you could be even more devious by storing "Main_main1_info + 2 + table size" as the canonical pointer. If you jump to *that* when dispatching to the closure, then you completely avoid the runtime overhead of the extra unconditional jump and get exactly the same code you're getting with GHC's native code generator.
> To access the table in LLVM IR, you'll be generating some truly special (i.e. horrible :) IR along the lines of (e.g. to load the 4294967299 field):
> load (gep (bitcast @Main_main1_info to i64*), 0, 2)
> The code generator probably isn't smart enough to turn that into a rip-relative memory access, but adding that should be straight-forward.
> The tricky bit will be figuring out how to ensure that the inline asm blob containing the table will come before the standard prolog. Perhaps this can be handled by the existing GHC calling convention, or through creative use of the naked attribute.
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
LLVM Developers mailing list
LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
-- 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.
More information about the llvm-dev