diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2011-02-20 12:57:14 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2011-02-20 12:57:14 +0000 | 
| commit | cf099d11218cb6f6c5cce947d6738e347f07fb12 (patch) | |
| tree | d2b61ce94e654cb01a254d2195259db5f9cc3f3c /lib/CodeGen/MachineSink.cpp | |
| parent | 49011b52fcba02a6051957b84705159f52fae4e4 (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/MachineSink.cpp')
| -rw-r--r-- | lib/CodeGen/MachineSink.cpp | 312 | 
1 files changed, 237 insertions, 75 deletions
diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp index c8f8fafe227e..8a93a24287b6 100644 --- a/lib/CodeGen/MachineSink.cpp +++ b/lib/CodeGen/MachineSink.cpp @@ -25,6 +25,7 @@  #include "llvm/Target/TargetRegisterInfo.h"  #include "llvm/Target/TargetInstrInfo.h"  #include "llvm/Target/TargetMachine.h" +#include "llvm/ADT/SmallSet.h"  #include "llvm/ADT/Statistic.h"  #include "llvm/Support/CommandLine.h"  #include "llvm/Support/Debug.h" @@ -34,27 +35,31 @@ using namespace llvm;  static cl::opt<bool>   SplitEdges("machine-sink-split",             cl::desc("Split critical edges during machine sinking"), -           cl::init(false), cl::Hidden); -static cl::opt<unsigned> -SplitLimit("split-limit", -           cl::init(~0u), cl::Hidden); +           cl::init(true), cl::Hidden); -STATISTIC(NumSunk,  "Number of machine instructions sunk"); -STATISTIC(NumSplit, "Number of critical edges split"); +STATISTIC(NumSunk,      "Number of machine instructions sunk"); +STATISTIC(NumSplit,     "Number of critical edges split"); +STATISTIC(NumCoalesces, "Number of copies coalesced");  namespace {    class MachineSinking : public MachineFunctionPass {      const TargetInstrInfo *TII;      const TargetRegisterInfo *TRI; -    MachineRegisterInfo  *RegInfo; // Machine register information +    MachineRegisterInfo  *MRI;  // Machine register information      MachineDominatorTree *DT;   // Machine dominator tree      MachineLoopInfo *LI;      AliasAnalysis *AA;      BitVector AllocatableSet;   // Which physregs are allocatable? +    // Remember which edges have been considered for breaking. +    SmallSet<std::pair<MachineBasicBlock*,MachineBasicBlock*>, 8> +    CEBCandidates; +    public:      static char ID; // Pass identification -    MachineSinking() : MachineFunctionPass(ID) {} +    MachineSinking() : MachineFunctionPass(ID) { +      initializeMachineSinkingPass(*PassRegistry::getPassRegistry()); +    }      virtual bool runOnMachineFunction(MachineFunction &MF); @@ -67,43 +72,125 @@ namespace {        AU.addPreserved<MachineDominatorTree>();        AU.addPreserved<MachineLoopInfo>();      } + +    virtual void releaseMemory() { +      CEBCandidates.clear(); +    } +    private:      bool ProcessBlock(MachineBasicBlock &MBB); -    MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *From, -                                         MachineBasicBlock *To); +    bool isWorthBreakingCriticalEdge(MachineInstr *MI, +                                     MachineBasicBlock *From, +                                     MachineBasicBlock *To); +    MachineBasicBlock *SplitCriticalEdge(MachineInstr *MI, +                                         MachineBasicBlock *From, +                                         MachineBasicBlock *To, +                                         bool BreakPHIEdge);      bool SinkInstruction(MachineInstr *MI, bool &SawStore);      bool AllUsesDominatedByBlock(unsigned Reg, MachineBasicBlock *MBB, -                               MachineBasicBlock *DefMBB, bool &LocalUse) const; +                                 MachineBasicBlock *DefMBB, +                                 bool &BreakPHIEdge, bool &LocalUse) const; +    bool PerformTrivialForwardCoalescing(MachineInstr *MI, +                                         MachineBasicBlock *MBB);    };  } // end anonymous namespace  char MachineSinking::ID = 0; -INITIALIZE_PASS(MachineSinking, "machine-sink", -                "Machine code sinking", false, false); +INITIALIZE_PASS_BEGIN(MachineSinking, "machine-sink", +                "Machine code sinking", false, false) +INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) +INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) +INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_END(MachineSinking, "machine-sink", +                "Machine code sinking", false, false)  FunctionPass *llvm::createMachineSinkingPass() { return new MachineSinking(); } +bool MachineSinking::PerformTrivialForwardCoalescing(MachineInstr *MI, +                                                     MachineBasicBlock *MBB) { +  if (!MI->isCopy()) +    return false; + +  unsigned SrcReg = MI->getOperand(1).getReg(); +  unsigned DstReg = MI->getOperand(0).getReg(); +  if (!TargetRegisterInfo::isVirtualRegister(SrcReg) || +      !TargetRegisterInfo::isVirtualRegister(DstReg) || +      !MRI->hasOneNonDBGUse(SrcReg)) +    return false; + +  const TargetRegisterClass *SRC = MRI->getRegClass(SrcReg); +  const TargetRegisterClass *DRC = MRI->getRegClass(DstReg); +  if (SRC != DRC) +    return false; + +  MachineInstr *DefMI = MRI->getVRegDef(SrcReg); +  if (DefMI->isCopyLike()) +    return false; +  DEBUG(dbgs() << "Coalescing: " << *DefMI); +  DEBUG(dbgs() << "*** to: " << *MI); +  MRI->replaceRegWith(DstReg, SrcReg); +  MI->eraseFromParent(); +  ++NumCoalesces; +  return true; +} +  /// AllUsesDominatedByBlock - Return true if all uses of the specified register  /// occur in blocks dominated by the specified block. If any use is in the  /// definition block, then return false since it is never legal to move def  /// after uses. -bool MachineSinking::AllUsesDominatedByBlock(unsigned Reg, -                                             MachineBasicBlock *MBB, -                                             MachineBasicBlock *DefMBB, -                                             bool &LocalUse) const { +bool +MachineSinking::AllUsesDominatedByBlock(unsigned Reg, +                                        MachineBasicBlock *MBB, +                                        MachineBasicBlock *DefMBB, +                                        bool &BreakPHIEdge, +                                        bool &LocalUse) const {    assert(TargetRegisterInfo::isVirtualRegister(Reg) &&           "Only makes sense for vregs"); + +  if (MRI->use_nodbg_empty(Reg)) +    return true; +    // Ignoring debug uses is necessary so debug info doesn't affect the code.    // This may leave a referencing dbg_value in the original block, before    // the definition of the vreg.  Dwarf generator handles this although the    // user might not get the right info at runtime. + +  // BreakPHIEdge is true if all the uses are in the successor MBB being sunken +  // into and they are all PHI nodes. In this case, machine-sink must break +  // the critical edge first. e.g. +  // +  // BB#1: derived from LLVM BB %bb4.preheader +  //   Predecessors according to CFG: BB#0 +  //     ... +  //     %reg16385<def> = DEC64_32r %reg16437, %EFLAGS<imp-def,dead> +  //     ... +  //     JE_4 <BB#37>, %EFLAGS<imp-use> +  //   Successors according to CFG: BB#37 BB#2 +  // +  // BB#2: derived from LLVM BB %bb.nph +  //   Predecessors according to CFG: BB#0 BB#1 +  //     %reg16386<def> = PHI %reg16434, <BB#0>, %reg16385, <BB#1> +  BreakPHIEdge = true;    for (MachineRegisterInfo::use_nodbg_iterator -         I = RegInfo->use_nodbg_begin(Reg), E = RegInfo->use_nodbg_end(); +         I = MRI->use_nodbg_begin(Reg), E = MRI->use_nodbg_end();         I != E; ++I) { -    // Determine the block of the use.      MachineInstr *UseInst = &*I;      MachineBasicBlock *UseBlock = UseInst->getParent(); +    if (!(UseBlock == MBB && UseInst->isPHI() && +          UseInst->getOperand(I.getOperandNo()+1).getMBB() == DefMBB)) { +      BreakPHIEdge = false; +      break; +    } +  } +  if (BreakPHIEdge) +    return true; +  for (MachineRegisterInfo::use_nodbg_iterator +         I = MRI->use_nodbg_begin(Reg), E = MRI->use_nodbg_end(); +       I != E; ++I) { +    // Determine the block of the use. +    MachineInstr *UseInst = &*I; +    MachineBasicBlock *UseBlock = UseInst->getParent();      if (UseInst->isPHI()) {        // PHI nodes use the operand in the predecessor block, not the block with        // the PHI. @@ -127,7 +214,7 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {    const TargetMachine &TM = MF.getTarget();    TII = TM.getInstrInfo();    TRI = TM.getRegisterInfo(); -  RegInfo = &MF.getRegInfo(); +  MRI = &MF.getRegInfo();    DT = &getAnalysis<MachineDominatorTree>();    LI = &getAnalysis<MachineLoopInfo>();    AA = &getAnalysis<AliasAnalysis>(); @@ -139,6 +226,7 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {      bool MadeChange = false;      // Process all basic blocks. +    CEBCandidates.clear();      for (MachineFunction::iterator I = MF.begin(), E = MF.end();           I != E; ++I)        MadeChange |= ProcessBlock(*I); @@ -177,6 +265,9 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {      if (MI->isDebugValue())        continue; +    if (PerformTrivialForwardCoalescing(MI, &MBB)) +      continue; +      if (SinkInstruction(MI, SawStore))        ++NumSunk, MadeChange = true; @@ -186,51 +277,92 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {    return MadeChange;  } -MachineBasicBlock *MachineSinking::SplitCriticalEdge(MachineBasicBlock *FromBB, -                                                     MachineBasicBlock *ToBB) { +bool MachineSinking::isWorthBreakingCriticalEdge(MachineInstr *MI, +                                                 MachineBasicBlock *From, +                                                 MachineBasicBlock *To) { +  // FIXME: Need much better heuristics. + +  // If the pass has already considered breaking this edge (during this pass +  // through the function), then let's go ahead and break it. This means +  // sinking multiple "cheap" instructions into the same block. +  if (!CEBCandidates.insert(std::make_pair(From, To))) +    return true; + +  if (!MI->isCopy() && !MI->getDesc().isAsCheapAsAMove()) +    return true; + +  // MI is cheap, we probably don't want to break the critical edge for it. +  // However, if this would allow some definitions of its source operands +  // to be sunk then it's probably worth it. +  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { +    const MachineOperand &MO = MI->getOperand(i); +    if (!MO.isReg()) continue; +    unsigned Reg = MO.getReg(); +    if (Reg == 0 || !TargetRegisterInfo::isPhysicalRegister(Reg)) +      continue; +    if (MRI->hasOneNonDBGUse(Reg)) +      return true; +  } + +  return false; +} + +MachineBasicBlock *MachineSinking::SplitCriticalEdge(MachineInstr *MI, +                                                     MachineBasicBlock *FromBB, +                                                     MachineBasicBlock *ToBB, +                                                     bool BreakPHIEdge) { +  if (!isWorthBreakingCriticalEdge(MI, FromBB, ToBB)) +    return 0; +    // Avoid breaking back edge. From == To means backedge for single BB loop. -  if (!SplitEdges || NumSplit == SplitLimit || FromBB == ToBB) +  if (!SplitEdges || FromBB == ToBB) +    return 0; + +  // Check for backedges of more "complex" loops. +  if (LI->getLoopFor(FromBB) == LI->getLoopFor(ToBB) && +      LI->isLoopHeader(ToBB))      return 0; -  // Check for more "complex" loops. -  if (LI->getLoopFor(FromBB) != LI->getLoopFor(ToBB) || -      !LI->isLoopHeader(ToBB)) { -    // It's not always legal to break critical edges and sink the computation -    // to the edge. -    // -    // BB#1: -    // v1024 -    // Beq BB#3 -    // <fallthrough> -    // BB#2: -    // ... no uses of v1024 -    // <fallthrough> -    // BB#3: -    // ... -    //       = v1024 -    // -    // If BB#1 -> BB#3 edge is broken and computation of v1024 is inserted: -    // -    // BB#1: -    // ... -    // Bne BB#2 -    // BB#4: -    // v1024 = -    // B BB#3 -    // BB#2: -    // ... no uses of v1024 -    // <fallthrough> -    // BB#3: -    // ... -    //       = v1024 -    // -    // This is incorrect since v1024 is not computed along the BB#1->BB#2->BB#3 -    // flow. We need to ensure the new basic block where the computation is -    // sunk to dominates all the uses. -    // It's only legal to break critical edge and sink the computation to the -    // new block if all the predecessors of "To", except for "From", are -    // not dominated by "From". Given SSA property, this means these -    // predecessors are dominated by "To". +  // It's not always legal to break critical edges and sink the computation +  // to the edge. +  // +  // BB#1: +  // v1024 +  // Beq BB#3 +  // <fallthrough> +  // BB#2: +  // ... no uses of v1024 +  // <fallthrough> +  // BB#3: +  // ... +  //       = v1024 +  // +  // If BB#1 -> BB#3 edge is broken and computation of v1024 is inserted: +  // +  // BB#1: +  // ... +  // Bne BB#2 +  // BB#4: +  // v1024 = +  // B BB#3 +  // BB#2: +  // ... no uses of v1024 +  // <fallthrough> +  // BB#3: +  // ... +  //       = v1024 +  // +  // This is incorrect since v1024 is not computed along the BB#1->BB#2->BB#3 +  // flow. We need to ensure the new basic block where the computation is +  // sunk to dominates all the uses. +  // It's only legal to break critical edge and sink the computation to the +  // new block if all the predecessors of "To", except for "From", are +  // not dominated by "From". Given SSA property, this means these +  // predecessors are dominated by "To". +  // +  // There is no need to do this check if all the uses are PHI nodes. PHI +  // sources are only defined on the specific predecessor edges. +  if (!BreakPHIEdge) {      for (MachineBasicBlock::pred_iterator PI = ToBB->pred_begin(),             E = ToBB->pred_end(); PI != E; ++PI) {        if (*PI == FromBB) @@ -238,17 +370,23 @@ MachineBasicBlock *MachineSinking::SplitCriticalEdge(MachineBasicBlock *FromBB,        if (!DT->dominates(ToBB, *PI))          return 0;      } - -    // FIXME: Determine if it's cost effective to break this edge. -    return FromBB->SplitCriticalEdge(ToBB, this);    } -  return 0; +  return FromBB->SplitCriticalEdge(ToBB, this); +} + +static bool AvoidsSinking(MachineInstr *MI, MachineRegisterInfo *MRI) { +  return MI->isInsertSubreg() || MI->isSubregToReg() || MI->isRegSequence();  }  /// SinkInstruction - Determine whether it is safe to sink the specified machine  /// instruction out of its current block into a successor.  bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) { +  // Don't sink insert_subreg, subreg_to_reg, reg_sequence. These are meant to +  // be close to the source to make it easier to coalesce. +  if (AvoidsSinking(MI, MRI)) +    return false; +    // Check if it's safe to move the instruction.    if (!MI->isSafeToMove(TII, AA, SawStore))      return false; @@ -269,6 +407,7 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {    // decide.    MachineBasicBlock *SuccToSinkTo = 0; +  bool BreakPHIEdge = false;    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {      const MachineOperand &MO = MI->getOperand(i);      if (!MO.isReg()) continue;  // Ignore non-register operands. @@ -281,7 +420,7 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {          // If the physreg has no defs anywhere, it's just an ambient register          // and we can freely move its uses. Alternatively, if it's allocatable,          // it could get allocated to something with a def during allocation. -        if (!RegInfo->def_empty(Reg)) +        if (!MRI->def_empty(Reg))            return false;          if (AllocatableSet.test(Reg)) @@ -290,7 +429,7 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {          // Check for a def among the register's aliases too.          for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {            unsigned AliasReg = *Alias; -          if (!RegInfo->def_empty(AliasReg)) +          if (!MRI->def_empty(AliasReg))              return false;            if (AllocatableSet.test(AliasReg)) @@ -305,7 +444,7 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {        if (MO.isUse()) continue;        // If it's not safe to move defs of the register class, then abort. -      if (!TII->isSafeToMoveRegClassDefs(RegInfo->getRegClass(Reg))) +      if (!TII->isSafeToMoveRegClassDefs(MRI->getRegClass(Reg)))          return false;        // FIXME: This picks a successor to sink into based on having one @@ -327,7 +466,8 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {          // If a previous operand picked a block to sink to, then this operand          // must be sinkable to the same block.          bool LocalUse = false; -        if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo, ParentBlock, LocalUse)) +        if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo, ParentBlock, +                                     BreakPHIEdge, LocalUse))            return false;          continue; @@ -338,7 +478,8 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {        for (MachineBasicBlock::succ_iterator SI = ParentBlock->succ_begin(),             E = ParentBlock->succ_end(); SI != E; ++SI) {          bool LocalUse = false; -        if (AllUsesDominatedByBlock(Reg, *SI, ParentBlock, LocalUse)) { +        if (AllUsesDominatedByBlock(Reg, *SI, ParentBlock, +                                    BreakPHIEdge, LocalUse)) {            SuccToSinkTo = *SI;            break;          } @@ -384,7 +525,6 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {    // If the block has multiple predecessors, this would introduce computation on    // a path that it doesn't already exist.  We could split the critical edge,    // but for now we just punt. -  // FIXME: Split critical edges if not backedges.    if (SuccToSinkTo->pred_size() > 1) {      // We cannot sink a load across a critical edge - there may be stores in      // other code paths. @@ -412,10 +552,11 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {      if (!TryBreak)        DEBUG(dbgs() << "Sinking along critical edge.\n");      else { -      MachineBasicBlock *NewSucc = SplitCriticalEdge(ParentBlock, SuccToSinkTo); +      MachineBasicBlock *NewSucc = +        SplitCriticalEdge(MI, ParentBlock, SuccToSinkTo, BreakPHIEdge);        if (!NewSucc) { -        DEBUG(dbgs() << -              " *** PUNTING: Not legal or profitable to break critical edge\n"); +        DEBUG(dbgs() << " *** PUNTING: Not legal or profitable to " +                        "break critical edge\n");          return false;        } else {          DEBUG(dbgs() << " *** Splitting critical edge:" @@ -424,10 +565,31 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {                << " -- BB#" << SuccToSinkTo->getNumber() << '\n');          SuccToSinkTo = NewSucc;          ++NumSplit; +        BreakPHIEdge = false;        }      }    } +  if (BreakPHIEdge) { +    // BreakPHIEdge is true if all the uses are in the successor MBB being +    // sunken into and they are all PHI nodes. In this case, machine-sink must +    // break the critical edge first. +    MachineBasicBlock *NewSucc = SplitCriticalEdge(MI, ParentBlock, +                                                   SuccToSinkTo, BreakPHIEdge); +    if (!NewSucc) { +      DEBUG(dbgs() << " *** PUNTING: Not legal or profitable to " +            "break critical edge\n"); +      return false; +    } + +    DEBUG(dbgs() << " *** Splitting critical edge:" +          " BB#" << ParentBlock->getNumber() +          << " -- BB#" << NewSucc->getNumber() +          << " -- BB#" << SuccToSinkTo->getNumber() << '\n'); +    SuccToSinkTo = NewSucc; +    ++NumSplit; +  } +    // Determine where to insert into. Skip phi nodes.    MachineBasicBlock::iterator InsertPos = SuccToSinkTo->begin();    while (InsertPos != SuccToSinkTo->end() && InsertPos->isPHI())  | 
