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" 21*bb80d3e1SKonstantin 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; 143*bb80d3e1SKonstantin Zhuravlyov /// Synchronization scope names registered with LLVMContext. 144*bb80d3e1SKonstantin 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*bb80d3e1SKonstantin Zhuravlyov void print(const LLVMContext &Context, const MachineMemOperand &Op); 169*bb80d3e1SKonstantin Zhuravlyov void printSyncScope(const LLVMContext &Context, SyncScope::ID SSID); 170f4baeb51SAlex Lorenz 1718cfc6867SAlex Lorenz void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI); 1728e0a1b48SAlex Lorenz }; 1738e0a1b48SAlex Lorenz 1745022f6bbSAlex Lorenz } // end namespace llvm 175345c1449SAlex Lorenz 176345c1449SAlex Lorenz namespace llvm { 177345c1449SAlex Lorenz namespace yaml { 178345c1449SAlex Lorenz 179345c1449SAlex Lorenz /// This struct serializes the LLVM IR module. 180345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> { 181345c1449SAlex Lorenz static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) { 182345c1449SAlex Lorenz Mod.print(OS, nullptr); 183345c1449SAlex Lorenz } 184fb69e66cSEugene Zelenko 185345c1449SAlex Lorenz static StringRef input(StringRef Str, void *Ctxt, Module &Mod) { 186345c1449SAlex Lorenz llvm_unreachable("LLVM Module is supposed to be parsed separately"); 187345c1449SAlex Lorenz return ""; 188345c1449SAlex Lorenz } 189345c1449SAlex Lorenz }; 190345c1449SAlex Lorenz 191345c1449SAlex Lorenz } // end namespace yaml 192345c1449SAlex Lorenz } // end namespace llvm 193345c1449SAlex Lorenz 19415a00a85SAlex Lorenz static void printReg(unsigned Reg, raw_ostream &OS, 19515a00a85SAlex Lorenz const TargetRegisterInfo *TRI) { 19615a00a85SAlex Lorenz // TODO: Print Stack Slots. 19715a00a85SAlex Lorenz if (!Reg) 19815a00a85SAlex Lorenz OS << '_'; 19915a00a85SAlex Lorenz else if (TargetRegisterInfo::isVirtualRegister(Reg)) 20015a00a85SAlex Lorenz OS << '%' << TargetRegisterInfo::virtReg2Index(Reg); 20115a00a85SAlex Lorenz else if (Reg < TRI->getNumRegs()) 20215a00a85SAlex Lorenz OS << '%' << StringRef(TRI->getName(Reg)).lower(); 20315a00a85SAlex Lorenz else 20415a00a85SAlex Lorenz llvm_unreachable("Can't print this kind of register yet"); 20515a00a85SAlex Lorenz } 20615a00a85SAlex Lorenz 207ab4cbcfdSAlex Lorenz static void printReg(unsigned Reg, yaml::StringValue &Dest, 208ab4cbcfdSAlex Lorenz const TargetRegisterInfo *TRI) { 209ab4cbcfdSAlex Lorenz raw_string_ostream OS(Dest.Value); 210ab4cbcfdSAlex Lorenz printReg(Reg, OS, TRI); 211ab4cbcfdSAlex Lorenz } 212ab4cbcfdSAlex Lorenz 213345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) { 2148f6f4285SAlex Lorenz initRegisterMaskIds(MF); 2158f6f4285SAlex Lorenz 216345c1449SAlex Lorenz yaml::MachineFunction YamlMF; 217345c1449SAlex Lorenz YamlMF.Name = MF.getName(); 2185b5f9753SAlex Lorenz YamlMF.Alignment = MF.getAlignment(); 2195b5f9753SAlex Lorenz YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice(); 220ad154c83SDerek Schuff 2210d7b0cb8SAhmed Bougacha YamlMF.Legalized = MF.getProperties().hasProperty( 2220d7b0cb8SAhmed Bougacha MachineFunctionProperties::Property::Legalized); 22324712655SAhmed Bougacha YamlMF.RegBankSelected = MF.getProperties().hasProperty( 22424712655SAhmed Bougacha MachineFunctionProperties::Property::RegBankSelected); 225b109d518SAhmed Bougacha YamlMF.Selected = MF.getProperties().hasProperty( 226b109d518SAhmed Bougacha MachineFunctionProperties::Property::Selected); 2270d7b0cb8SAhmed Bougacha 22828148ba8SAlex Lorenz convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo()); 229a6f9a37dSAlex Lorenz ModuleSlotTracker MST(MF.getFunction()->getParent()); 230a6f9a37dSAlex Lorenz MST.incorporateFunction(*MF.getFunction()); 231941a705bSMatthias Braun convert(MST, YamlMF.FrameInfo, MF.getFrameInfo()); 232ef331effSMatthias Braun convertStackObjects(YamlMF, MF, MST); 233ab980499SAlex Lorenz if (const auto *ConstantPool = MF.getConstantPool()) 234ab980499SAlex Lorenz convert(YamlMF, *ConstantPool); 2356799e9b3SAlex Lorenz if (const auto *JumpTableInfo = MF.getJumpTableInfo()) 2366799e9b3SAlex Lorenz convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo); 2375022f6bbSAlex Lorenz raw_string_ostream StrOS(YamlMF.Body.Value.Value); 2385022f6bbSAlex Lorenz bool IsNewlineNeeded = false; 2394f093bf1SAlex Lorenz for (const auto &MBB : MF) { 2405022f6bbSAlex Lorenz if (IsNewlineNeeded) 2415022f6bbSAlex Lorenz StrOS << "\n"; 2425022f6bbSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 2435022f6bbSAlex Lorenz .print(MBB); 2445022f6bbSAlex Lorenz IsNewlineNeeded = true; 2454f093bf1SAlex Lorenz } 2465022f6bbSAlex Lorenz StrOS.flush(); 247345c1449SAlex Lorenz yaml::Output Out(OS); 24856d87ef5SVivek Pandya if (!SimplifyMIR) 24956d87ef5SVivek Pandya Out.setWriteDefaultValues(true); 250345c1449SAlex Lorenz Out << YamlMF; 251345c1449SAlex Lorenz } 252345c1449SAlex Lorenz 2530ef61ec3SOren Ben Simhon static void printCustomRegMask(const uint32_t *RegMask, raw_ostream &OS, 2540ef61ec3SOren Ben Simhon const TargetRegisterInfo *TRI) { 2550ef61ec3SOren Ben Simhon assert(RegMask && "Can't print an empty register mask"); 2560ef61ec3SOren Ben Simhon OS << StringRef("CustomRegMask("); 2570ef61ec3SOren Ben Simhon 2580ef61ec3SOren Ben Simhon bool IsRegInRegMaskFound = false; 2590ef61ec3SOren Ben Simhon for (int I = 0, E = TRI->getNumRegs(); I < E; I++) { 2600ef61ec3SOren Ben Simhon // Check whether the register is asserted in regmask. 2610ef61ec3SOren Ben Simhon if (RegMask[I / 32] & (1u << (I % 32))) { 2620ef61ec3SOren Ben Simhon if (IsRegInRegMaskFound) 2630ef61ec3SOren Ben Simhon OS << ','; 2640ef61ec3SOren Ben Simhon printReg(I, OS, TRI); 2650ef61ec3SOren Ben Simhon IsRegInRegMaskFound = true; 2660ef61ec3SOren Ben Simhon } 2670ef61ec3SOren Ben Simhon } 2680ef61ec3SOren Ben Simhon 2690ef61ec3SOren Ben Simhon OS << ')'; 2700ef61ec3SOren Ben Simhon } 2710ef61ec3SOren Ben Simhon 27254565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 27328148ba8SAlex Lorenz const MachineRegisterInfo &RegInfo, 27428148ba8SAlex Lorenz const TargetRegisterInfo *TRI) { 27554565cf0SAlex Lorenz MF.TracksRegLiveness = RegInfo.tracksLiveness(); 27628148ba8SAlex Lorenz 27728148ba8SAlex Lorenz // Print the virtual register definitions. 27828148ba8SAlex Lorenz for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) { 27928148ba8SAlex Lorenz unsigned Reg = TargetRegisterInfo::index2VirtReg(I); 28028148ba8SAlex Lorenz yaml::VirtualRegisterDefinition VReg; 28128148ba8SAlex Lorenz VReg.ID = I; 282fab1cfe6SQuentin Colombet if (RegInfo.getRegClassOrNull(Reg)) 28328148ba8SAlex Lorenz VReg.Class = 28428148ba8SAlex Lorenz StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower(); 285fab1cfe6SQuentin Colombet else if (RegInfo.getRegBankOrNull(Reg)) 286fab1cfe6SQuentin Colombet VReg.Class = StringRef(RegInfo.getRegBankOrNull(Reg)->getName()).lower(); 287050b2118SQuentin Colombet else { 288050b2118SQuentin Colombet VReg.Class = std::string("_"); 289d28d3cc0STim Northover assert((RegInfo.def_empty(Reg) || RegInfo.getType(Reg).isValid()) && 2900f140c76STim Northover "Generic registers must have a valid type"); 291050b2118SQuentin Colombet } 292ab4cbcfdSAlex Lorenz unsigned PreferredReg = RegInfo.getSimpleHint(Reg); 293ab4cbcfdSAlex Lorenz if (PreferredReg) 294ab4cbcfdSAlex Lorenz printReg(PreferredReg, VReg.PreferredRegister, TRI); 29528148ba8SAlex Lorenz MF.VirtualRegisters.push_back(VReg); 29628148ba8SAlex Lorenz } 29712045a4bSAlex Lorenz 29812045a4bSAlex Lorenz // Print the live ins. 29912045a4bSAlex Lorenz for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) { 30012045a4bSAlex Lorenz yaml::MachineFunctionLiveIn LiveIn; 30112045a4bSAlex Lorenz printReg(I->first, LiveIn.Register, TRI); 30212045a4bSAlex Lorenz if (I->second) 30312045a4bSAlex Lorenz printReg(I->second, LiveIn.VirtualRegister, TRI); 30412045a4bSAlex Lorenz MF.LiveIns.push_back(LiveIn); 30512045a4bSAlex Lorenz } 3060ef61ec3SOren Ben Simhon 3070ef61ec3SOren Ben Simhon // Prints the callee saved registers. 3080ef61ec3SOren Ben Simhon if (RegInfo.isUpdatedCSRsInitialized()) { 3090ef61ec3SOren Ben Simhon const MCPhysReg *CalleeSavedRegs = RegInfo.getCalleeSavedRegs(); 310c4838087SAlex Lorenz std::vector<yaml::FlowStringValue> CalleeSavedRegisters; 3110ef61ec3SOren Ben Simhon for (const MCPhysReg *I = CalleeSavedRegs; *I; ++I) { 312c4838087SAlex Lorenz yaml::FlowStringValue Reg; 3130ef61ec3SOren Ben Simhon printReg(*I, Reg, TRI); 314c4838087SAlex Lorenz CalleeSavedRegisters.push_back(Reg); 315c4838087SAlex Lorenz } 316c4838087SAlex Lorenz MF.CalleeSavedRegisters = CalleeSavedRegisters; 31754565cf0SAlex Lorenz } 3180ef61ec3SOren Ben Simhon } 31954565cf0SAlex Lorenz 320a6f9a37dSAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 321a6f9a37dSAlex Lorenz yaml::MachineFrameInfo &YamlMFI, 32260541c1dSAlex Lorenz const MachineFrameInfo &MFI) { 32360541c1dSAlex Lorenz YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken(); 32460541c1dSAlex Lorenz YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken(); 32560541c1dSAlex Lorenz YamlMFI.HasStackMap = MFI.hasStackMap(); 32660541c1dSAlex Lorenz YamlMFI.HasPatchPoint = MFI.hasPatchPoint(); 32760541c1dSAlex Lorenz YamlMFI.StackSize = MFI.getStackSize(); 32860541c1dSAlex Lorenz YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment(); 32960541c1dSAlex Lorenz YamlMFI.MaxAlignment = MFI.getMaxAlignment(); 33060541c1dSAlex Lorenz YamlMFI.AdjustsStack = MFI.adjustsStack(); 33160541c1dSAlex Lorenz YamlMFI.HasCalls = MFI.hasCalls(); 332ab9438cbSMatthias Braun YamlMFI.MaxCallFrameSize = MFI.isMaxCallFrameSizeComputed() 333ab9438cbSMatthias Braun ? MFI.getMaxCallFrameSize() : ~0u; 33460541c1dSAlex Lorenz YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment(); 33560541c1dSAlex Lorenz YamlMFI.HasVAStart = MFI.hasVAStart(); 33660541c1dSAlex Lorenz YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc(); 337a6f9a37dSAlex Lorenz if (MFI.getSavePoint()) { 338a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.SavePoint.Value); 339a6f9a37dSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 340a6f9a37dSAlex Lorenz .printMBBReference(*MFI.getSavePoint()); 341a6f9a37dSAlex Lorenz } 342a6f9a37dSAlex Lorenz if (MFI.getRestorePoint()) { 343a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.RestorePoint.Value); 344a6f9a37dSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 345a6f9a37dSAlex Lorenz .printMBBReference(*MFI.getRestorePoint()); 346a6f9a37dSAlex Lorenz } 34760541c1dSAlex Lorenz } 34860541c1dSAlex Lorenz 349ef331effSMatthias Braun void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF, 350ef331effSMatthias Braun const MachineFunction &MF, 351ef331effSMatthias Braun ModuleSlotTracker &MST) { 352ef331effSMatthias Braun const MachineFrameInfo &MFI = MF.getFrameInfo(); 353ef331effSMatthias Braun const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 354de491f05SAlex Lorenz // Process fixed stack objects. 355f6bc8667SAlex Lorenz unsigned ID = 0; 356de491f05SAlex Lorenz for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) { 357de491f05SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 358de491f05SAlex Lorenz continue; 359de491f05SAlex Lorenz 360de491f05SAlex Lorenz yaml::FixedMachineStackObject YamlObject; 3617feaf7c6SAlex Lorenz YamlObject.ID = ID; 362de491f05SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 363de491f05SAlex Lorenz ? yaml::FixedMachineStackObject::SpillSlot 364de491f05SAlex Lorenz : yaml::FixedMachineStackObject::DefaultType; 365de491f05SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 366de491f05SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 367de491f05SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 368de491f05SAlex Lorenz YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I); 369de491f05SAlex Lorenz YamlObject.IsAliased = MFI.isAliasedObjectIndex(I); 370ef331effSMatthias Braun YMF.FixedStackObjects.push_back(YamlObject); 3717feaf7c6SAlex Lorenz StackObjectOperandMapping.insert( 3727feaf7c6SAlex Lorenz std::make_pair(I, FrameIndexOperand::createFixed(ID++))); 373de491f05SAlex Lorenz } 374de491f05SAlex Lorenz 375de491f05SAlex Lorenz // Process ordinary stack objects. 376de491f05SAlex Lorenz ID = 0; 377f6bc8667SAlex Lorenz for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) { 378f6bc8667SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 379f6bc8667SAlex Lorenz continue; 380f6bc8667SAlex Lorenz 381f6bc8667SAlex Lorenz yaml::MachineStackObject YamlObject; 3827feaf7c6SAlex Lorenz YamlObject.ID = ID; 38337643a04SAlex Lorenz if (const auto *Alloca = MFI.getObjectAllocation(I)) 38437643a04SAlex Lorenz YamlObject.Name.Value = 38537643a04SAlex Lorenz Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>"; 386f6bc8667SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 387f6bc8667SAlex Lorenz ? yaml::MachineStackObject::SpillSlot 388418f3ec1SAlex Lorenz : MFI.isVariableSizedObjectIndex(I) 389418f3ec1SAlex Lorenz ? yaml::MachineStackObject::VariableSized 390f6bc8667SAlex Lorenz : yaml::MachineStackObject::DefaultType; 391f6bc8667SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 392f6bc8667SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 393f6bc8667SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 394f6bc8667SAlex Lorenz 395ef331effSMatthias Braun YMF.StackObjects.push_back(YamlObject); 3967feaf7c6SAlex Lorenz StackObjectOperandMapping.insert(std::make_pair( 3977feaf7c6SAlex Lorenz I, FrameIndexOperand::create(YamlObject.Name.Value, ID++))); 398f6bc8667SAlex Lorenz } 3991bb48de1SAlex Lorenz 4001bb48de1SAlex Lorenz for (const auto &CSInfo : MFI.getCalleeSavedInfo()) { 4011bb48de1SAlex Lorenz yaml::StringValue Reg; 4021bb48de1SAlex Lorenz printReg(CSInfo.getReg(), Reg, TRI); 4031bb48de1SAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx()); 4041bb48de1SAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 4051bb48de1SAlex Lorenz "Invalid stack object index"); 4061bb48de1SAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 4071bb48de1SAlex Lorenz if (StackObject.IsFixed) 408ef331effSMatthias Braun YMF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg; 4091bb48de1SAlex Lorenz else 410ef331effSMatthias Braun YMF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg; 4111bb48de1SAlex Lorenz } 412a56ba6a6SAlex Lorenz for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) { 413a56ba6a6SAlex Lorenz auto LocalObject = MFI.getLocalFrameObjectMap(I); 414a56ba6a6SAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(LocalObject.first); 415a56ba6a6SAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 416a56ba6a6SAlex Lorenz "Invalid stack object index"); 417a56ba6a6SAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 418a56ba6a6SAlex Lorenz assert(!StackObject.IsFixed && "Expected a locally mapped stack object"); 419ef331effSMatthias Braun YMF.StackObjects[StackObject.ID].LocalOffset = LocalObject.second; 420a56ba6a6SAlex Lorenz } 421a314d813SAlex Lorenz 422a314d813SAlex Lorenz // Print the stack object references in the frame information class after 423a314d813SAlex Lorenz // converting the stack objects. 424a314d813SAlex Lorenz if (MFI.hasStackProtectorIndex()) { 425ef331effSMatthias Braun raw_string_ostream StrOS(YMF.FrameInfo.StackProtector.Value); 426a314d813SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 427a314d813SAlex Lorenz .printStackObjectReference(MFI.getStackProtectorIndex()); 428a314d813SAlex Lorenz } 429df9e3c6fSAlex Lorenz 430df9e3c6fSAlex Lorenz // Print the debug variable information. 431ef331effSMatthias Braun for (const MachineFunction::VariableDbgInfo &DebugVar : 432ef331effSMatthias Braun MF.getVariableDbgInfo()) { 433df9e3c6fSAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(DebugVar.Slot); 434df9e3c6fSAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 435df9e3c6fSAlex Lorenz "Invalid stack object index"); 436df9e3c6fSAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 437df9e3c6fSAlex Lorenz assert(!StackObject.IsFixed && "Expected a non-fixed stack object"); 438ef331effSMatthias Braun auto &Object = YMF.StackObjects[StackObject.ID]; 439df9e3c6fSAlex Lorenz { 440df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugVar.Value); 441df9e3c6fSAlex Lorenz DebugVar.Var->printAsOperand(StrOS, MST); 442df9e3c6fSAlex Lorenz } 443df9e3c6fSAlex Lorenz { 444df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugExpr.Value); 445df9e3c6fSAlex Lorenz DebugVar.Expr->printAsOperand(StrOS, MST); 446df9e3c6fSAlex Lorenz } 447df9e3c6fSAlex Lorenz { 448df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugLoc.Value); 449df9e3c6fSAlex Lorenz DebugVar.Loc->printAsOperand(StrOS, MST); 450df9e3c6fSAlex Lorenz } 451df9e3c6fSAlex Lorenz } 452f6bc8667SAlex Lorenz } 453f6bc8667SAlex Lorenz 454ab980499SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 455ab980499SAlex Lorenz const MachineConstantPool &ConstantPool) { 456ab980499SAlex Lorenz unsigned ID = 0; 457ab980499SAlex Lorenz for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) { 458ab980499SAlex Lorenz // TODO: Serialize target specific constant pool entries. 459ab980499SAlex Lorenz if (Constant.isMachineConstantPoolEntry()) 460ab980499SAlex Lorenz llvm_unreachable("Can't print target specific constant pool entries yet"); 461ab980499SAlex Lorenz 462ab980499SAlex Lorenz yaml::MachineConstantPoolValue YamlConstant; 463ab980499SAlex Lorenz std::string Str; 464ab980499SAlex Lorenz raw_string_ostream StrOS(Str); 465ab980499SAlex Lorenz Constant.Val.ConstVal->printAsOperand(StrOS); 466ab980499SAlex Lorenz YamlConstant.ID = ID++; 467ab980499SAlex Lorenz YamlConstant.Value = StrOS.str(); 468ab980499SAlex Lorenz YamlConstant.Alignment = Constant.getAlignment(); 469ab980499SAlex Lorenz MF.Constants.push_back(YamlConstant); 470ab980499SAlex Lorenz } 471ab980499SAlex Lorenz } 472ab980499SAlex Lorenz 473900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 4746799e9b3SAlex Lorenz yaml::MachineJumpTable &YamlJTI, 4756799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI) { 4766799e9b3SAlex Lorenz YamlJTI.Kind = JTI.getEntryKind(); 4776799e9b3SAlex Lorenz unsigned ID = 0; 4786799e9b3SAlex Lorenz for (const auto &Table : JTI.getJumpTables()) { 4796799e9b3SAlex Lorenz std::string Str; 4806799e9b3SAlex Lorenz yaml::MachineJumpTable::Entry Entry; 4816799e9b3SAlex Lorenz Entry.ID = ID++; 4826799e9b3SAlex Lorenz for (const auto *MBB : Table.MBBs) { 4836799e9b3SAlex Lorenz raw_string_ostream StrOS(Str); 4847feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 4857feaf7c6SAlex Lorenz .printMBBReference(*MBB); 4866799e9b3SAlex Lorenz Entry.Blocks.push_back(StrOS.str()); 4876799e9b3SAlex Lorenz Str.clear(); 4886799e9b3SAlex Lorenz } 4896799e9b3SAlex Lorenz YamlJTI.Entries.push_back(Entry); 4906799e9b3SAlex Lorenz } 4916799e9b3SAlex Lorenz } 4926799e9b3SAlex Lorenz 4938f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) { 4948f6f4285SAlex Lorenz const auto *TRI = MF.getSubtarget().getRegisterInfo(); 4958f6f4285SAlex Lorenz unsigned I = 0; 4968f6f4285SAlex Lorenz for (const uint32_t *Mask : TRI->getRegMasks()) 4978f6f4285SAlex Lorenz RegisterMaskIds.insert(std::make_pair(Mask, I++)); 4988f6f4285SAlex Lorenz } 4998f6f4285SAlex Lorenz 5008940114fSMatthias Braun void llvm::guessSuccessors(const MachineBasicBlock &MBB, 5018940114fSMatthias Braun SmallVectorImpl<MachineBasicBlock*> &Result, 5028940114fSMatthias Braun bool &IsFallthrough) { 5038940114fSMatthias Braun SmallPtrSet<MachineBasicBlock*,8> Seen; 5048940114fSMatthias Braun 5058940114fSMatthias Braun for (const MachineInstr &MI : MBB) { 5068940114fSMatthias Braun if (MI.isPHI()) 5078940114fSMatthias Braun continue; 5088940114fSMatthias Braun for (const MachineOperand &MO : MI.operands()) { 5098940114fSMatthias Braun if (!MO.isMBB()) 5108940114fSMatthias Braun continue; 5118940114fSMatthias Braun MachineBasicBlock *Succ = MO.getMBB(); 5128940114fSMatthias Braun auto RP = Seen.insert(Succ); 5138940114fSMatthias Braun if (RP.second) 5148940114fSMatthias Braun Result.push_back(Succ); 5158940114fSMatthias Braun } 5168940114fSMatthias Braun } 5178940114fSMatthias Braun MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr(); 5188940114fSMatthias Braun IsFallthrough = I == MBB.end() || !I->isBarrier(); 5198940114fSMatthias Braun } 5208940114fSMatthias Braun 5218940114fSMatthias Braun bool 5228940114fSMatthias Braun MIPrinter::canPredictBranchProbabilities(const MachineBasicBlock &MBB) const { 5238940114fSMatthias Braun if (MBB.succ_size() <= 1) 5248940114fSMatthias Braun return true; 5258940114fSMatthias Braun if (!MBB.hasSuccessorProbabilities()) 5268940114fSMatthias Braun return true; 5278940114fSMatthias Braun 5288940114fSMatthias Braun SmallVector<BranchProbability,8> Normalized(MBB.Probs.begin(), 5298940114fSMatthias Braun MBB.Probs.end()); 5308940114fSMatthias Braun BranchProbability::normalizeProbabilities(Normalized.begin(), 5318940114fSMatthias Braun Normalized.end()); 5328940114fSMatthias Braun SmallVector<BranchProbability,8> Equal(Normalized.size()); 5338940114fSMatthias Braun BranchProbability::normalizeProbabilities(Equal.begin(), Equal.end()); 5348940114fSMatthias Braun 5358940114fSMatthias Braun return std::equal(Normalized.begin(), Normalized.end(), Equal.begin()); 5368940114fSMatthias Braun } 5378940114fSMatthias Braun 5388940114fSMatthias Braun bool MIPrinter::canPredictSuccessors(const MachineBasicBlock &MBB) const { 5398940114fSMatthias Braun SmallVector<MachineBasicBlock*,8> GuessedSuccs; 5408940114fSMatthias Braun bool GuessedFallthrough; 5418940114fSMatthias Braun guessSuccessors(MBB, GuessedSuccs, GuessedFallthrough); 5428940114fSMatthias Braun if (GuessedFallthrough) { 5438940114fSMatthias Braun const MachineFunction &MF = *MBB.getParent(); 5448940114fSMatthias Braun MachineFunction::const_iterator NextI = std::next(MBB.getIterator()); 5458940114fSMatthias Braun if (NextI != MF.end()) { 5468940114fSMatthias Braun MachineBasicBlock *Next = const_cast<MachineBasicBlock*>(&*NextI); 5478940114fSMatthias Braun if (!is_contained(GuessedSuccs, Next)) 5488940114fSMatthias Braun GuessedSuccs.push_back(Next); 5498940114fSMatthias Braun } 5508940114fSMatthias Braun } 5518940114fSMatthias Braun if (GuessedSuccs.size() != MBB.succ_size()) 5528940114fSMatthias Braun return false; 5538940114fSMatthias Braun return std::equal(MBB.succ_begin(), MBB.succ_end(), GuessedSuccs.begin()); 5548940114fSMatthias Braun } 5558940114fSMatthias Braun 5565022f6bbSAlex Lorenz void MIPrinter::print(const MachineBasicBlock &MBB) { 5575022f6bbSAlex Lorenz assert(MBB.getNumber() >= 0 && "Invalid MBB number"); 5585022f6bbSAlex Lorenz OS << "bb." << MBB.getNumber(); 5595022f6bbSAlex Lorenz bool HasAttributes = false; 5605022f6bbSAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 5615022f6bbSAlex Lorenz if (BB->hasName()) { 5625022f6bbSAlex Lorenz OS << "." << BB->getName(); 5635022f6bbSAlex Lorenz } else { 5645022f6bbSAlex Lorenz HasAttributes = true; 5655022f6bbSAlex Lorenz OS << " ("; 5665022f6bbSAlex Lorenz int Slot = MST.getLocalSlot(BB); 5675022f6bbSAlex Lorenz if (Slot == -1) 5685022f6bbSAlex Lorenz OS << "<ir-block badref>"; 5695022f6bbSAlex Lorenz else 5705022f6bbSAlex Lorenz OS << (Twine("%ir-block.") + Twine(Slot)).str(); 5715022f6bbSAlex Lorenz } 5725022f6bbSAlex Lorenz } 5735022f6bbSAlex Lorenz if (MBB.hasAddressTaken()) { 5745022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 5755022f6bbSAlex Lorenz OS << "address-taken"; 5765022f6bbSAlex Lorenz HasAttributes = true; 5775022f6bbSAlex Lorenz } 5780e288234SReid Kleckner if (MBB.isEHPad()) { 5795022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 5805022f6bbSAlex Lorenz OS << "landing-pad"; 5815022f6bbSAlex Lorenz HasAttributes = true; 5825022f6bbSAlex Lorenz } 5835022f6bbSAlex Lorenz if (MBB.getAlignment()) { 5845022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 5855022f6bbSAlex Lorenz OS << "align " << MBB.getAlignment(); 5865022f6bbSAlex Lorenz HasAttributes = true; 5875022f6bbSAlex Lorenz } 5885022f6bbSAlex Lorenz if (HasAttributes) 5895022f6bbSAlex Lorenz OS << ")"; 5905022f6bbSAlex Lorenz OS << ":\n"; 5915022f6bbSAlex Lorenz 5925022f6bbSAlex Lorenz bool HasLineAttributes = false; 5935022f6bbSAlex Lorenz // Print the successors 5948940114fSMatthias Braun bool canPredictProbs = canPredictBranchProbabilities(MBB); 5958940114fSMatthias Braun if (!MBB.succ_empty() && (!SimplifyMIR || !canPredictProbs || 5968940114fSMatthias Braun !canPredictSuccessors(MBB))) { 5975022f6bbSAlex Lorenz OS.indent(2) << "successors: "; 5985022f6bbSAlex Lorenz for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) { 5995022f6bbSAlex Lorenz if (I != MBB.succ_begin()) 6005022f6bbSAlex Lorenz OS << ", "; 6015022f6bbSAlex Lorenz printMBBReference(**I); 6028940114fSMatthias Braun if (!SimplifyMIR || !canPredictProbs) 603b51774acSGeoff Berry OS << '(' 604b51774acSGeoff Berry << format("0x%08" PRIx32, MBB.getSuccProbability(I).getNumerator()) 605b51774acSGeoff Berry << ')'; 6065022f6bbSAlex Lorenz } 6075022f6bbSAlex Lorenz OS << "\n"; 6085022f6bbSAlex Lorenz HasLineAttributes = true; 6095022f6bbSAlex Lorenz } 6105022f6bbSAlex Lorenz 6115022f6bbSAlex Lorenz // Print the live in registers. 61211723322SMatthias Braun const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 61311723322SMatthias Braun if (MRI.tracksLiveness() && !MBB.livein_empty()) { 61411723322SMatthias Braun const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); 6155022f6bbSAlex Lorenz OS.indent(2) << "liveins: "; 616b2b7ef1dSMatthias Braun bool First = true; 617d9da1627SMatthias Braun for (const auto &LI : MBB.liveins()) { 618b2b7ef1dSMatthias Braun if (!First) 6195022f6bbSAlex Lorenz OS << ", "; 620b2b7ef1dSMatthias Braun First = false; 62111723322SMatthias Braun printReg(LI.PhysReg, OS, &TRI); 62291b5cf84SKrzysztof Parzyszek if (!LI.LaneMask.all()) 623d62669d7SKrzysztof Parzyszek OS << ":0x" << PrintLaneMask(LI.LaneMask); 6245022f6bbSAlex Lorenz } 6255022f6bbSAlex Lorenz OS << "\n"; 6265022f6bbSAlex Lorenz HasLineAttributes = true; 6275022f6bbSAlex Lorenz } 6285022f6bbSAlex Lorenz 6295022f6bbSAlex Lorenz if (HasLineAttributes) 6305022f6bbSAlex Lorenz OS << "\n"; 631f9a2b123SAlex Lorenz bool IsInBundle = false; 632f9a2b123SAlex Lorenz for (auto I = MBB.instr_begin(), E = MBB.instr_end(); I != E; ++I) { 633f9a2b123SAlex Lorenz const MachineInstr &MI = *I; 634f9a2b123SAlex Lorenz if (IsInBundle && !MI.isInsideBundle()) { 635f9a2b123SAlex Lorenz OS.indent(2) << "}\n"; 636f9a2b123SAlex Lorenz IsInBundle = false; 637f9a2b123SAlex Lorenz } 638f9a2b123SAlex Lorenz OS.indent(IsInBundle ? 4 : 2); 6395022f6bbSAlex Lorenz print(MI); 640f9a2b123SAlex Lorenz if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) { 641f9a2b123SAlex Lorenz OS << " {"; 642f9a2b123SAlex Lorenz IsInBundle = true; 643f9a2b123SAlex Lorenz } 6445022f6bbSAlex Lorenz OS << "\n"; 6455022f6bbSAlex Lorenz } 646f9a2b123SAlex Lorenz if (IsInBundle) 647f9a2b123SAlex Lorenz OS.indent(2) << "}\n"; 6485022f6bbSAlex Lorenz } 6495022f6bbSAlex Lorenz 6505ef93b0cSAlex Lorenz /// Return true when an instruction has tied register that can't be determined 6515ef93b0cSAlex Lorenz /// by the instruction's descriptor. 6525ef93b0cSAlex Lorenz static bool hasComplexRegisterTies(const MachineInstr &MI) { 6535ef93b0cSAlex Lorenz const MCInstrDesc &MCID = MI.getDesc(); 6545ef93b0cSAlex Lorenz for (unsigned I = 0, E = MI.getNumOperands(); I < E; ++I) { 6555ef93b0cSAlex Lorenz const auto &Operand = MI.getOperand(I); 6565ef93b0cSAlex Lorenz if (!Operand.isReg() || Operand.isDef()) 6575ef93b0cSAlex Lorenz // Ignore the defined registers as MCID marks only the uses as tied. 6585ef93b0cSAlex Lorenz continue; 6595ef93b0cSAlex Lorenz int ExpectedTiedIdx = MCID.getOperandConstraint(I, MCOI::TIED_TO); 6605ef93b0cSAlex Lorenz int TiedIdx = Operand.isTied() ? int(MI.findTiedOperandIdx(I)) : -1; 6615ef93b0cSAlex Lorenz if (ExpectedTiedIdx != TiedIdx) 6625ef93b0cSAlex Lorenz return true; 6635ef93b0cSAlex Lorenz } 6645ef93b0cSAlex Lorenz return false; 6655ef93b0cSAlex Lorenz } 6665ef93b0cSAlex Lorenz 667d28d3cc0STim Northover static LLT getTypeToPrint(const MachineInstr &MI, unsigned OpIdx, 668d28d3cc0STim Northover SmallBitVector &PrintedTypes, 669d28d3cc0STim Northover const MachineRegisterInfo &MRI) { 670d28d3cc0STim Northover const MachineOperand &Op = MI.getOperand(OpIdx); 671d28d3cc0STim Northover if (!Op.isReg()) 672d28d3cc0STim Northover return LLT{}; 673d28d3cc0STim Northover 674d28d3cc0STim Northover if (MI.isVariadic() || OpIdx >= MI.getNumExplicitOperands()) 675d28d3cc0STim Northover return MRI.getType(Op.getReg()); 676d28d3cc0STim Northover 677d28d3cc0STim Northover auto &OpInfo = MI.getDesc().OpInfo[OpIdx]; 678d28d3cc0STim Northover if (!OpInfo.isGenericType()) 679d28d3cc0STim Northover return MRI.getType(Op.getReg()); 680d28d3cc0STim Northover 681d28d3cc0STim Northover if (PrintedTypes[OpInfo.getGenericTypeIndex()]) 682d28d3cc0STim Northover return LLT{}; 683d28d3cc0STim Northover 684d28d3cc0STim Northover PrintedTypes.set(OpInfo.getGenericTypeIndex()); 685d28d3cc0STim Northover return MRI.getType(Op.getReg()); 686d28d3cc0STim Northover } 687d28d3cc0STim Northover 6888e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) { 6894e14a497SQuentin Colombet const auto *MF = MI.getParent()->getParent(); 6904e14a497SQuentin Colombet const auto &MRI = MF->getRegInfo(); 6914e14a497SQuentin Colombet const auto &SubTarget = MF->getSubtarget(); 692f3db51deSAlex Lorenz const auto *TRI = SubTarget.getRegisterInfo(); 693f3db51deSAlex Lorenz assert(TRI && "Expected target register info"); 6948e0a1b48SAlex Lorenz const auto *TII = SubTarget.getInstrInfo(); 6958e0a1b48SAlex Lorenz assert(TII && "Expected target instruction info"); 696f4baeb51SAlex Lorenz if (MI.isCFIInstruction()) 697f4baeb51SAlex Lorenz assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction"); 6988e0a1b48SAlex Lorenz 699d28d3cc0STim Northover SmallBitVector PrintedTypes(8); 7005ef93b0cSAlex Lorenz bool ShouldPrintRegisterTies = hasComplexRegisterTies(MI); 701f3db51deSAlex Lorenz unsigned I = 0, E = MI.getNumOperands(); 702f3db51deSAlex Lorenz for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() && 703f3db51deSAlex Lorenz !MI.getOperand(I).isImplicit(); 704f3db51deSAlex Lorenz ++I) { 705f3db51deSAlex Lorenz if (I) 706f3db51deSAlex Lorenz OS << ", "; 707d28d3cc0STim Northover print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies, 708d28d3cc0STim Northover getTypeToPrint(MI, I, PrintedTypes, MRI), 7094e14a497SQuentin Colombet /*IsDef=*/true); 710f3db51deSAlex Lorenz } 711f3db51deSAlex Lorenz 712f3db51deSAlex Lorenz if (I) 713f3db51deSAlex Lorenz OS << " = "; 714e5a44660SAlex Lorenz if (MI.getFlag(MachineInstr::FrameSetup)) 715e5a44660SAlex Lorenz OS << "frame-setup "; 7168e0a1b48SAlex Lorenz OS << TII->getName(MI.getOpcode()); 717f3db51deSAlex Lorenz if (I < E) 718f3db51deSAlex Lorenz OS << ' '; 719f3db51deSAlex Lorenz 720f3db51deSAlex Lorenz bool NeedComma = false; 721f3db51deSAlex Lorenz for (; I < E; ++I) { 722f3db51deSAlex Lorenz if (NeedComma) 723f3db51deSAlex Lorenz OS << ", "; 724d28d3cc0STim Northover print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies, 725d28d3cc0STim Northover getTypeToPrint(MI, I, PrintedTypes, MRI)); 726f3db51deSAlex Lorenz NeedComma = true; 727f3db51deSAlex Lorenz } 72846d760d1SAlex Lorenz 72946d760d1SAlex Lorenz if (MI.getDebugLoc()) { 73046d760d1SAlex Lorenz if (NeedComma) 73146d760d1SAlex Lorenz OS << ','; 73246d760d1SAlex Lorenz OS << " debug-location "; 73346d760d1SAlex Lorenz MI.getDebugLoc()->printAsOperand(OS, MST); 73446d760d1SAlex Lorenz } 7354af7e610SAlex Lorenz 7364af7e610SAlex Lorenz if (!MI.memoperands_empty()) { 7374af7e610SAlex Lorenz OS << " :: "; 738*bb80d3e1SKonstantin Zhuravlyov const LLVMContext &Context = MF->getFunction()->getContext(); 7394af7e610SAlex Lorenz bool NeedComma = false; 7404af7e610SAlex Lorenz for (const auto *Op : MI.memoperands()) { 7414af7e610SAlex Lorenz if (NeedComma) 7424af7e610SAlex Lorenz OS << ", "; 743*bb80d3e1SKonstantin Zhuravlyov print(Context, *Op); 7444af7e610SAlex Lorenz NeedComma = true; 7454af7e610SAlex Lorenz } 7464af7e610SAlex Lorenz } 747f3db51deSAlex Lorenz } 748f3db51deSAlex Lorenz 7495d26fa83SAlex Lorenz void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) { 7505d26fa83SAlex Lorenz OS << "%bb." << MBB.getNumber(); 7515d26fa83SAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 7525d26fa83SAlex Lorenz if (BB->hasName()) 7535d26fa83SAlex Lorenz OS << '.' << BB->getName(); 7545d26fa83SAlex Lorenz } 7555d26fa83SAlex Lorenz } 7565d26fa83SAlex Lorenz 75755dc6f81SAlex Lorenz static void printIRSlotNumber(raw_ostream &OS, int Slot) { 75855dc6f81SAlex Lorenz if (Slot == -1) 75955dc6f81SAlex Lorenz OS << "<badref>"; 76055dc6f81SAlex Lorenz else 76155dc6f81SAlex Lorenz OS << Slot; 76255dc6f81SAlex Lorenz } 76355dc6f81SAlex Lorenz 764deb53490SAlex Lorenz void MIPrinter::printIRBlockReference(const BasicBlock &BB) { 765deb53490SAlex Lorenz OS << "%ir-block."; 766deb53490SAlex Lorenz if (BB.hasName()) { 767deb53490SAlex Lorenz printLLVMNameWithoutPrefix(OS, BB.getName()); 768deb53490SAlex Lorenz return; 769deb53490SAlex Lorenz } 770cba8c5feSAlex Lorenz const Function *F = BB.getParent(); 771cba8c5feSAlex Lorenz int Slot; 772cba8c5feSAlex Lorenz if (F == MST.getCurrentFunction()) { 773cba8c5feSAlex Lorenz Slot = MST.getLocalSlot(&BB); 774cba8c5feSAlex Lorenz } else { 775cba8c5feSAlex Lorenz ModuleSlotTracker CustomMST(F->getParent(), 776cba8c5feSAlex Lorenz /*ShouldInitializeAllMetadata=*/false); 777cba8c5feSAlex Lorenz CustomMST.incorporateFunction(*F); 778cba8c5feSAlex Lorenz Slot = CustomMST.getLocalSlot(&BB); 779cba8c5feSAlex Lorenz } 78055dc6f81SAlex Lorenz printIRSlotNumber(OS, Slot); 781deb53490SAlex Lorenz } 782deb53490SAlex Lorenz 7834af7e610SAlex Lorenz void MIPrinter::printIRValueReference(const Value &V) { 78436efd388SAlex Lorenz if (isa<GlobalValue>(V)) { 78536efd388SAlex Lorenz V.printAsOperand(OS, /*PrintType=*/false, MST); 78636efd388SAlex Lorenz return; 78736efd388SAlex Lorenz } 788c1136ef3SAlex Lorenz if (isa<Constant>(V)) { 789c1136ef3SAlex Lorenz // Machine memory operands can load/store to/from constant value pointers. 790c1136ef3SAlex Lorenz OS << '`'; 791c1136ef3SAlex Lorenz V.printAsOperand(OS, /*PrintType=*/true, MST); 792c1136ef3SAlex Lorenz OS << '`'; 793c1136ef3SAlex Lorenz return; 794c1136ef3SAlex Lorenz } 7954af7e610SAlex Lorenz OS << "%ir."; 7964af7e610SAlex Lorenz if (V.hasName()) { 7974af7e610SAlex Lorenz printLLVMNameWithoutPrefix(OS, V.getName()); 7984af7e610SAlex Lorenz return; 7994af7e610SAlex Lorenz } 800dd13be0bSAlex Lorenz printIRSlotNumber(OS, MST.getLocalSlot(&V)); 8014af7e610SAlex Lorenz } 8024af7e610SAlex Lorenz 8037feaf7c6SAlex Lorenz void MIPrinter::printStackObjectReference(int FrameIndex) { 8047feaf7c6SAlex Lorenz auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex); 8057feaf7c6SAlex Lorenz assert(ObjectInfo != StackObjectOperandMapping.end() && 8067feaf7c6SAlex Lorenz "Invalid frame index"); 8077feaf7c6SAlex Lorenz const FrameIndexOperand &Operand = ObjectInfo->second; 8087feaf7c6SAlex Lorenz if (Operand.IsFixed) { 8097feaf7c6SAlex Lorenz OS << "%fixed-stack." << Operand.ID; 8107feaf7c6SAlex Lorenz return; 8117feaf7c6SAlex Lorenz } 8127feaf7c6SAlex Lorenz OS << "%stack." << Operand.ID; 8137feaf7c6SAlex Lorenz if (!Operand.Name.empty()) 8147feaf7c6SAlex Lorenz OS << '.' << Operand.Name; 8157feaf7c6SAlex Lorenz } 8167feaf7c6SAlex Lorenz 8175672a893SAlex Lorenz void MIPrinter::printOffset(int64_t Offset) { 8185672a893SAlex Lorenz if (Offset == 0) 8195672a893SAlex Lorenz return; 8205672a893SAlex Lorenz if (Offset < 0) { 8215672a893SAlex Lorenz OS << " - " << -Offset; 8225672a893SAlex Lorenz return; 8235672a893SAlex Lorenz } 8245672a893SAlex Lorenz OS << " + " << Offset; 8255672a893SAlex Lorenz } 8265672a893SAlex Lorenz 82749873a83SAlex Lorenz static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) { 82849873a83SAlex Lorenz auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); 82949873a83SAlex Lorenz for (const auto &I : Flags) { 83049873a83SAlex Lorenz if (I.first == TF) { 83149873a83SAlex Lorenz return I.second; 83249873a83SAlex Lorenz } 83349873a83SAlex Lorenz } 83449873a83SAlex Lorenz return nullptr; 83549873a83SAlex Lorenz } 83649873a83SAlex Lorenz 83749873a83SAlex Lorenz void MIPrinter::printTargetFlags(const MachineOperand &Op) { 83849873a83SAlex Lorenz if (!Op.getTargetFlags()) 83949873a83SAlex Lorenz return; 84049873a83SAlex Lorenz const auto *TII = 84149873a83SAlex Lorenz Op.getParent()->getParent()->getParent()->getSubtarget().getInstrInfo(); 84249873a83SAlex Lorenz assert(TII && "expected instruction info"); 84349873a83SAlex Lorenz auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags()); 84449873a83SAlex Lorenz OS << "target-flags("; 845f3630113SAlex Lorenz const bool HasDirectFlags = Flags.first; 846f3630113SAlex Lorenz const bool HasBitmaskFlags = Flags.second; 847f3630113SAlex Lorenz if (!HasDirectFlags && !HasBitmaskFlags) { 848f3630113SAlex Lorenz OS << "<unknown>) "; 849f3630113SAlex Lorenz return; 850f3630113SAlex Lorenz } 851f3630113SAlex Lorenz if (HasDirectFlags) { 85249873a83SAlex Lorenz if (const auto *Name = getTargetFlagName(TII, Flags.first)) 85349873a83SAlex Lorenz OS << Name; 85449873a83SAlex Lorenz else 85549873a83SAlex Lorenz OS << "<unknown target flag>"; 856f3630113SAlex Lorenz } 857f3630113SAlex Lorenz if (!HasBitmaskFlags) { 858f3630113SAlex Lorenz OS << ") "; 859f3630113SAlex Lorenz return; 860f3630113SAlex Lorenz } 861f3630113SAlex Lorenz bool IsCommaNeeded = HasDirectFlags; 862f3630113SAlex Lorenz unsigned BitMask = Flags.second; 863f3630113SAlex Lorenz auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags(); 864f3630113SAlex Lorenz for (const auto &Mask : BitMasks) { 865f3630113SAlex Lorenz // Check if the flag's bitmask has the bits of the current mask set. 866f3630113SAlex Lorenz if ((BitMask & Mask.first) == Mask.first) { 867f3630113SAlex Lorenz if (IsCommaNeeded) 868f3630113SAlex Lorenz OS << ", "; 869f3630113SAlex Lorenz IsCommaNeeded = true; 870f3630113SAlex Lorenz OS << Mask.second; 871f3630113SAlex Lorenz // Clear the bits which were serialized from the flag's bitmask. 872f3630113SAlex Lorenz BitMask &= ~(Mask.first); 873f3630113SAlex Lorenz } 874f3630113SAlex Lorenz } 875f3630113SAlex Lorenz if (BitMask) { 876f3630113SAlex Lorenz // When the resulting flag's bitmask isn't zero, we know that we didn't 877f3630113SAlex Lorenz // serialize all of the bit flags. 878f3630113SAlex Lorenz if (IsCommaNeeded) 879f3630113SAlex Lorenz OS << ", "; 880f3630113SAlex Lorenz OS << "<unknown bitmask target flag>"; 881f3630113SAlex Lorenz } 88249873a83SAlex Lorenz OS << ") "; 88349873a83SAlex Lorenz } 88449873a83SAlex Lorenz 885ef5c196fSAlex Lorenz static const char *getTargetIndexName(const MachineFunction &MF, int Index) { 886ef5c196fSAlex Lorenz const auto *TII = MF.getSubtarget().getInstrInfo(); 887ef5c196fSAlex Lorenz assert(TII && "expected instruction info"); 888ef5c196fSAlex Lorenz auto Indices = TII->getSerializableTargetIndices(); 889ef5c196fSAlex Lorenz for (const auto &I : Indices) { 890ef5c196fSAlex Lorenz if (I.first == Index) { 891ef5c196fSAlex Lorenz return I.second; 892ef5c196fSAlex Lorenz } 893ef5c196fSAlex Lorenz } 894ef5c196fSAlex Lorenz return nullptr; 895ef5c196fSAlex Lorenz } 896ef5c196fSAlex Lorenz 897e66a7ccfSAlex Lorenz void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI, 898d28d3cc0STim Northover unsigned I, bool ShouldPrintRegisterTies, LLT TypeToPrint, 899d28d3cc0STim Northover bool IsDef) { 90049873a83SAlex Lorenz printTargetFlags(Op); 901f3db51deSAlex Lorenz switch (Op.getType()) { 902f3db51deSAlex Lorenz case MachineOperand::MO_Register: 903cb268d46SAlex Lorenz if (Op.isImplicit()) 904cb268d46SAlex Lorenz OS << (Op.isDef() ? "implicit-def " : "implicit "); 905e66a7ccfSAlex Lorenz else if (!IsDef && Op.isDef()) 906e66a7ccfSAlex Lorenz // Print the 'def' flag only when the operand is defined after '='. 907e66a7ccfSAlex Lorenz OS << "def "; 9081039fd1aSAlex Lorenz if (Op.isInternalRead()) 9091039fd1aSAlex Lorenz OS << "internal "; 910cbbfd0b1SAlex Lorenz if (Op.isDead()) 911cbbfd0b1SAlex Lorenz OS << "dead "; 912495ad879SAlex Lorenz if (Op.isKill()) 913495ad879SAlex Lorenz OS << "killed "; 9144d026b89SAlex Lorenz if (Op.isUndef()) 9154d026b89SAlex Lorenz OS << "undef "; 91601c1a5eeSAlex Lorenz if (Op.isEarlyClobber()) 91701c1a5eeSAlex Lorenz OS << "early-clobber "; 9189075258bSAlex Lorenz if (Op.isDebug()) 9199075258bSAlex Lorenz OS << "debug-use "; 920f3db51deSAlex Lorenz printReg(Op.getReg(), OS, TRI); 9212eacca86SAlex Lorenz // Print the sub register. 9222eacca86SAlex Lorenz if (Op.getSubReg() != 0) 923333e468dSMatthias Braun OS << '.' << TRI->getSubRegIndexName(Op.getSubReg()); 9245ef93b0cSAlex Lorenz if (ShouldPrintRegisterTies && Op.isTied() && !Op.isDef()) 9255ef93b0cSAlex Lorenz OS << "(tied-def " << Op.getParent()->findTiedOperandIdx(I) << ")"; 926d28d3cc0STim Northover if (TypeToPrint.isValid()) 927d28d3cc0STim Northover OS << '(' << TypeToPrint << ')'; 928f3db51deSAlex Lorenz break; 929240fc1e0SAlex Lorenz case MachineOperand::MO_Immediate: 930240fc1e0SAlex Lorenz OS << Op.getImm(); 931240fc1e0SAlex Lorenz break; 93205e3882eSAlex Lorenz case MachineOperand::MO_CImmediate: 93305e3882eSAlex Lorenz Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); 93405e3882eSAlex Lorenz break; 935ad156fb6SAlex Lorenz case MachineOperand::MO_FPImmediate: 936ad156fb6SAlex Lorenz Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); 937ad156fb6SAlex Lorenz break; 93833f0aef3SAlex Lorenz case MachineOperand::MO_MachineBasicBlock: 9395d26fa83SAlex Lorenz printMBBReference(*Op.getMBB()); 94033f0aef3SAlex Lorenz break; 9417feaf7c6SAlex Lorenz case MachineOperand::MO_FrameIndex: 9427feaf7c6SAlex Lorenz printStackObjectReference(Op.getIndex()); 9437feaf7c6SAlex Lorenz break; 944ab980499SAlex Lorenz case MachineOperand::MO_ConstantPoolIndex: 945ab980499SAlex Lorenz OS << "%const." << Op.getIndex(); 9465672a893SAlex Lorenz printOffset(Op.getOffset()); 947ab980499SAlex Lorenz break; 948fb69e66cSEugene Zelenko case MachineOperand::MO_TargetIndex: 949ef5c196fSAlex Lorenz OS << "target-index("; 950ef5c196fSAlex Lorenz if (const auto *Name = getTargetIndexName( 951ef5c196fSAlex Lorenz *Op.getParent()->getParent()->getParent(), Op.getIndex())) 952ef5c196fSAlex Lorenz OS << Name; 953ef5c196fSAlex Lorenz else 954ef5c196fSAlex Lorenz OS << "<unknown>"; 955ef5c196fSAlex Lorenz OS << ')'; 9565672a893SAlex Lorenz printOffset(Op.getOffset()); 957ef5c196fSAlex Lorenz break; 95831d70683SAlex Lorenz case MachineOperand::MO_JumpTableIndex: 95931d70683SAlex Lorenz OS << "%jump-table." << Op.getIndex(); 96031d70683SAlex Lorenz break; 9618b5f9e44SMatthias Braun case MachineOperand::MO_ExternalSymbol: { 9628b5f9e44SMatthias Braun StringRef Name = Op.getSymbolName(); 9636ede3744SAlex Lorenz OS << '$'; 9648b5f9e44SMatthias Braun if (Name.empty()) { 9658b5f9e44SMatthias Braun OS << "\"\""; 9668b5f9e44SMatthias Braun } else { 9678b5f9e44SMatthias Braun printLLVMNameWithoutPrefix(OS, Name); 9688b5f9e44SMatthias Braun } 9695672a893SAlex Lorenz printOffset(Op.getOffset()); 9706ede3744SAlex Lorenz break; 9718b5f9e44SMatthias Braun } 9725d6108e4SAlex Lorenz case MachineOperand::MO_GlobalAddress: 973900b5cb2SAlex Lorenz Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 9745672a893SAlex Lorenz printOffset(Op.getOffset()); 9755d6108e4SAlex Lorenz break; 976deb53490SAlex Lorenz case MachineOperand::MO_BlockAddress: 977deb53490SAlex Lorenz OS << "blockaddress("; 978deb53490SAlex Lorenz Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, 979deb53490SAlex Lorenz MST); 980deb53490SAlex Lorenz OS << ", "; 981deb53490SAlex Lorenz printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); 982deb53490SAlex Lorenz OS << ')'; 9835672a893SAlex Lorenz printOffset(Op.getOffset()); 984deb53490SAlex Lorenz break; 9858f6f4285SAlex Lorenz case MachineOperand::MO_RegisterMask: { 9868f6f4285SAlex Lorenz auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); 9878f6f4285SAlex Lorenz if (RegMaskInfo != RegisterMaskIds.end()) 9888f6f4285SAlex Lorenz OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); 9898f6f4285SAlex Lorenz else 9900ef61ec3SOren Ben Simhon printCustomRegMask(Op.getRegMask(), OS, TRI); 9918f6f4285SAlex Lorenz break; 9928f6f4285SAlex Lorenz } 993b97c9ef4SAlex Lorenz case MachineOperand::MO_RegisterLiveOut: { 994b97c9ef4SAlex Lorenz const uint32_t *RegMask = Op.getRegLiveOut(); 995b97c9ef4SAlex Lorenz OS << "liveout("; 996b97c9ef4SAlex Lorenz bool IsCommaNeeded = false; 997b97c9ef4SAlex Lorenz for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { 998b97c9ef4SAlex Lorenz if (RegMask[Reg / 32] & (1U << (Reg % 32))) { 999b97c9ef4SAlex Lorenz if (IsCommaNeeded) 1000b97c9ef4SAlex Lorenz OS << ", "; 1001b97c9ef4SAlex Lorenz printReg(Reg, OS, TRI); 1002b97c9ef4SAlex Lorenz IsCommaNeeded = true; 1003b97c9ef4SAlex Lorenz } 1004b97c9ef4SAlex Lorenz } 1005b97c9ef4SAlex Lorenz OS << ")"; 1006b97c9ef4SAlex Lorenz break; 1007b97c9ef4SAlex Lorenz } 100835e44469SAlex Lorenz case MachineOperand::MO_Metadata: 100935e44469SAlex Lorenz Op.getMetadata()->printAsOperand(OS, MST); 101035e44469SAlex Lorenz break; 1011f22ca8adSAlex Lorenz case MachineOperand::MO_MCSymbol: 1012f22ca8adSAlex Lorenz OS << "<mcsymbol " << *Op.getMCSymbol() << ">"; 1013f22ca8adSAlex Lorenz break; 1014f4baeb51SAlex Lorenz case MachineOperand::MO_CFIIndex: { 1015f23ef437SMatthias Braun const MachineFunction &MF = *Op.getParent()->getParent()->getParent(); 1016f23ef437SMatthias Braun print(MF.getFrameInstructions()[Op.getCFIIndex()], TRI); 1017f4baeb51SAlex Lorenz break; 1018f4baeb51SAlex Lorenz } 10196b3bd612STim Northover case MachineOperand::MO_IntrinsicID: { 10206b3bd612STim Northover Intrinsic::ID ID = Op.getIntrinsicID(); 10216b3bd612STim Northover if (ID < Intrinsic::num_intrinsics) 10221523925dSPete Cooper OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')'; 10236b3bd612STim Northover else { 10246b3bd612STim Northover const MachineFunction &MF = *Op.getParent()->getParent()->getParent(); 10256b3bd612STim Northover const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo(); 10266b3bd612STim Northover OS << "intrinsic(@" << TII->getName(ID) << ')'; 10276b3bd612STim Northover } 10286b3bd612STim Northover break; 10296b3bd612STim Northover } 1030de3aea04STim Northover case MachineOperand::MO_Predicate: { 1031de3aea04STim Northover auto Pred = static_cast<CmpInst::Predicate>(Op.getPredicate()); 1032de3aea04STim Northover OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred(" 1033de3aea04STim Northover << CmpInst::getPredicateName(Pred) << ')'; 1034de3aea04STim Northover break; 1035de3aea04STim Northover } 1036f3db51deSAlex Lorenz } 10374f093bf1SAlex Lorenz } 10384f093bf1SAlex Lorenz 1039*bb80d3e1SKonstantin Zhuravlyov void MIPrinter::print(const LLVMContext &Context, const MachineMemOperand &Op) { 10404af7e610SAlex Lorenz OS << '('; 1041dc8de2a6SAlex Lorenz // TODO: Print operand's target specific flags. 1042a518b796SAlex Lorenz if (Op.isVolatile()) 1043a518b796SAlex Lorenz OS << "volatile "; 104410fd0385SAlex Lorenz if (Op.isNonTemporal()) 104510fd0385SAlex Lorenz OS << "non-temporal "; 1046adbf09e8SJustin Lebar if (Op.isDereferenceable()) 1047adbf09e8SJustin Lebar OS << "dereferenceable "; 1048dc8de2a6SAlex Lorenz if (Op.isInvariant()) 1049dc8de2a6SAlex Lorenz OS << "invariant "; 10504af7e610SAlex Lorenz if (Op.isLoad()) 10514af7e610SAlex Lorenz OS << "load "; 10524af7e610SAlex Lorenz else { 10534af7e610SAlex Lorenz assert(Op.isStore() && "Non load machine operand must be a store"); 10544af7e610SAlex Lorenz OS << "store "; 10554af7e610SAlex Lorenz } 1056b73e3090STim Northover 1057*bb80d3e1SKonstantin Zhuravlyov printSyncScope(Context, Op.getSyncScopeID()); 1058b73e3090STim Northover 1059b73e3090STim Northover if (Op.getOrdering() != AtomicOrdering::NotAtomic) 1060b73e3090STim Northover OS << toIRString(Op.getOrdering()) << ' '; 1061b73e3090STim Northover if (Op.getFailureOrdering() != AtomicOrdering::NotAtomic) 1062b73e3090STim Northover OS << toIRString(Op.getFailureOrdering()) << ' '; 1063b73e3090STim Northover 1064c25c9ccbSMatthias Braun OS << Op.getSize(); 106591097a3fSAlex Lorenz if (const Value *Val = Op.getValue()) { 1066c25c9ccbSMatthias Braun OS << (Op.isLoad() ? " from " : " into "); 10674af7e610SAlex Lorenz printIRValueReference(*Val); 1068c25c9ccbSMatthias Braun } else if (const PseudoSourceValue *PVal = Op.getPseudoValue()) { 1069c25c9ccbSMatthias Braun OS << (Op.isLoad() ? " from " : " into "); 107091097a3fSAlex Lorenz assert(PVal && "Expected a pseudo source value"); 107191097a3fSAlex Lorenz switch (PVal->kind()) { 107246e9558aSAlex Lorenz case PseudoSourceValue::Stack: 107346e9558aSAlex Lorenz OS << "stack"; 107446e9558aSAlex Lorenz break; 1075d858f874SAlex Lorenz case PseudoSourceValue::GOT: 1076d858f874SAlex Lorenz OS << "got"; 1077d858f874SAlex Lorenz break; 10784be56e93SAlex Lorenz case PseudoSourceValue::JumpTable: 10794be56e93SAlex Lorenz OS << "jump-table"; 10804be56e93SAlex Lorenz break; 108191097a3fSAlex Lorenz case PseudoSourceValue::ConstantPool: 108291097a3fSAlex Lorenz OS << "constant-pool"; 108391097a3fSAlex Lorenz break; 10840cc671bfSAlex Lorenz case PseudoSourceValue::FixedStack: 10850cc671bfSAlex Lorenz printStackObjectReference( 10860cc671bfSAlex Lorenz cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex()); 10870cc671bfSAlex Lorenz break; 108850b826fbSAlex Lorenz case PseudoSourceValue::GlobalValueCallEntry: 10890d009645SAlex Lorenz OS << "call-entry "; 109050b826fbSAlex Lorenz cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand( 109150b826fbSAlex Lorenz OS, /*PrintType=*/false, MST); 109250b826fbSAlex Lorenz break; 1093c3ba7508SAlex Lorenz case PseudoSourceValue::ExternalSymbolCallEntry: 10940d009645SAlex Lorenz OS << "call-entry $"; 1095c3ba7508SAlex Lorenz printLLVMNameWithoutPrefix( 1096c3ba7508SAlex Lorenz OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol()); 109791097a3fSAlex Lorenz break; 10987761abb6STom Stellard case PseudoSourceValue::TargetCustom: 10997761abb6STom Stellard llvm_unreachable("TargetCustom pseudo source values are not supported"); 11007761abb6STom Stellard break; 110191097a3fSAlex Lorenz } 110291097a3fSAlex Lorenz } 110383127739SAlex Lorenz printOffset(Op.getOffset()); 110461420f79SAlex Lorenz if (Op.getBaseAlignment() != Op.getSize()) 110561420f79SAlex Lorenz OS << ", align " << Op.getBaseAlignment(); 1106a617c916SAlex Lorenz auto AAInfo = Op.getAAInfo(); 1107a617c916SAlex Lorenz if (AAInfo.TBAA) { 1108a617c916SAlex Lorenz OS << ", !tbaa "; 1109a617c916SAlex Lorenz AAInfo.TBAA->printAsOperand(OS, MST); 1110a617c916SAlex Lorenz } 1111a16f624dSAlex Lorenz if (AAInfo.Scope) { 1112a16f624dSAlex Lorenz OS << ", !alias.scope "; 1113a16f624dSAlex Lorenz AAInfo.Scope->printAsOperand(OS, MST); 1114a16f624dSAlex Lorenz } 111503e940d1SAlex Lorenz if (AAInfo.NoAlias) { 111603e940d1SAlex Lorenz OS << ", !noalias "; 111703e940d1SAlex Lorenz AAInfo.NoAlias->printAsOperand(OS, MST); 111803e940d1SAlex Lorenz } 1119eb625686SAlex Lorenz if (Op.getRanges()) { 1120eb625686SAlex Lorenz OS << ", !range "; 1121eb625686SAlex Lorenz Op.getRanges()->printAsOperand(OS, MST); 1122eb625686SAlex Lorenz } 11234af7e610SAlex Lorenz OS << ')'; 11244af7e610SAlex Lorenz } 11254af7e610SAlex Lorenz 1126*bb80d3e1SKonstantin Zhuravlyov void MIPrinter::printSyncScope(const LLVMContext &Context, SyncScope::ID SSID) { 1127*bb80d3e1SKonstantin Zhuravlyov switch (SSID) { 1128*bb80d3e1SKonstantin Zhuravlyov case SyncScope::System: { 1129*bb80d3e1SKonstantin Zhuravlyov break; 1130*bb80d3e1SKonstantin Zhuravlyov } 1131*bb80d3e1SKonstantin Zhuravlyov default: { 1132*bb80d3e1SKonstantin Zhuravlyov if (SSNs.empty()) 1133*bb80d3e1SKonstantin Zhuravlyov Context.getSyncScopeNames(SSNs); 1134*bb80d3e1SKonstantin Zhuravlyov 1135*bb80d3e1SKonstantin Zhuravlyov OS << "syncscope(\""; 1136*bb80d3e1SKonstantin Zhuravlyov PrintEscapedString(SSNs[SSID], OS); 1137*bb80d3e1SKonstantin Zhuravlyov OS << "\") "; 1138*bb80d3e1SKonstantin Zhuravlyov break; 1139*bb80d3e1SKonstantin Zhuravlyov } 1140*bb80d3e1SKonstantin Zhuravlyov } 1141*bb80d3e1SKonstantin Zhuravlyov } 1142*bb80d3e1SKonstantin Zhuravlyov 11438cfc6867SAlex Lorenz static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS, 11448cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 11458cfc6867SAlex Lorenz int Reg = TRI->getLLVMRegNum(DwarfReg, true); 11468cfc6867SAlex Lorenz if (Reg == -1) { 11478cfc6867SAlex Lorenz OS << "<badreg>"; 11488cfc6867SAlex Lorenz return; 11498cfc6867SAlex Lorenz } 11508cfc6867SAlex Lorenz printReg(Reg, OS, TRI); 11518cfc6867SAlex Lorenz } 11528cfc6867SAlex Lorenz 11538cfc6867SAlex Lorenz void MIPrinter::print(const MCCFIInstruction &CFI, 11548cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 1155f4baeb51SAlex Lorenz switch (CFI.getOperation()) { 1156577d271aSAlex Lorenz case MCCFIInstruction::OpSameValue: 1157ee067920SMatthias Braun OS << "same_value "; 1158577d271aSAlex Lorenz if (CFI.getLabel()) 1159577d271aSAlex Lorenz OS << "<mcsymbol> "; 1160577d271aSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 1161577d271aSAlex Lorenz break; 11628cfc6867SAlex Lorenz case MCCFIInstruction::OpOffset: 1163ee067920SMatthias Braun OS << "offset "; 11648cfc6867SAlex Lorenz if (CFI.getLabel()) 11658cfc6867SAlex Lorenz OS << "<mcsymbol> "; 11668cfc6867SAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 11678cfc6867SAlex Lorenz OS << ", " << CFI.getOffset(); 11688cfc6867SAlex Lorenz break; 11695b0d5f6fSAlex Lorenz case MCCFIInstruction::OpDefCfaRegister: 1170ee067920SMatthias Braun OS << "def_cfa_register "; 11715b0d5f6fSAlex Lorenz if (CFI.getLabel()) 11725b0d5f6fSAlex Lorenz OS << "<mcsymbol> "; 11735b0d5f6fSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 11745b0d5f6fSAlex Lorenz break; 1175f4baeb51SAlex Lorenz case MCCFIInstruction::OpDefCfaOffset: 1176ee067920SMatthias Braun OS << "def_cfa_offset "; 1177f4baeb51SAlex Lorenz if (CFI.getLabel()) 1178f4baeb51SAlex Lorenz OS << "<mcsymbol> "; 1179f4baeb51SAlex Lorenz OS << CFI.getOffset(); 1180f4baeb51SAlex Lorenz break; 1181b139323fSAlex Lorenz case MCCFIInstruction::OpDefCfa: 1182ee067920SMatthias Braun OS << "def_cfa "; 1183b139323fSAlex Lorenz if (CFI.getLabel()) 1184b139323fSAlex Lorenz OS << "<mcsymbol> "; 1185b139323fSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 1186b139323fSAlex Lorenz OS << ", " << CFI.getOffset(); 1187b139323fSAlex Lorenz break; 1188f4baeb51SAlex Lorenz default: 1189f4baeb51SAlex Lorenz // TODO: Print the other CFI Operations. 1190f4baeb51SAlex Lorenz OS << "<unserializable cfi operation>"; 1191f4baeb51SAlex Lorenz break; 1192f4baeb51SAlex Lorenz } 1193f4baeb51SAlex Lorenz } 1194f4baeb51SAlex Lorenz 1195345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) { 1196345c1449SAlex Lorenz yaml::Output Out(OS); 1197345c1449SAlex Lorenz Out << const_cast<Module &>(M); 1198345c1449SAlex Lorenz } 1199345c1449SAlex Lorenz 1200345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) { 1201345c1449SAlex Lorenz MIRPrinter Printer(OS); 1202345c1449SAlex Lorenz Printer.print(MF); 1203345c1449SAlex Lorenz } 1204