summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2013-12-02 14:46:26 +0000
committerTim Northover <tnorthover@apple.com>2013-12-02 14:46:26 +0000
commitad249171e4fa718290be2f1b276c1b7864dd27f7 (patch)
tree8c84c193493f3b420f1a26d015fed7cbe537eaa8
parentc7cf4869a726ea8f36680d4ef220f9902075dee8 (diff)
downloadllvm-ad249171e4fa718290be2f1b276c1b7864dd27f7.tar.gz
llvm-ad249171e4fa718290be2f1b276c1b7864dd27f7.tar.bz2
llvm-ad249171e4fa718290be2f1b276c1b7864dd27f7.tar.xz
ARM: decide whether to use movw/movt based on "minsize" attribute.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196102 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp6
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.h3
-rw-r--r--lib/Target/ARM/ARMFrameLowering.cpp5
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp3
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp4
-rw-r--r--lib/Target/ARM/ARMSubtarget.h7
-rw-r--r--lib/Target/ARM/Thumb1FrameLowering.cpp6
-rw-r--r--lib/Target/ARM/Thumb2SizeReduction.cpp3
-rw-r--r--test/CodeGen/ARM/minsize-litpools.ll26
9 files changed, 49 insertions, 14 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 6e7d1b23ad..06cef6d603 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -1859,12 +1859,12 @@ void llvm::emitARMRegPlusImmediate(MachineBasicBlock &MBB,
}
}
-bool llvm::tryFoldSPUpdateIntoPushPop(MachineFunction &MF,
- MachineInstr *MI,
+bool llvm::tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget,
+ MachineFunction &MF, MachineInstr *MI,
unsigned NumBytes) {
// This optimisation potentially adds lots of load and store
// micro-operations, it's only really a great benefit to code-size.
- if (!MF.getFunction()->hasFnAttribute(Attribute::MinSize))
+ if (!Subtarget.isMinSize())
return false;
// If only one register is pushed/popped, LLVM can use an LDR/STR
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.h b/lib/Target/ARM/ARMBaseInstrInfo.h
index 93e59647d2..98b4c09a36 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.h
+++ b/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -417,7 +417,8 @@ void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
/// NumBytes. This can save a few bytes per function in code-size, but
/// obviously generates more memory traffic. As such, it only takes
/// effect in functions being optimised for size.
-bool tryFoldSPUpdateIntoPushPop(MachineFunction &MF, MachineInstr *MI,
+bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget,
+ MachineFunction &MF, MachineInstr *MI,
unsigned NumBytes);
/// rewriteARMFrameIndex / rewriteT2FrameIndex -
diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp
index 3e72d3690a..196f58dc5e 100644
--- a/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/lib/Target/ARM/ARMFrameLowering.cpp
@@ -256,7 +256,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
if (NumBytes) {
// Adjust SP after all the callee-save spills.
- if (tryFoldSPUpdateIntoPushPop(MF, LastPush, NumBytes))
+ if (tryFoldSPUpdateIntoPushPop(STI, MF, LastPush, NumBytes))
FramePtrOffsetInPush += NumBytes;
else
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes,
@@ -434,7 +434,8 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
ARM::SP)
.addReg(FramePtr));
}
- } else if (NumBytes && !tryFoldSPUpdateIntoPushPop(MF, FirstPop, NumBytes))
+ } else if (NumBytes &&
+ !tryFoldSPUpdateIntoPushPop(STI, MF, FirstPop, NumBytes))
emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
// Increment past our save areas.
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 2794852941..b7f0f6f67a 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -1745,8 +1745,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// FIXME: handle tail calls differently.
unsigned CallOpc;
- bool HasMinSizeAttr = MF.getFunction()->getAttributes().
- hasAttribute(AttributeSet::FunctionIndex, Attribute::MinSize);
+ bool HasMinSizeAttr = Subtarget->isMinSize();
if (Subtarget->isThumb()) {
if ((!isDirect || isARMFunc) && !Subtarget->hasV5TOps())
CallOpc = ARMISD::CALL_NOLINK;
diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp
index a11629852a..e907812039 100644
--- a/lib/Target/ARM/ARMSubtarget.cpp
+++ b/lib/Target/ARM/ARMSubtarget.cpp
@@ -102,6 +102,7 @@ void ARMSubtarget::initializeEnvironment() {
HasVFPv4 = false;
HasFPARMv8 = false;
HasNEON = false;
+ MinSize = false;
UseNEONForSinglePrecisionFP = false;
UseMulOps = UseFusedMulOps;
SlowFPVMLx = false;
@@ -151,6 +152,9 @@ void ARMSubtarget::resetSubtargetFeatures(const MachineFunction *MF) {
initializeEnvironment();
resetSubtargetFeatures(CPU, FS);
}
+
+ MinSize =
+ FnAttrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::MinSize);
}
void ARMSubtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) {
diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h
index ca5ba8541f..d6e8c81fb7 100644
--- a/lib/Target/ARM/ARMSubtarget.h
+++ b/lib/Target/ARM/ARMSubtarget.h
@@ -64,6 +64,10 @@ protected:
bool HasFPARMv8;
bool HasNEON;
+ /// MinSize - True if the function being compiled has the "minsize" attribute
+ /// and should be optimised for size at the expense of speed.
+ bool MinSize;
+
/// UseNEONForSinglePrecisionFP - if the NEONFP attribute has been
/// specified. Use the method useNEONForSinglePrecisionFP() to
/// determine if NEON should actually be used.
@@ -270,6 +274,7 @@ public:
bool hasCrypto() const { return HasCrypto; }
bool hasCRC() const { return HasCRC; }
bool hasVirtualization() const { return HasVirtualization; }
+ bool isMinSize() const { return MinSize; }
bool useNEONForSinglePrecisionFP() const {
return hasNEON() && UseNEONForSinglePrecisionFP; }
@@ -327,7 +332,7 @@ public:
bool isR9Reserved() const { return IsR9Reserved; }
- bool useMovt() const { return UseMovt && hasV6T2Ops(); }
+ bool useMovt() const { return UseMovt && !isMinSize(); }
bool supportsTailCall() const { return SupportsTailCall; }
bool allowsUnalignedMem() const { return AllowsUnalignedMem; }
diff --git a/lib/Target/ARM/Thumb1FrameLowering.cpp b/lib/Target/ARM/Thumb1FrameLowering.cpp
index cfb33f5b82..0a05c0b849 100644
--- a/lib/Target/ARM/Thumb1FrameLowering.cpp
+++ b/lib/Target/ARM/Thumb1FrameLowering.cpp
@@ -165,7 +165,7 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
NumBytes = DPRCSOffset;
int FramePtrOffsetInBlock = 0;
- if (tryFoldSPUpdateIntoPushPop(MF, prior(MBBI), NumBytes)) {
+ if (tryFoldSPUpdateIntoPushPop(STI, MF, prior(MBBI), NumBytes)) {
FramePtrOffsetInBlock = NumBytes;
NumBytes = 0;
}
@@ -291,9 +291,9 @@ void Thumb1FrameLowering::emitEpilogue(MachineFunction &MF,
&MBB.front() != MBBI &&
prior(MBBI)->getOpcode() == ARM::tPOP) {
MachineBasicBlock::iterator PMBBI = prior(MBBI);
- if (!tryFoldSPUpdateIntoPushPop(MF, PMBBI, NumBytes))
+ if (!tryFoldSPUpdateIntoPushPop(STI, MF, PMBBI, NumBytes))
emitSPUpdate(MBB, PMBBI, TII, dl, *RegInfo, NumBytes);
- } else if (!tryFoldSPUpdateIntoPushPop(MF, MBBI, NumBytes))
+ } else if (!tryFoldSPUpdateIntoPushPop(STI, MF, MBBI, NumBytes))
emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, NumBytes);
}
}
diff --git a/lib/Target/ARM/Thumb2SizeReduction.cpp b/lib/Target/ARM/Thumb2SizeReduction.cpp
index 4795aae12f..3ef822d94f 100644
--- a/lib/Target/ARM/Thumb2SizeReduction.cpp
+++ b/lib/Target/ARM/Thumb2SizeReduction.cpp
@@ -1012,8 +1012,7 @@ bool Thumb2SizeReduce::runOnMachineFunction(MachineFunction &MF) {
AttributeSet FnAttrs = MF.getFunction()->getAttributes();
OptimizeSize = FnAttrs.hasAttribute(AttributeSet::FunctionIndex,
Attribute::OptimizeForSize);
- MinimizeSize = FnAttrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::MinSize);
+ MinimizeSize = STI->isMinSize();
BlockInfo.clear();
BlockInfo.resize(MF.getNumBlockIDs());
diff --git a/test/CodeGen/ARM/minsize-litpools.ll b/test/CodeGen/ARM/minsize-litpools.ll
new file mode 100644
index 0000000000..d5cd2a9b72
--- /dev/null
+++ b/test/CodeGen/ARM/minsize-litpools.ll
@@ -0,0 +1,26 @@
+; RUN: llc -mtriple=thumbv7s %s -o - | FileCheck %s
+; RUN: llc -mtriple=armv7s %s -o - | FileCheck %s
+
+; CodeGen should be able to set and reset the MinSize subtarget-feature, and
+; make use of it in deciding whether to use MOVW/MOVT for global variables or a
+; lit-pool load (saving roughly 2 bytes of code).
+
+@var = global i32 0
+
+define i32 @small_global() minsize {
+; CHECK-LABEL: small_global:
+; CHECK: ldr r[[GLOBDEST:[0-9]+]], {{.?LCPI0_0}}
+; CHECK: ldr r0, [r[[GLOBDEST]]]
+
+ %val = load i32* @var
+ ret i32 %val
+}
+
+define i32 @big_global() {
+; CHECK-LABEL: big_global:
+; CHECK: movw [[GLOBDEST:r[0-9]+]], :lower16:var
+; CHECK: movt [[GLOBDEST]], :upper16:var
+
+ %val = load i32* @var
+ ret i32 %val
+}