void MIPrinter::print(const MachineBasicBlock &MBB) { assert(MBB.getNumber() >= 0 && "Invalid MBB number"); OS << "bb." << MBB.getNumber(); bool HasAttributes = false; if (const auto *BB = MBB.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 (MBB.hasAddressTaken()) { OS << (HasAttributes ? ", " : " ("); OS << "address-taken"; HasAttributes = true; } if (MBB.isEHPad()) { OS << (HasAttributes ? ", " : " ("); OS << "landing-pad"; HasAttributes = true; } if (MBB.getAlignment()) { OS << (HasAttributes ? ", " : " ("); OS << "align " << MBB.getAlignment(); HasAttributes = true; } if (HasAttributes) OS << ")"; OS << ":\n"; bool HasLineAttributes = false; // Print the successors bool canPredictProbs = canPredictBranchProbabilities(MBB); // Even if the list of successors is empty, if we cannot guess it, // we need to print it to tell the parser that the list is empty. // This is needed, because MI model unreachable as empty blocks // with an empty successor list. If the parser would see that // without the successor list, it would guess the code would // fallthrough. if ((!MBB.succ_empty() && !SimplifyMIR) || !canPredictProbs || !canPredictSuccessors(MBB)) { OS.indent(2) << "successors: "; for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) { if (I != MBB.succ_begin()) OS << ", "; OS << printMBBReference(**I); if (!SimplifyMIR || !canPredictProbs) OS << '(' << format("0x%08" PRIx32, MBB.getSuccProbability(I).getNumerator()) << ')'; } OS << "\n"; HasLineAttributes = true; } // Print the live in registers. const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); if (MRI.tracksLiveness() && !MBB.livein_empty()) { const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); OS.indent(2) << "liveins: "; bool First = true; for (const auto &LI : MBB.liveins()) { if (!First) OS << ", "; First = false; OS << printReg(LI.PhysReg, &TRI); if (!LI.LaneMask.all()) OS << ":0x" << PrintLaneMask(LI.LaneMask); } OS << "\n"; HasLineAttributes = true; } if (HasLineAttributes) OS << "\n"; bool IsInBundle = false; for (auto I = MBB.instr_begin(), E = MBB.instr_end(); I != E; ++I) { const MachineInstr &MI = *I; if (IsInBundle && !MI.isInsideBundle()) { OS.indent(2) << "}\n"; IsInBundle = false; } OS.indent(IsInBundle ? 4 : 2); print(MI); if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) { OS << " {"; IsInBundle = true; } OS << "\n"; } if (IsInBundle) OS.indent(2) << "}\n"; }
void MIPrinter::print(const MachineBasicBlock &MBB) { assert(MBB.getNumber() >= 0 && "Invalid MBB number"); OS << "bb." << MBB.getNumber(); bool HasAttributes = false; if (const auto *BB = MBB.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 (MBB.hasAddressTaken()) { OS << (HasAttributes ? ", " : " ("); OS << "address-taken"; HasAttributes = true; } if (MBB.isEHPad()) { OS << (HasAttributes ? ", " : " ("); OS << "landing-pad"; HasAttributes = true; } if (MBB.getAlignment()) { OS << (HasAttributes ? ", " : " ("); OS << "align " << MBB.getAlignment(); HasAttributes = true; } if (HasAttributes) OS << ")"; OS << ":\n"; bool HasLineAttributes = false; // Print the successors if (!MBB.succ_empty()) { OS.indent(2) << "successors: "; for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) { if (I != MBB.succ_begin()) OS << ", "; printMBBReference(**I); if (MBB.hasSuccessorProbabilities()) OS << '(' << MBB.getSuccProbability(I) << ')'; } OS << "\n"; HasLineAttributes = true; } // Print the live in registers. const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo(); assert(TRI && "Expected target register info"); if (!MBB.livein_empty()) { OS.indent(2) << "liveins: "; bool First = true; for (const auto &LI : MBB.liveins()) { if (!First) OS << ", "; First = false; printReg(LI.PhysReg, OS, TRI); if (LI.LaneMask != ~0u) OS << ":0x" << PrintLaneMask(LI.LaneMask); } OS << "\n"; HasLineAttributes = true; } if (HasLineAttributes) OS << "\n"; bool IsInBundle = false; for (auto I = MBB.instr_begin(), E = MBB.instr_end(); I != E; ++I) { const MachineInstr &MI = *I; if (IsInBundle && !MI.isInsideBundle()) { OS.indent(2) << "}\n"; IsInBundle = false; } OS.indent(IsInBundle ? 4 : 2); print(MI); if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) { OS << " {"; IsInBundle = true; } OS << "\n"; } if (IsInBundle) OS.indent(2) << "}\n"; }