[llvm-dev] RFC: Absolute or "fixed address" symbols as immediate operands
Peter Collingbourne via llvm-dev
llvm-dev at lists.llvm.org
Mon Oct 24 21:40:14 PDT 2016
On Mon, Oct 24, 2016 at 8:54 PM, Chandler Carruth <chandlerc at google.com>
wrote:
> On Mon, Oct 24, 2016 at 1:54 PM Peter Collingbourne via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
>
>> On Mon, Oct 24, 2016 at 1:36 PM, Friedman, Eli <efriedma at codeaurora.org>
>> wrote:
>>
>> On 10/24/2016 1:07 PM, Peter Collingbourne via llvm-dev wrote:
>>
>> On Mon, Oct 10, 2016 at 8:12 PM, Peter Collingbourne <peter at pcc.me.uk>
>> wrote:
>>
>> The specific change I have in mind is to allow !range metadata on
>> GlobalObjects. This would
>> be similar to existing !range metadata, but it would apply to the
>> "address" of the attached GlobalObject, rather than any value loaded from
>> it. Its presence on a GlobalObject would also imply that the address of the
>> GlobalObject is "fixed" at link time.
>>
>>
>> Going back to IR-level representation: here is an alternative
>> representation based on a suggestion from Eli.
>>
>> Introduce a new type of GlobalValue called GlobalConstant. GlobalConstant
>> would fit into the GlobalValue hierarchy like this:
>>
>> - GlobalValue
>> - GlobalConstant
>> - GlobalPointer
>> - GlobalIndirectSymbol
>> - GlobalAlias
>> - GlobalIFunc
>> - GlobalObject
>> - Function
>> - GlobalVariable
>>
>> GlobalValue would no longer be assumed to be of pointer type. The
>> getType() overload that takes a PointerType, as well as getValueType()
>> would be moved down to GlobalPointer. (A nice side benefit of this is that
>> it would help flush out cases where we are unnecessarily depending on
>> global pointee types.)
>>
>> A GlobalConstant can either be a definition or a declaration. A
>> definition would look like this:
>>
>> @foo = globalconst i32 42
>>
>>
>> This is equivalent to writing "foo = 42" in assembly?
>>
>>
>> Yes.
>>
>>
>>
>>
>> while a declaration would look like this:
>>
>> @foo = external globalconst i32
>>
>> GlobalConstant could also hold a linkage and visibility. Looking at the
>> other attributes that a GlobalValue can hold, many of them do not seem
>> appropriate for GlobalConstant and could potentially be moved to
>> GlobalPointer.
>>
>> Thoughts?
>>
>>
>> How do you plan to use this? The concept makes sense, but I've never
>> actually seen anyone use symbols this way.
>>
>>
>> I plan to use this as part of the ThinLTO implementation of control flow
>> integrity. See http://clang.llvm.org/docs/ControlFlowIntegrityDesign.html
>> for a description of how the design currently works in regular LTO.
>>
>> If you look at the asm snippets in that design doc, you will see a number
>> of hardcoded constants -- these constants are calculated at LTO time based
>> on whole program information. I want the intermediate object files to
>> depend on the constants so that their values can be substituted in at link
>> time. In ThinLTO, object files are cached, so if a value changes I want to
>> avoid invalidating the cache entries that depend on that value.
>>
>
> This states the context you want to use these in (CFI with ThinLTO)
> without actually stating how you plan to use them within that context. I
> think the latter would help motivate specific designs.
>
> Is there a write-up of the imagined CFI+ThinLTO design somewhere that
> (concisely) explains the plan?
>
Not just yet, at least not regarding the part which requires constants. I
will send that to the list separately.
> Maybe you could give some small and easy to understand example usage to
> motivate this?
>
Sure. Suppose you have two modules:
m1.ll:
@foo = globalconst i8 1
m2.ll:
@foo = external globalconst i8
define i32 @f(i32 %x) {
%1 = lshr i32 %x, zext i8 @foo to i32
%2 = and i32 %1, 1
ret i32 %2
}
These produce a pair of object files which when linked together produces a
function f that selects bit "foo" of its argument. I can link m2.ll with
some other object file with some other definition of foo to produce a
function f that selects some other bit. That other object file can be
produced independently of m2, which means that I can change the selected
bit without needing to recompile m2.
How is this more useful than a regular constant GlobalVariable? Let's look
at what the asm code for m2.ll would hypothetically look like:
.globl f
f:
shrl $foo, %edi
andl $1, %edi
movl %edi, %eax
retq
Compare this to the case where foo is a regular GlobalVariable which we
load from in f:
f:
movb foo(%rip), %cl
shrl %cl, %edi
andl $1, %edi
movl %edi, %eax
retq
As you can see there is a clear win in code size and register pressure.
Thanks,
--
--
Peter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161024/61293948/attachment-0001.html>
More information about the llvm-dev
mailing list