[LLVMdev] Best way to clean up empty global_ctors
Nico Weber
thakis at chromium.org
Wed Apr 30 17:09:24 PDT 2014
I'm not sure I understand what you mean. The unoptimized IR is
@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{
i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
define internal void @_GLOBAL__I_a() section
"__TEXT,__StaticInit,regular,pure_instructions" {
entry:
call void @__cxx_global_var_init()
ret void
}
define internal void @__cxx_global_var_init() section
"__TEXT,__StaticInit,regular,pure_instructions" {
entry:
%0 = load i32* @_ZN3Bar18LINKER_INITIALIZEDE, align 4
call void @_ZN3FooC1E17LinkerInitialized(%class.Foo* @foo, i32 %0)
ret void
}
; Function Attrs: ssp uwtable
define linkonce_odr void
@_ZN3FooC1E17LinkerInitialized(%class.Foo* %this, i32) unnamed_addr #0
align 2 {
entry:
%this.addr = alloca %class.Foo*, align 8
%.addr = alloca i32, align 4
store %class.Foo* %this, %class.Foo** %this.addr, align 8
store i32 %0, i32* %.addr, align 4
%this1 = load %class.Foo** %this.addr
%1 = load i32* %.addr, align 4
call void @_ZN3FooC2E17LinkerInitialized(%class.Foo* %this1, i32 %1)
ret void
}
…which is quite a bit of stuff. But other passes successfully reduce this to
@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{
i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
; Function Attrs: nounwind readnone
define internal void @_GLOBAL__I_a() #1 section
"__TEXT,__StaticInit,regular,pure_instructions" {
entry:
ret void
}
which is much nicer, and globalopt is able to reduce the latter bit to
an empty global_ctors list – the problem is that it runs before the IR
is optimized that much. Just doing globalopt once more (or doing just
the global_ctor bits of globalopt once more) is enough to fix the
problem. The existing machinery seems to do all that's needed, it just
needs to be used in a slightly different order as far as I understand.
On Wed, Apr 30, 2014 at 4:59 PM, Reid Kleckner <rnk at google.com> wrote:
> Can we strengthen globalopt to symbolically execute at most one direct call
> to any given function, or is that crazy talk?
>
>
> On Wed, Apr 30, 2014 at 4:48 PM, Nico Weber <thakis at chromium.org> wrote:
>>
>> Hi,
>>
>> I'd like to fix PR19590, which is about llvm.global_ctors containing
>> functions that end up being empty after optimization (which causes the
>> linker to add useless init_array entries to the output binary).
>> globalopt removes empty functions from llvm.global_ctors, but by the
>> time the function becomes empty globalopt has already run and it
>> doesn't run again.
>>
>> I'm wondering what the best fix is:
>> 1. Should globalopt run once more after all other passes have run?
>> 2. Or should the llvm.global_ctors optimization code in globalopt be
>> moved into a helper function somewhere that's called from both
>> globalopt and a new optimization pass cdtoropt that does nothing but
>> remove empty functions from llvm.global_ctors and llvm.global_dtors?
>> Then only this new pass would be added after all other passes. (This
>> new pass should run very quickly, it doesn't have to do much.)
>>
>> Thanks for any advice,
>> Nico
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>
More information about the llvm-dev
mailing list