rnk added subscribers: aeubanks, hans, rsmith.
rnk added a comment.

+@rsmith @hans @aeubanks

I think this would be an unfortunate code size and startup time regression for 
Itanium C++ inline variables. The existing code was written under the 
assumption that vague linkage (GVA_DiscardableODR) implies no initialization 
ordering, but I think you've found a valid counterexample.

> specifically when init_array is not used

Can you elaborate on why that is? Here's what I remember, and what I guess is 
happening. ELF has two initializer schemes: .init_array and .ctors. They are 
essentially equivalent, they are both arrays of function pointers, but one is 
called in reverse order and the other is called in forward order. The compiler 
knows which scheme is in use and it is controlled by -fuse-init-array.

The LLVM IR langref says that llvm.global_ctors are called in ascending 
priority order, and the order between initializers is not defined. That's not 
very helpful and often doesn't reflect reality. I wonder if we could do two 
things, perhaps separately:

1. emit llvm.global_ctors so that they are called in order of appearance in the 
IR array (is this not already true?)
2. define the order of initialization in LangRef

With the first change in place, we can be confident that so long as all 
includers of the `StaticsClass` in the test emit both initializers in the 
correct order, no matter which initializers prevail, they will be called in the 
correct order. Of course, this could break users relying on the existing 
ordering, nevermind that it is explicitly documented as undefined.

The second change is only a documentation change, but I would like to find a 
way to justify what LLVM does in GlobalOpt. GlobalOpt can effectively fold a 
dynamic initializer to constant memory in certain cases. That can only ever 
have the effect of making an initializer run earlier. As long as no 
initializers depend on observing uninitialized globals, that should be safe. 
The guarantee that we want to provide is that, for each initializer, all 
initializers prior to it in the global_ctors array will have run when it runs. 
Initializers that appear later may run earlier. Hopefully that covers both the 
usual way that .init_array sections are linked together and the way globalopt 
optimizes dynamic initialization.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103495/new/

https://reviews.llvm.org/D103495

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to