void MIRPrinter::convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB, const MachineBasicBlock &MBB) { assert(MBB.getNumber() >= 0 && "Invalid MBB number"); YamlMBB.ID = (unsigned)MBB.getNumber(); // TODO: Serialize unnamed BB references. if (const auto *BB = MBB.getBasicBlock()) YamlMBB.Name.Value = BB->hasName() ? BB->getName() : "<unnamed bb>"; else YamlMBB.Name.Value = ""; YamlMBB.Alignment = MBB.getAlignment(); YamlMBB.AddressTaken = MBB.hasAddressTaken(); YamlMBB.IsLandingPad = MBB.isLandingPad(); for (const auto *SuccMBB : MBB.successors()) { std::string Str; raw_string_ostream StrOS(Str); MIPrinter(StrOS, MST, RegisterMaskIds).printMBBReference(*SuccMBB); YamlMBB.Successors.push_back(StrOS.str()); } // Print the machine instructions. YamlMBB.Instructions.reserve(MBB.size()); std::string Str; for (const auto &MI : MBB) { raw_string_ostream StrOS(Str); MIPrinter(StrOS, MST, RegisterMaskIds).print(MI); YamlMBB.Instructions.push_back(StrOS.str()); Str.clear(); } }
void WinException::beginFunclet(const MachineBasicBlock &MBB, MCSymbol *Sym) { CurrentFuncletEntry = &MBB; const Function *F = Asm->MF->getFunction(); // If a symbol was not provided for the funclet, invent one. if (!Sym) { Sym = getMCSymbolForMBB(Asm, &MBB); // Describe our funclet symbol as a function with internal linkage. Asm->OutStreamer->BeginCOFFSymbolDef(Sym); Asm->OutStreamer->EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC); Asm->OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT); Asm->OutStreamer->EndCOFFSymbolDef(); // We want our funclet's entry point to be aligned such that no nops will be // present after the label. Asm->EmitAlignment(std::max(Asm->MF->getAlignment(), MBB.getAlignment()), F); // Now that we've emitted the alignment directive, point at our funclet. Asm->OutStreamer->EmitLabel(Sym); } // Mark 'Sym' as starting our funclet. if (shouldEmitMoves || shouldEmitPersonality) Asm->OutStreamer->EmitWinCFIStartProc(Sym); if (shouldEmitPersonality) { const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); const Function *PerFn = nullptr; // Determine which personality routine we are using for this funclet. if (F->hasPersonalityFn()) PerFn = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts()); const MCSymbol *PersHandlerSym = TLOF.getCFIPersonalitySymbol(PerFn, *Asm->Mang, Asm->TM, MMI); // Classify the personality routine so that we may reason about it. EHPersonality Per = EHPersonality::Unknown; if (F->hasPersonalityFn()) Per = classifyEHPersonality(F->getPersonalityFn()); // Do not emit a .seh_handler directive if it is a C++ cleanup funclet. if (Per != EHPersonality::MSVC_CXX || !CurrentFuncletEntry->isCleanupFuncletEntry()) Asm->OutStreamer->EmitWinEHHandler(PersHandlerSym, true, true); } }
void MIRPrinter::convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB, const MachineBasicBlock &MBB) { assert(MBB.getNumber() >= 0 && "Invalid MBB number"); YamlMBB.ID = (unsigned)MBB.getNumber(); if (const auto *BB = MBB.getBasicBlock()) { if (BB->hasName()) { YamlMBB.Name.Value = BB->getName(); } else { int Slot = MST.getLocalSlot(BB); if (Slot == -1) YamlMBB.IRBlock.Value = "<badref>"; else YamlMBB.IRBlock.Value = (Twine("%ir-block.") + Twine(Slot)).str(); } } YamlMBB.Alignment = MBB.getAlignment(); YamlMBB.AddressTaken = MBB.hasAddressTaken(); YamlMBB.IsLandingPad = MBB.isLandingPad(); for (const auto *SuccMBB : MBB.successors()) { std::string Str; raw_string_ostream StrOS(Str); MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) .printMBBReference(*SuccMBB); YamlMBB.Successors.push_back(StrOS.str()); } if (MBB.hasSuccessorWeights()) { for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) YamlMBB.SuccessorWeights.push_back( yaml::UnsignedValue(MBB.getSuccWeight(I))); } // Print the live in registers. const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo(); assert(TRI && "Expected target register info"); for (auto I = MBB.livein_begin(), E = MBB.livein_end(); I != E; ++I) { std::string Str; raw_string_ostream StrOS(Str); printReg(*I, StrOS, TRI); YamlMBB.LiveIns.push_back(StrOS.str()); } // Print the machine instructions. YamlMBB.Instructions.reserve(MBB.size()); std::string Str; for (const auto &MI : MBB) { raw_string_ostream StrOS(Str); MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping).print(MI); YamlMBB.Instructions.push_back(StrOS.str()); Str.clear(); } }
/// verify - check BBOffsets, BBSizes, alignment of islands void ARM64BranchRelaxation::verify() { #ifndef NDEBUG unsigned PrevNum = MF->begin()->getNumber(); for (MachineFunction::iterator MBBI = MF->begin(), E = MF->end(); MBBI != E; ++MBBI) { MachineBasicBlock *MBB = MBBI; unsigned Align = MBB->getAlignment(); unsigned Num = MBB->getNumber(); assert(BlockInfo[Num].Offset % (1u << Align) == 0); assert(!Num || BlockInfo[PrevNum].postOffset() <= BlockInfo[Num].Offset); PrevNum = Num; } #endif }
// Fill MBBs and Terminators, setting the addresses on the assumption // that no branches need relaxation. Return the size of the function under // this assumption. uint64_t SystemZLongBranch::initMBBInfo() { MF->RenumberBlocks(); unsigned NumBlocks = MF->size(); MBBs.clear(); MBBs.resize(NumBlocks); Terminators.clear(); Terminators.reserve(NumBlocks); BlockPosition Position(MF->getAlignment()); for (unsigned I = 0; I < NumBlocks; ++I) { MachineBasicBlock *MBB = MF->getBlockNumbered(I); MBBInfo &Block = MBBs[I]; // Record the alignment, for quick access. Block.Alignment = MBB->getAlignment(); // Calculate the size of the fixed part of the block. MachineBasicBlock::iterator MI = MBB->begin(); MachineBasicBlock::iterator End = MBB->end(); while (MI != End && !MI->isTerminator()) { Block.Size += TII->getInstSizeInBytes(*MI); ++MI; } skipNonTerminators(Position, Block); // Add the terminators. while (MI != End) { if (!MI->isDebugValue()) { assert(MI->isTerminator() && "Terminator followed by non-terminator"); Terminators.push_back(describeTerminator(*MI)); skipTerminator(Position, Terminators.back(), false); ++Block.NumTerminators; } ++MI; } } return Position.Address; }
void MIRPrinter::convert(yaml::MachineBasicBlock &YamlMBB, const MachineBasicBlock &MBB) { // TODO: Serialize unnamed BB references. if (const auto *BB = MBB.getBasicBlock()) YamlMBB.Name = BB->hasName() ? BB->getName() : "<unnamed bb>"; else YamlMBB.Name = ""; YamlMBB.Alignment = MBB.getAlignment(); YamlMBB.AddressTaken = MBB.hasAddressTaken(); YamlMBB.IsLandingPad = MBB.isLandingPad(); // Print the machine instructions. YamlMBB.Instructions.reserve(MBB.size()); std::string Str; for (const auto &MI : MBB) { raw_string_ostream StrOS(Str); MIPrinter(StrOS).print(MI); YamlMBB.Instructions.push_back(StrOS.str()); Str.clear(); } }
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.hasSuccessorWeights()) OS << '(' << MBB.getSuccWeight(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 (unsigned LI : MBB.liveins()) { if (!First) OS << ", "; First = false; printReg(LI, OS, TRI); } 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 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"; }