Leaf functions which do not save CSRs can be frameless even with -disable-fp-elim.
[oota-llvm.git] / lib / Target / ARM / ARMBaseRegisterInfo.cpp
index ca0bc4c675eb904d97c24f5c8c3430e91c77ee15..12fbb5dc03eafa47c86805c91b8cc0b876b8cb5d 100644 (file)
@@ -1,4 +1,4 @@
-//===- ARMBaseRegisterInfo.cpp - ARM Register Information -----------*- C++ -*-===//
+//===- ARMBaseRegisterInfo.cpp - ARM Register Information -------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -224,8 +224,8 @@ BitVector ARMBaseRegisterInfo::getReservedRegs(const MachineFunction &MF) const
   return Reserved;
 }
 
-bool
-ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const {
+bool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF,
+                                        unsigned Reg) const {
   switch (Reg) {
   default: break;
   case ARM::SP:
@@ -243,7 +243,8 @@ ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) cons
   return false;
 }
 
-const TargetRegisterClass *ARMBaseRegisterInfo::getPointerRegClass() const {
+const TargetRegisterClass *
+ARMBaseRegisterInfo::getPointerRegClass(unsigned Kind) const {
   return &ARM::GPRRegClass;
 }
 
@@ -439,6 +440,13 @@ bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
           MFI->isFrameAddressTaken());
 }
 
+bool ARMBaseRegisterInfo::hasStackFrame(const MachineFunction &MF) const {
+  const MachineFrameInfo *MFI = MF.getFrameInfo();
+  if (NoFramePointerElim && MFI->hasCalls())
+    return true;
+  return MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken();
+}
+
 /// estimateStackSize - Estimate and return the size of the frame.
 static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
   const MachineFrameInfo *FFI = MF.getFrameInfo();
@@ -461,27 +469,31 @@ static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
 /// estimateRSStackSizeLimit - Look at each instruction that references stack
 /// frames and return the stack size limit beyond which some of these
 /// instructions will require scratch register during their expansion later.
-static unsigned estimateRSStackSizeLimit(MachineFunction &MF,
-                                         const ARMBaseInstrInfo &TII) {
+unsigned
+ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const {
   unsigned Limit = (1 << 12) - 1;
-  for (MachineFunction::iterator BB = MF.begin(),E = MF.end();BB != E; ++BB) {
-    for (MachineBasicBlock::iterator I= BB->begin(); I != BB->end(); ++I) {
-      for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
-        if (I->getOperand(i).isFI()) {
-          unsigned Opcode = I->getOpcode();
-          const TargetInstrDesc &Desc = TII.get(Opcode);
-          unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
-          if (AddrMode == ARMII::AddrMode3 ||
-              AddrMode == ARMII::AddrModeT2_i8) {
-            return (1 << 8) - 1;
-          } else if (AddrMode == ARMII::AddrMode5 ||
-                     AddrMode == ARMII::AddrModeT2_i8s4) {
-            unsigned ThisLimit = ((1 << 8) - 1) * 4;
-            if (ThisLimit < Limit)
-              Limit = ThisLimit;
-          }
-          break; // At most one FI per instruction
-        }
+  for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) {
+    for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
+         I != E; ++I) {
+      for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
+        if (!I->getOperand(i).isFI()) continue;
+
+        const TargetInstrDesc &Desc = TII.get(I->getOpcode());
+        unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
+        if (AddrMode == ARMII::AddrMode3 ||
+            AddrMode == ARMII::AddrModeT2_i8)
+          return (1 << 8) - 1;
+
+        if (AddrMode == ARMII::AddrMode5 ||
+            AddrMode == ARMII::AddrModeT2_i8s4)
+          Limit = std::min(Limit, ((1U << 8) - 1) * 4);
+
+        if (AddrMode == ARMII::AddrModeT2_i12 && hasFP(MF))
+          // When the stack offset is negative, we will end up using
+          // the i8 instructions instead.
+          return (1 << 8) - 1;
+        break; // At most one FI per instruction
+      }
     }
   }
 
@@ -584,7 +596,7 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
   }
 
   bool ExtraCSSpill = false;
-  if (!CanEliminateFrame || hasFP(MF)) {
+  if (!CanEliminateFrame || hasStackFrame(MF)) {
     AFI->setHasStackFrame(true);
 
     // If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled.
@@ -640,7 +652,7 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
     // register scavenging.
     if (RS && !ExtraCSSpill && !AFI->isThumb1OnlyFunction()) {
       MachineFrameInfo  *MFI = MF.getFrameInfo();
-      if (estimateStackSize(MF, MFI) >= estimateRSStackSizeLimit(MF, TII)) {
+      if (estimateStackSize(MF, MFI) >= estimateRSStackSizeLimit(MF)) {
         // If any non-reserved CS register isn't spilled, just spill one or two
         // extra. That should take care of it!
         unsigned NumExtras = TargetAlign / 4;
@@ -898,7 +910,8 @@ emitLoadConstPool(MachineBasicBlock &MBB,
                   unsigned PredReg) const {
   MachineFunction &MF = *MBB.getParent();
   MachineConstantPool *ConstantPool = MF.getConstantPool();
-  Constant *C = ConstantInt::get(Type::Int32Ty, Val);
+  Constant *C =
+        ConstantInt::get(Type::getInt32Ty(MF.getFunction()->getContext()), Val);
   unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
 
   BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp))
@@ -1230,7 +1243,7 @@ static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
 }
 
 static bool isCSRestore(MachineInstr *MI,
-                        const ARMBaseInstrInfo &TII, 
+                        const ARMBaseInstrInfo &TII,
                         const unsigned *CSRegs) {
   return ((MI->getOpcode() == (int)ARM::FLDD ||
            MI->getOpcode() == (int)ARM::LDR ||
@@ -1284,17 +1297,21 @@ emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
           AFI->getDPRCalleeSavedAreaOffset()||
           hasFP(MF)) {
         if (NumBytes) {
-          unsigned SUBriOpc = isARM ? ARM::SUBri : ARM::t2SUBri;
-          BuildMI(MBB, MBBI, dl, TII.get(SUBriOpc), ARM::SP)
-            .addReg(FramePtr)
-            .addImm(NumBytes)
-            .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
+          if (isARM)
+            emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, FramePtr, -NumBytes,
+                                    ARMCC::AL, 0, TII);
+          else
+            emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, FramePtr, -NumBytes,
+                                    ARMCC::AL, 0, TII);
         } else {
           // Thumb2 or ARM.
-          unsigned MOVrOpc = isARM ? ARM::MOVr : ARM::t2MOVr;
-          BuildMI(MBB, MBBI, dl, TII.get(MOVrOpc), ARM::SP)
-            .addReg(FramePtr)
-            .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
+          if (isARM)
+            BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP)
+              .addReg(FramePtr)
+              .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
+          else
+            BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), ARM::SP)
+              .addReg(FramePtr);
         }
       }
     } else if (NumBytes)