1345c1449SAlex Lorenz //===- MIRPrinter.cpp - MIR serialization format printer ------------------===// 2345c1449SAlex Lorenz // 3345c1449SAlex Lorenz // The LLVM Compiler Infrastructure 4345c1449SAlex Lorenz // 5345c1449SAlex Lorenz // This file is distributed under the University of Illinois Open Source 6345c1449SAlex Lorenz // License. See LICENSE.TXT for details. 7345c1449SAlex Lorenz // 8345c1449SAlex Lorenz //===----------------------------------------------------------------------===// 9345c1449SAlex Lorenz // 10345c1449SAlex Lorenz // This file implements the class that prints out the LLVM IR and machine 11345c1449SAlex Lorenz // functions using the MIR serialization format. 12345c1449SAlex Lorenz // 13345c1449SAlex Lorenz //===----------------------------------------------------------------------===// 14345c1449SAlex Lorenz 15fb69e66cSEugene Zelenko #include "llvm/ADT/DenseMap.h" 16fb69e66cSEugene Zelenko #include "llvm/ADT/None.h" 17d28d3cc0STim Northover #include "llvm/ADT/SmallBitVector.h" 18fb69e66cSEugene Zelenko #include "llvm/ADT/SmallPtrSet.h" 19fb69e66cSEugene Zelenko #include "llvm/ADT/SmallVector.h" 20fb69e66cSEugene Zelenko #include "llvm/ADT/STLExtras.h" 21bb80d3e1SKonstantin Zhuravlyov #include "llvm/ADT/StringExtras.h" 22fb69e66cSEugene Zelenko #include "llvm/ADT/StringRef.h" 23fb69e66cSEugene Zelenko #include "llvm/ADT/Twine.h" 24fab1cfe6SQuentin Colombet #include "llvm/CodeGen/GlobalISel/RegisterBank.h" 25fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineBasicBlock.h" 26ab980499SAlex Lorenz #include "llvm/CodeGen/MachineConstantPool.h" 2760541c1dSAlex Lorenz #include "llvm/CodeGen/MachineFrameInfo.h" 28fab1cfe6SQuentin Colombet #include "llvm/CodeGen/MachineFunction.h" 29fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineInstr.h" 30fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineJumpTableInfo.h" 314af7e610SAlex Lorenz #include "llvm/CodeGen/MachineMemOperand.h" 32fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineOperand.h" 3354565cf0SAlex Lorenz #include "llvm/CodeGen/MachineRegisterInfo.h" 34fb69e66cSEugene Zelenko #include "llvm/CodeGen/MIRPrinter.h" 35fb69e66cSEugene Zelenko #include "llvm/CodeGen/MIRYamlMapping.h" 36fb69e66cSEugene Zelenko #include "llvm/CodeGen/PseudoSourceValue.h" 374f093bf1SAlex Lorenz #include "llvm/IR/BasicBlock.h" 38deb53490SAlex Lorenz #include "llvm/IR/Constants.h" 3928865809SReid Kleckner #include "llvm/IR/DebugInfo.h" 40fb69e66cSEugene Zelenko #include "llvm/IR/DebugLoc.h" 41fb69e66cSEugene Zelenko #include "llvm/IR/Function.h" 42fb69e66cSEugene Zelenko #include "llvm/IR/GlobalValue.h" 43fb69e66cSEugene Zelenko #include "llvm/IR/InstrTypes.h" 44fab1cfe6SQuentin Colombet #include "llvm/IR/Instructions.h" 456b3bd612STim Northover #include "llvm/IR/Intrinsics.h" 46fb69e66cSEugene Zelenko #include "llvm/IR/IRPrintingPasses.h" 47345c1449SAlex Lorenz #include "llvm/IR/Module.h" 48900b5cb2SAlex Lorenz #include "llvm/IR/ModuleSlotTracker.h" 49fb69e66cSEugene Zelenko #include "llvm/IR/Value.h" 50fb69e66cSEugene Zelenko #include "llvm/MC/LaneBitmask.h" 51fb69e66cSEugene Zelenko #include "llvm/MC/MCDwarf.h" 52f22ca8adSAlex Lorenz #include "llvm/MC/MCSymbol.h" 53fb69e66cSEugene Zelenko #include "llvm/Support/AtomicOrdering.h" 54fb69e66cSEugene Zelenko #include "llvm/Support/BranchProbability.h" 55fb69e66cSEugene Zelenko #include "llvm/Support/Casting.h" 56fb69e66cSEugene Zelenko #include "llvm/Support/CommandLine.h" 57fb69e66cSEugene Zelenko #include "llvm/Support/ErrorHandling.h" 58b51774acSGeoff Berry #include "llvm/Support/Format.h" 59fb69e66cSEugene Zelenko #include "llvm/Support/LowLevelTypeImpl.h" 60fab1cfe6SQuentin Colombet #include "llvm/Support/raw_ostream.h" 61fb69e66cSEugene Zelenko #include "llvm/Support/YAMLTraits.h" 628e0a1b48SAlex Lorenz #include "llvm/Target/TargetInstrInfo.h" 636b3bd612STim Northover #include "llvm/Target/TargetIntrinsicInfo.h" 64fb69e66cSEugene Zelenko #include "llvm/Target/TargetMachine.h" 65fb69e66cSEugene Zelenko #include "llvm/Target/TargetRegisterInfo.h" 668e0a1b48SAlex Lorenz #include "llvm/Target/TargetSubtargetInfo.h" 67fb69e66cSEugene Zelenko #include <algorithm> 68fb69e66cSEugene Zelenko #include <cassert> 69fb69e66cSEugene Zelenko #include <cinttypes> 70fb69e66cSEugene Zelenko #include <cstdint> 71fb69e66cSEugene Zelenko #include <iterator> 72fb69e66cSEugene Zelenko #include <string> 73fb69e66cSEugene Zelenko #include <utility> 74fb69e66cSEugene Zelenko #include <vector> 75345c1449SAlex Lorenz 76345c1449SAlex Lorenz using namespace llvm; 77345c1449SAlex Lorenz 788940114fSMatthias Braun static cl::opt<bool> SimplifyMIR("simplify-mir", 798940114fSMatthias Braun cl::desc("Leave out unnecessary information when printing MIR")); 808940114fSMatthias Braun 81345c1449SAlex Lorenz namespace { 82345c1449SAlex Lorenz 837feaf7c6SAlex Lorenz /// This structure describes how to print out stack object references. 847feaf7c6SAlex Lorenz struct FrameIndexOperand { 857feaf7c6SAlex Lorenz std::string Name; 867feaf7c6SAlex Lorenz unsigned ID; 877feaf7c6SAlex Lorenz bool IsFixed; 887feaf7c6SAlex Lorenz 897feaf7c6SAlex Lorenz FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed) 907feaf7c6SAlex Lorenz : Name(Name.str()), ID(ID), IsFixed(IsFixed) {} 917feaf7c6SAlex Lorenz 927feaf7c6SAlex Lorenz /// Return an ordinary stack object reference. 937feaf7c6SAlex Lorenz static FrameIndexOperand create(StringRef Name, unsigned ID) { 947feaf7c6SAlex Lorenz return FrameIndexOperand(Name, ID, /*IsFixed=*/false); 957feaf7c6SAlex Lorenz } 967feaf7c6SAlex Lorenz 977feaf7c6SAlex Lorenz /// Return a fixed stack object reference. 987feaf7c6SAlex Lorenz static FrameIndexOperand createFixed(unsigned ID) { 997feaf7c6SAlex Lorenz return FrameIndexOperand("", ID, /*IsFixed=*/true); 1007feaf7c6SAlex Lorenz } 1017feaf7c6SAlex Lorenz }; 1027feaf7c6SAlex Lorenz 103618b283cSAlex Lorenz } // end anonymous namespace 104618b283cSAlex Lorenz 105618b283cSAlex Lorenz namespace llvm { 106618b283cSAlex Lorenz 107345c1449SAlex Lorenz /// This class prints out the machine functions using the MIR serialization 108345c1449SAlex Lorenz /// format. 109345c1449SAlex Lorenz class MIRPrinter { 110345c1449SAlex Lorenz raw_ostream &OS; 1118f6f4285SAlex Lorenz DenseMap<const uint32_t *, unsigned> RegisterMaskIds; 1127feaf7c6SAlex Lorenz /// Maps from stack object indices to operand indices which will be used when 1137feaf7c6SAlex Lorenz /// printing frame index machine operands. 1147feaf7c6SAlex Lorenz DenseMap<int, FrameIndexOperand> StackObjectOperandMapping; 115345c1449SAlex Lorenz 116345c1449SAlex Lorenz public: 117345c1449SAlex Lorenz MIRPrinter(raw_ostream &OS) : OS(OS) {} 118345c1449SAlex Lorenz 119345c1449SAlex Lorenz void print(const MachineFunction &MF); 1204f093bf1SAlex Lorenz 12128148ba8SAlex Lorenz void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo, 12228148ba8SAlex Lorenz const TargetRegisterInfo *TRI); 123a6f9a37dSAlex Lorenz void convert(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI, 124a6f9a37dSAlex Lorenz const MachineFrameInfo &MFI); 125ab980499SAlex Lorenz void convert(yaml::MachineFunction &MF, 126ab980499SAlex Lorenz const MachineConstantPool &ConstantPool); 1276799e9b3SAlex Lorenz void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI, 1286799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI); 129ef331effSMatthias Braun void convertStackObjects(yaml::MachineFunction &YMF, 130ef331effSMatthias Braun const MachineFunction &MF, ModuleSlotTracker &MST); 1318f6f4285SAlex Lorenz 1328f6f4285SAlex Lorenz private: 1338f6f4285SAlex Lorenz void initRegisterMaskIds(const MachineFunction &MF); 134345c1449SAlex Lorenz }; 135345c1449SAlex Lorenz 1368e0a1b48SAlex Lorenz /// This class prints out the machine instructions using the MIR serialization 1378e0a1b48SAlex Lorenz /// format. 1388e0a1b48SAlex Lorenz class MIPrinter { 1398e0a1b48SAlex Lorenz raw_ostream &OS; 140900b5cb2SAlex Lorenz ModuleSlotTracker &MST; 1418f6f4285SAlex Lorenz const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds; 1427feaf7c6SAlex Lorenz const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping; 143bb80d3e1SKonstantin Zhuravlyov /// Synchronization scope names registered with LLVMContext. 144bb80d3e1SKonstantin Zhuravlyov SmallVector<StringRef, 8> SSNs; 1458e0a1b48SAlex Lorenz 1468940114fSMatthias Braun bool canPredictBranchProbabilities(const MachineBasicBlock &MBB) const; 1478940114fSMatthias Braun bool canPredictSuccessors(const MachineBasicBlock &MBB) const; 1488940114fSMatthias Braun 1498e0a1b48SAlex Lorenz public: 150900b5cb2SAlex Lorenz MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST, 1517feaf7c6SAlex Lorenz const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds, 1527feaf7c6SAlex Lorenz const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping) 1537feaf7c6SAlex Lorenz : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds), 1547feaf7c6SAlex Lorenz StackObjectOperandMapping(StackObjectOperandMapping) {} 1558e0a1b48SAlex Lorenz 1565022f6bbSAlex Lorenz void print(const MachineBasicBlock &MBB); 1575022f6bbSAlex Lorenz 1588e0a1b48SAlex Lorenz void print(const MachineInstr &MI); 1595d26fa83SAlex Lorenz void printMBBReference(const MachineBasicBlock &MBB); 160deb53490SAlex Lorenz void printIRBlockReference(const BasicBlock &BB); 1614af7e610SAlex Lorenz void printIRValueReference(const Value &V); 1627feaf7c6SAlex Lorenz void printStackObjectReference(int FrameIndex); 1635672a893SAlex Lorenz void printOffset(int64_t Offset); 16449873a83SAlex Lorenz void printTargetFlags(const MachineOperand &Op); 165e66a7ccfSAlex Lorenz void print(const MachineOperand &Op, const TargetRegisterInfo *TRI, 1664e14a497SQuentin Colombet unsigned I, bool ShouldPrintRegisterTies, 167d28d3cc0STim Northover LLT TypeToPrint, bool IsDef = false); 168*6748abe2SGeoff Berry void print(const LLVMContext &Context, const TargetInstrInfo &TII, 169*6748abe2SGeoff Berry const MachineMemOperand &Op); 170bb80d3e1SKonstantin Zhuravlyov void printSyncScope(const LLVMContext &Context, SyncScope::ID SSID); 171f4baeb51SAlex Lorenz 1728cfc6867SAlex Lorenz void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI); 1738e0a1b48SAlex Lorenz }; 1748e0a1b48SAlex Lorenz 1755022f6bbSAlex Lorenz } // end namespace llvm 176345c1449SAlex Lorenz 177345c1449SAlex Lorenz namespace llvm { 178345c1449SAlex Lorenz namespace yaml { 179345c1449SAlex Lorenz 180345c1449SAlex Lorenz /// This struct serializes the LLVM IR module. 181345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> { 182345c1449SAlex Lorenz static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) { 183345c1449SAlex Lorenz Mod.print(OS, nullptr); 184345c1449SAlex Lorenz } 185fb69e66cSEugene Zelenko 186345c1449SAlex Lorenz static StringRef input(StringRef Str, void *Ctxt, Module &Mod) { 187345c1449SAlex Lorenz llvm_unreachable("LLVM Module is supposed to be parsed separately"); 188345c1449SAlex Lorenz return ""; 189345c1449SAlex Lorenz } 190345c1449SAlex Lorenz }; 191345c1449SAlex Lorenz 192345c1449SAlex Lorenz } // end namespace yaml 193345c1449SAlex Lorenz } // end namespace llvm 194345c1449SAlex Lorenz 19515a00a85SAlex Lorenz static void printReg(unsigned Reg, raw_ostream &OS, 19615a00a85SAlex Lorenz const TargetRegisterInfo *TRI) { 19715a00a85SAlex Lorenz // TODO: Print Stack Slots. 19815a00a85SAlex Lorenz if (!Reg) 19915a00a85SAlex Lorenz OS << '_'; 20015a00a85SAlex Lorenz else if (TargetRegisterInfo::isVirtualRegister(Reg)) 20115a00a85SAlex Lorenz OS << '%' << TargetRegisterInfo::virtReg2Index(Reg); 20215a00a85SAlex Lorenz else if (Reg < TRI->getNumRegs()) 20315a00a85SAlex Lorenz OS << '%' << StringRef(TRI->getName(Reg)).lower(); 20415a00a85SAlex Lorenz else 20515a00a85SAlex Lorenz llvm_unreachable("Can't print this kind of register yet"); 20615a00a85SAlex Lorenz } 20715a00a85SAlex Lorenz 208ab4cbcfdSAlex Lorenz static void printReg(unsigned Reg, yaml::StringValue &Dest, 209ab4cbcfdSAlex Lorenz const TargetRegisterInfo *TRI) { 210ab4cbcfdSAlex Lorenz raw_string_ostream OS(Dest.Value); 211ab4cbcfdSAlex Lorenz printReg(Reg, OS, TRI); 212ab4cbcfdSAlex Lorenz } 213ab4cbcfdSAlex Lorenz 214345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) { 2158f6f4285SAlex Lorenz initRegisterMaskIds(MF); 2168f6f4285SAlex Lorenz 217345c1449SAlex Lorenz yaml::MachineFunction YamlMF; 218345c1449SAlex Lorenz YamlMF.Name = MF.getName(); 2195b5f9753SAlex Lorenz YamlMF.Alignment = MF.getAlignment(); 2205b5f9753SAlex Lorenz YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice(); 221ad154c83SDerek Schuff 2220d7b0cb8SAhmed Bougacha YamlMF.Legalized = MF.getProperties().hasProperty( 2230d7b0cb8SAhmed Bougacha MachineFunctionProperties::Property::Legalized); 22424712655SAhmed Bougacha YamlMF.RegBankSelected = MF.getProperties().hasProperty( 22524712655SAhmed Bougacha MachineFunctionProperties::Property::RegBankSelected); 226b109d518SAhmed Bougacha YamlMF.Selected = MF.getProperties().hasProperty( 227b109d518SAhmed Bougacha MachineFunctionProperties::Property::Selected); 2280d7b0cb8SAhmed Bougacha 22928148ba8SAlex Lorenz convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo()); 230a6f9a37dSAlex Lorenz ModuleSlotTracker MST(MF.getFunction()->getParent()); 231a6f9a37dSAlex Lorenz MST.incorporateFunction(*MF.getFunction()); 232941a705bSMatthias Braun convert(MST, YamlMF.FrameInfo, MF.getFrameInfo()); 233ef331effSMatthias Braun convertStackObjects(YamlMF, MF, MST); 234ab980499SAlex Lorenz if (const auto *ConstantPool = MF.getConstantPool()) 235ab980499SAlex Lorenz convert(YamlMF, *ConstantPool); 2366799e9b3SAlex Lorenz if (const auto *JumpTableInfo = MF.getJumpTableInfo()) 2376799e9b3SAlex Lorenz convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo); 2385022f6bbSAlex Lorenz raw_string_ostream StrOS(YamlMF.Body.Value.Value); 2395022f6bbSAlex Lorenz bool IsNewlineNeeded = false; 2404f093bf1SAlex Lorenz for (const auto &MBB : MF) { 2415022f6bbSAlex Lorenz if (IsNewlineNeeded) 2425022f6bbSAlex Lorenz StrOS << "\n"; 2435022f6bbSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 2445022f6bbSAlex Lorenz .print(MBB); 2455022f6bbSAlex Lorenz IsNewlineNeeded = true; 2464f093bf1SAlex Lorenz } 2475022f6bbSAlex Lorenz StrOS.flush(); 248345c1449SAlex Lorenz yaml::Output Out(OS); 24956d87ef5SVivek Pandya if (!SimplifyMIR) 25056d87ef5SVivek Pandya Out.setWriteDefaultValues(true); 251345c1449SAlex Lorenz Out << YamlMF; 252345c1449SAlex Lorenz } 253345c1449SAlex Lorenz 2540ef61ec3SOren Ben Simhon static void printCustomRegMask(const uint32_t *RegMask, raw_ostream &OS, 2550ef61ec3SOren Ben Simhon const TargetRegisterInfo *TRI) { 2560ef61ec3SOren Ben Simhon assert(RegMask && "Can't print an empty register mask"); 2570ef61ec3SOren Ben Simhon OS << StringRef("CustomRegMask("); 2580ef61ec3SOren Ben Simhon 2590ef61ec3SOren Ben Simhon bool IsRegInRegMaskFound = false; 2600ef61ec3SOren Ben Simhon for (int I = 0, E = TRI->getNumRegs(); I < E; I++) { 2610ef61ec3SOren Ben Simhon // Check whether the register is asserted in regmask. 2620ef61ec3SOren Ben Simhon if (RegMask[I / 32] & (1u << (I % 32))) { 2630ef61ec3SOren Ben Simhon if (IsRegInRegMaskFound) 2640ef61ec3SOren Ben Simhon OS << ','; 2650ef61ec3SOren Ben Simhon printReg(I, OS, TRI); 2660ef61ec3SOren Ben Simhon IsRegInRegMaskFound = true; 2670ef61ec3SOren Ben Simhon } 2680ef61ec3SOren Ben Simhon } 2690ef61ec3SOren Ben Simhon 2700ef61ec3SOren Ben Simhon OS << ')'; 2710ef61ec3SOren Ben Simhon } 2720ef61ec3SOren Ben Simhon 27354565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 27428148ba8SAlex Lorenz const MachineRegisterInfo &RegInfo, 27528148ba8SAlex Lorenz const TargetRegisterInfo *TRI) { 27654565cf0SAlex Lorenz MF.TracksRegLiveness = RegInfo.tracksLiveness(); 27728148ba8SAlex Lorenz 27828148ba8SAlex Lorenz // Print the virtual register definitions. 27928148ba8SAlex Lorenz for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) { 28028148ba8SAlex Lorenz unsigned Reg = TargetRegisterInfo::index2VirtReg(I); 28128148ba8SAlex Lorenz yaml::VirtualRegisterDefinition VReg; 28228148ba8SAlex Lorenz VReg.ID = I; 283fab1cfe6SQuentin Colombet if (RegInfo.getRegClassOrNull(Reg)) 28428148ba8SAlex Lorenz VReg.Class = 28528148ba8SAlex Lorenz StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower(); 286fab1cfe6SQuentin Colombet else if (RegInfo.getRegBankOrNull(Reg)) 287fab1cfe6SQuentin Colombet VReg.Class = StringRef(RegInfo.getRegBankOrNull(Reg)->getName()).lower(); 288050b2118SQuentin Colombet else { 289050b2118SQuentin Colombet VReg.Class = std::string("_"); 290d28d3cc0STim Northover assert((RegInfo.def_empty(Reg) || RegInfo.getType(Reg).isValid()) && 2910f140c76STim Northover "Generic registers must have a valid type"); 292050b2118SQuentin Colombet } 293ab4cbcfdSAlex Lorenz unsigned PreferredReg = RegInfo.getSimpleHint(Reg); 294ab4cbcfdSAlex Lorenz if (PreferredReg) 295ab4cbcfdSAlex Lorenz printReg(PreferredReg, VReg.PreferredRegister, TRI); 29628148ba8SAlex Lorenz MF.VirtualRegisters.push_back(VReg); 29728148ba8SAlex Lorenz } 29812045a4bSAlex Lorenz 29912045a4bSAlex Lorenz // Print the live ins. 30012045a4bSAlex Lorenz for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) { 30112045a4bSAlex Lorenz yaml::MachineFunctionLiveIn LiveIn; 30212045a4bSAlex Lorenz printReg(I->first, LiveIn.Register, TRI); 30312045a4bSAlex Lorenz if (I->second) 30412045a4bSAlex Lorenz printReg(I->second, LiveIn.VirtualRegister, TRI); 30512045a4bSAlex Lorenz MF.LiveIns.push_back(LiveIn); 30612045a4bSAlex Lorenz } 3070ef61ec3SOren Ben Simhon 3080ef61ec3SOren Ben Simhon // Prints the callee saved registers. 3090ef61ec3SOren Ben Simhon if (RegInfo.isUpdatedCSRsInitialized()) { 3100ef61ec3SOren Ben Simhon const MCPhysReg *CalleeSavedRegs = RegInfo.getCalleeSavedRegs(); 311c4838087SAlex Lorenz std::vector<yaml::FlowStringValue> CalleeSavedRegisters; 3120ef61ec3SOren Ben Simhon for (const MCPhysReg *I = CalleeSavedRegs; *I; ++I) { 313c4838087SAlex Lorenz yaml::FlowStringValue Reg; 3140ef61ec3SOren Ben Simhon printReg(*I, Reg, TRI); 315c4838087SAlex Lorenz CalleeSavedRegisters.push_back(Reg); 316c4838087SAlex Lorenz } 317c4838087SAlex Lorenz MF.CalleeSavedRegisters = CalleeSavedRegisters; 31854565cf0SAlex Lorenz } 3190ef61ec3SOren Ben Simhon } 32054565cf0SAlex Lorenz 321a6f9a37dSAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 322a6f9a37dSAlex Lorenz yaml::MachineFrameInfo &YamlMFI, 32360541c1dSAlex Lorenz const MachineFrameInfo &MFI) { 32460541c1dSAlex Lorenz YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken(); 32560541c1dSAlex Lorenz YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken(); 32660541c1dSAlex Lorenz YamlMFI.HasStackMap = MFI.hasStackMap(); 32760541c1dSAlex Lorenz YamlMFI.HasPatchPoint = MFI.hasPatchPoint(); 32860541c1dSAlex Lorenz YamlMFI.StackSize = MFI.getStackSize(); 32960541c1dSAlex Lorenz YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment(); 33060541c1dSAlex Lorenz YamlMFI.MaxAlignment = MFI.getMaxAlignment(); 33160541c1dSAlex Lorenz YamlMFI.AdjustsStack = MFI.adjustsStack(); 33260541c1dSAlex Lorenz YamlMFI.HasCalls = MFI.hasCalls(); 333ab9438cbSMatthias Braun YamlMFI.MaxCallFrameSize = MFI.isMaxCallFrameSizeComputed() 334ab9438cbSMatthias Braun ? MFI.getMaxCallFrameSize() : ~0u; 33560541c1dSAlex Lorenz YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment(); 33660541c1dSAlex Lorenz YamlMFI.HasVAStart = MFI.hasVAStart(); 33760541c1dSAlex Lorenz YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc(); 338a6f9a37dSAlex Lorenz if (MFI.getSavePoint()) { 339a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.SavePoint.Value); 340a6f9a37dSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 341a6f9a37dSAlex Lorenz .printMBBReference(*MFI.getSavePoint()); 342a6f9a37dSAlex Lorenz } 343a6f9a37dSAlex Lorenz if (MFI.getRestorePoint()) { 344a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.RestorePoint.Value); 345a6f9a37dSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 346a6f9a37dSAlex Lorenz .printMBBReference(*MFI.getRestorePoint()); 347a6f9a37dSAlex Lorenz } 34860541c1dSAlex Lorenz } 34960541c1dSAlex Lorenz 350ef331effSMatthias Braun void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF, 351ef331effSMatthias Braun const MachineFunction &MF, 352ef331effSMatthias Braun ModuleSlotTracker &MST) { 353ef331effSMatthias Braun const MachineFrameInfo &MFI = MF.getFrameInfo(); 354ef331effSMatthias Braun const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 355de491f05SAlex Lorenz // Process fixed stack objects. 356f6bc8667SAlex Lorenz unsigned ID = 0; 357de491f05SAlex Lorenz for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) { 358de491f05SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 359de491f05SAlex Lorenz continue; 360de491f05SAlex Lorenz 361de491f05SAlex Lorenz yaml::FixedMachineStackObject YamlObject; 3627feaf7c6SAlex Lorenz YamlObject.ID = ID; 363de491f05SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 364de491f05SAlex Lorenz ? yaml::FixedMachineStackObject::SpillSlot 365de491f05SAlex Lorenz : yaml::FixedMachineStackObject::DefaultType; 366de491f05SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 367de491f05SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 368de491f05SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 369de491f05SAlex Lorenz YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I); 370de491f05SAlex Lorenz YamlObject.IsAliased = MFI.isAliasedObjectIndex(I); 371ef331effSMatthias Braun YMF.FixedStackObjects.push_back(YamlObject); 3727feaf7c6SAlex Lorenz StackObjectOperandMapping.insert( 3737feaf7c6SAlex Lorenz std::make_pair(I, FrameIndexOperand::createFixed(ID++))); 374de491f05SAlex Lorenz } 375de491f05SAlex Lorenz 376de491f05SAlex Lorenz // Process ordinary stack objects. 377de491f05SAlex Lorenz ID = 0; 378f6bc8667SAlex Lorenz for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) { 379f6bc8667SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 380f6bc8667SAlex Lorenz continue; 381f6bc8667SAlex Lorenz 382f6bc8667SAlex Lorenz yaml::MachineStackObject YamlObject; 3837feaf7c6SAlex Lorenz YamlObject.ID = ID; 38437643a04SAlex Lorenz if (const auto *Alloca = MFI.getObjectAllocation(I)) 38537643a04SAlex Lorenz YamlObject.Name.Value = 38637643a04SAlex Lorenz Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>"; 387f6bc8667SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 388f6bc8667SAlex Lorenz ? yaml::MachineStackObject::SpillSlot 389418f3ec1SAlex Lorenz : MFI.isVariableSizedObjectIndex(I) 390418f3ec1SAlex Lorenz ? yaml::MachineStackObject::VariableSized 391f6bc8667SAlex Lorenz : yaml::MachineStackObject::DefaultType; 392f6bc8667SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 393f6bc8667SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 394f6bc8667SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 395f6bc8667SAlex Lorenz 396ef331effSMatthias Braun YMF.StackObjects.push_back(YamlObject); 3977feaf7c6SAlex Lorenz StackObjectOperandMapping.insert(std::make_pair( 3987feaf7c6SAlex Lorenz I, FrameIndexOperand::create(YamlObject.Name.Value, ID++))); 399f6bc8667SAlex Lorenz } 4001bb48de1SAlex Lorenz 4011bb48de1SAlex Lorenz for (const auto &CSInfo : MFI.getCalleeSavedInfo()) { 4021bb48de1SAlex Lorenz yaml::StringValue Reg; 4031bb48de1SAlex Lorenz printReg(CSInfo.getReg(), Reg, TRI); 4041bb48de1SAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx()); 4051bb48de1SAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 4061bb48de1SAlex Lorenz "Invalid stack object index"); 4071bb48de1SAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 4081bb48de1SAlex Lorenz if (StackObject.IsFixed) 409ef331effSMatthias Braun YMF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg; 4101bb48de1SAlex Lorenz else 411ef331effSMatthias Braun YMF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg; 4121bb48de1SAlex Lorenz } 413a56ba6a6SAlex Lorenz for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) { 414a56ba6a6SAlex Lorenz auto LocalObject = MFI.getLocalFrameObjectMap(I); 415a56ba6a6SAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(LocalObject.first); 416a56ba6a6SAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 417a56ba6a6SAlex Lorenz "Invalid stack object index"); 418a56ba6a6SAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 419a56ba6a6SAlex Lorenz assert(!StackObject.IsFixed && "Expected a locally mapped stack object"); 420ef331effSMatthias Braun YMF.StackObjects[StackObject.ID].LocalOffset = LocalObject.second; 421a56ba6a6SAlex Lorenz } 422a314d813SAlex Lorenz 423a314d813SAlex Lorenz // Print the stack object references in the frame information class after 424a314d813SAlex Lorenz // converting the stack objects. 425a314d813SAlex Lorenz if (MFI.hasStackProtectorIndex()) { 426ef331effSMatthias Braun raw_string_ostream StrOS(YMF.FrameInfo.StackProtector.Value); 427a314d813SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 428a314d813SAlex Lorenz .printStackObjectReference(MFI.getStackProtectorIndex()); 429a314d813SAlex Lorenz } 430df9e3c6fSAlex Lorenz 431df9e3c6fSAlex Lorenz // Print the debug variable information. 432ef331effSMatthias Braun for (const MachineFunction::VariableDbgInfo &DebugVar : 433ef331effSMatthias Braun MF.getVariableDbgInfo()) { 434df9e3c6fSAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(DebugVar.Slot); 435df9e3c6fSAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 436df9e3c6fSAlex Lorenz "Invalid stack object index"); 437df9e3c6fSAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 438df9e3c6fSAlex Lorenz assert(!StackObject.IsFixed && "Expected a non-fixed stack object"); 439ef331effSMatthias Braun auto &Object = YMF.StackObjects[StackObject.ID]; 440df9e3c6fSAlex Lorenz { 441df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugVar.Value); 442df9e3c6fSAlex Lorenz DebugVar.Var->printAsOperand(StrOS, MST); 443df9e3c6fSAlex Lorenz } 444df9e3c6fSAlex Lorenz { 445df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugExpr.Value); 446df9e3c6fSAlex Lorenz DebugVar.Expr->printAsOperand(StrOS, MST); 447df9e3c6fSAlex Lorenz } 448df9e3c6fSAlex Lorenz { 449df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugLoc.Value); 450df9e3c6fSAlex Lorenz DebugVar.Loc->printAsOperand(StrOS, MST); 451df9e3c6fSAlex Lorenz } 452df9e3c6fSAlex Lorenz } 453f6bc8667SAlex Lorenz } 454f6bc8667SAlex Lorenz 455ab980499SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 456ab980499SAlex Lorenz const MachineConstantPool &ConstantPool) { 457ab980499SAlex Lorenz unsigned ID = 0; 458ab980499SAlex Lorenz for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) { 459ab980499SAlex Lorenz // TODO: Serialize target specific constant pool entries. 460ab980499SAlex Lorenz if (Constant.isMachineConstantPoolEntry()) 461ab980499SAlex Lorenz llvm_unreachable("Can't print target specific constant pool entries yet"); 462ab980499SAlex Lorenz 463ab980499SAlex Lorenz yaml::MachineConstantPoolValue YamlConstant; 464ab980499SAlex Lorenz std::string Str; 465ab980499SAlex Lorenz raw_string_ostream StrOS(Str); 466ab980499SAlex Lorenz Constant.Val.ConstVal->printAsOperand(StrOS); 467ab980499SAlex Lorenz YamlConstant.ID = ID++; 468ab980499SAlex Lorenz YamlConstant.Value = StrOS.str(); 469ab980499SAlex Lorenz YamlConstant.Alignment = Constant.getAlignment(); 470ab980499SAlex Lorenz MF.Constants.push_back(YamlConstant); 471ab980499SAlex Lorenz } 472ab980499SAlex Lorenz } 473ab980499SAlex Lorenz 474900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 4756799e9b3SAlex Lorenz yaml::MachineJumpTable &YamlJTI, 4766799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI) { 4776799e9b3SAlex Lorenz YamlJTI.Kind = JTI.getEntryKind(); 4786799e9b3SAlex Lorenz unsigned ID = 0; 4796799e9b3SAlex Lorenz for (const auto &Table : JTI.getJumpTables()) { 4806799e9b3SAlex Lorenz std::string Str; 4816799e9b3SAlex Lorenz yaml::MachineJumpTable::Entry Entry; 4826799e9b3SAlex Lorenz Entry.ID = ID++; 4836799e9b3SAlex Lorenz for (const auto *MBB : Table.MBBs) { 4846799e9b3SAlex Lorenz raw_string_ostream StrOS(Str); 4857feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 4867feaf7c6SAlex Lorenz .printMBBReference(*MBB); 4876799e9b3SAlex Lorenz Entry.Blocks.push_back(StrOS.str()); 4886799e9b3SAlex Lorenz Str.clear(); 4896799e9b3SAlex Lorenz } 4906799e9b3SAlex Lorenz YamlJTI.Entries.push_back(Entry); 4916799e9b3SAlex Lorenz } 4926799e9b3SAlex Lorenz } 4936799e9b3SAlex Lorenz 4948f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) { 4958f6f4285SAlex Lorenz const auto *TRI = MF.getSubtarget().getRegisterInfo(); 4968f6f4285SAlex Lorenz unsigned I = 0; 4978f6f4285SAlex Lorenz for (const uint32_t *Mask : TRI->getRegMasks()) 4988f6f4285SAlex Lorenz RegisterMaskIds.insert(std::make_pair(Mask, I++)); 4998f6f4285SAlex Lorenz } 5008f6f4285SAlex Lorenz 5018940114fSMatthias Braun void llvm::guessSuccessors(const MachineBasicBlock &MBB, 5028940114fSMatthias Braun SmallVectorImpl<MachineBasicBlock*> &Result, 5038940114fSMatthias Braun bool &IsFallthrough) { 5048940114fSMatthias Braun SmallPtrSet<MachineBasicBlock*,8> Seen; 5058940114fSMatthias Braun 5068940114fSMatthias Braun for (const MachineInstr &MI : MBB) { 5078940114fSMatthias Braun if (MI.isPHI()) 5088940114fSMatthias Braun continue; 5098940114fSMatthias Braun for (const MachineOperand &MO : MI.operands()) { 5108940114fSMatthias Braun if (!MO.isMBB()) 5118940114fSMatthias Braun continue; 5128940114fSMatthias Braun MachineBasicBlock *Succ = MO.getMBB(); 5138940114fSMatthias Braun auto RP = Seen.insert(Succ); 5148940114fSMatthias Braun if (RP.second) 5158940114fSMatthias Braun Result.push_back(Succ); 5168940114fSMatthias Braun } 5178940114fSMatthias Braun } 5188940114fSMatthias Braun MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr(); 5198940114fSMatthias Braun IsFallthrough = I == MBB.end() || !I->isBarrier(); 5208940114fSMatthias Braun } 5218940114fSMatthias Braun 5228940114fSMatthias Braun bool 5238940114fSMatthias Braun MIPrinter::canPredictBranchProbabilities(const MachineBasicBlock &MBB) const { 5248940114fSMatthias Braun if (MBB.succ_size() <= 1) 5258940114fSMatthias Braun return true; 5268940114fSMatthias Braun if (!MBB.hasSuccessorProbabilities()) 5278940114fSMatthias Braun return true; 5288940114fSMatthias Braun 5298940114fSMatthias Braun SmallVector<BranchProbability,8> Normalized(MBB.Probs.begin(), 5308940114fSMatthias Braun MBB.Probs.end()); 5318940114fSMatthias Braun BranchProbability::normalizeProbabilities(Normalized.begin(), 5328940114fSMatthias Braun Normalized.end()); 5338940114fSMatthias Braun SmallVector<BranchProbability,8> Equal(Normalized.size()); 5348940114fSMatthias Braun BranchProbability::normalizeProbabilities(Equal.begin(), Equal.end()); 5358940114fSMatthias Braun 5368940114fSMatthias Braun return std::equal(Normalized.begin(), Normalized.end(), Equal.begin()); 5378940114fSMatthias Braun } 5388940114fSMatthias Braun 5398940114fSMatthias Braun bool MIPrinter::canPredictSuccessors(const MachineBasicBlock &MBB) const { 5408940114fSMatthias Braun SmallVector<MachineBasicBlock*,8> GuessedSuccs; 5418940114fSMatthias Braun bool GuessedFallthrough; 5428940114fSMatthias Braun guessSuccessors(MBB, GuessedSuccs, GuessedFallthrough); 5438940114fSMatthias Braun if (GuessedFallthrough) { 5448940114fSMatthias Braun const MachineFunction &MF = *MBB.getParent(); 5458940114fSMatthias Braun MachineFunction::const_iterator NextI = std::next(MBB.getIterator()); 5468940114fSMatthias Braun if (NextI != MF.end()) { 5478940114fSMatthias Braun MachineBasicBlock *Next = const_cast<MachineBasicBlock*>(&*NextI); 5488940114fSMatthias Braun if (!is_contained(GuessedSuccs, Next)) 5498940114fSMatthias Braun GuessedSuccs.push_back(Next); 5508940114fSMatthias Braun } 5518940114fSMatthias Braun } 5528940114fSMatthias Braun if (GuessedSuccs.size() != MBB.succ_size()) 5538940114fSMatthias Braun return false; 5548940114fSMatthias Braun return std::equal(MBB.succ_begin(), MBB.succ_end(), GuessedSuccs.begin()); 5558940114fSMatthias Braun } 5568940114fSMatthias Braun 5575022f6bbSAlex Lorenz void MIPrinter::print(const MachineBasicBlock &MBB) { 5585022f6bbSAlex Lorenz assert(MBB.getNumber() >= 0 && "Invalid MBB number"); 5595022f6bbSAlex Lorenz OS << "bb." << MBB.getNumber(); 5605022f6bbSAlex Lorenz bool HasAttributes = false; 5615022f6bbSAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 5625022f6bbSAlex Lorenz if (BB->hasName()) { 5635022f6bbSAlex Lorenz OS << "." << BB->getName(); 5645022f6bbSAlex Lorenz } else { 5655022f6bbSAlex Lorenz HasAttributes = true; 5665022f6bbSAlex Lorenz OS << " ("; 5675022f6bbSAlex Lorenz int Slot = MST.getLocalSlot(BB); 5685022f6bbSAlex Lorenz if (Slot == -1) 5695022f6bbSAlex Lorenz OS << "<ir-block badref>"; 5705022f6bbSAlex Lorenz else 5715022f6bbSAlex Lorenz OS << (Twine("%ir-block.") + Twine(Slot)).str(); 5725022f6bbSAlex Lorenz } 5735022f6bbSAlex Lorenz } 5745022f6bbSAlex Lorenz if (MBB.hasAddressTaken()) { 5755022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 5765022f6bbSAlex Lorenz OS << "address-taken"; 5775022f6bbSAlex Lorenz HasAttributes = true; 5785022f6bbSAlex Lorenz } 5790e288234SReid Kleckner if (MBB.isEHPad()) { 5805022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 5815022f6bbSAlex Lorenz OS << "landing-pad"; 5825022f6bbSAlex Lorenz HasAttributes = true; 5835022f6bbSAlex Lorenz } 5845022f6bbSAlex Lorenz if (MBB.getAlignment()) { 5855022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 5865022f6bbSAlex Lorenz OS << "align " << MBB.getAlignment(); 5875022f6bbSAlex Lorenz HasAttributes = true; 5885022f6bbSAlex Lorenz } 5895022f6bbSAlex Lorenz if (HasAttributes) 5905022f6bbSAlex Lorenz OS << ")"; 5915022f6bbSAlex Lorenz OS << ":\n"; 5925022f6bbSAlex Lorenz 5935022f6bbSAlex Lorenz bool HasLineAttributes = false; 5945022f6bbSAlex Lorenz // Print the successors 5958940114fSMatthias Braun bool canPredictProbs = canPredictBranchProbabilities(MBB); 5968940114fSMatthias Braun if (!MBB.succ_empty() && (!SimplifyMIR || !canPredictProbs || 5978940114fSMatthias Braun !canPredictSuccessors(MBB))) { 5985022f6bbSAlex Lorenz OS.indent(2) << "successors: "; 5995022f6bbSAlex Lorenz for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) { 6005022f6bbSAlex Lorenz if (I != MBB.succ_begin()) 6015022f6bbSAlex Lorenz OS << ", "; 6025022f6bbSAlex Lorenz printMBBReference(**I); 6038940114fSMatthias Braun if (!SimplifyMIR || !canPredictProbs) 604b51774acSGeoff Berry OS << '(' 605b51774acSGeoff Berry << format("0x%08" PRIx32, MBB.getSuccProbability(I).getNumerator()) 606b51774acSGeoff Berry << ')'; 6075022f6bbSAlex Lorenz } 6085022f6bbSAlex Lorenz OS << "\n"; 6095022f6bbSAlex Lorenz HasLineAttributes = true; 6105022f6bbSAlex Lorenz } 6115022f6bbSAlex Lorenz 6125022f6bbSAlex Lorenz // Print the live in registers. 61311723322SMatthias Braun const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 61411723322SMatthias Braun if (MRI.tracksLiveness() && !MBB.livein_empty()) { 61511723322SMatthias Braun const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); 6165022f6bbSAlex Lorenz OS.indent(2) << "liveins: "; 617b2b7ef1dSMatthias Braun bool First = true; 618d9da1627SMatthias Braun for (const auto &LI : MBB.liveins()) { 619b2b7ef1dSMatthias Braun if (!First) 6205022f6bbSAlex Lorenz OS << ", "; 621b2b7ef1dSMatthias Braun First = false; 62211723322SMatthias Braun printReg(LI.PhysReg, OS, &TRI); 62391b5cf84SKrzysztof Parzyszek if (!LI.LaneMask.all()) 624d62669d7SKrzysztof Parzyszek OS << ":0x" << PrintLaneMask(LI.LaneMask); 6255022f6bbSAlex Lorenz } 6265022f6bbSAlex Lorenz OS << "\n"; 6275022f6bbSAlex Lorenz HasLineAttributes = true; 6285022f6bbSAlex Lorenz } 6295022f6bbSAlex Lorenz 6305022f6bbSAlex Lorenz if (HasLineAttributes) 6315022f6bbSAlex Lorenz OS << "\n"; 632f9a2b123SAlex Lorenz bool IsInBundle = false; 633f9a2b123SAlex Lorenz for (auto I = MBB.instr_begin(), E = MBB.instr_end(); I != E; ++I) { 634f9a2b123SAlex Lorenz const MachineInstr &MI = *I; 635f9a2b123SAlex Lorenz if (IsInBundle && !MI.isInsideBundle()) { 636f9a2b123SAlex Lorenz OS.indent(2) << "}\n"; 637f9a2b123SAlex Lorenz IsInBundle = false; 638f9a2b123SAlex Lorenz } 639f9a2b123SAlex Lorenz OS.indent(IsInBundle ? 4 : 2); 6405022f6bbSAlex Lorenz print(MI); 641f9a2b123SAlex Lorenz if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) { 642f9a2b123SAlex Lorenz OS << " {"; 643f9a2b123SAlex Lorenz IsInBundle = true; 644f9a2b123SAlex Lorenz } 6455022f6bbSAlex Lorenz OS << "\n"; 6465022f6bbSAlex Lorenz } 647f9a2b123SAlex Lorenz if (IsInBundle) 648f9a2b123SAlex Lorenz OS.indent(2) << "}\n"; 6495022f6bbSAlex Lorenz } 6505022f6bbSAlex Lorenz 6515ef93b0cSAlex Lorenz /// Return true when an instruction has tied register that can't be determined 6525ef93b0cSAlex Lorenz /// by the instruction's descriptor. 6535ef93b0cSAlex Lorenz static bool hasComplexRegisterTies(const MachineInstr &MI) { 6545ef93b0cSAlex Lorenz const MCInstrDesc &MCID = MI.getDesc(); 6555ef93b0cSAlex Lorenz for (unsigned I = 0, E = MI.getNumOperands(); I < E; ++I) { 6565ef93b0cSAlex Lorenz const auto &Operand = MI.getOperand(I); 6575ef93b0cSAlex Lorenz if (!Operand.isReg() || Operand.isDef()) 6585ef93b0cSAlex Lorenz // Ignore the defined registers as MCID marks only the uses as tied. 6595ef93b0cSAlex Lorenz continue; 6605ef93b0cSAlex Lorenz int ExpectedTiedIdx = MCID.getOperandConstraint(I, MCOI::TIED_TO); 6615ef93b0cSAlex Lorenz int TiedIdx = Operand.isTied() ? int(MI.findTiedOperandIdx(I)) : -1; 6625ef93b0cSAlex Lorenz if (ExpectedTiedIdx != TiedIdx) 6635ef93b0cSAlex Lorenz return true; 6645ef93b0cSAlex Lorenz } 6655ef93b0cSAlex Lorenz return false; 6665ef93b0cSAlex Lorenz } 6675ef93b0cSAlex Lorenz 668d28d3cc0STim Northover static LLT getTypeToPrint(const MachineInstr &MI, unsigned OpIdx, 669d28d3cc0STim Northover SmallBitVector &PrintedTypes, 670d28d3cc0STim Northover const MachineRegisterInfo &MRI) { 671d28d3cc0STim Northover const MachineOperand &Op = MI.getOperand(OpIdx); 672d28d3cc0STim Northover if (!Op.isReg()) 673d28d3cc0STim Northover return LLT{}; 674d28d3cc0STim Northover 675d28d3cc0STim Northover if (MI.isVariadic() || OpIdx >= MI.getNumExplicitOperands()) 676d28d3cc0STim Northover return MRI.getType(Op.getReg()); 677d28d3cc0STim Northover 678d28d3cc0STim Northover auto &OpInfo = MI.getDesc().OpInfo[OpIdx]; 679d28d3cc0STim Northover if (!OpInfo.isGenericType()) 680d28d3cc0STim Northover return MRI.getType(Op.getReg()); 681d28d3cc0STim Northover 682d28d3cc0STim Northover if (PrintedTypes[OpInfo.getGenericTypeIndex()]) 683d28d3cc0STim Northover return LLT{}; 684d28d3cc0STim Northover 685d28d3cc0STim Northover PrintedTypes.set(OpInfo.getGenericTypeIndex()); 686d28d3cc0STim Northover return MRI.getType(Op.getReg()); 687d28d3cc0STim Northover } 688d28d3cc0STim Northover 6898e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) { 6904e14a497SQuentin Colombet const auto *MF = MI.getParent()->getParent(); 6914e14a497SQuentin Colombet const auto &MRI = MF->getRegInfo(); 6924e14a497SQuentin Colombet const auto &SubTarget = MF->getSubtarget(); 693f3db51deSAlex Lorenz const auto *TRI = SubTarget.getRegisterInfo(); 694f3db51deSAlex Lorenz assert(TRI && "Expected target register info"); 6958e0a1b48SAlex Lorenz const auto *TII = SubTarget.getInstrInfo(); 6968e0a1b48SAlex Lorenz assert(TII && "Expected target instruction info"); 697f4baeb51SAlex Lorenz if (MI.isCFIInstruction()) 698f4baeb51SAlex Lorenz assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction"); 6998e0a1b48SAlex Lorenz 700d28d3cc0STim Northover SmallBitVector PrintedTypes(8); 7015ef93b0cSAlex Lorenz bool ShouldPrintRegisterTies = hasComplexRegisterTies(MI); 702f3db51deSAlex Lorenz unsigned I = 0, E = MI.getNumOperands(); 703f3db51deSAlex Lorenz for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() && 704f3db51deSAlex Lorenz !MI.getOperand(I).isImplicit(); 705f3db51deSAlex Lorenz ++I) { 706f3db51deSAlex Lorenz if (I) 707f3db51deSAlex Lorenz OS << ", "; 708d28d3cc0STim Northover print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies, 709d28d3cc0STim Northover getTypeToPrint(MI, I, PrintedTypes, MRI), 7104e14a497SQuentin Colombet /*IsDef=*/true); 711f3db51deSAlex Lorenz } 712f3db51deSAlex Lorenz 713f3db51deSAlex Lorenz if (I) 714f3db51deSAlex Lorenz OS << " = "; 715e5a44660SAlex Lorenz if (MI.getFlag(MachineInstr::FrameSetup)) 716e5a44660SAlex Lorenz OS << "frame-setup "; 7178e0a1b48SAlex Lorenz OS << TII->getName(MI.getOpcode()); 718f3db51deSAlex Lorenz if (I < E) 719f3db51deSAlex Lorenz OS << ' '; 720f3db51deSAlex Lorenz 721f3db51deSAlex Lorenz bool NeedComma = false; 722f3db51deSAlex Lorenz for (; I < E; ++I) { 723f3db51deSAlex Lorenz if (NeedComma) 724f3db51deSAlex Lorenz OS << ", "; 725d28d3cc0STim Northover print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies, 726d28d3cc0STim Northover getTypeToPrint(MI, I, PrintedTypes, MRI)); 727f3db51deSAlex Lorenz NeedComma = true; 728f3db51deSAlex Lorenz } 72946d760d1SAlex Lorenz 73046d760d1SAlex Lorenz if (MI.getDebugLoc()) { 73146d760d1SAlex Lorenz if (NeedComma) 73246d760d1SAlex Lorenz OS << ','; 73346d760d1SAlex Lorenz OS << " debug-location "; 73446d760d1SAlex Lorenz MI.getDebugLoc()->printAsOperand(OS, MST); 73546d760d1SAlex Lorenz } 7364af7e610SAlex Lorenz 7374af7e610SAlex Lorenz if (!MI.memoperands_empty()) { 7384af7e610SAlex Lorenz OS << " :: "; 739bb80d3e1SKonstantin Zhuravlyov const LLVMContext &Context = MF->getFunction()->getContext(); 7404af7e610SAlex Lorenz bool NeedComma = false; 7414af7e610SAlex Lorenz for (const auto *Op : MI.memoperands()) { 7424af7e610SAlex Lorenz if (NeedComma) 7434af7e610SAlex Lorenz OS << ", "; 744*6748abe2SGeoff Berry print(Context, *TII, *Op); 7454af7e610SAlex Lorenz NeedComma = true; 7464af7e610SAlex Lorenz } 7474af7e610SAlex Lorenz } 748f3db51deSAlex Lorenz } 749f3db51deSAlex Lorenz 7505d26fa83SAlex Lorenz void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) { 7515d26fa83SAlex Lorenz OS << "%bb." << MBB.getNumber(); 7525d26fa83SAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 7535d26fa83SAlex Lorenz if (BB->hasName()) 7545d26fa83SAlex Lorenz OS << '.' << BB->getName(); 7555d26fa83SAlex Lorenz } 7565d26fa83SAlex Lorenz } 7575d26fa83SAlex Lorenz 75855dc6f81SAlex Lorenz static void printIRSlotNumber(raw_ostream &OS, int Slot) { 75955dc6f81SAlex Lorenz if (Slot == -1) 76055dc6f81SAlex Lorenz OS << "<badref>"; 76155dc6f81SAlex Lorenz else 76255dc6f81SAlex Lorenz OS << Slot; 76355dc6f81SAlex Lorenz } 76455dc6f81SAlex Lorenz 765deb53490SAlex Lorenz void MIPrinter::printIRBlockReference(const BasicBlock &BB) { 766deb53490SAlex Lorenz OS << "%ir-block."; 767deb53490SAlex Lorenz if (BB.hasName()) { 768deb53490SAlex Lorenz printLLVMNameWithoutPrefix(OS, BB.getName()); 769deb53490SAlex Lorenz return; 770deb53490SAlex Lorenz } 771cba8c5feSAlex Lorenz const Function *F = BB.getParent(); 772cba8c5feSAlex Lorenz int Slot; 773cba8c5feSAlex Lorenz if (F == MST.getCurrentFunction()) { 774cba8c5feSAlex Lorenz Slot = MST.getLocalSlot(&BB); 775cba8c5feSAlex Lorenz } else { 776cba8c5feSAlex Lorenz ModuleSlotTracker CustomMST(F->getParent(), 777cba8c5feSAlex Lorenz /*ShouldInitializeAllMetadata=*/false); 778cba8c5feSAlex Lorenz CustomMST.incorporateFunction(*F); 779cba8c5feSAlex Lorenz Slot = CustomMST.getLocalSlot(&BB); 780cba8c5feSAlex Lorenz } 78155dc6f81SAlex Lorenz printIRSlotNumber(OS, Slot); 782deb53490SAlex Lorenz } 783deb53490SAlex Lorenz 7844af7e610SAlex Lorenz void MIPrinter::printIRValueReference(const Value &V) { 78536efd388SAlex Lorenz if (isa<GlobalValue>(V)) { 78636efd388SAlex Lorenz V.printAsOperand(OS, /*PrintType=*/false, MST); 78736efd388SAlex Lorenz return; 78836efd388SAlex Lorenz } 789c1136ef3SAlex Lorenz if (isa<Constant>(V)) { 790c1136ef3SAlex Lorenz // Machine memory operands can load/store to/from constant value pointers. 791c1136ef3SAlex Lorenz OS << '`'; 792c1136ef3SAlex Lorenz V.printAsOperand(OS, /*PrintType=*/true, MST); 793c1136ef3SAlex Lorenz OS << '`'; 794c1136ef3SAlex Lorenz return; 795c1136ef3SAlex Lorenz } 7964af7e610SAlex Lorenz OS << "%ir."; 7974af7e610SAlex Lorenz if (V.hasName()) { 7984af7e610SAlex Lorenz printLLVMNameWithoutPrefix(OS, V.getName()); 7994af7e610SAlex Lorenz return; 8004af7e610SAlex Lorenz } 801dd13be0bSAlex Lorenz printIRSlotNumber(OS, MST.getLocalSlot(&V)); 8024af7e610SAlex Lorenz } 8034af7e610SAlex Lorenz 8047feaf7c6SAlex Lorenz void MIPrinter::printStackObjectReference(int FrameIndex) { 8057feaf7c6SAlex Lorenz auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex); 8067feaf7c6SAlex Lorenz assert(ObjectInfo != StackObjectOperandMapping.end() && 8077feaf7c6SAlex Lorenz "Invalid frame index"); 8087feaf7c6SAlex Lorenz const FrameIndexOperand &Operand = ObjectInfo->second; 8097feaf7c6SAlex Lorenz if (Operand.IsFixed) { 8107feaf7c6SAlex Lorenz OS << "%fixed-stack." << Operand.ID; 8117feaf7c6SAlex Lorenz return; 8127feaf7c6SAlex Lorenz } 8137feaf7c6SAlex Lorenz OS << "%stack." << Operand.ID; 8147feaf7c6SAlex Lorenz if (!Operand.Name.empty()) 8157feaf7c6SAlex Lorenz OS << '.' << Operand.Name; 8167feaf7c6SAlex Lorenz } 8177feaf7c6SAlex Lorenz 8185672a893SAlex Lorenz void MIPrinter::printOffset(int64_t Offset) { 8195672a893SAlex Lorenz if (Offset == 0) 8205672a893SAlex Lorenz return; 8215672a893SAlex Lorenz if (Offset < 0) { 8225672a893SAlex Lorenz OS << " - " << -Offset; 8235672a893SAlex Lorenz return; 8245672a893SAlex Lorenz } 8255672a893SAlex Lorenz OS << " + " << Offset; 8265672a893SAlex Lorenz } 8275672a893SAlex Lorenz 82849873a83SAlex Lorenz static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) { 82949873a83SAlex Lorenz auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); 83049873a83SAlex Lorenz for (const auto &I : Flags) { 83149873a83SAlex Lorenz if (I.first == TF) { 83249873a83SAlex Lorenz return I.second; 83349873a83SAlex Lorenz } 83449873a83SAlex Lorenz } 83549873a83SAlex Lorenz return nullptr; 83649873a83SAlex Lorenz } 83749873a83SAlex Lorenz 83849873a83SAlex Lorenz void MIPrinter::printTargetFlags(const MachineOperand &Op) { 83949873a83SAlex Lorenz if (!Op.getTargetFlags()) 84049873a83SAlex Lorenz return; 84149873a83SAlex Lorenz const auto *TII = 84249873a83SAlex Lorenz Op.getParent()->getParent()->getParent()->getSubtarget().getInstrInfo(); 84349873a83SAlex Lorenz assert(TII && "expected instruction info"); 84449873a83SAlex Lorenz auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags()); 84549873a83SAlex Lorenz OS << "target-flags("; 846f3630113SAlex Lorenz const bool HasDirectFlags = Flags.first; 847f3630113SAlex Lorenz const bool HasBitmaskFlags = Flags.second; 848f3630113SAlex Lorenz if (!HasDirectFlags && !HasBitmaskFlags) { 849f3630113SAlex Lorenz OS << "<unknown>) "; 850f3630113SAlex Lorenz return; 851f3630113SAlex Lorenz } 852f3630113SAlex Lorenz if (HasDirectFlags) { 85349873a83SAlex Lorenz if (const auto *Name = getTargetFlagName(TII, Flags.first)) 85449873a83SAlex Lorenz OS << Name; 85549873a83SAlex Lorenz else 85649873a83SAlex Lorenz OS << "<unknown target flag>"; 857f3630113SAlex Lorenz } 858f3630113SAlex Lorenz if (!HasBitmaskFlags) { 859f3630113SAlex Lorenz OS << ") "; 860f3630113SAlex Lorenz return; 861f3630113SAlex Lorenz } 862f3630113SAlex Lorenz bool IsCommaNeeded = HasDirectFlags; 863f3630113SAlex Lorenz unsigned BitMask = Flags.second; 864f3630113SAlex Lorenz auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags(); 865f3630113SAlex Lorenz for (const auto &Mask : BitMasks) { 866f3630113SAlex Lorenz // Check if the flag's bitmask has the bits of the current mask set. 867f3630113SAlex Lorenz if ((BitMask & Mask.first) == Mask.first) { 868f3630113SAlex Lorenz if (IsCommaNeeded) 869f3630113SAlex Lorenz OS << ", "; 870f3630113SAlex Lorenz IsCommaNeeded = true; 871f3630113SAlex Lorenz OS << Mask.second; 872f3630113SAlex Lorenz // Clear the bits which were serialized from the flag's bitmask. 873f3630113SAlex Lorenz BitMask &= ~(Mask.first); 874f3630113SAlex Lorenz } 875f3630113SAlex Lorenz } 876f3630113SAlex Lorenz if (BitMask) { 877f3630113SAlex Lorenz // When the resulting flag's bitmask isn't zero, we know that we didn't 878f3630113SAlex Lorenz // serialize all of the bit flags. 879f3630113SAlex Lorenz if (IsCommaNeeded) 880f3630113SAlex Lorenz OS << ", "; 881f3630113SAlex Lorenz OS << "<unknown bitmask target flag>"; 882f3630113SAlex Lorenz } 88349873a83SAlex Lorenz OS << ") "; 88449873a83SAlex Lorenz } 88549873a83SAlex Lorenz 886ef5c196fSAlex Lorenz static const char *getTargetIndexName(const MachineFunction &MF, int Index) { 887ef5c196fSAlex Lorenz const auto *TII = MF.getSubtarget().getInstrInfo(); 888ef5c196fSAlex Lorenz assert(TII && "expected instruction info"); 889ef5c196fSAlex Lorenz auto Indices = TII->getSerializableTargetIndices(); 890ef5c196fSAlex Lorenz for (const auto &I : Indices) { 891ef5c196fSAlex Lorenz if (I.first == Index) { 892ef5c196fSAlex Lorenz return I.second; 893ef5c196fSAlex Lorenz } 894ef5c196fSAlex Lorenz } 895ef5c196fSAlex Lorenz return nullptr; 896ef5c196fSAlex Lorenz } 897ef5c196fSAlex Lorenz 898e66a7ccfSAlex Lorenz void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI, 899d28d3cc0STim Northover unsigned I, bool ShouldPrintRegisterTies, LLT TypeToPrint, 900d28d3cc0STim Northover bool IsDef) { 90149873a83SAlex Lorenz printTargetFlags(Op); 902f3db51deSAlex Lorenz switch (Op.getType()) { 903f3db51deSAlex Lorenz case MachineOperand::MO_Register: 904cb268d46SAlex Lorenz if (Op.isImplicit()) 905cb268d46SAlex Lorenz OS << (Op.isDef() ? "implicit-def " : "implicit "); 906e66a7ccfSAlex Lorenz else if (!IsDef && Op.isDef()) 907e66a7ccfSAlex Lorenz // Print the 'def' flag only when the operand is defined after '='. 908e66a7ccfSAlex Lorenz OS << "def "; 9091039fd1aSAlex Lorenz if (Op.isInternalRead()) 9101039fd1aSAlex Lorenz OS << "internal "; 911cbbfd0b1SAlex Lorenz if (Op.isDead()) 912cbbfd0b1SAlex Lorenz OS << "dead "; 913495ad879SAlex Lorenz if (Op.isKill()) 914495ad879SAlex Lorenz OS << "killed "; 9154d026b89SAlex Lorenz if (Op.isUndef()) 9164d026b89SAlex Lorenz OS << "undef "; 91701c1a5eeSAlex Lorenz if (Op.isEarlyClobber()) 91801c1a5eeSAlex Lorenz OS << "early-clobber "; 9199075258bSAlex Lorenz if (Op.isDebug()) 9209075258bSAlex Lorenz OS << "debug-use "; 921f3db51deSAlex Lorenz printReg(Op.getReg(), OS, TRI); 9222eacca86SAlex Lorenz // Print the sub register. 9232eacca86SAlex Lorenz if (Op.getSubReg() != 0) 924333e468dSMatthias Braun OS << '.' << TRI->getSubRegIndexName(Op.getSubReg()); 9255ef93b0cSAlex Lorenz if (ShouldPrintRegisterTies && Op.isTied() && !Op.isDef()) 9265ef93b0cSAlex Lorenz OS << "(tied-def " << Op.getParent()->findTiedOperandIdx(I) << ")"; 927d28d3cc0STim Northover if (TypeToPrint.isValid()) 928d28d3cc0STim Northover OS << '(' << TypeToPrint << ')'; 929f3db51deSAlex Lorenz break; 930240fc1e0SAlex Lorenz case MachineOperand::MO_Immediate: 931240fc1e0SAlex Lorenz OS << Op.getImm(); 932240fc1e0SAlex Lorenz break; 93305e3882eSAlex Lorenz case MachineOperand::MO_CImmediate: 93405e3882eSAlex Lorenz Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); 93505e3882eSAlex Lorenz break; 936ad156fb6SAlex Lorenz case MachineOperand::MO_FPImmediate: 937ad156fb6SAlex Lorenz Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); 938ad156fb6SAlex Lorenz break; 93933f0aef3SAlex Lorenz case MachineOperand::MO_MachineBasicBlock: 9405d26fa83SAlex Lorenz printMBBReference(*Op.getMBB()); 94133f0aef3SAlex Lorenz break; 9427feaf7c6SAlex Lorenz case MachineOperand::MO_FrameIndex: 9437feaf7c6SAlex Lorenz printStackObjectReference(Op.getIndex()); 9447feaf7c6SAlex Lorenz break; 945ab980499SAlex Lorenz case MachineOperand::MO_ConstantPoolIndex: 946ab980499SAlex Lorenz OS << "%const." << Op.getIndex(); 9475672a893SAlex Lorenz printOffset(Op.getOffset()); 948ab980499SAlex Lorenz break; 949fb69e66cSEugene Zelenko case MachineOperand::MO_TargetIndex: 950ef5c196fSAlex Lorenz OS << "target-index("; 951ef5c196fSAlex Lorenz if (const auto *Name = getTargetIndexName( 952ef5c196fSAlex Lorenz *Op.getParent()->getParent()->getParent(), Op.getIndex())) 953ef5c196fSAlex Lorenz OS << Name; 954ef5c196fSAlex Lorenz else 955ef5c196fSAlex Lorenz OS << "<unknown>"; 956ef5c196fSAlex Lorenz OS << ')'; 9575672a893SAlex Lorenz printOffset(Op.getOffset()); 958ef5c196fSAlex Lorenz break; 95931d70683SAlex Lorenz case MachineOperand::MO_JumpTableIndex: 96031d70683SAlex Lorenz OS << "%jump-table." << Op.getIndex(); 96131d70683SAlex Lorenz break; 9628b5f9e44SMatthias Braun case MachineOperand::MO_ExternalSymbol: { 9638b5f9e44SMatthias Braun StringRef Name = Op.getSymbolName(); 9646ede3744SAlex Lorenz OS << '$'; 9658b5f9e44SMatthias Braun if (Name.empty()) { 9668b5f9e44SMatthias Braun OS << "\"\""; 9678b5f9e44SMatthias Braun } else { 9688b5f9e44SMatthias Braun printLLVMNameWithoutPrefix(OS, Name); 9698b5f9e44SMatthias Braun } 9705672a893SAlex Lorenz printOffset(Op.getOffset()); 9716ede3744SAlex Lorenz break; 9728b5f9e44SMatthias Braun } 9735d6108e4SAlex Lorenz case MachineOperand::MO_GlobalAddress: 974900b5cb2SAlex Lorenz Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 9755672a893SAlex Lorenz printOffset(Op.getOffset()); 9765d6108e4SAlex Lorenz break; 977deb53490SAlex Lorenz case MachineOperand::MO_BlockAddress: 978deb53490SAlex Lorenz OS << "blockaddress("; 979deb53490SAlex Lorenz Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, 980deb53490SAlex Lorenz MST); 981deb53490SAlex Lorenz OS << ", "; 982deb53490SAlex Lorenz printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); 983deb53490SAlex Lorenz OS << ')'; 9845672a893SAlex Lorenz printOffset(Op.getOffset()); 985deb53490SAlex Lorenz break; 9868f6f4285SAlex Lorenz case MachineOperand::MO_RegisterMask: { 9878f6f4285SAlex Lorenz auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); 9888f6f4285SAlex Lorenz if (RegMaskInfo != RegisterMaskIds.end()) 9898f6f4285SAlex Lorenz OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); 9908f6f4285SAlex Lorenz else 9910ef61ec3SOren Ben Simhon printCustomRegMask(Op.getRegMask(), OS, TRI); 9928f6f4285SAlex Lorenz break; 9938f6f4285SAlex Lorenz } 994b97c9ef4SAlex Lorenz case MachineOperand::MO_RegisterLiveOut: { 995b97c9ef4SAlex Lorenz const uint32_t *RegMask = Op.getRegLiveOut(); 996b97c9ef4SAlex Lorenz OS << "liveout("; 997b97c9ef4SAlex Lorenz bool IsCommaNeeded = false; 998b97c9ef4SAlex Lorenz for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { 999b97c9ef4SAlex Lorenz if (RegMask[Reg / 32] & (1U << (Reg % 32))) { 1000b97c9ef4SAlex Lorenz if (IsCommaNeeded) 1001b97c9ef4SAlex Lorenz OS << ", "; 1002b97c9ef4SAlex Lorenz printReg(Reg, OS, TRI); 1003b97c9ef4SAlex Lorenz IsCommaNeeded = true; 1004b97c9ef4SAlex Lorenz } 1005b97c9ef4SAlex Lorenz } 1006b97c9ef4SAlex Lorenz OS << ")"; 1007b97c9ef4SAlex Lorenz break; 1008b97c9ef4SAlex Lorenz } 100935e44469SAlex Lorenz case MachineOperand::MO_Metadata: 101035e44469SAlex Lorenz Op.getMetadata()->printAsOperand(OS, MST); 101135e44469SAlex Lorenz break; 1012f22ca8adSAlex Lorenz case MachineOperand::MO_MCSymbol: 1013f22ca8adSAlex Lorenz OS << "<mcsymbol " << *Op.getMCSymbol() << ">"; 1014f22ca8adSAlex Lorenz break; 1015f4baeb51SAlex Lorenz case MachineOperand::MO_CFIIndex: { 1016f23ef437SMatthias Braun const MachineFunction &MF = *Op.getParent()->getParent()->getParent(); 1017f23ef437SMatthias Braun print(MF.getFrameInstructions()[Op.getCFIIndex()], TRI); 1018f4baeb51SAlex Lorenz break; 1019f4baeb51SAlex Lorenz } 10206b3bd612STim Northover case MachineOperand::MO_IntrinsicID: { 10216b3bd612STim Northover Intrinsic::ID ID = Op.getIntrinsicID(); 10226b3bd612STim Northover if (ID < Intrinsic::num_intrinsics) 10231523925dSPete Cooper OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')'; 10246b3bd612STim Northover else { 10256b3bd612STim Northover const MachineFunction &MF = *Op.getParent()->getParent()->getParent(); 10266b3bd612STim Northover const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo(); 10276b3bd612STim Northover OS << "intrinsic(@" << TII->getName(ID) << ')'; 10286b3bd612STim Northover } 10296b3bd612STim Northover break; 10306b3bd612STim Northover } 1031de3aea04STim Northover case MachineOperand::MO_Predicate: { 1032de3aea04STim Northover auto Pred = static_cast<CmpInst::Predicate>(Op.getPredicate()); 1033de3aea04STim Northover OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred(" 1034de3aea04STim Northover << CmpInst::getPredicateName(Pred) << ')'; 1035de3aea04STim Northover break; 1036de3aea04STim Northover } 1037f3db51deSAlex Lorenz } 10384f093bf1SAlex Lorenz } 10394f093bf1SAlex Lorenz 1040*6748abe2SGeoff Berry static const char *getTargetMMOFlagName(const TargetInstrInfo &TII, 1041*6748abe2SGeoff Berry unsigned TMMOFlag) { 1042*6748abe2SGeoff Berry auto Flags = TII.getSerializableMachineMemOperandTargetFlags(); 1043*6748abe2SGeoff Berry for (const auto &I : Flags) { 1044*6748abe2SGeoff Berry if (I.first == TMMOFlag) { 1045*6748abe2SGeoff Berry return I.second; 1046*6748abe2SGeoff Berry } 1047*6748abe2SGeoff Berry } 1048*6748abe2SGeoff Berry return nullptr; 1049*6748abe2SGeoff Berry } 1050*6748abe2SGeoff Berry 1051*6748abe2SGeoff Berry void MIPrinter::print(const LLVMContext &Context, const TargetInstrInfo &TII, 1052*6748abe2SGeoff Berry const MachineMemOperand &Op) { 10534af7e610SAlex Lorenz OS << '('; 1054a518b796SAlex Lorenz if (Op.isVolatile()) 1055a518b796SAlex Lorenz OS << "volatile "; 105610fd0385SAlex Lorenz if (Op.isNonTemporal()) 105710fd0385SAlex Lorenz OS << "non-temporal "; 1058adbf09e8SJustin Lebar if (Op.isDereferenceable()) 1059adbf09e8SJustin Lebar OS << "dereferenceable "; 1060dc8de2a6SAlex Lorenz if (Op.isInvariant()) 1061dc8de2a6SAlex Lorenz OS << "invariant "; 1062*6748abe2SGeoff Berry if (Op.getFlags() & MachineMemOperand::MOTargetFlag1) 1063*6748abe2SGeoff Berry OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag1) 1064*6748abe2SGeoff Berry << "\" "; 1065*6748abe2SGeoff Berry if (Op.getFlags() & MachineMemOperand::MOTargetFlag2) 1066*6748abe2SGeoff Berry OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag2) 1067*6748abe2SGeoff Berry << "\" "; 1068*6748abe2SGeoff Berry if (Op.getFlags() & MachineMemOperand::MOTargetFlag3) 1069*6748abe2SGeoff Berry OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag3) 1070*6748abe2SGeoff Berry << "\" "; 10714af7e610SAlex Lorenz if (Op.isLoad()) 10724af7e610SAlex Lorenz OS << "load "; 10734af7e610SAlex Lorenz else { 10744af7e610SAlex Lorenz assert(Op.isStore() && "Non load machine operand must be a store"); 10754af7e610SAlex Lorenz OS << "store "; 10764af7e610SAlex Lorenz } 1077b73e3090STim Northover 1078bb80d3e1SKonstantin Zhuravlyov printSyncScope(Context, Op.getSyncScopeID()); 1079b73e3090STim Northover 1080b73e3090STim Northover if (Op.getOrdering() != AtomicOrdering::NotAtomic) 1081b73e3090STim Northover OS << toIRString(Op.getOrdering()) << ' '; 1082b73e3090STim Northover if (Op.getFailureOrdering() != AtomicOrdering::NotAtomic) 1083b73e3090STim Northover OS << toIRString(Op.getFailureOrdering()) << ' '; 1084b73e3090STim Northover 1085c25c9ccbSMatthias Braun OS << Op.getSize(); 108691097a3fSAlex Lorenz if (const Value *Val = Op.getValue()) { 1087c25c9ccbSMatthias Braun OS << (Op.isLoad() ? " from " : " into "); 10884af7e610SAlex Lorenz printIRValueReference(*Val); 1089c25c9ccbSMatthias Braun } else if (const PseudoSourceValue *PVal = Op.getPseudoValue()) { 1090c25c9ccbSMatthias Braun OS << (Op.isLoad() ? " from " : " into "); 109191097a3fSAlex Lorenz assert(PVal && "Expected a pseudo source value"); 109291097a3fSAlex Lorenz switch (PVal->kind()) { 109346e9558aSAlex Lorenz case PseudoSourceValue::Stack: 109446e9558aSAlex Lorenz OS << "stack"; 109546e9558aSAlex Lorenz break; 1096d858f874SAlex Lorenz case PseudoSourceValue::GOT: 1097d858f874SAlex Lorenz OS << "got"; 1098d858f874SAlex Lorenz break; 10994be56e93SAlex Lorenz case PseudoSourceValue::JumpTable: 11004be56e93SAlex Lorenz OS << "jump-table"; 11014be56e93SAlex Lorenz break; 110291097a3fSAlex Lorenz case PseudoSourceValue::ConstantPool: 110391097a3fSAlex Lorenz OS << "constant-pool"; 110491097a3fSAlex Lorenz break; 11050cc671bfSAlex Lorenz case PseudoSourceValue::FixedStack: 11060cc671bfSAlex Lorenz printStackObjectReference( 11070cc671bfSAlex Lorenz cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex()); 11080cc671bfSAlex Lorenz break; 110950b826fbSAlex Lorenz case PseudoSourceValue::GlobalValueCallEntry: 11100d009645SAlex Lorenz OS << "call-entry "; 111150b826fbSAlex Lorenz cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand( 111250b826fbSAlex Lorenz OS, /*PrintType=*/false, MST); 111350b826fbSAlex Lorenz break; 1114c3ba7508SAlex Lorenz case PseudoSourceValue::ExternalSymbolCallEntry: 11150d009645SAlex Lorenz OS << "call-entry $"; 1116c3ba7508SAlex Lorenz printLLVMNameWithoutPrefix( 1117c3ba7508SAlex Lorenz OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol()); 111891097a3fSAlex Lorenz break; 11197761abb6STom Stellard case PseudoSourceValue::TargetCustom: 11207761abb6STom Stellard llvm_unreachable("TargetCustom pseudo source values are not supported"); 11217761abb6STom Stellard break; 112291097a3fSAlex Lorenz } 112391097a3fSAlex Lorenz } 112483127739SAlex Lorenz printOffset(Op.getOffset()); 112561420f79SAlex Lorenz if (Op.getBaseAlignment() != Op.getSize()) 112661420f79SAlex Lorenz OS << ", align " << Op.getBaseAlignment(); 1127a617c916SAlex Lorenz auto AAInfo = Op.getAAInfo(); 1128a617c916SAlex Lorenz if (AAInfo.TBAA) { 1129a617c916SAlex Lorenz OS << ", !tbaa "; 1130a617c916SAlex Lorenz AAInfo.TBAA->printAsOperand(OS, MST); 1131a617c916SAlex Lorenz } 1132a16f624dSAlex Lorenz if (AAInfo.Scope) { 1133a16f624dSAlex Lorenz OS << ", !alias.scope "; 1134a16f624dSAlex Lorenz AAInfo.Scope->printAsOperand(OS, MST); 1135a16f624dSAlex Lorenz } 113603e940d1SAlex Lorenz if (AAInfo.NoAlias) { 113703e940d1SAlex Lorenz OS << ", !noalias "; 113803e940d1SAlex Lorenz AAInfo.NoAlias->printAsOperand(OS, MST); 113903e940d1SAlex Lorenz } 1140eb625686SAlex Lorenz if (Op.getRanges()) { 1141eb625686SAlex Lorenz OS << ", !range "; 1142eb625686SAlex Lorenz Op.getRanges()->printAsOperand(OS, MST); 1143eb625686SAlex Lorenz } 11444af7e610SAlex Lorenz OS << ')'; 11454af7e610SAlex Lorenz } 11464af7e610SAlex Lorenz 1147bb80d3e1SKonstantin Zhuravlyov void MIPrinter::printSyncScope(const LLVMContext &Context, SyncScope::ID SSID) { 1148bb80d3e1SKonstantin Zhuravlyov switch (SSID) { 1149bb80d3e1SKonstantin Zhuravlyov case SyncScope::System: { 1150bb80d3e1SKonstantin Zhuravlyov break; 1151bb80d3e1SKonstantin Zhuravlyov } 1152bb80d3e1SKonstantin Zhuravlyov default: { 1153bb80d3e1SKonstantin Zhuravlyov if (SSNs.empty()) 1154bb80d3e1SKonstantin Zhuravlyov Context.getSyncScopeNames(SSNs); 1155bb80d3e1SKonstantin Zhuravlyov 1156bb80d3e1SKonstantin Zhuravlyov OS << "syncscope(\""; 1157bb80d3e1SKonstantin Zhuravlyov PrintEscapedString(SSNs[SSID], OS); 1158bb80d3e1SKonstantin Zhuravlyov OS << "\") "; 1159bb80d3e1SKonstantin Zhuravlyov break; 1160bb80d3e1SKonstantin Zhuravlyov } 1161bb80d3e1SKonstantin Zhuravlyov } 1162bb80d3e1SKonstantin Zhuravlyov } 1163bb80d3e1SKonstantin Zhuravlyov 11648cfc6867SAlex Lorenz static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS, 11658cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 11668cfc6867SAlex Lorenz int Reg = TRI->getLLVMRegNum(DwarfReg, true); 11678cfc6867SAlex Lorenz if (Reg == -1) { 11688cfc6867SAlex Lorenz OS << "<badreg>"; 11698cfc6867SAlex Lorenz return; 11708cfc6867SAlex Lorenz } 11718cfc6867SAlex Lorenz printReg(Reg, OS, TRI); 11728cfc6867SAlex Lorenz } 11738cfc6867SAlex Lorenz 11748cfc6867SAlex Lorenz void MIPrinter::print(const MCCFIInstruction &CFI, 11758cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 1176f4baeb51SAlex Lorenz switch (CFI.getOperation()) { 1177577d271aSAlex Lorenz case MCCFIInstruction::OpSameValue: 1178ee067920SMatthias Braun OS << "same_value "; 1179577d271aSAlex Lorenz if (CFI.getLabel()) 1180577d271aSAlex Lorenz OS << "<mcsymbol> "; 1181577d271aSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 1182577d271aSAlex Lorenz break; 11838cfc6867SAlex Lorenz case MCCFIInstruction::OpOffset: 1184ee067920SMatthias Braun OS << "offset "; 11858cfc6867SAlex Lorenz if (CFI.getLabel()) 11868cfc6867SAlex Lorenz OS << "<mcsymbol> "; 11878cfc6867SAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 11888cfc6867SAlex Lorenz OS << ", " << CFI.getOffset(); 11898cfc6867SAlex Lorenz break; 11905b0d5f6fSAlex Lorenz case MCCFIInstruction::OpDefCfaRegister: 1191ee067920SMatthias Braun OS << "def_cfa_register "; 11925b0d5f6fSAlex Lorenz if (CFI.getLabel()) 11935b0d5f6fSAlex Lorenz OS << "<mcsymbol> "; 11945b0d5f6fSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 11955b0d5f6fSAlex Lorenz break; 1196f4baeb51SAlex Lorenz case MCCFIInstruction::OpDefCfaOffset: 1197ee067920SMatthias Braun OS << "def_cfa_offset "; 1198f4baeb51SAlex Lorenz if (CFI.getLabel()) 1199f4baeb51SAlex Lorenz OS << "<mcsymbol> "; 1200f4baeb51SAlex Lorenz OS << CFI.getOffset(); 1201f4baeb51SAlex Lorenz break; 1202b139323fSAlex Lorenz case MCCFIInstruction::OpDefCfa: 1203ee067920SMatthias Braun OS << "def_cfa "; 1204b139323fSAlex Lorenz if (CFI.getLabel()) 1205b139323fSAlex Lorenz OS << "<mcsymbol> "; 1206b139323fSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 1207b139323fSAlex Lorenz OS << ", " << CFI.getOffset(); 1208b139323fSAlex Lorenz break; 1209f4baeb51SAlex Lorenz default: 1210f4baeb51SAlex Lorenz // TODO: Print the other CFI Operations. 1211f4baeb51SAlex Lorenz OS << "<unserializable cfi operation>"; 1212f4baeb51SAlex Lorenz break; 1213f4baeb51SAlex Lorenz } 1214f4baeb51SAlex Lorenz } 1215f4baeb51SAlex Lorenz 1216345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) { 1217345c1449SAlex Lorenz yaml::Output Out(OS); 1218345c1449SAlex Lorenz Out << const_cast<Module &>(M); 1219345c1449SAlex Lorenz } 1220345c1449SAlex Lorenz 1221345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) { 1222345c1449SAlex Lorenz MIRPrinter Printer(OS); 1223345c1449SAlex Lorenz Printer.print(MF); 1224345c1449SAlex Lorenz } 1225