summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-06-23 16:53:59 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-06-23 16:53:59 +0000
commitbb2fcd19214fe8fda3867e5fef320ae27d9e1fc0 (patch)
tree67f59398da712cc78ed82da4e082ba42b69535ac /llvm/lib
parent9ac7181a2c577dc5c0d2cddd294ac508f818d997 (diff)
downloadbcm5719-llvm-bb2fcd19214fe8fda3867e5fef320ae27d9e1fc0.tar.gz
bcm5719-llvm-bb2fcd19214fe8fda3867e5fef320ae27d9e1fc0.zip
[Hexagon] Handle decreasing of stack alignment in frame lowering
llvm-svn: 306124
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp19
-rw-r--r--llvm/lib/Target/Hexagon/HexagonFrameLowering.h2
-rw-r--r--llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp30
-rw-r--r--llvm/lib/Target/Hexagon/HexagonRegisterInfo.h2
4 files changed, 51 insertions, 2 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
index f0b7f587379..601a5d303cd 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -552,7 +552,7 @@ void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB,
auto &HRI = *HST.getRegisterInfo();
DebugLoc dl;
- unsigned MaxAlign = std::max(MFI.getMaxAlignment(), getStackAlignment());
+ unsigned MaxAlign = std::max(getMaxStackAlignment(MF), getStackAlignment());
// Calculate the total stack frame size.
// Get the number of bytes to allocate from the FrameInfo.
@@ -2354,11 +2354,26 @@ void HexagonFrameLowering::expandAlloca(MachineInstr *AI,
}
}
+unsigned
+HexagonFrameLowering::getMaxStackAlignment(const MachineFunction &MF) const {
+ const MachineFrameInfo &MFI = MF.getFrameInfo();
+ // MFI's MaxAlignment can only grow, but we can actually reduce it
+ // for vector spills.
+ unsigned MaxAlign = 0;
+ for (int i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
+ if (MFI.isDeadObjectIndex(i))
+ continue;
+ unsigned Align = MFI.getObjectAlignment(i);
+ MaxAlign = std::max(MaxAlign, Align);
+ }
+ return MaxAlign;
+}
+
bool HexagonFrameLowering::needsAligna(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
if (!MFI.hasVarSizedObjects())
return false;
- unsigned MaxA = MFI.getMaxAlignment();
+ unsigned MaxA = getMaxStackAlignment(MF);
if (MaxA <= getStackAlignment())
return false;
return true;
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
index 529a61d4a5b..29bafaee78c 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
@@ -82,6 +82,8 @@ public:
const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI)
const override;
+ unsigned getMaxStackAlignment(const MachineFunction &MF) const;
+
bool needsAligna(const MachineFunction &MF) const;
const MachineInstr *getAlignaInstr(const MachineFunction &MF) const;
diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
index 1fc157900ed..b44177b0a35 100644
--- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
@@ -283,6 +283,36 @@ bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF)
return MF.getSubtarget<HexagonSubtarget>().getFrameLowering()->hasFP(MF);
}
+// The stack alignment on Hexagon can actually decrease in some cases,
+// specifically in some subset of cases when a variable-sized stack object
+// is present.
+// The issue is two-fold:
+// First of all, if there is a variable-sized object and the stack needs
+// extra alignment (due to pre-existing local objects), then a special
+// register will be reserved up front, acting as the aligned stack pointer
+// (call it AP). This register is only guaranteed to be live for accessing
+// these pre-existing local objects (the ones with the higher alignment).
+// Now, if the register allocator introduces vector register spills, their
+// spill slots will initially have an alignment equal to the register size,
+// which is higher than the normal stack alignment. Ideally, they should be
+// loaded/stored using AP, but AP may not be available at all required
+// places. To avoid this issue, the vector spill slots will have their
+// alignment lowered to 8, and they will be loaded/stored using unaligned
+// instructions.
+//
+// The lowering of the stack alignment may happen if the stack had a
+// variable-sized object, but otherwise retained its default alignment
+// up until register allocation. If the register allocator introduces
+// a vector spill, it will cause the max stack alignment to grow
+// (inside MachineFrameInfo). When the alignment of the spills is reset
+// back to the default stack alignment, MFI's max stack alignment will
+// not reflect that (since it cannot be lowered). Relying on that during
+// frame lowering will cause an unnecessary stack realignment.
+bool HexagonRegisterInfo::needsStackRealignment(const MachineFunction &MF)
+ const {
+ auto &HFI = *MF.getSubtarget<HexagonSubtarget>().getFrameLowering();
+ return HFI.getMaxStackAlignment(MF) > HFI.getStackAlignment();
+}
unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const {
return Hexagon::R6;
diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.h b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.h
index 5f65fad2cc0..568bdd0b806 100644
--- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.h
+++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.h
@@ -55,6 +55,8 @@ public:
return true;
}
+ bool needsStackRealignment(const MachineFunction &MF) const;
+
/// Returns true if the frame pointer is valid.
bool useFPForScavengingIndex(const MachineFunction &MF) const override;
OpenPOWER on IntegriCloud