[PATCH] Implement function prefix data as an IR feature.

Duncan Sands duncan.sands at gmail.com
Fri Aug 2 07:50:40 PDT 2013


On 30/07/13 07:24, Chris Lattner wrote:
>
> On Jul 20, 2013, at 6:40 PM, Peter Collingbourne <peter at pcc.me.uk> wrote:
>
>> Previous discussion:
>> http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-July/063909.html
>>
>> http://llvm-reviews.chandlerc.com/D1191
>
>
> This is gross, but I'm not morally opposed to this approach. :-)

Same feelings here :)  I thought a bit about how I would have designed this, and
came up with the following.  The essential thing if I understood right is to be
able to "allocate" a block of constant memory (with an initial value) and to
attach it to a function somehow so that the address of the memory can be
computed from the address of the function.

1) The block of constant memory.  It would be great to be able to do
optimizations on this, such as folding loads from it to the loaded value.
Duplicating a bunch of existing optimizations seems like a bad idea, so I
propose representing it as a global variable, so we get these optimizations
for free:

   @prefix_data1 = private constant %type { ... initial value ... }

Of course this global is going to end up with some kind of funky address, and
be placed in a strange place (maybe inside the code for the function it is
attached to), but from a semantic viewpoint I think it doesn't really differ
much from any other global constant, so let it be one.  There are all kinds
of details such as what linkage type and visibility to allow, but I think
these are minor and I didn't worry about them.  There are probably also issues
like: it can't be more aligned than the function.

2) Attaching it to the function.  I have no particular opinion about this, so
let me just invent something for the sake of this email:

   define void @foo(void) attach @prefix_data1 { ... }

There's the question of whether this counts as a use of @prefix_data1 or not.
I didn't think about this.

3) Getting hold of the address of the constant from the function.  Since you may
want to use the prefix data in initial values for other globals, at first glance
there should be a new ConstantExpr that takes a function and returns the address
of the prefix data if any.  Eg: "%type* prefix_data (@foo)" would return the
address of the data attached to foo, i.e. @prefix_data1.  Constant folding is
easy: when the constant folder see "prefix_data (function)" with an identifiable
function @foo, it would then look at @foo to see what data is attached; it is
@prefix_data1, so it replaces the constant expression with @prefix_data1.
But then you have to ask: how useful is this new constant expression, since
whenever you know what the function is, you don't need the constant expression,
you can just use @prefix_data1 directly.  I'm thinking that for initializing
other globals, you probably in practice always know what the function was
(@foo), so then you can just use the prefix data global (@prefix_data1) in the
initializer directly.  If a new ConstantExpr isn't needed, then things get much
simpler: there can just be a new intrinsic

   %addr = call %type* llvm.prefix_data(function)

computing the address of the prefix data for a function from the address of the
function.

And that's it.

As for implementation, I've got nothing against Peter's suggested implementation
(except that codegen should be injecting the magic code sequence that causes
control to jump over the data).  This suggested setup does allow for alternative
implementations though.

Ciao, Duncan.

PS: I'll be away for the next three weeks, so don't be surprised if I don't
reply to emails.



More information about the llvm-commits mailing list