XMM6-XMM15 are callee-saved on Win64. Patch by Nicolas Capens!
[oota-llvm.git] / lib / Target / X86 / X86RegisterInfo.cpp
index 111b0e0d28fa40c50f2153609ea120357208367a..e86c6be0dd389fcbf39844b814b084522092c092 100644 (file)
@@ -25,6 +25,7 @@
 #include "llvm/CodeGen/ValueTypes.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineLocation.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
@@ -36,6 +37,7 @@
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Compiler.h"
 using namespace llvm;
 
 X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm,
@@ -157,6 +159,14 @@ X86RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
 
 const unsigned *
 X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
+  bool callsEHReturn = false;
+
+  if (MF) {
+    const MachineFrameInfo *MFI = MF->getFrameInfo();
+    const MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+    callsEHReturn = (MMI ? MMI->callsEHReturn() : false);
+  }
+
   static const unsigned CalleeSavedRegs32Bit[] = {
     X86::ESI, X86::EDI, X86::EBX, X86::EBP,  0
   };
@@ -169,29 +179,39 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
     X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
   };
 
+  static const unsigned CalleeSavedRegs64EHRet[] = {
+    X86::RAX, X86::RDX, X86::RBX, X86::R12,
+    X86::R13, X86::R14, X86::R15, X86::RBP, 0
+  };
+
   static const unsigned CalleeSavedRegsWin64[] = {
-    X86::RBX, X86::RBP, X86::RDI, X86::RSI,
-    X86::R12, X86::R13, X86::R14, X86::R15, 0
+    X86::RBX,   X86::RBP,   X86::RDI,   X86::RSI,
+    X86::R12,   X86::R13,   X86::R14,   X86::R15,
+    X86::XMM6,  X86::XMM7,  X86::XMM8,  X86::XMM9,
+    X86::XMM10, X86::XMM11, X86::XMM12, X86::XMM13,
+    X86::XMM14, X86::XMM15, 0
   };
 
   if (Is64Bit) {
     if (IsWin64)
       return CalleeSavedRegsWin64;
     else
-      return CalleeSavedRegs64Bit;
+      return (callsEHReturn ? CalleeSavedRegs64EHRet : CalleeSavedRegs64Bit);
   } else {
-    if (MF) {
-        MachineFrameInfo *MFI = MF->getFrameInfo();
-        MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
-        if (MMI && MMI->callsEHReturn())
-          return CalleeSavedRegs32EHRet;
-    }
-    return CalleeSavedRegs32Bit;
+    return (callsEHReturn ? CalleeSavedRegs32EHRet : CalleeSavedRegs32Bit);
   }
 }
 
 const TargetRegisterClass* const*
 X86RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
+  bool callsEHReturn = false;
+
+  if (MF) {
+    const MachineFrameInfo *MFI = MF->getFrameInfo();
+    const MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+    callsEHReturn = (MMI ? MMI->callsEHReturn() : false);
+  }
+
   static const TargetRegisterClass * const CalleeSavedRegClasses32Bit[] = {
     &X86::GR32RegClass, &X86::GR32RegClass,
     &X86::GR32RegClass, &X86::GR32RegClass,  0
@@ -206,28 +226,34 @@ X86RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
     &X86::GR64RegClass, &X86::GR64RegClass,
     &X86::GR64RegClass, &X86::GR64RegClass, 0
   };
-  static const TargetRegisterClass * const CalleeSavedRegClassesWin64[] = {
+  static const TargetRegisterClass * const CalleeSavedRegClasses64EHRet[] = {
     &X86::GR64RegClass, &X86::GR64RegClass,
     &X86::GR64RegClass, &X86::GR64RegClass,
     &X86::GR64RegClass, &X86::GR64RegClass,
     &X86::GR64RegClass, &X86::GR64RegClass, 0
   };
+  static const TargetRegisterClass * const CalleeSavedRegClassesWin64[] = {
+    &X86::GR64RegClass,  &X86::GR64RegClass,
+    &X86::GR64RegClass,  &X86::GR64RegClass,
+    &X86::GR64RegClass,  &X86::GR64RegClass,
+    &X86::GR64RegClass,  &X86::GR64RegClass,
+    &X86::VR128RegClass, &X86::VR128RegClass,
+    &X86::VR128RegClass, &X86::VR128RegClass,
+    &X86::VR128RegClass, &X86::VR128RegClass,
+    &X86::VR128RegClass, &X86::VR128RegClass,
+    &X86::VR128RegClass, &X86::VR128RegClass, 0
+  };
 
   if (Is64Bit) {
     if (IsWin64)
       return CalleeSavedRegClassesWin64;
     else
-      return CalleeSavedRegClasses64Bit;
+      return (callsEHReturn ?
+              CalleeSavedRegClasses64EHRet : CalleeSavedRegClasses64Bit);
   } else {
-    if (MF) {
-        MachineFrameInfo *MFI = MF->getFrameInfo();
-        MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
-        if (MMI && MMI->callsEHReturn())
-          return CalleeSavedRegClasses32EHRet;
-    }
-    return CalleeSavedRegClasses32Bit;
+    return (callsEHReturn ?
+            CalleeSavedRegClasses32EHRet : CalleeSavedRegClasses32Bit);
   }
-
 }
 
 BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
