diff options
| author | Anton Korobeynikov <asl@math.spbu.ru> | 2010-11-27 23:05:25 +0000 | 
|---|---|---|
| committer | Anton Korobeynikov <asl@math.spbu.ru> | 2010-11-27 23:05:25 +0000 | 
| commit | 94c5ae08750f314bc3cf1bf882b686244a3927d9 (patch) | |
| tree | 2321c65c1ab4eb60729a6a210ebceb4f4508ceae /lib/Target | |
| parent | cd775ceff0b25a0b026f643a7990c2924bd310a3 (diff) | |
| download | external_llvm-94c5ae08750f314bc3cf1bf882b686244a3927d9.zip external_llvm-94c5ae08750f314bc3cf1bf882b686244a3927d9.tar.gz external_llvm-94c5ae08750f314bc3cf1bf882b686244a3927d9.tar.bz2  | |
Move more PEI-related hooks to TFI
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120229 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
28 files changed, 775 insertions, 776 deletions
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 42159c9..3e7c1c3 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -591,328 +591,6 @@ cannotEliminateFrame(const MachineFunction &MF) const {      || needsStackRealignment(MF);  } -/// estimateStackSize - Estimate and return the size of the frame. -static unsigned estimateStackSize(MachineFunction &MF) { -  const MachineFrameInfo *FFI = MF.getFrameInfo(); -  int Offset = 0; -  for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { -    int FixedOff = -FFI->getObjectOffset(i); -    if (FixedOff > Offset) Offset = FixedOff; -  } -  for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { -    if (FFI->isDeadObjectIndex(i)) -      continue; -    Offset += FFI->getObjectSize(i); -    unsigned Align = FFI->getObjectAlignment(i); -    // Adjust to alignment boundary -    Offset = (Offset+Align-1)/Align*Align; -  } -  return (unsigned)Offset; -} - -/// estimateRSStackSizeLimit - Look at each instruction that references stack -/// frames and return the stack size limit beyond which some of these -/// instructions will require a scratch register during their expansion later. -unsigned -ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const { -  const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); -  const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); -  unsigned Limit = (1 << 12) - 1; -  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; - -        // When using ADDri to get the address of a stack object, 255 is the -        // largest offset guaranteed to fit in the immediate offset. -        if (I->getOpcode() == ARM::ADDri) { -          Limit = std::min(Limit, (1U << 8) - 1); -          break; -        } - -        // Otherwise check the addressing mode. -        switch (I->getDesc().TSFlags & ARMII::AddrModeMask) { -        case ARMII::AddrMode3: -        case ARMII::AddrModeT2_i8: -          Limit = std::min(Limit, (1U << 8) - 1); -          break; -        case ARMII::AddrMode5: -        case ARMII::AddrModeT2_i8s4: -          Limit = std::min(Limit, ((1U << 8) - 1) * 4); -          break; -        case ARMII::AddrModeT2_i12: -          // i12 supports only positive offset so these will be converted to -          // i8 opcodes. See llvm::rewriteT2FrameIndex. -          if (TFI->hasFP(MF) && AFI->hasStackFrame()) -            Limit = std::min(Limit, (1U << 8) - 1); -          break; -        case ARMII::AddrMode4: -        case ARMII::AddrMode6: -          // Addressing modes 4 & 6 (load/store) instructions can't encode an -          // immediate offset for stack references. -          return 0; -        default: -          break; -        } -        break; // At most one FI per instruction -      } -    } -  } - -  return Limit; -} - -static unsigned GetFunctionSizeInBytes(const MachineFunction &MF, -                                       const ARMBaseInstrInfo &TII) { -  unsigned FnSize = 0; -  for (MachineFunction::const_iterator MBBI = MF.begin(), E = MF.end(); -       MBBI != E; ++MBBI) { -    const MachineBasicBlock &MBB = *MBBI; -    for (MachineBasicBlock::const_iterator I = MBB.begin(),E = MBB.end(); -         I != E; ++I) -      FnSize += TII.GetInstSizeInBytes(I); -  } -  return FnSize; -} - -void -ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                                       RegScavenger *RS) const { -  // This tells PEI to spill the FP as if it is any other callee-save register -  // to take advantage the eliminateFrameIndex machinery. This also ensures it -  // is spilled in the order specified by getCalleeSavedRegs() to make it easier -  // to combine multiple loads / stores. -  bool CanEliminateFrame = true; -  bool CS1Spilled = false; -  bool LRSpilled = false; -  unsigned NumGPRSpills = 0; -  SmallVector<unsigned, 4> UnspilledCS1GPRs; -  SmallVector<unsigned, 4> UnspilledCS2GPRs; -  const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); -  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); -  MachineFrameInfo *MFI = MF.getFrameInfo(); - -  // Spill R4 if Thumb2 function requires stack realignment - it will be used as -  // scratch register. Also spill R4 if Thumb2 function has varsized objects, -  // since it's always posible to restore sp from fp in a single instruction. -  // FIXME: It will be better just to find spare register here. -  if (AFI->isThumb2Function() && -      (MFI->hasVarSizedObjects() || needsStackRealignment(MF))) -    MF.getRegInfo().setPhysRegUsed(ARM::R4); - -  // Spill LR if Thumb1 function uses variable length argument lists. -  if (AFI->isThumb1OnlyFunction() && AFI->getVarArgsRegSaveSize() > 0) -    MF.getRegInfo().setPhysRegUsed(ARM::LR); - -  // Spill the BasePtr if it's used. -  if (hasBasePointer(MF)) -    MF.getRegInfo().setPhysRegUsed(BasePtr); - -  // Don't spill FP if the frame can be eliminated. This is determined -  // by scanning the callee-save registers to see if any is used. -  const unsigned *CSRegs = getCalleeSavedRegs(); -  for (unsigned i = 0; CSRegs[i]; ++i) { -    unsigned Reg = CSRegs[i]; -    bool Spilled = false; -    if (MF.getRegInfo().isPhysRegUsed(Reg)) { -      AFI->setCSRegisterIsSpilled(Reg); -      Spilled = true; -      CanEliminateFrame = false; -    } else { -      // Check alias registers too. -      for (const unsigned *Aliases = getAliasSet(Reg); *Aliases; ++Aliases) { -        if (MF.getRegInfo().isPhysRegUsed(*Aliases)) { -          Spilled = true; -          CanEliminateFrame = false; -        } -      } -    } - -    if (!ARM::GPRRegisterClass->contains(Reg)) -      continue; - -    if (Spilled) { -      NumGPRSpills++; - -      if (!STI.isTargetDarwin()) { -        if (Reg == ARM::LR) -          LRSpilled = true; -        CS1Spilled = true; -        continue; -      } - -      // Keep track if LR and any of R4, R5, R6, and R7 is spilled. -      switch (Reg) { -      case ARM::LR: -        LRSpilled = true; -        // Fallthrough -      case ARM::R4: -      case ARM::R5: -      case ARM::R6: -      case ARM::R7: -        CS1Spilled = true; -        break; -      default: -        break; -      } -    } else { -      if (!STI.isTargetDarwin()) { -        UnspilledCS1GPRs.push_back(Reg); -        continue; -      } - -      switch (Reg) { -      case ARM::R4: -      case ARM::R5: -      case ARM::R6: -      case ARM::R7: -      case ARM::LR: -        UnspilledCS1GPRs.push_back(Reg); -        break; -      default: -        UnspilledCS2GPRs.push_back(Reg); -        break; -      } -    } -  } - -  bool ForceLRSpill = false; -  if (!LRSpilled && AFI->isThumb1OnlyFunction()) { -    unsigned FnSize = GetFunctionSizeInBytes(MF, TII); -    // Force LR to be spilled if the Thumb function size is > 2048. This enables -    // use of BL to implement far jump. If it turns out that it's not needed -    // then the branch fix up path will undo it. -    if (FnSize >= (1 << 11)) { -      CanEliminateFrame = false; -      ForceLRSpill = true; -    } -  } - -  // If any of the stack slot references may be out of range of an immediate -  // offset, make sure a register (or a spill slot) is available for the -  // register scavenger. Note that if we're indexing off the frame pointer, the -  // effective stack size is 4 bytes larger since the FP points to the stack -  // slot of the previous FP. Also, if we have variable sized objects in the -  // function, stack slot references will often be negative, and some of -  // our instructions are positive-offset only, so conservatively consider -  // that case to want a spill slot (or register) as well. Similarly, if -  // the function adjusts the stack pointer during execution and the -  // adjustments aren't already part of our stack size estimate, our offset -  // calculations may be off, so be conservative. -  // FIXME: We could add logic to be more precise about negative offsets -  //        and which instructions will need a scratch register for them. Is it -  //        worth the effort and added fragility? -  bool BigStack = -    (RS && -     (estimateStackSize(MF) + ((TFI->hasFP(MF) && AFI->hasStackFrame()) ? 4:0) >= -      estimateRSStackSizeLimit(MF))) -    || MFI->hasVarSizedObjects() -    || (MFI->adjustsStack() && !TFI->canSimplifyCallFramePseudos(MF)); - -  bool ExtraCSSpill = false; -  if (BigStack || !CanEliminateFrame || cannotEliminateFrame(MF)) { -    AFI->setHasStackFrame(true); - -    // If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled. -    // Spill LR as well so we can fold BX_RET to the registers restore (LDM). -    if (!LRSpilled && CS1Spilled) { -      MF.getRegInfo().setPhysRegUsed(ARM::LR); -      AFI->setCSRegisterIsSpilled(ARM::LR); -      NumGPRSpills++; -      UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(), -                                    UnspilledCS1GPRs.end(), (unsigned)ARM::LR)); -      ForceLRSpill = false; -      ExtraCSSpill = true; -    } - -    if (TFI->hasFP(MF)) { -      MF.getRegInfo().setPhysRegUsed(FramePtr); -      NumGPRSpills++; -    } - -    // If stack and double are 8-byte aligned and we are spilling an odd number -    // of GPRs, spill one extra callee save GPR so we won't have to pad between -    // the integer and double callee save areas. -    unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); -    if (TargetAlign == 8 && (NumGPRSpills & 1)) { -      if (CS1Spilled && !UnspilledCS1GPRs.empty()) { -        for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) { -          unsigned Reg = UnspilledCS1GPRs[i]; -          // Don't spill high register if the function is thumb1 -          if (!AFI->isThumb1OnlyFunction() || -              isARMLowRegister(Reg) || Reg == ARM::LR) { -            MF.getRegInfo().setPhysRegUsed(Reg); -            AFI->setCSRegisterIsSpilled(Reg); -            if (!isReservedReg(MF, Reg)) -              ExtraCSSpill = true; -            break; -          } -        } -      } else if (!UnspilledCS2GPRs.empty() && -                 !AFI->isThumb1OnlyFunction()) { -        unsigned Reg = UnspilledCS2GPRs.front(); -        MF.getRegInfo().setPhysRegUsed(Reg); -        AFI->setCSRegisterIsSpilled(Reg); -        if (!isReservedReg(MF, Reg)) -          ExtraCSSpill = true; -      } -    } - -    // Estimate if we might need to scavenge a register at some point in order -    // to materialize a stack offset. If so, either spill one additional -    // callee-saved register or reserve a special spill slot to facilitate -    // register scavenging. Thumb1 needs a spill slot for stack pointer -    // adjustments also, even when the frame itself is small. -    if (BigStack && !ExtraCSSpill) { -      // 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; -      SmallVector<unsigned, 2> Extras; -      while (NumExtras && !UnspilledCS1GPRs.empty()) { -        unsigned Reg = UnspilledCS1GPRs.back(); -        UnspilledCS1GPRs.pop_back(); -        if (!isReservedReg(MF, Reg) && -            (!AFI->isThumb1OnlyFunction() || isARMLowRegister(Reg) || -             Reg == ARM::LR)) { -          Extras.push_back(Reg); -          NumExtras--; -        } -      } -      // For non-Thumb1 functions, also check for hi-reg CS registers -      if (!AFI->isThumb1OnlyFunction()) { -        while (NumExtras && !UnspilledCS2GPRs.empty()) { -          unsigned Reg = UnspilledCS2GPRs.back(); -          UnspilledCS2GPRs.pop_back(); -          if (!isReservedReg(MF, Reg)) { -            Extras.push_back(Reg); -            NumExtras--; -          } -        } -      } -      if (Extras.size() && NumExtras == 0) { -        for (unsigned i = 0, e = Extras.size(); i != e; ++i) { -          MF.getRegInfo().setPhysRegUsed(Extras[i]); -          AFI->setCSRegisterIsSpilled(Extras[i]); -        } -      } else if (!AFI->isThumb1OnlyFunction()) { -        // note: Thumb1 functions spill to R12, not the stack.  Reserve a slot -        // closest to SP or frame pointer. -        const TargetRegisterClass *RC = ARM::GPRRegisterClass; -        RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), -                                                           RC->getAlignment(), -                                                           false)); -      } -    } -  } - -  if (ForceLRSpill) { -    MF.getRegInfo().setPhysRegUsed(ARM::LR); -    AFI->setCSRegisterIsSpilled(ARM::LR); -    AFI->setLRIsSpilledForFarJump(true); -  } -} -  unsigned ARMBaseRegisterInfo::getRARegister() const {    return ARM::LR;  } diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h index 718f484..23a466f 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -154,9 +154,6 @@ public:    bool cannotEliminateFrame(const MachineFunction &MF) const; -  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                            RegScavenger *RS = NULL) const; -    // Debug information queries.    unsigned getRARegister() const;    unsigned getFrameRegister(const MachineFunction &MF) const; @@ -198,8 +195,6 @@ public:                                     int SPAdj, RegScavenger *RS = NULL) const;  private: -  unsigned estimateRSStackSizeLimit(MachineFunction &MF) const; -    unsigned getRegisterPairEven(unsigned Reg, const MachineFunction &MF) const;    unsigned getRegisterPairOdd(unsigned Reg, const MachineFunction &MF) const; diff --git a/lib/Target/ARM/ARMFrameInfo.cpp b/lib/Target/ARM/ARMFrameInfo.cpp index d379bf0..e2531d0 100644 --- a/lib/Target/ARM/ARMFrameInfo.cpp +++ b/lib/Target/ARM/ARMFrameInfo.cpp @@ -18,6 +18,7 @@  #include "llvm/CodeGen/MachineFunction.h"  #include "llvm/CodeGen/MachineInstrBuilder.h"  #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/RegisterScavenging.h"  #include "llvm/Target/TargetOptions.h"  using namespace llvm; @@ -614,3 +615,327 @@ bool ARMFrameInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,    return true;  } + +// FIXME: Make generic? +static unsigned GetFunctionSizeInBytes(const MachineFunction &MF, +                                       const ARMBaseInstrInfo &TII) { +  unsigned FnSize = 0; +  for (MachineFunction::const_iterator MBBI = MF.begin(), E = MF.end(); +       MBBI != E; ++MBBI) { +    const MachineBasicBlock &MBB = *MBBI; +    for (MachineBasicBlock::const_iterator I = MBB.begin(),E = MBB.end(); +         I != E; ++I) +      FnSize += TII.GetInstSizeInBytes(I); +  } +  return FnSize; +} + +/// estimateStackSize - Estimate and return the size of the frame. +/// FIXME: Make generic? +static unsigned estimateStackSize(MachineFunction &MF) { +  const MachineFrameInfo *FFI = MF.getFrameInfo(); +  int Offset = 0; +  for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { +    int FixedOff = -FFI->getObjectOffset(i); +    if (FixedOff > Offset) Offset = FixedOff; +  } +  for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { +    if (FFI->isDeadObjectIndex(i)) +      continue; +    Offset += FFI->getObjectSize(i); +    unsigned Align = FFI->getObjectAlignment(i); +    // Adjust to alignment boundary +    Offset = (Offset+Align-1)/Align*Align; +  } +  return (unsigned)Offset; +} + +/// estimateRSStackSizeLimit - Look at each instruction that references stack +/// frames and return the stack size limit beyond which some of these +/// instructions will require a scratch register during their expansion later. +// FIXME: Move to TII? +static unsigned estimateRSStackSizeLimit(MachineFunction &MF, +                                         const TargetFrameInfo *TFI) { +  const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); +  unsigned Limit = (1 << 12) - 1; +  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; + +        // When using ADDri to get the address of a stack object, 255 is the +        // largest offset guaranteed to fit in the immediate offset. +        if (I->getOpcode() == ARM::ADDri) { +          Limit = std::min(Limit, (1U << 8) - 1); +          break; +        } + +        // Otherwise check the addressing mode. +        switch (I->getDesc().TSFlags & ARMII::AddrModeMask) { +        case ARMII::AddrMode3: +        case ARMII::AddrModeT2_i8: +          Limit = std::min(Limit, (1U << 8) - 1); +          break; +        case ARMII::AddrMode5: +        case ARMII::AddrModeT2_i8s4: +          Limit = std::min(Limit, ((1U << 8) - 1) * 4); +          break; +        case ARMII::AddrModeT2_i12: +          // i12 supports only positive offset so these will be converted to +          // i8 opcodes. See llvm::rewriteT2FrameIndex. +          if (TFI->hasFP(MF) && AFI->hasStackFrame()) +            Limit = std::min(Limit, (1U << 8) - 1); +          break; +        case ARMII::AddrMode4: +        case ARMII::AddrMode6: +          // Addressing modes 4 & 6 (load/store) instructions can't encode an +          // immediate offset for stack references. +          return 0; +        default: +          break; +        } +        break; // At most one FI per instruction +      } +    } +  } + +  return Limit; +} + +void +ARMFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                                   RegScavenger *RS) const { +  // This tells PEI to spill the FP as if it is any other callee-save register +  // to take advantage the eliminateFrameIndex machinery. This also ensures it +  // is spilled in the order specified by getCalleeSavedRegs() to make it easier +  // to combine multiple loads / stores. +  bool CanEliminateFrame = true; +  bool CS1Spilled = false; +  bool LRSpilled = false; +  unsigned NumGPRSpills = 0; +  SmallVector<unsigned, 4> UnspilledCS1GPRs; +  SmallVector<unsigned, 4> UnspilledCS2GPRs; +  const ARMBaseRegisterInfo *RegInfo = +    static_cast<const ARMBaseRegisterInfo*>(MF.getTarget().getRegisterInfo()); +  const ARMBaseInstrInfo &TII = +    *static_cast<const ARMBaseInstrInfo*>(MF.getTarget().getInstrInfo()); +  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); +  MachineFrameInfo *MFI = MF.getFrameInfo(); +  unsigned FramePtr = RegInfo->getFrameRegister(MF); + +  // Spill R4 if Thumb2 function requires stack realignment - it will be used as +  // scratch register. Also spill R4 if Thumb2 function has varsized objects, +  // since it's always posible to restore sp from fp in a single instruction. +  // FIXME: It will be better just to find spare register here. +  if (AFI->isThumb2Function() && +      (MFI->hasVarSizedObjects() || RegInfo->needsStackRealignment(MF))) +    MF.getRegInfo().setPhysRegUsed(ARM::R4); + +  // Spill LR if Thumb1 function uses variable length argument lists. +  if (AFI->isThumb1OnlyFunction() && AFI->getVarArgsRegSaveSize() > 0) +    MF.getRegInfo().setPhysRegUsed(ARM::LR); + +  // Spill the BasePtr if it's used. +  if (RegInfo->hasBasePointer(MF)) +    MF.getRegInfo().setPhysRegUsed(RegInfo->getBaseRegister()); + +  // Don't spill FP if the frame can be eliminated. This is determined +  // by scanning the callee-save registers to see if any is used. +  const unsigned *CSRegs = RegInfo->getCalleeSavedRegs(); +  for (unsigned i = 0; CSRegs[i]; ++i) { +    unsigned Reg = CSRegs[i]; +    bool Spilled = false; +    if (MF.getRegInfo().isPhysRegUsed(Reg)) { +      AFI->setCSRegisterIsSpilled(Reg); +      Spilled = true; +      CanEliminateFrame = false; +    } else { +      // Check alias registers too. +      for (const unsigned *Aliases = +             RegInfo->getAliasSet(Reg); *Aliases; ++Aliases) { +        if (MF.getRegInfo().isPhysRegUsed(*Aliases)) { +          Spilled = true; +          CanEliminateFrame = false; +        } +      } +    } + +    if (!ARM::GPRRegisterClass->contains(Reg)) +      continue; + +    if (Spilled) { +      NumGPRSpills++; + +      if (!STI.isTargetDarwin()) { +        if (Reg == ARM::LR) +          LRSpilled = true; +        CS1Spilled = true; +        continue; +      } + +      // Keep track if LR and any of R4, R5, R6, and R7 is spilled. +      switch (Reg) { +      case ARM::LR: +        LRSpilled = true; +        // Fallthrough +      case ARM::R4: case ARM::R5: +      case ARM::R6: case ARM::R7: +        CS1Spilled = true; +        break; +      default: +        break; +      } +    } else { +      if (!STI.isTargetDarwin()) { +        UnspilledCS1GPRs.push_back(Reg); +        continue; +      } + +      switch (Reg) { +      case ARM::R4: case ARM::R5: +      case ARM::R6: case ARM::R7: +      case ARM::LR: +        UnspilledCS1GPRs.push_back(Reg); +        break; +      default: +        UnspilledCS2GPRs.push_back(Reg); +        break; +      } +    } +  } + +  bool ForceLRSpill = false; +  if (!LRSpilled && AFI->isThumb1OnlyFunction()) { +    unsigned FnSize = GetFunctionSizeInBytes(MF, TII); +    // Force LR to be spilled if the Thumb function size is > 2048. This enables +    // use of BL to implement far jump. If it turns out that it's not needed +    // then the branch fix up path will undo it. +    if (FnSize >= (1 << 11)) { +      CanEliminateFrame = false; +      ForceLRSpill = true; +    } +  } + +  // If any of the stack slot references may be out of range of an immediate +  // offset, make sure a register (or a spill slot) is available for the +  // register scavenger. Note that if we're indexing off the frame pointer, the +  // effective stack size is 4 bytes larger since the FP points to the stack +  // slot of the previous FP. Also, if we have variable sized objects in the +  // function, stack slot references will often be negative, and some of +  // our instructions are positive-offset only, so conservatively consider +  // that case to want a spill slot (or register) as well. Similarly, if +  // the function adjusts the stack pointer during execution and the +  // adjustments aren't already part of our stack size estimate, our offset +  // calculations may be off, so be conservative. +  // FIXME: We could add logic to be more precise about negative offsets +  //        and which instructions will need a scratch register for them. Is it +  //        worth the effort and added fragility? +  bool BigStack = +    (RS && +     (estimateStackSize(MF) + ((hasFP(MF) && AFI->hasStackFrame()) ? 4:0) >= +      estimateRSStackSizeLimit(MF, this))) +    || MFI->hasVarSizedObjects() +    || (MFI->adjustsStack() && !canSimplifyCallFramePseudos(MF)); + +  bool ExtraCSSpill = false; +  if (BigStack || !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF)) { +    AFI->setHasStackFrame(true); + +    // If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled. +    // Spill LR as well so we can fold BX_RET to the registers restore (LDM). +    if (!LRSpilled && CS1Spilled) { +      MF.getRegInfo().setPhysRegUsed(ARM::LR); +      AFI->setCSRegisterIsSpilled(ARM::LR); +      NumGPRSpills++; +      UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(), +                                    UnspilledCS1GPRs.end(), (unsigned)ARM::LR)); +      ForceLRSpill = false; +      ExtraCSSpill = true; +    } + +    if (hasFP(MF)) { +      MF.getRegInfo().setPhysRegUsed(FramePtr); +      NumGPRSpills++; +    } + +    // If stack and double are 8-byte aligned and we are spilling an odd number +    // of GPRs, spill one extra callee save GPR so we won't have to pad between +    // the integer and double callee save areas. +    unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); +    if (TargetAlign == 8 && (NumGPRSpills & 1)) { +      if (CS1Spilled && !UnspilledCS1GPRs.empty()) { +        for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) { +          unsigned Reg = UnspilledCS1GPRs[i]; +          // Don't spill high register if the function is thumb1 +          if (!AFI->isThumb1OnlyFunction() || +              isARMLowRegister(Reg) || Reg == ARM::LR) { +            MF.getRegInfo().setPhysRegUsed(Reg); +            AFI->setCSRegisterIsSpilled(Reg); +            if (!RegInfo->isReservedReg(MF, Reg)) +              ExtraCSSpill = true; +            break; +          } +        } +      } else if (!UnspilledCS2GPRs.empty() && !AFI->isThumb1OnlyFunction()) { +        unsigned Reg = UnspilledCS2GPRs.front(); +        MF.getRegInfo().setPhysRegUsed(Reg); +        AFI->setCSRegisterIsSpilled(Reg); +        if (!RegInfo->isReservedReg(MF, Reg)) +          ExtraCSSpill = true; +      } +    } + +    // Estimate if we might need to scavenge a register at some point in order +    // to materialize a stack offset. If so, either spill one additional +    // callee-saved register or reserve a special spill slot to facilitate +    // register scavenging. Thumb1 needs a spill slot for stack pointer +    // adjustments also, even when the frame itself is small. +    if (BigStack && !ExtraCSSpill) { +      // 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; +      SmallVector<unsigned, 2> Extras; +      while (NumExtras && !UnspilledCS1GPRs.empty()) { +        unsigned Reg = UnspilledCS1GPRs.back(); +        UnspilledCS1GPRs.pop_back(); +        if (!RegInfo->isReservedReg(MF, Reg) && +            (!AFI->isThumb1OnlyFunction() || isARMLowRegister(Reg) || +             Reg == ARM::LR)) { +          Extras.push_back(Reg); +          NumExtras--; +        } +      } +      // For non-Thumb1 functions, also check for hi-reg CS registers +      if (!AFI->isThumb1OnlyFunction()) { +        while (NumExtras && !UnspilledCS2GPRs.empty()) { +          unsigned Reg = UnspilledCS2GPRs.back(); +          UnspilledCS2GPRs.pop_back(); +          if (!RegInfo->isReservedReg(MF, Reg)) { +            Extras.push_back(Reg); +            NumExtras--; +          } +        } +      } +      if (Extras.size() && NumExtras == 0) { +        for (unsigned i = 0, e = Extras.size(); i != e; ++i) { +          MF.getRegInfo().setPhysRegUsed(Extras[i]); +          AFI->setCSRegisterIsSpilled(Extras[i]); +        } +      } else if (!AFI->isThumb1OnlyFunction()) { +        // note: Thumb1 functions spill to R12, not the stack.  Reserve a slot +        // closest to SP or frame pointer. +        const TargetRegisterClass *RC = ARM::GPRRegisterClass; +        RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), +                                                           RC->getAlignment(), +                                                           false)); +      } +    } +  } + +  if (ForceLRSpill) { +    MF.getRegInfo().setPhysRegUsed(ARM::LR); +    AFI->setCSRegisterIsSpilled(ARM::LR); +    AFI->setLRIsSpilledForFarJump(true); +  } +} diff --git a/lib/Target/ARM/ARMFrameInfo.h b/lib/Target/ARM/ARMFrameInfo.h index 7b34c15..886f749 100644 --- a/lib/Target/ARM/ARMFrameInfo.h +++ b/lib/Target/ARM/ARMFrameInfo.h @@ -54,6 +54,9 @@ public:                                   unsigned &FrameReg, int SPAdj) const;    int getFrameIndexOffset(const MachineFunction &MF, int FI) const; +  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                            RegScavenger *RS) const; +   private:    void emitPopInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,                     const std::vector<CalleeSavedInfo> &CSI, unsigned Opc, diff --git a/lib/Target/Blackfin/BlackfinFrameInfo.cpp b/lib/Target/Blackfin/BlackfinFrameInfo.cpp index 4f9054b..c57dc30 100644 --- a/lib/Target/Blackfin/BlackfinFrameInfo.cpp +++ b/lib/Target/Blackfin/BlackfinFrameInfo.cpp @@ -16,6 +16,7 @@  #include "llvm/CodeGen/MachineFrameInfo.h"  #include "llvm/CodeGen/MachineFunction.h"  #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/RegisterScavenging.h"  #include "llvm/Target/TargetOptions.h"  using namespace llvm; @@ -105,3 +106,19 @@ void BlackfinFrameInfo::emitEpilogue(MachineFunction &MF,    // emit an UNLINK instruction    BuildMI(MBB, MBBI, dl, TII.get(BF::UNLINK));  } + +void BlackfinFrameInfo:: +processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                     RegScavenger *RS) const { +  MachineFrameInfo *MFI = MF.getFrameInfo(); +  const BlackfinRegisterInfo *RegInfo = +    static_cast<const BlackfinRegisterInfo*>(MF.getTarget().getRegisterInfo()); +  const TargetRegisterClass *RC = BF::DPRegisterClass; + +  if (RegInfo->requiresRegisterScavenging(MF)) { +    // Reserve a slot close to SP or frame pointer. +    RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), +                                                       RC->getAlignment(), +                                                       false)); +  } +} diff --git a/lib/Target/Blackfin/BlackfinFrameInfo.h b/lib/Target/Blackfin/BlackfinFrameInfo.h index 3b53f34..8f46b3e 100644 --- a/lib/Target/Blackfin/BlackfinFrameInfo.h +++ b/lib/Target/Blackfin/BlackfinFrameInfo.h @@ -36,6 +36,9 @@ public:    void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;    bool hasFP(const MachineFunction &MF) const; + +  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                            RegScavenger *RS) const;  };  } // End llvm namespace diff --git a/lib/Target/Blackfin/BlackfinRegisterInfo.cpp b/lib/Target/Blackfin/BlackfinRegisterInfo.cpp index 23df625..9865b3b 100644 --- a/lib/Target/Blackfin/BlackfinRegisterInfo.cpp +++ b/lib/Target/Blackfin/BlackfinRegisterInfo.cpp @@ -325,19 +325,6 @@ BlackfinRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,    }  } -void BlackfinRegisterInfo:: -processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                     RegScavenger *RS) const { -  MachineFrameInfo *MFI = MF.getFrameInfo(); -  const TargetRegisterClass *RC = BF::DPRegisterClass; -  if (requiresRegisterScavenging(MF)) { -    // Reserve a slot close to SP or frame pointer. -    RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), -                                                       RC->getAlignment(), -                                                       false)); -  } -} -  unsigned BlackfinRegisterInfo::getRARegister() const {    return BF::RETS;  } diff --git a/lib/Target/Blackfin/BlackfinRegisterInfo.h b/lib/Target/Blackfin/BlackfinRegisterInfo.h index 0c47d25..642b8ad 100644 --- a/lib/Target/Blackfin/BlackfinRegisterInfo.h +++ b/lib/Target/Blackfin/BlackfinRegisterInfo.h @@ -52,9 +52,6 @@ namespace llvm {      void eliminateFrameIndex(MachineBasicBlock::iterator II,                               int SPAdj, RegScavenger *RS = NULL) const; -    void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                              RegScavenger *RS) const; -      unsigned getFrameRegister(const MachineFunction &MF) const;      unsigned getRARegister() const; diff --git a/lib/Target/CellSPU/SPUFrameInfo.cpp b/lib/Target/CellSPU/SPUFrameInfo.cpp index 114d858..1b7d88b 100644 --- a/lib/Target/CellSPU/SPUFrameInfo.cpp +++ b/lib/Target/CellSPU/SPUFrameInfo.cpp @@ -22,6 +22,7 @@  #include "llvm/CodeGen/MachineInstrBuilder.h"  #include "llvm/CodeGen/MachineModuleInfo.h"  #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/RegisterScavenging.h"  #include "llvm/Target/TargetData.h"  #include "llvm/Target/TargetOptions.h"  #include "llvm/Support/CommandLine.h" @@ -255,3 +256,20 @@ void SPUFrameInfo::getInitialFrameState(std::vector<MachineMove> &Moves) const {    MachineLocation Src(SPU::R1, 0);    Moves.push_back(MachineMove(0, Dst, Src));  } + +void SPUFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                                        RegScavenger *RS) const{ +  // Mark LR and SP unused, since the prolog spills them to stack and +  // we don't want anyone else to spill them for us. +  // +  // Also, unless R2 is really used someday, don't spill it automatically. +  MF.getRegInfo().setPhysRegUnused(SPU::R0); +  MF.getRegInfo().setPhysRegUnused(SPU::R1); +  MF.getRegInfo().setPhysRegUnused(SPU::R2); + +  MachineFrameInfo *MFI = MF.getFrameInfo(); +  const TargetRegisterClass *RC = &SPU::R32CRegClass; +  RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), +                                                     RC->getAlignment(), +                                                     false)); +} diff --git a/lib/Target/CellSPU/SPUFrameInfo.h b/lib/Target/CellSPU/SPUFrameInfo.h index f1cb254..aca6fcd 100644 --- a/lib/Target/CellSPU/SPUFrameInfo.h +++ b/lib/Target/CellSPU/SPUFrameInfo.h @@ -40,6 +40,9 @@ namespace llvm {      //! Prediate: Target has dedicated frame pointer      bool hasFP(const MachineFunction &MF) const; +    void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                              RegScavenger *RS = NULL) const; +      //! Perform target-specific stack frame setup.      void getInitialFrameState(std::vector<MachineMove> &Moves) const; diff --git a/lib/Target/CellSPU/SPURegisterInfo.cpp b/lib/Target/CellSPU/SPURegisterInfo.cpp index 405994a..d81fc19 100644 --- a/lib/Target/CellSPU/SPURegisterInfo.cpp +++ b/lib/Target/CellSPU/SPURegisterInfo.cpp @@ -310,24 +310,6 @@ SPURegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,    }  } -void SPURegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                                           RegScavenger *RS) -  const { -  // Mark LR and SP unused, since the prolog spills them to stack and -  // we don't want anyone else to spill them for us. -  // -  // Also, unless R2 is really used someday, don't spill it automatically. -  MF.getRegInfo().setPhysRegUnused(SPU::R0); -  MF.getRegInfo().setPhysRegUnused(SPU::R1); -  MF.getRegInfo().setPhysRegUnused(SPU::R2); - -  MachineFrameInfo *MFI = MF.getFrameInfo(); -  const TargetRegisterClass *RC = &SPU::R32CRegClass; -  RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), -                                                     RC->getAlignment(), -                                                     false)); -} -  unsigned  SPURegisterInfo::getRARegister() const  { diff --git a/lib/Target/CellSPU/SPURegisterInfo.h b/lib/Target/CellSPU/SPURegisterInfo.h index 9942fe1..641da04 100644 --- a/lib/Target/CellSPU/SPURegisterInfo.h +++ b/lib/Target/CellSPU/SPURegisterInfo.h @@ -64,9 +64,6 @@ namespace llvm {      void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,                               RegScavenger *RS = NULL) const; -    void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                              RegScavenger *RS = NULL) const; -      //! Get return address register (LR, aka R0)      unsigned getRARegister() const;      //! Get the stack frame register (SP, aka R1) diff --git a/lib/Target/PowerPC/PPCFrameInfo.cpp b/lib/Target/PowerPC/PPCFrameInfo.cpp index 8fa4bda..817b8f1 100644 --- a/lib/Target/PowerPC/PPCFrameInfo.cpp +++ b/lib/Target/PowerPC/PPCFrameInfo.cpp @@ -20,6 +20,7 @@  #include "llvm/CodeGen/MachineInstrBuilder.h"  #include "llvm/CodeGen/MachineModuleInfo.h"  #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/RegisterScavenging.h"  #include "llvm/Target/TargetOptions.h"  using namespace llvm; @@ -696,3 +697,261 @@ void PPCFrameInfo::getInitialFrameState(std::vector<MachineMove> &Moves) const {    MachineLocation Src(PPC::R1, 0);    Moves.push_back(MachineMove(0, Dst, Src));  } + +static bool spillsCR(const MachineFunction &MF) { +  const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); +  return FuncInfo->isCRSpilled(); +} + +/// MustSaveLR - Return true if this function requires that we save the LR +/// register onto the stack in the prolog and restore it in the epilog of the +/// function. +static bool MustSaveLR(const MachineFunction &MF, unsigned LR) { +  const PPCFunctionInfo *MFI = MF.getInfo<PPCFunctionInfo>(); + +  // We need a save/restore of LR if there is any def of LR (which is +  // defined by calls, including the PIC setup sequence), or if there is +  // some use of the LR stack slot (e.g. for builtin_return_address). +  // (LR comes in 32 and 64 bit versions.) +  MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR); +  return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired(); +} + +void +PPCFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                                   RegScavenger *RS) const { +  const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); + +  //  Save and clear the LR state. +  PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); +  unsigned LR = RegInfo->getRARegister(); +  FI->setMustSaveLR(MustSaveLR(MF, LR)); +  MF.getRegInfo().setPhysRegUnused(LR); + +  //  Save R31 if necessary +  int FPSI = FI->getFramePointerSaveIndex(); +  bool isPPC64 = Subtarget.isPPC64(); +  bool isDarwinABI  = Subtarget.isDarwinABI(); +  MachineFrameInfo *MFI = MF.getFrameInfo(); + +  // If the frame pointer save index hasn't been defined yet. +  if (!FPSI && hasFP(MF)) { +    // Find out what the fix offset of the frame pointer save area. +    int FPOffset = getFramePointerSaveOffset(isPPC64, isDarwinABI); +    // Allocate the frame index for frame pointer save area. +    FPSI = MF.getFrameInfo()->CreateFixedObject(isPPC64? 8 : 4, FPOffset, true); +    // Save the result. +    FI->setFramePointerSaveIndex(FPSI); +  } + +  // Reserve stack space to move the linkage area to in case of a tail call. +  int TCSPDelta = 0; +  if (GuaranteedTailCallOpt && (TCSPDelta = FI->getTailCallSPDelta()) < 0) { +    MF.getFrameInfo()->CreateFixedObject(-1 * TCSPDelta, TCSPDelta, true); +  } + +  // Reserve a slot closest to SP or frame pointer if we have a dynalloc or +  // a large stack, which will require scavenging a register to materialize a +  // large offset. +  // FIXME: this doesn't actually check stack size, so is a bit pessimistic +  // FIXME: doesn't detect whether or not we need to spill vXX, which requires +  //        r0 for now. + +  if (RegInfo->requiresRegisterScavenging(MF)) // FIXME (64-bit): Enable. +    if (hasFP(MF) || spillsCR(MF)) { +      const TargetRegisterClass *GPRC = &PPC::GPRCRegClass; +      const TargetRegisterClass *G8RC = &PPC::G8RCRegClass; +      const TargetRegisterClass *RC = isPPC64 ? G8RC : GPRC; +      RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), +                                                         RC->getAlignment(), +                                                         false)); +    } +} + +void PPCFrameInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) +                                                                        const { +  // Early exit if not using the SVR4 ABI. +  if (!Subtarget.isSVR4ABI()) +    return; + +  // Get callee saved register information. +  MachineFrameInfo *FFI = MF.getFrameInfo(); +  const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); + +  // Early exit if no callee saved registers are modified! +  if (CSI.empty() && !hasFP(MF)) { +    return; +  } + +  unsigned MinGPR = PPC::R31; +  unsigned MinG8R = PPC::X31; +  unsigned MinFPR = PPC::F31; +  unsigned MinVR = PPC::V31; + +  bool HasGPSaveArea = false; +  bool HasG8SaveArea = false; +  bool HasFPSaveArea = false; +  bool HasCRSaveArea = false; +  bool HasVRSAVESaveArea = false; +  bool HasVRSaveArea = false; + +  SmallVector<CalleeSavedInfo, 18> GPRegs; +  SmallVector<CalleeSavedInfo, 18> G8Regs; +  SmallVector<CalleeSavedInfo, 18> FPRegs; +  SmallVector<CalleeSavedInfo, 18> VRegs; + +  for (unsigned i = 0, e = CSI.size(); i != e; ++i) { +    unsigned Reg = CSI[i].getReg(); +    if (PPC::GPRCRegisterClass->contains(Reg)) { +      HasGPSaveArea = true; + +      GPRegs.push_back(CSI[i]); + +      if (Reg < MinGPR) { +        MinGPR = Reg; +      } +    } else if (PPC::G8RCRegisterClass->contains(Reg)) { +      HasG8SaveArea = true; + +      G8Regs.push_back(CSI[i]); + +      if (Reg < MinG8R) { +        MinG8R = Reg; +      } +    } else if (PPC::F8RCRegisterClass->contains(Reg)) { +      HasFPSaveArea = true; + +      FPRegs.push_back(CSI[i]); + +      if (Reg < MinFPR) { +        MinFPR = Reg; +      } +// FIXME SVR4: Disable CR save area for now. +    } else if (PPC::CRBITRCRegisterClass->contains(Reg) +               || PPC::CRRCRegisterClass->contains(Reg)) { +//      HasCRSaveArea = true; +    } else if (PPC::VRSAVERCRegisterClass->contains(Reg)) { +      HasVRSAVESaveArea = true; +    } else if (PPC::VRRCRegisterClass->contains(Reg)) { +      HasVRSaveArea = true; + +      VRegs.push_back(CSI[i]); + +      if (Reg < MinVR) { +        MinVR = Reg; +      } +    } else { +      llvm_unreachable("Unknown RegisterClass!"); +    } +  } + +  PPCFunctionInfo *PFI = MF.getInfo<PPCFunctionInfo>(); + +  int64_t LowerBound = 0; + +  // Take into account stack space reserved for tail calls. +  int TCSPDelta = 0; +  if (GuaranteedTailCallOpt && (TCSPDelta = PFI->getTailCallSPDelta()) < 0) { +    LowerBound = TCSPDelta; +  } + +  // The Floating-point register save area is right below the back chain word +  // of the previous stack frame. +  if (HasFPSaveArea) { +    for (unsigned i = 0, e = FPRegs.size(); i != e; ++i) { +      int FI = FPRegs[i].getFrameIdx(); + +      FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); +    } + +    LowerBound -= (31 - PPCRegisterInfo::getRegisterNumbering(MinFPR) + 1) * 8; +  } + +  // Check whether the frame pointer register is allocated. If so, make sure it +  // is spilled to the correct offset. +  if (hasFP(MF)) { +    HasGPSaveArea = true; + +    int FI = PFI->getFramePointerSaveIndex(); +    assert(FI && "No Frame Pointer Save Slot!"); + +    FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); +  } + +  // General register save area starts right below the Floating-point +  // register save area. +  if (HasGPSaveArea || HasG8SaveArea) { +    // Move general register save area spill slots down, taking into account +    // the size of the Floating-point register save area. +    for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) { +      int FI = GPRegs[i].getFrameIdx(); + +      FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); +    } + +    // Move general register save area spill slots down, taking into account +    // the size of the Floating-point register save area. +    for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) { +      int FI = G8Regs[i].getFrameIdx(); + +      FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); +    } + +    unsigned MinReg = +      std::min<unsigned>(PPCRegisterInfo::getRegisterNumbering(MinGPR), +                         PPCRegisterInfo::getRegisterNumbering(MinG8R)); + +    if (Subtarget.isPPC64()) { +      LowerBound -= (31 - MinReg + 1) * 8; +    } else { +      LowerBound -= (31 - MinReg + 1) * 4; +    } +  } + +  // The CR save area is below the general register save area. +  if (HasCRSaveArea) { +    // FIXME SVR4: Is it actually possible to have multiple elements in CSI +    //             which have the CR/CRBIT register class? +    // Adjust the frame index of the CR spill slot. +    for (unsigned i = 0, e = CSI.size(); i != e; ++i) { +      unsigned Reg = CSI[i].getReg(); + +      if (PPC::CRBITRCRegisterClass->contains(Reg) || +          PPC::CRRCRegisterClass->contains(Reg)) { +        int FI = CSI[i].getFrameIdx(); + +        FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); +      } +    } + +    LowerBound -= 4; // The CR save area is always 4 bytes long. +  } + +  if (HasVRSAVESaveArea) { +    // FIXME SVR4: Is it actually possible to have multiple elements in CSI +    //             which have the VRSAVE register class? +    // Adjust the frame index of the VRSAVE spill slot. +    for (unsigned i = 0, e = CSI.size(); i != e; ++i) { +      unsigned Reg = CSI[i].getReg(); + +      if (PPC::VRSAVERCRegisterClass->contains(Reg)) { +        int FI = CSI[i].getFrameIdx(); + +        FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); +      } +    } + +    LowerBound -= 4; // The VRSAVE save area is always 4 bytes long. +  } + +  if (HasVRSaveArea) { +    // Insert alignment padding, we need 16-byte alignment. +    LowerBound = (LowerBound - 15) & ~(15); + +    for (unsigned i = 0, e = VRegs.size(); i != e; ++i) { +      int FI = VRegs[i].getFrameIdx(); + +      FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); +    } +  } +} diff --git a/lib/Target/PowerPC/PPCFrameInfo.h b/lib/Target/PowerPC/PPCFrameInfo.h index 54448db..204aec8 100644 --- a/lib/Target/PowerPC/PPCFrameInfo.h +++ b/lib/Target/PowerPC/PPCFrameInfo.h @@ -40,6 +40,10 @@ public:    bool hasFP(const MachineFunction &MF) const;    void getInitialFrameState(std::vector<MachineMove> &Moves) const; +  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                            RegScavenger *RS = NULL) const; +  void processFunctionBeforeFrameFinalized(MachineFunction &MF) const; +    /// targetHandlesStackFrameRounding - Returns true if the target is    /// responsible for rounding up the stack frame (probably at emitPrologue    /// time). diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 182b65a..daef277 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -58,14 +58,11 @@ cl::opt<bool> EnablePPC64RS("enable-ppc64-regscavenger",  using namespace llvm; -#define EnableRegisterScavenging \ -  ((EnablePPC32RS && !Subtarget.isPPC64()) || \ -   (EnablePPC64RS && Subtarget.isPPC64())) -  // FIXME (64-bit): Should be inlined.  bool  PPCRegisterInfo::requiresRegisterScavenging(const MachineFunction &) const { -  return EnableRegisterScavenging; +  return ((EnablePPC32RS && !Subtarget.isPPC64()) || +          (EnablePPC64RS && Subtarget.isPPC64()));  }  /// getRegisterNumbering - Given the enum value for some register, e.g. @@ -259,11 +256,6 @@ PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {    return Subtarget.isPPC64() ? SVR4_64_CalleeSavedRegs : SVR4_CalleeSavedRegs;  } -static bool spillsCR(const MachineFunction &MF) { -  const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); -  return FuncInfo->isCRSpilled(); -} -  BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {    BitVector Reserved(getNumRegs());    const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); @@ -293,7 +285,7 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {      Reserved.set(PPC::R13);      Reserved.set(PPC::R31); -    if (!EnableRegisterScavenging) +    if (!requiresRegisterScavenging(MF))        Reserved.set(PPC::R0);    // FIXME (64-bit): Remove      Reserved.set(PPC::X0); @@ -323,22 +315,6 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {  // Stack Frame Processing methods  //===----------------------------------------------------------------------===// -/// MustSaveLR - Return true if this function requires that we save the LR -/// register onto the stack in the prolog and restore it in the epilog of the -/// function. -static bool MustSaveLR(const MachineFunction &MF, unsigned LR) { -  const PPCFunctionInfo *MFI = MF.getInfo<PPCFunctionInfo>(); -   -  // We need a save/restore of LR if there is any def of LR (which is -  // defined by calls, including the PIC setup sequence), or if there is -  // some use of the LR stack slot (e.g. for builtin_return_address). -  // (LR comes in 32 and 64 bit versions.) -  MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR); -  return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired(); -} - - -  void PPCRegisterInfo::  eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,                                MachineBasicBlock::iterator I) const { @@ -435,7 +411,7 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II,    // FIXME (64-bit): Use "findScratchRegister"    unsigned Reg; -  if (EnableRegisterScavenging) +  if (requiresRegisterScavenging(MF))      Reg = findScratchRegister(II, RS, RC, SPAdj);    else      Reg = PPC::R0; @@ -445,7 +421,7 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II,        .addReg(PPC::R31)        .addImm(FrameSize);    } else if (LP64) { -    if (EnableRegisterScavenging) // FIXME (64-bit): Use "true" part. +    if (requiresRegisterScavenging(MF)) // FIXME (64-bit): Use "true" part.        BuildMI(MBB, II, dl, TII.get(PPC::LD), Reg)          .addImm(0)          .addReg(PPC::X1); @@ -462,7 +438,7 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II,    // Grow the stack and update the stack pointer link, then determine the    // address of new allocated space.    if (LP64) { -    if (EnableRegisterScavenging) // FIXME (64-bit): Use "true" part. +    if (requiresRegisterScavenging(MF)) // FIXME (64-bit): Use "true" part.        BuildMI(MBB, II, dl, TII.get(PPC::STDUX))          .addReg(Reg, RegState::Kill)          .addReg(PPC::X1) @@ -597,7 +573,7 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,    }    // Special case for pseudo-op SPILL_CR. -  if (EnableRegisterScavenging) // FIXME (64-bit): Enable by default. +  if (requiresRegisterScavenging(MF)) // FIXME (64-bit): Enable by default.      if (OpC == PPC::SPILL_CR) {        lowerCRSpilling(II, FrameIndex, SPAdj, RS);        return; @@ -655,7 +631,7 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,    // FIXME (64-bit): Use "findScratchRegister".    unsigned SReg; -  if (EnableRegisterScavenging) +  if (requiresRegisterScavenging(MF))      SReg = findScratchRegister(II, RS, &PPC::GPRCRegClass, SPAdj);    else      SReg = PPC::R0; @@ -688,248 +664,6 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,    MI.getOperand(OperandBase + 1).ChangeToRegister(SReg, false);  } -void -PPCRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                                      RegScavenger *RS) const { -  const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); - -  //  Save and clear the LR state. -  PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>(); -  unsigned LR = getRARegister(); -  FI->setMustSaveLR(MustSaveLR(MF, LR)); -  MF.getRegInfo().setPhysRegUnused(LR); - -  //  Save R31 if necessary -  int FPSI = FI->getFramePointerSaveIndex(); -  bool isPPC64 = Subtarget.isPPC64(); -  bool isDarwinABI  = Subtarget.isDarwinABI(); -  MachineFrameInfo *MFI = MF.getFrameInfo(); - -  // If the frame pointer save index hasn't been defined yet. -  if (!FPSI && TFI->hasFP(MF)) { -    // Find out what the fix offset of the frame pointer save area. -    int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(isPPC64, -                                                           isDarwinABI); -    // Allocate the frame index for frame pointer save area. -    FPSI = MF.getFrameInfo()->CreateFixedObject(isPPC64? 8 : 4, FPOffset, true); -    // Save the result. -    FI->setFramePointerSaveIndex(FPSI); -  } - -  // Reserve stack space to move the linkage area to in case of a tail call. -  int TCSPDelta = 0; -  if (GuaranteedTailCallOpt && (TCSPDelta = FI->getTailCallSPDelta()) < 0) { -    MF.getFrameInfo()->CreateFixedObject(-1 * TCSPDelta, TCSPDelta, true); -  } - -  // Reserve a slot closest to SP or frame pointer if we have a dynalloc or -  // a large stack, which will require scavenging a register to materialize a -  // large offset. -  // FIXME: this doesn't actually check stack size, so is a bit pessimistic -  // FIXME: doesn't detect whether or not we need to spill vXX, which requires -  //        r0 for now. - -  if (EnableRegisterScavenging) // FIXME (64-bit): Enable. -    if (TFI->hasFP(MF) || spillsCR(MF)) { -      const TargetRegisterClass *GPRC = &PPC::GPRCRegClass; -      const TargetRegisterClass *G8RC = &PPC::G8RCRegClass; -      const TargetRegisterClass *RC = isPPC64 ? G8RC : GPRC; -      RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), -                                                         RC->getAlignment(), -                                                         false)); -    } -} - -void -PPCRegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) -                                                     const { -  // Early exit if not using the SVR4 ABI. -  if (!Subtarget.isSVR4ABI()) { -    return; -  } - -  // Get callee saved register information. -  MachineFrameInfo *FFI = MF.getFrameInfo(); -  const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); -  const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); - -  // Early exit if no callee saved registers are modified! -  if (CSI.empty() && !TFI->hasFP(MF)) { -    return; -  } - -  unsigned MinGPR = PPC::R31; -  unsigned MinG8R = PPC::X31; -  unsigned MinFPR = PPC::F31; -  unsigned MinVR = PPC::V31; -   -  bool HasGPSaveArea = false; -  bool HasG8SaveArea = false; -  bool HasFPSaveArea = false; -  bool HasCRSaveArea = false; -  bool HasVRSAVESaveArea = false; -  bool HasVRSaveArea = false; -   -  SmallVector<CalleeSavedInfo, 18> GPRegs; -  SmallVector<CalleeSavedInfo, 18> G8Regs; -  SmallVector<CalleeSavedInfo, 18> FPRegs; -  SmallVector<CalleeSavedInfo, 18> VRegs; -   -  for (unsigned i = 0, e = CSI.size(); i != e; ++i) { -    unsigned Reg = CSI[i].getReg(); -    if (PPC::GPRCRegisterClass->contains(Reg)) { -      HasGPSaveArea = true; -       -      GPRegs.push_back(CSI[i]); -       -      if (Reg < MinGPR) { -        MinGPR = Reg; -      } -    } else if (PPC::G8RCRegisterClass->contains(Reg)) { -      HasG8SaveArea = true; - -      G8Regs.push_back(CSI[i]); - -      if (Reg < MinG8R) { -        MinG8R = Reg; -      } -    } else if (PPC::F8RCRegisterClass->contains(Reg)) { -      HasFPSaveArea = true; -       -      FPRegs.push_back(CSI[i]); -       -      if (Reg < MinFPR) { -        MinFPR = Reg; -      } -// FIXME SVR4: Disable CR save area for now. -    } else if (PPC::CRBITRCRegisterClass->contains(Reg) -               || PPC::CRRCRegisterClass->contains(Reg)) { -//      HasCRSaveArea = true; -    } else if (PPC::VRSAVERCRegisterClass->contains(Reg)) { -      HasVRSAVESaveArea = true; -    } else if (PPC::VRRCRegisterClass->contains(Reg)) { -      HasVRSaveArea = true; -       -      VRegs.push_back(CSI[i]); -       -      if (Reg < MinVR) { -        MinVR = Reg; -      } -    } else { -      llvm_unreachable("Unknown RegisterClass!"); -    } -  } - -  PPCFunctionInfo *PFI = MF.getInfo<PPCFunctionInfo>(); -   -  int64_t LowerBound = 0; - -  // Take into account stack space reserved for tail calls. -  int TCSPDelta = 0; -  if (GuaranteedTailCallOpt && (TCSPDelta = PFI->getTailCallSPDelta()) < 0) { -    LowerBound = TCSPDelta; -  } - -  // The Floating-point register save area is right below the back chain word -  // of the previous stack frame. -  if (HasFPSaveArea) { -    for (unsigned i = 0, e = FPRegs.size(); i != e; ++i) { -      int FI = FPRegs[i].getFrameIdx(); -       -      FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); -    } -     -    LowerBound -= (31 - getRegisterNumbering(MinFPR) + 1) * 8;  -  } - -  // Check whether the frame pointer register is allocated. If so, make sure it -  // is spilled to the correct offset. -  if (TFI->hasFP(MF)) { -    HasGPSaveArea = true; -     -    int FI = PFI->getFramePointerSaveIndex(); -    assert(FI && "No Frame Pointer Save Slot!"); -     -    FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); -  } -   -  // General register save area starts right below the Floating-point -  // register save area. -  if (HasGPSaveArea || HasG8SaveArea) { -    // Move general register save area spill slots down, taking into account -    // the size of the Floating-point register save area. -    for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) { -      int FI = GPRegs[i].getFrameIdx(); -       -      FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); -    } -     -    // Move general register save area spill slots down, taking into account -    // the size of the Floating-point register save area. -    for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) { -      int FI = G8Regs[i].getFrameIdx(); - -      FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); -    } - -    unsigned MinReg = std::min<unsigned>(getRegisterNumbering(MinGPR), -                                         getRegisterNumbering(MinG8R)); - -    if (Subtarget.isPPC64()) { -      LowerBound -= (31 - MinReg + 1) * 8; -    } else { -      LowerBound -= (31 - MinReg + 1) * 4; -    } -  } -   -  // The CR save area is below the general register save area. -  if (HasCRSaveArea) { -    // FIXME SVR4: Is it actually possible to have multiple elements in CSI -    //             which have the CR/CRBIT register class? -    // Adjust the frame index of the CR spill slot. -    for (unsigned i = 0, e = CSI.size(); i != e; ++i) { -      unsigned Reg = CSI[i].getReg(); -     -      if (PPC::CRBITRCRegisterClass->contains(Reg) || -          PPC::CRRCRegisterClass->contains(Reg)) { -        int FI = CSI[i].getFrameIdx(); - -        FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); -      } -    } -     -    LowerBound -= 4; // The CR save area is always 4 bytes long. -  } -   -  if (HasVRSAVESaveArea) { -    // FIXME SVR4: Is it actually possible to have multiple elements in CSI -    //             which have the VRSAVE register class? -    // Adjust the frame index of the VRSAVE spill slot. -    for (unsigned i = 0, e = CSI.size(); i != e; ++i) { -      unsigned Reg = CSI[i].getReg(); -     -      if (PPC::VRSAVERCRegisterClass->contains(Reg)) { -        int FI = CSI[i].getFrameIdx(); - -        FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); -      } -    } -     -    LowerBound -= 4; // The VRSAVE save area is always 4 bytes long. -  } -   -  if (HasVRSaveArea) { -    // Insert alignment padding, we need 16-byte alignment. -    LowerBound = (LowerBound - 15) & ~(15); -     -    for (unsigned i = 0, e = VRegs.size(); i != e; ++i) { -      int FI = VRegs[i].getFrameIdx(); -       -      FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); -    } -  } -} -  unsigned PPCRegisterInfo::getRARegister() const {    return !Subtarget.isPPC64() ? PPC::LR : PPC::LR8;  } diff --git a/lib/Target/PowerPC/PPCRegisterInfo.h b/lib/Target/PowerPC/PPCRegisterInfo.h index 8a9b522..aa29ffe 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.h +++ b/lib/Target/PowerPC/PPCRegisterInfo.h @@ -59,10 +59,6 @@ public:    void eliminateFrameIndex(MachineBasicBlock::iterator II,                             int SPAdj, RegScavenger *RS = NULL) const; -  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                            RegScavenger *RS = NULL) const; -  void processFunctionBeforeFrameFinalized(MachineFunction &MF) const; -    // Debug information queries.    unsigned getRARegister() const;    unsigned getFrameRegister(const MachineFunction &MF) const; diff --git a/lib/Target/SystemZ/SystemZFrameInfo.cpp b/lib/Target/SystemZ/SystemZFrameInfo.cpp index 7fde9a0..d453940 100644 --- a/lib/Target/SystemZ/SystemZFrameInfo.cpp +++ b/lib/Target/SystemZ/SystemZFrameInfo.cpp @@ -351,3 +351,38 @@ SystemZFrameInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,    return true;  } + +void +SystemZFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                                       RegScavenger *RS) const { +  // Determine whether R15/R14 will ever be clobbered inside the function. And +  // if yes - mark it as 'callee' saved. +  MachineFrameInfo *FFI = MF.getFrameInfo(); +  MachineRegisterInfo &MRI = MF.getRegInfo(); + +  // Check whether high FPRs are ever used, if yes - we need to save R15 as +  // well. +  static const unsigned HighFPRs[] = { +    SystemZ::F8L,  SystemZ::F9L,  SystemZ::F10L, SystemZ::F11L, +    SystemZ::F12L, SystemZ::F13L, SystemZ::F14L, SystemZ::F15L, +    SystemZ::F8S,  SystemZ::F9S,  SystemZ::F10S, SystemZ::F11S, +    SystemZ::F12S, SystemZ::F13S, SystemZ::F14S, SystemZ::F15S, +  }; + +  bool HighFPRsUsed = false; +  for (unsigned i = 0, e = array_lengthof(HighFPRs); i != e; ++i) +    HighFPRsUsed |= MRI.isPhysRegUsed(HighFPRs[i]); + +  if (FFI->hasCalls()) +    /* FIXME: function is varargs */ +    /* FIXME: function grabs RA */ +    /* FIXME: function calls eh_return */ +    MRI.setPhysRegUsed(SystemZ::R14D); + +  if (HighFPRsUsed || +      FFI->hasCalls() || +      FFI->getObjectIndexEnd() != 0 || // Contains automatic variables +      FFI->hasVarSizedObjects() // Function calls dynamic alloca's +      /* FIXME: function is varargs */) +    MRI.setPhysRegUsed(SystemZ::R15D); +} diff --git a/lib/Target/SystemZ/SystemZFrameInfo.h b/lib/Target/SystemZ/SystemZFrameInfo.h index a977502..e7f25c6 100644 --- a/lib/Target/SystemZ/SystemZFrameInfo.h +++ b/lib/Target/SystemZ/SystemZFrameInfo.h @@ -44,6 +44,9 @@ public:                                     const std::vector<CalleeSavedInfo> &CSI,                                     const TargetRegisterInfo *TRI) const; +  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                            RegScavenger *RS) const; +    bool hasReservedCallFrame(const MachineFunction &MF) const { return true; }    bool hasFP(const MachineFunction &MF) const;    int getFrameIndexOffset(const MachineFunction &MF, int FI) const; diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/lib/Target/SystemZ/SystemZRegisterInfo.cpp index 32f81ce..401d88f 100644 --- a/lib/Target/SystemZ/SystemZRegisterInfo.cpp +++ b/lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -99,41 +99,6 @@ SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,    MI.getOperand(i+1).ChangeToImmediate(Offset);  } -void -SystemZRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                                       RegScavenger *RS) const { -  // Determine whether R15/R14 will ever be clobbered inside the function. And -  // if yes - mark it as 'callee' saved. -  MachineFrameInfo *FFI = MF.getFrameInfo(); -  MachineRegisterInfo &MRI = MF.getRegInfo(); - -  // Check whether high FPRs are ever used, if yes - we need to save R15 as -  // well. -  static const unsigned HighFPRs[] = { -    SystemZ::F8L,  SystemZ::F9L,  SystemZ::F10L, SystemZ::F11L, -    SystemZ::F12L, SystemZ::F13L, SystemZ::F14L, SystemZ::F15L, -    SystemZ::F8S,  SystemZ::F9S,  SystemZ::F10S, SystemZ::F11S, -    SystemZ::F12S, SystemZ::F13S, SystemZ::F14S, SystemZ::F15S, -  }; - -  bool HighFPRsUsed = false; -  for (unsigned i = 0, e = array_lengthof(HighFPRs); i != e; ++i) -    HighFPRsUsed |= MRI.isPhysRegUsed(HighFPRs[i]); - -  if (FFI->hasCalls()) -    /* FIXME: function is varargs */ -    /* FIXME: function grabs RA */ -    /* FIXME: function calls eh_return */ -    MRI.setPhysRegUsed(SystemZ::R14D); - -  if (HighFPRsUsed || -      FFI->hasCalls() || -      FFI->getObjectIndexEnd() != 0 || // Contains automatic variables -      FFI->hasVarSizedObjects() // Function calls dynamic alloca's -      /* FIXME: function is varargs */) -    MRI.setPhysRegUsed(SystemZ::R15D); -} -  unsigned SystemZRegisterInfo::getRARegister() const {    assert(0 && "What is the return address register");    return 0; diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.h b/lib/Target/SystemZ/SystemZRegisterInfo.h index 7d8dcfc..b450798 100644 --- a/lib/Target/SystemZ/SystemZRegisterInfo.h +++ b/lib/Target/SystemZ/SystemZRegisterInfo.h @@ -41,10 +41,6 @@ struct SystemZRegisterInfo : public SystemZGenRegisterInfo {    void eliminateFrameIndex(MachineBasicBlock::iterator II,                             int SPAdj, RegScavenger *RS = NULL) const; - -  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                            RegScavenger *RS) const; -    // Debug information queries.    unsigned getRARegister() const;    unsigned getFrameRegister(const MachineFunction &MF) const; diff --git a/lib/Target/X86/X86FrameInfo.cpp b/lib/Target/X86/X86FrameInfo.cpp index 192ed8e..494e905 100644 --- a/lib/Target/X86/X86FrameInfo.cpp +++ b/lib/Target/X86/X86FrameInfo.cpp @@ -870,3 +870,44 @@ bool X86FrameInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,    }    return true;  } + +void +X86FrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                                   RegScavenger *RS) const { +  MachineFrameInfo *MFI = MF.getFrameInfo(); +  const X86RegisterInfo *RegInfo = TM.getRegisterInfo(); +  unsigned SlotSize = RegInfo->getSlotSize(); + +  X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); +  int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); + +  if (TailCallReturnAddrDelta < 0) { +    // create RETURNADDR area +    //   arg +    //   arg +    //   RETADDR +    //   { ... +    //     RETADDR area +    //     ... +    //   } +    //   [EBP] +    MFI->CreateFixedObject(-TailCallReturnAddrDelta, +                           (-1U*SlotSize)+TailCallReturnAddrDelta, true); +  } + +  if (hasFP(MF)) { +    assert((TailCallReturnAddrDelta <= 0) && +           "The Delta should always be zero or negative"); +    const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); + +    // Create a frame entry for the EBP register that must be saved. +    int FrameIdx = MFI->CreateFixedObject(SlotSize, +                                          -(int)SlotSize + +                                          TFI.getOffsetOfLocalArea() + +                                          TailCallReturnAddrDelta, +                                          true); +    assert(FrameIdx == MFI->getObjectIndexBegin() && +           "Slot for EBP register must be last in order to be found!"); +    FrameIdx = 0; +  } +} diff --git a/lib/Target/X86/X86FrameInfo.h b/lib/Target/X86/X86FrameInfo.h index d265c61..fbbde92 100644 --- a/lib/Target/X86/X86FrameInfo.h +++ b/lib/Target/X86/X86FrameInfo.h @@ -40,15 +40,18 @@ public:    void emitPrologue(MachineFunction &MF) const;    void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; +  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                            RegScavenger *RS = NULL) const; +    bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,                                   MachineBasicBlock::iterator MI,                                   const std::vector<CalleeSavedInfo> &CSI,                                   const TargetRegisterInfo *TRI) const; -bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, -                                 MachineBasicBlock::iterator MI, -                                 const std::vector<CalleeSavedInfo> &CSI, -                                 const TargetRegisterInfo *TRI) const; +  bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, +                                   MachineBasicBlock::iterator MI, +                                   const std::vector<CalleeSavedInfo> &CSI, +                                   const TargetRegisterInfo *TRI) const;    bool hasFP(const MachineFunction &MF) const;    bool hasReservedCallFrame(const MachineFunction &MF) const; diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 3228b14..10266cd 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -609,46 +609,6 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,    }  } -void -X86RegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                                      RegScavenger *RS) const { -  MachineFrameInfo *MFI = MF.getFrameInfo(); -  const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); - -  X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); -  int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); - -  if (TailCallReturnAddrDelta < 0) { -    // create RETURNADDR area -    //   arg -    //   arg -    //   RETADDR -    //   { ... -    //     RETADDR area -    //     ... -    //   } -    //   [EBP] -    MFI->CreateFixedObject(-TailCallReturnAddrDelta, -                           (-1U*SlotSize)+TailCallReturnAddrDelta, true); -  } - -  if (TFI->hasFP(MF)) { -    assert((TailCallReturnAddrDelta <= 0) && -           "The Delta should always be zero or negative"); -    const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); - -    // Create a frame entry for the EBP register that must be saved. -    int FrameIdx = MFI->CreateFixedObject(SlotSize, -                                          -(int)SlotSize + -                                          TFI.getOffsetOfLocalArea() + -                                          TailCallReturnAddrDelta, -                                          true); -    assert(FrameIdx == MFI->getObjectIndexBegin() && -           "Slot for EBP register must be last in order to be found!"); -    FrameIdx = 0; -  } -} -  unsigned X86RegisterInfo::getRARegister() const {    return Is64Bit ? X86::RIP     // Should have dwarf #16.                   : X86::EIP;    // Should have dwarf #8. diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h index e6e235b..064be64 100644 --- a/lib/Target/X86/X86RegisterInfo.h +++ b/lib/Target/X86/X86RegisterInfo.h @@ -125,9 +125,6 @@ public:    void eliminateFrameIndex(MachineBasicBlock::iterator MI,                             int SPAdj, RegScavenger *RS = NULL) const; -  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                            RegScavenger *RS = NULL) const; -    // Debug information queries.    unsigned getRARegister() const;    unsigned getFrameRegister(const MachineFunction &MF) const; diff --git a/lib/Target/XCore/XCoreFrameInfo.cpp b/lib/Target/XCore/XCoreFrameInfo.cpp index cf957a7..117dc37 100644 --- a/lib/Target/XCore/XCoreFrameInfo.cpp +++ b/lib/Target/XCore/XCoreFrameInfo.cpp @@ -22,6 +22,7 @@  #include "llvm/CodeGen/MachineInstrBuilder.h"  #include "llvm/CodeGen/MachineModuleInfo.h"  #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/RegisterScavenging.h"  #include "llvm/Target/TargetData.h"  #include "llvm/Target/TargetOptions.h"  #include "llvm/Support/ErrorHandling.h" @@ -336,3 +337,46 @@ bool XCoreFrameInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,    }    return true;  } + +void +XCoreFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                                     RegScavenger *RS) const { +  MachineFrameInfo *MFI = MF.getFrameInfo(); +  const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); +  bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR); +  const TargetRegisterClass *RC = XCore::GRRegsRegisterClass; +  XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); +  if (LRUsed) { +    MF.getRegInfo().setPhysRegUnused(XCore::LR); + +    bool isVarArg = MF.getFunction()->isVarArg(); +    int FrameIdx; +    if (! isVarArg) { +      // A fixed offset of 0 allows us to save / restore LR using entsp / retsp. +      FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0, true); +    } else { +      FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment(), +                                        false); +    } +    XFI->setUsesLR(FrameIdx); +    XFI->setLRSpillSlot(FrameIdx); +  } +  if (RegInfo->requiresRegisterScavenging(MF)) { +    // Reserve a slot close to SP or frame pointer. +    RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), +                                                       RC->getAlignment(), +                                                       false)); +  } +  if (hasFP(MF)) { +    // A callee save register is used to hold the FP. +    // This needs saving / restoring in the epilogue / prologue. +    XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(), +                                               RC->getAlignment(), +                                               false)); +  } +} + +void XCoreFrameInfo:: +processFunctionBeforeFrameFinalized(MachineFunction &MF) const { + +} diff --git a/lib/Target/XCore/XCoreFrameInfo.h b/lib/Target/XCore/XCoreFrameInfo.h index 57983d1..9a98e16 100644 --- a/lib/Target/XCore/XCoreFrameInfo.h +++ b/lib/Target/XCore/XCoreFrameInfo.h @@ -44,6 +44,11 @@ namespace llvm {      void getInitialFrameState(std::vector<MachineMove> &Moves) const; +    void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, +                                              RegScavenger *RS = NULL) const; + +    void processFunctionBeforeFrameFinalized(MachineFunction &MF) const; +      //! Stack slot size (4 bytes)      static int stackSlotSize() {        return 4; diff --git a/lib/Target/XCore/XCoreRegisterInfo.cpp b/lib/Target/XCore/XCoreRegisterInfo.cpp index 1ee3c59..106d23b 100644 --- a/lib/Target/XCore/XCoreRegisterInfo.cpp +++ b/lib/Target/XCore/XCoreRegisterInfo.cpp @@ -295,49 +295,6 @@ XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,    MBB.erase(II);  } -void -XCoreRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                                      RegScavenger *RS) const { -  MachineFrameInfo *MFI = MF.getFrameInfo(); -  const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); -  bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR); -  const TargetRegisterClass *RC = XCore::GRRegsRegisterClass; -  XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); -  if (LRUsed) { -    MF.getRegInfo().setPhysRegUnused(XCore::LR); -     -    bool isVarArg = MF.getFunction()->isVarArg(); -    int FrameIdx; -    if (! isVarArg) { -      // A fixed offset of 0 allows us to save / restore LR using entsp / retsp. -      FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0, true); -    } else { -      FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment(), -                                        false); -    } -    XFI->setUsesLR(FrameIdx); -    XFI->setLRSpillSlot(FrameIdx); -  } -  if (requiresRegisterScavenging(MF)) { -    // Reserve a slot close to SP or frame pointer. -    RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), -                                                       RC->getAlignment(), -                                                       false)); -  } -  if (TFI->hasFP(MF)) { -    // A callee save register is used to hold the FP. -    // This needs saving / restoring in the epilogue / prologue. -    XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(), -                                               RC->getAlignment(), -                                               false)); -  } -} - -void XCoreRegisterInfo:: -processFunctionBeforeFrameFinalized(MachineFunction &MF) const { -   -} -  void XCoreRegisterInfo::  loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,              unsigned DstReg, int64_t Value, DebugLoc dl) const { diff --git a/lib/Target/XCore/XCoreRegisterInfo.h b/lib/Target/XCore/XCoreRegisterInfo.h index 3d21282..2185755 100644 --- a/lib/Target/XCore/XCoreRegisterInfo.h +++ b/lib/Target/XCore/XCoreRegisterInfo.h @@ -55,11 +55,6 @@ public:    void eliminateFrameIndex(MachineBasicBlock::iterator II,                             int SPAdj, RegScavenger *RS = NULL) const; -  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, -                                                RegScavenger *RS = NULL) const; - -  void processFunctionBeforeFrameFinalized(MachineFunction &MF) const; -    // Debug information queries.    unsigned getRARegister() const;    unsigned getFrameRegister(const MachineFunction &MF) const;  | 
