summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/MachineFunction.cpp
diff options
context:
space:
mode:
authorJames Molloy <james.molloy@arm.com>2016-09-26 07:26:24 +0000
committerJames Molloy <james.molloy@arm.com>2016-09-26 07:26:24 +0000
commit9abb2fa5bb66785379c5b4cb46426cb61ee01c93 (patch)
treee127550fa15cdf122cbceac62e705ca84f8d530a /llvm/lib/CodeGen/MachineFunction.cpp
parent9559f04b9db004375b10f79e30d0e321c62ab222 (diff)
downloadbcm5719-llvm-9abb2fa5bb66785379c5b4cb46426cb61ee01c93.tar.gz
bcm5719-llvm-9abb2fa5bb66785379c5b4cb46426cb61ee01c93.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). This recommit contains fixes for a nasty bug related to fast-isel fallback - because fast-isel doesn't know about this optimization, if it runs and emits references to a string that we inline (because fast-isel fell back to SDAG) we will end up with an inlined string and also an out-of-line string, and we won't emit the out-of-line string, causing backend failures. It also contains fixes for emitting .text relocations which made the sanitizer bots unhappy. llvm-svn: 282387
Diffstat (limited to 'llvm/lib/CodeGen/MachineFunction.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineFunction.cpp13
1 files changed, 10 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index 90ca5206c74..f6da4b15ccf 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -898,13 +898,20 @@ MachineConstantPoolEntry::getSectionKind(const DataLayout *DL) const {
}
MachineConstantPool::~MachineConstantPool() {
+ // A constant may be a member of both Constants and MachineCPVsSharingEntries,
+ // so keep track of which we've deleted to avoid double deletions.
+ DenseSet<MachineConstantPoolValue*> Deleted;
for (unsigned i = 0, e = Constants.size(); i != e; ++i)
- if (Constants[i].isMachineConstantPoolEntry())
+ if (Constants[i].isMachineConstantPoolEntry()) {
+ Deleted.insert(Constants[i].Val.MachineCPVal);
delete Constants[i].Val.MachineCPVal;
+ }
for (DenseSet<MachineConstantPoolValue*>::iterator I =
MachineCPVsSharingEntries.begin(), E = MachineCPVsSharingEntries.end();
- I != E; ++I)
- delete *I;
+ I != E; ++I) {
+ if (Deleted.count(*I) == 0)
+ delete *I;
+ }
}
/// Test whether the given two constants can be allocated the same constant pool
OpenPOWER on IntegriCloud