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 153f833edcSDavid Blaikie #include "llvm/CodeGen/MIRPrinter.h" 16fb69e66cSEugene Zelenko #include "llvm/ADT/DenseMap.h" 17fb69e66cSEugene Zelenko #include "llvm/ADT/None.h" 183f833edcSDavid Blaikie #include "llvm/ADT/STLExtras.h" 19d28d3cc0STim Northover #include "llvm/ADT/SmallBitVector.h" 20fb69e66cSEugene Zelenko #include "llvm/ADT/SmallPtrSet.h" 21fb69e66cSEugene Zelenko #include "llvm/ADT/SmallVector.h" 22bb80d3e1SKonstantin Zhuravlyov #include "llvm/ADT/StringExtras.h" 23fb69e66cSEugene Zelenko #include "llvm/ADT/StringRef.h" 24fb69e66cSEugene Zelenko #include "llvm/ADT/Twine.h" 25fab1cfe6SQuentin Colombet #include "llvm/CodeGen/GlobalISel/RegisterBank.h" 263f833edcSDavid Blaikie #include "llvm/CodeGen/MIRYamlMapping.h" 27fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineBasicBlock.h" 28ab980499SAlex Lorenz #include "llvm/CodeGen/MachineConstantPool.h" 2960541c1dSAlex Lorenz #include "llvm/CodeGen/MachineFrameInfo.h" 30fab1cfe6SQuentin Colombet #include "llvm/CodeGen/MachineFunction.h" 31fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineInstr.h" 32fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineJumpTableInfo.h" 334af7e610SAlex Lorenz #include "llvm/CodeGen/MachineMemOperand.h" 34fb69e66cSEugene Zelenko #include "llvm/CodeGen/MachineOperand.h" 3554565cf0SAlex Lorenz #include "llvm/CodeGen/MachineRegisterInfo.h" 36fb69e66cSEugene Zelenko #include "llvm/CodeGen/PseudoSourceValue.h" 373f833edcSDavid Blaikie #include "llvm/CodeGen/TargetInstrInfo.h" 38*b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h" 39*b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h" 404f093bf1SAlex Lorenz #include "llvm/IR/BasicBlock.h" 41deb53490SAlex Lorenz #include "llvm/IR/Constants.h" 4228865809SReid Kleckner #include "llvm/IR/DebugInfo.h" 43fb69e66cSEugene Zelenko #include "llvm/IR/DebugLoc.h" 44fb69e66cSEugene Zelenko #include "llvm/IR/Function.h" 45fb69e66cSEugene Zelenko #include "llvm/IR/GlobalValue.h" 463f833edcSDavid Blaikie #include "llvm/IR/IRPrintingPasses.h" 47fb69e66cSEugene Zelenko #include "llvm/IR/InstrTypes.h" 48fab1cfe6SQuentin Colombet #include "llvm/IR/Instructions.h" 496b3bd612STim Northover #include "llvm/IR/Intrinsics.h" 50345c1449SAlex Lorenz #include "llvm/IR/Module.h" 51900b5cb2SAlex Lorenz #include "llvm/IR/ModuleSlotTracker.h" 52fb69e66cSEugene Zelenko #include "llvm/IR/Value.h" 53fb69e66cSEugene Zelenko #include "llvm/MC/LaneBitmask.h" 54fb69e66cSEugene Zelenko #include "llvm/MC/MCDwarf.h" 55f22ca8adSAlex Lorenz #include "llvm/MC/MCSymbol.h" 56fb69e66cSEugene Zelenko #include "llvm/Support/AtomicOrdering.h" 57fb69e66cSEugene Zelenko #include "llvm/Support/BranchProbability.h" 58fb69e66cSEugene Zelenko #include "llvm/Support/Casting.h" 59fb69e66cSEugene Zelenko #include "llvm/Support/CommandLine.h" 60fb69e66cSEugene Zelenko #include "llvm/Support/ErrorHandling.h" 61b51774acSGeoff Berry #include "llvm/Support/Format.h" 62fb69e66cSEugene Zelenko #include "llvm/Support/LowLevelTypeImpl.h" 63fb69e66cSEugene Zelenko #include "llvm/Support/YAMLTraits.h" 643f833edcSDavid Blaikie #include "llvm/Support/raw_ostream.h" 656b3bd612STim Northover #include "llvm/Target/TargetIntrinsicInfo.h" 66fb69e66cSEugene Zelenko #include "llvm/Target/TargetMachine.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); 165a42ed3e3SBjorn Pettersson void print(const MachineInstr &MI, unsigned OpIdx, 166a42ed3e3SBjorn Pettersson const TargetRegisterInfo *TRI, bool ShouldPrintRegisterTies, 167d28d3cc0STim Northover LLT TypeToPrint, bool IsDef = false); 1686748abe2SGeoff Berry void print(const LLVMContext &Context, const TargetInstrInfo &TII, 1696748abe2SGeoff 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 2736c452834SJustin Bogner static void printRegClassOrBank(unsigned Reg, raw_ostream &OS, 2746c452834SJustin Bogner const MachineRegisterInfo &RegInfo, 2756c452834SJustin Bogner const TargetRegisterInfo *TRI) { 2766c452834SJustin Bogner if (RegInfo.getRegClassOrNull(Reg)) 2776c452834SJustin Bogner OS << StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower(); 2786c452834SJustin Bogner else if (RegInfo.getRegBankOrNull(Reg)) 2796c452834SJustin Bogner OS << StringRef(RegInfo.getRegBankOrNull(Reg)->getName()).lower(); 2806c452834SJustin Bogner else { 2816c452834SJustin Bogner OS << "_"; 2826c452834SJustin Bogner assert((RegInfo.def_empty(Reg) || RegInfo.getType(Reg).isValid()) && 2836c452834SJustin Bogner "Generic registers must have a valid type"); 2846c452834SJustin Bogner } 2856c452834SJustin Bogner } 2866c452834SJustin Bogner 2876c452834SJustin Bogner static void printRegClassOrBank(unsigned Reg, yaml::StringValue &Dest, 2886c452834SJustin Bogner const MachineRegisterInfo &RegInfo, 2896c452834SJustin Bogner const TargetRegisterInfo *TRI) { 2906c452834SJustin Bogner raw_string_ostream OS(Dest.Value); 2916c452834SJustin Bogner printRegClassOrBank(Reg, OS, RegInfo, TRI); 2926c452834SJustin Bogner } 2936c452834SJustin Bogner 2946c452834SJustin Bogner 29554565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 29628148ba8SAlex Lorenz const MachineRegisterInfo &RegInfo, 29728148ba8SAlex Lorenz const TargetRegisterInfo *TRI) { 29854565cf0SAlex Lorenz MF.TracksRegLiveness = RegInfo.tracksLiveness(); 29928148ba8SAlex Lorenz 30028148ba8SAlex Lorenz // Print the virtual register definitions. 30128148ba8SAlex Lorenz for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) { 30228148ba8SAlex Lorenz unsigned Reg = TargetRegisterInfo::index2VirtReg(I); 30328148ba8SAlex Lorenz yaml::VirtualRegisterDefinition VReg; 30428148ba8SAlex Lorenz VReg.ID = I; 3056c452834SJustin Bogner printRegClassOrBank(Reg, VReg.Class, RegInfo, TRI); 306ab4cbcfdSAlex Lorenz unsigned PreferredReg = RegInfo.getSimpleHint(Reg); 307ab4cbcfdSAlex Lorenz if (PreferredReg) 308ab4cbcfdSAlex Lorenz printReg(PreferredReg, VReg.PreferredRegister, TRI); 30928148ba8SAlex Lorenz MF.VirtualRegisters.push_back(VReg); 31028148ba8SAlex Lorenz } 31112045a4bSAlex Lorenz 31212045a4bSAlex Lorenz // Print the live ins. 31372518eaaSKrzysztof Parzyszek for (std::pair<unsigned, unsigned> LI : RegInfo.liveins()) { 31412045a4bSAlex Lorenz yaml::MachineFunctionLiveIn LiveIn; 31572518eaaSKrzysztof Parzyszek printReg(LI.first, LiveIn.Register, TRI); 31672518eaaSKrzysztof Parzyszek if (LI.second) 31772518eaaSKrzysztof Parzyszek printReg(LI.second, LiveIn.VirtualRegister, TRI); 31812045a4bSAlex Lorenz MF.LiveIns.push_back(LiveIn); 31912045a4bSAlex Lorenz } 3200ef61ec3SOren Ben Simhon 3210ef61ec3SOren Ben Simhon // Prints the callee saved registers. 3220ef61ec3SOren Ben Simhon if (RegInfo.isUpdatedCSRsInitialized()) { 3230ef61ec3SOren Ben Simhon const MCPhysReg *CalleeSavedRegs = RegInfo.getCalleeSavedRegs(); 324c4838087SAlex Lorenz std::vector<yaml::FlowStringValue> CalleeSavedRegisters; 3250ef61ec3SOren Ben Simhon for (const MCPhysReg *I = CalleeSavedRegs; *I; ++I) { 326c4838087SAlex Lorenz yaml::FlowStringValue Reg; 3270ef61ec3SOren Ben Simhon printReg(*I, Reg, TRI); 328c4838087SAlex Lorenz CalleeSavedRegisters.push_back(Reg); 329c4838087SAlex Lorenz } 330c4838087SAlex Lorenz MF.CalleeSavedRegisters = CalleeSavedRegisters; 33154565cf0SAlex Lorenz } 3320ef61ec3SOren Ben Simhon } 33354565cf0SAlex Lorenz 334a6f9a37dSAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 335a6f9a37dSAlex Lorenz yaml::MachineFrameInfo &YamlMFI, 33660541c1dSAlex Lorenz const MachineFrameInfo &MFI) { 33760541c1dSAlex Lorenz YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken(); 33860541c1dSAlex Lorenz YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken(); 33960541c1dSAlex Lorenz YamlMFI.HasStackMap = MFI.hasStackMap(); 34060541c1dSAlex Lorenz YamlMFI.HasPatchPoint = MFI.hasPatchPoint(); 34160541c1dSAlex Lorenz YamlMFI.StackSize = MFI.getStackSize(); 34260541c1dSAlex Lorenz YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment(); 34360541c1dSAlex Lorenz YamlMFI.MaxAlignment = MFI.getMaxAlignment(); 34460541c1dSAlex Lorenz YamlMFI.AdjustsStack = MFI.adjustsStack(); 34560541c1dSAlex Lorenz YamlMFI.HasCalls = MFI.hasCalls(); 346ab9438cbSMatthias Braun YamlMFI.MaxCallFrameSize = MFI.isMaxCallFrameSizeComputed() 347ab9438cbSMatthias Braun ? MFI.getMaxCallFrameSize() : ~0u; 34860541c1dSAlex Lorenz YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment(); 34960541c1dSAlex Lorenz YamlMFI.HasVAStart = MFI.hasVAStart(); 35060541c1dSAlex Lorenz YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc(); 351a6f9a37dSAlex Lorenz if (MFI.getSavePoint()) { 352a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.SavePoint.Value); 353a6f9a37dSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 354a6f9a37dSAlex Lorenz .printMBBReference(*MFI.getSavePoint()); 355a6f9a37dSAlex Lorenz } 356a6f9a37dSAlex Lorenz if (MFI.getRestorePoint()) { 357a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.RestorePoint.Value); 358a6f9a37dSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 359a6f9a37dSAlex Lorenz .printMBBReference(*MFI.getRestorePoint()); 360a6f9a37dSAlex Lorenz } 36160541c1dSAlex Lorenz } 36260541c1dSAlex Lorenz 363ef331effSMatthias Braun void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF, 364ef331effSMatthias Braun const MachineFunction &MF, 365ef331effSMatthias Braun ModuleSlotTracker &MST) { 366ef331effSMatthias Braun const MachineFrameInfo &MFI = MF.getFrameInfo(); 367ef331effSMatthias Braun const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 368de491f05SAlex Lorenz // Process fixed stack objects. 369f6bc8667SAlex Lorenz unsigned ID = 0; 370de491f05SAlex Lorenz for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) { 371de491f05SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 372de491f05SAlex Lorenz continue; 373de491f05SAlex Lorenz 374de491f05SAlex Lorenz yaml::FixedMachineStackObject YamlObject; 3757feaf7c6SAlex Lorenz YamlObject.ID = ID; 376de491f05SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 377de491f05SAlex Lorenz ? yaml::FixedMachineStackObject::SpillSlot 378de491f05SAlex Lorenz : yaml::FixedMachineStackObject::DefaultType; 379de491f05SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 380de491f05SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 381de491f05SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 382db78273bSMatt Arsenault YamlObject.StackID = MFI.getStackID(I); 383de491f05SAlex Lorenz YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I); 384de491f05SAlex Lorenz YamlObject.IsAliased = MFI.isAliasedObjectIndex(I); 385ef331effSMatthias Braun YMF.FixedStackObjects.push_back(YamlObject); 3867feaf7c6SAlex Lorenz StackObjectOperandMapping.insert( 3877feaf7c6SAlex Lorenz std::make_pair(I, FrameIndexOperand::createFixed(ID++))); 388de491f05SAlex Lorenz } 389de491f05SAlex Lorenz 390de491f05SAlex Lorenz // Process ordinary stack objects. 391de491f05SAlex Lorenz ID = 0; 392f6bc8667SAlex Lorenz for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) { 393f6bc8667SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 394f6bc8667SAlex Lorenz continue; 395f6bc8667SAlex Lorenz 396f6bc8667SAlex Lorenz yaml::MachineStackObject YamlObject; 3977feaf7c6SAlex Lorenz YamlObject.ID = ID; 39837643a04SAlex Lorenz if (const auto *Alloca = MFI.getObjectAllocation(I)) 39937643a04SAlex Lorenz YamlObject.Name.Value = 40037643a04SAlex Lorenz Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>"; 401f6bc8667SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 402f6bc8667SAlex Lorenz ? yaml::MachineStackObject::SpillSlot 403418f3ec1SAlex Lorenz : MFI.isVariableSizedObjectIndex(I) 404418f3ec1SAlex Lorenz ? yaml::MachineStackObject::VariableSized 405f6bc8667SAlex Lorenz : yaml::MachineStackObject::DefaultType; 406f6bc8667SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 407f6bc8667SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 408f6bc8667SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 409db78273bSMatt Arsenault YamlObject.StackID = MFI.getStackID(I); 410f6bc8667SAlex Lorenz 411ef331effSMatthias Braun YMF.StackObjects.push_back(YamlObject); 4127feaf7c6SAlex Lorenz StackObjectOperandMapping.insert(std::make_pair( 4137feaf7c6SAlex Lorenz I, FrameIndexOperand::create(YamlObject.Name.Value, ID++))); 414f6bc8667SAlex Lorenz } 4151bb48de1SAlex Lorenz 4161bb48de1SAlex Lorenz for (const auto &CSInfo : MFI.getCalleeSavedInfo()) { 4171bb48de1SAlex Lorenz yaml::StringValue Reg; 4181bb48de1SAlex Lorenz printReg(CSInfo.getReg(), Reg, TRI); 4191bb48de1SAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx()); 4201bb48de1SAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 4211bb48de1SAlex Lorenz "Invalid stack object index"); 4221bb48de1SAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 4235c3e8a45SMatthias Braun if (StackObject.IsFixed) { 424ef331effSMatthias Braun YMF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg; 4255c3e8a45SMatthias Braun YMF.FixedStackObjects[StackObject.ID].CalleeSavedRestored = 4265c3e8a45SMatthias Braun CSInfo.isRestored(); 4275c3e8a45SMatthias Braun } else { 428ef331effSMatthias Braun YMF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg; 4295c3e8a45SMatthias Braun YMF.StackObjects[StackObject.ID].CalleeSavedRestored = 4305c3e8a45SMatthias Braun CSInfo.isRestored(); 4315c3e8a45SMatthias Braun } 4321bb48de1SAlex Lorenz } 433a56ba6a6SAlex Lorenz for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) { 434a56ba6a6SAlex Lorenz auto LocalObject = MFI.getLocalFrameObjectMap(I); 435a56ba6a6SAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(LocalObject.first); 436a56ba6a6SAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 437a56ba6a6SAlex Lorenz "Invalid stack object index"); 438a56ba6a6SAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 439a56ba6a6SAlex Lorenz assert(!StackObject.IsFixed && "Expected a locally mapped stack object"); 440ef331effSMatthias Braun YMF.StackObjects[StackObject.ID].LocalOffset = LocalObject.second; 441a56ba6a6SAlex Lorenz } 442a314d813SAlex Lorenz 443a314d813SAlex Lorenz // Print the stack object references in the frame information class after 444a314d813SAlex Lorenz // converting the stack objects. 445a314d813SAlex Lorenz if (MFI.hasStackProtectorIndex()) { 446ef331effSMatthias Braun raw_string_ostream StrOS(YMF.FrameInfo.StackProtector.Value); 447a314d813SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 448a314d813SAlex Lorenz .printStackObjectReference(MFI.getStackProtectorIndex()); 449a314d813SAlex Lorenz } 450df9e3c6fSAlex Lorenz 451df9e3c6fSAlex Lorenz // Print the debug variable information. 452ef331effSMatthias Braun for (const MachineFunction::VariableDbgInfo &DebugVar : 453ef331effSMatthias Braun MF.getVariableDbgInfo()) { 454df9e3c6fSAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(DebugVar.Slot); 455df9e3c6fSAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 456df9e3c6fSAlex Lorenz "Invalid stack object index"); 457df9e3c6fSAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 458df9e3c6fSAlex Lorenz assert(!StackObject.IsFixed && "Expected a non-fixed stack object"); 459ef331effSMatthias Braun auto &Object = YMF.StackObjects[StackObject.ID]; 460df9e3c6fSAlex Lorenz { 461df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugVar.Value); 462df9e3c6fSAlex Lorenz DebugVar.Var->printAsOperand(StrOS, MST); 463df9e3c6fSAlex Lorenz } 464df9e3c6fSAlex Lorenz { 465df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugExpr.Value); 466df9e3c6fSAlex Lorenz DebugVar.Expr->printAsOperand(StrOS, MST); 467df9e3c6fSAlex Lorenz } 468df9e3c6fSAlex Lorenz { 469df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugLoc.Value); 470df9e3c6fSAlex Lorenz DebugVar.Loc->printAsOperand(StrOS, MST); 471df9e3c6fSAlex Lorenz } 472df9e3c6fSAlex Lorenz } 473f6bc8667SAlex Lorenz } 474f6bc8667SAlex Lorenz 475ab980499SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 476ab980499SAlex Lorenz const MachineConstantPool &ConstantPool) { 477ab980499SAlex Lorenz unsigned ID = 0; 478ab980499SAlex Lorenz for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) { 479ab980499SAlex Lorenz std::string Str; 480ab980499SAlex Lorenz raw_string_ostream StrOS(Str); 481d5a00b0fSDiana Picus if (Constant.isMachineConstantPoolEntry()) { 482d5a00b0fSDiana Picus Constant.Val.MachineCPVal->print(StrOS); 483d5a00b0fSDiana Picus } else { 484ab980499SAlex Lorenz Constant.Val.ConstVal->printAsOperand(StrOS); 485d5a00b0fSDiana Picus } 486d5a00b0fSDiana Picus 487d5a00b0fSDiana Picus yaml::MachineConstantPoolValue YamlConstant; 488ab980499SAlex Lorenz YamlConstant.ID = ID++; 489ab980499SAlex Lorenz YamlConstant.Value = StrOS.str(); 490ab980499SAlex Lorenz YamlConstant.Alignment = Constant.getAlignment(); 491d5a00b0fSDiana Picus YamlConstant.IsTargetSpecific = Constant.isMachineConstantPoolEntry(); 492d5a00b0fSDiana Picus 493ab980499SAlex Lorenz MF.Constants.push_back(YamlConstant); 494ab980499SAlex Lorenz } 495ab980499SAlex Lorenz } 496ab980499SAlex Lorenz 497900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 4986799e9b3SAlex Lorenz yaml::MachineJumpTable &YamlJTI, 4996799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI) { 5006799e9b3SAlex Lorenz YamlJTI.Kind = JTI.getEntryKind(); 5016799e9b3SAlex Lorenz unsigned ID = 0; 5026799e9b3SAlex Lorenz for (const auto &Table : JTI.getJumpTables()) { 5036799e9b3SAlex Lorenz std::string Str; 5046799e9b3SAlex Lorenz yaml::MachineJumpTable::Entry Entry; 5056799e9b3SAlex Lorenz Entry.ID = ID++; 5066799e9b3SAlex Lorenz for (const auto *MBB : Table.MBBs) { 5076799e9b3SAlex Lorenz raw_string_ostream StrOS(Str); 5087feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 5097feaf7c6SAlex Lorenz .printMBBReference(*MBB); 5106799e9b3SAlex Lorenz Entry.Blocks.push_back(StrOS.str()); 5116799e9b3SAlex Lorenz Str.clear(); 5126799e9b3SAlex Lorenz } 5136799e9b3SAlex Lorenz YamlJTI.Entries.push_back(Entry); 5146799e9b3SAlex Lorenz } 5156799e9b3SAlex Lorenz } 5166799e9b3SAlex Lorenz 5178f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) { 5188f6f4285SAlex Lorenz const auto *TRI = MF.getSubtarget().getRegisterInfo(); 5198f6f4285SAlex Lorenz unsigned I = 0; 5208f6f4285SAlex Lorenz for (const uint32_t *Mask : TRI->getRegMasks()) 5218f6f4285SAlex Lorenz RegisterMaskIds.insert(std::make_pair(Mask, I++)); 5228f6f4285SAlex Lorenz } 5238f6f4285SAlex Lorenz 5248940114fSMatthias Braun void llvm::guessSuccessors(const MachineBasicBlock &MBB, 5258940114fSMatthias Braun SmallVectorImpl<MachineBasicBlock*> &Result, 5268940114fSMatthias Braun bool &IsFallthrough) { 5278940114fSMatthias Braun SmallPtrSet<MachineBasicBlock*,8> Seen; 5288940114fSMatthias Braun 5298940114fSMatthias Braun for (const MachineInstr &MI : MBB) { 5308940114fSMatthias Braun if (MI.isPHI()) 5318940114fSMatthias Braun continue; 5328940114fSMatthias Braun for (const MachineOperand &MO : MI.operands()) { 5338940114fSMatthias Braun if (!MO.isMBB()) 5348940114fSMatthias Braun continue; 5358940114fSMatthias Braun MachineBasicBlock *Succ = MO.getMBB(); 5368940114fSMatthias Braun auto RP = Seen.insert(Succ); 5378940114fSMatthias Braun if (RP.second) 5388940114fSMatthias Braun Result.push_back(Succ); 5398940114fSMatthias Braun } 5408940114fSMatthias Braun } 5418940114fSMatthias Braun MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr(); 5428940114fSMatthias Braun IsFallthrough = I == MBB.end() || !I->isBarrier(); 5438940114fSMatthias Braun } 5448940114fSMatthias Braun 5458940114fSMatthias Braun bool 5468940114fSMatthias Braun MIPrinter::canPredictBranchProbabilities(const MachineBasicBlock &MBB) const { 5478940114fSMatthias Braun if (MBB.succ_size() <= 1) 5488940114fSMatthias Braun return true; 5498940114fSMatthias Braun if (!MBB.hasSuccessorProbabilities()) 5508940114fSMatthias Braun return true; 5518940114fSMatthias Braun 5528940114fSMatthias Braun SmallVector<BranchProbability,8> Normalized(MBB.Probs.begin(), 5538940114fSMatthias Braun MBB.Probs.end()); 5548940114fSMatthias Braun BranchProbability::normalizeProbabilities(Normalized.begin(), 5558940114fSMatthias Braun Normalized.end()); 5568940114fSMatthias Braun SmallVector<BranchProbability,8> Equal(Normalized.size()); 5578940114fSMatthias Braun BranchProbability::normalizeProbabilities(Equal.begin(), Equal.end()); 5588940114fSMatthias Braun 5598940114fSMatthias Braun return std::equal(Normalized.begin(), Normalized.end(), Equal.begin()); 5608940114fSMatthias Braun } 5618940114fSMatthias Braun 5628940114fSMatthias Braun bool MIPrinter::canPredictSuccessors(const MachineBasicBlock &MBB) const { 5638940114fSMatthias Braun SmallVector<MachineBasicBlock*,8> GuessedSuccs; 5648940114fSMatthias Braun bool GuessedFallthrough; 5658940114fSMatthias Braun guessSuccessors(MBB, GuessedSuccs, GuessedFallthrough); 5668940114fSMatthias Braun if (GuessedFallthrough) { 5678940114fSMatthias Braun const MachineFunction &MF = *MBB.getParent(); 5688940114fSMatthias Braun MachineFunction::const_iterator NextI = std::next(MBB.getIterator()); 5698940114fSMatthias Braun if (NextI != MF.end()) { 5708940114fSMatthias Braun MachineBasicBlock *Next = const_cast<MachineBasicBlock*>(&*NextI); 5718940114fSMatthias Braun if (!is_contained(GuessedSuccs, Next)) 5728940114fSMatthias Braun GuessedSuccs.push_back(Next); 5738940114fSMatthias Braun } 5748940114fSMatthias Braun } 5758940114fSMatthias Braun if (GuessedSuccs.size() != MBB.succ_size()) 5768940114fSMatthias Braun return false; 5778940114fSMatthias Braun return std::equal(MBB.succ_begin(), MBB.succ_end(), GuessedSuccs.begin()); 5788940114fSMatthias Braun } 5798940114fSMatthias Braun 5805022f6bbSAlex Lorenz void MIPrinter::print(const MachineBasicBlock &MBB) { 5815022f6bbSAlex Lorenz assert(MBB.getNumber() >= 0 && "Invalid MBB number"); 5825022f6bbSAlex Lorenz OS << "bb." << MBB.getNumber(); 5835022f6bbSAlex Lorenz bool HasAttributes = false; 5845022f6bbSAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 5855022f6bbSAlex Lorenz if (BB->hasName()) { 5865022f6bbSAlex Lorenz OS << "." << BB->getName(); 5875022f6bbSAlex Lorenz } else { 5885022f6bbSAlex Lorenz HasAttributes = true; 5895022f6bbSAlex Lorenz OS << " ("; 5905022f6bbSAlex Lorenz int Slot = MST.getLocalSlot(BB); 5915022f6bbSAlex Lorenz if (Slot == -1) 5925022f6bbSAlex Lorenz OS << "<ir-block badref>"; 5935022f6bbSAlex Lorenz else 5945022f6bbSAlex Lorenz OS << (Twine("%ir-block.") + Twine(Slot)).str(); 5955022f6bbSAlex Lorenz } 5965022f6bbSAlex Lorenz } 5975022f6bbSAlex Lorenz if (MBB.hasAddressTaken()) { 5985022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 5995022f6bbSAlex Lorenz OS << "address-taken"; 6005022f6bbSAlex Lorenz HasAttributes = true; 6015022f6bbSAlex Lorenz } 6020e288234SReid Kleckner if (MBB.isEHPad()) { 6035022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 6045022f6bbSAlex Lorenz OS << "landing-pad"; 6055022f6bbSAlex Lorenz HasAttributes = true; 6065022f6bbSAlex Lorenz } 6075022f6bbSAlex Lorenz if (MBB.getAlignment()) { 6085022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 6095022f6bbSAlex Lorenz OS << "align " << MBB.getAlignment(); 6105022f6bbSAlex Lorenz HasAttributes = true; 6115022f6bbSAlex Lorenz } 6125022f6bbSAlex Lorenz if (HasAttributes) 6135022f6bbSAlex Lorenz OS << ")"; 6145022f6bbSAlex Lorenz OS << ":\n"; 6155022f6bbSAlex Lorenz 6165022f6bbSAlex Lorenz bool HasLineAttributes = false; 6175022f6bbSAlex Lorenz // Print the successors 6188940114fSMatthias Braun bool canPredictProbs = canPredictBranchProbabilities(MBB); 619d652aeb1SQuentin Colombet // Even if the list of successors is empty, if we cannot guess it, 620d652aeb1SQuentin Colombet // we need to print it to tell the parser that the list is empty. 621d652aeb1SQuentin Colombet // This is needed, because MI model unreachable as empty blocks 622d652aeb1SQuentin Colombet // with an empty successor list. If the parser would see that 623d652aeb1SQuentin Colombet // without the successor list, it would guess the code would 624d652aeb1SQuentin Colombet // fallthrough. 625d652aeb1SQuentin Colombet if ((!MBB.succ_empty() && !SimplifyMIR) || !canPredictProbs || 626d652aeb1SQuentin Colombet !canPredictSuccessors(MBB)) { 6275022f6bbSAlex Lorenz OS.indent(2) << "successors: "; 6285022f6bbSAlex Lorenz for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) { 6295022f6bbSAlex Lorenz if (I != MBB.succ_begin()) 6305022f6bbSAlex Lorenz OS << ", "; 6315022f6bbSAlex Lorenz printMBBReference(**I); 6328940114fSMatthias Braun if (!SimplifyMIR || !canPredictProbs) 633b51774acSGeoff Berry OS << '(' 634b51774acSGeoff Berry << format("0x%08" PRIx32, MBB.getSuccProbability(I).getNumerator()) 635b51774acSGeoff Berry << ')'; 6365022f6bbSAlex Lorenz } 6375022f6bbSAlex Lorenz OS << "\n"; 6385022f6bbSAlex Lorenz HasLineAttributes = true; 6395022f6bbSAlex Lorenz } 6405022f6bbSAlex Lorenz 6415022f6bbSAlex Lorenz // Print the live in registers. 64211723322SMatthias Braun const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 64311723322SMatthias Braun if (MRI.tracksLiveness() && !MBB.livein_empty()) { 64411723322SMatthias Braun const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); 6455022f6bbSAlex Lorenz OS.indent(2) << "liveins: "; 646b2b7ef1dSMatthias Braun bool First = true; 647d9da1627SMatthias Braun for (const auto &LI : MBB.liveins()) { 648b2b7ef1dSMatthias Braun if (!First) 6495022f6bbSAlex Lorenz OS << ", "; 650b2b7ef1dSMatthias Braun First = false; 65111723322SMatthias Braun printReg(LI.PhysReg, OS, &TRI); 65291b5cf84SKrzysztof Parzyszek if (!LI.LaneMask.all()) 653d62669d7SKrzysztof Parzyszek OS << ":0x" << PrintLaneMask(LI.LaneMask); 6545022f6bbSAlex Lorenz } 6555022f6bbSAlex Lorenz OS << "\n"; 6565022f6bbSAlex Lorenz HasLineAttributes = true; 6575022f6bbSAlex Lorenz } 6585022f6bbSAlex Lorenz 6595022f6bbSAlex Lorenz if (HasLineAttributes) 6605022f6bbSAlex Lorenz OS << "\n"; 661f9a2b123SAlex Lorenz bool IsInBundle = false; 662f9a2b123SAlex Lorenz for (auto I = MBB.instr_begin(), E = MBB.instr_end(); I != E; ++I) { 663f9a2b123SAlex Lorenz const MachineInstr &MI = *I; 664f9a2b123SAlex Lorenz if (IsInBundle && !MI.isInsideBundle()) { 665f9a2b123SAlex Lorenz OS.indent(2) << "}\n"; 666f9a2b123SAlex Lorenz IsInBundle = false; 667f9a2b123SAlex Lorenz } 668f9a2b123SAlex Lorenz OS.indent(IsInBundle ? 4 : 2); 6695022f6bbSAlex Lorenz print(MI); 670f9a2b123SAlex Lorenz if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) { 671f9a2b123SAlex Lorenz OS << " {"; 672f9a2b123SAlex Lorenz IsInBundle = true; 673f9a2b123SAlex Lorenz } 6745022f6bbSAlex Lorenz OS << "\n"; 6755022f6bbSAlex Lorenz } 676f9a2b123SAlex Lorenz if (IsInBundle) 677f9a2b123SAlex Lorenz OS.indent(2) << "}\n"; 6785022f6bbSAlex Lorenz } 6795022f6bbSAlex Lorenz 6805ef93b0cSAlex Lorenz /// Return true when an instruction has tied register that can't be determined 6815ef93b0cSAlex Lorenz /// by the instruction's descriptor. 6825ef93b0cSAlex Lorenz static bool hasComplexRegisterTies(const MachineInstr &MI) { 6835ef93b0cSAlex Lorenz const MCInstrDesc &MCID = MI.getDesc(); 6845ef93b0cSAlex Lorenz for (unsigned I = 0, E = MI.getNumOperands(); I < E; ++I) { 6855ef93b0cSAlex Lorenz const auto &Operand = MI.getOperand(I); 6865ef93b0cSAlex Lorenz if (!Operand.isReg() || Operand.isDef()) 6875ef93b0cSAlex Lorenz // Ignore the defined registers as MCID marks only the uses as tied. 6885ef93b0cSAlex Lorenz continue; 6895ef93b0cSAlex Lorenz int ExpectedTiedIdx = MCID.getOperandConstraint(I, MCOI::TIED_TO); 6905ef93b0cSAlex Lorenz int TiedIdx = Operand.isTied() ? int(MI.findTiedOperandIdx(I)) : -1; 6915ef93b0cSAlex Lorenz if (ExpectedTiedIdx != TiedIdx) 6925ef93b0cSAlex Lorenz return true; 6935ef93b0cSAlex Lorenz } 6945ef93b0cSAlex Lorenz return false; 6955ef93b0cSAlex Lorenz } 6965ef93b0cSAlex Lorenz 697d28d3cc0STim Northover static LLT getTypeToPrint(const MachineInstr &MI, unsigned OpIdx, 698d28d3cc0STim Northover SmallBitVector &PrintedTypes, 699d28d3cc0STim Northover const MachineRegisterInfo &MRI) { 700d28d3cc0STim Northover const MachineOperand &Op = MI.getOperand(OpIdx); 701d28d3cc0STim Northover if (!Op.isReg()) 702d28d3cc0STim Northover return LLT{}; 703d28d3cc0STim Northover 704d28d3cc0STim Northover if (MI.isVariadic() || OpIdx >= MI.getNumExplicitOperands()) 705d28d3cc0STim Northover return MRI.getType(Op.getReg()); 706d28d3cc0STim Northover 707d28d3cc0STim Northover auto &OpInfo = MI.getDesc().OpInfo[OpIdx]; 708d28d3cc0STim Northover if (!OpInfo.isGenericType()) 709d28d3cc0STim Northover return MRI.getType(Op.getReg()); 710d28d3cc0STim Northover 711d28d3cc0STim Northover if (PrintedTypes[OpInfo.getGenericTypeIndex()]) 712d28d3cc0STim Northover return LLT{}; 713d28d3cc0STim Northover 714d28d3cc0STim Northover PrintedTypes.set(OpInfo.getGenericTypeIndex()); 715d28d3cc0STim Northover return MRI.getType(Op.getReg()); 716d28d3cc0STim Northover } 717d28d3cc0STim Northover 7188e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) { 719fdf9bf4fSJustin Bogner const auto *MF = MI.getMF(); 7204e14a497SQuentin Colombet const auto &MRI = MF->getRegInfo(); 7214e14a497SQuentin Colombet const auto &SubTarget = MF->getSubtarget(); 722f3db51deSAlex Lorenz const auto *TRI = SubTarget.getRegisterInfo(); 723f3db51deSAlex Lorenz assert(TRI && "Expected target register info"); 7248e0a1b48SAlex Lorenz const auto *TII = SubTarget.getInstrInfo(); 7258e0a1b48SAlex Lorenz assert(TII && "Expected target instruction info"); 726f4baeb51SAlex Lorenz if (MI.isCFIInstruction()) 727f4baeb51SAlex Lorenz assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction"); 7288e0a1b48SAlex Lorenz 729d28d3cc0STim Northover SmallBitVector PrintedTypes(8); 7305ef93b0cSAlex Lorenz bool ShouldPrintRegisterTies = hasComplexRegisterTies(MI); 731f3db51deSAlex Lorenz unsigned I = 0, E = MI.getNumOperands(); 732f3db51deSAlex Lorenz for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() && 733f3db51deSAlex Lorenz !MI.getOperand(I).isImplicit(); 734f3db51deSAlex Lorenz ++I) { 735f3db51deSAlex Lorenz if (I) 736f3db51deSAlex Lorenz OS << ", "; 737a42ed3e3SBjorn Pettersson print(MI, I, TRI, ShouldPrintRegisterTies, 738d28d3cc0STim Northover getTypeToPrint(MI, I, PrintedTypes, MRI), 7394e14a497SQuentin Colombet /*IsDef=*/true); 740f3db51deSAlex Lorenz } 741f3db51deSAlex Lorenz 742f3db51deSAlex Lorenz if (I) 743f3db51deSAlex Lorenz OS << " = "; 744e5a44660SAlex Lorenz if (MI.getFlag(MachineInstr::FrameSetup)) 745e5a44660SAlex Lorenz OS << "frame-setup "; 7468e0a1b48SAlex Lorenz OS << TII->getName(MI.getOpcode()); 747f3db51deSAlex Lorenz if (I < E) 748f3db51deSAlex Lorenz OS << ' '; 749f3db51deSAlex Lorenz 750f3db51deSAlex Lorenz bool NeedComma = false; 751f3db51deSAlex Lorenz for (; I < E; ++I) { 752f3db51deSAlex Lorenz if (NeedComma) 753f3db51deSAlex Lorenz OS << ", "; 754a42ed3e3SBjorn Pettersson print(MI, I, TRI, ShouldPrintRegisterTies, 755d28d3cc0STim Northover getTypeToPrint(MI, I, PrintedTypes, MRI)); 756f3db51deSAlex Lorenz NeedComma = true; 757f3db51deSAlex Lorenz } 75846d760d1SAlex Lorenz 75946d760d1SAlex Lorenz if (MI.getDebugLoc()) { 76046d760d1SAlex Lorenz if (NeedComma) 76146d760d1SAlex Lorenz OS << ','; 76246d760d1SAlex Lorenz OS << " debug-location "; 76346d760d1SAlex Lorenz MI.getDebugLoc()->printAsOperand(OS, MST); 76446d760d1SAlex Lorenz } 7654af7e610SAlex Lorenz 7664af7e610SAlex Lorenz if (!MI.memoperands_empty()) { 7674af7e610SAlex Lorenz OS << " :: "; 768bb80d3e1SKonstantin Zhuravlyov const LLVMContext &Context = MF->getFunction()->getContext(); 7694af7e610SAlex Lorenz bool NeedComma = false; 7704af7e610SAlex Lorenz for (const auto *Op : MI.memoperands()) { 7714af7e610SAlex Lorenz if (NeedComma) 7724af7e610SAlex Lorenz OS << ", "; 7736748abe2SGeoff Berry print(Context, *TII, *Op); 7744af7e610SAlex Lorenz NeedComma = true; 7754af7e610SAlex Lorenz } 7764af7e610SAlex Lorenz } 777f3db51deSAlex Lorenz } 778f3db51deSAlex Lorenz 7795d26fa83SAlex Lorenz void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) { 7805d26fa83SAlex Lorenz OS << "%bb." << MBB.getNumber(); 7815d26fa83SAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 7825d26fa83SAlex Lorenz if (BB->hasName()) 7835d26fa83SAlex Lorenz OS << '.' << BB->getName(); 7845d26fa83SAlex Lorenz } 7855d26fa83SAlex Lorenz } 7865d26fa83SAlex Lorenz 78755dc6f81SAlex Lorenz static void printIRSlotNumber(raw_ostream &OS, int Slot) { 78855dc6f81SAlex Lorenz if (Slot == -1) 78955dc6f81SAlex Lorenz OS << "<badref>"; 79055dc6f81SAlex Lorenz else 79155dc6f81SAlex Lorenz OS << Slot; 79255dc6f81SAlex Lorenz } 79355dc6f81SAlex Lorenz 794deb53490SAlex Lorenz void MIPrinter::printIRBlockReference(const BasicBlock &BB) { 795deb53490SAlex Lorenz OS << "%ir-block."; 796deb53490SAlex Lorenz if (BB.hasName()) { 797deb53490SAlex Lorenz printLLVMNameWithoutPrefix(OS, BB.getName()); 798deb53490SAlex Lorenz return; 799deb53490SAlex Lorenz } 800cba8c5feSAlex Lorenz const Function *F = BB.getParent(); 801cba8c5feSAlex Lorenz int Slot; 802cba8c5feSAlex Lorenz if (F == MST.getCurrentFunction()) { 803cba8c5feSAlex Lorenz Slot = MST.getLocalSlot(&BB); 804cba8c5feSAlex Lorenz } else { 805cba8c5feSAlex Lorenz ModuleSlotTracker CustomMST(F->getParent(), 806cba8c5feSAlex Lorenz /*ShouldInitializeAllMetadata=*/false); 807cba8c5feSAlex Lorenz CustomMST.incorporateFunction(*F); 808cba8c5feSAlex Lorenz Slot = CustomMST.getLocalSlot(&BB); 809cba8c5feSAlex Lorenz } 81055dc6f81SAlex Lorenz printIRSlotNumber(OS, Slot); 811deb53490SAlex Lorenz } 812deb53490SAlex Lorenz 8134af7e610SAlex Lorenz void MIPrinter::printIRValueReference(const Value &V) { 81436efd388SAlex Lorenz if (isa<GlobalValue>(V)) { 81536efd388SAlex Lorenz V.printAsOperand(OS, /*PrintType=*/false, MST); 81636efd388SAlex Lorenz return; 81736efd388SAlex Lorenz } 818c1136ef3SAlex Lorenz if (isa<Constant>(V)) { 819c1136ef3SAlex Lorenz // Machine memory operands can load/store to/from constant value pointers. 820c1136ef3SAlex Lorenz OS << '`'; 821c1136ef3SAlex Lorenz V.printAsOperand(OS, /*PrintType=*/true, MST); 822c1136ef3SAlex Lorenz OS << '`'; 823c1136ef3SAlex Lorenz return; 824c1136ef3SAlex Lorenz } 8254af7e610SAlex Lorenz OS << "%ir."; 8264af7e610SAlex Lorenz if (V.hasName()) { 8274af7e610SAlex Lorenz printLLVMNameWithoutPrefix(OS, V.getName()); 8284af7e610SAlex Lorenz return; 8294af7e610SAlex Lorenz } 830dd13be0bSAlex Lorenz printIRSlotNumber(OS, MST.getLocalSlot(&V)); 8314af7e610SAlex Lorenz } 8324af7e610SAlex Lorenz 8337feaf7c6SAlex Lorenz void MIPrinter::printStackObjectReference(int FrameIndex) { 8347feaf7c6SAlex Lorenz auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex); 8357feaf7c6SAlex Lorenz assert(ObjectInfo != StackObjectOperandMapping.end() && 8367feaf7c6SAlex Lorenz "Invalid frame index"); 8377feaf7c6SAlex Lorenz const FrameIndexOperand &Operand = ObjectInfo->second; 8387feaf7c6SAlex Lorenz if (Operand.IsFixed) { 8397feaf7c6SAlex Lorenz OS << "%fixed-stack." << Operand.ID; 8407feaf7c6SAlex Lorenz return; 8417feaf7c6SAlex Lorenz } 8427feaf7c6SAlex Lorenz OS << "%stack." << Operand.ID; 8437feaf7c6SAlex Lorenz if (!Operand.Name.empty()) 8447feaf7c6SAlex Lorenz OS << '.' << Operand.Name; 8457feaf7c6SAlex Lorenz } 8467feaf7c6SAlex Lorenz 8475672a893SAlex Lorenz void MIPrinter::printOffset(int64_t Offset) { 8485672a893SAlex Lorenz if (Offset == 0) 8495672a893SAlex Lorenz return; 8505672a893SAlex Lorenz if (Offset < 0) { 8515672a893SAlex Lorenz OS << " - " << -Offset; 8525672a893SAlex Lorenz return; 8535672a893SAlex Lorenz } 8545672a893SAlex Lorenz OS << " + " << Offset; 8555672a893SAlex Lorenz } 8565672a893SAlex Lorenz 85749873a83SAlex Lorenz static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) { 85849873a83SAlex Lorenz auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); 85949873a83SAlex Lorenz for (const auto &I : Flags) { 86049873a83SAlex Lorenz if (I.first == TF) { 86149873a83SAlex Lorenz return I.second; 86249873a83SAlex Lorenz } 86349873a83SAlex Lorenz } 86449873a83SAlex Lorenz return nullptr; 86549873a83SAlex Lorenz } 86649873a83SAlex Lorenz 86749873a83SAlex Lorenz void MIPrinter::printTargetFlags(const MachineOperand &Op) { 86849873a83SAlex Lorenz if (!Op.getTargetFlags()) 86949873a83SAlex Lorenz return; 870fdf9bf4fSJustin Bogner const auto *TII = Op.getParent()->getMF()->getSubtarget().getInstrInfo(); 87149873a83SAlex Lorenz assert(TII && "expected instruction info"); 87249873a83SAlex Lorenz auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags()); 87349873a83SAlex Lorenz OS << "target-flags("; 874f3630113SAlex Lorenz const bool HasDirectFlags = Flags.first; 875f3630113SAlex Lorenz const bool HasBitmaskFlags = Flags.second; 876f3630113SAlex Lorenz if (!HasDirectFlags && !HasBitmaskFlags) { 877f3630113SAlex Lorenz OS << "<unknown>) "; 878f3630113SAlex Lorenz return; 879f3630113SAlex Lorenz } 880f3630113SAlex Lorenz if (HasDirectFlags) { 88149873a83SAlex Lorenz if (const auto *Name = getTargetFlagName(TII, Flags.first)) 88249873a83SAlex Lorenz OS << Name; 88349873a83SAlex Lorenz else 88449873a83SAlex Lorenz OS << "<unknown target flag>"; 885f3630113SAlex Lorenz } 886f3630113SAlex Lorenz if (!HasBitmaskFlags) { 887f3630113SAlex Lorenz OS << ") "; 888f3630113SAlex Lorenz return; 889f3630113SAlex Lorenz } 890f3630113SAlex Lorenz bool IsCommaNeeded = HasDirectFlags; 891f3630113SAlex Lorenz unsigned BitMask = Flags.second; 892f3630113SAlex Lorenz auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags(); 893f3630113SAlex Lorenz for (const auto &Mask : BitMasks) { 894f3630113SAlex Lorenz // Check if the flag's bitmask has the bits of the current mask set. 895f3630113SAlex Lorenz if ((BitMask & Mask.first) == Mask.first) { 896f3630113SAlex Lorenz if (IsCommaNeeded) 897f3630113SAlex Lorenz OS << ", "; 898f3630113SAlex Lorenz IsCommaNeeded = true; 899f3630113SAlex Lorenz OS << Mask.second; 900f3630113SAlex Lorenz // Clear the bits which were serialized from the flag's bitmask. 901f3630113SAlex Lorenz BitMask &= ~(Mask.first); 902f3630113SAlex Lorenz } 903f3630113SAlex Lorenz } 904f3630113SAlex Lorenz if (BitMask) { 905f3630113SAlex Lorenz // When the resulting flag's bitmask isn't zero, we know that we didn't 906f3630113SAlex Lorenz // serialize all of the bit flags. 907f3630113SAlex Lorenz if (IsCommaNeeded) 908f3630113SAlex Lorenz OS << ", "; 909f3630113SAlex Lorenz OS << "<unknown bitmask target flag>"; 910f3630113SAlex Lorenz } 91149873a83SAlex Lorenz OS << ") "; 91249873a83SAlex Lorenz } 91349873a83SAlex Lorenz 914ef5c196fSAlex Lorenz static const char *getTargetIndexName(const MachineFunction &MF, int Index) { 915ef5c196fSAlex Lorenz const auto *TII = MF.getSubtarget().getInstrInfo(); 916ef5c196fSAlex Lorenz assert(TII && "expected instruction info"); 917ef5c196fSAlex Lorenz auto Indices = TII->getSerializableTargetIndices(); 918ef5c196fSAlex Lorenz for (const auto &I : Indices) { 919ef5c196fSAlex Lorenz if (I.first == Index) { 920ef5c196fSAlex Lorenz return I.second; 921ef5c196fSAlex Lorenz } 922ef5c196fSAlex Lorenz } 923ef5c196fSAlex Lorenz return nullptr; 924ef5c196fSAlex Lorenz } 925ef5c196fSAlex Lorenz 926a42ed3e3SBjorn Pettersson void MIPrinter::print(const MachineInstr &MI, unsigned OpIdx, 927a42ed3e3SBjorn Pettersson const TargetRegisterInfo *TRI, 928a42ed3e3SBjorn Pettersson bool ShouldPrintRegisterTies, LLT TypeToPrint, 929d28d3cc0STim Northover bool IsDef) { 930a42ed3e3SBjorn Pettersson const MachineOperand &Op = MI.getOperand(OpIdx); 93149873a83SAlex Lorenz printTargetFlags(Op); 932f3db51deSAlex Lorenz switch (Op.getType()) { 9336c452834SJustin Bogner case MachineOperand::MO_Register: { 9346c452834SJustin Bogner unsigned Reg = Op.getReg(); 935cb268d46SAlex Lorenz if (Op.isImplicit()) 936cb268d46SAlex Lorenz OS << (Op.isDef() ? "implicit-def " : "implicit "); 937e66a7ccfSAlex Lorenz else if (!IsDef && Op.isDef()) 938e66a7ccfSAlex Lorenz // Print the 'def' flag only when the operand is defined after '='. 939e66a7ccfSAlex Lorenz OS << "def "; 9401039fd1aSAlex Lorenz if (Op.isInternalRead()) 9411039fd1aSAlex Lorenz OS << "internal "; 942cbbfd0b1SAlex Lorenz if (Op.isDead()) 943cbbfd0b1SAlex Lorenz OS << "dead "; 944495ad879SAlex Lorenz if (Op.isKill()) 945495ad879SAlex Lorenz OS << "killed "; 9464d026b89SAlex Lorenz if (Op.isUndef()) 9474d026b89SAlex Lorenz OS << "undef "; 94801c1a5eeSAlex Lorenz if (Op.isEarlyClobber()) 94901c1a5eeSAlex Lorenz OS << "early-clobber "; 9509075258bSAlex Lorenz if (Op.isDebug()) 9519075258bSAlex Lorenz OS << "debug-use "; 9526c452834SJustin Bogner printReg(Reg, OS, TRI); 9532eacca86SAlex Lorenz // Print the sub register. 9542eacca86SAlex Lorenz if (Op.getSubReg() != 0) 955333e468dSMatthias Braun OS << '.' << TRI->getSubRegIndexName(Op.getSubReg()); 9566c452834SJustin Bogner if (TargetRegisterInfo::isVirtualRegister(Reg)) { 9576c452834SJustin Bogner const MachineRegisterInfo &MRI = Op.getParent()->getMF()->getRegInfo(); 9586c452834SJustin Bogner if (IsDef || MRI.def_empty(Reg)) { 9596c452834SJustin Bogner OS << ':'; 9606c452834SJustin Bogner printRegClassOrBank(Reg, OS, MRI, TRI); 9616c452834SJustin Bogner } 9626c452834SJustin Bogner } 9635ef93b0cSAlex Lorenz if (ShouldPrintRegisterTies && Op.isTied() && !Op.isDef()) 964a42ed3e3SBjorn Pettersson OS << "(tied-def " << Op.getParent()->findTiedOperandIdx(OpIdx) << ")"; 965d28d3cc0STim Northover if (TypeToPrint.isValid()) 966d28d3cc0STim Northover OS << '(' << TypeToPrint << ')'; 967f3db51deSAlex Lorenz break; 9686c452834SJustin Bogner } 969240fc1e0SAlex Lorenz case MachineOperand::MO_Immediate: 970a42ed3e3SBjorn Pettersson if (MI.isOperandSubregIdx(OpIdx)) 971a42ed3e3SBjorn Pettersson OS << "%subreg." << TRI->getSubRegIndexName(Op.getImm()); 972a42ed3e3SBjorn Pettersson else 973240fc1e0SAlex Lorenz OS << Op.getImm(); 974240fc1e0SAlex Lorenz break; 97505e3882eSAlex Lorenz case MachineOperand::MO_CImmediate: 97605e3882eSAlex Lorenz Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); 97705e3882eSAlex Lorenz break; 978ad156fb6SAlex Lorenz case MachineOperand::MO_FPImmediate: 979ad156fb6SAlex Lorenz Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); 980ad156fb6SAlex Lorenz break; 98133f0aef3SAlex Lorenz case MachineOperand::MO_MachineBasicBlock: 9825d26fa83SAlex Lorenz printMBBReference(*Op.getMBB()); 98333f0aef3SAlex Lorenz break; 9847feaf7c6SAlex Lorenz case MachineOperand::MO_FrameIndex: 9857feaf7c6SAlex Lorenz printStackObjectReference(Op.getIndex()); 9867feaf7c6SAlex Lorenz break; 987ab980499SAlex Lorenz case MachineOperand::MO_ConstantPoolIndex: 988ab980499SAlex Lorenz OS << "%const." << Op.getIndex(); 9895672a893SAlex Lorenz printOffset(Op.getOffset()); 990ab980499SAlex Lorenz break; 991fb69e66cSEugene Zelenko case MachineOperand::MO_TargetIndex: 992ef5c196fSAlex Lorenz OS << "target-index("; 993fdf9bf4fSJustin Bogner if (const auto *Name = 994fdf9bf4fSJustin Bogner getTargetIndexName(*Op.getParent()->getMF(), Op.getIndex())) 995ef5c196fSAlex Lorenz OS << Name; 996ef5c196fSAlex Lorenz else 997ef5c196fSAlex Lorenz OS << "<unknown>"; 998ef5c196fSAlex Lorenz OS << ')'; 9995672a893SAlex Lorenz printOffset(Op.getOffset()); 1000ef5c196fSAlex Lorenz break; 100131d70683SAlex Lorenz case MachineOperand::MO_JumpTableIndex: 100231d70683SAlex Lorenz OS << "%jump-table." << Op.getIndex(); 100331d70683SAlex Lorenz break; 10048b5f9e44SMatthias Braun case MachineOperand::MO_ExternalSymbol: { 10058b5f9e44SMatthias Braun StringRef Name = Op.getSymbolName(); 10066ede3744SAlex Lorenz OS << '$'; 10078b5f9e44SMatthias Braun if (Name.empty()) { 10088b5f9e44SMatthias Braun OS << "\"\""; 10098b5f9e44SMatthias Braun } else { 10108b5f9e44SMatthias Braun printLLVMNameWithoutPrefix(OS, Name); 10118b5f9e44SMatthias Braun } 10125672a893SAlex Lorenz printOffset(Op.getOffset()); 10136ede3744SAlex Lorenz break; 10148b5f9e44SMatthias Braun } 10155d6108e4SAlex Lorenz case MachineOperand::MO_GlobalAddress: 1016900b5cb2SAlex Lorenz Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 10175672a893SAlex Lorenz printOffset(Op.getOffset()); 10185d6108e4SAlex Lorenz break; 1019deb53490SAlex Lorenz case MachineOperand::MO_BlockAddress: 1020deb53490SAlex Lorenz OS << "blockaddress("; 1021deb53490SAlex Lorenz Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, 1022deb53490SAlex Lorenz MST); 1023deb53490SAlex Lorenz OS << ", "; 1024deb53490SAlex Lorenz printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); 1025deb53490SAlex Lorenz OS << ')'; 10265672a893SAlex Lorenz printOffset(Op.getOffset()); 1027deb53490SAlex Lorenz break; 10288f6f4285SAlex Lorenz case MachineOperand::MO_RegisterMask: { 10298f6f4285SAlex Lorenz auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); 10308f6f4285SAlex Lorenz if (RegMaskInfo != RegisterMaskIds.end()) 10318f6f4285SAlex Lorenz OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); 10328f6f4285SAlex Lorenz else 10330ef61ec3SOren Ben Simhon printCustomRegMask(Op.getRegMask(), OS, TRI); 10348f6f4285SAlex Lorenz break; 10358f6f4285SAlex Lorenz } 1036b97c9ef4SAlex Lorenz case MachineOperand::MO_RegisterLiveOut: { 1037b97c9ef4SAlex Lorenz const uint32_t *RegMask = Op.getRegLiveOut(); 1038b97c9ef4SAlex Lorenz OS << "liveout("; 1039b97c9ef4SAlex Lorenz bool IsCommaNeeded = false; 1040b97c9ef4SAlex Lorenz for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { 1041b97c9ef4SAlex Lorenz if (RegMask[Reg / 32] & (1U << (Reg % 32))) { 1042b97c9ef4SAlex Lorenz if (IsCommaNeeded) 1043b97c9ef4SAlex Lorenz OS << ", "; 1044b97c9ef4SAlex Lorenz printReg(Reg, OS, TRI); 1045b97c9ef4SAlex Lorenz IsCommaNeeded = true; 1046b97c9ef4SAlex Lorenz } 1047b97c9ef4SAlex Lorenz } 1048b97c9ef4SAlex Lorenz OS << ")"; 1049b97c9ef4SAlex Lorenz break; 1050b97c9ef4SAlex Lorenz } 105135e44469SAlex Lorenz case MachineOperand::MO_Metadata: 105235e44469SAlex Lorenz Op.getMetadata()->printAsOperand(OS, MST); 105335e44469SAlex Lorenz break; 1054f22ca8adSAlex Lorenz case MachineOperand::MO_MCSymbol: 1055f22ca8adSAlex Lorenz OS << "<mcsymbol " << *Op.getMCSymbol() << ">"; 1056f22ca8adSAlex Lorenz break; 1057f4baeb51SAlex Lorenz case MachineOperand::MO_CFIIndex: { 1058fdf9bf4fSJustin Bogner const MachineFunction &MF = *Op.getParent()->getMF(); 1059f23ef437SMatthias Braun print(MF.getFrameInstructions()[Op.getCFIIndex()], TRI); 1060f4baeb51SAlex Lorenz break; 1061f4baeb51SAlex Lorenz } 10626b3bd612STim Northover case MachineOperand::MO_IntrinsicID: { 10636b3bd612STim Northover Intrinsic::ID ID = Op.getIntrinsicID(); 10646b3bd612STim Northover if (ID < Intrinsic::num_intrinsics) 10651523925dSPete Cooper OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')'; 10666b3bd612STim Northover else { 1067fdf9bf4fSJustin Bogner const MachineFunction &MF = *Op.getParent()->getMF(); 10686b3bd612STim Northover const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo(); 10696b3bd612STim Northover OS << "intrinsic(@" << TII->getName(ID) << ')'; 10706b3bd612STim Northover } 10716b3bd612STim Northover break; 10726b3bd612STim Northover } 1073de3aea04STim Northover case MachineOperand::MO_Predicate: { 1074de3aea04STim Northover auto Pred = static_cast<CmpInst::Predicate>(Op.getPredicate()); 1075de3aea04STim Northover OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred(" 1076de3aea04STim Northover << CmpInst::getPredicateName(Pred) << ')'; 1077de3aea04STim Northover break; 1078de3aea04STim Northover } 1079f3db51deSAlex Lorenz } 10804f093bf1SAlex Lorenz } 10814f093bf1SAlex Lorenz 10826748abe2SGeoff Berry static const char *getTargetMMOFlagName(const TargetInstrInfo &TII, 10836748abe2SGeoff Berry unsigned TMMOFlag) { 10846748abe2SGeoff Berry auto Flags = TII.getSerializableMachineMemOperandTargetFlags(); 10856748abe2SGeoff Berry for (const auto &I : Flags) { 10866748abe2SGeoff Berry if (I.first == TMMOFlag) { 10876748abe2SGeoff Berry return I.second; 10886748abe2SGeoff Berry } 10896748abe2SGeoff Berry } 10906748abe2SGeoff Berry return nullptr; 10916748abe2SGeoff Berry } 10926748abe2SGeoff Berry 10936748abe2SGeoff Berry void MIPrinter::print(const LLVMContext &Context, const TargetInstrInfo &TII, 10946748abe2SGeoff Berry const MachineMemOperand &Op) { 10954af7e610SAlex Lorenz OS << '('; 1096a518b796SAlex Lorenz if (Op.isVolatile()) 1097a518b796SAlex Lorenz OS << "volatile "; 109810fd0385SAlex Lorenz if (Op.isNonTemporal()) 109910fd0385SAlex Lorenz OS << "non-temporal "; 1100adbf09e8SJustin Lebar if (Op.isDereferenceable()) 1101adbf09e8SJustin Lebar OS << "dereferenceable "; 1102dc8de2a6SAlex Lorenz if (Op.isInvariant()) 1103dc8de2a6SAlex Lorenz OS << "invariant "; 11046748abe2SGeoff Berry if (Op.getFlags() & MachineMemOperand::MOTargetFlag1) 11056748abe2SGeoff Berry OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag1) 11066748abe2SGeoff Berry << "\" "; 11076748abe2SGeoff Berry if (Op.getFlags() & MachineMemOperand::MOTargetFlag2) 11086748abe2SGeoff Berry OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag2) 11096748abe2SGeoff Berry << "\" "; 11106748abe2SGeoff Berry if (Op.getFlags() & MachineMemOperand::MOTargetFlag3) 11116748abe2SGeoff Berry OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag3) 11126748abe2SGeoff Berry << "\" "; 11134af7e610SAlex Lorenz if (Op.isLoad()) 11144af7e610SAlex Lorenz OS << "load "; 11154af7e610SAlex Lorenz else { 11164af7e610SAlex Lorenz assert(Op.isStore() && "Non load machine operand must be a store"); 11174af7e610SAlex Lorenz OS << "store "; 11184af7e610SAlex Lorenz } 1119b73e3090STim Northover 1120bb80d3e1SKonstantin Zhuravlyov printSyncScope(Context, Op.getSyncScopeID()); 1121b73e3090STim Northover 1122b73e3090STim Northover if (Op.getOrdering() != AtomicOrdering::NotAtomic) 1123b73e3090STim Northover OS << toIRString(Op.getOrdering()) << ' '; 1124b73e3090STim Northover if (Op.getFailureOrdering() != AtomicOrdering::NotAtomic) 1125b73e3090STim Northover OS << toIRString(Op.getFailureOrdering()) << ' '; 1126b73e3090STim Northover 1127c25c9ccbSMatthias Braun OS << Op.getSize(); 112891097a3fSAlex Lorenz if (const Value *Val = Op.getValue()) { 1129c25c9ccbSMatthias Braun OS << (Op.isLoad() ? " from " : " into "); 11304af7e610SAlex Lorenz printIRValueReference(*Val); 1131c25c9ccbSMatthias Braun } else if (const PseudoSourceValue *PVal = Op.getPseudoValue()) { 1132c25c9ccbSMatthias Braun OS << (Op.isLoad() ? " from " : " into "); 113391097a3fSAlex Lorenz assert(PVal && "Expected a pseudo source value"); 113491097a3fSAlex Lorenz switch (PVal->kind()) { 113546e9558aSAlex Lorenz case PseudoSourceValue::Stack: 113646e9558aSAlex Lorenz OS << "stack"; 113746e9558aSAlex Lorenz break; 1138d858f874SAlex Lorenz case PseudoSourceValue::GOT: 1139d858f874SAlex Lorenz OS << "got"; 1140d858f874SAlex Lorenz break; 11414be56e93SAlex Lorenz case PseudoSourceValue::JumpTable: 11424be56e93SAlex Lorenz OS << "jump-table"; 11434be56e93SAlex Lorenz break; 114491097a3fSAlex Lorenz case PseudoSourceValue::ConstantPool: 114591097a3fSAlex Lorenz OS << "constant-pool"; 114691097a3fSAlex Lorenz break; 11470cc671bfSAlex Lorenz case PseudoSourceValue::FixedStack: 11480cc671bfSAlex Lorenz printStackObjectReference( 11490cc671bfSAlex Lorenz cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex()); 11500cc671bfSAlex Lorenz break; 115150b826fbSAlex Lorenz case PseudoSourceValue::GlobalValueCallEntry: 11520d009645SAlex Lorenz OS << "call-entry "; 115350b826fbSAlex Lorenz cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand( 115450b826fbSAlex Lorenz OS, /*PrintType=*/false, MST); 115550b826fbSAlex Lorenz break; 1156c3ba7508SAlex Lorenz case PseudoSourceValue::ExternalSymbolCallEntry: 11570d009645SAlex Lorenz OS << "call-entry $"; 1158c3ba7508SAlex Lorenz printLLVMNameWithoutPrefix( 1159c3ba7508SAlex Lorenz OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol()); 116091097a3fSAlex Lorenz break; 11617761abb6STom Stellard case PseudoSourceValue::TargetCustom: 11627761abb6STom Stellard llvm_unreachable("TargetCustom pseudo source values are not supported"); 11637761abb6STom Stellard break; 116491097a3fSAlex Lorenz } 116591097a3fSAlex Lorenz } 116683127739SAlex Lorenz printOffset(Op.getOffset()); 116761420f79SAlex Lorenz if (Op.getBaseAlignment() != Op.getSize()) 116861420f79SAlex Lorenz OS << ", align " << Op.getBaseAlignment(); 1169a617c916SAlex Lorenz auto AAInfo = Op.getAAInfo(); 1170a617c916SAlex Lorenz if (AAInfo.TBAA) { 1171a617c916SAlex Lorenz OS << ", !tbaa "; 1172a617c916SAlex Lorenz AAInfo.TBAA->printAsOperand(OS, MST); 1173a617c916SAlex Lorenz } 1174a16f624dSAlex Lorenz if (AAInfo.Scope) { 1175a16f624dSAlex Lorenz OS << ", !alias.scope "; 1176a16f624dSAlex Lorenz AAInfo.Scope->printAsOperand(OS, MST); 1177a16f624dSAlex Lorenz } 117803e940d1SAlex Lorenz if (AAInfo.NoAlias) { 117903e940d1SAlex Lorenz OS << ", !noalias "; 118003e940d1SAlex Lorenz AAInfo.NoAlias->printAsOperand(OS, MST); 118103e940d1SAlex Lorenz } 1182eb625686SAlex Lorenz if (Op.getRanges()) { 1183eb625686SAlex Lorenz OS << ", !range "; 1184eb625686SAlex Lorenz Op.getRanges()->printAsOperand(OS, MST); 1185eb625686SAlex Lorenz } 11864af7e610SAlex Lorenz OS << ')'; 11874af7e610SAlex Lorenz } 11884af7e610SAlex Lorenz 1189bb80d3e1SKonstantin Zhuravlyov void MIPrinter::printSyncScope(const LLVMContext &Context, SyncScope::ID SSID) { 1190bb80d3e1SKonstantin Zhuravlyov switch (SSID) { 1191bb80d3e1SKonstantin Zhuravlyov case SyncScope::System: { 1192bb80d3e1SKonstantin Zhuravlyov break; 1193bb80d3e1SKonstantin Zhuravlyov } 1194bb80d3e1SKonstantin Zhuravlyov default: { 1195bb80d3e1SKonstantin Zhuravlyov if (SSNs.empty()) 1196bb80d3e1SKonstantin Zhuravlyov Context.getSyncScopeNames(SSNs); 1197bb80d3e1SKonstantin Zhuravlyov 1198bb80d3e1SKonstantin Zhuravlyov OS << "syncscope(\""; 1199bb80d3e1SKonstantin Zhuravlyov PrintEscapedString(SSNs[SSID], OS); 1200bb80d3e1SKonstantin Zhuravlyov OS << "\") "; 1201bb80d3e1SKonstantin Zhuravlyov break; 1202bb80d3e1SKonstantin Zhuravlyov } 1203bb80d3e1SKonstantin Zhuravlyov } 1204bb80d3e1SKonstantin Zhuravlyov } 1205bb80d3e1SKonstantin Zhuravlyov 12068cfc6867SAlex Lorenz static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS, 12078cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 12088cfc6867SAlex Lorenz int Reg = TRI->getLLVMRegNum(DwarfReg, true); 12098cfc6867SAlex Lorenz if (Reg == -1) { 12108cfc6867SAlex Lorenz OS << "<badreg>"; 12118cfc6867SAlex Lorenz return; 12128cfc6867SAlex Lorenz } 12138cfc6867SAlex Lorenz printReg(Reg, OS, TRI); 12148cfc6867SAlex Lorenz } 12158cfc6867SAlex Lorenz 12168cfc6867SAlex Lorenz void MIPrinter::print(const MCCFIInstruction &CFI, 12178cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 1218f4baeb51SAlex Lorenz switch (CFI.getOperation()) { 1219577d271aSAlex Lorenz case MCCFIInstruction::OpSameValue: 1220ee067920SMatthias Braun OS << "same_value "; 1221577d271aSAlex Lorenz if (CFI.getLabel()) 1222577d271aSAlex Lorenz OS << "<mcsymbol> "; 1223577d271aSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 1224577d271aSAlex Lorenz break; 12258cfc6867SAlex Lorenz case MCCFIInstruction::OpOffset: 1226ee067920SMatthias Braun OS << "offset "; 12278cfc6867SAlex Lorenz if (CFI.getLabel()) 12288cfc6867SAlex Lorenz OS << "<mcsymbol> "; 12298cfc6867SAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 12308cfc6867SAlex Lorenz OS << ", " << CFI.getOffset(); 12318cfc6867SAlex Lorenz break; 12325b0d5f6fSAlex Lorenz case MCCFIInstruction::OpDefCfaRegister: 1233ee067920SMatthias Braun OS << "def_cfa_register "; 12345b0d5f6fSAlex Lorenz if (CFI.getLabel()) 12355b0d5f6fSAlex Lorenz OS << "<mcsymbol> "; 12365b0d5f6fSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 12375b0d5f6fSAlex Lorenz break; 1238f4baeb51SAlex Lorenz case MCCFIInstruction::OpDefCfaOffset: 1239ee067920SMatthias Braun OS << "def_cfa_offset "; 1240f4baeb51SAlex Lorenz if (CFI.getLabel()) 1241f4baeb51SAlex Lorenz OS << "<mcsymbol> "; 1242f4baeb51SAlex Lorenz OS << CFI.getOffset(); 1243f4baeb51SAlex Lorenz break; 1244b139323fSAlex Lorenz case MCCFIInstruction::OpDefCfa: 1245ee067920SMatthias Braun OS << "def_cfa "; 1246b139323fSAlex Lorenz if (CFI.getLabel()) 1247b139323fSAlex Lorenz OS << "<mcsymbol> "; 1248b139323fSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 1249b139323fSAlex Lorenz OS << ", " << CFI.getOffset(); 1250b139323fSAlex Lorenz break; 125166d2c269SFrancis Visoiu Mistrih case MCCFIInstruction::OpRestore: 125266d2c269SFrancis Visoiu Mistrih OS << "restore "; 125366d2c269SFrancis Visoiu Mistrih if (CFI.getLabel()) 125466d2c269SFrancis Visoiu Mistrih OS << "<mcsymbol> "; 125566d2c269SFrancis Visoiu Mistrih printCFIRegister(CFI.getRegister(), OS, TRI); 125666d2c269SFrancis Visoiu Mistrih break; 1257f4baeb51SAlex Lorenz default: 1258f4baeb51SAlex Lorenz // TODO: Print the other CFI Operations. 1259f4baeb51SAlex Lorenz OS << "<unserializable cfi operation>"; 1260f4baeb51SAlex Lorenz break; 1261f4baeb51SAlex Lorenz } 1262f4baeb51SAlex Lorenz } 1263f4baeb51SAlex Lorenz 1264345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) { 1265345c1449SAlex Lorenz yaml::Output Out(OS); 1266345c1449SAlex Lorenz Out << const_cast<Module &>(M); 1267345c1449SAlex Lorenz } 1268345c1449SAlex Lorenz 1269345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) { 1270345c1449SAlex Lorenz MIRPrinter Printer(OS); 1271345c1449SAlex Lorenz Printer.print(MF); 1272345c1449SAlex Lorenz } 1273