diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2014-03-18 19:23:41 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2014-03-18 19:23:41 +0000 | 
| commit | 4f00c8c645ed203d6be62502f5c477e3aeee720b (patch) | |
| tree | ad1f1a1affa2ca2d4fb6a38d6f7ce0e92b196fd5 /contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp | |
| parent | f42ca756b99c73564d3c218a5141d025bda99bc9 (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp')
| -rw-r--r-- | contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp | 41 | 
1 files changed, 40 insertions, 1 deletions
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index 4309dc1d48cb..e9d23244f4d6 100644 --- a/contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -33,6 +33,7 @@  #include "llvm/Support/ErrorHandling.h"  #include "llvm/Support/MathExtras.h"  #include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetFrameLowering.h"  #include "llvm/Target/TargetLowering.h"  #include "llvm/Target/TargetOptions.h"  #include "llvm/Target/TargetRegisterInfo.h" @@ -55,7 +56,8 @@ static bool isUsedOutsideOfDefiningBlock(const Instruction *I) {    return false;  } -void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf) { +void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, +                               SelectionDAG *DAG) {    const TargetLowering *TLI = TM.getTargetLowering();    Fn = &fn; @@ -100,6 +102,43 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf) {    for (; BB != EB; ++BB)      for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();           I != E; ++I) { +      // Look for dynamic allocas. +      if (const AllocaInst *AI = dyn_cast<AllocaInst>(I)) { +        if (!AI->isStaticAlloca()) { +          unsigned Align = std::max( +              (unsigned)TLI->getDataLayout()->getPrefTypeAlignment( +                AI->getAllocatedType()), +              AI->getAlignment()); +          unsigned StackAlign = TM.getFrameLowering()->getStackAlignment(); +          if (Align <= StackAlign) +            Align = 0; +          // Inform the Frame Information that we have variable-sized objects. +          MF->getFrameInfo()->CreateVariableSizedObject(Align ? Align : 1, AI); +        } +      } + +      // Look for inline asm that clobbers the SP register. +      if (isa<CallInst>(I) || isa<InvokeInst>(I)) { +        ImmutableCallSite CS(I); +        if (const InlineAsm *IA = dyn_cast<InlineAsm>(CS.getCalledValue())) { +          unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); +          std::vector<TargetLowering::AsmOperandInfo> Ops = +            TLI->ParseConstraints(CS); +          for (size_t I = 0, E = Ops.size(); I != E; ++I) { +            TargetLowering::AsmOperandInfo &Op = Ops[I]; +            if (Op.Type == InlineAsm::isClobber) { +              // Clobbers don't have SDValue operands, hence SDValue(). +              TLI->ComputeConstraintToUse(Op, SDValue(), DAG); +              std::pair<unsigned, const TargetRegisterClass*> PhysReg = +                TLI->getRegForInlineAsmConstraint(Op.ConstraintCode, +                                                  Op.ConstraintVT); +              if (PhysReg.first == SP) +                MF->getFrameInfo()->setHasInlineAsmWithSPAdjust(true); +            } +          } +        } +      } +        // Mark values used outside their block as exported, by allocating        // a virtual register for them.        if (isUsedOutsideOfDefiningBlock(I))  | 
