diff options
Diffstat (limited to 'lib/CodeGen/MachineFunction.cpp')
| -rw-r--r-- | lib/CodeGen/MachineFunction.cpp | 173 | 
1 files changed, 149 insertions, 24 deletions
diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index 91d521185767..04321f329282 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -14,28 +14,28 @@  //===----------------------------------------------------------------------===//  #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/DebugInfo.h" -#include "llvm/Function.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Analysis/ConstantFolding.h"  #include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineFunctionPass.h"  #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunctionPass.h"  #include "llvm/CodeGen/MachineInstr.h"  #include "llvm/CodeGen/MachineJumpTableInfo.h"  #include "llvm/CodeGen/MachineModuleInfo.h"  #include "llvm/CodeGen/MachineRegisterInfo.h"  #include "llvm/CodeGen/Passes.h" +#include "llvm/DebugInfo.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Function.h"  #include "llvm/MC/MCAsmInfo.h"  #include "llvm/MC/MCContext.h" -#include "llvm/Analysis/ConstantFolding.h"  #include "llvm/Support/Debug.h" -#include "llvm/DataLayout.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetFrameLowering.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/STLExtras.h"  #include "llvm/Support/GraphWriter.h"  #include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetFrameLowering.h" +#include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetMachine.h"  using namespace llvm;  //===----------------------------------------------------------------------===// @@ -58,14 +58,17 @@ MachineFunction::MachineFunction(const Function *F, const TargetMachine &TM,    else      RegInfo = 0;    MFInfo = 0; -  FrameInfo = new (Allocator) MachineFrameInfo(*TM.getFrameLowering()); -  if (Fn->getFnAttributes().hasAttribute(Attributes::StackAlignment)) +  FrameInfo = new (Allocator) MachineFrameInfo(*TM.getFrameLowering(), +                                               TM.Options.RealignStack); +  if (Fn->getAttributes().hasAttribute(AttributeSet::FunctionIndex, +                                       Attribute::StackAlignment))      FrameInfo->ensureMaxAlignment(Fn->getAttributes(). -                                  getFnAttributes().getStackAlignment()); +                                getStackAlignment(AttributeSet::FunctionIndex));    ConstantPool = new (Allocator) MachineConstantPool(TM.getDataLayout());    Alignment = TM.getTargetLowering()->getMinFunctionAlignment();    // FIXME: Shouldn't use pref alignment if explicit alignment is set on Fn. -  if (!Fn->getFnAttributes().hasAttribute(Attributes::OptimizeForSize)) +  if (!Fn->getAttributes().hasAttribute(AttributeSet::FunctionIndex, +                                        Attribute::OptimizeForSize))      Alignment = std::max(Alignment,                           TM.getTargetLowering()->getPrefFunctionAlignment());    FunctionNumber = FunctionNum; @@ -73,8 +76,15 @@ MachineFunction::MachineFunction(const Function *F, const TargetMachine &TM,  }  MachineFunction::~MachineFunction() { -  BasicBlocks.clear(); +  // Don't call destructors on MachineInstr and MachineOperand. All of their +  // memory comes from the BumpPtrAllocator which is about to be purged. +  // +  // Do call MachineBasicBlock destructors, it contains std::vectors. +  for (iterator I = begin(), E = end(); I != E; I = BasicBlocks.erase(I)) +    I->Insts.clearAndLeakNodesUnsafely(); +    InstructionRecycler.clear(Allocator); +  OperandRecycler.clear(Allocator);    BasicBlockRecycler.clear(Allocator);    if (RegInfo) {      RegInfo->~MachineRegisterInfo(); @@ -157,7 +167,7 @@ MachineInstr *  MachineFunction::CreateMachineInstr(const MCInstrDesc &MCID,                                      DebugLoc DL, bool NoImp) {    return new (InstructionRecycler.Allocate<MachineInstr>(Allocator)) -    MachineInstr(MCID, DL, NoImp); +    MachineInstr(*this, MCID, DL, NoImp);  }  /// CloneMachineInstr - Create a new MachineInstr which is a copy of the @@ -172,9 +182,17 @@ MachineFunction::CloneMachineInstr(const MachineInstr *Orig) {  /// DeleteMachineInstr - Delete the given MachineInstr.  /// +/// This function also serves as the MachineInstr destructor - the real +/// ~MachineInstr() destructor must be empty.  void  MachineFunction::DeleteMachineInstr(MachineInstr *MI) { -  MI->~MachineInstr(); +  // Strip it for parts. The operand array and the MI object itself are +  // independently recyclable. +  if (MI->Operands) +    deallocateOperandArray(MI->CapOperands, MI->Operands); +  // Don't call ~MachineInstr() which must be trivial anyway because +  // ~MachineFunction drops whole lists of MachineInstrs wihout calling their +  // destructors.    InstructionRecycler.Deallocate(Allocator, MI);  } @@ -328,13 +346,6 @@ void MachineFunction::print(raw_ostream &OS, SlotIndexes *Indexes) const {      }      OS << '\n';    } -  if (RegInfo && !RegInfo->liveout_empty()) { -    OS << "Function Live Outs:"; -    for (MachineRegisterInfo::liveout_iterator -         I = RegInfo->liveout_begin(), E = RegInfo->liveout_end(); I != E; ++I) -      OS << ' ' << PrintReg(*I, TRI); -    OS << '\n'; -  }    for (const_iterator BB = begin(), E = end(); BB != E; ++BB) {      OS << '\n'; @@ -445,6 +456,70 @@ MCSymbol *MachineFunction::getPICBaseSymbol() const {  //  MachineFrameInfo implementation  //===----------------------------------------------------------------------===// +/// ensureMaxAlignment - Make sure the function is at least Align bytes +/// aligned. +void MachineFrameInfo::ensureMaxAlignment(unsigned Align) { +  if (!TFI.isStackRealignable() || !RealignOption) +    assert(Align <= TFI.getStackAlignment() && +           "For targets without stack realignment, Align is out of limit!"); +  if (MaxAlignment < Align) MaxAlignment = Align; +} + +/// clampStackAlignment - Clamp the alignment if requested and emit a warning. +static inline unsigned clampStackAlignment(bool ShouldClamp, unsigned Align, +                                           unsigned StackAlign) { +  if (!ShouldClamp || Align <= StackAlign) +    return Align; +  DEBUG(dbgs() << "Warning: requested alignment " << Align +               << " exceeds the stack alignment " << StackAlign +               << " when stack realignment is off" << '\n'); +  return StackAlign; +} + +/// CreateStackObject - Create a new statically sized stack object, returning +/// a nonnegative identifier to represent it. +/// +int MachineFrameInfo::CreateStackObject(uint64_t Size, unsigned Alignment, +                      bool isSS, bool MayNeedSP, const AllocaInst *Alloca) { +  assert(Size != 0 && "Cannot allocate zero size stack objects!"); +  Alignment = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption, +                                  Alignment, TFI.getStackAlignment()); +  Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP, +                                Alloca)); +  int Index = (int)Objects.size() - NumFixedObjects - 1; +  assert(Index >= 0 && "Bad frame index!"); +  ensureMaxAlignment(Alignment); +  return Index; +} + +/// CreateSpillStackObject - Create a new statically sized stack object that +/// represents a spill slot, returning a nonnegative identifier to represent +/// it. +/// +int MachineFrameInfo::CreateSpillStackObject(uint64_t Size, +                                             unsigned Alignment) { +  Alignment = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption, +                                  Alignment, TFI.getStackAlignment());  +  CreateStackObject(Size, Alignment, true, false); +  int Index = (int)Objects.size() - NumFixedObjects - 1; +  ensureMaxAlignment(Alignment); +  return Index; +} + +/// CreateVariableSizedObject - Notify the MachineFrameInfo object that a +/// variable sized object has been created.  This must be created whenever a +/// variable sized object is created, whether or not the index returned is +/// actually used. +/// +int MachineFrameInfo::CreateVariableSizedObject(unsigned Alignment) { +  HasVarSizedObjects = true; +  Alignment = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption, +                                  Alignment, TFI.getStackAlignment());  +  Objects.push_back(StackObject(0, Alignment, 0, false, false, true, 0)); +  ensureMaxAlignment(Alignment); +  return (int)Objects.size()-NumFixedObjects-1; +} +  /// CreateFixedObject - Create a new object at a fixed location on the stack.  /// All fixed objects should be created before other objects are created for  /// efficiency. By default, fixed objects are immutable. This returns an @@ -459,6 +534,8 @@ int MachineFrameInfo::CreateFixedObject(uint64_t Size, int64_t SPOffset,    // object is 16-byte aligned.    unsigned StackAlign = TFI.getStackAlignment();    unsigned Align = MinAlign(SPOffset, StackAlign); +  Align = clampStackAlignment(!TFI.isStackRealignable() || !RealignOption, +                              Align, TFI.getStackAlignment());     Objects.insert(Objects.begin(), StackObject(Size, Align, SPOffset, Immutable,                                                /*isSS*/   false,                                                /*NeedSP*/ false, @@ -497,6 +574,54 @@ MachineFrameInfo::getPristineRegs(const MachineBasicBlock *MBB) const {    return BV;  } +unsigned MachineFrameInfo::estimateStackSize(const MachineFunction &MF) const { +  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); +  const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); +  unsigned MaxAlign = getMaxAlignment(); +  int Offset = 0; + +  // This code is very, very similar to PEI::calculateFrameObjectOffsets(). +  // It really should be refactored to share code. Until then, changes +  // should keep in mind that there's tight coupling between the two. + +  for (int i = getObjectIndexBegin(); i != 0; ++i) { +    int FixedOff = -getObjectOffset(i); +    if (FixedOff > Offset) Offset = FixedOff; +  } +  for (unsigned i = 0, e = getObjectIndexEnd(); i != e; ++i) { +    if (isDeadObjectIndex(i)) +      continue; +    Offset += getObjectSize(i); +    unsigned Align = getObjectAlignment(i); +    // Adjust to alignment boundary +    Offset = (Offset+Align-1)/Align*Align; + +    MaxAlign = std::max(Align, MaxAlign); +  } + +  if (adjustsStack() && TFI->hasReservedCallFrame(MF)) +    Offset += getMaxCallFrameSize(); + +  // Round up the size to a multiple of the alignment.  If the function has +  // any calls or alloca's, align to the target's StackAlignment value to +  // ensure that the callee's frame or the alloca data is suitably aligned; +  // otherwise, for leaf functions, align to the TransientStackAlignment +  // value. +  unsigned StackAlign; +  if (adjustsStack() || hasVarSizedObjects() || +      (RegInfo->needsStackRealignment(MF) && getObjectIndexEnd() != 0)) +    StackAlign = TFI->getStackAlignment(); +  else +    StackAlign = TFI->getTransientStackAlignment(); + +  // If the frame pointer is eliminated, all frame offsets will be relative to +  // SP not FP. Align to MaxAlign so this works. +  StackAlign = std::max(StackAlign, MaxAlign); +  unsigned AlignMask = StackAlign - 1; +  Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); + +  return (unsigned)Offset; +}  void MachineFrameInfo::print(const MachineFunction &MF, raw_ostream &OS) const{    if (Objects.empty()) return;  | 
