10b57cec5SDimitry Andric //===- MIRPrinter.cpp - MIR serialization format printer ------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the class that prints out the LLVM IR and machine 100b57cec5SDimitry Andric // functions using the MIR serialization format. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/CodeGen/MIRPrinter.h" 150b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 160b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 170b57cec5SDimitry Andric #include "llvm/ADT/SmallBitVector.h" 180b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 190b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 200b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/MIRYamlMapping.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 260b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h" 280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h" 29fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineModuleSlotTracker.h" 300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 32fe6060f1SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h" 330b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 340b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 350b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 36*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/LowLevelType.h" 3781ad6265SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 380b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 390b57cec5SDimitry Andric #include "llvm/IR/Function.h" 400b57cec5SDimitry Andric #include "llvm/IR/IRPrintingPasses.h" 410b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 420b57cec5SDimitry Andric #include "llvm/IR/Module.h" 430b57cec5SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h" 440b57cec5SDimitry Andric #include "llvm/IR/Value.h" 450b57cec5SDimitry Andric #include "llvm/MC/LaneBitmask.h" 460b57cec5SDimitry Andric #include "llvm/Support/BranchProbability.h" 470b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 480b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 490b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 500b57cec5SDimitry Andric #include "llvm/Support/Format.h" 510b57cec5SDimitry Andric #include "llvm/Support/YAMLTraits.h" 520b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 530b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 540b57cec5SDimitry Andric #include <algorithm> 550b57cec5SDimitry Andric #include <cassert> 560b57cec5SDimitry Andric #include <cinttypes> 570b57cec5SDimitry Andric #include <cstdint> 580b57cec5SDimitry Andric #include <iterator> 590b57cec5SDimitry Andric #include <string> 600b57cec5SDimitry Andric #include <utility> 610b57cec5SDimitry Andric #include <vector> 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric using namespace llvm; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric static cl::opt<bool> SimplifyMIR( 660b57cec5SDimitry Andric "simplify-mir", cl::Hidden, 670b57cec5SDimitry Andric cl::desc("Leave out unnecessary information when printing MIR")); 680b57cec5SDimitry Andric 695ffd83dbSDimitry Andric static cl::opt<bool> PrintLocations("mir-debug-loc", cl::Hidden, cl::init(true), 705ffd83dbSDimitry Andric cl::desc("Print MIR debug-locations")); 715ffd83dbSDimitry Andric 72*0fca6ea1SDimitry Andric extern cl::opt<bool> WriteNewDbgInfoFormat; 73*0fca6ea1SDimitry Andric 740b57cec5SDimitry Andric namespace { 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric /// This structure describes how to print out stack object references. 770b57cec5SDimitry Andric struct FrameIndexOperand { 780b57cec5SDimitry Andric std::string Name; 790b57cec5SDimitry Andric unsigned ID; 800b57cec5SDimitry Andric bool IsFixed; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed) 830b57cec5SDimitry Andric : Name(Name.str()), ID(ID), IsFixed(IsFixed) {} 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric /// Return an ordinary stack object reference. 860b57cec5SDimitry Andric static FrameIndexOperand create(StringRef Name, unsigned ID) { 870b57cec5SDimitry Andric return FrameIndexOperand(Name, ID, /*IsFixed=*/false); 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric /// Return a fixed stack object reference. 910b57cec5SDimitry Andric static FrameIndexOperand createFixed(unsigned ID) { 920b57cec5SDimitry Andric return FrameIndexOperand("", ID, /*IsFixed=*/true); 930b57cec5SDimitry Andric } 940b57cec5SDimitry Andric }; 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric } // end anonymous namespace 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric namespace llvm { 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric /// This class prints out the machine functions using the MIR serialization 1010b57cec5SDimitry Andric /// format. 1020b57cec5SDimitry Andric class MIRPrinter { 1030b57cec5SDimitry Andric raw_ostream &OS; 1040b57cec5SDimitry Andric DenseMap<const uint32_t *, unsigned> RegisterMaskIds; 1050b57cec5SDimitry Andric /// Maps from stack object indices to operand indices which will be used when 1060b57cec5SDimitry Andric /// printing frame index machine operands. 1070b57cec5SDimitry Andric DenseMap<int, FrameIndexOperand> StackObjectOperandMapping; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric public: 1100b57cec5SDimitry Andric MIRPrinter(raw_ostream &OS) : OS(OS) {} 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric void print(const MachineFunction &MF); 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo, 1150b57cec5SDimitry Andric const TargetRegisterInfo *TRI); 1160b57cec5SDimitry Andric void convert(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI, 1170b57cec5SDimitry Andric const MachineFrameInfo &MFI); 1180b57cec5SDimitry Andric void convert(yaml::MachineFunction &MF, 1190b57cec5SDimitry Andric const MachineConstantPool &ConstantPool); 1200b57cec5SDimitry Andric void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI, 1210b57cec5SDimitry Andric const MachineJumpTableInfo &JTI); 1220b57cec5SDimitry Andric void convertStackObjects(yaml::MachineFunction &YMF, 1230b57cec5SDimitry Andric const MachineFunction &MF, ModuleSlotTracker &MST); 12406c3fb27SDimitry Andric void convertEntryValueObjects(yaml::MachineFunction &YMF, 12506c3fb27SDimitry Andric const MachineFunction &MF, 12606c3fb27SDimitry Andric ModuleSlotTracker &MST); 1270b57cec5SDimitry Andric void convertCallSiteObjects(yaml::MachineFunction &YMF, 1280b57cec5SDimitry Andric const MachineFunction &MF, 1290b57cec5SDimitry Andric ModuleSlotTracker &MST); 130fe6060f1SDimitry Andric void convertMachineMetadataNodes(yaml::MachineFunction &YMF, 131fe6060f1SDimitry Andric const MachineFunction &MF, 132fe6060f1SDimitry Andric MachineModuleSlotTracker &MST); 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric private: 1350b57cec5SDimitry Andric void initRegisterMaskIds(const MachineFunction &MF); 1360b57cec5SDimitry Andric }; 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric /// This class prints out the machine instructions using the MIR serialization 1390b57cec5SDimitry Andric /// format. 1400b57cec5SDimitry Andric class MIPrinter { 1410b57cec5SDimitry Andric raw_ostream &OS; 1420b57cec5SDimitry Andric ModuleSlotTracker &MST; 1430b57cec5SDimitry Andric const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds; 1440b57cec5SDimitry Andric const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping; 1450b57cec5SDimitry Andric /// Synchronization scope names registered with LLVMContext. 1460b57cec5SDimitry Andric SmallVector<StringRef, 8> SSNs; 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric bool canPredictBranchProbabilities(const MachineBasicBlock &MBB) const; 1490b57cec5SDimitry Andric bool canPredictSuccessors(const MachineBasicBlock &MBB) const; 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric public: 1520b57cec5SDimitry Andric MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST, 1530b57cec5SDimitry Andric const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds, 1540b57cec5SDimitry Andric const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping) 1550b57cec5SDimitry Andric : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds), 1560b57cec5SDimitry Andric StackObjectOperandMapping(StackObjectOperandMapping) {} 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric void print(const MachineBasicBlock &MBB); 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric void print(const MachineInstr &MI); 1610b57cec5SDimitry Andric void printStackObjectReference(int FrameIndex); 1620b57cec5SDimitry Andric void print(const MachineInstr &MI, unsigned OpIdx, 1635ffd83dbSDimitry Andric const TargetRegisterInfo *TRI, const TargetInstrInfo *TII, 1645ffd83dbSDimitry Andric bool ShouldPrintRegisterTies, LLT TypeToPrint, 1655ffd83dbSDimitry Andric bool PrintDef = true); 1660b57cec5SDimitry Andric }; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric } // end namespace llvm 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric namespace llvm { 1710b57cec5SDimitry Andric namespace yaml { 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric /// This struct serializes the LLVM IR module. 1740b57cec5SDimitry Andric template <> struct BlockScalarTraits<Module> { 1750b57cec5SDimitry Andric static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) { 1760b57cec5SDimitry Andric Mod.print(OS, nullptr); 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric static StringRef input(StringRef Str, void *Ctxt, Module &Mod) { 1800b57cec5SDimitry Andric llvm_unreachable("LLVM Module is supposed to be parsed separately"); 1810b57cec5SDimitry Andric return ""; 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric }; 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric } // end namespace yaml 1860b57cec5SDimitry Andric } // end namespace llvm 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric static void printRegMIR(unsigned Reg, yaml::StringValue &Dest, 1890b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 1900b57cec5SDimitry Andric raw_string_ostream OS(Dest.Value); 1910b57cec5SDimitry Andric OS << printReg(Reg, TRI); 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric void MIRPrinter::print(const MachineFunction &MF) { 1950b57cec5SDimitry Andric initRegisterMaskIds(MF); 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric yaml::MachineFunction YamlMF; 1980b57cec5SDimitry Andric YamlMF.Name = MF.getName(); 1995ffd83dbSDimitry Andric YamlMF.Alignment = MF.getAlignment(); 2000b57cec5SDimitry Andric YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice(); 2010b57cec5SDimitry Andric YamlMF.HasWinCFI = MF.hasWinCFI(); 2020b57cec5SDimitry Andric 20381ad6265SDimitry Andric YamlMF.CallsEHReturn = MF.callsEHReturn(); 20481ad6265SDimitry Andric YamlMF.CallsUnwindInit = MF.callsUnwindInit(); 20581ad6265SDimitry Andric YamlMF.HasEHCatchret = MF.hasEHCatchret(); 20681ad6265SDimitry Andric YamlMF.HasEHScopes = MF.hasEHScopes(); 20781ad6265SDimitry Andric YamlMF.HasEHFunclets = MF.hasEHFunclets(); 20806c3fb27SDimitry Andric YamlMF.IsOutlined = MF.isOutlined(); 209bdd1243dSDimitry Andric YamlMF.UseDebugInstrRef = MF.useDebugInstrRef(); 21081ad6265SDimitry Andric 2110b57cec5SDimitry Andric YamlMF.Legalized = MF.getProperties().hasProperty( 2120b57cec5SDimitry Andric MachineFunctionProperties::Property::Legalized); 2130b57cec5SDimitry Andric YamlMF.RegBankSelected = MF.getProperties().hasProperty( 2140b57cec5SDimitry Andric MachineFunctionProperties::Property::RegBankSelected); 2150b57cec5SDimitry Andric YamlMF.Selected = MF.getProperties().hasProperty( 2160b57cec5SDimitry Andric MachineFunctionProperties::Property::Selected); 2170b57cec5SDimitry Andric YamlMF.FailedISel = MF.getProperties().hasProperty( 2180b57cec5SDimitry Andric MachineFunctionProperties::Property::FailedISel); 219349cc55cSDimitry Andric YamlMF.FailsVerification = MF.getProperties().hasProperty( 220349cc55cSDimitry Andric MachineFunctionProperties::Property::FailsVerification); 2210eae32dcSDimitry Andric YamlMF.TracksDebugUserValues = MF.getProperties().hasProperty( 2220eae32dcSDimitry Andric MachineFunctionProperties::Property::TracksDebugUserValues); 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo()); 225fe6060f1SDimitry Andric MachineModuleSlotTracker MST(&MF); 2260b57cec5SDimitry Andric MST.incorporateFunction(MF.getFunction()); 2270b57cec5SDimitry Andric convert(MST, YamlMF.FrameInfo, MF.getFrameInfo()); 2280b57cec5SDimitry Andric convertStackObjects(YamlMF, MF, MST); 22906c3fb27SDimitry Andric convertEntryValueObjects(YamlMF, MF, MST); 2300b57cec5SDimitry Andric convertCallSiteObjects(YamlMF, MF, MST); 231fe6060f1SDimitry Andric for (const auto &Sub : MF.DebugValueSubstitutions) { 232fe6060f1SDimitry Andric const auto &SubSrc = Sub.Src; 233fe6060f1SDimitry Andric const auto &SubDest = Sub.Dest; 234fe6060f1SDimitry Andric YamlMF.DebugValueSubstitutions.push_back({SubSrc.first, SubSrc.second, 235fe6060f1SDimitry Andric SubDest.first, 236fe6060f1SDimitry Andric SubDest.second, 237fe6060f1SDimitry Andric Sub.Subreg}); 238fe6060f1SDimitry Andric } 2390b57cec5SDimitry Andric if (const auto *ConstantPool = MF.getConstantPool()) 2400b57cec5SDimitry Andric convert(YamlMF, *ConstantPool); 2410b57cec5SDimitry Andric if (const auto *JumpTableInfo = MF.getJumpTableInfo()) 2420b57cec5SDimitry Andric convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo); 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric const TargetMachine &TM = MF.getTarget(); 2450b57cec5SDimitry Andric YamlMF.MachineFuncInfo = 2460b57cec5SDimitry Andric std::unique_ptr<yaml::MachineFunctionInfo>(TM.convertFuncInfoToYAML(MF)); 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric raw_string_ostream StrOS(YamlMF.Body.Value.Value); 2490b57cec5SDimitry Andric bool IsNewlineNeeded = false; 2500b57cec5SDimitry Andric for (const auto &MBB : MF) { 2510b57cec5SDimitry Andric if (IsNewlineNeeded) 2520b57cec5SDimitry Andric StrOS << "\n"; 2530b57cec5SDimitry Andric MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 2540b57cec5SDimitry Andric .print(MBB); 2550b57cec5SDimitry Andric IsNewlineNeeded = true; 2560b57cec5SDimitry Andric } 2570b57cec5SDimitry Andric StrOS.flush(); 258fe6060f1SDimitry Andric // Convert machine metadata collected during the print of the machine 259fe6060f1SDimitry Andric // function. 260fe6060f1SDimitry Andric convertMachineMetadataNodes(YamlMF, MF, MST); 261fe6060f1SDimitry Andric 2620b57cec5SDimitry Andric yaml::Output Out(OS); 2630b57cec5SDimitry Andric if (!SimplifyMIR) 2640b57cec5SDimitry Andric Out.setWriteDefaultValues(true); 2650b57cec5SDimitry Andric Out << YamlMF; 2660b57cec5SDimitry Andric } 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric static void printCustomRegMask(const uint32_t *RegMask, raw_ostream &OS, 2690b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 2700b57cec5SDimitry Andric assert(RegMask && "Can't print an empty register mask"); 2710b57cec5SDimitry Andric OS << StringRef("CustomRegMask("); 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric bool IsRegInRegMaskFound = false; 2740b57cec5SDimitry Andric for (int I = 0, E = TRI->getNumRegs(); I < E; I++) { 2750b57cec5SDimitry Andric // Check whether the register is asserted in regmask. 2760b57cec5SDimitry Andric if (RegMask[I / 32] & (1u << (I % 32))) { 2770b57cec5SDimitry Andric if (IsRegInRegMaskFound) 2780b57cec5SDimitry Andric OS << ','; 2790b57cec5SDimitry Andric OS << printReg(I, TRI); 2800b57cec5SDimitry Andric IsRegInRegMaskFound = true; 2810b57cec5SDimitry Andric } 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric OS << ')'; 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric static void printRegClassOrBank(unsigned Reg, yaml::StringValue &Dest, 2880b57cec5SDimitry Andric const MachineRegisterInfo &RegInfo, 2890b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 2900b57cec5SDimitry Andric raw_string_ostream OS(Dest.Value); 2910b57cec5SDimitry Andric OS << printRegClassOrBank(Reg, RegInfo, TRI); 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric template <typename T> 2950b57cec5SDimitry Andric static void 2960b57cec5SDimitry Andric printStackObjectDbgInfo(const MachineFunction::VariableDbgInfo &DebugVar, 2970b57cec5SDimitry Andric T &Object, ModuleSlotTracker &MST) { 2980b57cec5SDimitry Andric std::array<std::string *, 3> Outputs{{&Object.DebugVar.Value, 2990b57cec5SDimitry Andric &Object.DebugExpr.Value, 3000b57cec5SDimitry Andric &Object.DebugLoc.Value}}; 3010b57cec5SDimitry Andric std::array<const Metadata *, 3> Metas{{DebugVar.Var, 3020b57cec5SDimitry Andric DebugVar.Expr, 3030b57cec5SDimitry Andric DebugVar.Loc}}; 3040b57cec5SDimitry Andric for (unsigned i = 0; i < 3; ++i) { 3050b57cec5SDimitry Andric raw_string_ostream StrOS(*Outputs[i]); 3060b57cec5SDimitry Andric Metas[i]->printAsOperand(StrOS, MST); 3070b57cec5SDimitry Andric } 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric void MIRPrinter::convert(yaml::MachineFunction &MF, 3110b57cec5SDimitry Andric const MachineRegisterInfo &RegInfo, 3120b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 3130b57cec5SDimitry Andric MF.TracksRegLiveness = RegInfo.tracksLiveness(); 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric // Print the virtual register definitions. 3160b57cec5SDimitry Andric for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) { 317bdd1243dSDimitry Andric Register Reg = Register::index2VirtReg(I); 3180b57cec5SDimitry Andric yaml::VirtualRegisterDefinition VReg; 3190b57cec5SDimitry Andric VReg.ID = I; 3200b57cec5SDimitry Andric if (RegInfo.getVRegName(Reg) != "") 3210b57cec5SDimitry Andric continue; 3220b57cec5SDimitry Andric ::printRegClassOrBank(Reg, VReg.Class, RegInfo, TRI); 323bdd1243dSDimitry Andric Register PreferredReg = RegInfo.getSimpleHint(Reg); 3240b57cec5SDimitry Andric if (PreferredReg) 3250b57cec5SDimitry Andric printRegMIR(PreferredReg, VReg.PreferredRegister, TRI); 3260b57cec5SDimitry Andric MF.VirtualRegisters.push_back(VReg); 3270b57cec5SDimitry Andric } 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric // Print the live ins. 3300b57cec5SDimitry Andric for (std::pair<unsigned, unsigned> LI : RegInfo.liveins()) { 3310b57cec5SDimitry Andric yaml::MachineFunctionLiveIn LiveIn; 3320b57cec5SDimitry Andric printRegMIR(LI.first, LiveIn.Register, TRI); 3330b57cec5SDimitry Andric if (LI.second) 3340b57cec5SDimitry Andric printRegMIR(LI.second, LiveIn.VirtualRegister, TRI); 3350b57cec5SDimitry Andric MF.LiveIns.push_back(LiveIn); 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric // Prints the callee saved registers. 3390b57cec5SDimitry Andric if (RegInfo.isUpdatedCSRsInitialized()) { 3400b57cec5SDimitry Andric const MCPhysReg *CalleeSavedRegs = RegInfo.getCalleeSavedRegs(); 3410b57cec5SDimitry Andric std::vector<yaml::FlowStringValue> CalleeSavedRegisters; 3420b57cec5SDimitry Andric for (const MCPhysReg *I = CalleeSavedRegs; *I; ++I) { 3430b57cec5SDimitry Andric yaml::FlowStringValue Reg; 3440b57cec5SDimitry Andric printRegMIR(*I, Reg, TRI); 3450b57cec5SDimitry Andric CalleeSavedRegisters.push_back(Reg); 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric MF.CalleeSavedRegisters = CalleeSavedRegisters; 3480b57cec5SDimitry Andric } 3490b57cec5SDimitry Andric } 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric void MIRPrinter::convert(ModuleSlotTracker &MST, 3520b57cec5SDimitry Andric yaml::MachineFrameInfo &YamlMFI, 3530b57cec5SDimitry Andric const MachineFrameInfo &MFI) { 3540b57cec5SDimitry Andric YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken(); 3550b57cec5SDimitry Andric YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken(); 3560b57cec5SDimitry Andric YamlMFI.HasStackMap = MFI.hasStackMap(); 3570b57cec5SDimitry Andric YamlMFI.HasPatchPoint = MFI.hasPatchPoint(); 3580b57cec5SDimitry Andric YamlMFI.StackSize = MFI.getStackSize(); 3590b57cec5SDimitry Andric YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment(); 3605ffd83dbSDimitry Andric YamlMFI.MaxAlignment = MFI.getMaxAlign().value(); 3610b57cec5SDimitry Andric YamlMFI.AdjustsStack = MFI.adjustsStack(); 3620b57cec5SDimitry Andric YamlMFI.HasCalls = MFI.hasCalls(); 3630b57cec5SDimitry Andric YamlMFI.MaxCallFrameSize = MFI.isMaxCallFrameSizeComputed() 3640b57cec5SDimitry Andric ? MFI.getMaxCallFrameSize() : ~0u; 3650b57cec5SDimitry Andric YamlMFI.CVBytesOfCalleeSavedRegisters = 3660b57cec5SDimitry Andric MFI.getCVBytesOfCalleeSavedRegisters(); 3670b57cec5SDimitry Andric YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment(); 3680b57cec5SDimitry Andric YamlMFI.HasVAStart = MFI.hasVAStart(); 3690b57cec5SDimitry Andric YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc(); 370fe6060f1SDimitry Andric YamlMFI.HasTailCall = MFI.hasTailCall(); 371*0fca6ea1SDimitry Andric YamlMFI.IsCalleeSavedInfoValid = MFI.isCalleeSavedInfoValid(); 3720b57cec5SDimitry Andric YamlMFI.LocalFrameSize = MFI.getLocalFrameSize(); 3730b57cec5SDimitry Andric if (MFI.getSavePoint()) { 3740b57cec5SDimitry Andric raw_string_ostream StrOS(YamlMFI.SavePoint.Value); 3750b57cec5SDimitry Andric StrOS << printMBBReference(*MFI.getSavePoint()); 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric if (MFI.getRestorePoint()) { 3780b57cec5SDimitry Andric raw_string_ostream StrOS(YamlMFI.RestorePoint.Value); 3790b57cec5SDimitry Andric StrOS << printMBBReference(*MFI.getRestorePoint()); 3800b57cec5SDimitry Andric } 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 38306c3fb27SDimitry Andric void MIRPrinter::convertEntryValueObjects(yaml::MachineFunction &YMF, 38406c3fb27SDimitry Andric const MachineFunction &MF, 38506c3fb27SDimitry Andric ModuleSlotTracker &MST) { 38606c3fb27SDimitry Andric const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 38706c3fb27SDimitry Andric for (const MachineFunction::VariableDbgInfo &DebugVar : 38806c3fb27SDimitry Andric MF.getEntryValueVariableDbgInfo()) { 38906c3fb27SDimitry Andric yaml::EntryValueObject &Obj = YMF.EntryValueObjects.emplace_back(); 39006c3fb27SDimitry Andric printStackObjectDbgInfo(DebugVar, Obj, MST); 39106c3fb27SDimitry Andric MCRegister EntryValReg = DebugVar.getEntryValueRegister(); 39206c3fb27SDimitry Andric printRegMIR(EntryValReg, Obj.EntryValueRegister, TRI); 39306c3fb27SDimitry Andric } 39406c3fb27SDimitry Andric } 39506c3fb27SDimitry Andric 3960b57cec5SDimitry Andric void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF, 3970b57cec5SDimitry Andric const MachineFunction &MF, 3980b57cec5SDimitry Andric ModuleSlotTracker &MST) { 3990b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo(); 4000b57cec5SDimitry Andric const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 401e8d8bef9SDimitry Andric 4020b57cec5SDimitry Andric // Process fixed stack objects. 403e8d8bef9SDimitry Andric assert(YMF.FixedStackObjects.empty()); 404e8d8bef9SDimitry Andric SmallVector<int, 32> FixedStackObjectsIdx; 405e8d8bef9SDimitry Andric const int BeginIdx = MFI.getObjectIndexBegin(); 406e8d8bef9SDimitry Andric if (BeginIdx < 0) 407e8d8bef9SDimitry Andric FixedStackObjectsIdx.reserve(-BeginIdx); 408e8d8bef9SDimitry Andric 4090b57cec5SDimitry Andric unsigned ID = 0; 410e8d8bef9SDimitry Andric for (int I = BeginIdx; I < 0; ++I, ++ID) { 411e8d8bef9SDimitry Andric FixedStackObjectsIdx.push_back(-1); // Fill index for possible dead. 4120b57cec5SDimitry Andric if (MFI.isDeadObjectIndex(I)) 4130b57cec5SDimitry Andric continue; 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric yaml::FixedMachineStackObject YamlObject; 4160b57cec5SDimitry Andric YamlObject.ID = ID; 4170b57cec5SDimitry Andric YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 4180b57cec5SDimitry Andric ? yaml::FixedMachineStackObject::SpillSlot 4190b57cec5SDimitry Andric : yaml::FixedMachineStackObject::DefaultType; 4200b57cec5SDimitry Andric YamlObject.Offset = MFI.getObjectOffset(I); 4210b57cec5SDimitry Andric YamlObject.Size = MFI.getObjectSize(I); 4225ffd83dbSDimitry Andric YamlObject.Alignment = MFI.getObjectAlign(I); 4230b57cec5SDimitry Andric YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I); 4240b57cec5SDimitry Andric YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I); 4250b57cec5SDimitry Andric YamlObject.IsAliased = MFI.isAliasedObjectIndex(I); 426e8d8bef9SDimitry Andric // Save the ID' position in FixedStackObjects storage vector. 427e8d8bef9SDimitry Andric FixedStackObjectsIdx[ID] = YMF.FixedStackObjects.size(); 4280b57cec5SDimitry Andric YMF.FixedStackObjects.push_back(YamlObject); 4290b57cec5SDimitry Andric StackObjectOperandMapping.insert( 4300b57cec5SDimitry Andric std::make_pair(I, FrameIndexOperand::createFixed(ID))); 4310b57cec5SDimitry Andric } 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric // Process ordinary stack objects. 434e8d8bef9SDimitry Andric assert(YMF.StackObjects.empty()); 435e8d8bef9SDimitry Andric SmallVector<unsigned, 32> StackObjectsIdx; 436e8d8bef9SDimitry Andric const int EndIdx = MFI.getObjectIndexEnd(); 437e8d8bef9SDimitry Andric if (EndIdx > 0) 438e8d8bef9SDimitry Andric StackObjectsIdx.reserve(EndIdx); 4390b57cec5SDimitry Andric ID = 0; 440e8d8bef9SDimitry Andric for (int I = 0; I < EndIdx; ++I, ++ID) { 441e8d8bef9SDimitry Andric StackObjectsIdx.push_back(-1); // Fill index for possible dead. 4420b57cec5SDimitry Andric if (MFI.isDeadObjectIndex(I)) 4430b57cec5SDimitry Andric continue; 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric yaml::MachineStackObject YamlObject; 4460b57cec5SDimitry Andric YamlObject.ID = ID; 4470b57cec5SDimitry Andric if (const auto *Alloca = MFI.getObjectAllocation(I)) 4485ffd83dbSDimitry Andric YamlObject.Name.Value = std::string( 449e8d8bef9SDimitry Andric Alloca->hasName() ? Alloca->getName() : ""); 4500b57cec5SDimitry Andric YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 4510b57cec5SDimitry Andric ? yaml::MachineStackObject::SpillSlot 4520b57cec5SDimitry Andric : MFI.isVariableSizedObjectIndex(I) 4530b57cec5SDimitry Andric ? yaml::MachineStackObject::VariableSized 4540b57cec5SDimitry Andric : yaml::MachineStackObject::DefaultType; 4550b57cec5SDimitry Andric YamlObject.Offset = MFI.getObjectOffset(I); 4560b57cec5SDimitry Andric YamlObject.Size = MFI.getObjectSize(I); 4575ffd83dbSDimitry Andric YamlObject.Alignment = MFI.getObjectAlign(I); 4580b57cec5SDimitry Andric YamlObject.StackID = (TargetStackID::Value)MFI.getStackID(I); 4590b57cec5SDimitry Andric 460e8d8bef9SDimitry Andric // Save the ID' position in StackObjects storage vector. 461e8d8bef9SDimitry Andric StackObjectsIdx[ID] = YMF.StackObjects.size(); 4620b57cec5SDimitry Andric YMF.StackObjects.push_back(YamlObject); 4630b57cec5SDimitry Andric StackObjectOperandMapping.insert(std::make_pair( 4640b57cec5SDimitry Andric I, FrameIndexOperand::create(YamlObject.Name.Value, ID))); 4650b57cec5SDimitry Andric } 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric for (const auto &CSInfo : MFI.getCalleeSavedInfo()) { 468e8d8bef9SDimitry Andric const int FrameIdx = CSInfo.getFrameIdx(); 469e8d8bef9SDimitry Andric if (!CSInfo.isSpilledToReg() && MFI.isDeadObjectIndex(FrameIdx)) 4700b57cec5SDimitry Andric continue; 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric yaml::StringValue Reg; 4730b57cec5SDimitry Andric printRegMIR(CSInfo.getReg(), Reg, TRI); 4740b57cec5SDimitry Andric if (!CSInfo.isSpilledToReg()) { 475e8d8bef9SDimitry Andric assert(FrameIdx >= MFI.getObjectIndexBegin() && 476e8d8bef9SDimitry Andric FrameIdx < MFI.getObjectIndexEnd() && 4770b57cec5SDimitry Andric "Invalid stack object index"); 478e8d8bef9SDimitry Andric if (FrameIdx < 0) { // Negative index means fixed objects. 479e8d8bef9SDimitry Andric auto &Object = 480e8d8bef9SDimitry Andric YMF.FixedStackObjects 481e8d8bef9SDimitry Andric [FixedStackObjectsIdx[FrameIdx + MFI.getNumFixedObjects()]]; 482e8d8bef9SDimitry Andric Object.CalleeSavedRegister = Reg; 483e8d8bef9SDimitry Andric Object.CalleeSavedRestored = CSInfo.isRestored(); 4840b57cec5SDimitry Andric } else { 485e8d8bef9SDimitry Andric auto &Object = YMF.StackObjects[StackObjectsIdx[FrameIdx]]; 486e8d8bef9SDimitry Andric Object.CalleeSavedRegister = Reg; 487e8d8bef9SDimitry Andric Object.CalleeSavedRestored = CSInfo.isRestored(); 4880b57cec5SDimitry Andric } 4890b57cec5SDimitry Andric } 4900b57cec5SDimitry Andric } 4910b57cec5SDimitry Andric for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) { 4920b57cec5SDimitry Andric auto LocalObject = MFI.getLocalFrameObjectMap(I); 493e8d8bef9SDimitry Andric assert(LocalObject.first >= 0 && "Expected a locally mapped stack object"); 494e8d8bef9SDimitry Andric YMF.StackObjects[StackObjectsIdx[LocalObject.first]].LocalOffset = 495e8d8bef9SDimitry Andric LocalObject.second; 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric // Print the stack object references in the frame information class after 4990b57cec5SDimitry Andric // converting the stack objects. 5000b57cec5SDimitry Andric if (MFI.hasStackProtectorIndex()) { 5010b57cec5SDimitry Andric raw_string_ostream StrOS(YMF.FrameInfo.StackProtector.Value); 5020b57cec5SDimitry Andric MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 5030b57cec5SDimitry Andric .printStackObjectReference(MFI.getStackProtectorIndex()); 5040b57cec5SDimitry Andric } 5050b57cec5SDimitry Andric 50681ad6265SDimitry Andric if (MFI.hasFunctionContextIndex()) { 50781ad6265SDimitry Andric raw_string_ostream StrOS(YMF.FrameInfo.FunctionContext.Value); 50881ad6265SDimitry Andric MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 50981ad6265SDimitry Andric .printStackObjectReference(MFI.getFunctionContextIndex()); 51081ad6265SDimitry Andric } 51181ad6265SDimitry Andric 5120b57cec5SDimitry Andric // Print the debug variable information. 5130b57cec5SDimitry Andric for (const MachineFunction::VariableDbgInfo &DebugVar : 51406c3fb27SDimitry Andric MF.getInStackSlotVariableDbgInfo()) { 51506c3fb27SDimitry Andric int Idx = DebugVar.getStackSlot(); 51606c3fb27SDimitry Andric assert(Idx >= MFI.getObjectIndexBegin() && Idx < MFI.getObjectIndexEnd() && 5170b57cec5SDimitry Andric "Invalid stack object index"); 51806c3fb27SDimitry Andric if (Idx < 0) { // Negative index means fixed objects. 519e8d8bef9SDimitry Andric auto &Object = 52006c3fb27SDimitry Andric YMF.FixedStackObjects[FixedStackObjectsIdx[Idx + 521e8d8bef9SDimitry Andric MFI.getNumFixedObjects()]]; 5220b57cec5SDimitry Andric printStackObjectDbgInfo(DebugVar, Object, MST); 5230b57cec5SDimitry Andric } else { 52406c3fb27SDimitry Andric auto &Object = YMF.StackObjects[StackObjectsIdx[Idx]]; 5250b57cec5SDimitry Andric printStackObjectDbgInfo(DebugVar, Object, MST); 5260b57cec5SDimitry Andric } 5270b57cec5SDimitry Andric } 5280b57cec5SDimitry Andric } 5290b57cec5SDimitry Andric 5300b57cec5SDimitry Andric void MIRPrinter::convertCallSiteObjects(yaml::MachineFunction &YMF, 5310b57cec5SDimitry Andric const MachineFunction &MF, 5320b57cec5SDimitry Andric ModuleSlotTracker &MST) { 5330b57cec5SDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo(); 5340b57cec5SDimitry Andric for (auto CSInfo : MF.getCallSitesInfo()) { 5350b57cec5SDimitry Andric yaml::CallSiteInfo YmlCS; 5360b57cec5SDimitry Andric yaml::CallSiteInfo::MachineInstrLoc CallLocation; 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric // Prepare instruction position. 5398bcb0991SDimitry Andric MachineBasicBlock::const_instr_iterator CallI = CSInfo.first->getIterator(); 5400b57cec5SDimitry Andric CallLocation.BlockNum = CallI->getParent()->getNumber(); 5410b57cec5SDimitry Andric // Get call instruction offset from the beginning of block. 5428bcb0991SDimitry Andric CallLocation.Offset = 5438bcb0991SDimitry Andric std::distance(CallI->getParent()->instr_begin(), CallI); 5440b57cec5SDimitry Andric YmlCS.CallLocation = CallLocation; 5450b57cec5SDimitry Andric // Construct call arguments and theirs forwarding register info. 546*0fca6ea1SDimitry Andric for (auto ArgReg : CSInfo.second.ArgRegPairs) { 5470b57cec5SDimitry Andric yaml::CallSiteInfo::ArgRegPair YmlArgReg; 5480b57cec5SDimitry Andric YmlArgReg.ArgNo = ArgReg.ArgNo; 5490b57cec5SDimitry Andric printRegMIR(ArgReg.Reg, YmlArgReg.Reg, TRI); 5500b57cec5SDimitry Andric YmlCS.ArgForwardingRegs.emplace_back(YmlArgReg); 5510b57cec5SDimitry Andric } 5520b57cec5SDimitry Andric YMF.CallSitesInfo.push_back(YmlCS); 5530b57cec5SDimitry Andric } 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric // Sort call info by position of call instructions. 5560b57cec5SDimitry Andric llvm::sort(YMF.CallSitesInfo.begin(), YMF.CallSitesInfo.end(), 5570b57cec5SDimitry Andric [](yaml::CallSiteInfo A, yaml::CallSiteInfo B) { 5580b57cec5SDimitry Andric if (A.CallLocation.BlockNum == B.CallLocation.BlockNum) 5590b57cec5SDimitry Andric return A.CallLocation.Offset < B.CallLocation.Offset; 5600b57cec5SDimitry Andric return A.CallLocation.BlockNum < B.CallLocation.BlockNum; 5610b57cec5SDimitry Andric }); 5620b57cec5SDimitry Andric } 5630b57cec5SDimitry Andric 564fe6060f1SDimitry Andric void MIRPrinter::convertMachineMetadataNodes(yaml::MachineFunction &YMF, 565fe6060f1SDimitry Andric const MachineFunction &MF, 566fe6060f1SDimitry Andric MachineModuleSlotTracker &MST) { 567fe6060f1SDimitry Andric MachineModuleSlotTracker::MachineMDNodeListType MDList; 568fe6060f1SDimitry Andric MST.collectMachineMDNodes(MDList); 569fe6060f1SDimitry Andric for (auto &MD : MDList) { 570fe6060f1SDimitry Andric std::string NS; 571fe6060f1SDimitry Andric raw_string_ostream StrOS(NS); 572fe6060f1SDimitry Andric MD.second->print(StrOS, MST, MF.getFunction().getParent()); 573*0fca6ea1SDimitry Andric YMF.MachineMetadataNodes.push_back(NS); 574fe6060f1SDimitry Andric } 575fe6060f1SDimitry Andric } 576fe6060f1SDimitry Andric 5770b57cec5SDimitry Andric void MIRPrinter::convert(yaml::MachineFunction &MF, 5780b57cec5SDimitry Andric const MachineConstantPool &ConstantPool) { 5790b57cec5SDimitry Andric unsigned ID = 0; 5800b57cec5SDimitry Andric for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) { 5810b57cec5SDimitry Andric std::string Str; 5820b57cec5SDimitry Andric raw_string_ostream StrOS(Str); 5830b57cec5SDimitry Andric if (Constant.isMachineConstantPoolEntry()) { 5840b57cec5SDimitry Andric Constant.Val.MachineCPVal->print(StrOS); 5850b57cec5SDimitry Andric } else { 5860b57cec5SDimitry Andric Constant.Val.ConstVal->printAsOperand(StrOS); 5870b57cec5SDimitry Andric } 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric yaml::MachineConstantPoolValue YamlConstant; 5900b57cec5SDimitry Andric YamlConstant.ID = ID++; 591*0fca6ea1SDimitry Andric YamlConstant.Value = Str; 5925ffd83dbSDimitry Andric YamlConstant.Alignment = Constant.getAlign(); 5930b57cec5SDimitry Andric YamlConstant.IsTargetSpecific = Constant.isMachineConstantPoolEntry(); 5940b57cec5SDimitry Andric 5950b57cec5SDimitry Andric MF.Constants.push_back(YamlConstant); 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric } 5980b57cec5SDimitry Andric 5990b57cec5SDimitry Andric void MIRPrinter::convert(ModuleSlotTracker &MST, 6000b57cec5SDimitry Andric yaml::MachineJumpTable &YamlJTI, 6010b57cec5SDimitry Andric const MachineJumpTableInfo &JTI) { 6020b57cec5SDimitry Andric YamlJTI.Kind = JTI.getEntryKind(); 6030b57cec5SDimitry Andric unsigned ID = 0; 6040b57cec5SDimitry Andric for (const auto &Table : JTI.getJumpTables()) { 6050b57cec5SDimitry Andric std::string Str; 6060b57cec5SDimitry Andric yaml::MachineJumpTable::Entry Entry; 6070b57cec5SDimitry Andric Entry.ID = ID++; 6080b57cec5SDimitry Andric for (const auto *MBB : Table.MBBs) { 6090b57cec5SDimitry Andric raw_string_ostream StrOS(Str); 6100b57cec5SDimitry Andric StrOS << printMBBReference(*MBB); 611*0fca6ea1SDimitry Andric Entry.Blocks.push_back(Str); 6120b57cec5SDimitry Andric Str.clear(); 6130b57cec5SDimitry Andric } 6140b57cec5SDimitry Andric YamlJTI.Entries.push_back(Entry); 6150b57cec5SDimitry Andric } 6160b57cec5SDimitry Andric } 6170b57cec5SDimitry Andric 6180b57cec5SDimitry Andric void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) { 6190b57cec5SDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo(); 6200b57cec5SDimitry Andric unsigned I = 0; 6210b57cec5SDimitry Andric for (const uint32_t *Mask : TRI->getRegMasks()) 6220b57cec5SDimitry Andric RegisterMaskIds.insert(std::make_pair(Mask, I++)); 6230b57cec5SDimitry Andric } 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric void llvm::guessSuccessors(const MachineBasicBlock &MBB, 6260b57cec5SDimitry Andric SmallVectorImpl<MachineBasicBlock*> &Result, 6270b57cec5SDimitry Andric bool &IsFallthrough) { 6280b57cec5SDimitry Andric SmallPtrSet<MachineBasicBlock*,8> Seen; 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric for (const MachineInstr &MI : MBB) { 6310b57cec5SDimitry Andric if (MI.isPHI()) 6320b57cec5SDimitry Andric continue; 6330b57cec5SDimitry Andric for (const MachineOperand &MO : MI.operands()) { 6340b57cec5SDimitry Andric if (!MO.isMBB()) 6350b57cec5SDimitry Andric continue; 6360b57cec5SDimitry Andric MachineBasicBlock *Succ = MO.getMBB(); 6370b57cec5SDimitry Andric auto RP = Seen.insert(Succ); 6380b57cec5SDimitry Andric if (RP.second) 6390b57cec5SDimitry Andric Result.push_back(Succ); 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric } 6420b57cec5SDimitry Andric MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr(); 6430b57cec5SDimitry Andric IsFallthrough = I == MBB.end() || !I->isBarrier(); 6440b57cec5SDimitry Andric } 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric bool 6470b57cec5SDimitry Andric MIPrinter::canPredictBranchProbabilities(const MachineBasicBlock &MBB) const { 6480b57cec5SDimitry Andric if (MBB.succ_size() <= 1) 6490b57cec5SDimitry Andric return true; 6500b57cec5SDimitry Andric if (!MBB.hasSuccessorProbabilities()) 6510b57cec5SDimitry Andric return true; 6520b57cec5SDimitry Andric 6530b57cec5SDimitry Andric SmallVector<BranchProbability,8> Normalized(MBB.Probs.begin(), 6540b57cec5SDimitry Andric MBB.Probs.end()); 6550b57cec5SDimitry Andric BranchProbability::normalizeProbabilities(Normalized.begin(), 6560b57cec5SDimitry Andric Normalized.end()); 6570b57cec5SDimitry Andric SmallVector<BranchProbability,8> Equal(Normalized.size()); 6580b57cec5SDimitry Andric BranchProbability::normalizeProbabilities(Equal.begin(), Equal.end()); 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andric return std::equal(Normalized.begin(), Normalized.end(), Equal.begin()); 6610b57cec5SDimitry Andric } 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric bool MIPrinter::canPredictSuccessors(const MachineBasicBlock &MBB) const { 6640b57cec5SDimitry Andric SmallVector<MachineBasicBlock*,8> GuessedSuccs; 6650b57cec5SDimitry Andric bool GuessedFallthrough; 6660b57cec5SDimitry Andric guessSuccessors(MBB, GuessedSuccs, GuessedFallthrough); 6670b57cec5SDimitry Andric if (GuessedFallthrough) { 6680b57cec5SDimitry Andric const MachineFunction &MF = *MBB.getParent(); 6690b57cec5SDimitry Andric MachineFunction::const_iterator NextI = std::next(MBB.getIterator()); 6700b57cec5SDimitry Andric if (NextI != MF.end()) { 6710b57cec5SDimitry Andric MachineBasicBlock *Next = const_cast<MachineBasicBlock*>(&*NextI); 6720b57cec5SDimitry Andric if (!is_contained(GuessedSuccs, Next)) 6730b57cec5SDimitry Andric GuessedSuccs.push_back(Next); 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric } 6760b57cec5SDimitry Andric if (GuessedSuccs.size() != MBB.succ_size()) 6770b57cec5SDimitry Andric return false; 6780b57cec5SDimitry Andric return std::equal(MBB.succ_begin(), MBB.succ_end(), GuessedSuccs.begin()); 6790b57cec5SDimitry Andric } 6800b57cec5SDimitry Andric 6810b57cec5SDimitry Andric void MIPrinter::print(const MachineBasicBlock &MBB) { 6820b57cec5SDimitry Andric assert(MBB.getNumber() >= 0 && "Invalid MBB number"); 683e8d8bef9SDimitry Andric MBB.printName(OS, 684e8d8bef9SDimitry Andric MachineBasicBlock::PrintNameIr | 685e8d8bef9SDimitry Andric MachineBasicBlock::PrintNameAttributes, 686e8d8bef9SDimitry Andric &MST); 6870b57cec5SDimitry Andric OS << ":\n"; 6880b57cec5SDimitry Andric 6890b57cec5SDimitry Andric bool HasLineAttributes = false; 6900b57cec5SDimitry Andric // Print the successors 6910b57cec5SDimitry Andric bool canPredictProbs = canPredictBranchProbabilities(MBB); 6920b57cec5SDimitry Andric // Even if the list of successors is empty, if we cannot guess it, 6930b57cec5SDimitry Andric // we need to print it to tell the parser that the list is empty. 6940b57cec5SDimitry Andric // This is needed, because MI model unreachable as empty blocks 6950b57cec5SDimitry Andric // with an empty successor list. If the parser would see that 6960b57cec5SDimitry Andric // without the successor list, it would guess the code would 6970b57cec5SDimitry Andric // fallthrough. 6980b57cec5SDimitry Andric if ((!MBB.succ_empty() && !SimplifyMIR) || !canPredictProbs || 6990b57cec5SDimitry Andric !canPredictSuccessors(MBB)) { 7000b57cec5SDimitry Andric OS.indent(2) << "successors:"; 701*0fca6ea1SDimitry Andric if (!MBB.succ_empty()) 702*0fca6ea1SDimitry Andric OS << " "; 7030b57cec5SDimitry Andric for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) { 7040b57cec5SDimitry Andric if (I != MBB.succ_begin()) 7050b57cec5SDimitry Andric OS << ", "; 7060b57cec5SDimitry Andric OS << printMBBReference(**I); 7070b57cec5SDimitry Andric if (!SimplifyMIR || !canPredictProbs) 7080b57cec5SDimitry Andric OS << '(' 7090b57cec5SDimitry Andric << format("0x%08" PRIx32, MBB.getSuccProbability(I).getNumerator()) 7100b57cec5SDimitry Andric << ')'; 7110b57cec5SDimitry Andric } 7120b57cec5SDimitry Andric OS << "\n"; 7130b57cec5SDimitry Andric HasLineAttributes = true; 7140b57cec5SDimitry Andric } 7150b57cec5SDimitry Andric 7160b57cec5SDimitry Andric // Print the live in registers. 7170b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 71881ad6265SDimitry Andric if (!MBB.livein_empty()) { 7190b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); 7200b57cec5SDimitry Andric OS.indent(2) << "liveins: "; 7210b57cec5SDimitry Andric bool First = true; 72281ad6265SDimitry Andric for (const auto &LI : MBB.liveins_dbg()) { 7230b57cec5SDimitry Andric if (!First) 7240b57cec5SDimitry Andric OS << ", "; 7250b57cec5SDimitry Andric First = false; 7260b57cec5SDimitry Andric OS << printReg(LI.PhysReg, &TRI); 7270b57cec5SDimitry Andric if (!LI.LaneMask.all()) 7280b57cec5SDimitry Andric OS << ":0x" << PrintLaneMask(LI.LaneMask); 7290b57cec5SDimitry Andric } 7300b57cec5SDimitry Andric OS << "\n"; 7310b57cec5SDimitry Andric HasLineAttributes = true; 7320b57cec5SDimitry Andric } 7330b57cec5SDimitry Andric 734*0fca6ea1SDimitry Andric if (HasLineAttributes && !MBB.empty()) 7350b57cec5SDimitry Andric OS << "\n"; 7360b57cec5SDimitry Andric bool IsInBundle = false; 737*0fca6ea1SDimitry Andric for (const MachineInstr &MI : MBB.instrs()) { 7380b57cec5SDimitry Andric if (IsInBundle && !MI.isInsideBundle()) { 7390b57cec5SDimitry Andric OS.indent(2) << "}\n"; 7400b57cec5SDimitry Andric IsInBundle = false; 7410b57cec5SDimitry Andric } 7420b57cec5SDimitry Andric OS.indent(IsInBundle ? 4 : 2); 7430b57cec5SDimitry Andric print(MI); 7440b57cec5SDimitry Andric if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) { 7450b57cec5SDimitry Andric OS << " {"; 7460b57cec5SDimitry Andric IsInBundle = true; 7470b57cec5SDimitry Andric } 7480b57cec5SDimitry Andric OS << "\n"; 7490b57cec5SDimitry Andric } 7500b57cec5SDimitry Andric if (IsInBundle) 7510b57cec5SDimitry Andric OS.indent(2) << "}\n"; 7520b57cec5SDimitry Andric } 7530b57cec5SDimitry Andric 7540b57cec5SDimitry Andric void MIPrinter::print(const MachineInstr &MI) { 7550b57cec5SDimitry Andric const auto *MF = MI.getMF(); 7560b57cec5SDimitry Andric const auto &MRI = MF->getRegInfo(); 7570b57cec5SDimitry Andric const auto &SubTarget = MF->getSubtarget(); 7580b57cec5SDimitry Andric const auto *TRI = SubTarget.getRegisterInfo(); 7590b57cec5SDimitry Andric assert(TRI && "Expected target register info"); 7600b57cec5SDimitry Andric const auto *TII = SubTarget.getInstrInfo(); 7610b57cec5SDimitry Andric assert(TII && "Expected target instruction info"); 7620b57cec5SDimitry Andric if (MI.isCFIInstruction()) 7630b57cec5SDimitry Andric assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction"); 7640b57cec5SDimitry Andric 7650b57cec5SDimitry Andric SmallBitVector PrintedTypes(8); 7660b57cec5SDimitry Andric bool ShouldPrintRegisterTies = MI.hasComplexRegisterTies(); 7670b57cec5SDimitry Andric unsigned I = 0, E = MI.getNumOperands(); 7680b57cec5SDimitry Andric for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() && 7690b57cec5SDimitry Andric !MI.getOperand(I).isImplicit(); 7700b57cec5SDimitry Andric ++I) { 7710b57cec5SDimitry Andric if (I) 7720b57cec5SDimitry Andric OS << ", "; 7735ffd83dbSDimitry Andric print(MI, I, TRI, TII, ShouldPrintRegisterTies, 7740b57cec5SDimitry Andric MI.getTypeToPrint(I, PrintedTypes, MRI), 7750b57cec5SDimitry Andric /*PrintDef=*/false); 7760b57cec5SDimitry Andric } 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andric if (I) 7790b57cec5SDimitry Andric OS << " = "; 7800b57cec5SDimitry Andric if (MI.getFlag(MachineInstr::FrameSetup)) 7810b57cec5SDimitry Andric OS << "frame-setup "; 7820b57cec5SDimitry Andric if (MI.getFlag(MachineInstr::FrameDestroy)) 7830b57cec5SDimitry Andric OS << "frame-destroy "; 7840b57cec5SDimitry Andric if (MI.getFlag(MachineInstr::FmNoNans)) 7850b57cec5SDimitry Andric OS << "nnan "; 7860b57cec5SDimitry Andric if (MI.getFlag(MachineInstr::FmNoInfs)) 7870b57cec5SDimitry Andric OS << "ninf "; 7880b57cec5SDimitry Andric if (MI.getFlag(MachineInstr::FmNsz)) 7890b57cec5SDimitry Andric OS << "nsz "; 7900b57cec5SDimitry Andric if (MI.getFlag(MachineInstr::FmArcp)) 7910b57cec5SDimitry Andric OS << "arcp "; 7920b57cec5SDimitry Andric if (MI.getFlag(MachineInstr::FmContract)) 7930b57cec5SDimitry Andric OS << "contract "; 7940b57cec5SDimitry Andric if (MI.getFlag(MachineInstr::FmAfn)) 7950b57cec5SDimitry Andric OS << "afn "; 7960b57cec5SDimitry Andric if (MI.getFlag(MachineInstr::FmReassoc)) 7970b57cec5SDimitry Andric OS << "reassoc "; 7980b57cec5SDimitry Andric if (MI.getFlag(MachineInstr::NoUWrap)) 7990b57cec5SDimitry Andric OS << "nuw "; 8000b57cec5SDimitry Andric if (MI.getFlag(MachineInstr::NoSWrap)) 8010b57cec5SDimitry Andric OS << "nsw "; 8020b57cec5SDimitry Andric if (MI.getFlag(MachineInstr::IsExact)) 8030b57cec5SDimitry Andric OS << "exact "; 804480093f4SDimitry Andric if (MI.getFlag(MachineInstr::NoFPExcept)) 805480093f4SDimitry Andric OS << "nofpexcept "; 8065ffd83dbSDimitry Andric if (MI.getFlag(MachineInstr::NoMerge)) 8075ffd83dbSDimitry Andric OS << "nomerge "; 80806c3fb27SDimitry Andric if (MI.getFlag(MachineInstr::Unpredictable)) 80906c3fb27SDimitry Andric OS << "unpredictable "; 8105f757f3fSDimitry Andric if (MI.getFlag(MachineInstr::NoConvergent)) 8115f757f3fSDimitry Andric OS << "noconvergent "; 812*0fca6ea1SDimitry Andric if (MI.getFlag(MachineInstr::NonNeg)) 813*0fca6ea1SDimitry Andric OS << "nneg "; 814*0fca6ea1SDimitry Andric if (MI.getFlag(MachineInstr::Disjoint)) 815*0fca6ea1SDimitry Andric OS << "disjoint "; 816*0fca6ea1SDimitry Andric if (MI.getFlag(MachineInstr::NoUSWrap)) 817*0fca6ea1SDimitry Andric OS << "nusw "; 8180b57cec5SDimitry Andric 8190b57cec5SDimitry Andric OS << TII->getName(MI.getOpcode()); 8200b57cec5SDimitry Andric if (I < E) 8210b57cec5SDimitry Andric OS << ' '; 8220b57cec5SDimitry Andric 8230b57cec5SDimitry Andric bool NeedComma = false; 8240b57cec5SDimitry Andric for (; I < E; ++I) { 8250b57cec5SDimitry Andric if (NeedComma) 8260b57cec5SDimitry Andric OS << ", "; 8275ffd83dbSDimitry Andric print(MI, I, TRI, TII, ShouldPrintRegisterTies, 8280b57cec5SDimitry Andric MI.getTypeToPrint(I, PrintedTypes, MRI)); 8290b57cec5SDimitry Andric NeedComma = true; 8300b57cec5SDimitry Andric } 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric // Print any optional symbols attached to this instruction as-if they were 8330b57cec5SDimitry Andric // operands. 8340b57cec5SDimitry Andric if (MCSymbol *PreInstrSymbol = MI.getPreInstrSymbol()) { 8350b57cec5SDimitry Andric if (NeedComma) 8360b57cec5SDimitry Andric OS << ','; 8370b57cec5SDimitry Andric OS << " pre-instr-symbol "; 8380b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *PreInstrSymbol); 8390b57cec5SDimitry Andric NeedComma = true; 8400b57cec5SDimitry Andric } 8410b57cec5SDimitry Andric if (MCSymbol *PostInstrSymbol = MI.getPostInstrSymbol()) { 8420b57cec5SDimitry Andric if (NeedComma) 8430b57cec5SDimitry Andric OS << ','; 8440b57cec5SDimitry Andric OS << " post-instr-symbol "; 8450b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *PostInstrSymbol); 8460b57cec5SDimitry Andric NeedComma = true; 8470b57cec5SDimitry Andric } 848480093f4SDimitry Andric if (MDNode *HeapAllocMarker = MI.getHeapAllocMarker()) { 849480093f4SDimitry Andric if (NeedComma) 850480093f4SDimitry Andric OS << ','; 851480093f4SDimitry Andric OS << " heap-alloc-marker "; 852480093f4SDimitry Andric HeapAllocMarker->printAsOperand(OS, MST); 853480093f4SDimitry Andric NeedComma = true; 854480093f4SDimitry Andric } 855bdd1243dSDimitry Andric if (MDNode *PCSections = MI.getPCSections()) { 856bdd1243dSDimitry Andric if (NeedComma) 857bdd1243dSDimitry Andric OS << ','; 858bdd1243dSDimitry Andric OS << " pcsections "; 859bdd1243dSDimitry Andric PCSections->printAsOperand(OS, MST); 860bdd1243dSDimitry Andric NeedComma = true; 861bdd1243dSDimitry Andric } 862*0fca6ea1SDimitry Andric if (MDNode *MMRA = MI.getMMRAMetadata()) { 863*0fca6ea1SDimitry Andric if (NeedComma) 864*0fca6ea1SDimitry Andric OS << ','; 865*0fca6ea1SDimitry Andric OS << " mmra "; 866*0fca6ea1SDimitry Andric MMRA->printAsOperand(OS, MST); 867*0fca6ea1SDimitry Andric NeedComma = true; 868*0fca6ea1SDimitry Andric } 869bdd1243dSDimitry Andric if (uint32_t CFIType = MI.getCFIType()) { 870bdd1243dSDimitry Andric if (NeedComma) 871bdd1243dSDimitry Andric OS << ','; 872bdd1243dSDimitry Andric OS << " cfi-type " << CFIType; 873bdd1243dSDimitry Andric NeedComma = true; 874bdd1243dSDimitry Andric } 8750b57cec5SDimitry Andric 876e8d8bef9SDimitry Andric if (auto Num = MI.peekDebugInstrNum()) { 877e8d8bef9SDimitry Andric if (NeedComma) 878e8d8bef9SDimitry Andric OS << ','; 879e8d8bef9SDimitry Andric OS << " debug-instr-number " << Num; 880e8d8bef9SDimitry Andric NeedComma = true; 881e8d8bef9SDimitry Andric } 882e8d8bef9SDimitry Andric 8835ffd83dbSDimitry Andric if (PrintLocations) { 8840b57cec5SDimitry Andric if (const DebugLoc &DL = MI.getDebugLoc()) { 8850b57cec5SDimitry Andric if (NeedComma) 8860b57cec5SDimitry Andric OS << ','; 8870b57cec5SDimitry Andric OS << " debug-location "; 8880b57cec5SDimitry Andric DL->printAsOperand(OS, MST); 8890b57cec5SDimitry Andric } 8905ffd83dbSDimitry Andric } 8910b57cec5SDimitry Andric 8920b57cec5SDimitry Andric if (!MI.memoperands_empty()) { 8930b57cec5SDimitry Andric OS << " :: "; 8940b57cec5SDimitry Andric const LLVMContext &Context = MF->getFunction().getContext(); 8950b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF->getFrameInfo(); 8960b57cec5SDimitry Andric bool NeedComma = false; 8970b57cec5SDimitry Andric for (const auto *Op : MI.memoperands()) { 8980b57cec5SDimitry Andric if (NeedComma) 8990b57cec5SDimitry Andric OS << ", "; 9000b57cec5SDimitry Andric Op->print(OS, MST, SSNs, Context, &MFI, TII); 9010b57cec5SDimitry Andric NeedComma = true; 9020b57cec5SDimitry Andric } 9030b57cec5SDimitry Andric } 9040b57cec5SDimitry Andric } 9050b57cec5SDimitry Andric 9060b57cec5SDimitry Andric void MIPrinter::printStackObjectReference(int FrameIndex) { 9070b57cec5SDimitry Andric auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex); 9080b57cec5SDimitry Andric assert(ObjectInfo != StackObjectOperandMapping.end() && 9090b57cec5SDimitry Andric "Invalid frame index"); 9100b57cec5SDimitry Andric const FrameIndexOperand &Operand = ObjectInfo->second; 9110b57cec5SDimitry Andric MachineOperand::printStackObjectReference(OS, Operand.ID, Operand.IsFixed, 9120b57cec5SDimitry Andric Operand.Name); 9130b57cec5SDimitry Andric } 9140b57cec5SDimitry Andric 9155ffd83dbSDimitry Andric static std::string formatOperandComment(std::string Comment) { 9165ffd83dbSDimitry Andric if (Comment.empty()) 9175ffd83dbSDimitry Andric return Comment; 9185ffd83dbSDimitry Andric return std::string(" /* " + Comment + " */"); 9195ffd83dbSDimitry Andric } 9205ffd83dbSDimitry Andric 9210b57cec5SDimitry Andric void MIPrinter::print(const MachineInstr &MI, unsigned OpIdx, 9220b57cec5SDimitry Andric const TargetRegisterInfo *TRI, 9235ffd83dbSDimitry Andric const TargetInstrInfo *TII, 9240b57cec5SDimitry Andric bool ShouldPrintRegisterTies, LLT TypeToPrint, 9250b57cec5SDimitry Andric bool PrintDef) { 9260b57cec5SDimitry Andric const MachineOperand &Op = MI.getOperand(OpIdx); 9275ffd83dbSDimitry Andric std::string MOComment = TII->createMIROperandComment(MI, Op, OpIdx, TRI); 9285ffd83dbSDimitry Andric 9290b57cec5SDimitry Andric switch (Op.getType()) { 9300b57cec5SDimitry Andric case MachineOperand::MO_Immediate: 9310b57cec5SDimitry Andric if (MI.isOperandSubregIdx(OpIdx)) { 9320b57cec5SDimitry Andric MachineOperand::printTargetFlags(OS, Op); 9330b57cec5SDimitry Andric MachineOperand::printSubRegIdx(OS, Op.getImm(), TRI); 9340b57cec5SDimitry Andric break; 9350b57cec5SDimitry Andric } 936bdd1243dSDimitry Andric [[fallthrough]]; 9370b57cec5SDimitry Andric case MachineOperand::MO_Register: 9380b57cec5SDimitry Andric case MachineOperand::MO_CImmediate: 9390b57cec5SDimitry Andric case MachineOperand::MO_FPImmediate: 9400b57cec5SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 9410b57cec5SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 9420b57cec5SDimitry Andric case MachineOperand::MO_TargetIndex: 9430b57cec5SDimitry Andric case MachineOperand::MO_JumpTableIndex: 9440b57cec5SDimitry Andric case MachineOperand::MO_ExternalSymbol: 9450b57cec5SDimitry Andric case MachineOperand::MO_GlobalAddress: 9460b57cec5SDimitry Andric case MachineOperand::MO_RegisterLiveOut: 9470b57cec5SDimitry Andric case MachineOperand::MO_Metadata: 9480b57cec5SDimitry Andric case MachineOperand::MO_MCSymbol: 9490b57cec5SDimitry Andric case MachineOperand::MO_CFIIndex: 9500b57cec5SDimitry Andric case MachineOperand::MO_IntrinsicID: 9510b57cec5SDimitry Andric case MachineOperand::MO_Predicate: 9528bcb0991SDimitry Andric case MachineOperand::MO_BlockAddress: 953bdd1243dSDimitry Andric case MachineOperand::MO_DbgInstrRef: 9548bcb0991SDimitry Andric case MachineOperand::MO_ShuffleMask: { 9550b57cec5SDimitry Andric unsigned TiedOperandIdx = 0; 9560b57cec5SDimitry Andric if (ShouldPrintRegisterTies && Op.isReg() && Op.isTied() && !Op.isDef()) 9570b57cec5SDimitry Andric TiedOperandIdx = Op.getParent()->findTiedOperandIdx(OpIdx); 9580b57cec5SDimitry Andric const TargetIntrinsicInfo *TII = MI.getMF()->getTarget().getIntrinsicInfo(); 959480093f4SDimitry Andric Op.print(OS, MST, TypeToPrint, OpIdx, PrintDef, /*IsStandalone=*/false, 9600b57cec5SDimitry Andric ShouldPrintRegisterTies, TiedOperandIdx, TRI, TII); 9615ffd83dbSDimitry Andric OS << formatOperandComment(MOComment); 9620b57cec5SDimitry Andric break; 9630b57cec5SDimitry Andric } 9640b57cec5SDimitry Andric case MachineOperand::MO_FrameIndex: 9650b57cec5SDimitry Andric printStackObjectReference(Op.getIndex()); 9660b57cec5SDimitry Andric break; 9670b57cec5SDimitry Andric case MachineOperand::MO_RegisterMask: { 9680b57cec5SDimitry Andric auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); 9690b57cec5SDimitry Andric if (RegMaskInfo != RegisterMaskIds.end()) 9700b57cec5SDimitry Andric OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); 9710b57cec5SDimitry Andric else 9720b57cec5SDimitry Andric printCustomRegMask(Op.getRegMask(), OS, TRI); 9730b57cec5SDimitry Andric break; 9740b57cec5SDimitry Andric } 9750b57cec5SDimitry Andric } 9760b57cec5SDimitry Andric } 9770b57cec5SDimitry Andric 978480093f4SDimitry Andric void MIRFormatter::printIRValue(raw_ostream &OS, const Value &V, 979480093f4SDimitry Andric ModuleSlotTracker &MST) { 980480093f4SDimitry Andric if (isa<GlobalValue>(V)) { 981480093f4SDimitry Andric V.printAsOperand(OS, /*PrintType=*/false, MST); 982480093f4SDimitry Andric return; 983480093f4SDimitry Andric } 984480093f4SDimitry Andric if (isa<Constant>(V)) { 985480093f4SDimitry Andric // Machine memory operands can load/store to/from constant value pointers. 986480093f4SDimitry Andric OS << '`'; 987480093f4SDimitry Andric V.printAsOperand(OS, /*PrintType=*/true, MST); 988480093f4SDimitry Andric OS << '`'; 989480093f4SDimitry Andric return; 990480093f4SDimitry Andric } 991480093f4SDimitry Andric OS << "%ir."; 992480093f4SDimitry Andric if (V.hasName()) { 993480093f4SDimitry Andric printLLVMNameWithoutPrefix(OS, V.getName()); 994480093f4SDimitry Andric return; 995480093f4SDimitry Andric } 996480093f4SDimitry Andric int Slot = MST.getCurrentFunction() ? MST.getLocalSlot(&V) : -1; 997480093f4SDimitry Andric MachineOperand::printIRSlotNumber(OS, Slot); 998480093f4SDimitry Andric } 999480093f4SDimitry Andric 10000b57cec5SDimitry Andric void llvm::printMIR(raw_ostream &OS, const Module &M) { 1001*0fca6ea1SDimitry Andric ScopedDbgInfoFormatSetter FormatSetter(const_cast<Module &>(M), 1002*0fca6ea1SDimitry Andric WriteNewDbgInfoFormat); 10035f757f3fSDimitry Andric 10040b57cec5SDimitry Andric yaml::Output Out(OS); 10050b57cec5SDimitry Andric Out << const_cast<Module &>(M); 10060b57cec5SDimitry Andric } 10070b57cec5SDimitry Andric 10080b57cec5SDimitry Andric void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) { 1009*0fca6ea1SDimitry Andric // RemoveDIs: as there's no textual form for DbgRecords yet, print debug-info 10105f757f3fSDimitry Andric // in dbg.value format. 1011*0fca6ea1SDimitry Andric ScopedDbgInfoFormatSetter FormatSetter( 1012*0fca6ea1SDimitry Andric const_cast<Function &>(MF.getFunction()), WriteNewDbgInfoFormat); 10135f757f3fSDimitry Andric 10140b57cec5SDimitry Andric MIRPrinter Printer(OS); 10150b57cec5SDimitry Andric Printer.print(MF); 10160b57cec5SDimitry Andric } 1017