Enabling merging of extern globals appears to be generally either beneficial or harmless. On some benchmarks suites (on Cortex-M4F, Cortex-A9, and Cortex-A57) it gives improvements in the 1-5% range, but in the rest the overall effect is zero.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
So, if this is positive performance-wise, I'm fine with it, but I don't think you can enable it on all platforms (at least not without testing).
For instance, this won't work on Mach-O, most importantly because aliases are just regular symbols, and symbols are (usually) assumed atomic; __MergedGlobals wouldn't be in this case.
On a related note, on targets where aliases aren't an issue, I think we should use them all the time, even when merging internal globals. It lets us
- get rid of cryptic _MergedGlobals symbols
- use the source symbols instead
- simplify some DebugInfo weirdness (you won't need a 'plus' expression if you can just reference a symbol).
That's where I discovered the Mach-O symbol alias issue!
lib/Target/ARM/ARMTargetMachine.cpp | ||
---|---|---|
354 ↗ | (On Diff #29100) | Even with the comment, can you add: /*MergeExternalByDefault=*/true |
Do you know where I could find out more about this? Looking at the Apple Mach-O documentation (https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/MachORuntime/index.html) I don't see anything like this. What exactly do you mean by 'atomic' here?
Looking at the Mach-O object output of global-merge-external.ll I do see a couple of oddities (based on my understanding of the above document), but they appear to happen whether extern global merging is enabled or not:
- Both zero-initialized variables and a zero-initialized MergedGlobals go in a section named __common, but I would expect them to go in a section named __data: https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/Assembler/040-Assembler_Directives/asm_directives.html#//apple_ref/doc/uid/TP30000823-CJBDFFDF says of __data "The compiler places all non-const initialized data (even initialized to zero) in this section".
- Global variables and global aliases end up with symbol flag REFERENCE_FLAG_UNDEFINED_NON_LAZY but I would expect REFERENCE_FLAG_DEFINED.
New patch makes the suggested change. I've not yet added anything to disable it on Mach-O because it would be nice to know first why exactly it wouldn't work on Mach-O.
With the ".subsections_via_symbols" directive, each section is split up into "subsections", each one associated with a single symbol. The linker is free to strip or reorder these subsections. Since aliases are just regular symbols, aliases into _MergedGlobals could potentially cause it to be broken apart in the final binary, thus making the offset-addressing code invalid (since the code should only reference the first symbol, the rest might get dead-stripped).
Hope that helps, sorry for the delay!
Ah, I see, and that directive gets emitted by ARMAsmPrinter::EmitEndOfAsmFile. I'll upload a new patch that disables merging of globals on Mach-O.