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" 204af7e610SAlex Lorenz #include "llvm/CodeGen/MachineMemOperand.h" 21f4baeb51SAlex Lorenz #include "llvm/CodeGen/MachineModuleInfo.h" 2254565cf0SAlex Lorenz #include "llvm/CodeGen/MachineRegisterInfo.h" 23345c1449SAlex Lorenz #include "llvm/CodeGen/MIRYamlMapping.h" 244f093bf1SAlex Lorenz #include "llvm/IR/BasicBlock.h" 25deb53490SAlex Lorenz #include "llvm/IR/Constants.h" 2637643a04SAlex Lorenz #include "llvm/IR/Instructions.h" 276ede3744SAlex Lorenz #include "llvm/IR/IRPrintingPasses.h" 28345c1449SAlex Lorenz #include "llvm/IR/Module.h" 29900b5cb2SAlex Lorenz #include "llvm/IR/ModuleSlotTracker.h" 30345c1449SAlex Lorenz #include "llvm/Support/MemoryBuffer.h" 31345c1449SAlex Lorenz #include "llvm/Support/raw_ostream.h" 32345c1449SAlex Lorenz #include "llvm/Support/YAMLTraits.h" 338e0a1b48SAlex Lorenz #include "llvm/Target/TargetInstrInfo.h" 348e0a1b48SAlex Lorenz #include "llvm/Target/TargetSubtargetInfo.h" 35345c1449SAlex Lorenz 36345c1449SAlex Lorenz using namespace llvm; 37345c1449SAlex Lorenz 38345c1449SAlex Lorenz namespace { 39345c1449SAlex Lorenz 407feaf7c6SAlex Lorenz /// This structure describes how to print out stack object references. 417feaf7c6SAlex Lorenz struct FrameIndexOperand { 427feaf7c6SAlex Lorenz std::string Name; 437feaf7c6SAlex Lorenz unsigned ID; 447feaf7c6SAlex Lorenz bool IsFixed; 457feaf7c6SAlex Lorenz 467feaf7c6SAlex Lorenz FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed) 477feaf7c6SAlex Lorenz : Name(Name.str()), ID(ID), IsFixed(IsFixed) {} 487feaf7c6SAlex Lorenz 497feaf7c6SAlex Lorenz /// Return an ordinary stack object reference. 507feaf7c6SAlex Lorenz static FrameIndexOperand create(StringRef Name, unsigned ID) { 517feaf7c6SAlex Lorenz return FrameIndexOperand(Name, ID, /*IsFixed=*/false); 527feaf7c6SAlex Lorenz } 537feaf7c6SAlex Lorenz 547feaf7c6SAlex Lorenz /// Return a fixed stack object reference. 557feaf7c6SAlex Lorenz static FrameIndexOperand createFixed(unsigned ID) { 567feaf7c6SAlex Lorenz return FrameIndexOperand("", ID, /*IsFixed=*/true); 577feaf7c6SAlex Lorenz } 587feaf7c6SAlex Lorenz }; 597feaf7c6SAlex Lorenz 60618b283cSAlex Lorenz } // end anonymous namespace 61618b283cSAlex Lorenz 62618b283cSAlex Lorenz namespace llvm { 63618b283cSAlex Lorenz 64345c1449SAlex Lorenz /// This class prints out the machine functions using the MIR serialization 65345c1449SAlex Lorenz /// format. 66345c1449SAlex Lorenz class MIRPrinter { 67345c1449SAlex Lorenz raw_ostream &OS; 688f6f4285SAlex Lorenz DenseMap<const uint32_t *, unsigned> RegisterMaskIds; 697feaf7c6SAlex Lorenz /// Maps from stack object indices to operand indices which will be used when 707feaf7c6SAlex Lorenz /// printing frame index machine operands. 717feaf7c6SAlex Lorenz DenseMap<int, FrameIndexOperand> StackObjectOperandMapping; 72345c1449SAlex Lorenz 73345c1449SAlex Lorenz public: 74345c1449SAlex Lorenz MIRPrinter(raw_ostream &OS) : OS(OS) {} 75345c1449SAlex Lorenz 76345c1449SAlex Lorenz void print(const MachineFunction &MF); 774f093bf1SAlex Lorenz 7828148ba8SAlex Lorenz void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo, 7928148ba8SAlex Lorenz const TargetRegisterInfo *TRI); 80a6f9a37dSAlex Lorenz void convert(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI, 81a6f9a37dSAlex Lorenz const MachineFrameInfo &MFI); 82ab980499SAlex Lorenz void convert(yaml::MachineFunction &MF, 83ab980499SAlex Lorenz const MachineConstantPool &ConstantPool); 846799e9b3SAlex Lorenz void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI, 856799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI); 86900b5cb2SAlex Lorenz void convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB, 875d6108e4SAlex Lorenz const MachineBasicBlock &MBB); 88f6bc8667SAlex Lorenz void convertStackObjects(yaml::MachineFunction &MF, 891bb48de1SAlex Lorenz const MachineFrameInfo &MFI, 901bb48de1SAlex Lorenz const TargetRegisterInfo *TRI); 918f6f4285SAlex Lorenz 928f6f4285SAlex Lorenz private: 938f6f4285SAlex Lorenz void initRegisterMaskIds(const MachineFunction &MF); 94345c1449SAlex Lorenz }; 95345c1449SAlex Lorenz 96618b283cSAlex Lorenz } // end namespace llvm 97618b283cSAlex Lorenz 98618b283cSAlex Lorenz namespace { 99618b283cSAlex 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 1158e0a1b48SAlex Lorenz void print(const MachineInstr &MI); 1165d26fa83SAlex Lorenz void printMBBReference(const MachineBasicBlock &MBB); 117deb53490SAlex Lorenz void printIRBlockReference(const BasicBlock &BB); 1184af7e610SAlex Lorenz void printIRValueReference(const Value &V); 1197feaf7c6SAlex Lorenz void printStackObjectReference(int FrameIndex); 1205672a893SAlex Lorenz void printOffset(int64_t Offset); 12149873a83SAlex Lorenz void printTargetFlags(const MachineOperand &Op); 122f3db51deSAlex Lorenz void print(const MachineOperand &Op, const TargetRegisterInfo *TRI); 1234af7e610SAlex Lorenz void print(const MachineMemOperand &Op); 124f4baeb51SAlex Lorenz 1258cfc6867SAlex Lorenz void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI); 1268e0a1b48SAlex Lorenz }; 1278e0a1b48SAlex Lorenz 128345c1449SAlex Lorenz } // end anonymous namespace 129345c1449SAlex Lorenz 130345c1449SAlex Lorenz namespace llvm { 131345c1449SAlex Lorenz namespace yaml { 132345c1449SAlex Lorenz 133345c1449SAlex Lorenz /// This struct serializes the LLVM IR module. 134345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> { 135345c1449SAlex Lorenz static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) { 136345c1449SAlex Lorenz Mod.print(OS, nullptr); 137345c1449SAlex Lorenz } 138345c1449SAlex Lorenz static StringRef input(StringRef Str, void *Ctxt, Module &Mod) { 139345c1449SAlex Lorenz llvm_unreachable("LLVM Module is supposed to be parsed separately"); 140345c1449SAlex Lorenz return ""; 141345c1449SAlex Lorenz } 142345c1449SAlex Lorenz }; 143345c1449SAlex Lorenz 144345c1449SAlex Lorenz } // end namespace yaml 145345c1449SAlex Lorenz } // end namespace llvm 146345c1449SAlex Lorenz 14715a00a85SAlex Lorenz static void printReg(unsigned Reg, raw_ostream &OS, 14815a00a85SAlex Lorenz const TargetRegisterInfo *TRI) { 14915a00a85SAlex Lorenz // TODO: Print Stack Slots. 15015a00a85SAlex Lorenz if (!Reg) 15115a00a85SAlex Lorenz OS << '_'; 15215a00a85SAlex Lorenz else if (TargetRegisterInfo::isVirtualRegister(Reg)) 15315a00a85SAlex Lorenz OS << '%' << TargetRegisterInfo::virtReg2Index(Reg); 15415a00a85SAlex Lorenz else if (Reg < TRI->getNumRegs()) 15515a00a85SAlex Lorenz OS << '%' << StringRef(TRI->getName(Reg)).lower(); 15615a00a85SAlex Lorenz else 15715a00a85SAlex Lorenz llvm_unreachable("Can't print this kind of register yet"); 15815a00a85SAlex Lorenz } 15915a00a85SAlex Lorenz 160ab4cbcfdSAlex Lorenz static void printReg(unsigned Reg, yaml::StringValue &Dest, 161ab4cbcfdSAlex Lorenz const TargetRegisterInfo *TRI) { 162ab4cbcfdSAlex Lorenz raw_string_ostream OS(Dest.Value); 163ab4cbcfdSAlex Lorenz printReg(Reg, OS, TRI); 164ab4cbcfdSAlex Lorenz } 165ab4cbcfdSAlex Lorenz 166345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) { 1678f6f4285SAlex Lorenz initRegisterMaskIds(MF); 1688f6f4285SAlex Lorenz 169345c1449SAlex Lorenz yaml::MachineFunction YamlMF; 170345c1449SAlex Lorenz YamlMF.Name = MF.getName(); 1715b5f9753SAlex Lorenz YamlMF.Alignment = MF.getAlignment(); 1725b5f9753SAlex Lorenz YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice(); 1735b5f9753SAlex Lorenz YamlMF.HasInlineAsm = MF.hasInlineAsm(); 17428148ba8SAlex Lorenz convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo()); 175a6f9a37dSAlex Lorenz ModuleSlotTracker MST(MF.getFunction()->getParent()); 176a6f9a37dSAlex Lorenz MST.incorporateFunction(*MF.getFunction()); 177a6f9a37dSAlex Lorenz convert(MST, YamlMF.FrameInfo, *MF.getFrameInfo()); 1781bb48de1SAlex Lorenz convertStackObjects(YamlMF, *MF.getFrameInfo(), 1791bb48de1SAlex Lorenz MF.getSubtarget().getRegisterInfo()); 180ab980499SAlex Lorenz if (const auto *ConstantPool = MF.getConstantPool()) 181ab980499SAlex Lorenz convert(YamlMF, *ConstantPool); 1826799e9b3SAlex Lorenz if (const auto *JumpTableInfo = MF.getJumpTableInfo()) 1836799e9b3SAlex Lorenz convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo); 1844f093bf1SAlex Lorenz for (const auto &MBB : MF) { 1854f093bf1SAlex Lorenz yaml::MachineBasicBlock YamlMBB; 186900b5cb2SAlex Lorenz convert(MST, YamlMBB, MBB); 1874f093bf1SAlex Lorenz YamlMF.BasicBlocks.push_back(YamlMBB); 1884f093bf1SAlex Lorenz } 189345c1449SAlex Lorenz yaml::Output Out(OS); 190345c1449SAlex Lorenz Out << YamlMF; 191345c1449SAlex Lorenz } 192345c1449SAlex Lorenz 19354565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 19428148ba8SAlex Lorenz const MachineRegisterInfo &RegInfo, 19528148ba8SAlex Lorenz const TargetRegisterInfo *TRI) { 19654565cf0SAlex Lorenz MF.IsSSA = RegInfo.isSSA(); 19754565cf0SAlex Lorenz MF.TracksRegLiveness = RegInfo.tracksLiveness(); 19854565cf0SAlex Lorenz MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled(); 19928148ba8SAlex Lorenz 20028148ba8SAlex Lorenz // Print the virtual register definitions. 20128148ba8SAlex Lorenz for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) { 20228148ba8SAlex Lorenz unsigned Reg = TargetRegisterInfo::index2VirtReg(I); 20328148ba8SAlex Lorenz yaml::VirtualRegisterDefinition VReg; 20428148ba8SAlex Lorenz VReg.ID = I; 20528148ba8SAlex Lorenz VReg.Class = 20628148ba8SAlex Lorenz StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower(); 207ab4cbcfdSAlex Lorenz unsigned PreferredReg = RegInfo.getSimpleHint(Reg); 208ab4cbcfdSAlex Lorenz if (PreferredReg) 209ab4cbcfdSAlex Lorenz printReg(PreferredReg, VReg.PreferredRegister, TRI); 21028148ba8SAlex Lorenz MF.VirtualRegisters.push_back(VReg); 21128148ba8SAlex Lorenz } 21212045a4bSAlex Lorenz 21312045a4bSAlex Lorenz // Print the live ins. 21412045a4bSAlex Lorenz for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) { 21512045a4bSAlex Lorenz yaml::MachineFunctionLiveIn LiveIn; 21612045a4bSAlex Lorenz printReg(I->first, LiveIn.Register, TRI); 21712045a4bSAlex Lorenz if (I->second) 21812045a4bSAlex Lorenz printReg(I->second, LiveIn.VirtualRegister, TRI); 21912045a4bSAlex Lorenz MF.LiveIns.push_back(LiveIn); 22012045a4bSAlex Lorenz } 221c4838087SAlex Lorenz // The used physical register mask is printed as an inverted callee saved 222c4838087SAlex Lorenz // register mask. 223c4838087SAlex Lorenz const BitVector &UsedPhysRegMask = RegInfo.getUsedPhysRegsMask(); 224c4838087SAlex Lorenz if (UsedPhysRegMask.none()) 225c4838087SAlex Lorenz return; 226c4838087SAlex Lorenz std::vector<yaml::FlowStringValue> CalleeSavedRegisters; 227c4838087SAlex Lorenz for (unsigned I = 0, E = UsedPhysRegMask.size(); I != E; ++I) { 228c4838087SAlex Lorenz if (!UsedPhysRegMask[I]) { 229c4838087SAlex Lorenz yaml::FlowStringValue Reg; 230c4838087SAlex Lorenz printReg(I, Reg, TRI); 231c4838087SAlex Lorenz CalleeSavedRegisters.push_back(Reg); 232c4838087SAlex Lorenz } 233c4838087SAlex Lorenz } 234c4838087SAlex Lorenz MF.CalleeSavedRegisters = CalleeSavedRegisters; 23554565cf0SAlex Lorenz } 23654565cf0SAlex Lorenz 237a6f9a37dSAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 238a6f9a37dSAlex Lorenz yaml::MachineFrameInfo &YamlMFI, 23960541c1dSAlex Lorenz const MachineFrameInfo &MFI) { 24060541c1dSAlex Lorenz YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken(); 24160541c1dSAlex Lorenz YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken(); 24260541c1dSAlex Lorenz YamlMFI.HasStackMap = MFI.hasStackMap(); 24360541c1dSAlex Lorenz YamlMFI.HasPatchPoint = MFI.hasPatchPoint(); 24460541c1dSAlex Lorenz YamlMFI.StackSize = MFI.getStackSize(); 24560541c1dSAlex Lorenz YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment(); 24660541c1dSAlex Lorenz YamlMFI.MaxAlignment = MFI.getMaxAlignment(); 24760541c1dSAlex Lorenz YamlMFI.AdjustsStack = MFI.adjustsStack(); 24860541c1dSAlex Lorenz YamlMFI.HasCalls = MFI.hasCalls(); 24960541c1dSAlex Lorenz YamlMFI.MaxCallFrameSize = MFI.getMaxCallFrameSize(); 25060541c1dSAlex Lorenz YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment(); 25160541c1dSAlex Lorenz YamlMFI.HasVAStart = MFI.hasVAStart(); 25260541c1dSAlex Lorenz YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc(); 253a6f9a37dSAlex Lorenz if (MFI.getSavePoint()) { 254a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.SavePoint.Value); 255a6f9a37dSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 256a6f9a37dSAlex Lorenz .printMBBReference(*MFI.getSavePoint()); 257a6f9a37dSAlex Lorenz } 258a6f9a37dSAlex Lorenz if (MFI.getRestorePoint()) { 259a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.RestorePoint.Value); 260a6f9a37dSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 261a6f9a37dSAlex Lorenz .printMBBReference(*MFI.getRestorePoint()); 262a6f9a37dSAlex Lorenz } 26360541c1dSAlex Lorenz } 26460541c1dSAlex Lorenz 265f6bc8667SAlex Lorenz void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF, 2661bb48de1SAlex Lorenz const MachineFrameInfo &MFI, 2671bb48de1SAlex Lorenz const TargetRegisterInfo *TRI) { 268de491f05SAlex Lorenz // Process fixed stack objects. 269f6bc8667SAlex Lorenz unsigned ID = 0; 270de491f05SAlex Lorenz for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) { 271de491f05SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 272de491f05SAlex Lorenz continue; 273de491f05SAlex Lorenz 274de491f05SAlex Lorenz yaml::FixedMachineStackObject YamlObject; 2757feaf7c6SAlex Lorenz YamlObject.ID = ID; 276de491f05SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 277de491f05SAlex Lorenz ? yaml::FixedMachineStackObject::SpillSlot 278de491f05SAlex Lorenz : yaml::FixedMachineStackObject::DefaultType; 279de491f05SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 280de491f05SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 281de491f05SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 282de491f05SAlex Lorenz YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I); 283de491f05SAlex Lorenz YamlObject.IsAliased = MFI.isAliasedObjectIndex(I); 284de491f05SAlex Lorenz MF.FixedStackObjects.push_back(YamlObject); 2857feaf7c6SAlex Lorenz StackObjectOperandMapping.insert( 2867feaf7c6SAlex Lorenz std::make_pair(I, FrameIndexOperand::createFixed(ID++))); 287de491f05SAlex Lorenz } 288de491f05SAlex Lorenz 289de491f05SAlex Lorenz // Process ordinary stack objects. 290de491f05SAlex Lorenz ID = 0; 291f6bc8667SAlex Lorenz for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) { 292f6bc8667SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 293f6bc8667SAlex Lorenz continue; 294f6bc8667SAlex Lorenz 295f6bc8667SAlex Lorenz yaml::MachineStackObject YamlObject; 2967feaf7c6SAlex Lorenz YamlObject.ID = ID; 29737643a04SAlex Lorenz if (const auto *Alloca = MFI.getObjectAllocation(I)) 29837643a04SAlex Lorenz YamlObject.Name.Value = 29937643a04SAlex Lorenz Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>"; 300f6bc8667SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 301f6bc8667SAlex Lorenz ? yaml::MachineStackObject::SpillSlot 302418f3ec1SAlex Lorenz : MFI.isVariableSizedObjectIndex(I) 303418f3ec1SAlex Lorenz ? yaml::MachineStackObject::VariableSized 304f6bc8667SAlex Lorenz : yaml::MachineStackObject::DefaultType; 305f6bc8667SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 306f6bc8667SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 307f6bc8667SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 308f6bc8667SAlex Lorenz 309f6bc8667SAlex Lorenz MF.StackObjects.push_back(YamlObject); 3107feaf7c6SAlex Lorenz StackObjectOperandMapping.insert(std::make_pair( 3117feaf7c6SAlex Lorenz I, FrameIndexOperand::create(YamlObject.Name.Value, ID++))); 312f6bc8667SAlex Lorenz } 3131bb48de1SAlex Lorenz 3141bb48de1SAlex Lorenz for (const auto &CSInfo : MFI.getCalleeSavedInfo()) { 3151bb48de1SAlex Lorenz yaml::StringValue Reg; 3161bb48de1SAlex Lorenz printReg(CSInfo.getReg(), Reg, TRI); 3171bb48de1SAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx()); 3181bb48de1SAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 3191bb48de1SAlex Lorenz "Invalid stack object index"); 3201bb48de1SAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 3211bb48de1SAlex Lorenz if (StackObject.IsFixed) 3221bb48de1SAlex Lorenz MF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg; 3231bb48de1SAlex Lorenz else 3241bb48de1SAlex Lorenz MF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg; 3251bb48de1SAlex Lorenz } 326f6bc8667SAlex Lorenz } 327f6bc8667SAlex Lorenz 328ab980499SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 329ab980499SAlex Lorenz const MachineConstantPool &ConstantPool) { 330ab980499SAlex Lorenz unsigned ID = 0; 331ab980499SAlex Lorenz for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) { 332ab980499SAlex Lorenz // TODO: Serialize target specific constant pool entries. 333ab980499SAlex Lorenz if (Constant.isMachineConstantPoolEntry()) 334ab980499SAlex Lorenz llvm_unreachable("Can't print target specific constant pool entries yet"); 335ab980499SAlex Lorenz 336ab980499SAlex Lorenz yaml::MachineConstantPoolValue YamlConstant; 337ab980499SAlex Lorenz std::string Str; 338ab980499SAlex Lorenz raw_string_ostream StrOS(Str); 339ab980499SAlex Lorenz Constant.Val.ConstVal->printAsOperand(StrOS); 340ab980499SAlex Lorenz YamlConstant.ID = ID++; 341ab980499SAlex Lorenz YamlConstant.Value = StrOS.str(); 342ab980499SAlex Lorenz YamlConstant.Alignment = Constant.getAlignment(); 343ab980499SAlex Lorenz MF.Constants.push_back(YamlConstant); 344ab980499SAlex Lorenz } 345ab980499SAlex Lorenz } 346ab980499SAlex Lorenz 347900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 3486799e9b3SAlex Lorenz yaml::MachineJumpTable &YamlJTI, 3496799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI) { 3506799e9b3SAlex Lorenz YamlJTI.Kind = JTI.getEntryKind(); 3516799e9b3SAlex Lorenz unsigned ID = 0; 3526799e9b3SAlex Lorenz for (const auto &Table : JTI.getJumpTables()) { 3536799e9b3SAlex Lorenz std::string Str; 3546799e9b3SAlex Lorenz yaml::MachineJumpTable::Entry Entry; 3556799e9b3SAlex Lorenz Entry.ID = ID++; 3566799e9b3SAlex Lorenz for (const auto *MBB : Table.MBBs) { 3576799e9b3SAlex Lorenz raw_string_ostream StrOS(Str); 3587feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 3597feaf7c6SAlex Lorenz .printMBBReference(*MBB); 3606799e9b3SAlex Lorenz Entry.Blocks.push_back(StrOS.str()); 3616799e9b3SAlex Lorenz Str.clear(); 3626799e9b3SAlex Lorenz } 3636799e9b3SAlex Lorenz YamlJTI.Entries.push_back(Entry); 3646799e9b3SAlex Lorenz } 3656799e9b3SAlex Lorenz } 3666799e9b3SAlex Lorenz 3676799e9b3SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 368900b5cb2SAlex Lorenz yaml::MachineBasicBlock &YamlMBB, 3694f093bf1SAlex Lorenz const MachineBasicBlock &MBB) { 37033f0aef3SAlex Lorenz assert(MBB.getNumber() >= 0 && "Invalid MBB number"); 37133f0aef3SAlex Lorenz YamlMBB.ID = (unsigned)MBB.getNumber(); 3728a1915b0SAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 3738a1915b0SAlex Lorenz if (BB->hasName()) { 3748a1915b0SAlex Lorenz YamlMBB.Name.Value = BB->getName(); 3758a1915b0SAlex Lorenz } else { 3768a1915b0SAlex Lorenz int Slot = MST.getLocalSlot(BB); 3778a1915b0SAlex Lorenz if (Slot == -1) 3788a1915b0SAlex Lorenz YamlMBB.IRBlock.Value = "<badref>"; 3794f093bf1SAlex Lorenz else 3808a1915b0SAlex Lorenz YamlMBB.IRBlock.Value = (Twine("%ir-block.") + Twine(Slot)).str(); 3818a1915b0SAlex Lorenz } 3828a1915b0SAlex Lorenz } 3834f093bf1SAlex Lorenz YamlMBB.Alignment = MBB.getAlignment(); 3844f093bf1SAlex Lorenz YamlMBB.AddressTaken = MBB.hasAddressTaken(); 3854f093bf1SAlex Lorenz YamlMBB.IsLandingPad = MBB.isLandingPad(); 386eb5112bfSAlex Lorenz for (const auto *SuccMBB : MBB.successors()) { 387f09df00dSAlex Lorenz std::string Str; 388f09df00dSAlex Lorenz raw_string_ostream StrOS(Str); 3897feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 3907feaf7c6SAlex Lorenz .printMBBReference(*SuccMBB); 391f09df00dSAlex Lorenz YamlMBB.Successors.push_back(StrOS.str()); 392f09df00dSAlex Lorenz } 393618b283cSAlex Lorenz if (MBB.hasSuccessorWeights()) { 394618b283cSAlex Lorenz for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) 395618b283cSAlex Lorenz YamlMBB.SuccessorWeights.push_back( 396618b283cSAlex Lorenz yaml::UnsignedValue(MBB.getSuccWeight(I))); 397618b283cSAlex Lorenz } 3989fab370dSAlex Lorenz // Print the live in registers. 3999fab370dSAlex Lorenz const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo(); 4009fab370dSAlex Lorenz assert(TRI && "Expected target register info"); 4019fab370dSAlex Lorenz for (auto I = MBB.livein_begin(), E = MBB.livein_end(); I != E; ++I) { 4029fab370dSAlex Lorenz std::string Str; 4039fab370dSAlex Lorenz raw_string_ostream StrOS(Str); 4049fab370dSAlex Lorenz printReg(*I, StrOS, TRI); 4059fab370dSAlex Lorenz YamlMBB.LiveIns.push_back(StrOS.str()); 4069fab370dSAlex Lorenz } 4078e0a1b48SAlex Lorenz // Print the machine instructions. 4088e0a1b48SAlex Lorenz YamlMBB.Instructions.reserve(MBB.size()); 4098e0a1b48SAlex Lorenz std::string Str; 4108e0a1b48SAlex Lorenz for (const auto &MI : MBB) { 4118e0a1b48SAlex Lorenz raw_string_ostream StrOS(Str); 4127feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping).print(MI); 4138e0a1b48SAlex Lorenz YamlMBB.Instructions.push_back(StrOS.str()); 4148e0a1b48SAlex Lorenz Str.clear(); 4158e0a1b48SAlex Lorenz } 4168e0a1b48SAlex Lorenz } 4178e0a1b48SAlex Lorenz 4188f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) { 4198f6f4285SAlex Lorenz const auto *TRI = MF.getSubtarget().getRegisterInfo(); 4208f6f4285SAlex Lorenz unsigned I = 0; 4218f6f4285SAlex Lorenz for (const uint32_t *Mask : TRI->getRegMasks()) 4228f6f4285SAlex Lorenz RegisterMaskIds.insert(std::make_pair(Mask, I++)); 4238f6f4285SAlex Lorenz } 4248f6f4285SAlex Lorenz 4258e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) { 4268e0a1b48SAlex Lorenz const auto &SubTarget = MI.getParent()->getParent()->getSubtarget(); 427f3db51deSAlex Lorenz const auto *TRI = SubTarget.getRegisterInfo(); 428f3db51deSAlex Lorenz assert(TRI && "Expected target register info"); 4298e0a1b48SAlex Lorenz const auto *TII = SubTarget.getInstrInfo(); 4308e0a1b48SAlex Lorenz assert(TII && "Expected target instruction info"); 431f4baeb51SAlex Lorenz if (MI.isCFIInstruction()) 432f4baeb51SAlex Lorenz assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction"); 4338e0a1b48SAlex Lorenz 434f3db51deSAlex Lorenz unsigned I = 0, E = MI.getNumOperands(); 435f3db51deSAlex Lorenz for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() && 436f3db51deSAlex Lorenz !MI.getOperand(I).isImplicit(); 437f3db51deSAlex Lorenz ++I) { 438f3db51deSAlex Lorenz if (I) 439f3db51deSAlex Lorenz OS << ", "; 440f3db51deSAlex Lorenz print(MI.getOperand(I), TRI); 441f3db51deSAlex Lorenz } 442f3db51deSAlex Lorenz 443f3db51deSAlex Lorenz if (I) 444f3db51deSAlex Lorenz OS << " = "; 445e5a44660SAlex Lorenz if (MI.getFlag(MachineInstr::FrameSetup)) 446e5a44660SAlex Lorenz OS << "frame-setup "; 4478e0a1b48SAlex Lorenz OS << TII->getName(MI.getOpcode()); 4484af7e610SAlex Lorenz // TODO: Print the bundling instruction flags. 449f3db51deSAlex Lorenz if (I < E) 450f3db51deSAlex Lorenz OS << ' '; 451f3db51deSAlex Lorenz 452f3db51deSAlex Lorenz bool NeedComma = false; 453f3db51deSAlex Lorenz for (; I < E; ++I) { 454f3db51deSAlex Lorenz if (NeedComma) 455f3db51deSAlex Lorenz OS << ", "; 456f3db51deSAlex Lorenz print(MI.getOperand(I), TRI); 457f3db51deSAlex Lorenz NeedComma = true; 458f3db51deSAlex Lorenz } 45946d760d1SAlex Lorenz 46046d760d1SAlex Lorenz if (MI.getDebugLoc()) { 46146d760d1SAlex Lorenz if (NeedComma) 46246d760d1SAlex Lorenz OS << ','; 46346d760d1SAlex Lorenz OS << " debug-location "; 46446d760d1SAlex Lorenz MI.getDebugLoc()->printAsOperand(OS, MST); 46546d760d1SAlex Lorenz } 4664af7e610SAlex Lorenz 4674af7e610SAlex Lorenz if (!MI.memoperands_empty()) { 4684af7e610SAlex Lorenz OS << " :: "; 4694af7e610SAlex Lorenz bool NeedComma = false; 4704af7e610SAlex Lorenz for (const auto *Op : MI.memoperands()) { 4714af7e610SAlex Lorenz if (NeedComma) 4724af7e610SAlex Lorenz OS << ", "; 4734af7e610SAlex Lorenz print(*Op); 4744af7e610SAlex Lorenz NeedComma = true; 4754af7e610SAlex Lorenz } 4764af7e610SAlex Lorenz } 477f3db51deSAlex Lorenz } 478f3db51deSAlex Lorenz 4795d26fa83SAlex Lorenz void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) { 4805d26fa83SAlex Lorenz OS << "%bb." << MBB.getNumber(); 4815d26fa83SAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 4825d26fa83SAlex Lorenz if (BB->hasName()) 4835d26fa83SAlex Lorenz OS << '.' << BB->getName(); 4845d26fa83SAlex Lorenz } 4855d26fa83SAlex Lorenz } 4865d26fa83SAlex Lorenz 487deb53490SAlex Lorenz void MIPrinter::printIRBlockReference(const BasicBlock &BB) { 488deb53490SAlex Lorenz OS << "%ir-block."; 489deb53490SAlex Lorenz if (BB.hasName()) { 490deb53490SAlex Lorenz printLLVMNameWithoutPrefix(OS, BB.getName()); 491deb53490SAlex Lorenz return; 492deb53490SAlex Lorenz } 493cba8c5feSAlex Lorenz const Function *F = BB.getParent(); 494cba8c5feSAlex Lorenz int Slot; 495cba8c5feSAlex Lorenz if (F == MST.getCurrentFunction()) { 496cba8c5feSAlex Lorenz Slot = MST.getLocalSlot(&BB); 497cba8c5feSAlex Lorenz } else { 498cba8c5feSAlex Lorenz ModuleSlotTracker CustomMST(F->getParent(), 499cba8c5feSAlex Lorenz /*ShouldInitializeAllMetadata=*/false); 500cba8c5feSAlex Lorenz CustomMST.incorporateFunction(*F); 501cba8c5feSAlex Lorenz Slot = CustomMST.getLocalSlot(&BB); 502cba8c5feSAlex Lorenz } 503deb53490SAlex Lorenz if (Slot == -1) 504deb53490SAlex Lorenz OS << "<badref>"; 505deb53490SAlex Lorenz else 506deb53490SAlex Lorenz OS << Slot; 507deb53490SAlex Lorenz } 508deb53490SAlex Lorenz 5094af7e610SAlex Lorenz void MIPrinter::printIRValueReference(const Value &V) { 5104af7e610SAlex Lorenz OS << "%ir."; 5114af7e610SAlex Lorenz if (V.hasName()) { 5124af7e610SAlex Lorenz printLLVMNameWithoutPrefix(OS, V.getName()); 5134af7e610SAlex Lorenz return; 5144af7e610SAlex Lorenz } 5154af7e610SAlex Lorenz // TODO: Serialize the unnamed IR value references. 5164af7e610SAlex Lorenz OS << "<unserializable ir value>"; 5174af7e610SAlex Lorenz } 5184af7e610SAlex Lorenz 5197feaf7c6SAlex Lorenz void MIPrinter::printStackObjectReference(int FrameIndex) { 5207feaf7c6SAlex Lorenz auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex); 5217feaf7c6SAlex Lorenz assert(ObjectInfo != StackObjectOperandMapping.end() && 5227feaf7c6SAlex Lorenz "Invalid frame index"); 5237feaf7c6SAlex Lorenz const FrameIndexOperand &Operand = ObjectInfo->second; 5247feaf7c6SAlex Lorenz if (Operand.IsFixed) { 5257feaf7c6SAlex Lorenz OS << "%fixed-stack." << Operand.ID; 5267feaf7c6SAlex Lorenz return; 5277feaf7c6SAlex Lorenz } 5287feaf7c6SAlex Lorenz OS << "%stack." << Operand.ID; 5297feaf7c6SAlex Lorenz if (!Operand.Name.empty()) 5307feaf7c6SAlex Lorenz OS << '.' << Operand.Name; 5317feaf7c6SAlex Lorenz } 5327feaf7c6SAlex Lorenz 5335672a893SAlex Lorenz void MIPrinter::printOffset(int64_t Offset) { 5345672a893SAlex Lorenz if (Offset == 0) 5355672a893SAlex Lorenz return; 5365672a893SAlex Lorenz if (Offset < 0) { 5375672a893SAlex Lorenz OS << " - " << -Offset; 5385672a893SAlex Lorenz return; 5395672a893SAlex Lorenz } 5405672a893SAlex Lorenz OS << " + " << Offset; 5415672a893SAlex Lorenz } 5425672a893SAlex Lorenz 54349873a83SAlex Lorenz static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) { 54449873a83SAlex Lorenz auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); 54549873a83SAlex Lorenz for (const auto &I : Flags) { 54649873a83SAlex Lorenz if (I.first == TF) { 54749873a83SAlex Lorenz return I.second; 54849873a83SAlex Lorenz } 54949873a83SAlex Lorenz } 55049873a83SAlex Lorenz return nullptr; 55149873a83SAlex Lorenz } 55249873a83SAlex Lorenz 55349873a83SAlex Lorenz void MIPrinter::printTargetFlags(const MachineOperand &Op) { 55449873a83SAlex Lorenz if (!Op.getTargetFlags()) 55549873a83SAlex Lorenz return; 55649873a83SAlex Lorenz const auto *TII = 55749873a83SAlex Lorenz Op.getParent()->getParent()->getParent()->getSubtarget().getInstrInfo(); 55849873a83SAlex Lorenz assert(TII && "expected instruction info"); 55949873a83SAlex Lorenz auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags()); 56049873a83SAlex Lorenz OS << "target-flags("; 56149873a83SAlex Lorenz if (const auto *Name = getTargetFlagName(TII, Flags.first)) 56249873a83SAlex Lorenz OS << Name; 56349873a83SAlex Lorenz else 56449873a83SAlex Lorenz OS << "<unknown target flag>"; 56549873a83SAlex Lorenz // TODO: Print the target's bit flags. 56649873a83SAlex Lorenz OS << ") "; 56749873a83SAlex Lorenz } 56849873a83SAlex Lorenz 569ef5c196fSAlex Lorenz static const char *getTargetIndexName(const MachineFunction &MF, int Index) { 570ef5c196fSAlex Lorenz const auto *TII = MF.getSubtarget().getInstrInfo(); 571ef5c196fSAlex Lorenz assert(TII && "expected instruction info"); 572ef5c196fSAlex Lorenz auto Indices = TII->getSerializableTargetIndices(); 573ef5c196fSAlex Lorenz for (const auto &I : Indices) { 574ef5c196fSAlex Lorenz if (I.first == Index) { 575ef5c196fSAlex Lorenz return I.second; 576ef5c196fSAlex Lorenz } 577ef5c196fSAlex Lorenz } 578ef5c196fSAlex Lorenz return nullptr; 579ef5c196fSAlex Lorenz } 580ef5c196fSAlex Lorenz 581f3db51deSAlex Lorenz void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { 58249873a83SAlex Lorenz printTargetFlags(Op); 583f3db51deSAlex Lorenz switch (Op.getType()) { 584f3db51deSAlex Lorenz case MachineOperand::MO_Register: 585cb268d46SAlex Lorenz // TODO: Print the other register flags. 586cb268d46SAlex Lorenz if (Op.isImplicit()) 587cb268d46SAlex Lorenz OS << (Op.isDef() ? "implicit-def " : "implicit "); 588cbbfd0b1SAlex Lorenz if (Op.isDead()) 589cbbfd0b1SAlex Lorenz OS << "dead "; 590495ad879SAlex Lorenz if (Op.isKill()) 591495ad879SAlex Lorenz OS << "killed "; 5924d026b89SAlex Lorenz if (Op.isUndef()) 5934d026b89SAlex Lorenz OS << "undef "; 59401c1a5eeSAlex Lorenz if (Op.isEarlyClobber()) 59501c1a5eeSAlex Lorenz OS << "early-clobber "; 5969075258bSAlex Lorenz if (Op.isDebug()) 5979075258bSAlex Lorenz OS << "debug-use "; 598f3db51deSAlex Lorenz printReg(Op.getReg(), OS, TRI); 5992eacca86SAlex Lorenz // Print the sub register. 6002eacca86SAlex Lorenz if (Op.getSubReg() != 0) 6012eacca86SAlex Lorenz OS << ':' << TRI->getSubRegIndexName(Op.getSubReg()); 602f3db51deSAlex Lorenz break; 603240fc1e0SAlex Lorenz case MachineOperand::MO_Immediate: 604240fc1e0SAlex Lorenz OS << Op.getImm(); 605240fc1e0SAlex Lorenz break; 60605e3882eSAlex Lorenz case MachineOperand::MO_CImmediate: 60705e3882eSAlex Lorenz Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); 60805e3882eSAlex Lorenz break; 609ad156fb6SAlex Lorenz case MachineOperand::MO_FPImmediate: 610ad156fb6SAlex Lorenz Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); 611ad156fb6SAlex Lorenz break; 61233f0aef3SAlex Lorenz case MachineOperand::MO_MachineBasicBlock: 6135d26fa83SAlex Lorenz printMBBReference(*Op.getMBB()); 61433f0aef3SAlex Lorenz break; 6157feaf7c6SAlex Lorenz case MachineOperand::MO_FrameIndex: 6167feaf7c6SAlex Lorenz printStackObjectReference(Op.getIndex()); 6177feaf7c6SAlex Lorenz break; 618ab980499SAlex Lorenz case MachineOperand::MO_ConstantPoolIndex: 619ab980499SAlex Lorenz OS << "%const." << Op.getIndex(); 6205672a893SAlex Lorenz printOffset(Op.getOffset()); 621ab980499SAlex Lorenz break; 622ef5c196fSAlex Lorenz case MachineOperand::MO_TargetIndex: { 623ef5c196fSAlex Lorenz OS << "target-index("; 624ef5c196fSAlex Lorenz if (const auto *Name = getTargetIndexName( 625ef5c196fSAlex Lorenz *Op.getParent()->getParent()->getParent(), Op.getIndex())) 626ef5c196fSAlex Lorenz OS << Name; 627ef5c196fSAlex Lorenz else 628ef5c196fSAlex Lorenz OS << "<unknown>"; 629ef5c196fSAlex Lorenz OS << ')'; 6305672a893SAlex Lorenz printOffset(Op.getOffset()); 631ef5c196fSAlex Lorenz break; 632ef5c196fSAlex Lorenz } 63331d70683SAlex Lorenz case MachineOperand::MO_JumpTableIndex: 63431d70683SAlex Lorenz OS << "%jump-table." << Op.getIndex(); 63531d70683SAlex Lorenz break; 6366ede3744SAlex Lorenz case MachineOperand::MO_ExternalSymbol: 6376ede3744SAlex Lorenz OS << '$'; 6386ede3744SAlex Lorenz printLLVMNameWithoutPrefix(OS, Op.getSymbolName()); 6395672a893SAlex Lorenz printOffset(Op.getOffset()); 6406ede3744SAlex Lorenz break; 6415d6108e4SAlex Lorenz case MachineOperand::MO_GlobalAddress: 642900b5cb2SAlex Lorenz Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 6435672a893SAlex Lorenz printOffset(Op.getOffset()); 6445d6108e4SAlex Lorenz break; 645deb53490SAlex Lorenz case MachineOperand::MO_BlockAddress: 646deb53490SAlex Lorenz OS << "blockaddress("; 647deb53490SAlex Lorenz Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, 648deb53490SAlex Lorenz MST); 649deb53490SAlex Lorenz OS << ", "; 650deb53490SAlex Lorenz printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); 651deb53490SAlex Lorenz OS << ')'; 6525672a893SAlex Lorenz printOffset(Op.getOffset()); 653deb53490SAlex Lorenz break; 6548f6f4285SAlex Lorenz case MachineOperand::MO_RegisterMask: { 6558f6f4285SAlex Lorenz auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); 6568f6f4285SAlex Lorenz if (RegMaskInfo != RegisterMaskIds.end()) 6578f6f4285SAlex Lorenz OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); 6588f6f4285SAlex Lorenz else 6598f6f4285SAlex Lorenz llvm_unreachable("Can't print this machine register mask yet."); 6608f6f4285SAlex Lorenz break; 6618f6f4285SAlex Lorenz } 662b97c9ef4SAlex Lorenz case MachineOperand::MO_RegisterLiveOut: { 663b97c9ef4SAlex Lorenz const uint32_t *RegMask = Op.getRegLiveOut(); 664b97c9ef4SAlex Lorenz OS << "liveout("; 665b97c9ef4SAlex Lorenz bool IsCommaNeeded = false; 666b97c9ef4SAlex Lorenz for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { 667b97c9ef4SAlex Lorenz if (RegMask[Reg / 32] & (1U << (Reg % 32))) { 668b97c9ef4SAlex Lorenz if (IsCommaNeeded) 669b97c9ef4SAlex Lorenz OS << ", "; 670b97c9ef4SAlex Lorenz printReg(Reg, OS, TRI); 671b97c9ef4SAlex Lorenz IsCommaNeeded = true; 672b97c9ef4SAlex Lorenz } 673b97c9ef4SAlex Lorenz } 674b97c9ef4SAlex Lorenz OS << ")"; 675b97c9ef4SAlex Lorenz break; 676b97c9ef4SAlex Lorenz } 67735e44469SAlex Lorenz case MachineOperand::MO_Metadata: 67835e44469SAlex Lorenz Op.getMetadata()->printAsOperand(OS, MST); 67935e44469SAlex Lorenz break; 680f4baeb51SAlex Lorenz case MachineOperand::MO_CFIIndex: { 681f4baeb51SAlex Lorenz const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI(); 6828cfc6867SAlex Lorenz print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI); 683f4baeb51SAlex Lorenz break; 684f4baeb51SAlex Lorenz } 685f3db51deSAlex Lorenz default: 686f3db51deSAlex Lorenz // TODO: Print the other machine operands. 687f3db51deSAlex Lorenz llvm_unreachable("Can't print this machine operand at the moment"); 688f3db51deSAlex Lorenz } 6894f093bf1SAlex Lorenz } 6904f093bf1SAlex Lorenz 6914af7e610SAlex Lorenz void MIPrinter::print(const MachineMemOperand &Op) { 6924af7e610SAlex Lorenz OS << '('; 693dc8de2a6SAlex Lorenz // TODO: Print operand's target specific flags. 694a518b796SAlex Lorenz if (Op.isVolatile()) 695a518b796SAlex Lorenz OS << "volatile "; 69610fd0385SAlex Lorenz if (Op.isNonTemporal()) 69710fd0385SAlex Lorenz OS << "non-temporal "; 698dc8de2a6SAlex Lorenz if (Op.isInvariant()) 699dc8de2a6SAlex Lorenz OS << "invariant "; 7004af7e610SAlex Lorenz if (Op.isLoad()) 7014af7e610SAlex Lorenz OS << "load "; 7024af7e610SAlex Lorenz else { 7034af7e610SAlex Lorenz assert(Op.isStore() && "Non load machine operand must be a store"); 7044af7e610SAlex Lorenz OS << "store "; 7054af7e610SAlex Lorenz } 7064af7e610SAlex Lorenz OS << Op.getSize() << (Op.isLoad() ? " from " : " into "); 70791097a3fSAlex Lorenz if (const Value *Val = Op.getValue()) { 7084af7e610SAlex Lorenz printIRValueReference(*Val); 70991097a3fSAlex Lorenz } else { 71091097a3fSAlex Lorenz const PseudoSourceValue *PVal = Op.getPseudoValue(); 71191097a3fSAlex Lorenz assert(PVal && "Expected a pseudo source value"); 71291097a3fSAlex Lorenz switch (PVal->kind()) { 71346e9558aSAlex Lorenz case PseudoSourceValue::Stack: 71446e9558aSAlex Lorenz OS << "stack"; 71546e9558aSAlex Lorenz break; 716d858f874SAlex Lorenz case PseudoSourceValue::GOT: 717d858f874SAlex Lorenz OS << "got"; 718d858f874SAlex Lorenz break; 7194be56e93SAlex Lorenz case PseudoSourceValue::JumpTable: 7204be56e93SAlex Lorenz OS << "jump-table"; 7214be56e93SAlex Lorenz break; 72291097a3fSAlex Lorenz case PseudoSourceValue::ConstantPool: 72391097a3fSAlex Lorenz OS << "constant-pool"; 72491097a3fSAlex Lorenz break; 725*0cc671bfSAlex Lorenz case PseudoSourceValue::FixedStack: 726*0cc671bfSAlex Lorenz printStackObjectReference( 727*0cc671bfSAlex Lorenz cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex()); 728*0cc671bfSAlex Lorenz break; 72991097a3fSAlex Lorenz default: 73091097a3fSAlex Lorenz // TODO: Print the other pseudo source values. 73191097a3fSAlex Lorenz OS << "<unserializable pseudo value>"; 73291097a3fSAlex Lorenz break; 73391097a3fSAlex Lorenz } 73491097a3fSAlex Lorenz } 73583127739SAlex Lorenz printOffset(Op.getOffset()); 73661420f79SAlex Lorenz if (Op.getBaseAlignment() != Op.getSize()) 73761420f79SAlex Lorenz OS << ", align " << Op.getBaseAlignment(); 7384af7e610SAlex Lorenz // TODO: Print the metadata attributes. 7394af7e610SAlex Lorenz OS << ')'; 7404af7e610SAlex Lorenz } 7414af7e610SAlex Lorenz 7428cfc6867SAlex Lorenz static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS, 7438cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 7448cfc6867SAlex Lorenz int Reg = TRI->getLLVMRegNum(DwarfReg, true); 7458cfc6867SAlex Lorenz if (Reg == -1) { 7468cfc6867SAlex Lorenz OS << "<badreg>"; 7478cfc6867SAlex Lorenz return; 7488cfc6867SAlex Lorenz } 7498cfc6867SAlex Lorenz printReg(Reg, OS, TRI); 7508cfc6867SAlex Lorenz } 7518cfc6867SAlex Lorenz 7528cfc6867SAlex Lorenz void MIPrinter::print(const MCCFIInstruction &CFI, 7538cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 754f4baeb51SAlex Lorenz switch (CFI.getOperation()) { 7558cfc6867SAlex Lorenz case MCCFIInstruction::OpOffset: 7568cfc6867SAlex Lorenz OS << ".cfi_offset "; 7578cfc6867SAlex Lorenz if (CFI.getLabel()) 7588cfc6867SAlex Lorenz OS << "<mcsymbol> "; 7598cfc6867SAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 7608cfc6867SAlex Lorenz OS << ", " << CFI.getOffset(); 7618cfc6867SAlex Lorenz break; 7625b0d5f6fSAlex Lorenz case MCCFIInstruction::OpDefCfaRegister: 7635b0d5f6fSAlex Lorenz OS << ".cfi_def_cfa_register "; 7645b0d5f6fSAlex Lorenz if (CFI.getLabel()) 7655b0d5f6fSAlex Lorenz OS << "<mcsymbol> "; 7665b0d5f6fSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 7675b0d5f6fSAlex Lorenz break; 768f4baeb51SAlex Lorenz case MCCFIInstruction::OpDefCfaOffset: 769f4baeb51SAlex Lorenz OS << ".cfi_def_cfa_offset "; 770f4baeb51SAlex Lorenz if (CFI.getLabel()) 771f4baeb51SAlex Lorenz OS << "<mcsymbol> "; 772f4baeb51SAlex Lorenz OS << CFI.getOffset(); 773f4baeb51SAlex Lorenz break; 774b139323fSAlex Lorenz case MCCFIInstruction::OpDefCfa: 775b139323fSAlex Lorenz OS << ".cfi_def_cfa "; 776b139323fSAlex Lorenz if (CFI.getLabel()) 777b139323fSAlex Lorenz OS << "<mcsymbol> "; 778b139323fSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 779b139323fSAlex Lorenz OS << ", " << CFI.getOffset(); 780b139323fSAlex Lorenz break; 781f4baeb51SAlex Lorenz default: 782f4baeb51SAlex Lorenz // TODO: Print the other CFI Operations. 783f4baeb51SAlex Lorenz OS << "<unserializable cfi operation>"; 784f4baeb51SAlex Lorenz break; 785f4baeb51SAlex Lorenz } 786f4baeb51SAlex Lorenz } 787f4baeb51SAlex Lorenz 788345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) { 789345c1449SAlex Lorenz yaml::Output Out(OS); 790345c1449SAlex Lorenz Out << const_cast<Module &>(M); 791345c1449SAlex Lorenz } 792345c1449SAlex Lorenz 793345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) { 794345c1449SAlex Lorenz MIRPrinter Printer(OS); 795345c1449SAlex Lorenz Printer.print(MF); 796345c1449SAlex Lorenz } 797