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" 38b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h" 39b3bde2eaSDavid 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 788065f0b9SZachary Turner static cl::opt<bool> SimplifyMIR( 798065f0b9SZachary Turner "simplify-mir", cl::Hidden, 808940114fSMatthias Braun cl::desc("Leave out unnecessary information when printing MIR")); 818940114fSMatthias Braun 82345c1449SAlex Lorenz namespace { 83345c1449SAlex Lorenz 847feaf7c6SAlex Lorenz /// This structure describes how to print out stack object references. 857feaf7c6SAlex Lorenz struct FrameIndexOperand { 867feaf7c6SAlex Lorenz std::string Name; 877feaf7c6SAlex Lorenz unsigned ID; 887feaf7c6SAlex Lorenz bool IsFixed; 897feaf7c6SAlex Lorenz 907feaf7c6SAlex Lorenz FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed) 917feaf7c6SAlex Lorenz : Name(Name.str()), ID(ID), IsFixed(IsFixed) {} 927feaf7c6SAlex Lorenz 937feaf7c6SAlex Lorenz /// Return an ordinary stack object reference. 947feaf7c6SAlex Lorenz static FrameIndexOperand create(StringRef Name, unsigned ID) { 957feaf7c6SAlex Lorenz return FrameIndexOperand(Name, ID, /*IsFixed=*/false); 967feaf7c6SAlex Lorenz } 977feaf7c6SAlex Lorenz 987feaf7c6SAlex Lorenz /// Return a fixed stack object reference. 997feaf7c6SAlex Lorenz static FrameIndexOperand createFixed(unsigned ID) { 1007feaf7c6SAlex Lorenz return FrameIndexOperand("", ID, /*IsFixed=*/true); 1017feaf7c6SAlex Lorenz } 1027feaf7c6SAlex Lorenz }; 1037feaf7c6SAlex Lorenz 104618b283cSAlex Lorenz } // end anonymous namespace 105618b283cSAlex Lorenz 106618b283cSAlex Lorenz namespace llvm { 107618b283cSAlex Lorenz 108345c1449SAlex Lorenz /// This class prints out the machine functions using the MIR serialization 109345c1449SAlex Lorenz /// format. 110345c1449SAlex Lorenz class MIRPrinter { 111345c1449SAlex Lorenz raw_ostream &OS; 1128f6f4285SAlex Lorenz DenseMap<const uint32_t *, unsigned> RegisterMaskIds; 1137feaf7c6SAlex Lorenz /// Maps from stack object indices to operand indices which will be used when 1147feaf7c6SAlex Lorenz /// printing frame index machine operands. 1157feaf7c6SAlex Lorenz DenseMap<int, FrameIndexOperand> StackObjectOperandMapping; 116345c1449SAlex Lorenz 117345c1449SAlex Lorenz public: 118345c1449SAlex Lorenz MIRPrinter(raw_ostream &OS) : OS(OS) {} 119345c1449SAlex Lorenz 120345c1449SAlex Lorenz void print(const MachineFunction &MF); 1214f093bf1SAlex Lorenz 12228148ba8SAlex Lorenz void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo, 12328148ba8SAlex Lorenz const TargetRegisterInfo *TRI); 124a6f9a37dSAlex Lorenz void convert(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI, 125a6f9a37dSAlex Lorenz const MachineFrameInfo &MFI); 126ab980499SAlex Lorenz void convert(yaml::MachineFunction &MF, 127ab980499SAlex Lorenz const MachineConstantPool &ConstantPool); 1286799e9b3SAlex Lorenz void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI, 1296799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI); 130ef331effSMatthias Braun void convertStackObjects(yaml::MachineFunction &YMF, 131ef331effSMatthias Braun const MachineFunction &MF, ModuleSlotTracker &MST); 1328f6f4285SAlex Lorenz 1338f6f4285SAlex Lorenz private: 1348f6f4285SAlex Lorenz void initRegisterMaskIds(const MachineFunction &MF); 135345c1449SAlex Lorenz }; 136345c1449SAlex Lorenz 1378e0a1b48SAlex Lorenz /// This class prints out the machine instructions using the MIR serialization 1388e0a1b48SAlex Lorenz /// format. 1398e0a1b48SAlex Lorenz class MIPrinter { 1408e0a1b48SAlex Lorenz raw_ostream &OS; 141900b5cb2SAlex Lorenz ModuleSlotTracker &MST; 1428f6f4285SAlex Lorenz const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds; 1437feaf7c6SAlex Lorenz const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping; 144bb80d3e1SKonstantin Zhuravlyov /// Synchronization scope names registered with LLVMContext. 145bb80d3e1SKonstantin Zhuravlyov SmallVector<StringRef, 8> SSNs; 1468e0a1b48SAlex Lorenz 1478940114fSMatthias Braun bool canPredictBranchProbabilities(const MachineBasicBlock &MBB) const; 1488940114fSMatthias Braun bool canPredictSuccessors(const MachineBasicBlock &MBB) const; 1498940114fSMatthias Braun 1508e0a1b48SAlex Lorenz public: 151900b5cb2SAlex Lorenz MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST, 1527feaf7c6SAlex Lorenz const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds, 1537feaf7c6SAlex Lorenz const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping) 1547feaf7c6SAlex Lorenz : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds), 1557feaf7c6SAlex Lorenz StackObjectOperandMapping(StackObjectOperandMapping) {} 1568e0a1b48SAlex Lorenz 1575022f6bbSAlex Lorenz void print(const MachineBasicBlock &MBB); 1585022f6bbSAlex Lorenz 1598e0a1b48SAlex Lorenz void print(const MachineInstr &MI); 160deb53490SAlex Lorenz void printIRBlockReference(const BasicBlock &BB); 1614af7e610SAlex Lorenz void printIRValueReference(const Value &V); 1627feaf7c6SAlex Lorenz void printStackObjectReference(int FrameIndex); 163a42ed3e3SBjorn Pettersson void print(const MachineInstr &MI, unsigned OpIdx, 164a42ed3e3SBjorn Pettersson const TargetRegisterInfo *TRI, bool ShouldPrintRegisterTies, 165a8a83d15SFrancis Visoiu Mistrih LLT TypeToPrint, bool PrintDef = true); 1666748abe2SGeoff Berry void print(const LLVMContext &Context, const TargetInstrInfo &TII, 1676748abe2SGeoff Berry const MachineMemOperand &Op); 168bb80d3e1SKonstantin Zhuravlyov void printSyncScope(const LLVMContext &Context, SyncScope::ID SSID); 1698e0a1b48SAlex Lorenz }; 1708e0a1b48SAlex Lorenz 1715022f6bbSAlex Lorenz } // end namespace llvm 172345c1449SAlex Lorenz 173345c1449SAlex Lorenz namespace llvm { 174345c1449SAlex Lorenz namespace yaml { 175345c1449SAlex Lorenz 176345c1449SAlex Lorenz /// This struct serializes the LLVM IR module. 177345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> { 178345c1449SAlex Lorenz static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) { 179345c1449SAlex Lorenz Mod.print(OS, nullptr); 180345c1449SAlex Lorenz } 181fb69e66cSEugene Zelenko 182345c1449SAlex Lorenz static StringRef input(StringRef Str, void *Ctxt, Module &Mod) { 183345c1449SAlex Lorenz llvm_unreachable("LLVM Module is supposed to be parsed separately"); 184345c1449SAlex Lorenz return ""; 185345c1449SAlex Lorenz } 186345c1449SAlex Lorenz }; 187345c1449SAlex Lorenz 188345c1449SAlex Lorenz } // end namespace yaml 189345c1449SAlex Lorenz } // end namespace llvm 190345c1449SAlex Lorenz 1919d419d3bSFrancis Visoiu Mistrih static void printRegMIR(unsigned Reg, yaml::StringValue &Dest, 192ab4cbcfdSAlex Lorenz const TargetRegisterInfo *TRI) { 193ab4cbcfdSAlex Lorenz raw_string_ostream OS(Dest.Value); 194c71cced0SFrancis Visoiu Mistrih OS << printReg(Reg, TRI); 195ab4cbcfdSAlex Lorenz } 196ab4cbcfdSAlex Lorenz 197345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) { 1988f6f4285SAlex Lorenz initRegisterMaskIds(MF); 1998f6f4285SAlex Lorenz 200345c1449SAlex Lorenz yaml::MachineFunction YamlMF; 201345c1449SAlex Lorenz YamlMF.Name = MF.getName(); 2025b5f9753SAlex Lorenz YamlMF.Alignment = MF.getAlignment(); 2035b5f9753SAlex Lorenz YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice(); 204ad154c83SDerek Schuff 2050d7b0cb8SAhmed Bougacha YamlMF.Legalized = MF.getProperties().hasProperty( 2060d7b0cb8SAhmed Bougacha MachineFunctionProperties::Property::Legalized); 20724712655SAhmed Bougacha YamlMF.RegBankSelected = MF.getProperties().hasProperty( 20824712655SAhmed Bougacha MachineFunctionProperties::Property::RegBankSelected); 209b109d518SAhmed Bougacha YamlMF.Selected = MF.getProperties().hasProperty( 210b109d518SAhmed Bougacha MachineFunctionProperties::Property::Selected); 2110d7b0cb8SAhmed Bougacha 21228148ba8SAlex Lorenz convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo()); 213f1caa283SMatthias Braun ModuleSlotTracker MST(MF.getFunction().getParent()); 214f1caa283SMatthias Braun MST.incorporateFunction(MF.getFunction()); 215941a705bSMatthias Braun convert(MST, YamlMF.FrameInfo, MF.getFrameInfo()); 216ef331effSMatthias Braun convertStackObjects(YamlMF, MF, MST); 217ab980499SAlex Lorenz if (const auto *ConstantPool = MF.getConstantPool()) 218ab980499SAlex Lorenz convert(YamlMF, *ConstantPool); 2196799e9b3SAlex Lorenz if (const auto *JumpTableInfo = MF.getJumpTableInfo()) 2206799e9b3SAlex Lorenz convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo); 2215022f6bbSAlex Lorenz raw_string_ostream StrOS(YamlMF.Body.Value.Value); 2225022f6bbSAlex Lorenz bool IsNewlineNeeded = false; 2234f093bf1SAlex Lorenz for (const auto &MBB : MF) { 2245022f6bbSAlex Lorenz if (IsNewlineNeeded) 2255022f6bbSAlex Lorenz StrOS << "\n"; 2265022f6bbSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 2275022f6bbSAlex Lorenz .print(MBB); 2285022f6bbSAlex Lorenz IsNewlineNeeded = true; 2294f093bf1SAlex Lorenz } 2305022f6bbSAlex Lorenz StrOS.flush(); 231345c1449SAlex Lorenz yaml::Output Out(OS); 23256d87ef5SVivek Pandya if (!SimplifyMIR) 23356d87ef5SVivek Pandya Out.setWriteDefaultValues(true); 234345c1449SAlex Lorenz Out << YamlMF; 235345c1449SAlex Lorenz } 236345c1449SAlex Lorenz 2370ef61ec3SOren Ben Simhon static void printCustomRegMask(const uint32_t *RegMask, raw_ostream &OS, 2380ef61ec3SOren Ben Simhon const TargetRegisterInfo *TRI) { 2390ef61ec3SOren Ben Simhon assert(RegMask && "Can't print an empty register mask"); 2400ef61ec3SOren Ben Simhon OS << StringRef("CustomRegMask("); 2410ef61ec3SOren Ben Simhon 2420ef61ec3SOren Ben Simhon bool IsRegInRegMaskFound = false; 2430ef61ec3SOren Ben Simhon for (int I = 0, E = TRI->getNumRegs(); I < E; I++) { 2440ef61ec3SOren Ben Simhon // Check whether the register is asserted in regmask. 2450ef61ec3SOren Ben Simhon if (RegMask[I / 32] & (1u << (I % 32))) { 2460ef61ec3SOren Ben Simhon if (IsRegInRegMaskFound) 2470ef61ec3SOren Ben Simhon OS << ','; 248c71cced0SFrancis Visoiu Mistrih OS << printReg(I, TRI); 2490ef61ec3SOren Ben Simhon IsRegInRegMaskFound = true; 2500ef61ec3SOren Ben Simhon } 2510ef61ec3SOren Ben Simhon } 2520ef61ec3SOren Ben Simhon 2530ef61ec3SOren Ben Simhon OS << ')'; 2540ef61ec3SOren Ben Simhon } 2550ef61ec3SOren Ben Simhon 2566c452834SJustin Bogner static void printRegClassOrBank(unsigned Reg, yaml::StringValue &Dest, 2576c452834SJustin Bogner const MachineRegisterInfo &RegInfo, 2586c452834SJustin Bogner const TargetRegisterInfo *TRI) { 2596c452834SJustin Bogner raw_string_ostream OS(Dest.Value); 260a8a83d15SFrancis Visoiu Mistrih OS << printRegClassOrBank(Reg, RegInfo, TRI); 2616c452834SJustin Bogner } 2626c452834SJustin Bogner 2636c452834SJustin Bogner 26454565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 26528148ba8SAlex Lorenz const MachineRegisterInfo &RegInfo, 26628148ba8SAlex Lorenz const TargetRegisterInfo *TRI) { 26754565cf0SAlex Lorenz MF.TracksRegLiveness = RegInfo.tracksLiveness(); 26828148ba8SAlex Lorenz 26928148ba8SAlex Lorenz // Print the virtual register definitions. 27028148ba8SAlex Lorenz for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) { 27128148ba8SAlex Lorenz unsigned Reg = TargetRegisterInfo::index2VirtReg(I); 27228148ba8SAlex Lorenz yaml::VirtualRegisterDefinition VReg; 27328148ba8SAlex Lorenz VReg.ID = I; 274a8a83d15SFrancis Visoiu Mistrih ::printRegClassOrBank(Reg, VReg.Class, RegInfo, TRI); 275ab4cbcfdSAlex Lorenz unsigned PreferredReg = RegInfo.getSimpleHint(Reg); 276ab4cbcfdSAlex Lorenz if (PreferredReg) 2779d419d3bSFrancis Visoiu Mistrih printRegMIR(PreferredReg, VReg.PreferredRegister, TRI); 27828148ba8SAlex Lorenz MF.VirtualRegisters.push_back(VReg); 27928148ba8SAlex Lorenz } 28012045a4bSAlex Lorenz 28112045a4bSAlex Lorenz // Print the live ins. 28272518eaaSKrzysztof Parzyszek for (std::pair<unsigned, unsigned> LI : RegInfo.liveins()) { 28312045a4bSAlex Lorenz yaml::MachineFunctionLiveIn LiveIn; 2849d419d3bSFrancis Visoiu Mistrih printRegMIR(LI.first, LiveIn.Register, TRI); 28572518eaaSKrzysztof Parzyszek if (LI.second) 2869d419d3bSFrancis Visoiu Mistrih printRegMIR(LI.second, LiveIn.VirtualRegister, TRI); 28712045a4bSAlex Lorenz MF.LiveIns.push_back(LiveIn); 28812045a4bSAlex Lorenz } 2890ef61ec3SOren Ben Simhon 2900ef61ec3SOren Ben Simhon // Prints the callee saved registers. 2910ef61ec3SOren Ben Simhon if (RegInfo.isUpdatedCSRsInitialized()) { 2920ef61ec3SOren Ben Simhon const MCPhysReg *CalleeSavedRegs = RegInfo.getCalleeSavedRegs(); 293c4838087SAlex Lorenz std::vector<yaml::FlowStringValue> CalleeSavedRegisters; 2940ef61ec3SOren Ben Simhon for (const MCPhysReg *I = CalleeSavedRegs; *I; ++I) { 295c4838087SAlex Lorenz yaml::FlowStringValue Reg; 2969d419d3bSFrancis Visoiu Mistrih printRegMIR(*I, Reg, TRI); 297c4838087SAlex Lorenz CalleeSavedRegisters.push_back(Reg); 298c4838087SAlex Lorenz } 299c4838087SAlex Lorenz MF.CalleeSavedRegisters = CalleeSavedRegisters; 30054565cf0SAlex Lorenz } 3010ef61ec3SOren Ben Simhon } 30254565cf0SAlex Lorenz 303a6f9a37dSAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 304a6f9a37dSAlex Lorenz yaml::MachineFrameInfo &YamlMFI, 30560541c1dSAlex Lorenz const MachineFrameInfo &MFI) { 30660541c1dSAlex Lorenz YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken(); 30760541c1dSAlex Lorenz YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken(); 30860541c1dSAlex Lorenz YamlMFI.HasStackMap = MFI.hasStackMap(); 30960541c1dSAlex Lorenz YamlMFI.HasPatchPoint = MFI.hasPatchPoint(); 31060541c1dSAlex Lorenz YamlMFI.StackSize = MFI.getStackSize(); 31160541c1dSAlex Lorenz YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment(); 31260541c1dSAlex Lorenz YamlMFI.MaxAlignment = MFI.getMaxAlignment(); 31360541c1dSAlex Lorenz YamlMFI.AdjustsStack = MFI.adjustsStack(); 31460541c1dSAlex Lorenz YamlMFI.HasCalls = MFI.hasCalls(); 315ab9438cbSMatthias Braun YamlMFI.MaxCallFrameSize = MFI.isMaxCallFrameSizeComputed() 316ab9438cbSMatthias Braun ? MFI.getMaxCallFrameSize() : ~0u; 31760541c1dSAlex Lorenz YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment(); 31860541c1dSAlex Lorenz YamlMFI.HasVAStart = MFI.hasVAStart(); 31960541c1dSAlex Lorenz YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc(); 320a6f9a37dSAlex Lorenz if (MFI.getSavePoint()) { 321a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.SavePoint.Value); 32225528d6dSFrancis Visoiu Mistrih StrOS << printMBBReference(*MFI.getSavePoint()); 323a6f9a37dSAlex Lorenz } 324a6f9a37dSAlex Lorenz if (MFI.getRestorePoint()) { 325a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.RestorePoint.Value); 32625528d6dSFrancis Visoiu Mistrih StrOS << printMBBReference(*MFI.getRestorePoint()); 327a6f9a37dSAlex Lorenz } 32860541c1dSAlex Lorenz } 32960541c1dSAlex Lorenz 330ef331effSMatthias Braun void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF, 331ef331effSMatthias Braun const MachineFunction &MF, 332ef331effSMatthias Braun ModuleSlotTracker &MST) { 333ef331effSMatthias Braun const MachineFrameInfo &MFI = MF.getFrameInfo(); 334ef331effSMatthias Braun const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 335de491f05SAlex Lorenz // Process fixed stack objects. 336f6bc8667SAlex Lorenz unsigned ID = 0; 337de491f05SAlex Lorenz for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) { 338de491f05SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 339de491f05SAlex Lorenz continue; 340de491f05SAlex Lorenz 341de491f05SAlex Lorenz yaml::FixedMachineStackObject YamlObject; 3427feaf7c6SAlex Lorenz YamlObject.ID = ID; 343de491f05SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 344de491f05SAlex Lorenz ? yaml::FixedMachineStackObject::SpillSlot 345de491f05SAlex Lorenz : yaml::FixedMachineStackObject::DefaultType; 346de491f05SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 347de491f05SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 348de491f05SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 349db78273bSMatt Arsenault YamlObject.StackID = MFI.getStackID(I); 350de491f05SAlex Lorenz YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I); 351de491f05SAlex Lorenz YamlObject.IsAliased = MFI.isAliasedObjectIndex(I); 352ef331effSMatthias Braun YMF.FixedStackObjects.push_back(YamlObject); 3537feaf7c6SAlex Lorenz StackObjectOperandMapping.insert( 3547feaf7c6SAlex Lorenz std::make_pair(I, FrameIndexOperand::createFixed(ID++))); 355de491f05SAlex Lorenz } 356de491f05SAlex Lorenz 357de491f05SAlex Lorenz // Process ordinary stack objects. 358de491f05SAlex Lorenz ID = 0; 359f6bc8667SAlex Lorenz for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) { 360f6bc8667SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 361f6bc8667SAlex Lorenz continue; 362f6bc8667SAlex Lorenz 363f6bc8667SAlex Lorenz yaml::MachineStackObject YamlObject; 3647feaf7c6SAlex Lorenz YamlObject.ID = ID; 36537643a04SAlex Lorenz if (const auto *Alloca = MFI.getObjectAllocation(I)) 36637643a04SAlex Lorenz YamlObject.Name.Value = 36737643a04SAlex Lorenz Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>"; 368f6bc8667SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 369f6bc8667SAlex Lorenz ? yaml::MachineStackObject::SpillSlot 370418f3ec1SAlex Lorenz : MFI.isVariableSizedObjectIndex(I) 371418f3ec1SAlex Lorenz ? yaml::MachineStackObject::VariableSized 372f6bc8667SAlex Lorenz : yaml::MachineStackObject::DefaultType; 373f6bc8667SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 374f6bc8667SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 375f6bc8667SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 376db78273bSMatt Arsenault YamlObject.StackID = MFI.getStackID(I); 377f6bc8667SAlex Lorenz 378ef331effSMatthias Braun YMF.StackObjects.push_back(YamlObject); 3797feaf7c6SAlex Lorenz StackObjectOperandMapping.insert(std::make_pair( 3807feaf7c6SAlex Lorenz I, FrameIndexOperand::create(YamlObject.Name.Value, ID++))); 381f6bc8667SAlex Lorenz } 3821bb48de1SAlex Lorenz 3831bb48de1SAlex Lorenz for (const auto &CSInfo : MFI.getCalleeSavedInfo()) { 3841bb48de1SAlex Lorenz yaml::StringValue Reg; 3859d419d3bSFrancis Visoiu Mistrih printRegMIR(CSInfo.getReg(), Reg, TRI); 3861bb48de1SAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx()); 3871bb48de1SAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 3881bb48de1SAlex Lorenz "Invalid stack object index"); 3891bb48de1SAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 3905c3e8a45SMatthias Braun if (StackObject.IsFixed) { 391ef331effSMatthias Braun YMF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg; 3925c3e8a45SMatthias Braun YMF.FixedStackObjects[StackObject.ID].CalleeSavedRestored = 3935c3e8a45SMatthias Braun CSInfo.isRestored(); 3945c3e8a45SMatthias Braun } else { 395ef331effSMatthias Braun YMF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg; 3965c3e8a45SMatthias Braun YMF.StackObjects[StackObject.ID].CalleeSavedRestored = 3975c3e8a45SMatthias Braun CSInfo.isRestored(); 3985c3e8a45SMatthias Braun } 3991bb48de1SAlex Lorenz } 400a56ba6a6SAlex Lorenz for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) { 401a56ba6a6SAlex Lorenz auto LocalObject = MFI.getLocalFrameObjectMap(I); 402a56ba6a6SAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(LocalObject.first); 403a56ba6a6SAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 404a56ba6a6SAlex Lorenz "Invalid stack object index"); 405a56ba6a6SAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 406a56ba6a6SAlex Lorenz assert(!StackObject.IsFixed && "Expected a locally mapped stack object"); 407ef331effSMatthias Braun YMF.StackObjects[StackObject.ID].LocalOffset = LocalObject.second; 408a56ba6a6SAlex Lorenz } 409a314d813SAlex Lorenz 410a314d813SAlex Lorenz // Print the stack object references in the frame information class after 411a314d813SAlex Lorenz // converting the stack objects. 412a314d813SAlex Lorenz if (MFI.hasStackProtectorIndex()) { 413ef331effSMatthias Braun raw_string_ostream StrOS(YMF.FrameInfo.StackProtector.Value); 414a314d813SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 415a314d813SAlex Lorenz .printStackObjectReference(MFI.getStackProtectorIndex()); 416a314d813SAlex Lorenz } 417df9e3c6fSAlex Lorenz 418df9e3c6fSAlex Lorenz // Print the debug variable information. 419ef331effSMatthias Braun for (const MachineFunction::VariableDbgInfo &DebugVar : 420ef331effSMatthias Braun MF.getVariableDbgInfo()) { 421df9e3c6fSAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(DebugVar.Slot); 422df9e3c6fSAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 423df9e3c6fSAlex Lorenz "Invalid stack object index"); 424df9e3c6fSAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 425df9e3c6fSAlex Lorenz assert(!StackObject.IsFixed && "Expected a non-fixed stack object"); 426ef331effSMatthias Braun auto &Object = YMF.StackObjects[StackObject.ID]; 427df9e3c6fSAlex Lorenz { 428df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugVar.Value); 429df9e3c6fSAlex Lorenz DebugVar.Var->printAsOperand(StrOS, MST); 430df9e3c6fSAlex Lorenz } 431df9e3c6fSAlex Lorenz { 432df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugExpr.Value); 433df9e3c6fSAlex Lorenz DebugVar.Expr->printAsOperand(StrOS, MST); 434df9e3c6fSAlex Lorenz } 435df9e3c6fSAlex Lorenz { 436df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugLoc.Value); 437df9e3c6fSAlex Lorenz DebugVar.Loc->printAsOperand(StrOS, MST); 438df9e3c6fSAlex Lorenz } 439df9e3c6fSAlex Lorenz } 440f6bc8667SAlex Lorenz } 441f6bc8667SAlex Lorenz 442ab980499SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 443ab980499SAlex Lorenz const MachineConstantPool &ConstantPool) { 444ab980499SAlex Lorenz unsigned ID = 0; 445ab980499SAlex Lorenz for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) { 446ab980499SAlex Lorenz std::string Str; 447ab980499SAlex Lorenz raw_string_ostream StrOS(Str); 448d5a00b0fSDiana Picus if (Constant.isMachineConstantPoolEntry()) { 449d5a00b0fSDiana Picus Constant.Val.MachineCPVal->print(StrOS); 450d5a00b0fSDiana Picus } else { 451ab980499SAlex Lorenz Constant.Val.ConstVal->printAsOperand(StrOS); 452d5a00b0fSDiana Picus } 453d5a00b0fSDiana Picus 454d5a00b0fSDiana Picus yaml::MachineConstantPoolValue YamlConstant; 455ab980499SAlex Lorenz YamlConstant.ID = ID++; 456ab980499SAlex Lorenz YamlConstant.Value = StrOS.str(); 457ab980499SAlex Lorenz YamlConstant.Alignment = Constant.getAlignment(); 458d5a00b0fSDiana Picus YamlConstant.IsTargetSpecific = Constant.isMachineConstantPoolEntry(); 459d5a00b0fSDiana Picus 460ab980499SAlex Lorenz MF.Constants.push_back(YamlConstant); 461ab980499SAlex Lorenz } 462ab980499SAlex Lorenz } 463ab980499SAlex Lorenz 464900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 4656799e9b3SAlex Lorenz yaml::MachineJumpTable &YamlJTI, 4666799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI) { 4676799e9b3SAlex Lorenz YamlJTI.Kind = JTI.getEntryKind(); 4686799e9b3SAlex Lorenz unsigned ID = 0; 4696799e9b3SAlex Lorenz for (const auto &Table : JTI.getJumpTables()) { 4706799e9b3SAlex Lorenz std::string Str; 4716799e9b3SAlex Lorenz yaml::MachineJumpTable::Entry Entry; 4726799e9b3SAlex Lorenz Entry.ID = ID++; 4736799e9b3SAlex Lorenz for (const auto *MBB : Table.MBBs) { 4746799e9b3SAlex Lorenz raw_string_ostream StrOS(Str); 47525528d6dSFrancis Visoiu Mistrih StrOS << printMBBReference(*MBB); 4766799e9b3SAlex Lorenz Entry.Blocks.push_back(StrOS.str()); 4776799e9b3SAlex Lorenz Str.clear(); 4786799e9b3SAlex Lorenz } 4796799e9b3SAlex Lorenz YamlJTI.Entries.push_back(Entry); 4806799e9b3SAlex Lorenz } 4816799e9b3SAlex Lorenz } 4826799e9b3SAlex Lorenz 4838f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) { 4848f6f4285SAlex Lorenz const auto *TRI = MF.getSubtarget().getRegisterInfo(); 4858f6f4285SAlex Lorenz unsigned I = 0; 4868f6f4285SAlex Lorenz for (const uint32_t *Mask : TRI->getRegMasks()) 4878f6f4285SAlex Lorenz RegisterMaskIds.insert(std::make_pair(Mask, I++)); 4888f6f4285SAlex Lorenz } 4898f6f4285SAlex Lorenz 4908940114fSMatthias Braun void llvm::guessSuccessors(const MachineBasicBlock &MBB, 4918940114fSMatthias Braun SmallVectorImpl<MachineBasicBlock*> &Result, 4928940114fSMatthias Braun bool &IsFallthrough) { 4938940114fSMatthias Braun SmallPtrSet<MachineBasicBlock*,8> Seen; 4948940114fSMatthias Braun 4958940114fSMatthias Braun for (const MachineInstr &MI : MBB) { 4968940114fSMatthias Braun if (MI.isPHI()) 4978940114fSMatthias Braun continue; 4988940114fSMatthias Braun for (const MachineOperand &MO : MI.operands()) { 4998940114fSMatthias Braun if (!MO.isMBB()) 5008940114fSMatthias Braun continue; 5018940114fSMatthias Braun MachineBasicBlock *Succ = MO.getMBB(); 5028940114fSMatthias Braun auto RP = Seen.insert(Succ); 5038940114fSMatthias Braun if (RP.second) 5048940114fSMatthias Braun Result.push_back(Succ); 5058940114fSMatthias Braun } 5068940114fSMatthias Braun } 5078940114fSMatthias Braun MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr(); 5088940114fSMatthias Braun IsFallthrough = I == MBB.end() || !I->isBarrier(); 5098940114fSMatthias Braun } 5108940114fSMatthias Braun 5118940114fSMatthias Braun bool 5128940114fSMatthias Braun MIPrinter::canPredictBranchProbabilities(const MachineBasicBlock &MBB) const { 5138940114fSMatthias Braun if (MBB.succ_size() <= 1) 5148940114fSMatthias Braun return true; 5158940114fSMatthias Braun if (!MBB.hasSuccessorProbabilities()) 5168940114fSMatthias Braun return true; 5178940114fSMatthias Braun 5188940114fSMatthias Braun SmallVector<BranchProbability,8> Normalized(MBB.Probs.begin(), 5198940114fSMatthias Braun MBB.Probs.end()); 5208940114fSMatthias Braun BranchProbability::normalizeProbabilities(Normalized.begin(), 5218940114fSMatthias Braun Normalized.end()); 5228940114fSMatthias Braun SmallVector<BranchProbability,8> Equal(Normalized.size()); 5238940114fSMatthias Braun BranchProbability::normalizeProbabilities(Equal.begin(), Equal.end()); 5248940114fSMatthias Braun 5258940114fSMatthias Braun return std::equal(Normalized.begin(), Normalized.end(), Equal.begin()); 5268940114fSMatthias Braun } 5278940114fSMatthias Braun 5288940114fSMatthias Braun bool MIPrinter::canPredictSuccessors(const MachineBasicBlock &MBB) const { 5298940114fSMatthias Braun SmallVector<MachineBasicBlock*,8> GuessedSuccs; 5308940114fSMatthias Braun bool GuessedFallthrough; 5318940114fSMatthias Braun guessSuccessors(MBB, GuessedSuccs, GuessedFallthrough); 5328940114fSMatthias Braun if (GuessedFallthrough) { 5338940114fSMatthias Braun const MachineFunction &MF = *MBB.getParent(); 5348940114fSMatthias Braun MachineFunction::const_iterator NextI = std::next(MBB.getIterator()); 5358940114fSMatthias Braun if (NextI != MF.end()) { 5368940114fSMatthias Braun MachineBasicBlock *Next = const_cast<MachineBasicBlock*>(&*NextI); 5378940114fSMatthias Braun if (!is_contained(GuessedSuccs, Next)) 5388940114fSMatthias Braun GuessedSuccs.push_back(Next); 5398940114fSMatthias Braun } 5408940114fSMatthias Braun } 5418940114fSMatthias Braun if (GuessedSuccs.size() != MBB.succ_size()) 5428940114fSMatthias Braun return false; 5438940114fSMatthias Braun return std::equal(MBB.succ_begin(), MBB.succ_end(), GuessedSuccs.begin()); 5448940114fSMatthias Braun } 5458940114fSMatthias Braun 5465022f6bbSAlex Lorenz void MIPrinter::print(const MachineBasicBlock &MBB) { 5475022f6bbSAlex Lorenz assert(MBB.getNumber() >= 0 && "Invalid MBB number"); 5485022f6bbSAlex Lorenz OS << "bb." << MBB.getNumber(); 5495022f6bbSAlex Lorenz bool HasAttributes = false; 5505022f6bbSAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 5515022f6bbSAlex Lorenz if (BB->hasName()) { 5525022f6bbSAlex Lorenz OS << "." << BB->getName(); 5535022f6bbSAlex Lorenz } else { 5545022f6bbSAlex Lorenz HasAttributes = true; 5555022f6bbSAlex Lorenz OS << " ("; 5565022f6bbSAlex Lorenz int Slot = MST.getLocalSlot(BB); 5575022f6bbSAlex Lorenz if (Slot == -1) 5585022f6bbSAlex Lorenz OS << "<ir-block badref>"; 5595022f6bbSAlex Lorenz else 5605022f6bbSAlex Lorenz OS << (Twine("%ir-block.") + Twine(Slot)).str(); 5615022f6bbSAlex Lorenz } 5625022f6bbSAlex Lorenz } 5635022f6bbSAlex Lorenz if (MBB.hasAddressTaken()) { 5645022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 5655022f6bbSAlex Lorenz OS << "address-taken"; 5665022f6bbSAlex Lorenz HasAttributes = true; 5675022f6bbSAlex Lorenz } 5680e288234SReid Kleckner if (MBB.isEHPad()) { 5695022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 5705022f6bbSAlex Lorenz OS << "landing-pad"; 5715022f6bbSAlex Lorenz HasAttributes = true; 5725022f6bbSAlex Lorenz } 5735022f6bbSAlex Lorenz if (MBB.getAlignment()) { 5745022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 5755022f6bbSAlex Lorenz OS << "align " << MBB.getAlignment(); 5765022f6bbSAlex Lorenz HasAttributes = true; 5775022f6bbSAlex Lorenz } 5785022f6bbSAlex Lorenz if (HasAttributes) 5795022f6bbSAlex Lorenz OS << ")"; 5805022f6bbSAlex Lorenz OS << ":\n"; 5815022f6bbSAlex Lorenz 5825022f6bbSAlex Lorenz bool HasLineAttributes = false; 5835022f6bbSAlex Lorenz // Print the successors 5848940114fSMatthias Braun bool canPredictProbs = canPredictBranchProbabilities(MBB); 585d652aeb1SQuentin Colombet // Even if the list of successors is empty, if we cannot guess it, 586d652aeb1SQuentin Colombet // we need to print it to tell the parser that the list is empty. 587d652aeb1SQuentin Colombet // This is needed, because MI model unreachable as empty blocks 588d652aeb1SQuentin Colombet // with an empty successor list. If the parser would see that 589d652aeb1SQuentin Colombet // without the successor list, it would guess the code would 590d652aeb1SQuentin Colombet // fallthrough. 591d652aeb1SQuentin Colombet if ((!MBB.succ_empty() && !SimplifyMIR) || !canPredictProbs || 592d652aeb1SQuentin Colombet !canPredictSuccessors(MBB)) { 5935022f6bbSAlex Lorenz OS.indent(2) << "successors: "; 5945022f6bbSAlex Lorenz for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) { 5955022f6bbSAlex Lorenz if (I != MBB.succ_begin()) 5965022f6bbSAlex Lorenz OS << ", "; 59725528d6dSFrancis Visoiu Mistrih OS << printMBBReference(**I); 5988940114fSMatthias Braun if (!SimplifyMIR || !canPredictProbs) 599b51774acSGeoff Berry OS << '(' 600b51774acSGeoff Berry << format("0x%08" PRIx32, MBB.getSuccProbability(I).getNumerator()) 601b51774acSGeoff Berry << ')'; 6025022f6bbSAlex Lorenz } 6035022f6bbSAlex Lorenz OS << "\n"; 6045022f6bbSAlex Lorenz HasLineAttributes = true; 6055022f6bbSAlex Lorenz } 6065022f6bbSAlex Lorenz 6075022f6bbSAlex Lorenz // Print the live in registers. 60811723322SMatthias Braun const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 60911723322SMatthias Braun if (MRI.tracksLiveness() && !MBB.livein_empty()) { 61011723322SMatthias Braun const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); 6115022f6bbSAlex Lorenz OS.indent(2) << "liveins: "; 612b2b7ef1dSMatthias Braun bool First = true; 613d9da1627SMatthias Braun for (const auto &LI : MBB.liveins()) { 614b2b7ef1dSMatthias Braun if (!First) 6155022f6bbSAlex Lorenz OS << ", "; 616b2b7ef1dSMatthias Braun First = false; 617c71cced0SFrancis Visoiu Mistrih OS << printReg(LI.PhysReg, &TRI); 61891b5cf84SKrzysztof Parzyszek if (!LI.LaneMask.all()) 619d62669d7SKrzysztof Parzyszek OS << ":0x" << PrintLaneMask(LI.LaneMask); 6205022f6bbSAlex Lorenz } 6215022f6bbSAlex Lorenz OS << "\n"; 6225022f6bbSAlex Lorenz HasLineAttributes = true; 6235022f6bbSAlex Lorenz } 6245022f6bbSAlex Lorenz 6255022f6bbSAlex Lorenz if (HasLineAttributes) 6265022f6bbSAlex Lorenz OS << "\n"; 627f9a2b123SAlex Lorenz bool IsInBundle = false; 628f9a2b123SAlex Lorenz for (auto I = MBB.instr_begin(), E = MBB.instr_end(); I != E; ++I) { 629f9a2b123SAlex Lorenz const MachineInstr &MI = *I; 630f9a2b123SAlex Lorenz if (IsInBundle && !MI.isInsideBundle()) { 631f9a2b123SAlex Lorenz OS.indent(2) << "}\n"; 632f9a2b123SAlex Lorenz IsInBundle = false; 633f9a2b123SAlex Lorenz } 634f9a2b123SAlex Lorenz OS.indent(IsInBundle ? 4 : 2); 6355022f6bbSAlex Lorenz print(MI); 636f9a2b123SAlex Lorenz if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) { 637f9a2b123SAlex Lorenz OS << " {"; 638f9a2b123SAlex Lorenz IsInBundle = true; 639f9a2b123SAlex Lorenz } 6405022f6bbSAlex Lorenz OS << "\n"; 6415022f6bbSAlex Lorenz } 642f9a2b123SAlex Lorenz if (IsInBundle) 643f9a2b123SAlex Lorenz OS.indent(2) << "}\n"; 6445022f6bbSAlex Lorenz } 6455022f6bbSAlex Lorenz 6468e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) { 647fdf9bf4fSJustin Bogner const auto *MF = MI.getMF(); 6484e14a497SQuentin Colombet const auto &MRI = MF->getRegInfo(); 6494e14a497SQuentin Colombet const auto &SubTarget = MF->getSubtarget(); 650f3db51deSAlex Lorenz const auto *TRI = SubTarget.getRegisterInfo(); 651f3db51deSAlex Lorenz assert(TRI && "Expected target register info"); 6528e0a1b48SAlex Lorenz const auto *TII = SubTarget.getInstrInfo(); 6538e0a1b48SAlex Lorenz assert(TII && "Expected target instruction info"); 654f4baeb51SAlex Lorenz if (MI.isCFIInstruction()) 655f4baeb51SAlex Lorenz assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction"); 6568e0a1b48SAlex Lorenz 657d28d3cc0STim Northover SmallBitVector PrintedTypes(8); 658a8a83d15SFrancis Visoiu Mistrih bool ShouldPrintRegisterTies = MI.hasComplexRegisterTies(); 659f3db51deSAlex Lorenz unsigned I = 0, E = MI.getNumOperands(); 660f3db51deSAlex Lorenz for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() && 661f3db51deSAlex Lorenz !MI.getOperand(I).isImplicit(); 662f3db51deSAlex Lorenz ++I) { 663f3db51deSAlex Lorenz if (I) 664f3db51deSAlex Lorenz OS << ", "; 665a42ed3e3SBjorn Pettersson print(MI, I, TRI, ShouldPrintRegisterTies, 666a8a83d15SFrancis Visoiu Mistrih MI.getTypeToPrint(I, PrintedTypes, MRI), 667a8a83d15SFrancis Visoiu Mistrih /*PrintDef=*/false); 668f3db51deSAlex Lorenz } 669f3db51deSAlex Lorenz 670f3db51deSAlex Lorenz if (I) 671f3db51deSAlex Lorenz OS << " = "; 672e5a44660SAlex Lorenz if (MI.getFlag(MachineInstr::FrameSetup)) 673e5a44660SAlex Lorenz OS << "frame-setup "; 6748e0a1b48SAlex Lorenz OS << TII->getName(MI.getOpcode()); 675f3db51deSAlex Lorenz if (I < E) 676f3db51deSAlex Lorenz OS << ' '; 677f3db51deSAlex Lorenz 678f3db51deSAlex Lorenz bool NeedComma = false; 679f3db51deSAlex Lorenz for (; I < E; ++I) { 680f3db51deSAlex Lorenz if (NeedComma) 681f3db51deSAlex Lorenz OS << ", "; 682a42ed3e3SBjorn Pettersson print(MI, I, TRI, ShouldPrintRegisterTies, 683a8a83d15SFrancis Visoiu Mistrih MI.getTypeToPrint(I, PrintedTypes, MRI)); 684f3db51deSAlex Lorenz NeedComma = true; 685f3db51deSAlex Lorenz } 68646d760d1SAlex Lorenz 68746d760d1SAlex Lorenz if (MI.getDebugLoc()) { 68846d760d1SAlex Lorenz if (NeedComma) 68946d760d1SAlex Lorenz OS << ','; 69046d760d1SAlex Lorenz OS << " debug-location "; 69146d760d1SAlex Lorenz MI.getDebugLoc()->printAsOperand(OS, MST); 69246d760d1SAlex Lorenz } 6934af7e610SAlex Lorenz 6944af7e610SAlex Lorenz if (!MI.memoperands_empty()) { 6954af7e610SAlex Lorenz OS << " :: "; 696f1caa283SMatthias Braun const LLVMContext &Context = MF->getFunction().getContext(); 6974af7e610SAlex Lorenz bool NeedComma = false; 6984af7e610SAlex Lorenz for (const auto *Op : MI.memoperands()) { 6994af7e610SAlex Lorenz if (NeedComma) 7004af7e610SAlex Lorenz OS << ", "; 7016748abe2SGeoff Berry print(Context, *TII, *Op); 7024af7e610SAlex Lorenz NeedComma = true; 7034af7e610SAlex Lorenz } 7044af7e610SAlex Lorenz } 705f3db51deSAlex Lorenz } 706f3db51deSAlex Lorenz 70755dc6f81SAlex Lorenz static void printIRSlotNumber(raw_ostream &OS, int Slot) { 70855dc6f81SAlex Lorenz if (Slot == -1) 70955dc6f81SAlex Lorenz OS << "<badref>"; 71055dc6f81SAlex Lorenz else 71155dc6f81SAlex Lorenz OS << Slot; 71255dc6f81SAlex Lorenz } 71355dc6f81SAlex Lorenz 714deb53490SAlex Lorenz void MIPrinter::printIRBlockReference(const BasicBlock &BB) { 715deb53490SAlex Lorenz OS << "%ir-block."; 716deb53490SAlex Lorenz if (BB.hasName()) { 717deb53490SAlex Lorenz printLLVMNameWithoutPrefix(OS, BB.getName()); 718deb53490SAlex Lorenz return; 719deb53490SAlex Lorenz } 720cba8c5feSAlex Lorenz const Function *F = BB.getParent(); 721cba8c5feSAlex Lorenz int Slot; 722cba8c5feSAlex Lorenz if (F == MST.getCurrentFunction()) { 723cba8c5feSAlex Lorenz Slot = MST.getLocalSlot(&BB); 724cba8c5feSAlex Lorenz } else { 725cba8c5feSAlex Lorenz ModuleSlotTracker CustomMST(F->getParent(), 726cba8c5feSAlex Lorenz /*ShouldInitializeAllMetadata=*/false); 727cba8c5feSAlex Lorenz CustomMST.incorporateFunction(*F); 728cba8c5feSAlex Lorenz Slot = CustomMST.getLocalSlot(&BB); 729cba8c5feSAlex Lorenz } 73055dc6f81SAlex Lorenz printIRSlotNumber(OS, Slot); 731deb53490SAlex Lorenz } 732deb53490SAlex Lorenz 7334af7e610SAlex Lorenz void MIPrinter::printIRValueReference(const Value &V) { 73436efd388SAlex Lorenz if (isa<GlobalValue>(V)) { 73536efd388SAlex Lorenz V.printAsOperand(OS, /*PrintType=*/false, MST); 73636efd388SAlex Lorenz return; 73736efd388SAlex Lorenz } 738c1136ef3SAlex Lorenz if (isa<Constant>(V)) { 739c1136ef3SAlex Lorenz // Machine memory operands can load/store to/from constant value pointers. 740c1136ef3SAlex Lorenz OS << '`'; 741c1136ef3SAlex Lorenz V.printAsOperand(OS, /*PrintType=*/true, MST); 742c1136ef3SAlex Lorenz OS << '`'; 743c1136ef3SAlex Lorenz return; 744c1136ef3SAlex Lorenz } 7454af7e610SAlex Lorenz OS << "%ir."; 7464af7e610SAlex Lorenz if (V.hasName()) { 7474af7e610SAlex Lorenz printLLVMNameWithoutPrefix(OS, V.getName()); 7484af7e610SAlex Lorenz return; 7494af7e610SAlex Lorenz } 750dd13be0bSAlex Lorenz printIRSlotNumber(OS, MST.getLocalSlot(&V)); 7514af7e610SAlex Lorenz } 7524af7e610SAlex Lorenz 7537feaf7c6SAlex Lorenz void MIPrinter::printStackObjectReference(int FrameIndex) { 7547feaf7c6SAlex Lorenz auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex); 7557feaf7c6SAlex Lorenz assert(ObjectInfo != StackObjectOperandMapping.end() && 7567feaf7c6SAlex Lorenz "Invalid frame index"); 7577feaf7c6SAlex Lorenz const FrameIndexOperand &Operand = ObjectInfo->second; 7580b5bdceaSFrancis Visoiu Mistrih MachineOperand::printStackObjectReference(OS, Operand.ID, Operand.IsFixed, 7590b5bdceaSFrancis Visoiu Mistrih Operand.Name); 7607feaf7c6SAlex Lorenz } 7617feaf7c6SAlex Lorenz 762a42ed3e3SBjorn Pettersson void MIPrinter::print(const MachineInstr &MI, unsigned OpIdx, 763a42ed3e3SBjorn Pettersson const TargetRegisterInfo *TRI, 764a42ed3e3SBjorn Pettersson bool ShouldPrintRegisterTies, LLT TypeToPrint, 765a8a83d15SFrancis Visoiu Mistrih bool PrintDef) { 766a42ed3e3SBjorn Pettersson const MachineOperand &Op = MI.getOperand(OpIdx); 767f3db51deSAlex Lorenz switch (Op.getType()) { 768440f69c9SFrancis Visoiu Mistrih case MachineOperand::MO_Immediate: 769440f69c9SFrancis Visoiu Mistrih if (MI.isOperandSubregIdx(OpIdx)) { 7705df3bbf3SFrancis Visoiu Mistrih MachineOperand::printTargetFlags(OS, Op); 771440f69c9SFrancis Visoiu Mistrih MachineOperand::printSubregIdx(OS, Op.getImm(), TRI); 772440f69c9SFrancis Visoiu Mistrih break; 773440f69c9SFrancis Visoiu Mistrih } 774440f69c9SFrancis Visoiu Mistrih LLVM_FALLTHROUGH; 7756c4ca713SFrancis Visoiu Mistrih case MachineOperand::MO_Register: 776f4bd2955SFrancis Visoiu Mistrih case MachineOperand::MO_CImmediate: 7773b265c8fSFrancis Visoiu Mistrih case MachineOperand::MO_FPImmediate: 77826ae8a65SFrancis Visoiu Mistrih case MachineOperand::MO_MachineBasicBlock: 779b3a0d513SFrancis Visoiu Mistrih case MachineOperand::MO_ConstantPoolIndex: 780b41dbbe3SFrancis Visoiu Mistrih case MachineOperand::MO_TargetIndex: 781e76c5fcdSFrancis Visoiu Mistrih case MachineOperand::MO_JumpTableIndex: 7825df3bbf3SFrancis Visoiu Mistrih case MachineOperand::MO_ExternalSymbol: 783bdaf8bfaSFrancis Visoiu Mistrih case MachineOperand::MO_GlobalAddress: 7842db59382SFrancis Visoiu Mistrih case MachineOperand::MO_RegisterLiveOut: 7853c99371cSFrancis Visoiu Mistrih case MachineOperand::MO_Metadata: 786874ae6faSFrancis Visoiu Mistrih case MachineOperand::MO_MCSymbol: 787*bbd610aeSFrancis Visoiu Mistrih case MachineOperand::MO_CFIIndex: 788*bbd610aeSFrancis Visoiu Mistrih case MachineOperand::MO_IntrinsicID: { 789a8a83d15SFrancis Visoiu Mistrih unsigned TiedOperandIdx = 0; 790440f69c9SFrancis Visoiu Mistrih if (ShouldPrintRegisterTies && Op.isReg() && Op.isTied() && !Op.isDef()) 791a8a83d15SFrancis Visoiu Mistrih TiedOperandIdx = Op.getParent()->findTiedOperandIdx(OpIdx); 792a8a83d15SFrancis Visoiu Mistrih const TargetIntrinsicInfo *TII = MI.getMF()->getTarget().getIntrinsicInfo(); 793a8a83d15SFrancis Visoiu Mistrih Op.print(OS, MST, TypeToPrint, PrintDef, ShouldPrintRegisterTies, 794a8a83d15SFrancis Visoiu Mistrih TiedOperandIdx, TRI, TII); 795f3db51deSAlex Lorenz break; 7966c452834SJustin Bogner } 7977feaf7c6SAlex Lorenz case MachineOperand::MO_FrameIndex: 7987feaf7c6SAlex Lorenz printStackObjectReference(Op.getIndex()); 7997feaf7c6SAlex Lorenz break; 800deb53490SAlex Lorenz case MachineOperand::MO_BlockAddress: 801deb53490SAlex Lorenz OS << "blockaddress("; 802deb53490SAlex Lorenz Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, 803deb53490SAlex Lorenz MST); 804deb53490SAlex Lorenz OS << ", "; 805deb53490SAlex Lorenz printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); 806deb53490SAlex Lorenz OS << ')'; 80781226602SFrancis Visoiu Mistrih MachineOperand::printOperandOffset(Op.getOffset()); 808deb53490SAlex Lorenz break; 8098f6f4285SAlex Lorenz case MachineOperand::MO_RegisterMask: { 8108f6f4285SAlex Lorenz auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); 8118f6f4285SAlex Lorenz if (RegMaskInfo != RegisterMaskIds.end()) 8128f6f4285SAlex Lorenz OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); 8138f6f4285SAlex Lorenz else 8140ef61ec3SOren Ben Simhon printCustomRegMask(Op.getRegMask(), OS, TRI); 8158f6f4285SAlex Lorenz break; 8168f6f4285SAlex Lorenz } 817de3aea04STim Northover case MachineOperand::MO_Predicate: { 818de3aea04STim Northover auto Pred = static_cast<CmpInst::Predicate>(Op.getPredicate()); 819de3aea04STim Northover OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred(" 820de3aea04STim Northover << CmpInst::getPredicateName(Pred) << ')'; 821de3aea04STim Northover break; 822de3aea04STim Northover } 823f3db51deSAlex Lorenz } 8244f093bf1SAlex Lorenz } 8254f093bf1SAlex Lorenz 8266748abe2SGeoff Berry static const char *getTargetMMOFlagName(const TargetInstrInfo &TII, 8276748abe2SGeoff Berry unsigned TMMOFlag) { 8286748abe2SGeoff Berry auto Flags = TII.getSerializableMachineMemOperandTargetFlags(); 8296748abe2SGeoff Berry for (const auto &I : Flags) { 8306748abe2SGeoff Berry if (I.first == TMMOFlag) { 8316748abe2SGeoff Berry return I.second; 8326748abe2SGeoff Berry } 8336748abe2SGeoff Berry } 8346748abe2SGeoff Berry return nullptr; 8356748abe2SGeoff Berry } 8366748abe2SGeoff Berry 8376748abe2SGeoff Berry void MIPrinter::print(const LLVMContext &Context, const TargetInstrInfo &TII, 8386748abe2SGeoff Berry const MachineMemOperand &Op) { 8394af7e610SAlex Lorenz OS << '('; 840a518b796SAlex Lorenz if (Op.isVolatile()) 841a518b796SAlex Lorenz OS << "volatile "; 84210fd0385SAlex Lorenz if (Op.isNonTemporal()) 84310fd0385SAlex Lorenz OS << "non-temporal "; 844adbf09e8SJustin Lebar if (Op.isDereferenceable()) 845adbf09e8SJustin Lebar OS << "dereferenceable "; 846dc8de2a6SAlex Lorenz if (Op.isInvariant()) 847dc8de2a6SAlex Lorenz OS << "invariant "; 8486748abe2SGeoff Berry if (Op.getFlags() & MachineMemOperand::MOTargetFlag1) 8496748abe2SGeoff Berry OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag1) 8506748abe2SGeoff Berry << "\" "; 8516748abe2SGeoff Berry if (Op.getFlags() & MachineMemOperand::MOTargetFlag2) 8526748abe2SGeoff Berry OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag2) 8536748abe2SGeoff Berry << "\" "; 8546748abe2SGeoff Berry if (Op.getFlags() & MachineMemOperand::MOTargetFlag3) 8556748abe2SGeoff Berry OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag3) 8566748abe2SGeoff Berry << "\" "; 85717d277b7SDaniel Sanders 85817d277b7SDaniel Sanders assert((Op.isLoad() || Op.isStore()) && "machine memory operand must be a load or store (or both)"); 8594af7e610SAlex Lorenz if (Op.isLoad()) 8604af7e610SAlex Lorenz OS << "load "; 86117d277b7SDaniel Sanders if (Op.isStore()) 8624af7e610SAlex Lorenz OS << "store "; 863b73e3090STim Northover 864bb80d3e1SKonstantin Zhuravlyov printSyncScope(Context, Op.getSyncScopeID()); 865b73e3090STim Northover 866b73e3090STim Northover if (Op.getOrdering() != AtomicOrdering::NotAtomic) 867b73e3090STim Northover OS << toIRString(Op.getOrdering()) << ' '; 868b73e3090STim Northover if (Op.getFailureOrdering() != AtomicOrdering::NotAtomic) 869b73e3090STim Northover OS << toIRString(Op.getFailureOrdering()) << ' '; 870b73e3090STim Northover 871c25c9ccbSMatthias Braun OS << Op.getSize(); 87291097a3fSAlex Lorenz if (const Value *Val = Op.getValue()) { 87317d277b7SDaniel Sanders OS << ((Op.isLoad() && Op.isStore()) ? " on " 87417d277b7SDaniel Sanders : Op.isLoad() ? " from " : " into "); 8754af7e610SAlex Lorenz printIRValueReference(*Val); 876c25c9ccbSMatthias Braun } else if (const PseudoSourceValue *PVal = Op.getPseudoValue()) { 87717d277b7SDaniel Sanders OS << ((Op.isLoad() && Op.isStore()) ? " on " 87817d277b7SDaniel Sanders : Op.isLoad() ? " from " : " into "); 87991097a3fSAlex Lorenz assert(PVal && "Expected a pseudo source value"); 88091097a3fSAlex Lorenz switch (PVal->kind()) { 88146e9558aSAlex Lorenz case PseudoSourceValue::Stack: 88246e9558aSAlex Lorenz OS << "stack"; 88346e9558aSAlex Lorenz break; 884d858f874SAlex Lorenz case PseudoSourceValue::GOT: 885d858f874SAlex Lorenz OS << "got"; 886d858f874SAlex Lorenz break; 8874be56e93SAlex Lorenz case PseudoSourceValue::JumpTable: 8884be56e93SAlex Lorenz OS << "jump-table"; 8894be56e93SAlex Lorenz break; 89091097a3fSAlex Lorenz case PseudoSourceValue::ConstantPool: 89191097a3fSAlex Lorenz OS << "constant-pool"; 89291097a3fSAlex Lorenz break; 8930cc671bfSAlex Lorenz case PseudoSourceValue::FixedStack: 8940cc671bfSAlex Lorenz printStackObjectReference( 8950cc671bfSAlex Lorenz cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex()); 8960cc671bfSAlex Lorenz break; 89750b826fbSAlex Lorenz case PseudoSourceValue::GlobalValueCallEntry: 8980d009645SAlex Lorenz OS << "call-entry "; 89950b826fbSAlex Lorenz cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand( 90050b826fbSAlex Lorenz OS, /*PrintType=*/false, MST); 90150b826fbSAlex Lorenz break; 902c3ba7508SAlex Lorenz case PseudoSourceValue::ExternalSymbolCallEntry: 9030d009645SAlex Lorenz OS << "call-entry $"; 904c3ba7508SAlex Lorenz printLLVMNameWithoutPrefix( 905c3ba7508SAlex Lorenz OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol()); 90691097a3fSAlex Lorenz break; 9077761abb6STom Stellard case PseudoSourceValue::TargetCustom: 9087761abb6STom Stellard llvm_unreachable("TargetCustom pseudo source values are not supported"); 9097761abb6STom Stellard break; 91091097a3fSAlex Lorenz } 91191097a3fSAlex Lorenz } 91281226602SFrancis Visoiu Mistrih MachineOperand::printOperandOffset(OS, Op.getOffset()); 91361420f79SAlex Lorenz if (Op.getBaseAlignment() != Op.getSize()) 91461420f79SAlex Lorenz OS << ", align " << Op.getBaseAlignment(); 915a617c916SAlex Lorenz auto AAInfo = Op.getAAInfo(); 916a617c916SAlex Lorenz if (AAInfo.TBAA) { 917a617c916SAlex Lorenz OS << ", !tbaa "; 918a617c916SAlex Lorenz AAInfo.TBAA->printAsOperand(OS, MST); 919a617c916SAlex Lorenz } 920a16f624dSAlex Lorenz if (AAInfo.Scope) { 921a16f624dSAlex Lorenz OS << ", !alias.scope "; 922a16f624dSAlex Lorenz AAInfo.Scope->printAsOperand(OS, MST); 923a16f624dSAlex Lorenz } 92403e940d1SAlex Lorenz if (AAInfo.NoAlias) { 92503e940d1SAlex Lorenz OS << ", !noalias "; 92603e940d1SAlex Lorenz AAInfo.NoAlias->printAsOperand(OS, MST); 92703e940d1SAlex Lorenz } 928eb625686SAlex Lorenz if (Op.getRanges()) { 929eb625686SAlex Lorenz OS << ", !range "; 930eb625686SAlex Lorenz Op.getRanges()->printAsOperand(OS, MST); 931eb625686SAlex Lorenz } 9324af7e610SAlex Lorenz OS << ')'; 9334af7e610SAlex Lorenz } 9344af7e610SAlex Lorenz 935bb80d3e1SKonstantin Zhuravlyov void MIPrinter::printSyncScope(const LLVMContext &Context, SyncScope::ID SSID) { 936bb80d3e1SKonstantin Zhuravlyov switch (SSID) { 937bb80d3e1SKonstantin Zhuravlyov case SyncScope::System: { 938bb80d3e1SKonstantin Zhuravlyov break; 939bb80d3e1SKonstantin Zhuravlyov } 940bb80d3e1SKonstantin Zhuravlyov default: { 941bb80d3e1SKonstantin Zhuravlyov if (SSNs.empty()) 942bb80d3e1SKonstantin Zhuravlyov Context.getSyncScopeNames(SSNs); 943bb80d3e1SKonstantin Zhuravlyov 944bb80d3e1SKonstantin Zhuravlyov OS << "syncscope(\""; 945bb80d3e1SKonstantin Zhuravlyov PrintEscapedString(SSNs[SSID], OS); 946bb80d3e1SKonstantin Zhuravlyov OS << "\") "; 947bb80d3e1SKonstantin Zhuravlyov break; 948bb80d3e1SKonstantin Zhuravlyov } 949bb80d3e1SKonstantin Zhuravlyov } 950bb80d3e1SKonstantin Zhuravlyov } 951bb80d3e1SKonstantin Zhuravlyov 952345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) { 953345c1449SAlex Lorenz yaml::Output Out(OS); 954345c1449SAlex Lorenz Out << const_cast<Module &>(M); 955345c1449SAlex Lorenz } 956345c1449SAlex Lorenz 957345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) { 958345c1449SAlex Lorenz MIRPrinter Printer(OS); 959345c1449SAlex Lorenz Printer.print(MF); 960345c1449SAlex Lorenz } 961