@@ -267,8 +293,8 @@ static unsigned calculateMaxStackAlignment(const MachineFrameInfo *FFI) {
 // if frame pointer elimination is disabled.
 //
 bool X86RegisterInfo::hasFP(const MachineFunction &MF) const {
-  MachineFrameInfo *MFI = MF.getFrameInfo();
-  MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+  const MachineFrameInfo *MFI = MF.getFrameInfo();
+  const MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
 
   return (NoFramePointerElim ||
           needsStackRealignment(MF) ||
@@ -278,18 +304,12 @@ bool X86RegisterInfo::hasFP(const MachineFunction &MF) const {
 }
 
 bool X86RegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
-  MachineFrameInfo *MFI = MF.getFrameInfo();;
-
-  // FIXME: This is really really ugly, but it seems we need to decide, whether
-  // we will need stack realignment or not too early (during RA stage).
-  unsigned MaxAlign = MFI->getMaxAlignment();
-  if (!MaxAlign)
-    MaxAlign = calculateMaxStackAlignment(MFI);
+  const MachineFrameInfo *MFI = MF.getFrameInfo();;
 
   // FIXME: Currently we don't support stack realignment for functions with
   // variable-sized allocas
   return (RealignStack &&
-          (MaxAlign > StackAlign &&
+          (MFI->getMaxAlignment() > StackAlign &&
            !MFI->hasVarSizedObjects()));
 }
 
@@ -307,11 +327,9 @@ X86RegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const {
       // Skip the saved EBP
       Offset += SlotSize;
     else {
-      unsigned MaxAlign = MF.getFrameInfo()->getMaxAlignment();
-      uint64_t FrameSize =
-        (StackSize - SlotSize + MaxAlign - 1)/MaxAlign*MaxAlign;
-
-      return Offset + FrameSize - SlotSize;
+      unsigned Align = MF.getFrameInfo()->getObjectAlignment(FI);
+      assert( (-(Offset + StackSize)) % Align == 0);
+      return Offset + StackSize;
     }
 
     // FIXME: Support tail calls
@@ -349,8 +367,8 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
 
       MachineInstr *New = 0;
       if (Old->getOpcode() == X86::ADJCALLSTACKDOWN) {
-        New=BuildMI(TII.get(Is64Bit ? X86::SUB64ri32 : X86::SUB32ri), StackPtr)
-          .addReg(StackPtr).addImm(Amount);
+        New = BuildMI(MF, TII.get(Is64Bit ? X86::SUB64ri32 : X86::SUB32ri),
+                      StackPtr).addReg(StackPtr).addImm(Amount);
       } else {
         assert(Old->getOpcode() == X86::ADJCALLSTACKUP);
         // factor out the amount the callee already popped.
@@ -360,7 +378,8 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
           unsigned Opc = (Amount < 128) ?
             (Is64Bit ? X86::ADD64ri8 : X86::ADD32ri8) :
             (Is64Bit ? X86::ADD64ri32 : X86::ADD32ri);
-          New = BuildMI(TII.get(Opc), StackPtr).addReg(StackPtr).addImm(Amount);
+          New = BuildMI(MF, TII.get(Opc), StackPtr)
+            .addReg(StackPtr).addImm(Amount);
         }
       }
 
@@ -376,7 +395,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
         (Is64Bit ? X86::SUB64ri8 : X86::SUB32ri8) :
         (Is64Bit ? X86::SUB64ri32 : X86::SUB32ri);
       MachineInstr *New =
-        BuildMI(TII.get(Opc), StackPtr).addReg(StackPtr).addImm(CalleeAmt);
+        BuildMI(MF, TII.get(Opc), StackPtr).addReg(StackPtr).addImm(CalleeAmt);
       MBB.insert(I, New);
     }
   }
@@ -422,7 +441,8 @@ X86RegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
 
   // Calculate and set max stack object alignment early, so we can decide
   // whether we will need stack realignment (and thus FP).
-  unsigned MaxAlign = calculateMaxStackAlignment(FFI);
+  unsigned MaxAlign = std::max(FFI->getMaxAlignment(),
+                               calculateMaxStackAlignment(FFI));
 
   FFI->setMaxAlignment(MaxAlign);
 }
@@ -697,7 +717,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
     if (needsFrameMoves) {
       // Mark effective beginning of when frame pointer becomes valid.
       FrameLabelId = MMI->NextLabelID();
-      BuildMI(MBB, MBBI, TII.get(X86::LABEL)).addImm(FrameLabelId).addImm(0);
+      BuildMI(MBB, MBBI, TII.get(X86::DBG_LABEL)).addImm(FrameLabelId);
     }
 
     // Update EBP with the new base value...
