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" 17ab980499SAlex Lorenz #include "llvm/CodeGen/MachineConstantPool.h" 18345c1449SAlex Lorenz #include "llvm/CodeGen/MachineFunction.h" 1960541c1dSAlex Lorenz #include "llvm/CodeGen/MachineFrameInfo.h" 20f4baeb51SAlex Lorenz #include "llvm/CodeGen/MachineModuleInfo.h" 2154565cf0SAlex Lorenz #include "llvm/CodeGen/MachineRegisterInfo.h" 22345c1449SAlex Lorenz #include "llvm/CodeGen/MIRYamlMapping.h" 234f093bf1SAlex Lorenz #include "llvm/IR/BasicBlock.h" 2437643a04SAlex Lorenz #include "llvm/IR/Instructions.h" 256ede3744SAlex Lorenz #include "llvm/IR/IRPrintingPasses.h" 26345c1449SAlex Lorenz #include "llvm/IR/Module.h" 27900b5cb2SAlex Lorenz #include "llvm/IR/ModuleSlotTracker.h" 28345c1449SAlex Lorenz #include "llvm/Support/MemoryBuffer.h" 29345c1449SAlex Lorenz #include "llvm/Support/raw_ostream.h" 30345c1449SAlex Lorenz #include "llvm/Support/YAMLTraits.h" 318e0a1b48SAlex Lorenz #include "llvm/Target/TargetInstrInfo.h" 328e0a1b48SAlex Lorenz #include "llvm/Target/TargetSubtargetInfo.h" 33345c1449SAlex Lorenz 34345c1449SAlex Lorenz using namespace llvm; 35345c1449SAlex Lorenz 36345c1449SAlex Lorenz namespace { 37345c1449SAlex Lorenz 387feaf7c6SAlex Lorenz /// This structure describes how to print out stack object references. 397feaf7c6SAlex Lorenz struct FrameIndexOperand { 407feaf7c6SAlex Lorenz std::string Name; 417feaf7c6SAlex Lorenz unsigned ID; 427feaf7c6SAlex Lorenz bool IsFixed; 437feaf7c6SAlex Lorenz 447feaf7c6SAlex Lorenz FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed) 457feaf7c6SAlex Lorenz : Name(Name.str()), ID(ID), IsFixed(IsFixed) {} 467feaf7c6SAlex Lorenz 477feaf7c6SAlex Lorenz /// Return an ordinary stack object reference. 487feaf7c6SAlex Lorenz static FrameIndexOperand create(StringRef Name, unsigned ID) { 497feaf7c6SAlex Lorenz return FrameIndexOperand(Name, ID, /*IsFixed=*/false); 507feaf7c6SAlex Lorenz } 517feaf7c6SAlex Lorenz 527feaf7c6SAlex Lorenz /// Return a fixed stack object reference. 537feaf7c6SAlex Lorenz static FrameIndexOperand createFixed(unsigned ID) { 547feaf7c6SAlex Lorenz return FrameIndexOperand("", ID, /*IsFixed=*/true); 557feaf7c6SAlex Lorenz } 567feaf7c6SAlex Lorenz }; 577feaf7c6SAlex Lorenz 58345c1449SAlex Lorenz /// This class prints out the machine functions using the MIR serialization 59345c1449SAlex Lorenz /// format. 60345c1449SAlex Lorenz class MIRPrinter { 61345c1449SAlex Lorenz raw_ostream &OS; 628f6f4285SAlex Lorenz DenseMap<const uint32_t *, unsigned> RegisterMaskIds; 637feaf7c6SAlex Lorenz /// Maps from stack object indices to operand indices which will be used when 647feaf7c6SAlex Lorenz /// printing frame index machine operands. 657feaf7c6SAlex Lorenz DenseMap<int, FrameIndexOperand> StackObjectOperandMapping; 66345c1449SAlex Lorenz 67345c1449SAlex Lorenz public: 68345c1449SAlex Lorenz MIRPrinter(raw_ostream &OS) : OS(OS) {} 69345c1449SAlex Lorenz 70345c1449SAlex Lorenz void print(const MachineFunction &MF); 714f093bf1SAlex Lorenz 7228148ba8SAlex Lorenz void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo, 7328148ba8SAlex Lorenz const TargetRegisterInfo *TRI); 7460541c1dSAlex Lorenz void convert(yaml::MachineFrameInfo &YamlMFI, const MachineFrameInfo &MFI); 75ab980499SAlex Lorenz void convert(yaml::MachineFunction &MF, 76ab980499SAlex Lorenz const MachineConstantPool &ConstantPool); 776799e9b3SAlex Lorenz void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI, 786799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI); 79900b5cb2SAlex Lorenz void convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB, 805d6108e4SAlex Lorenz const MachineBasicBlock &MBB); 81f6bc8667SAlex Lorenz void convertStackObjects(yaml::MachineFunction &MF, 82f6bc8667SAlex Lorenz const MachineFrameInfo &MFI); 838f6f4285SAlex Lorenz 848f6f4285SAlex Lorenz private: 858f6f4285SAlex Lorenz void initRegisterMaskIds(const MachineFunction &MF); 86345c1449SAlex Lorenz }; 87345c1449SAlex Lorenz 888e0a1b48SAlex Lorenz /// This class prints out the machine instructions using the MIR serialization 898e0a1b48SAlex Lorenz /// format. 908e0a1b48SAlex Lorenz class MIPrinter { 918e0a1b48SAlex Lorenz raw_ostream &OS; 92900b5cb2SAlex Lorenz ModuleSlotTracker &MST; 938f6f4285SAlex Lorenz const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds; 947feaf7c6SAlex Lorenz const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping; 958e0a1b48SAlex Lorenz 968e0a1b48SAlex Lorenz public: 97900b5cb2SAlex Lorenz MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST, 987feaf7c6SAlex Lorenz const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds, 997feaf7c6SAlex Lorenz const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping) 1007feaf7c6SAlex Lorenz : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds), 1017feaf7c6SAlex Lorenz StackObjectOperandMapping(StackObjectOperandMapping) {} 1028e0a1b48SAlex Lorenz 1038e0a1b48SAlex Lorenz void print(const MachineInstr &MI); 1045d26fa83SAlex Lorenz void printMBBReference(const MachineBasicBlock &MBB); 1057feaf7c6SAlex Lorenz void printStackObjectReference(int FrameIndex); 106f3db51deSAlex Lorenz void print(const MachineOperand &Op, const TargetRegisterInfo *TRI); 107f4baeb51SAlex Lorenz 108f4baeb51SAlex Lorenz void print(const MCCFIInstruction &CFI); 1098e0a1b48SAlex Lorenz }; 1108e0a1b48SAlex Lorenz 111345c1449SAlex Lorenz } // end anonymous namespace 112345c1449SAlex Lorenz 113345c1449SAlex Lorenz namespace llvm { 114345c1449SAlex Lorenz namespace yaml { 115345c1449SAlex Lorenz 116345c1449SAlex Lorenz /// This struct serializes the LLVM IR module. 117345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> { 118345c1449SAlex Lorenz static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) { 119345c1449SAlex Lorenz Mod.print(OS, nullptr); 120345c1449SAlex Lorenz } 121345c1449SAlex Lorenz static StringRef input(StringRef Str, void *Ctxt, Module &Mod) { 122345c1449SAlex Lorenz llvm_unreachable("LLVM Module is supposed to be parsed separately"); 123345c1449SAlex Lorenz return ""; 124345c1449SAlex Lorenz } 125345c1449SAlex Lorenz }; 126345c1449SAlex Lorenz 127345c1449SAlex Lorenz } // end namespace yaml 128345c1449SAlex Lorenz } // end namespace llvm 129345c1449SAlex Lorenz 13015a00a85SAlex Lorenz static void printReg(unsigned Reg, raw_ostream &OS, 13115a00a85SAlex Lorenz const TargetRegisterInfo *TRI) { 13215a00a85SAlex Lorenz // TODO: Print Stack Slots. 13315a00a85SAlex Lorenz if (!Reg) 13415a00a85SAlex Lorenz OS << '_'; 13515a00a85SAlex Lorenz else if (TargetRegisterInfo::isVirtualRegister(Reg)) 13615a00a85SAlex Lorenz OS << '%' << TargetRegisterInfo::virtReg2Index(Reg); 13715a00a85SAlex Lorenz else if (Reg < TRI->getNumRegs()) 13815a00a85SAlex Lorenz OS << '%' << StringRef(TRI->getName(Reg)).lower(); 13915a00a85SAlex Lorenz else 14015a00a85SAlex Lorenz llvm_unreachable("Can't print this kind of register yet"); 14115a00a85SAlex Lorenz } 14215a00a85SAlex Lorenz 143345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) { 1448f6f4285SAlex Lorenz initRegisterMaskIds(MF); 1458f6f4285SAlex Lorenz 146345c1449SAlex Lorenz yaml::MachineFunction YamlMF; 147345c1449SAlex Lorenz YamlMF.Name = MF.getName(); 1485b5f9753SAlex Lorenz YamlMF.Alignment = MF.getAlignment(); 1495b5f9753SAlex Lorenz YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice(); 1505b5f9753SAlex Lorenz YamlMF.HasInlineAsm = MF.hasInlineAsm(); 15128148ba8SAlex Lorenz convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo()); 15260541c1dSAlex Lorenz convert(YamlMF.FrameInfo, *MF.getFrameInfo()); 153f6bc8667SAlex Lorenz convertStackObjects(YamlMF, *MF.getFrameInfo()); 154ab980499SAlex Lorenz if (const auto *ConstantPool = MF.getConstantPool()) 155ab980499SAlex Lorenz convert(YamlMF, *ConstantPool); 15633f0aef3SAlex Lorenz 157900b5cb2SAlex Lorenz ModuleSlotTracker MST(MF.getFunction()->getParent()); 1586799e9b3SAlex Lorenz if (const auto *JumpTableInfo = MF.getJumpTableInfo()) 1596799e9b3SAlex Lorenz convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo); 1606799e9b3SAlex Lorenz int I = 0; 1614f093bf1SAlex Lorenz for (const auto &MBB : MF) { 16233f0aef3SAlex Lorenz // TODO: Allow printing of non sequentially numbered MBBs. 16333f0aef3SAlex Lorenz // This is currently needed as the basic block references get their index 16433f0aef3SAlex Lorenz // from MBB.getNumber(), thus it should be sequential so that the parser can 16533f0aef3SAlex Lorenz // map back to the correct MBBs when parsing the output. 16633f0aef3SAlex Lorenz assert(MBB.getNumber() == I++ && 16733f0aef3SAlex Lorenz "Can't print MBBs that aren't sequentially numbered"); 168ec6b26b9SAlex Lorenz (void)I; 1694f093bf1SAlex Lorenz yaml::MachineBasicBlock YamlMBB; 170900b5cb2SAlex Lorenz convert(MST, YamlMBB, MBB); 1714f093bf1SAlex Lorenz YamlMF.BasicBlocks.push_back(YamlMBB); 1724f093bf1SAlex Lorenz } 173345c1449SAlex Lorenz yaml::Output Out(OS); 174345c1449SAlex Lorenz Out << YamlMF; 175345c1449SAlex Lorenz } 176345c1449SAlex Lorenz 17754565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 17828148ba8SAlex Lorenz const MachineRegisterInfo &RegInfo, 17928148ba8SAlex Lorenz const TargetRegisterInfo *TRI) { 18054565cf0SAlex Lorenz MF.IsSSA = RegInfo.isSSA(); 18154565cf0SAlex Lorenz MF.TracksRegLiveness = RegInfo.tracksLiveness(); 18254565cf0SAlex Lorenz MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled(); 18328148ba8SAlex Lorenz 18428148ba8SAlex Lorenz // Print the virtual register definitions. 18528148ba8SAlex Lorenz for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) { 18628148ba8SAlex Lorenz unsigned Reg = TargetRegisterInfo::index2VirtReg(I); 18728148ba8SAlex Lorenz yaml::VirtualRegisterDefinition VReg; 18828148ba8SAlex Lorenz VReg.ID = I; 18928148ba8SAlex Lorenz VReg.Class = 19028148ba8SAlex Lorenz StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower(); 19128148ba8SAlex Lorenz MF.VirtualRegisters.push_back(VReg); 19228148ba8SAlex Lorenz } 19354565cf0SAlex Lorenz } 19454565cf0SAlex Lorenz 19560541c1dSAlex Lorenz void MIRPrinter::convert(yaml::MachineFrameInfo &YamlMFI, 19660541c1dSAlex Lorenz const MachineFrameInfo &MFI) { 19760541c1dSAlex Lorenz YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken(); 19860541c1dSAlex Lorenz YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken(); 19960541c1dSAlex Lorenz YamlMFI.HasStackMap = MFI.hasStackMap(); 20060541c1dSAlex Lorenz YamlMFI.HasPatchPoint = MFI.hasPatchPoint(); 20160541c1dSAlex Lorenz YamlMFI.StackSize = MFI.getStackSize(); 20260541c1dSAlex Lorenz YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment(); 20360541c1dSAlex Lorenz YamlMFI.MaxAlignment = MFI.getMaxAlignment(); 20460541c1dSAlex Lorenz YamlMFI.AdjustsStack = MFI.adjustsStack(); 20560541c1dSAlex Lorenz YamlMFI.HasCalls = MFI.hasCalls(); 20660541c1dSAlex Lorenz YamlMFI.MaxCallFrameSize = MFI.getMaxCallFrameSize(); 20760541c1dSAlex Lorenz YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment(); 20860541c1dSAlex Lorenz YamlMFI.HasVAStart = MFI.hasVAStart(); 20960541c1dSAlex Lorenz YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc(); 21060541c1dSAlex Lorenz } 21160541c1dSAlex Lorenz 212f6bc8667SAlex Lorenz void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF, 213f6bc8667SAlex Lorenz const MachineFrameInfo &MFI) { 214de491f05SAlex Lorenz // Process fixed stack objects. 215f6bc8667SAlex Lorenz unsigned ID = 0; 216de491f05SAlex Lorenz for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) { 217de491f05SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 218de491f05SAlex Lorenz continue; 219de491f05SAlex Lorenz 220de491f05SAlex Lorenz yaml::FixedMachineStackObject YamlObject; 2217feaf7c6SAlex Lorenz YamlObject.ID = ID; 222de491f05SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 223de491f05SAlex Lorenz ? yaml::FixedMachineStackObject::SpillSlot 224de491f05SAlex Lorenz : yaml::FixedMachineStackObject::DefaultType; 225de491f05SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 226de491f05SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 227de491f05SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 228de491f05SAlex Lorenz YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I); 229de491f05SAlex Lorenz YamlObject.IsAliased = MFI.isAliasedObjectIndex(I); 230de491f05SAlex Lorenz MF.FixedStackObjects.push_back(YamlObject); 2317feaf7c6SAlex Lorenz StackObjectOperandMapping.insert( 2327feaf7c6SAlex Lorenz std::make_pair(I, FrameIndexOperand::createFixed(ID++))); 233de491f05SAlex Lorenz } 234de491f05SAlex Lorenz 235de491f05SAlex Lorenz // Process ordinary stack objects. 236de491f05SAlex Lorenz ID = 0; 237f6bc8667SAlex Lorenz for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) { 238f6bc8667SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 239f6bc8667SAlex Lorenz continue; 240f6bc8667SAlex Lorenz 241f6bc8667SAlex Lorenz yaml::MachineStackObject YamlObject; 2427feaf7c6SAlex Lorenz YamlObject.ID = ID; 24337643a04SAlex Lorenz if (const auto *Alloca = MFI.getObjectAllocation(I)) 24437643a04SAlex Lorenz YamlObject.Name.Value = 24537643a04SAlex Lorenz Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>"; 246f6bc8667SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 247f6bc8667SAlex Lorenz ? yaml::MachineStackObject::SpillSlot 248418f3ec1SAlex Lorenz : MFI.isVariableSizedObjectIndex(I) 249418f3ec1SAlex Lorenz ? yaml::MachineStackObject::VariableSized 250f6bc8667SAlex Lorenz : yaml::MachineStackObject::DefaultType; 251f6bc8667SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 252f6bc8667SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 253f6bc8667SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 254f6bc8667SAlex Lorenz 255f6bc8667SAlex Lorenz MF.StackObjects.push_back(YamlObject); 2567feaf7c6SAlex Lorenz StackObjectOperandMapping.insert(std::make_pair( 2577feaf7c6SAlex Lorenz I, FrameIndexOperand::create(YamlObject.Name.Value, ID++))); 258f6bc8667SAlex Lorenz } 259f6bc8667SAlex Lorenz } 260f6bc8667SAlex Lorenz 261ab980499SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 262ab980499SAlex Lorenz const MachineConstantPool &ConstantPool) { 263ab980499SAlex Lorenz unsigned ID = 0; 264ab980499SAlex Lorenz for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) { 265ab980499SAlex Lorenz // TODO: Serialize target specific constant pool entries. 266ab980499SAlex Lorenz if (Constant.isMachineConstantPoolEntry()) 267ab980499SAlex Lorenz llvm_unreachable("Can't print target specific constant pool entries yet"); 268ab980499SAlex Lorenz 269ab980499SAlex Lorenz yaml::MachineConstantPoolValue YamlConstant; 270ab980499SAlex Lorenz std::string Str; 271ab980499SAlex Lorenz raw_string_ostream StrOS(Str); 272ab980499SAlex Lorenz Constant.Val.ConstVal->printAsOperand(StrOS); 273ab980499SAlex Lorenz YamlConstant.ID = ID++; 274ab980499SAlex Lorenz YamlConstant.Value = StrOS.str(); 275ab980499SAlex Lorenz YamlConstant.Alignment = Constant.getAlignment(); 276ab980499SAlex Lorenz MF.Constants.push_back(YamlConstant); 277ab980499SAlex Lorenz } 278ab980499SAlex Lorenz } 279ab980499SAlex Lorenz 280900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 2816799e9b3SAlex Lorenz yaml::MachineJumpTable &YamlJTI, 2826799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI) { 2836799e9b3SAlex Lorenz YamlJTI.Kind = JTI.getEntryKind(); 2846799e9b3SAlex Lorenz unsigned ID = 0; 2856799e9b3SAlex Lorenz for (const auto &Table : JTI.getJumpTables()) { 2866799e9b3SAlex Lorenz std::string Str; 2876799e9b3SAlex Lorenz yaml::MachineJumpTable::Entry Entry; 2886799e9b3SAlex Lorenz Entry.ID = ID++; 2896799e9b3SAlex Lorenz for (const auto *MBB : Table.MBBs) { 2906799e9b3SAlex Lorenz raw_string_ostream StrOS(Str); 2917feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 2927feaf7c6SAlex Lorenz .printMBBReference(*MBB); 2936799e9b3SAlex Lorenz Entry.Blocks.push_back(StrOS.str()); 2946799e9b3SAlex Lorenz Str.clear(); 2956799e9b3SAlex Lorenz } 2966799e9b3SAlex Lorenz YamlJTI.Entries.push_back(Entry); 2976799e9b3SAlex Lorenz } 2986799e9b3SAlex Lorenz } 2996799e9b3SAlex Lorenz 3006799e9b3SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 301900b5cb2SAlex Lorenz yaml::MachineBasicBlock &YamlMBB, 3024f093bf1SAlex Lorenz const MachineBasicBlock &MBB) { 30333f0aef3SAlex Lorenz assert(MBB.getNumber() >= 0 && "Invalid MBB number"); 30433f0aef3SAlex Lorenz YamlMBB.ID = (unsigned)MBB.getNumber(); 3054f093bf1SAlex Lorenz // TODO: Serialize unnamed BB references. 3064f093bf1SAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) 307b1f9ce8fSAlex Lorenz YamlMBB.Name.Value = BB->hasName() ? BB->getName() : "<unnamed bb>"; 3084f093bf1SAlex Lorenz else 309b1f9ce8fSAlex Lorenz YamlMBB.Name.Value = ""; 3104f093bf1SAlex Lorenz YamlMBB.Alignment = MBB.getAlignment(); 3114f093bf1SAlex Lorenz YamlMBB.AddressTaken = MBB.hasAddressTaken(); 3124f093bf1SAlex Lorenz YamlMBB.IsLandingPad = MBB.isLandingPad(); 313eb5112bfSAlex Lorenz for (const auto *SuccMBB : MBB.successors()) { 314f09df00dSAlex Lorenz std::string Str; 315f09df00dSAlex Lorenz raw_string_ostream StrOS(Str); 3167feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 3177feaf7c6SAlex Lorenz .printMBBReference(*SuccMBB); 318f09df00dSAlex Lorenz YamlMBB.Successors.push_back(StrOS.str()); 319f09df00dSAlex Lorenz } 3209fab370dSAlex Lorenz // Print the live in registers. 3219fab370dSAlex Lorenz const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo(); 3229fab370dSAlex Lorenz assert(TRI && "Expected target register info"); 3239fab370dSAlex Lorenz for (auto I = MBB.livein_begin(), E = MBB.livein_end(); I != E; ++I) { 3249fab370dSAlex Lorenz std::string Str; 3259fab370dSAlex Lorenz raw_string_ostream StrOS(Str); 3269fab370dSAlex Lorenz printReg(*I, StrOS, TRI); 3279fab370dSAlex Lorenz YamlMBB.LiveIns.push_back(StrOS.str()); 3289fab370dSAlex Lorenz } 3298e0a1b48SAlex Lorenz // Print the machine instructions. 3308e0a1b48SAlex Lorenz YamlMBB.Instructions.reserve(MBB.size()); 3318e0a1b48SAlex Lorenz std::string Str; 3328e0a1b48SAlex Lorenz for (const auto &MI : MBB) { 3338e0a1b48SAlex Lorenz raw_string_ostream StrOS(Str); 3347feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping).print(MI); 3358e0a1b48SAlex Lorenz YamlMBB.Instructions.push_back(StrOS.str()); 3368e0a1b48SAlex Lorenz Str.clear(); 3378e0a1b48SAlex Lorenz } 3388e0a1b48SAlex Lorenz } 3398e0a1b48SAlex Lorenz 3408f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) { 3418f6f4285SAlex Lorenz const auto *TRI = MF.getSubtarget().getRegisterInfo(); 3428f6f4285SAlex Lorenz unsigned I = 0; 3438f6f4285SAlex Lorenz for (const uint32_t *Mask : TRI->getRegMasks()) 3448f6f4285SAlex Lorenz RegisterMaskIds.insert(std::make_pair(Mask, I++)); 3458f6f4285SAlex Lorenz } 3468f6f4285SAlex Lorenz 3478e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) { 3488e0a1b48SAlex Lorenz const auto &SubTarget = MI.getParent()->getParent()->getSubtarget(); 349f3db51deSAlex Lorenz const auto *TRI = SubTarget.getRegisterInfo(); 350f3db51deSAlex Lorenz assert(TRI && "Expected target register info"); 3518e0a1b48SAlex Lorenz const auto *TII = SubTarget.getInstrInfo(); 3528e0a1b48SAlex Lorenz assert(TII && "Expected target instruction info"); 353f4baeb51SAlex Lorenz if (MI.isCFIInstruction()) 354f4baeb51SAlex Lorenz assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction"); 3558e0a1b48SAlex Lorenz 356f3db51deSAlex Lorenz unsigned I = 0, E = MI.getNumOperands(); 357f3db51deSAlex Lorenz for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() && 358f3db51deSAlex Lorenz !MI.getOperand(I).isImplicit(); 359f3db51deSAlex Lorenz ++I) { 360f3db51deSAlex Lorenz if (I) 361f3db51deSAlex Lorenz OS << ", "; 362f3db51deSAlex Lorenz print(MI.getOperand(I), TRI); 363f3db51deSAlex Lorenz } 364f3db51deSAlex Lorenz 365f3db51deSAlex Lorenz if (I) 366f3db51deSAlex Lorenz OS << " = "; 367e5a44660SAlex Lorenz if (MI.getFlag(MachineInstr::FrameSetup)) 368e5a44660SAlex Lorenz OS << "frame-setup "; 3698e0a1b48SAlex Lorenz OS << TII->getName(MI.getOpcode()); 370e5a44660SAlex Lorenz // TODO: Print the bundling instruction flags, machine mem operands. 371f3db51deSAlex Lorenz if (I < E) 372f3db51deSAlex Lorenz OS << ' '; 373f3db51deSAlex Lorenz 374f3db51deSAlex Lorenz bool NeedComma = false; 375f3db51deSAlex Lorenz for (; I < E; ++I) { 376f3db51deSAlex Lorenz if (NeedComma) 377f3db51deSAlex Lorenz OS << ", "; 378f3db51deSAlex Lorenz print(MI.getOperand(I), TRI); 379f3db51deSAlex Lorenz NeedComma = true; 380f3db51deSAlex Lorenz } 381*46d760d1SAlex Lorenz 382*46d760d1SAlex Lorenz if (MI.getDebugLoc()) { 383*46d760d1SAlex Lorenz if (NeedComma) 384*46d760d1SAlex Lorenz OS << ','; 385*46d760d1SAlex Lorenz OS << " debug-location "; 386*46d760d1SAlex Lorenz MI.getDebugLoc()->printAsOperand(OS, MST); 387*46d760d1SAlex Lorenz } 388f3db51deSAlex Lorenz } 389f3db51deSAlex Lorenz 3905d26fa83SAlex Lorenz void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) { 3915d26fa83SAlex Lorenz OS << "%bb." << MBB.getNumber(); 3925d26fa83SAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 3935d26fa83SAlex Lorenz if (BB->hasName()) 3945d26fa83SAlex Lorenz OS << '.' << BB->getName(); 3955d26fa83SAlex Lorenz } 3965d26fa83SAlex Lorenz } 3975d26fa83SAlex Lorenz 3987feaf7c6SAlex Lorenz void MIPrinter::printStackObjectReference(int FrameIndex) { 3997feaf7c6SAlex Lorenz auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex); 4007feaf7c6SAlex Lorenz assert(ObjectInfo != StackObjectOperandMapping.end() && 4017feaf7c6SAlex Lorenz "Invalid frame index"); 4027feaf7c6SAlex Lorenz const FrameIndexOperand &Operand = ObjectInfo->second; 4037feaf7c6SAlex Lorenz if (Operand.IsFixed) { 4047feaf7c6SAlex Lorenz OS << "%fixed-stack." << Operand.ID; 4057feaf7c6SAlex Lorenz return; 4067feaf7c6SAlex Lorenz } 4077feaf7c6SAlex Lorenz OS << "%stack." << Operand.ID; 4087feaf7c6SAlex Lorenz if (!Operand.Name.empty()) 4097feaf7c6SAlex Lorenz OS << '.' << Operand.Name; 4107feaf7c6SAlex Lorenz } 4117feaf7c6SAlex Lorenz 412f3db51deSAlex Lorenz void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { 413f3db51deSAlex Lorenz switch (Op.getType()) { 414f3db51deSAlex Lorenz case MachineOperand::MO_Register: 415cb268d46SAlex Lorenz // TODO: Print the other register flags. 416cb268d46SAlex Lorenz if (Op.isImplicit()) 417cb268d46SAlex Lorenz OS << (Op.isDef() ? "implicit-def " : "implicit "); 418cbbfd0b1SAlex Lorenz if (Op.isDead()) 419cbbfd0b1SAlex Lorenz OS << "dead "; 420495ad879SAlex Lorenz if (Op.isKill()) 421495ad879SAlex Lorenz OS << "killed "; 4224d026b89SAlex Lorenz if (Op.isUndef()) 4234d026b89SAlex Lorenz OS << "undef "; 424f3db51deSAlex Lorenz printReg(Op.getReg(), OS, TRI); 4252eacca86SAlex Lorenz // Print the sub register. 4262eacca86SAlex Lorenz if (Op.getSubReg() != 0) 4272eacca86SAlex Lorenz OS << ':' << TRI->getSubRegIndexName(Op.getSubReg()); 428f3db51deSAlex Lorenz break; 429240fc1e0SAlex Lorenz case MachineOperand::MO_Immediate: 430240fc1e0SAlex Lorenz OS << Op.getImm(); 431240fc1e0SAlex Lorenz break; 43233f0aef3SAlex Lorenz case MachineOperand::MO_MachineBasicBlock: 4335d26fa83SAlex Lorenz printMBBReference(*Op.getMBB()); 43433f0aef3SAlex Lorenz break; 4357feaf7c6SAlex Lorenz case MachineOperand::MO_FrameIndex: 4367feaf7c6SAlex Lorenz printStackObjectReference(Op.getIndex()); 4377feaf7c6SAlex Lorenz break; 438ab980499SAlex Lorenz case MachineOperand::MO_ConstantPoolIndex: 439ab980499SAlex Lorenz OS << "%const." << Op.getIndex(); 440ab980499SAlex Lorenz // TODO: Print offset and target flags. 441ab980499SAlex Lorenz break; 44231d70683SAlex Lorenz case MachineOperand::MO_JumpTableIndex: 44331d70683SAlex Lorenz OS << "%jump-table." << Op.getIndex(); 44431d70683SAlex Lorenz // TODO: Print target flags. 44531d70683SAlex Lorenz break; 4466ede3744SAlex Lorenz case MachineOperand::MO_ExternalSymbol: 4476ede3744SAlex Lorenz OS << '$'; 4486ede3744SAlex Lorenz printLLVMNameWithoutPrefix(OS, Op.getSymbolName()); 4496ede3744SAlex Lorenz // TODO: Print the target flags. 4506ede3744SAlex Lorenz break; 4515d6108e4SAlex Lorenz case MachineOperand::MO_GlobalAddress: 452900b5cb2SAlex Lorenz Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 4535d6108e4SAlex Lorenz // TODO: Print offset and target flags. 4545d6108e4SAlex Lorenz break; 4558f6f4285SAlex Lorenz case MachineOperand::MO_RegisterMask: { 4568f6f4285SAlex Lorenz auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); 4578f6f4285SAlex Lorenz if (RegMaskInfo != RegisterMaskIds.end()) 4588f6f4285SAlex Lorenz OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); 4598f6f4285SAlex Lorenz else 4608f6f4285SAlex Lorenz llvm_unreachable("Can't print this machine register mask yet."); 4618f6f4285SAlex Lorenz break; 4628f6f4285SAlex Lorenz } 46335e44469SAlex Lorenz case MachineOperand::MO_Metadata: 46435e44469SAlex Lorenz Op.getMetadata()->printAsOperand(OS, MST); 46535e44469SAlex Lorenz break; 466f4baeb51SAlex Lorenz case MachineOperand::MO_CFIIndex: { 467f4baeb51SAlex Lorenz const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI(); 468f4baeb51SAlex Lorenz print(MMI.getFrameInstructions()[Op.getCFIIndex()]); 469f4baeb51SAlex Lorenz break; 470f4baeb51SAlex Lorenz } 471f3db51deSAlex Lorenz default: 472f3db51deSAlex Lorenz // TODO: Print the other machine operands. 473f3db51deSAlex Lorenz llvm_unreachable("Can't print this machine operand at the moment"); 474f3db51deSAlex Lorenz } 4754f093bf1SAlex Lorenz } 4764f093bf1SAlex Lorenz 477f4baeb51SAlex Lorenz void MIPrinter::print(const MCCFIInstruction &CFI) { 478f4baeb51SAlex Lorenz switch (CFI.getOperation()) { 479f4baeb51SAlex Lorenz case MCCFIInstruction::OpDefCfaOffset: 480f4baeb51SAlex Lorenz OS << ".cfi_def_cfa_offset "; 481f4baeb51SAlex Lorenz if (CFI.getLabel()) 482f4baeb51SAlex Lorenz OS << "<mcsymbol> "; 483f4baeb51SAlex Lorenz OS << CFI.getOffset(); 484f4baeb51SAlex Lorenz break; 485f4baeb51SAlex Lorenz default: 486f4baeb51SAlex Lorenz // TODO: Print the other CFI Operations. 487f4baeb51SAlex Lorenz OS << "<unserializable cfi operation>"; 488f4baeb51SAlex Lorenz break; 489f4baeb51SAlex Lorenz } 490f4baeb51SAlex Lorenz } 491f4baeb51SAlex Lorenz 492345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) { 493345c1449SAlex Lorenz yaml::Output Out(OS); 494345c1449SAlex Lorenz Out << const_cast<Module &>(M); 495345c1449SAlex Lorenz } 496345c1449SAlex Lorenz 497345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) { 498345c1449SAlex Lorenz MIRPrinter Printer(OS); 499345c1449SAlex Lorenz Printer.print(MF); 500345c1449SAlex Lorenz } 501