diff options
author | James Molloy <james.molloy@arm.com> | 2016-09-12 13:42:16 +0000 |
---|---|---|
committer | James Molloy <james.molloy@arm.com> | 2016-09-12 13:42:16 +0000 |
commit | 8f82d45ff418f460baa4f7dd38374f7adb690805 (patch) | |
tree | a7f2e2290874dac42bae262f7c15925ba2d36564 /llvm/lib/Target/ARM/ARMAsmPrinter.cpp | |
parent | a4c424654e658c7e582dbb91f09ad7ce24d8d8ef (diff) | |
download | bcm5719-llvm-8f82d45ff418f460baa4f7dd38374f7adb690805.tar.gz bcm5719-llvm-8f82d45ff418f460baa4f7dd38374f7adb690805.zip |
[ARM] Promote small global constants to constant pools
If a constant is unamed_addr and is only used within one function, we can save
on the code size and runtime cost of an indirection by changing the global's storage
to inside the constant pool. For example, instead of:
ldr r0, .CPI0
bl printf
bx lr
.CPI0: &format_string
format_string: .asciz "hello, world!\n"
We can emit:
adr r0, .CPI0
bl printf
bx lr
.CPI0: .asciz "hello, world!\n"
This can cause significant code size savings when many small strings are used in one
function (4 bytes per string).
llvm-svn: 281213
Diffstat (limited to 'llvm/lib/Target/ARM/ARMAsmPrinter.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index d19a2b9466f..2a20c4789fa 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -96,6 +96,13 @@ void ARMAsmPrinter::EmitXXStructor(const DataLayout &DL, const Constant *CV) { OutStreamer->EmitValue(E, Size); } +void ARMAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { + if (PromotedGlobals.count(GV)) + // The global was promoted into a constant pool. It should not be emitted. + return; + AsmPrinter::EmitGlobalVariable(GV); +} + /// runOnMachineFunction - This uses the EmitInstruction() /// method to print assembly for each instruction. /// @@ -108,6 +115,12 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { const Function* F = MF.getFunction(); const TargetMachine& TM = MF.getTarget(); + // Collect all globals that had their storage promoted to a constant pool. + // Functions are emitted before variables, so this accumulates promoted + // globals from all functions in PromotedGlobals. + for (auto *GV : AFI->getGlobalsPromotedToConstantPool()) + PromotedGlobals.insert(GV); + // Calculate this function's optimization goal. unsigned OptimizationGoal; if (F->hasFnAttribute(Attribute::OptimizeNone)) |