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, 821bb48de1SAlex Lorenz const MachineFrameInfo &MFI, 831bb48de1SAlex Lorenz const TargetRegisterInfo *TRI); 848f6f4285SAlex Lorenz 858f6f4285SAlex Lorenz private: 868f6f4285SAlex Lorenz void initRegisterMaskIds(const MachineFunction &MF); 87345c1449SAlex Lorenz }; 88345c1449SAlex Lorenz 898e0a1b48SAlex Lorenz /// This class prints out the machine instructions using the MIR serialization 908e0a1b48SAlex Lorenz /// format. 918e0a1b48SAlex Lorenz class MIPrinter { 928e0a1b48SAlex Lorenz raw_ostream &OS; 93900b5cb2SAlex Lorenz ModuleSlotTracker &MST; 948f6f4285SAlex Lorenz const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds; 957feaf7c6SAlex Lorenz const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping; 968e0a1b48SAlex Lorenz 978e0a1b48SAlex Lorenz public: 98900b5cb2SAlex Lorenz MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST, 997feaf7c6SAlex Lorenz const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds, 1007feaf7c6SAlex Lorenz const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping) 1017feaf7c6SAlex Lorenz : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds), 1027feaf7c6SAlex Lorenz StackObjectOperandMapping(StackObjectOperandMapping) {} 1038e0a1b48SAlex Lorenz 1048e0a1b48SAlex Lorenz void print(const MachineInstr &MI); 1055d26fa83SAlex Lorenz void printMBBReference(const MachineBasicBlock &MBB); 1067feaf7c6SAlex Lorenz void printStackObjectReference(int FrameIndex); 107f3db51deSAlex Lorenz void print(const MachineOperand &Op, const TargetRegisterInfo *TRI); 108f4baeb51SAlex Lorenz 1098cfc6867SAlex Lorenz void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI); 1108e0a1b48SAlex Lorenz }; 1118e0a1b48SAlex Lorenz 112345c1449SAlex Lorenz } // end anonymous namespace 113345c1449SAlex Lorenz 114345c1449SAlex Lorenz namespace llvm { 115345c1449SAlex Lorenz namespace yaml { 116345c1449SAlex Lorenz 117345c1449SAlex Lorenz /// This struct serializes the LLVM IR module. 118345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> { 119345c1449SAlex Lorenz static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) { 120345c1449SAlex Lorenz Mod.print(OS, nullptr); 121345c1449SAlex Lorenz } 122345c1449SAlex Lorenz static StringRef input(StringRef Str, void *Ctxt, Module &Mod) { 123345c1449SAlex Lorenz llvm_unreachable("LLVM Module is supposed to be parsed separately"); 124345c1449SAlex Lorenz return ""; 125345c1449SAlex Lorenz } 126345c1449SAlex Lorenz }; 127345c1449SAlex Lorenz 128345c1449SAlex Lorenz } // end namespace yaml 129345c1449SAlex Lorenz } // end namespace llvm 130345c1449SAlex Lorenz 13115a00a85SAlex Lorenz static void printReg(unsigned Reg, raw_ostream &OS, 13215a00a85SAlex Lorenz const TargetRegisterInfo *TRI) { 13315a00a85SAlex Lorenz // TODO: Print Stack Slots. 13415a00a85SAlex Lorenz if (!Reg) 13515a00a85SAlex Lorenz OS << '_'; 13615a00a85SAlex Lorenz else if (TargetRegisterInfo::isVirtualRegister(Reg)) 13715a00a85SAlex Lorenz OS << '%' << TargetRegisterInfo::virtReg2Index(Reg); 13815a00a85SAlex Lorenz else if (Reg < TRI->getNumRegs()) 13915a00a85SAlex Lorenz OS << '%' << StringRef(TRI->getName(Reg)).lower(); 14015a00a85SAlex Lorenz else 14115a00a85SAlex Lorenz llvm_unreachable("Can't print this kind of register yet"); 14215a00a85SAlex Lorenz } 14315a00a85SAlex Lorenz 144ab4cbcfdSAlex Lorenz static void printReg(unsigned Reg, yaml::StringValue &Dest, 145ab4cbcfdSAlex Lorenz const TargetRegisterInfo *TRI) { 146ab4cbcfdSAlex Lorenz raw_string_ostream OS(Dest.Value); 147ab4cbcfdSAlex Lorenz printReg(Reg, OS, TRI); 148ab4cbcfdSAlex Lorenz } 149ab4cbcfdSAlex Lorenz 150345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) { 1518f6f4285SAlex Lorenz initRegisterMaskIds(MF); 1528f6f4285SAlex Lorenz 153345c1449SAlex Lorenz yaml::MachineFunction YamlMF; 154345c1449SAlex Lorenz YamlMF.Name = MF.getName(); 1555b5f9753SAlex Lorenz YamlMF.Alignment = MF.getAlignment(); 1565b5f9753SAlex Lorenz YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice(); 1575b5f9753SAlex Lorenz YamlMF.HasInlineAsm = MF.hasInlineAsm(); 15828148ba8SAlex Lorenz convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo()); 15960541c1dSAlex Lorenz convert(YamlMF.FrameInfo, *MF.getFrameInfo()); 1601bb48de1SAlex Lorenz convertStackObjects(YamlMF, *MF.getFrameInfo(), 1611bb48de1SAlex Lorenz MF.getSubtarget().getRegisterInfo()); 162ab980499SAlex Lorenz if (const auto *ConstantPool = MF.getConstantPool()) 163ab980499SAlex Lorenz convert(YamlMF, *ConstantPool); 16433f0aef3SAlex Lorenz 165900b5cb2SAlex Lorenz ModuleSlotTracker MST(MF.getFunction()->getParent()); 166*8a1915b0SAlex Lorenz MST.incorporateFunction(*MF.getFunction()); 1676799e9b3SAlex Lorenz if (const auto *JumpTableInfo = MF.getJumpTableInfo()) 1686799e9b3SAlex Lorenz convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo); 1696799e9b3SAlex Lorenz int I = 0; 1704f093bf1SAlex Lorenz for (const auto &MBB : MF) { 17133f0aef3SAlex Lorenz // TODO: Allow printing of non sequentially numbered MBBs. 17233f0aef3SAlex Lorenz // This is currently needed as the basic block references get their index 17333f0aef3SAlex Lorenz // from MBB.getNumber(), thus it should be sequential so that the parser can 17433f0aef3SAlex Lorenz // map back to the correct MBBs when parsing the output. 17533f0aef3SAlex Lorenz assert(MBB.getNumber() == I++ && 17633f0aef3SAlex Lorenz "Can't print MBBs that aren't sequentially numbered"); 177ec6b26b9SAlex Lorenz (void)I; 1784f093bf1SAlex Lorenz yaml::MachineBasicBlock YamlMBB; 179900b5cb2SAlex Lorenz convert(MST, YamlMBB, MBB); 1804f093bf1SAlex Lorenz YamlMF.BasicBlocks.push_back(YamlMBB); 1814f093bf1SAlex Lorenz } 182345c1449SAlex Lorenz yaml::Output Out(OS); 183345c1449SAlex Lorenz Out << YamlMF; 184345c1449SAlex Lorenz } 185345c1449SAlex Lorenz 18654565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 18728148ba8SAlex Lorenz const MachineRegisterInfo &RegInfo, 18828148ba8SAlex Lorenz const TargetRegisterInfo *TRI) { 18954565cf0SAlex Lorenz MF.IsSSA = RegInfo.isSSA(); 19054565cf0SAlex Lorenz MF.TracksRegLiveness = RegInfo.tracksLiveness(); 19154565cf0SAlex Lorenz MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled(); 19228148ba8SAlex Lorenz 19328148ba8SAlex Lorenz // Print the virtual register definitions. 19428148ba8SAlex Lorenz for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) { 19528148ba8SAlex Lorenz unsigned Reg = TargetRegisterInfo::index2VirtReg(I); 19628148ba8SAlex Lorenz yaml::VirtualRegisterDefinition VReg; 19728148ba8SAlex Lorenz VReg.ID = I; 19828148ba8SAlex Lorenz VReg.Class = 19928148ba8SAlex Lorenz StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower(); 200ab4cbcfdSAlex Lorenz unsigned PreferredReg = RegInfo.getSimpleHint(Reg); 201ab4cbcfdSAlex Lorenz if (PreferredReg) 202ab4cbcfdSAlex Lorenz printReg(PreferredReg, VReg.PreferredRegister, TRI); 20328148ba8SAlex Lorenz MF.VirtualRegisters.push_back(VReg); 20428148ba8SAlex Lorenz } 20512045a4bSAlex Lorenz 20612045a4bSAlex Lorenz // Print the live ins. 20712045a4bSAlex Lorenz for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) { 20812045a4bSAlex Lorenz yaml::MachineFunctionLiveIn LiveIn; 20912045a4bSAlex Lorenz printReg(I->first, LiveIn.Register, TRI); 21012045a4bSAlex Lorenz if (I->second) 21112045a4bSAlex Lorenz printReg(I->second, LiveIn.VirtualRegister, TRI); 21212045a4bSAlex Lorenz MF.LiveIns.push_back(LiveIn); 21312045a4bSAlex Lorenz } 21454565cf0SAlex Lorenz } 21554565cf0SAlex Lorenz 21660541c1dSAlex Lorenz void MIRPrinter::convert(yaml::MachineFrameInfo &YamlMFI, 21760541c1dSAlex Lorenz const MachineFrameInfo &MFI) { 21860541c1dSAlex Lorenz YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken(); 21960541c1dSAlex Lorenz YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken(); 22060541c1dSAlex Lorenz YamlMFI.HasStackMap = MFI.hasStackMap(); 22160541c1dSAlex Lorenz YamlMFI.HasPatchPoint = MFI.hasPatchPoint(); 22260541c1dSAlex Lorenz YamlMFI.StackSize = MFI.getStackSize(); 22360541c1dSAlex Lorenz YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment(); 22460541c1dSAlex Lorenz YamlMFI.MaxAlignment = MFI.getMaxAlignment(); 22560541c1dSAlex Lorenz YamlMFI.AdjustsStack = MFI.adjustsStack(); 22660541c1dSAlex Lorenz YamlMFI.HasCalls = MFI.hasCalls(); 22760541c1dSAlex Lorenz YamlMFI.MaxCallFrameSize = MFI.getMaxCallFrameSize(); 22860541c1dSAlex Lorenz YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment(); 22960541c1dSAlex Lorenz YamlMFI.HasVAStart = MFI.hasVAStart(); 23060541c1dSAlex Lorenz YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc(); 23160541c1dSAlex Lorenz } 23260541c1dSAlex Lorenz 233f6bc8667SAlex Lorenz void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF, 2341bb48de1SAlex Lorenz const MachineFrameInfo &MFI, 2351bb48de1SAlex Lorenz const TargetRegisterInfo *TRI) { 236de491f05SAlex Lorenz // Process fixed stack objects. 237f6bc8667SAlex Lorenz unsigned ID = 0; 238de491f05SAlex Lorenz for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) { 239de491f05SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 240de491f05SAlex Lorenz continue; 241de491f05SAlex Lorenz 242de491f05SAlex Lorenz yaml::FixedMachineStackObject YamlObject; 2437feaf7c6SAlex Lorenz YamlObject.ID = ID; 244de491f05SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 245de491f05SAlex Lorenz ? yaml::FixedMachineStackObject::SpillSlot 246de491f05SAlex Lorenz : yaml::FixedMachineStackObject::DefaultType; 247de491f05SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 248de491f05SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 249de491f05SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 250de491f05SAlex Lorenz YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I); 251de491f05SAlex Lorenz YamlObject.IsAliased = MFI.isAliasedObjectIndex(I); 252de491f05SAlex Lorenz MF.FixedStackObjects.push_back(YamlObject); 2537feaf7c6SAlex Lorenz StackObjectOperandMapping.insert( 2547feaf7c6SAlex Lorenz std::make_pair(I, FrameIndexOperand::createFixed(ID++))); 255de491f05SAlex Lorenz } 256de491f05SAlex Lorenz 257de491f05SAlex Lorenz // Process ordinary stack objects. 258de491f05SAlex Lorenz ID = 0; 259f6bc8667SAlex Lorenz for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) { 260f6bc8667SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 261f6bc8667SAlex Lorenz continue; 262f6bc8667SAlex Lorenz 263f6bc8667SAlex Lorenz yaml::MachineStackObject YamlObject; 2647feaf7c6SAlex Lorenz YamlObject.ID = ID; 26537643a04SAlex Lorenz if (const auto *Alloca = MFI.getObjectAllocation(I)) 26637643a04SAlex Lorenz YamlObject.Name.Value = 26737643a04SAlex Lorenz Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>"; 268f6bc8667SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 269f6bc8667SAlex Lorenz ? yaml::MachineStackObject::SpillSlot 270418f3ec1SAlex Lorenz : MFI.isVariableSizedObjectIndex(I) 271418f3ec1SAlex Lorenz ? yaml::MachineStackObject::VariableSized 272f6bc8667SAlex Lorenz : yaml::MachineStackObject::DefaultType; 273f6bc8667SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 274f6bc8667SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 275f6bc8667SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 276f6bc8667SAlex Lorenz 277f6bc8667SAlex Lorenz MF.StackObjects.push_back(YamlObject); 2787feaf7c6SAlex Lorenz StackObjectOperandMapping.insert(std::make_pair( 2797feaf7c6SAlex Lorenz I, FrameIndexOperand::create(YamlObject.Name.Value, ID++))); 280f6bc8667SAlex Lorenz } 2811bb48de1SAlex Lorenz 2821bb48de1SAlex Lorenz for (const auto &CSInfo : MFI.getCalleeSavedInfo()) { 2831bb48de1SAlex Lorenz yaml::StringValue Reg; 2841bb48de1SAlex Lorenz printReg(CSInfo.getReg(), Reg, TRI); 2851bb48de1SAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx()); 2861bb48de1SAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 2871bb48de1SAlex Lorenz "Invalid stack object index"); 2881bb48de1SAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 2891bb48de1SAlex Lorenz if (StackObject.IsFixed) 2901bb48de1SAlex Lorenz MF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg; 2911bb48de1SAlex Lorenz else 2921bb48de1SAlex Lorenz MF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg; 2931bb48de1SAlex Lorenz } 294f6bc8667SAlex Lorenz } 295f6bc8667SAlex Lorenz 296ab980499SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 297ab980499SAlex Lorenz const MachineConstantPool &ConstantPool) { 298ab980499SAlex Lorenz unsigned ID = 0; 299ab980499SAlex Lorenz for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) { 300ab980499SAlex Lorenz // TODO: Serialize target specific constant pool entries. 301ab980499SAlex Lorenz if (Constant.isMachineConstantPoolEntry()) 302ab980499SAlex Lorenz llvm_unreachable("Can't print target specific constant pool entries yet"); 303ab980499SAlex Lorenz 304ab980499SAlex Lorenz yaml::MachineConstantPoolValue YamlConstant; 305ab980499SAlex Lorenz std::string Str; 306ab980499SAlex Lorenz raw_string_ostream StrOS(Str); 307ab980499SAlex Lorenz Constant.Val.ConstVal->printAsOperand(StrOS); 308ab980499SAlex Lorenz YamlConstant.ID = ID++; 309ab980499SAlex Lorenz YamlConstant.Value = StrOS.str(); 310ab980499SAlex Lorenz YamlConstant.Alignment = Constant.getAlignment(); 311ab980499SAlex Lorenz MF.Constants.push_back(YamlConstant); 312ab980499SAlex Lorenz } 313ab980499SAlex Lorenz } 314ab980499SAlex Lorenz 315900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 3166799e9b3SAlex Lorenz yaml::MachineJumpTable &YamlJTI, 3176799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI) { 3186799e9b3SAlex Lorenz YamlJTI.Kind = JTI.getEntryKind(); 3196799e9b3SAlex Lorenz unsigned ID = 0; 3206799e9b3SAlex Lorenz for (const auto &Table : JTI.getJumpTables()) { 3216799e9b3SAlex Lorenz std::string Str; 3226799e9b3SAlex Lorenz yaml::MachineJumpTable::Entry Entry; 3236799e9b3SAlex Lorenz Entry.ID = ID++; 3246799e9b3SAlex Lorenz for (const auto *MBB : Table.MBBs) { 3256799e9b3SAlex Lorenz raw_string_ostream StrOS(Str); 3267feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 3277feaf7c6SAlex Lorenz .printMBBReference(*MBB); 3286799e9b3SAlex Lorenz Entry.Blocks.push_back(StrOS.str()); 3296799e9b3SAlex Lorenz Str.clear(); 3306799e9b3SAlex Lorenz } 3316799e9b3SAlex Lorenz YamlJTI.Entries.push_back(Entry); 3326799e9b3SAlex Lorenz } 3336799e9b3SAlex Lorenz } 3346799e9b3SAlex Lorenz 3356799e9b3SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 336900b5cb2SAlex Lorenz yaml::MachineBasicBlock &YamlMBB, 3374f093bf1SAlex Lorenz const MachineBasicBlock &MBB) { 33833f0aef3SAlex Lorenz assert(MBB.getNumber() >= 0 && "Invalid MBB number"); 33933f0aef3SAlex Lorenz YamlMBB.ID = (unsigned)MBB.getNumber(); 340*8a1915b0SAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 341*8a1915b0SAlex Lorenz if (BB->hasName()) { 342*8a1915b0SAlex Lorenz YamlMBB.Name.Value = BB->getName(); 343*8a1915b0SAlex Lorenz } else { 344*8a1915b0SAlex Lorenz int Slot = MST.getLocalSlot(BB); 345*8a1915b0SAlex Lorenz if (Slot == -1) 346*8a1915b0SAlex Lorenz YamlMBB.IRBlock.Value = "<badref>"; 3474f093bf1SAlex Lorenz else 348*8a1915b0SAlex Lorenz YamlMBB.IRBlock.Value = (Twine("%ir-block.") + Twine(Slot)).str(); 349*8a1915b0SAlex Lorenz } 350*8a1915b0SAlex Lorenz } 3514f093bf1SAlex Lorenz YamlMBB.Alignment = MBB.getAlignment(); 3524f093bf1SAlex Lorenz YamlMBB.AddressTaken = MBB.hasAddressTaken(); 3534f093bf1SAlex Lorenz YamlMBB.IsLandingPad = MBB.isLandingPad(); 354eb5112bfSAlex Lorenz for (const auto *SuccMBB : MBB.successors()) { 355f09df00dSAlex Lorenz std::string Str; 356f09df00dSAlex Lorenz raw_string_ostream StrOS(Str); 3577feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 3587feaf7c6SAlex Lorenz .printMBBReference(*SuccMBB); 359f09df00dSAlex Lorenz YamlMBB.Successors.push_back(StrOS.str()); 360f09df00dSAlex Lorenz } 3619fab370dSAlex Lorenz // Print the live in registers. 3629fab370dSAlex Lorenz const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo(); 3639fab370dSAlex Lorenz assert(TRI && "Expected target register info"); 3649fab370dSAlex Lorenz for (auto I = MBB.livein_begin(), E = MBB.livein_end(); I != E; ++I) { 3659fab370dSAlex Lorenz std::string Str; 3669fab370dSAlex Lorenz raw_string_ostream StrOS(Str); 3679fab370dSAlex Lorenz printReg(*I, StrOS, TRI); 3689fab370dSAlex Lorenz YamlMBB.LiveIns.push_back(StrOS.str()); 3699fab370dSAlex Lorenz } 3708e0a1b48SAlex Lorenz // Print the machine instructions. 3718e0a1b48SAlex Lorenz YamlMBB.Instructions.reserve(MBB.size()); 3728e0a1b48SAlex Lorenz std::string Str; 3738e0a1b48SAlex Lorenz for (const auto &MI : MBB) { 3748e0a1b48SAlex Lorenz raw_string_ostream StrOS(Str); 3757feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping).print(MI); 3768e0a1b48SAlex Lorenz YamlMBB.Instructions.push_back(StrOS.str()); 3778e0a1b48SAlex Lorenz Str.clear(); 3788e0a1b48SAlex Lorenz } 3798e0a1b48SAlex Lorenz } 3808e0a1b48SAlex Lorenz 3818f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) { 3828f6f4285SAlex Lorenz const auto *TRI = MF.getSubtarget().getRegisterInfo(); 3838f6f4285SAlex Lorenz unsigned I = 0; 3848f6f4285SAlex Lorenz for (const uint32_t *Mask : TRI->getRegMasks()) 3858f6f4285SAlex Lorenz RegisterMaskIds.insert(std::make_pair(Mask, I++)); 3868f6f4285SAlex Lorenz } 3878f6f4285SAlex Lorenz 3888e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) { 3898e0a1b48SAlex Lorenz const auto &SubTarget = MI.getParent()->getParent()->getSubtarget(); 390f3db51deSAlex Lorenz const auto *TRI = SubTarget.getRegisterInfo(); 391f3db51deSAlex Lorenz assert(TRI && "Expected target register info"); 3928e0a1b48SAlex Lorenz const auto *TII = SubTarget.getInstrInfo(); 3938e0a1b48SAlex Lorenz assert(TII && "Expected target instruction info"); 394f4baeb51SAlex Lorenz if (MI.isCFIInstruction()) 395f4baeb51SAlex Lorenz assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction"); 3968e0a1b48SAlex Lorenz 397f3db51deSAlex Lorenz unsigned I = 0, E = MI.getNumOperands(); 398f3db51deSAlex Lorenz for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() && 399f3db51deSAlex Lorenz !MI.getOperand(I).isImplicit(); 400f3db51deSAlex Lorenz ++I) { 401f3db51deSAlex Lorenz if (I) 402f3db51deSAlex Lorenz OS << ", "; 403f3db51deSAlex Lorenz print(MI.getOperand(I), TRI); 404f3db51deSAlex Lorenz } 405f3db51deSAlex Lorenz 406f3db51deSAlex Lorenz if (I) 407f3db51deSAlex Lorenz OS << " = "; 408e5a44660SAlex Lorenz if (MI.getFlag(MachineInstr::FrameSetup)) 409e5a44660SAlex Lorenz OS << "frame-setup "; 4108e0a1b48SAlex Lorenz OS << TII->getName(MI.getOpcode()); 411e5a44660SAlex Lorenz // TODO: Print the bundling instruction flags, machine mem operands. 412f3db51deSAlex Lorenz if (I < E) 413f3db51deSAlex Lorenz OS << ' '; 414f3db51deSAlex Lorenz 415f3db51deSAlex Lorenz bool NeedComma = false; 416f3db51deSAlex Lorenz for (; I < E; ++I) { 417f3db51deSAlex Lorenz if (NeedComma) 418f3db51deSAlex Lorenz OS << ", "; 419f3db51deSAlex Lorenz print(MI.getOperand(I), TRI); 420f3db51deSAlex Lorenz NeedComma = true; 421f3db51deSAlex Lorenz } 42246d760d1SAlex Lorenz 42346d760d1SAlex Lorenz if (MI.getDebugLoc()) { 42446d760d1SAlex Lorenz if (NeedComma) 42546d760d1SAlex Lorenz OS << ','; 42646d760d1SAlex Lorenz OS << " debug-location "; 42746d760d1SAlex Lorenz MI.getDebugLoc()->printAsOperand(OS, MST); 42846d760d1SAlex Lorenz } 429f3db51deSAlex Lorenz } 430f3db51deSAlex Lorenz 4315d26fa83SAlex Lorenz void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) { 4325d26fa83SAlex Lorenz OS << "%bb." << MBB.getNumber(); 4335d26fa83SAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 4345d26fa83SAlex Lorenz if (BB->hasName()) 4355d26fa83SAlex Lorenz OS << '.' << BB->getName(); 4365d26fa83SAlex Lorenz } 4375d26fa83SAlex Lorenz } 4385d26fa83SAlex Lorenz 4397feaf7c6SAlex Lorenz void MIPrinter::printStackObjectReference(int FrameIndex) { 4407feaf7c6SAlex Lorenz auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex); 4417feaf7c6SAlex Lorenz assert(ObjectInfo != StackObjectOperandMapping.end() && 4427feaf7c6SAlex Lorenz "Invalid frame index"); 4437feaf7c6SAlex Lorenz const FrameIndexOperand &Operand = ObjectInfo->second; 4447feaf7c6SAlex Lorenz if (Operand.IsFixed) { 4457feaf7c6SAlex Lorenz OS << "%fixed-stack." << Operand.ID; 4467feaf7c6SAlex Lorenz return; 4477feaf7c6SAlex Lorenz } 4487feaf7c6SAlex Lorenz OS << "%stack." << Operand.ID; 4497feaf7c6SAlex Lorenz if (!Operand.Name.empty()) 4507feaf7c6SAlex Lorenz OS << '.' << Operand.Name; 4517feaf7c6SAlex Lorenz } 4527feaf7c6SAlex Lorenz 453f3db51deSAlex Lorenz void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { 454f3db51deSAlex Lorenz switch (Op.getType()) { 455f3db51deSAlex Lorenz case MachineOperand::MO_Register: 456cb268d46SAlex Lorenz // TODO: Print the other register flags. 457cb268d46SAlex Lorenz if (Op.isImplicit()) 458cb268d46SAlex Lorenz OS << (Op.isDef() ? "implicit-def " : "implicit "); 459cbbfd0b1SAlex Lorenz if (Op.isDead()) 460cbbfd0b1SAlex Lorenz OS << "dead "; 461495ad879SAlex Lorenz if (Op.isKill()) 462495ad879SAlex Lorenz OS << "killed "; 4634d026b89SAlex Lorenz if (Op.isUndef()) 4644d026b89SAlex Lorenz OS << "undef "; 465f3db51deSAlex Lorenz printReg(Op.getReg(), OS, TRI); 4662eacca86SAlex Lorenz // Print the sub register. 4672eacca86SAlex Lorenz if (Op.getSubReg() != 0) 4682eacca86SAlex Lorenz OS << ':' << TRI->getSubRegIndexName(Op.getSubReg()); 469f3db51deSAlex Lorenz break; 470240fc1e0SAlex Lorenz case MachineOperand::MO_Immediate: 471240fc1e0SAlex Lorenz OS << Op.getImm(); 472240fc1e0SAlex Lorenz break; 47333f0aef3SAlex Lorenz case MachineOperand::MO_MachineBasicBlock: 4745d26fa83SAlex Lorenz printMBBReference(*Op.getMBB()); 47533f0aef3SAlex Lorenz break; 4767feaf7c6SAlex Lorenz case MachineOperand::MO_FrameIndex: 4777feaf7c6SAlex Lorenz printStackObjectReference(Op.getIndex()); 4787feaf7c6SAlex Lorenz break; 479ab980499SAlex Lorenz case MachineOperand::MO_ConstantPoolIndex: 480ab980499SAlex Lorenz OS << "%const." << Op.getIndex(); 481ab980499SAlex Lorenz // TODO: Print offset and target flags. 482ab980499SAlex Lorenz break; 48331d70683SAlex Lorenz case MachineOperand::MO_JumpTableIndex: 48431d70683SAlex Lorenz OS << "%jump-table." << Op.getIndex(); 48531d70683SAlex Lorenz // TODO: Print target flags. 48631d70683SAlex Lorenz break; 4876ede3744SAlex Lorenz case MachineOperand::MO_ExternalSymbol: 4886ede3744SAlex Lorenz OS << '$'; 4896ede3744SAlex Lorenz printLLVMNameWithoutPrefix(OS, Op.getSymbolName()); 4906ede3744SAlex Lorenz // TODO: Print the target flags. 4916ede3744SAlex Lorenz break; 4925d6108e4SAlex Lorenz case MachineOperand::MO_GlobalAddress: 493900b5cb2SAlex Lorenz Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 4945d6108e4SAlex Lorenz // TODO: Print offset and target flags. 4955d6108e4SAlex Lorenz break; 4968f6f4285SAlex Lorenz case MachineOperand::MO_RegisterMask: { 4978f6f4285SAlex Lorenz auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); 4988f6f4285SAlex Lorenz if (RegMaskInfo != RegisterMaskIds.end()) 4998f6f4285SAlex Lorenz OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); 5008f6f4285SAlex Lorenz else 5018f6f4285SAlex Lorenz llvm_unreachable("Can't print this machine register mask yet."); 5028f6f4285SAlex Lorenz break; 5038f6f4285SAlex Lorenz } 50435e44469SAlex Lorenz case MachineOperand::MO_Metadata: 50535e44469SAlex Lorenz Op.getMetadata()->printAsOperand(OS, MST); 50635e44469SAlex Lorenz break; 507f4baeb51SAlex Lorenz case MachineOperand::MO_CFIIndex: { 508f4baeb51SAlex Lorenz const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI(); 5098cfc6867SAlex Lorenz print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI); 510f4baeb51SAlex Lorenz break; 511f4baeb51SAlex Lorenz } 512f3db51deSAlex Lorenz default: 513f3db51deSAlex Lorenz // TODO: Print the other machine operands. 514f3db51deSAlex Lorenz llvm_unreachable("Can't print this machine operand at the moment"); 515f3db51deSAlex Lorenz } 5164f093bf1SAlex Lorenz } 5174f093bf1SAlex Lorenz 5188cfc6867SAlex Lorenz static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS, 5198cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 5208cfc6867SAlex Lorenz int Reg = TRI->getLLVMRegNum(DwarfReg, true); 5218cfc6867SAlex Lorenz if (Reg == -1) { 5228cfc6867SAlex Lorenz OS << "<badreg>"; 5238cfc6867SAlex Lorenz return; 5248cfc6867SAlex Lorenz } 5258cfc6867SAlex Lorenz printReg(Reg, OS, TRI); 5268cfc6867SAlex Lorenz } 5278cfc6867SAlex Lorenz 5288cfc6867SAlex Lorenz void MIPrinter::print(const MCCFIInstruction &CFI, 5298cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 530f4baeb51SAlex Lorenz switch (CFI.getOperation()) { 5318cfc6867SAlex Lorenz case MCCFIInstruction::OpOffset: 5328cfc6867SAlex Lorenz OS << ".cfi_offset "; 5338cfc6867SAlex Lorenz if (CFI.getLabel()) 5348cfc6867SAlex Lorenz OS << "<mcsymbol> "; 5358cfc6867SAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 5368cfc6867SAlex Lorenz OS << ", " << CFI.getOffset(); 5378cfc6867SAlex Lorenz break; 5385b0d5f6fSAlex Lorenz case MCCFIInstruction::OpDefCfaRegister: 5395b0d5f6fSAlex Lorenz OS << ".cfi_def_cfa_register "; 5405b0d5f6fSAlex Lorenz if (CFI.getLabel()) 5415b0d5f6fSAlex Lorenz OS << "<mcsymbol> "; 5425b0d5f6fSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 5435b0d5f6fSAlex Lorenz break; 544f4baeb51SAlex Lorenz case MCCFIInstruction::OpDefCfaOffset: 545f4baeb51SAlex Lorenz OS << ".cfi_def_cfa_offset "; 546f4baeb51SAlex Lorenz if (CFI.getLabel()) 547f4baeb51SAlex Lorenz OS << "<mcsymbol> "; 548f4baeb51SAlex Lorenz OS << CFI.getOffset(); 549f4baeb51SAlex Lorenz break; 550f4baeb51SAlex Lorenz default: 551f4baeb51SAlex Lorenz // TODO: Print the other CFI Operations. 552f4baeb51SAlex Lorenz OS << "<unserializable cfi operation>"; 553f4baeb51SAlex Lorenz break; 554f4baeb51SAlex Lorenz } 555f4baeb51SAlex Lorenz } 556f4baeb51SAlex Lorenz 557345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) { 558345c1449SAlex Lorenz yaml::Output Out(OS); 559345c1449SAlex Lorenz Out << const_cast<Module &>(M); 560345c1449SAlex Lorenz } 561345c1449SAlex Lorenz 562345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) { 563345c1449SAlex Lorenz MIRPrinter Printer(OS); 564345c1449SAlex Lorenz Printer.print(MF); 565345c1449SAlex Lorenz } 566