summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
diff options
context:
space:
mode:
authorVasileios Kalintiris <Vasileios.Kalintiris@imgtec.com>2015-06-02 13:14:46 +0000
committerVasileios Kalintiris <Vasileios.Kalintiris@imgtec.com>2015-06-02 13:14:46 +0000
commitbb698c7d5f23474930fae702ac44ee5ab8e03781 (patch)
tree396c2a5e09d20a93b4c77957e1729d864a3094df /llvm/lib/Target/Mips/MipsRegisterInfo.cpp
parente62307421053f527e2837e7a4d1d3c246b39303f (diff)
downloadbcm5719-llvm-bb698c7d5f23474930fae702ac44ee5ab8e03781.tar.gz
bcm5719-llvm-bb698c7d5f23474930fae702ac44ee5ab8e03781.zip
[mips] Add support for dynamic stack realignment.
Summary: With this change we are able to realign the stack dynamically, whenever it contains objects with alignment requirements that are larger than the alignment specified from the given ABI. We have to use the $fp register as the frame pointer when we perform dynamic stack realignment. In complex stack frames, with variably-sized objects, we reserve additionally the callee-saved register $s7 as the base pointer in order to reference locals. Reviewers: dsanders Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8633 llvm-svn: 238829
Diffstat (limited to 'llvm/lib/Target/Mips/MipsRegisterInfo.cpp')
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterInfo.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
index f72fb4d622e..f6647e6a846 100644
--- a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
@@ -21,6 +21,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/IR/Constants.h"
@@ -178,6 +179,15 @@ getReservedRegs(const MachineFunction &MF) const {
else {
Reserved.set(Mips::FP);
Reserved.set(Mips::FP_64);
+
+ // Reserve the base register if we need to both realign the stack and
+ // allocate variable-sized objects at runtime. This should test the
+ // same conditions as MipsFrameLowering::hasBP().
+ if (needsStackRealignment(MF) &&
+ MF.getFrameInfo()->hasVarSizedObjects()) {
+ Reserved.set(Mips::S7);
+ Reserved.set(Mips::S7_64);
+ }
}
}
@@ -271,6 +281,67 @@ getFrameRegister(const MachineFunction &MF) const {
else
return TFI->hasFP(MF) ? (IsN64 ? Mips::FP_64 : Mips::FP) :
(IsN64 ? Mips::SP_64 : Mips::SP);
+}
+bool MipsRegisterInfo::canRealignStack(const MachineFunction &MF) const {
+ const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
+ unsigned FP = Subtarget.isGP32bit() ? Mips::FP : Mips::FP_64;
+ unsigned BP = Subtarget.isGP32bit() ? Mips::S7 : Mips::S7_64;
+
+ // Support dynamic stack realignment only for targets with standard encoding.
+ if (!Subtarget.hasStandardEncoding())
+ return false;
+
+ // We can't perform dynamic stack realignment if we can't reserve the
+ // frame pointer register.
+ if (!MF.getRegInfo().canReserveReg(FP))
+ return false;
+
+ // We can realign the stack if we know the maximum call frame size and we
+ // don't have variable sized objects.
+ if (Subtarget.getFrameLowering()->hasReservedCallFrame(MF))
+ return true;
+
+ // We have to reserve the base pointer register in the presence of variable
+ // sized objects.
+ return MF.getRegInfo().canReserveReg(BP);
}
+bool MipsRegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
+ const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
+
+ bool CanRealign = canRealignStack(MF);
+
+ // Avoid realigning functions that explicitly do not want to be realigned.
+ // Normally, we should report an error when a function should be dynamically
+ // realigned but also has the attribute no-realign-stack. Unfortunately,
+ // with this attribute, MachineFrameInfo clamps each new object's alignment
+ // to that of the stack's alignment as specified by the ABI. As a result,
+ // the information of whether we have objects with larger alignment
+ // requirement than the stack's alignment is already lost at this point.
+ if (MF.getFunction()->hasFnAttribute("no-realign-stack"))
+ return false;
+
+ const Function *F = MF.getFunction();
+ if (F->hasFnAttribute(Attribute::StackAlignment)) {
+#ifdef DEBUG
+ if (!CanRealign)
+ DEBUG(dbgs() << "It's not possible to realign the stack of the function: "
+ << F->getName() << "\n");
+#endif
+ return CanRealign;
+ }
+
+ unsigned StackAlignment = Subtarget.getFrameLowering()->getStackAlignment();
+ if (MFI->getMaxAlignment() > StackAlignment) {
+#ifdef DEBUG
+ if (!CanRealign)
+ DEBUG(dbgs() << "It's not possible to realign the stack of the function: "
+ << F->getName() << "\n");
+#endif
+ return CanRealign;
+ }
+
+ return false;
+}
OpenPOWER on IntegriCloud