diff options
Diffstat (limited to 'lib/CodeGen/MachineBasicBlock.cpp')
| -rw-r--r-- | lib/CodeGen/MachineBasicBlock.cpp | 239 | 
1 files changed, 176 insertions, 63 deletions
| diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index 209abf34d885..38e8369dc739 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -24,6 +24,7 @@  #include "llvm/CodeGen/TargetInstrInfo.h"  #include "llvm/CodeGen/TargetRegisterInfo.h"  #include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/Config/llvm-config.h"  #include "llvm/IR/BasicBlock.h"  #include "llvm/IR/DataLayout.h"  #include "llvm/IR/DebugInfoMetadata.h" @@ -173,7 +174,7 @@ MachineBasicBlock::SkipPHIsLabelsAndDebug(MachineBasicBlock::iterator I) {    const TargetInstrInfo *TII = getParent()->getSubtarget().getInstrInfo();    iterator E = end(); -  while (I != E && (I->isPHI() || I->isPosition() || I->isDebugValue() || +  while (I != E && (I->isPHI() || I->isPosition() || I->isDebugInstr() ||                      TII->isBasicBlockPrologue(*I)))      ++I;    // FIXME: This needs to change if we wish to bundle labels / dbg_values @@ -186,7 +187,7 @@ MachineBasicBlock::SkipPHIsLabelsAndDebug(MachineBasicBlock::iterator I) {  MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() {    iterator B = begin(), E = end(), I = E; -  while (I != B && ((--I)->isTerminator() || I->isDebugValue())) +  while (I != B && ((--I)->isTerminator() || I->isDebugInstr()))      ; /*noop */    while (I != E && !I->isTerminator())      ++I; @@ -195,7 +196,7 @@ MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() {  MachineBasicBlock::instr_iterator MachineBasicBlock::getFirstInstrTerminator() {    instr_iterator B = instr_begin(), E = instr_end(), I = E; -  while (I != B && ((--I)->isTerminator() || I->isDebugValue())) +  while (I != B && ((--I)->isTerminator() || I->isDebugInstr()))      ; /*noop */    while (I != E && !I->isTerminator())      ++I; @@ -213,7 +214,7 @@ MachineBasicBlock::iterator MachineBasicBlock::getLastNonDebugInstr() {    while (I != B) {      --I;      // Return instruction that starts a bundle. -    if (I->isDebugValue() || I->isInsideBundle()) +    if (I->isDebugInstr() || I->isInsideBundle())        continue;      return I;    } @@ -259,8 +260,8 @@ std::string MachineBasicBlock::getFullName() const {    return Name;  } -void MachineBasicBlock::print(raw_ostream &OS, const SlotIndexes *Indexes) -    const { +void MachineBasicBlock::print(raw_ostream &OS, const SlotIndexes *Indexes, +                              bool IsStandalone) const {    const MachineFunction *MF = getParent();    if (!MF) {      OS << "Can't print out MachineBasicBlock because parent MachineFunction" @@ -270,11 +271,13 @@ void MachineBasicBlock::print(raw_ostream &OS, const SlotIndexes *Indexes)    const Function &F = MF->getFunction();    const Module *M = F.getParent();    ModuleSlotTracker MST(M); -  print(OS, MST, Indexes); +  MST.incorporateFunction(F); +  print(OS, MST, Indexes, IsStandalone);  }  void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST, -                              const SlotIndexes *Indexes) const { +                              const SlotIndexes *Indexes, +                              bool IsStandalone) const {    const MachineFunction *MF = getParent();    if (!MF) {      OS << "Can't print out MachineBasicBlock because parent MachineFunction" @@ -285,70 +288,143 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,    if (Indexes)      OS << Indexes->getMBBStartIdx(this) << '\t'; -  OS << printMBBReference(*this) << ": "; - -  const char *Comma = ""; -  if (const BasicBlock *LBB = getBasicBlock()) { -    OS << Comma << "derived from LLVM BB "; -    LBB->printAsOperand(OS, /*PrintType=*/false, MST); -    Comma = ", "; +  OS << "bb." << getNumber(); +  bool HasAttributes = false; +  if (const auto *BB = getBasicBlock()) { +    if (BB->hasName()) { +      OS << "." << BB->getName(); +    } else { +      HasAttributes = true; +      OS << " ("; +      int Slot = MST.getLocalSlot(BB); +      if (Slot == -1) +        OS << "<ir-block badref>"; +      else +        OS << (Twine("%ir-block.") + Twine(Slot)).str(); +    }    } -  if (isEHPad()) { OS << Comma << "EH LANDING PAD"; Comma = ", "; } -  if (hasAddressTaken()) { OS << Comma << "ADDRESS TAKEN"; Comma = ", "; } -  if (Alignment) -    OS << Comma << "Align " << Alignment << " (" << (1u << Alignment) -       << " bytes)"; -  OS << '\n'; +  if (hasAddressTaken()) { +    OS << (HasAttributes ? ", " : " ("); +    OS << "address-taken"; +    HasAttributes = true; +  } +  if (isEHPad()) { +    OS << (HasAttributes ? ", " : " ("); +    OS << "landing-pad"; +    HasAttributes = true; +  } +  if (getAlignment()) { +    OS << (HasAttributes ? ", " : " ("); +    OS << "align " << getAlignment(); +    HasAttributes = true; +  } +  if (HasAttributes) +    OS << ")"; +  OS << ":\n";    const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); -  if (!livein_empty()) { +  const MachineRegisterInfo &MRI = MF->getRegInfo(); +  const TargetInstrInfo &TII = *getParent()->getSubtarget().getInstrInfo(); +  bool HasLineAttributes = false; + +  // Print the preds of this block according to the CFG. +  if (!pred_empty() && IsStandalone) {      if (Indexes) OS << '\t'; -    OS << "    Live Ins:"; -    for (const auto &LI : LiveIns) { -      OS << ' ' << printReg(LI.PhysReg, TRI); -      if (!LI.LaneMask.all()) -        OS << ':' << PrintLaneMask(LI.LaneMask); +    // Don't indent(2), align with previous line attributes. +    OS << "; predecessors: "; +    for (auto I = pred_begin(), E = pred_end(); I != E; ++I) { +      if (I != pred_begin()) +        OS << ", "; +      OS << printMBBReference(**I);      }      OS << '\n'; +    HasLineAttributes = true;    } -  // Print the preds of this block according to the CFG. -  if (!pred_empty()) { + +  if (!succ_empty()) {      if (Indexes) OS << '\t'; -    OS << "    Predecessors according to CFG:"; -    for (const_pred_iterator PI = pred_begin(), E = pred_end(); PI != E; ++PI) -      OS << " " << printMBBReference(*(*PI)); +    // Print the successors +    OS.indent(2) << "successors: "; +    for (auto I = succ_begin(), E = succ_end(); I != E; ++I) { +      if (I != succ_begin()) +        OS << ", "; +      OS << printMBBReference(**I); +      if (!Probs.empty()) +        OS << '(' +           << format("0x%08" PRIx32, getSuccProbability(I).getNumerator()) +           << ')'; +    } +    if (!Probs.empty() && IsStandalone) { +      // Print human readable probabilities as comments. +      OS << "; "; +      for (auto I = succ_begin(), E = succ_end(); I != E; ++I) { +        const BranchProbability &BP = *getProbabilityIterator(I); +        if (I != succ_begin()) +          OS << ", "; +        OS << printMBBReference(**I) << '(' +           << format("%.2f%%", +                     rint(((double)BP.getNumerator() / BP.getDenominator()) * +                          100.0 * 100.0) / +                         100.0) +           << ')'; +      } +    } +      OS << '\n'; +    HasLineAttributes = true; +  } + +  if (!livein_empty() && MRI.tracksLiveness()) { +    if (Indexes) OS << '\t'; +    OS.indent(2) << "liveins: "; + +    bool First = true; +    for (const auto &LI : liveins()) { +      if (!First) +        OS << ", "; +      First = false; +      OS << printReg(LI.PhysReg, TRI); +      if (!LI.LaneMask.all()) +        OS << ":0x" << PrintLaneMask(LI.LaneMask); +    } +    HasLineAttributes = true;    } -  for (auto &I : instrs()) { +  if (HasLineAttributes) +    OS << '\n'; + +  bool IsInBundle = false; +  for (const MachineInstr &MI : instrs()) {      if (Indexes) { -      if (Indexes->hasIndex(I)) -        OS << Indexes->getInstructionIndex(I); +      if (Indexes->hasIndex(MI)) +        OS << Indexes->getInstructionIndex(MI);        OS << '\t';      } -    OS << '\t'; -    if (I.isInsideBundle()) -      OS << "  * "; -    I.print(OS, MST); -  } -  // Print the successors of this block according to the CFG. -  if (!succ_empty()) { -    if (Indexes) OS << '\t'; -    OS << "    Successors according to CFG:"; -    for (const_succ_iterator SI = succ_begin(), E = succ_end(); SI != E; ++SI) { -      OS << " " << printMBBReference(*(*SI)); -      if (!Probs.empty()) -        OS << '(' << *getProbabilityIterator(SI) << ')'; +    if (IsInBundle && !MI.isInsideBundle()) { +      OS.indent(2) << "}\n"; +      IsInBundle = false; +    } + +    OS.indent(IsInBundle ? 4 : 2); +    MI.print(OS, MST, IsStandalone, /*SkipOpers=*/false, /*SkipDebugLoc=*/false, +             /*AddNewLine=*/false, &TII); + +    if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) { +      OS << " {"; +      IsInBundle = true;      }      OS << '\n';    } -  if (IrrLoopHeaderWeight) { + +  if (IsInBundle) +    OS.indent(2) << "}\n"; + +  if (IrrLoopHeaderWeight && IsStandalone) {      if (Indexes) OS << '\t'; -    OS << "    Irreducible loop header weight: " -       << IrrLoopHeaderWeight.getValue(); -    OS << '\n'; +    OS.indent(2) << "; Irreducible loop header weight: " +                 << IrrLoopHeaderWeight.getValue() << '\n';    }  } @@ -382,10 +458,10 @@ bool MachineBasicBlock::isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask) const {  }  void MachineBasicBlock::sortUniqueLiveIns() { -  std::sort(LiveIns.begin(), LiveIns.end(), -            [](const RegisterMaskPair &LI0, const RegisterMaskPair &LI1) { -              return LI0.PhysReg < LI1.PhysReg; -            }); +  llvm::sort(LiveIns.begin(), LiveIns.end(), +             [](const RegisterMaskPair &LI0, const RegisterMaskPair &LI1) { +               return LI0.PhysReg < LI1.PhysReg; +             });    // Liveins are sorted by physreg now we can merge their lanemasks.    LiveInVector::const_iterator I = LiveIns.begin();    LiveInVector::const_iterator J; @@ -583,6 +659,25 @@ void MachineBasicBlock::addSuccessorWithoutProb(MachineBasicBlock *Succ) {    Succ->addPredecessor(this);  } +void MachineBasicBlock::splitSuccessor(MachineBasicBlock *Old, +                                       MachineBasicBlock *New, +                                       bool NormalizeSuccProbs) { +  succ_iterator OldI = llvm::find(successors(), Old); +  assert(OldI != succ_end() && "Old is not a successor of this block!"); +  assert(llvm::find(successors(), New) == succ_end() && +         "New is already a successor of this block!"); + +  // Add a new successor with equal probability as the original one. Note +  // that we directly copy the probability using the iterator rather than +  // getting a potentially synthetic probability computed when unknown. This +  // preserves the probabilities as-is and then we can renormalize them and +  // query them effectively afterward. +  addSuccessor(New, Probs.empty() ? BranchProbability::getUnknown() +                                  : *getProbabilityIterator(OldI)); +  if (NormalizeSuccProbs) +    normalizeSuccProbs(); +} +  void MachineBasicBlock::removeSuccessor(MachineBasicBlock *Succ,                                          bool NormalizeSuccProbs) {    succ_iterator I = find(Successors, Succ); @@ -646,6 +741,14 @@ void MachineBasicBlock::replaceSuccessor(MachineBasicBlock *Old,    removeSuccessor(OldI);  } +void MachineBasicBlock::copySuccessor(MachineBasicBlock *Orig, +                                      succ_iterator I) { +  if (Orig->Probs.empty()) +    addSuccessor(*I, Orig->getSuccProbability(I)); +  else +    addSuccessorWithoutProb(*I); +} +  void MachineBasicBlock::addPredecessor(MachineBasicBlock *Pred) {    Predecessors.push_back(Pred);  } @@ -771,9 +874,9 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ,    MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock();    MF->insert(std::next(MachineFunction::iterator(this)), NMBB); -  DEBUG(dbgs() << "Splitting critical edge: " << printMBBReference(*this) -               << " -- " << printMBBReference(*NMBB) << " -- " -               << printMBBReference(*Succ) << '\n'); +  LLVM_DEBUG(dbgs() << "Splitting critical edge: " << printMBBReference(*this) +                    << " -- " << printMBBReference(*NMBB) << " -- " +                    << printMBBReference(*Succ) << '\n');    LiveIntervals *LIS = P.getAnalysisIfAvailable<LiveIntervals>();    SlotIndexes *Indexes = P.getAnalysisIfAvailable<SlotIndexes>(); @@ -802,7 +905,7 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ,          if (TargetRegisterInfo::isPhysicalRegister(Reg) ||              LV->getVarInfo(Reg).removeKill(*MI)) {            KilledRegs.push_back(Reg); -          DEBUG(dbgs() << "Removing terminator kill: " << *MI); +          LLVM_DEBUG(dbgs() << "Removing terminator kill: " << *MI);            OI->setIsKill(false);          }        } @@ -893,7 +996,7 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ,            continue;          if (TargetRegisterInfo::isVirtualRegister(Reg))            LV->getVarInfo(Reg).Kills.push_back(&*I); -        DEBUG(dbgs() << "Restored terminator kill: " << *I); +        LLVM_DEBUG(dbgs() << "Restored terminator kill: " << *I);          break;        }      } @@ -1026,8 +1129,8 @@ bool MachineBasicBlock::canSplitCriticalEdge(    // case that we can't handle. Since this never happens in properly optimized    // code, just skip those edges.    if (TBB && TBB == FBB) { -    DEBUG(dbgs() << "Won't split critical edge after degenerate " -                 << printMBBReference(*this) << '\n'); +    LLVM_DEBUG(dbgs() << "Won't split critical edge after degenerate " +                      << printMBBReference(*this) << '\n');      return false;    }    return true; @@ -1181,6 +1284,16 @@ MachineBasicBlock::findDebugLoc(instr_iterator MBBI) {    return {};  } +/// Find the previous valid DebugLoc preceding MBBI, skipping and DBG_VALUE +/// instructions.  Return UnknownLoc if there is none. +DebugLoc MachineBasicBlock::findPrevDebugLoc(instr_iterator MBBI) { +  if (MBBI == instr_begin()) return {}; +  // Skip debug declarations, we don't want a DebugLoc from them. +  MBBI = skipDebugInstructionsBackward(std::prev(MBBI), instr_begin()); +  if (!MBBI->isDebugInstr()) return MBBI->getDebugLoc(); +  return {}; +} +  /// Find and return the merged DebugLoc of the branch instructions of the block.  /// Return UnknownLoc if there is none.  DebugLoc | 
