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 15345c1449SAlex Lorenz #include "MIRPrinter.h" 16345c1449SAlex Lorenz #include "llvm/ADT/STLExtras.h" 17d28d3cc0STim Northover #include "llvm/ADT/SmallBitVector.h" 18fab1cfe6SQuentin Colombet #include "llvm/CodeGen/GlobalISel/RegisterBank.h" 19fab1cfe6SQuentin Colombet #include "llvm/CodeGen/MIRYamlMapping.h" 20ab980499SAlex Lorenz #include "llvm/CodeGen/MachineConstantPool.h" 2160541c1dSAlex Lorenz #include "llvm/CodeGen/MachineFrameInfo.h" 22fab1cfe6SQuentin Colombet #include "llvm/CodeGen/MachineFunction.h" 234af7e610SAlex Lorenz #include "llvm/CodeGen/MachineMemOperand.h" 24f4baeb51SAlex Lorenz #include "llvm/CodeGen/MachineModuleInfo.h" 2554565cf0SAlex Lorenz #include "llvm/CodeGen/MachineRegisterInfo.h" 264f093bf1SAlex Lorenz #include "llvm/IR/BasicBlock.h" 27deb53490SAlex Lorenz #include "llvm/IR/Constants.h" 2828865809SReid Kleckner #include "llvm/IR/DebugInfo.h" 296ede3744SAlex Lorenz #include "llvm/IR/IRPrintingPasses.h" 30fab1cfe6SQuentin Colombet #include "llvm/IR/Instructions.h" 316b3bd612STim Northover #include "llvm/IR/Intrinsics.h" 32345c1449SAlex Lorenz #include "llvm/IR/Module.h" 33900b5cb2SAlex Lorenz #include "llvm/IR/ModuleSlotTracker.h" 34f22ca8adSAlex Lorenz #include "llvm/MC/MCSymbol.h" 35b51774acSGeoff Berry #include "llvm/Support/Format.h" 36345c1449SAlex Lorenz #include "llvm/Support/MemoryBuffer.h" 37345c1449SAlex Lorenz #include "llvm/Support/YAMLTraits.h" 38fab1cfe6SQuentin Colombet #include "llvm/Support/raw_ostream.h" 398e0a1b48SAlex Lorenz #include "llvm/Target/TargetInstrInfo.h" 406b3bd612STim Northover #include "llvm/Target/TargetIntrinsicInfo.h" 418e0a1b48SAlex Lorenz #include "llvm/Target/TargetSubtargetInfo.h" 42345c1449SAlex Lorenz 43345c1449SAlex Lorenz using namespace llvm; 44345c1449SAlex Lorenz 45345c1449SAlex Lorenz namespace { 46345c1449SAlex Lorenz 477feaf7c6SAlex Lorenz /// This structure describes how to print out stack object references. 487feaf7c6SAlex Lorenz struct FrameIndexOperand { 497feaf7c6SAlex Lorenz std::string Name; 507feaf7c6SAlex Lorenz unsigned ID; 517feaf7c6SAlex Lorenz bool IsFixed; 527feaf7c6SAlex Lorenz 537feaf7c6SAlex Lorenz FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed) 547feaf7c6SAlex Lorenz : Name(Name.str()), ID(ID), IsFixed(IsFixed) {} 557feaf7c6SAlex Lorenz 567feaf7c6SAlex Lorenz /// Return an ordinary stack object reference. 577feaf7c6SAlex Lorenz static FrameIndexOperand create(StringRef Name, unsigned ID) { 587feaf7c6SAlex Lorenz return FrameIndexOperand(Name, ID, /*IsFixed=*/false); 597feaf7c6SAlex Lorenz } 607feaf7c6SAlex Lorenz 617feaf7c6SAlex Lorenz /// Return a fixed stack object reference. 627feaf7c6SAlex Lorenz static FrameIndexOperand createFixed(unsigned ID) { 637feaf7c6SAlex Lorenz return FrameIndexOperand("", ID, /*IsFixed=*/true); 647feaf7c6SAlex Lorenz } 657feaf7c6SAlex Lorenz }; 667feaf7c6SAlex Lorenz 67618b283cSAlex Lorenz } // end anonymous namespace 68618b283cSAlex Lorenz 69618b283cSAlex Lorenz namespace llvm { 70618b283cSAlex Lorenz 71345c1449SAlex Lorenz /// This class prints out the machine functions using the MIR serialization 72345c1449SAlex Lorenz /// format. 73345c1449SAlex Lorenz class MIRPrinter { 74345c1449SAlex Lorenz raw_ostream &OS; 758f6f4285SAlex Lorenz DenseMap<const uint32_t *, unsigned> RegisterMaskIds; 767feaf7c6SAlex Lorenz /// Maps from stack object indices to operand indices which will be used when 777feaf7c6SAlex Lorenz /// printing frame index machine operands. 787feaf7c6SAlex Lorenz DenseMap<int, FrameIndexOperand> StackObjectOperandMapping; 79345c1449SAlex Lorenz 80345c1449SAlex Lorenz public: 81345c1449SAlex Lorenz MIRPrinter(raw_ostream &OS) : OS(OS) {} 82345c1449SAlex Lorenz 83345c1449SAlex Lorenz void print(const MachineFunction &MF); 844f093bf1SAlex Lorenz 8528148ba8SAlex Lorenz void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo, 8628148ba8SAlex Lorenz const TargetRegisterInfo *TRI); 87a6f9a37dSAlex Lorenz void convert(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI, 88a6f9a37dSAlex Lorenz const MachineFrameInfo &MFI); 89ab980499SAlex Lorenz void convert(yaml::MachineFunction &MF, 90ab980499SAlex Lorenz const MachineConstantPool &ConstantPool); 916799e9b3SAlex Lorenz void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI, 926799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI); 93*ef331effSMatthias Braun void convertStackObjects(yaml::MachineFunction &YMF, 94*ef331effSMatthias Braun const MachineFunction &MF, ModuleSlotTracker &MST); 958f6f4285SAlex Lorenz 968f6f4285SAlex Lorenz private: 978f6f4285SAlex Lorenz void initRegisterMaskIds(const MachineFunction &MF); 98345c1449SAlex Lorenz }; 99345c1449SAlex Lorenz 1008e0a1b48SAlex Lorenz /// This class prints out the machine instructions using the MIR serialization 1018e0a1b48SAlex Lorenz /// format. 1028e0a1b48SAlex Lorenz class MIPrinter { 1038e0a1b48SAlex Lorenz raw_ostream &OS; 104900b5cb2SAlex Lorenz ModuleSlotTracker &MST; 1058f6f4285SAlex Lorenz const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds; 1067feaf7c6SAlex Lorenz const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping; 1078e0a1b48SAlex Lorenz 1088e0a1b48SAlex Lorenz public: 109900b5cb2SAlex Lorenz MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST, 1107feaf7c6SAlex Lorenz const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds, 1117feaf7c6SAlex Lorenz const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping) 1127feaf7c6SAlex Lorenz : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds), 1137feaf7c6SAlex Lorenz StackObjectOperandMapping(StackObjectOperandMapping) {} 1148e0a1b48SAlex Lorenz 1155022f6bbSAlex Lorenz void print(const MachineBasicBlock &MBB); 1165022f6bbSAlex Lorenz 1178e0a1b48SAlex Lorenz void print(const MachineInstr &MI); 1185d26fa83SAlex Lorenz void printMBBReference(const MachineBasicBlock &MBB); 119deb53490SAlex Lorenz void printIRBlockReference(const BasicBlock &BB); 1204af7e610SAlex Lorenz void printIRValueReference(const Value &V); 1217feaf7c6SAlex Lorenz void printStackObjectReference(int FrameIndex); 1225672a893SAlex Lorenz void printOffset(int64_t Offset); 12349873a83SAlex Lorenz void printTargetFlags(const MachineOperand &Op); 124e66a7ccfSAlex Lorenz void print(const MachineOperand &Op, const TargetRegisterInfo *TRI, 1254e14a497SQuentin Colombet unsigned I, bool ShouldPrintRegisterTies, 126d28d3cc0STim Northover LLT TypeToPrint, bool IsDef = false); 1274af7e610SAlex Lorenz void print(const MachineMemOperand &Op); 128f4baeb51SAlex Lorenz 1298cfc6867SAlex Lorenz void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI); 1308e0a1b48SAlex Lorenz }; 1318e0a1b48SAlex Lorenz 1325022f6bbSAlex Lorenz } // end namespace llvm 133345c1449SAlex Lorenz 134345c1449SAlex Lorenz namespace llvm { 135345c1449SAlex Lorenz namespace yaml { 136345c1449SAlex Lorenz 137345c1449SAlex Lorenz /// This struct serializes the LLVM IR module. 138345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> { 139345c1449SAlex Lorenz static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) { 140345c1449SAlex Lorenz Mod.print(OS, nullptr); 141345c1449SAlex Lorenz } 142345c1449SAlex Lorenz static StringRef input(StringRef Str, void *Ctxt, Module &Mod) { 143345c1449SAlex Lorenz llvm_unreachable("LLVM Module is supposed to be parsed separately"); 144345c1449SAlex Lorenz return ""; 145345c1449SAlex Lorenz } 146345c1449SAlex Lorenz }; 147345c1449SAlex Lorenz 148345c1449SAlex Lorenz } // end namespace yaml 149345c1449SAlex Lorenz } // end namespace llvm 150345c1449SAlex Lorenz 15115a00a85SAlex Lorenz static void printReg(unsigned Reg, raw_ostream &OS, 15215a00a85SAlex Lorenz const TargetRegisterInfo *TRI) { 15315a00a85SAlex Lorenz // TODO: Print Stack Slots. 15415a00a85SAlex Lorenz if (!Reg) 15515a00a85SAlex Lorenz OS << '_'; 15615a00a85SAlex Lorenz else if (TargetRegisterInfo::isVirtualRegister(Reg)) 15715a00a85SAlex Lorenz OS << '%' << TargetRegisterInfo::virtReg2Index(Reg); 15815a00a85SAlex Lorenz else if (Reg < TRI->getNumRegs()) 15915a00a85SAlex Lorenz OS << '%' << StringRef(TRI->getName(Reg)).lower(); 16015a00a85SAlex Lorenz else 16115a00a85SAlex Lorenz llvm_unreachable("Can't print this kind of register yet"); 16215a00a85SAlex Lorenz } 16315a00a85SAlex Lorenz 164ab4cbcfdSAlex Lorenz static void printReg(unsigned Reg, yaml::StringValue &Dest, 165ab4cbcfdSAlex Lorenz const TargetRegisterInfo *TRI) { 166ab4cbcfdSAlex Lorenz raw_string_ostream OS(Dest.Value); 167ab4cbcfdSAlex Lorenz printReg(Reg, OS, TRI); 168ab4cbcfdSAlex Lorenz } 169ab4cbcfdSAlex Lorenz 170345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) { 1718f6f4285SAlex Lorenz initRegisterMaskIds(MF); 1728f6f4285SAlex Lorenz 173345c1449SAlex Lorenz yaml::MachineFunction YamlMF; 174345c1449SAlex Lorenz YamlMF.Name = MF.getName(); 1755b5f9753SAlex Lorenz YamlMF.Alignment = MF.getAlignment(); 1765b5f9753SAlex Lorenz YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice(); 177ad154c83SDerek Schuff 1780d7b0cb8SAhmed Bougacha YamlMF.Legalized = MF.getProperties().hasProperty( 1790d7b0cb8SAhmed Bougacha MachineFunctionProperties::Property::Legalized); 18024712655SAhmed Bougacha YamlMF.RegBankSelected = MF.getProperties().hasProperty( 18124712655SAhmed Bougacha MachineFunctionProperties::Property::RegBankSelected); 182b109d518SAhmed Bougacha YamlMF.Selected = MF.getProperties().hasProperty( 183b109d518SAhmed Bougacha MachineFunctionProperties::Property::Selected); 1840d7b0cb8SAhmed Bougacha 18528148ba8SAlex Lorenz convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo()); 186a6f9a37dSAlex Lorenz ModuleSlotTracker MST(MF.getFunction()->getParent()); 187a6f9a37dSAlex Lorenz MST.incorporateFunction(*MF.getFunction()); 188941a705bSMatthias Braun convert(MST, YamlMF.FrameInfo, MF.getFrameInfo()); 189*ef331effSMatthias Braun convertStackObjects(YamlMF, MF, MST); 190ab980499SAlex Lorenz if (const auto *ConstantPool = MF.getConstantPool()) 191ab980499SAlex Lorenz convert(YamlMF, *ConstantPool); 1926799e9b3SAlex Lorenz if (const auto *JumpTableInfo = MF.getJumpTableInfo()) 1936799e9b3SAlex Lorenz convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo); 1945022f6bbSAlex Lorenz raw_string_ostream StrOS(YamlMF.Body.Value.Value); 1955022f6bbSAlex Lorenz bool IsNewlineNeeded = false; 1964f093bf1SAlex Lorenz for (const auto &MBB : MF) { 1975022f6bbSAlex Lorenz if (IsNewlineNeeded) 1985022f6bbSAlex Lorenz StrOS << "\n"; 1995022f6bbSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 2005022f6bbSAlex Lorenz .print(MBB); 2015022f6bbSAlex Lorenz IsNewlineNeeded = true; 2024f093bf1SAlex Lorenz } 2035022f6bbSAlex Lorenz StrOS.flush(); 204345c1449SAlex Lorenz yaml::Output Out(OS); 205345c1449SAlex Lorenz Out << YamlMF; 206345c1449SAlex Lorenz } 207345c1449SAlex Lorenz 20854565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 20928148ba8SAlex Lorenz const MachineRegisterInfo &RegInfo, 21028148ba8SAlex Lorenz const TargetRegisterInfo *TRI) { 21154565cf0SAlex Lorenz MF.TracksRegLiveness = RegInfo.tracksLiveness(); 21228148ba8SAlex Lorenz 21328148ba8SAlex Lorenz // Print the virtual register definitions. 21428148ba8SAlex Lorenz for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) { 21528148ba8SAlex Lorenz unsigned Reg = TargetRegisterInfo::index2VirtReg(I); 21628148ba8SAlex Lorenz yaml::VirtualRegisterDefinition VReg; 21728148ba8SAlex Lorenz VReg.ID = I; 218fab1cfe6SQuentin Colombet if (RegInfo.getRegClassOrNull(Reg)) 21928148ba8SAlex Lorenz VReg.Class = 22028148ba8SAlex Lorenz StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower(); 221fab1cfe6SQuentin Colombet else if (RegInfo.getRegBankOrNull(Reg)) 222fab1cfe6SQuentin Colombet VReg.Class = StringRef(RegInfo.getRegBankOrNull(Reg)->getName()).lower(); 223050b2118SQuentin Colombet else { 224050b2118SQuentin Colombet VReg.Class = std::string("_"); 225d28d3cc0STim Northover assert((RegInfo.def_empty(Reg) || RegInfo.getType(Reg).isValid()) && 2260f140c76STim Northover "Generic registers must have a valid type"); 227050b2118SQuentin Colombet } 228ab4cbcfdSAlex Lorenz unsigned PreferredReg = RegInfo.getSimpleHint(Reg); 229ab4cbcfdSAlex Lorenz if (PreferredReg) 230ab4cbcfdSAlex Lorenz printReg(PreferredReg, VReg.PreferredRegister, TRI); 23128148ba8SAlex Lorenz MF.VirtualRegisters.push_back(VReg); 23228148ba8SAlex Lorenz } 23312045a4bSAlex Lorenz 23412045a4bSAlex Lorenz // Print the live ins. 23512045a4bSAlex Lorenz for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) { 23612045a4bSAlex Lorenz yaml::MachineFunctionLiveIn LiveIn; 23712045a4bSAlex Lorenz printReg(I->first, LiveIn.Register, TRI); 23812045a4bSAlex Lorenz if (I->second) 23912045a4bSAlex Lorenz printReg(I->second, LiveIn.VirtualRegister, TRI); 24012045a4bSAlex Lorenz MF.LiveIns.push_back(LiveIn); 24112045a4bSAlex Lorenz } 242c4838087SAlex Lorenz // The used physical register mask is printed as an inverted callee saved 243c4838087SAlex Lorenz // register mask. 244c4838087SAlex Lorenz const BitVector &UsedPhysRegMask = RegInfo.getUsedPhysRegsMask(); 245c4838087SAlex Lorenz if (UsedPhysRegMask.none()) 246c4838087SAlex Lorenz return; 247c4838087SAlex Lorenz std::vector<yaml::FlowStringValue> CalleeSavedRegisters; 248c4838087SAlex Lorenz for (unsigned I = 0, E = UsedPhysRegMask.size(); I != E; ++I) { 249c4838087SAlex Lorenz if (!UsedPhysRegMask[I]) { 250c4838087SAlex Lorenz yaml::FlowStringValue Reg; 251c4838087SAlex Lorenz printReg(I, Reg, TRI); 252c4838087SAlex Lorenz CalleeSavedRegisters.push_back(Reg); 253c4838087SAlex Lorenz } 254c4838087SAlex Lorenz } 255c4838087SAlex Lorenz MF.CalleeSavedRegisters = CalleeSavedRegisters; 25654565cf0SAlex Lorenz } 25754565cf0SAlex Lorenz 258a6f9a37dSAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 259a6f9a37dSAlex Lorenz yaml::MachineFrameInfo &YamlMFI, 26060541c1dSAlex Lorenz const MachineFrameInfo &MFI) { 26160541c1dSAlex Lorenz YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken(); 26260541c1dSAlex Lorenz YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken(); 26360541c1dSAlex Lorenz YamlMFI.HasStackMap = MFI.hasStackMap(); 26460541c1dSAlex Lorenz YamlMFI.HasPatchPoint = MFI.hasPatchPoint(); 26560541c1dSAlex Lorenz YamlMFI.StackSize = MFI.getStackSize(); 26660541c1dSAlex Lorenz YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment(); 26760541c1dSAlex Lorenz YamlMFI.MaxAlignment = MFI.getMaxAlignment(); 26860541c1dSAlex Lorenz YamlMFI.AdjustsStack = MFI.adjustsStack(); 26960541c1dSAlex Lorenz YamlMFI.HasCalls = MFI.hasCalls(); 27060541c1dSAlex Lorenz YamlMFI.MaxCallFrameSize = MFI.getMaxCallFrameSize(); 27160541c1dSAlex Lorenz YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment(); 27260541c1dSAlex Lorenz YamlMFI.HasVAStart = MFI.hasVAStart(); 27360541c1dSAlex Lorenz YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc(); 274a6f9a37dSAlex Lorenz if (MFI.getSavePoint()) { 275a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.SavePoint.Value); 276a6f9a37dSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 277a6f9a37dSAlex Lorenz .printMBBReference(*MFI.getSavePoint()); 278a6f9a37dSAlex Lorenz } 279a6f9a37dSAlex Lorenz if (MFI.getRestorePoint()) { 280a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.RestorePoint.Value); 281a6f9a37dSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 282a6f9a37dSAlex Lorenz .printMBBReference(*MFI.getRestorePoint()); 283a6f9a37dSAlex Lorenz } 28460541c1dSAlex Lorenz } 28560541c1dSAlex Lorenz 286*ef331effSMatthias Braun void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF, 287*ef331effSMatthias Braun const MachineFunction &MF, 288*ef331effSMatthias Braun ModuleSlotTracker &MST) { 289*ef331effSMatthias Braun const MachineFrameInfo &MFI = MF.getFrameInfo(); 290*ef331effSMatthias Braun const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 291de491f05SAlex Lorenz // Process fixed stack objects. 292f6bc8667SAlex Lorenz unsigned ID = 0; 293de491f05SAlex Lorenz for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) { 294de491f05SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 295de491f05SAlex Lorenz continue; 296de491f05SAlex Lorenz 297de491f05SAlex Lorenz yaml::FixedMachineStackObject YamlObject; 2987feaf7c6SAlex Lorenz YamlObject.ID = ID; 299de491f05SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 300de491f05SAlex Lorenz ? yaml::FixedMachineStackObject::SpillSlot 301de491f05SAlex Lorenz : yaml::FixedMachineStackObject::DefaultType; 302de491f05SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 303de491f05SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 304de491f05SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 305de491f05SAlex Lorenz YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I); 306de491f05SAlex Lorenz YamlObject.IsAliased = MFI.isAliasedObjectIndex(I); 307*ef331effSMatthias Braun YMF.FixedStackObjects.push_back(YamlObject); 3087feaf7c6SAlex Lorenz StackObjectOperandMapping.insert( 3097feaf7c6SAlex Lorenz std::make_pair(I, FrameIndexOperand::createFixed(ID++))); 310de491f05SAlex Lorenz } 311de491f05SAlex Lorenz 312de491f05SAlex Lorenz // Process ordinary stack objects. 313de491f05SAlex Lorenz ID = 0; 314f6bc8667SAlex Lorenz for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) { 315f6bc8667SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 316f6bc8667SAlex Lorenz continue; 317f6bc8667SAlex Lorenz 318f6bc8667SAlex Lorenz yaml::MachineStackObject YamlObject; 3197feaf7c6SAlex Lorenz YamlObject.ID = ID; 32037643a04SAlex Lorenz if (const auto *Alloca = MFI.getObjectAllocation(I)) 32137643a04SAlex Lorenz YamlObject.Name.Value = 32237643a04SAlex Lorenz Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>"; 323f6bc8667SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 324f6bc8667SAlex Lorenz ? yaml::MachineStackObject::SpillSlot 325418f3ec1SAlex Lorenz : MFI.isVariableSizedObjectIndex(I) 326418f3ec1SAlex Lorenz ? yaml::MachineStackObject::VariableSized 327f6bc8667SAlex Lorenz : yaml::MachineStackObject::DefaultType; 328f6bc8667SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 329f6bc8667SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 330f6bc8667SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 331f6bc8667SAlex Lorenz 332*ef331effSMatthias Braun YMF.StackObjects.push_back(YamlObject); 3337feaf7c6SAlex Lorenz StackObjectOperandMapping.insert(std::make_pair( 3347feaf7c6SAlex Lorenz I, FrameIndexOperand::create(YamlObject.Name.Value, ID++))); 335f6bc8667SAlex Lorenz } 3361bb48de1SAlex Lorenz 3371bb48de1SAlex Lorenz for (const auto &CSInfo : MFI.getCalleeSavedInfo()) { 3381bb48de1SAlex Lorenz yaml::StringValue Reg; 3391bb48de1SAlex Lorenz printReg(CSInfo.getReg(), Reg, TRI); 3401bb48de1SAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx()); 3411bb48de1SAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 3421bb48de1SAlex Lorenz "Invalid stack object index"); 3431bb48de1SAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 3441bb48de1SAlex Lorenz if (StackObject.IsFixed) 345*ef331effSMatthias Braun YMF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg; 3461bb48de1SAlex Lorenz else 347*ef331effSMatthias Braun YMF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg; 3481bb48de1SAlex Lorenz } 349a56ba6a6SAlex Lorenz for (unsigned I = 0, E = MFI.getLocalFrameObjectCount(); I < E; ++I) { 350a56ba6a6SAlex Lorenz auto LocalObject = MFI.getLocalFrameObjectMap(I); 351a56ba6a6SAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(LocalObject.first); 352a56ba6a6SAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 353a56ba6a6SAlex Lorenz "Invalid stack object index"); 354a56ba6a6SAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 355a56ba6a6SAlex Lorenz assert(!StackObject.IsFixed && "Expected a locally mapped stack object"); 356*ef331effSMatthias Braun YMF.StackObjects[StackObject.ID].LocalOffset = LocalObject.second; 357a56ba6a6SAlex Lorenz } 358a314d813SAlex Lorenz 359a314d813SAlex Lorenz // Print the stack object references in the frame information class after 360a314d813SAlex Lorenz // converting the stack objects. 361a314d813SAlex Lorenz if (MFI.hasStackProtectorIndex()) { 362*ef331effSMatthias Braun raw_string_ostream StrOS(YMF.FrameInfo.StackProtector.Value); 363a314d813SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 364a314d813SAlex Lorenz .printStackObjectReference(MFI.getStackProtectorIndex()); 365a314d813SAlex Lorenz } 366df9e3c6fSAlex Lorenz 367df9e3c6fSAlex Lorenz // Print the debug variable information. 368*ef331effSMatthias Braun for (const MachineFunction::VariableDbgInfo &DebugVar : 369*ef331effSMatthias Braun MF.getVariableDbgInfo()) { 370df9e3c6fSAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(DebugVar.Slot); 371df9e3c6fSAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 372df9e3c6fSAlex Lorenz "Invalid stack object index"); 373df9e3c6fSAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 374df9e3c6fSAlex Lorenz assert(!StackObject.IsFixed && "Expected a non-fixed stack object"); 375*ef331effSMatthias Braun auto &Object = YMF.StackObjects[StackObject.ID]; 376df9e3c6fSAlex Lorenz { 377df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugVar.Value); 378df9e3c6fSAlex Lorenz DebugVar.Var->printAsOperand(StrOS, MST); 379df9e3c6fSAlex Lorenz } 380df9e3c6fSAlex Lorenz { 381df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugExpr.Value); 382df9e3c6fSAlex Lorenz DebugVar.Expr->printAsOperand(StrOS, MST); 383df9e3c6fSAlex Lorenz } 384df9e3c6fSAlex Lorenz { 385df9e3c6fSAlex Lorenz raw_string_ostream StrOS(Object.DebugLoc.Value); 386df9e3c6fSAlex Lorenz DebugVar.Loc->printAsOperand(StrOS, MST); 387df9e3c6fSAlex Lorenz } 388df9e3c6fSAlex Lorenz } 389f6bc8667SAlex Lorenz } 390f6bc8667SAlex Lorenz 391ab980499SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 392ab980499SAlex Lorenz const MachineConstantPool &ConstantPool) { 393ab980499SAlex Lorenz unsigned ID = 0; 394ab980499SAlex Lorenz for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) { 395ab980499SAlex Lorenz // TODO: Serialize target specific constant pool entries. 396ab980499SAlex Lorenz if (Constant.isMachineConstantPoolEntry()) 397ab980499SAlex Lorenz llvm_unreachable("Can't print target specific constant pool entries yet"); 398ab980499SAlex Lorenz 399ab980499SAlex Lorenz yaml::MachineConstantPoolValue YamlConstant; 400ab980499SAlex Lorenz std::string Str; 401ab980499SAlex Lorenz raw_string_ostream StrOS(Str); 402ab980499SAlex Lorenz Constant.Val.ConstVal->printAsOperand(StrOS); 403ab980499SAlex Lorenz YamlConstant.ID = ID++; 404ab980499SAlex Lorenz YamlConstant.Value = StrOS.str(); 405ab980499SAlex Lorenz YamlConstant.Alignment = Constant.getAlignment(); 406ab980499SAlex Lorenz MF.Constants.push_back(YamlConstant); 407ab980499SAlex Lorenz } 408ab980499SAlex Lorenz } 409ab980499SAlex Lorenz 410900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 4116799e9b3SAlex Lorenz yaml::MachineJumpTable &YamlJTI, 4126799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI) { 4136799e9b3SAlex Lorenz YamlJTI.Kind = JTI.getEntryKind(); 4146799e9b3SAlex Lorenz unsigned ID = 0; 4156799e9b3SAlex Lorenz for (const auto &Table : JTI.getJumpTables()) { 4166799e9b3SAlex Lorenz std::string Str; 4176799e9b3SAlex Lorenz yaml::MachineJumpTable::Entry Entry; 4186799e9b3SAlex Lorenz Entry.ID = ID++; 4196799e9b3SAlex Lorenz for (const auto *MBB : Table.MBBs) { 4206799e9b3SAlex Lorenz raw_string_ostream StrOS(Str); 4217feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 4227feaf7c6SAlex Lorenz .printMBBReference(*MBB); 4236799e9b3SAlex Lorenz Entry.Blocks.push_back(StrOS.str()); 4246799e9b3SAlex Lorenz Str.clear(); 4256799e9b3SAlex Lorenz } 4266799e9b3SAlex Lorenz YamlJTI.Entries.push_back(Entry); 4276799e9b3SAlex Lorenz } 4286799e9b3SAlex Lorenz } 4296799e9b3SAlex Lorenz 4308f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) { 4318f6f4285SAlex Lorenz const auto *TRI = MF.getSubtarget().getRegisterInfo(); 4328f6f4285SAlex Lorenz unsigned I = 0; 4338f6f4285SAlex Lorenz for (const uint32_t *Mask : TRI->getRegMasks()) 4348f6f4285SAlex Lorenz RegisterMaskIds.insert(std::make_pair(Mask, I++)); 4358f6f4285SAlex Lorenz } 4368f6f4285SAlex Lorenz 4375022f6bbSAlex Lorenz void MIPrinter::print(const MachineBasicBlock &MBB) { 4385022f6bbSAlex Lorenz assert(MBB.getNumber() >= 0 && "Invalid MBB number"); 4395022f6bbSAlex Lorenz OS << "bb." << MBB.getNumber(); 4405022f6bbSAlex Lorenz bool HasAttributes = false; 4415022f6bbSAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 4425022f6bbSAlex Lorenz if (BB->hasName()) { 4435022f6bbSAlex Lorenz OS << "." << BB->getName(); 4445022f6bbSAlex Lorenz } else { 4455022f6bbSAlex Lorenz HasAttributes = true; 4465022f6bbSAlex Lorenz OS << " ("; 4475022f6bbSAlex Lorenz int Slot = MST.getLocalSlot(BB); 4485022f6bbSAlex Lorenz if (Slot == -1) 4495022f6bbSAlex Lorenz OS << "<ir-block badref>"; 4505022f6bbSAlex Lorenz else 4515022f6bbSAlex Lorenz OS << (Twine("%ir-block.") + Twine(Slot)).str(); 4525022f6bbSAlex Lorenz } 4535022f6bbSAlex Lorenz } 4545022f6bbSAlex Lorenz if (MBB.hasAddressTaken()) { 4555022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 4565022f6bbSAlex Lorenz OS << "address-taken"; 4575022f6bbSAlex Lorenz HasAttributes = true; 4585022f6bbSAlex Lorenz } 4590e288234SReid Kleckner if (MBB.isEHPad()) { 4605022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 4615022f6bbSAlex Lorenz OS << "landing-pad"; 4625022f6bbSAlex Lorenz HasAttributes = true; 4635022f6bbSAlex Lorenz } 4645022f6bbSAlex Lorenz if (MBB.getAlignment()) { 4655022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 4665022f6bbSAlex Lorenz OS << "align " << MBB.getAlignment(); 4675022f6bbSAlex Lorenz HasAttributes = true; 4685022f6bbSAlex Lorenz } 4695022f6bbSAlex Lorenz if (HasAttributes) 4705022f6bbSAlex Lorenz OS << ")"; 4715022f6bbSAlex Lorenz OS << ":\n"; 4725022f6bbSAlex Lorenz 4735022f6bbSAlex Lorenz bool HasLineAttributes = false; 4745022f6bbSAlex Lorenz // Print the successors 4755022f6bbSAlex Lorenz if (!MBB.succ_empty()) { 4765022f6bbSAlex Lorenz OS.indent(2) << "successors: "; 4775022f6bbSAlex Lorenz for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) { 4785022f6bbSAlex Lorenz if (I != MBB.succ_begin()) 4795022f6bbSAlex Lorenz OS << ", "; 4805022f6bbSAlex Lorenz printMBBReference(**I); 481d97c100dSCong Hou if (MBB.hasSuccessorProbabilities()) 482b51774acSGeoff Berry OS << '(' 483b51774acSGeoff Berry << format("0x%08" PRIx32, MBB.getSuccProbability(I).getNumerator()) 484b51774acSGeoff Berry << ')'; 4855022f6bbSAlex Lorenz } 4865022f6bbSAlex Lorenz OS << "\n"; 4875022f6bbSAlex Lorenz HasLineAttributes = true; 4885022f6bbSAlex Lorenz } 4895022f6bbSAlex Lorenz 4905022f6bbSAlex Lorenz // Print the live in registers. 4915022f6bbSAlex Lorenz const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo(); 4925022f6bbSAlex Lorenz assert(TRI && "Expected target register info"); 4935022f6bbSAlex Lorenz if (!MBB.livein_empty()) { 4945022f6bbSAlex Lorenz OS.indent(2) << "liveins: "; 495b2b7ef1dSMatthias Braun bool First = true; 496d9da1627SMatthias Braun for (const auto &LI : MBB.liveins()) { 497b2b7ef1dSMatthias Braun if (!First) 4985022f6bbSAlex Lorenz OS << ", "; 499b2b7ef1dSMatthias Braun First = false; 500d9da1627SMatthias Braun printReg(LI.PhysReg, OS, TRI); 501d9da1627SMatthias Braun if (LI.LaneMask != ~0u) 502d62669d7SKrzysztof Parzyszek OS << ":0x" << PrintLaneMask(LI.LaneMask); 5035022f6bbSAlex Lorenz } 5045022f6bbSAlex Lorenz OS << "\n"; 5055022f6bbSAlex Lorenz HasLineAttributes = true; 5065022f6bbSAlex Lorenz } 5075022f6bbSAlex Lorenz 5085022f6bbSAlex Lorenz if (HasLineAttributes) 5095022f6bbSAlex Lorenz OS << "\n"; 510f9a2b123SAlex Lorenz bool IsInBundle = false; 511f9a2b123SAlex Lorenz for (auto I = MBB.instr_begin(), E = MBB.instr_end(); I != E; ++I) { 512f9a2b123SAlex Lorenz const MachineInstr &MI = *I; 513f9a2b123SAlex Lorenz if (IsInBundle && !MI.isInsideBundle()) { 514f9a2b123SAlex Lorenz OS.indent(2) << "}\n"; 515f9a2b123SAlex Lorenz IsInBundle = false; 516f9a2b123SAlex Lorenz } 517f9a2b123SAlex Lorenz OS.indent(IsInBundle ? 4 : 2); 5185022f6bbSAlex Lorenz print(MI); 519f9a2b123SAlex Lorenz if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) { 520f9a2b123SAlex Lorenz OS << " {"; 521f9a2b123SAlex Lorenz IsInBundle = true; 522f9a2b123SAlex Lorenz } 5235022f6bbSAlex Lorenz OS << "\n"; 5245022f6bbSAlex Lorenz } 525f9a2b123SAlex Lorenz if (IsInBundle) 526f9a2b123SAlex Lorenz OS.indent(2) << "}\n"; 5275022f6bbSAlex Lorenz } 5285022f6bbSAlex Lorenz 5295ef93b0cSAlex Lorenz /// Return true when an instruction has tied register that can't be determined 5305ef93b0cSAlex Lorenz /// by the instruction's descriptor. 5315ef93b0cSAlex Lorenz static bool hasComplexRegisterTies(const MachineInstr &MI) { 5325ef93b0cSAlex Lorenz const MCInstrDesc &MCID = MI.getDesc(); 5335ef93b0cSAlex Lorenz for (unsigned I = 0, E = MI.getNumOperands(); I < E; ++I) { 5345ef93b0cSAlex Lorenz const auto &Operand = MI.getOperand(I); 5355ef93b0cSAlex Lorenz if (!Operand.isReg() || Operand.isDef()) 5365ef93b0cSAlex Lorenz // Ignore the defined registers as MCID marks only the uses as tied. 5375ef93b0cSAlex Lorenz continue; 5385ef93b0cSAlex Lorenz int ExpectedTiedIdx = MCID.getOperandConstraint(I, MCOI::TIED_TO); 5395ef93b0cSAlex Lorenz int TiedIdx = Operand.isTied() ? int(MI.findTiedOperandIdx(I)) : -1; 5405ef93b0cSAlex Lorenz if (ExpectedTiedIdx != TiedIdx) 5415ef93b0cSAlex Lorenz return true; 5425ef93b0cSAlex Lorenz } 5435ef93b0cSAlex Lorenz return false; 5445ef93b0cSAlex Lorenz } 5455ef93b0cSAlex Lorenz 546d28d3cc0STim Northover static LLT getTypeToPrint(const MachineInstr &MI, unsigned OpIdx, 547d28d3cc0STim Northover SmallBitVector &PrintedTypes, 548d28d3cc0STim Northover const MachineRegisterInfo &MRI) { 549d28d3cc0STim Northover const MachineOperand &Op = MI.getOperand(OpIdx); 550d28d3cc0STim Northover if (!Op.isReg()) 551d28d3cc0STim Northover return LLT{}; 552d28d3cc0STim Northover 553d28d3cc0STim Northover if (MI.isVariadic() || OpIdx >= MI.getNumExplicitOperands()) 554d28d3cc0STim Northover return MRI.getType(Op.getReg()); 555d28d3cc0STim Northover 556d28d3cc0STim Northover auto &OpInfo = MI.getDesc().OpInfo[OpIdx]; 557d28d3cc0STim Northover if (!OpInfo.isGenericType()) 558d28d3cc0STim Northover return MRI.getType(Op.getReg()); 559d28d3cc0STim Northover 560d28d3cc0STim Northover if (PrintedTypes[OpInfo.getGenericTypeIndex()]) 561d28d3cc0STim Northover return LLT{}; 562d28d3cc0STim Northover 563d28d3cc0STim Northover PrintedTypes.set(OpInfo.getGenericTypeIndex()); 564d28d3cc0STim Northover return MRI.getType(Op.getReg()); 565d28d3cc0STim Northover } 566d28d3cc0STim Northover 5678e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) { 5684e14a497SQuentin Colombet const auto *MF = MI.getParent()->getParent(); 5694e14a497SQuentin Colombet const auto &MRI = MF->getRegInfo(); 5704e14a497SQuentin Colombet const auto &SubTarget = MF->getSubtarget(); 571f3db51deSAlex Lorenz const auto *TRI = SubTarget.getRegisterInfo(); 572f3db51deSAlex Lorenz assert(TRI && "Expected target register info"); 5738e0a1b48SAlex Lorenz const auto *TII = SubTarget.getInstrInfo(); 5748e0a1b48SAlex Lorenz assert(TII && "Expected target instruction info"); 575f4baeb51SAlex Lorenz if (MI.isCFIInstruction()) 576f4baeb51SAlex Lorenz assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction"); 5778e0a1b48SAlex Lorenz 578d28d3cc0STim Northover SmallBitVector PrintedTypes(8); 5795ef93b0cSAlex Lorenz bool ShouldPrintRegisterTies = hasComplexRegisterTies(MI); 580f3db51deSAlex Lorenz unsigned I = 0, E = MI.getNumOperands(); 581f3db51deSAlex Lorenz for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() && 582f3db51deSAlex Lorenz !MI.getOperand(I).isImplicit(); 583f3db51deSAlex Lorenz ++I) { 584f3db51deSAlex Lorenz if (I) 585f3db51deSAlex Lorenz OS << ", "; 586d28d3cc0STim Northover print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies, 587d28d3cc0STim Northover getTypeToPrint(MI, I, PrintedTypes, MRI), 5884e14a497SQuentin Colombet /*IsDef=*/true); 589f3db51deSAlex Lorenz } 590f3db51deSAlex Lorenz 591f3db51deSAlex Lorenz if (I) 592f3db51deSAlex Lorenz OS << " = "; 593e5a44660SAlex Lorenz if (MI.getFlag(MachineInstr::FrameSetup)) 594e5a44660SAlex Lorenz OS << "frame-setup "; 5958e0a1b48SAlex Lorenz OS << TII->getName(MI.getOpcode()); 596f3db51deSAlex Lorenz if (I < E) 597f3db51deSAlex Lorenz OS << ' '; 598f3db51deSAlex Lorenz 599f3db51deSAlex Lorenz bool NeedComma = false; 600f3db51deSAlex Lorenz for (; I < E; ++I) { 601f3db51deSAlex Lorenz if (NeedComma) 602f3db51deSAlex Lorenz OS << ", "; 603d28d3cc0STim Northover print(MI.getOperand(I), TRI, I, ShouldPrintRegisterTies, 604d28d3cc0STim Northover getTypeToPrint(MI, I, PrintedTypes, MRI)); 605f3db51deSAlex Lorenz NeedComma = true; 606f3db51deSAlex Lorenz } 60746d760d1SAlex Lorenz 60846d760d1SAlex Lorenz if (MI.getDebugLoc()) { 60946d760d1SAlex Lorenz if (NeedComma) 61046d760d1SAlex Lorenz OS << ','; 61146d760d1SAlex Lorenz OS << " debug-location "; 61246d760d1SAlex Lorenz MI.getDebugLoc()->printAsOperand(OS, MST); 61346d760d1SAlex Lorenz } 6144af7e610SAlex Lorenz 6154af7e610SAlex Lorenz if (!MI.memoperands_empty()) { 6164af7e610SAlex Lorenz OS << " :: "; 6174af7e610SAlex Lorenz bool NeedComma = false; 6184af7e610SAlex Lorenz for (const auto *Op : MI.memoperands()) { 6194af7e610SAlex Lorenz if (NeedComma) 6204af7e610SAlex Lorenz OS << ", "; 6214af7e610SAlex Lorenz print(*Op); 6224af7e610SAlex Lorenz NeedComma = true; 6234af7e610SAlex Lorenz } 6244af7e610SAlex Lorenz } 625f3db51deSAlex Lorenz } 626f3db51deSAlex Lorenz 6275d26fa83SAlex Lorenz void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) { 6285d26fa83SAlex Lorenz OS << "%bb." << MBB.getNumber(); 6295d26fa83SAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 6305d26fa83SAlex Lorenz if (BB->hasName()) 6315d26fa83SAlex Lorenz OS << '.' << BB->getName(); 6325d26fa83SAlex Lorenz } 6335d26fa83SAlex Lorenz } 6345d26fa83SAlex Lorenz 63555dc6f81SAlex Lorenz static void printIRSlotNumber(raw_ostream &OS, int Slot) { 63655dc6f81SAlex Lorenz if (Slot == -1) 63755dc6f81SAlex Lorenz OS << "<badref>"; 63855dc6f81SAlex Lorenz else 63955dc6f81SAlex Lorenz OS << Slot; 64055dc6f81SAlex Lorenz } 64155dc6f81SAlex Lorenz 642deb53490SAlex Lorenz void MIPrinter::printIRBlockReference(const BasicBlock &BB) { 643deb53490SAlex Lorenz OS << "%ir-block."; 644deb53490SAlex Lorenz if (BB.hasName()) { 645deb53490SAlex Lorenz printLLVMNameWithoutPrefix(OS, BB.getName()); 646deb53490SAlex Lorenz return; 647deb53490SAlex Lorenz } 648cba8c5feSAlex Lorenz const Function *F = BB.getParent(); 649cba8c5feSAlex Lorenz int Slot; 650cba8c5feSAlex Lorenz if (F == MST.getCurrentFunction()) { 651cba8c5feSAlex Lorenz Slot = MST.getLocalSlot(&BB); 652cba8c5feSAlex Lorenz } else { 653cba8c5feSAlex Lorenz ModuleSlotTracker CustomMST(F->getParent(), 654cba8c5feSAlex Lorenz /*ShouldInitializeAllMetadata=*/false); 655cba8c5feSAlex Lorenz CustomMST.incorporateFunction(*F); 656cba8c5feSAlex Lorenz Slot = CustomMST.getLocalSlot(&BB); 657cba8c5feSAlex Lorenz } 65855dc6f81SAlex Lorenz printIRSlotNumber(OS, Slot); 659deb53490SAlex Lorenz } 660deb53490SAlex Lorenz 6614af7e610SAlex Lorenz void MIPrinter::printIRValueReference(const Value &V) { 66236efd388SAlex Lorenz if (isa<GlobalValue>(V)) { 66336efd388SAlex Lorenz V.printAsOperand(OS, /*PrintType=*/false, MST); 66436efd388SAlex Lorenz return; 66536efd388SAlex Lorenz } 666c1136ef3SAlex Lorenz if (isa<Constant>(V)) { 667c1136ef3SAlex Lorenz // Machine memory operands can load/store to/from constant value pointers. 668c1136ef3SAlex Lorenz OS << '`'; 669c1136ef3SAlex Lorenz V.printAsOperand(OS, /*PrintType=*/true, MST); 670c1136ef3SAlex Lorenz OS << '`'; 671c1136ef3SAlex Lorenz return; 672c1136ef3SAlex Lorenz } 6734af7e610SAlex Lorenz OS << "%ir."; 6744af7e610SAlex Lorenz if (V.hasName()) { 6754af7e610SAlex Lorenz printLLVMNameWithoutPrefix(OS, V.getName()); 6764af7e610SAlex Lorenz return; 6774af7e610SAlex Lorenz } 678dd13be0bSAlex Lorenz printIRSlotNumber(OS, MST.getLocalSlot(&V)); 6794af7e610SAlex Lorenz } 6804af7e610SAlex Lorenz 6817feaf7c6SAlex Lorenz void MIPrinter::printStackObjectReference(int FrameIndex) { 6827feaf7c6SAlex Lorenz auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex); 6837feaf7c6SAlex Lorenz assert(ObjectInfo != StackObjectOperandMapping.end() && 6847feaf7c6SAlex Lorenz "Invalid frame index"); 6857feaf7c6SAlex Lorenz const FrameIndexOperand &Operand = ObjectInfo->second; 6867feaf7c6SAlex Lorenz if (Operand.IsFixed) { 6877feaf7c6SAlex Lorenz OS << "%fixed-stack." << Operand.ID; 6887feaf7c6SAlex Lorenz return; 6897feaf7c6SAlex Lorenz } 6907feaf7c6SAlex Lorenz OS << "%stack." << Operand.ID; 6917feaf7c6SAlex Lorenz if (!Operand.Name.empty()) 6927feaf7c6SAlex Lorenz OS << '.' << Operand.Name; 6937feaf7c6SAlex Lorenz } 6947feaf7c6SAlex Lorenz 6955672a893SAlex Lorenz void MIPrinter::printOffset(int64_t Offset) { 6965672a893SAlex Lorenz if (Offset == 0) 6975672a893SAlex Lorenz return; 6985672a893SAlex Lorenz if (Offset < 0) { 6995672a893SAlex Lorenz OS << " - " << -Offset; 7005672a893SAlex Lorenz return; 7015672a893SAlex Lorenz } 7025672a893SAlex Lorenz OS << " + " << Offset; 7035672a893SAlex Lorenz } 7045672a893SAlex Lorenz 70549873a83SAlex Lorenz static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) { 70649873a83SAlex Lorenz auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); 70749873a83SAlex Lorenz for (const auto &I : Flags) { 70849873a83SAlex Lorenz if (I.first == TF) { 70949873a83SAlex Lorenz return I.second; 71049873a83SAlex Lorenz } 71149873a83SAlex Lorenz } 71249873a83SAlex Lorenz return nullptr; 71349873a83SAlex Lorenz } 71449873a83SAlex Lorenz 71549873a83SAlex Lorenz void MIPrinter::printTargetFlags(const MachineOperand &Op) { 71649873a83SAlex Lorenz if (!Op.getTargetFlags()) 71749873a83SAlex Lorenz return; 71849873a83SAlex Lorenz const auto *TII = 71949873a83SAlex Lorenz Op.getParent()->getParent()->getParent()->getSubtarget().getInstrInfo(); 72049873a83SAlex Lorenz assert(TII && "expected instruction info"); 72149873a83SAlex Lorenz auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags()); 72249873a83SAlex Lorenz OS << "target-flags("; 723f3630113SAlex Lorenz const bool HasDirectFlags = Flags.first; 724f3630113SAlex Lorenz const bool HasBitmaskFlags = Flags.second; 725f3630113SAlex Lorenz if (!HasDirectFlags && !HasBitmaskFlags) { 726f3630113SAlex Lorenz OS << "<unknown>) "; 727f3630113SAlex Lorenz return; 728f3630113SAlex Lorenz } 729f3630113SAlex Lorenz if (HasDirectFlags) { 73049873a83SAlex Lorenz if (const auto *Name = getTargetFlagName(TII, Flags.first)) 73149873a83SAlex Lorenz OS << Name; 73249873a83SAlex Lorenz else 73349873a83SAlex Lorenz OS << "<unknown target flag>"; 734f3630113SAlex Lorenz } 735f3630113SAlex Lorenz if (!HasBitmaskFlags) { 736f3630113SAlex Lorenz OS << ") "; 737f3630113SAlex Lorenz return; 738f3630113SAlex Lorenz } 739f3630113SAlex Lorenz bool IsCommaNeeded = HasDirectFlags; 740f3630113SAlex Lorenz unsigned BitMask = Flags.second; 741f3630113SAlex Lorenz auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags(); 742f3630113SAlex Lorenz for (const auto &Mask : BitMasks) { 743f3630113SAlex Lorenz // Check if the flag's bitmask has the bits of the current mask set. 744f3630113SAlex Lorenz if ((BitMask & Mask.first) == Mask.first) { 745f3630113SAlex Lorenz if (IsCommaNeeded) 746f3630113SAlex Lorenz OS << ", "; 747f3630113SAlex Lorenz IsCommaNeeded = true; 748f3630113SAlex Lorenz OS << Mask.second; 749f3630113SAlex Lorenz // Clear the bits which were serialized from the flag's bitmask. 750f3630113SAlex Lorenz BitMask &= ~(Mask.first); 751f3630113SAlex Lorenz } 752f3630113SAlex Lorenz } 753f3630113SAlex Lorenz if (BitMask) { 754f3630113SAlex Lorenz // When the resulting flag's bitmask isn't zero, we know that we didn't 755f3630113SAlex Lorenz // serialize all of the bit flags. 756f3630113SAlex Lorenz if (IsCommaNeeded) 757f3630113SAlex Lorenz OS << ", "; 758f3630113SAlex Lorenz OS << "<unknown bitmask target flag>"; 759f3630113SAlex Lorenz } 76049873a83SAlex Lorenz OS << ") "; 76149873a83SAlex Lorenz } 76249873a83SAlex Lorenz 763ef5c196fSAlex Lorenz static const char *getTargetIndexName(const MachineFunction &MF, int Index) { 764ef5c196fSAlex Lorenz const auto *TII = MF.getSubtarget().getInstrInfo(); 765ef5c196fSAlex Lorenz assert(TII && "expected instruction info"); 766ef5c196fSAlex Lorenz auto Indices = TII->getSerializableTargetIndices(); 767ef5c196fSAlex Lorenz for (const auto &I : Indices) { 768ef5c196fSAlex Lorenz if (I.first == Index) { 769ef5c196fSAlex Lorenz return I.second; 770ef5c196fSAlex Lorenz } 771ef5c196fSAlex Lorenz } 772ef5c196fSAlex Lorenz return nullptr; 773ef5c196fSAlex Lorenz } 774ef5c196fSAlex Lorenz 775e66a7ccfSAlex Lorenz void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI, 776d28d3cc0STim Northover unsigned I, bool ShouldPrintRegisterTies, LLT TypeToPrint, 777d28d3cc0STim Northover bool IsDef) { 77849873a83SAlex Lorenz printTargetFlags(Op); 779f3db51deSAlex Lorenz switch (Op.getType()) { 780f3db51deSAlex Lorenz case MachineOperand::MO_Register: 781cb268d46SAlex Lorenz if (Op.isImplicit()) 782cb268d46SAlex Lorenz OS << (Op.isDef() ? "implicit-def " : "implicit "); 783e66a7ccfSAlex Lorenz else if (!IsDef && Op.isDef()) 784e66a7ccfSAlex Lorenz // Print the 'def' flag only when the operand is defined after '='. 785e66a7ccfSAlex Lorenz OS << "def "; 7861039fd1aSAlex Lorenz if (Op.isInternalRead()) 7871039fd1aSAlex Lorenz OS << "internal "; 788cbbfd0b1SAlex Lorenz if (Op.isDead()) 789cbbfd0b1SAlex Lorenz OS << "dead "; 790495ad879SAlex Lorenz if (Op.isKill()) 791495ad879SAlex Lorenz OS << "killed "; 7924d026b89SAlex Lorenz if (Op.isUndef()) 7934d026b89SAlex Lorenz OS << "undef "; 79401c1a5eeSAlex Lorenz if (Op.isEarlyClobber()) 79501c1a5eeSAlex Lorenz OS << "early-clobber "; 7969075258bSAlex Lorenz if (Op.isDebug()) 7979075258bSAlex Lorenz OS << "debug-use "; 798f3db51deSAlex Lorenz printReg(Op.getReg(), OS, TRI); 7992eacca86SAlex Lorenz // Print the sub register. 8002eacca86SAlex Lorenz if (Op.getSubReg() != 0) 801333e468dSMatthias Braun OS << '.' << TRI->getSubRegIndexName(Op.getSubReg()); 8025ef93b0cSAlex Lorenz if (ShouldPrintRegisterTies && Op.isTied() && !Op.isDef()) 8035ef93b0cSAlex Lorenz OS << "(tied-def " << Op.getParent()->findTiedOperandIdx(I) << ")"; 804d28d3cc0STim Northover if (TypeToPrint.isValid()) 805d28d3cc0STim Northover OS << '(' << TypeToPrint << ')'; 806f3db51deSAlex Lorenz break; 807240fc1e0SAlex Lorenz case MachineOperand::MO_Immediate: 808240fc1e0SAlex Lorenz OS << Op.getImm(); 809240fc1e0SAlex Lorenz break; 81005e3882eSAlex Lorenz case MachineOperand::MO_CImmediate: 81105e3882eSAlex Lorenz Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); 81205e3882eSAlex Lorenz break; 813ad156fb6SAlex Lorenz case MachineOperand::MO_FPImmediate: 814ad156fb6SAlex Lorenz Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); 815ad156fb6SAlex Lorenz break; 81633f0aef3SAlex Lorenz case MachineOperand::MO_MachineBasicBlock: 8175d26fa83SAlex Lorenz printMBBReference(*Op.getMBB()); 81833f0aef3SAlex Lorenz break; 8197feaf7c6SAlex Lorenz case MachineOperand::MO_FrameIndex: 8207feaf7c6SAlex Lorenz printStackObjectReference(Op.getIndex()); 8217feaf7c6SAlex Lorenz break; 822ab980499SAlex Lorenz case MachineOperand::MO_ConstantPoolIndex: 823ab980499SAlex Lorenz OS << "%const." << Op.getIndex(); 8245672a893SAlex Lorenz printOffset(Op.getOffset()); 825ab980499SAlex Lorenz break; 826ef5c196fSAlex Lorenz case MachineOperand::MO_TargetIndex: { 827ef5c196fSAlex Lorenz OS << "target-index("; 828ef5c196fSAlex Lorenz if (const auto *Name = getTargetIndexName( 829ef5c196fSAlex Lorenz *Op.getParent()->getParent()->getParent(), Op.getIndex())) 830ef5c196fSAlex Lorenz OS << Name; 831ef5c196fSAlex Lorenz else 832ef5c196fSAlex Lorenz OS << "<unknown>"; 833ef5c196fSAlex Lorenz OS << ')'; 8345672a893SAlex Lorenz printOffset(Op.getOffset()); 835ef5c196fSAlex Lorenz break; 836ef5c196fSAlex Lorenz } 83731d70683SAlex Lorenz case MachineOperand::MO_JumpTableIndex: 83831d70683SAlex Lorenz OS << "%jump-table." << Op.getIndex(); 83931d70683SAlex Lorenz break; 8406ede3744SAlex Lorenz case MachineOperand::MO_ExternalSymbol: 8416ede3744SAlex Lorenz OS << '$'; 8426ede3744SAlex Lorenz printLLVMNameWithoutPrefix(OS, Op.getSymbolName()); 8435672a893SAlex Lorenz printOffset(Op.getOffset()); 8446ede3744SAlex Lorenz break; 8455d6108e4SAlex Lorenz case MachineOperand::MO_GlobalAddress: 846900b5cb2SAlex Lorenz Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 8475672a893SAlex Lorenz printOffset(Op.getOffset()); 8485d6108e4SAlex Lorenz break; 849deb53490SAlex Lorenz case MachineOperand::MO_BlockAddress: 850deb53490SAlex Lorenz OS << "blockaddress("; 851deb53490SAlex Lorenz Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, 852deb53490SAlex Lorenz MST); 853deb53490SAlex Lorenz OS << ", "; 854deb53490SAlex Lorenz printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); 855deb53490SAlex Lorenz OS << ')'; 8565672a893SAlex Lorenz printOffset(Op.getOffset()); 857deb53490SAlex Lorenz break; 8588f6f4285SAlex Lorenz case MachineOperand::MO_RegisterMask: { 8598f6f4285SAlex Lorenz auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); 8608f6f4285SAlex Lorenz if (RegMaskInfo != RegisterMaskIds.end()) 8618f6f4285SAlex Lorenz OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); 8628f6f4285SAlex Lorenz else 8638f6f4285SAlex Lorenz llvm_unreachable("Can't print this machine register mask yet."); 8648f6f4285SAlex Lorenz break; 8658f6f4285SAlex Lorenz } 866b97c9ef4SAlex Lorenz case MachineOperand::MO_RegisterLiveOut: { 867b97c9ef4SAlex Lorenz const uint32_t *RegMask = Op.getRegLiveOut(); 868b97c9ef4SAlex Lorenz OS << "liveout("; 869b97c9ef4SAlex Lorenz bool IsCommaNeeded = false; 870b97c9ef4SAlex Lorenz for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { 871b97c9ef4SAlex Lorenz if (RegMask[Reg / 32] & (1U << (Reg % 32))) { 872b97c9ef4SAlex Lorenz if (IsCommaNeeded) 873b97c9ef4SAlex Lorenz OS << ", "; 874b97c9ef4SAlex Lorenz printReg(Reg, OS, TRI); 875b97c9ef4SAlex Lorenz IsCommaNeeded = true; 876b97c9ef4SAlex Lorenz } 877b97c9ef4SAlex Lorenz } 878b97c9ef4SAlex Lorenz OS << ")"; 879b97c9ef4SAlex Lorenz break; 880b97c9ef4SAlex Lorenz } 88135e44469SAlex Lorenz case MachineOperand::MO_Metadata: 88235e44469SAlex Lorenz Op.getMetadata()->printAsOperand(OS, MST); 88335e44469SAlex Lorenz break; 884f22ca8adSAlex Lorenz case MachineOperand::MO_MCSymbol: 885f22ca8adSAlex Lorenz OS << "<mcsymbol " << *Op.getMCSymbol() << ">"; 886f22ca8adSAlex Lorenz break; 887f4baeb51SAlex Lorenz case MachineOperand::MO_CFIIndex: { 888f23ef437SMatthias Braun const MachineFunction &MF = *Op.getParent()->getParent()->getParent(); 889f23ef437SMatthias Braun print(MF.getFrameInstructions()[Op.getCFIIndex()], TRI); 890f4baeb51SAlex Lorenz break; 891f4baeb51SAlex Lorenz } 8926b3bd612STim Northover case MachineOperand::MO_IntrinsicID: { 8936b3bd612STim Northover Intrinsic::ID ID = Op.getIntrinsicID(); 8946b3bd612STim Northover if (ID < Intrinsic::num_intrinsics) 8951523925dSPete Cooper OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')'; 8966b3bd612STim Northover else { 8976b3bd612STim Northover const MachineFunction &MF = *Op.getParent()->getParent()->getParent(); 8986b3bd612STim Northover const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo(); 8996b3bd612STim Northover OS << "intrinsic(@" << TII->getName(ID) << ')'; 9006b3bd612STim Northover } 9016b3bd612STim Northover break; 9026b3bd612STim Northover } 903de3aea04STim Northover case MachineOperand::MO_Predicate: { 904de3aea04STim Northover auto Pred = static_cast<CmpInst::Predicate>(Op.getPredicate()); 905de3aea04STim Northover OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred(" 906de3aea04STim Northover << CmpInst::getPredicateName(Pred) << ')'; 907de3aea04STim Northover break; 908de3aea04STim Northover } 909f3db51deSAlex Lorenz } 9104f093bf1SAlex Lorenz } 9114f093bf1SAlex Lorenz 9124af7e610SAlex Lorenz void MIPrinter::print(const MachineMemOperand &Op) { 9134af7e610SAlex Lorenz OS << '('; 914dc8de2a6SAlex Lorenz // TODO: Print operand's target specific flags. 915a518b796SAlex Lorenz if (Op.isVolatile()) 916a518b796SAlex Lorenz OS << "volatile "; 91710fd0385SAlex Lorenz if (Op.isNonTemporal()) 91810fd0385SAlex Lorenz OS << "non-temporal "; 919adbf09e8SJustin Lebar if (Op.isDereferenceable()) 920adbf09e8SJustin Lebar OS << "dereferenceable "; 921dc8de2a6SAlex Lorenz if (Op.isInvariant()) 922dc8de2a6SAlex Lorenz OS << "invariant "; 9234af7e610SAlex Lorenz if (Op.isLoad()) 9244af7e610SAlex Lorenz OS << "load "; 9254af7e610SAlex Lorenz else { 9264af7e610SAlex Lorenz assert(Op.isStore() && "Non load machine operand must be a store"); 9274af7e610SAlex Lorenz OS << "store "; 9284af7e610SAlex Lorenz } 929c25c9ccbSMatthias Braun OS << Op.getSize(); 93091097a3fSAlex Lorenz if (const Value *Val = Op.getValue()) { 931c25c9ccbSMatthias Braun OS << (Op.isLoad() ? " from " : " into "); 9324af7e610SAlex Lorenz printIRValueReference(*Val); 933c25c9ccbSMatthias Braun } else if (const PseudoSourceValue *PVal = Op.getPseudoValue()) { 934c25c9ccbSMatthias Braun OS << (Op.isLoad() ? " from " : " into "); 93591097a3fSAlex Lorenz assert(PVal && "Expected a pseudo source value"); 93691097a3fSAlex Lorenz switch (PVal->kind()) { 93746e9558aSAlex Lorenz case PseudoSourceValue::Stack: 93846e9558aSAlex Lorenz OS << "stack"; 93946e9558aSAlex Lorenz break; 940d858f874SAlex Lorenz case PseudoSourceValue::GOT: 941d858f874SAlex Lorenz OS << "got"; 942d858f874SAlex Lorenz break; 9434be56e93SAlex Lorenz case PseudoSourceValue::JumpTable: 9444be56e93SAlex Lorenz OS << "jump-table"; 9454be56e93SAlex Lorenz break; 94691097a3fSAlex Lorenz case PseudoSourceValue::ConstantPool: 94791097a3fSAlex Lorenz OS << "constant-pool"; 94891097a3fSAlex Lorenz break; 9490cc671bfSAlex Lorenz case PseudoSourceValue::FixedStack: 9500cc671bfSAlex Lorenz printStackObjectReference( 9510cc671bfSAlex Lorenz cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex()); 9520cc671bfSAlex Lorenz break; 95350b826fbSAlex Lorenz case PseudoSourceValue::GlobalValueCallEntry: 9540d009645SAlex Lorenz OS << "call-entry "; 95550b826fbSAlex Lorenz cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand( 95650b826fbSAlex Lorenz OS, /*PrintType=*/false, MST); 95750b826fbSAlex Lorenz break; 958c3ba7508SAlex Lorenz case PseudoSourceValue::ExternalSymbolCallEntry: 9590d009645SAlex Lorenz OS << "call-entry $"; 960c3ba7508SAlex Lorenz printLLVMNameWithoutPrefix( 961c3ba7508SAlex Lorenz OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol()); 96291097a3fSAlex Lorenz break; 96391097a3fSAlex Lorenz } 96491097a3fSAlex Lorenz } 96583127739SAlex Lorenz printOffset(Op.getOffset()); 96661420f79SAlex Lorenz if (Op.getBaseAlignment() != Op.getSize()) 96761420f79SAlex Lorenz OS << ", align " << Op.getBaseAlignment(); 968a617c916SAlex Lorenz auto AAInfo = Op.getAAInfo(); 969a617c916SAlex Lorenz if (AAInfo.TBAA) { 970a617c916SAlex Lorenz OS << ", !tbaa "; 971a617c916SAlex Lorenz AAInfo.TBAA->printAsOperand(OS, MST); 972a617c916SAlex Lorenz } 973a16f624dSAlex Lorenz if (AAInfo.Scope) { 974a16f624dSAlex Lorenz OS << ", !alias.scope "; 975a16f624dSAlex Lorenz AAInfo.Scope->printAsOperand(OS, MST); 976a16f624dSAlex Lorenz } 97703e940d1SAlex Lorenz if (AAInfo.NoAlias) { 97803e940d1SAlex Lorenz OS << ", !noalias "; 97903e940d1SAlex Lorenz AAInfo.NoAlias->printAsOperand(OS, MST); 98003e940d1SAlex Lorenz } 981eb625686SAlex Lorenz if (Op.getRanges()) { 982eb625686SAlex Lorenz OS << ", !range "; 983eb625686SAlex Lorenz Op.getRanges()->printAsOperand(OS, MST); 984eb625686SAlex Lorenz } 9854af7e610SAlex Lorenz OS << ')'; 9864af7e610SAlex Lorenz } 9874af7e610SAlex Lorenz 9888cfc6867SAlex Lorenz static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS, 9898cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 9908cfc6867SAlex Lorenz int Reg = TRI->getLLVMRegNum(DwarfReg, true); 9918cfc6867SAlex Lorenz if (Reg == -1) { 9928cfc6867SAlex Lorenz OS << "<badreg>"; 9938cfc6867SAlex Lorenz return; 9948cfc6867SAlex Lorenz } 9958cfc6867SAlex Lorenz printReg(Reg, OS, TRI); 9968cfc6867SAlex Lorenz } 9978cfc6867SAlex Lorenz 9988cfc6867SAlex Lorenz void MIPrinter::print(const MCCFIInstruction &CFI, 9998cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 1000f4baeb51SAlex Lorenz switch (CFI.getOperation()) { 1001577d271aSAlex Lorenz case MCCFIInstruction::OpSameValue: 1002ee067920SMatthias Braun OS << "same_value "; 1003577d271aSAlex Lorenz if (CFI.getLabel()) 1004577d271aSAlex Lorenz OS << "<mcsymbol> "; 1005577d271aSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 1006577d271aSAlex Lorenz break; 10078cfc6867SAlex Lorenz case MCCFIInstruction::OpOffset: 1008ee067920SMatthias Braun OS << "offset "; 10098cfc6867SAlex Lorenz if (CFI.getLabel()) 10108cfc6867SAlex Lorenz OS << "<mcsymbol> "; 10118cfc6867SAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 10128cfc6867SAlex Lorenz OS << ", " << CFI.getOffset(); 10138cfc6867SAlex Lorenz break; 10145b0d5f6fSAlex Lorenz case MCCFIInstruction::OpDefCfaRegister: 1015ee067920SMatthias Braun OS << "def_cfa_register "; 10165b0d5f6fSAlex Lorenz if (CFI.getLabel()) 10175b0d5f6fSAlex Lorenz OS << "<mcsymbol> "; 10185b0d5f6fSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 10195b0d5f6fSAlex Lorenz break; 1020f4baeb51SAlex Lorenz case MCCFIInstruction::OpDefCfaOffset: 1021ee067920SMatthias Braun OS << "def_cfa_offset "; 1022f4baeb51SAlex Lorenz if (CFI.getLabel()) 1023f4baeb51SAlex Lorenz OS << "<mcsymbol> "; 1024f4baeb51SAlex Lorenz OS << CFI.getOffset(); 1025f4baeb51SAlex Lorenz break; 1026b139323fSAlex Lorenz case MCCFIInstruction::OpDefCfa: 1027ee067920SMatthias Braun OS << "def_cfa "; 1028b139323fSAlex Lorenz if (CFI.getLabel()) 1029b139323fSAlex Lorenz OS << "<mcsymbol> "; 1030b139323fSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 1031b139323fSAlex Lorenz OS << ", " << CFI.getOffset(); 1032b139323fSAlex Lorenz break; 1033f4baeb51SAlex Lorenz default: 1034f4baeb51SAlex Lorenz // TODO: Print the other CFI Operations. 1035f4baeb51SAlex Lorenz OS << "<unserializable cfi operation>"; 1036f4baeb51SAlex Lorenz break; 1037f4baeb51SAlex Lorenz } 1038f4baeb51SAlex Lorenz } 1039f4baeb51SAlex Lorenz 1040345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) { 1041345c1449SAlex Lorenz yaml::Output Out(OS); 1042345c1449SAlex Lorenz Out << const_cast<Module &>(M); 1043345c1449SAlex Lorenz } 1044345c1449SAlex Lorenz 1045345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) { 1046345c1449SAlex Lorenz MIRPrinter Printer(OS); 1047345c1449SAlex Lorenz Printer.print(MF); 1048345c1449SAlex Lorenz } 1049