@@ -716,7 +736,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
   if (needsFrameMoves) {
     // Mark effective beginning of when frame pointer is ready.
     ReadyLabelId = MMI->NextLabelID();
-    BuildMI(MBB, MBBI, TII.get(X86::LABEL)).addImm(ReadyLabelId).addImm(0);
+    BuildMI(MBB, MBBI, TII.get(X86::DBG_LABEL)).addImm(ReadyLabelId);
   }
 
   // Skip the callee-saved push instructions.
@@ -754,8 +774,8 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
         BuildMI(MBB, MBBI, TII.get(X86::CALLpcrel32))
           .addExternalSymbol("_alloca");
         // Restore EAX
-        MachineInstr *MI = addRegOffset(BuildMI(TII.get(X86::MOV32rm),X86::EAX),
-                                        StackPtr, NumBytes-4);
+        MachineInstr *MI = addRegOffset(BuildMI(MF, TII.get(X86::MOV32rm),X86::EAX),
+                                        StackPtr, false, NumBytes-4);
         MBB.insert(MBBI, MI);
       }
     } else {
@@ -791,6 +811,7 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
   case X86::TCRETURNri64:
   case X86::TCRETURNdi64:
   case X86::EH_RETURN:
+  case X86::EH_RETURN64:
   case X86::TAILJMPd:
   case X86::TAILJMPr:
   case X86::TAILJMPm: break;  // These are ok
@@ -850,12 +871,12 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
   } else if (MFI->hasVarSizedObjects()) {
     if (CSSize) {
       unsigned Opc = Is64Bit ? X86::LEA64r : X86::LEA32r;
-      MachineInstr *MI = addRegOffset(BuildMI(TII.get(Opc), StackPtr),
-                                      FramePtr, -CSSize);
+      MachineInstr *MI = addRegOffset(BuildMI(MF, TII.get(Opc), StackPtr),
+                                      FramePtr, false, -CSSize);
       MBB.insert(MBBI, MI);
     } else
-      BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),StackPtr).
-        addReg(FramePtr);
+      BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),
+              StackPtr).addReg(FramePtr);
 
   } else {
     // adjust stack pointer back: ESP += numbytes
@@ -864,12 +885,13 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
   }
 
   // We're returning from function via eh_return.
-  if (RetOpcode == X86::EH_RETURN) {
+  if (RetOpcode == X86::EH_RETURN || RetOpcode == X86::EH_RETURN64) {
     MBBI = prior(MBB.end());
     MachineOperand &DestAddr  = MBBI->getOperand(0);
     assert(DestAddr.isRegister() && "Offset should be in register!");
-    BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),StackPtr).
-      addReg(DestAddr.getReg());
+    BuildMI(MBB, MBBI,
+            TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),
+            StackPtr).addReg(DestAddr.getReg());
   // Tail call return: adjust the stack pointer and jump to callee
   } else if (RetOpcode == X86::TCRETURNri || RetOpcode == X86::TCRETURNdi ||
              RetOpcode== X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64) {
@@ -950,8 +972,8 @@ unsigned X86RegisterInfo::getEHHandlerRegister() const {
 }
 
 namespace llvm {
-unsigned getX86SubSuperRegister(unsigned Reg, MVT::ValueType VT, bool High) {
-  switch (VT) {
+unsigned getX86SubSuperRegister(unsigned Reg, MVT VT, bool High) {
+  switch (VT.getSimpleVT()) {
   default: return Reg;
   case MVT::i8:
     if (High) {
@@ -1118,3 +1140,38 @@ unsigned getX86SubSuperRegister(unsigned Reg, MVT::ValueType VT, bool High) {
 }
 
 #include "X86GenRegisterInfo.inc"
+
+namespace {
+  struct VISIBILITY_HIDDEN MSAC : public MachineFunctionPass {
+    static char ID;
+    MSAC() : MachineFunctionPass(&ID) {}
+
+    virtual bool runOnMachineFunction(MachineFunction &MF) {
+      MachineFrameInfo *FFI = MF.getFrameInfo();
+      MachineRegisterInfo &RI = MF.getRegInfo();
+
+      // Calculate max stack alignment of all already allocated stack objects.
+      unsigned MaxAlign = calculateMaxStackAlignment(FFI);
+
+      // Be over-conservative: scan over all vreg defs and find, whether vector
+      // registers are used. If yes - there is probability, that vector register
+      // will be spilled and thus stack needs to be aligned properly.
+      for (unsigned RegNum = TargetRegisterInfo::FirstVirtualRegister;
+           RegNum < RI.getLastVirtReg(); ++RegNum)
+        MaxAlign = std::max(MaxAlign, RI.getRegClass(RegNum)->getAlignment());
+
+      FFI->setMaxAlignment(MaxAlign);
+
+      return false;
+    }
+
+    virtual const char *getPassName() const {
+      return "X86 Maximal Stack Alignment Calculator";
+    }
+  };
+
+  char MSAC::ID = 0;
+}
+
+FunctionPass*
+llvm::createX86MaxStackAlignmentCalculatorPass() { return new MSAC(); }