diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/MipsRegisterInfo.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Mips/MipsRegisterInfo.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Target/Mips/MipsRegisterInfo.cpp b/contrib/llvm/lib/Target/Mips/MipsRegisterInfo.cpp index f72fb4d..f6647e6 100644 --- a/contrib/llvm/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/contrib/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; +} |