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); 86f6bc8667SAlex Lorenz void convertStackObjects(yaml::MachineFunction &MF, 871bb48de1SAlex Lorenz const MachineFrameInfo &MFI, 881bb48de1SAlex Lorenz const TargetRegisterInfo *TRI); 898f6f4285SAlex Lorenz 908f6f4285SAlex Lorenz private: 918f6f4285SAlex Lorenz void initRegisterMaskIds(const MachineFunction &MF); 92345c1449SAlex Lorenz }; 93345c1449SAlex Lorenz 948e0a1b48SAlex Lorenz /// This class prints out the machine instructions using the MIR serialization 958e0a1b48SAlex Lorenz /// format. 968e0a1b48SAlex Lorenz class MIPrinter { 978e0a1b48SAlex Lorenz raw_ostream &OS; 98900b5cb2SAlex Lorenz ModuleSlotTracker &MST; 998f6f4285SAlex Lorenz const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds; 1007feaf7c6SAlex Lorenz const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping; 1018e0a1b48SAlex Lorenz 1028e0a1b48SAlex Lorenz public: 103900b5cb2SAlex Lorenz MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST, 1047feaf7c6SAlex Lorenz const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds, 1057feaf7c6SAlex Lorenz const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping) 1067feaf7c6SAlex Lorenz : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds), 1077feaf7c6SAlex Lorenz StackObjectOperandMapping(StackObjectOperandMapping) {} 1088e0a1b48SAlex Lorenz 1095022f6bbSAlex Lorenz void print(const MachineBasicBlock &MBB); 1105022f6bbSAlex Lorenz 1118e0a1b48SAlex Lorenz void print(const MachineInstr &MI); 1125d26fa83SAlex Lorenz void printMBBReference(const MachineBasicBlock &MBB); 113deb53490SAlex Lorenz void printIRBlockReference(const BasicBlock &BB); 1144af7e610SAlex Lorenz void printIRValueReference(const Value &V); 1157feaf7c6SAlex Lorenz void printStackObjectReference(int FrameIndex); 1165672a893SAlex Lorenz void printOffset(int64_t Offset); 11749873a83SAlex Lorenz void printTargetFlags(const MachineOperand &Op); 118f3db51deSAlex Lorenz void print(const MachineOperand &Op, const TargetRegisterInfo *TRI); 1194af7e610SAlex Lorenz void print(const MachineMemOperand &Op); 120f4baeb51SAlex Lorenz 1218cfc6867SAlex Lorenz void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI); 1228e0a1b48SAlex Lorenz }; 1238e0a1b48SAlex Lorenz 1245022f6bbSAlex Lorenz } // end namespace llvm 125345c1449SAlex Lorenz 126345c1449SAlex Lorenz namespace llvm { 127345c1449SAlex Lorenz namespace yaml { 128345c1449SAlex Lorenz 129345c1449SAlex Lorenz /// This struct serializes the LLVM IR module. 130345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> { 131345c1449SAlex Lorenz static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) { 132345c1449SAlex Lorenz Mod.print(OS, nullptr); 133345c1449SAlex Lorenz } 134345c1449SAlex Lorenz static StringRef input(StringRef Str, void *Ctxt, Module &Mod) { 135345c1449SAlex Lorenz llvm_unreachable("LLVM Module is supposed to be parsed separately"); 136345c1449SAlex Lorenz return ""; 137345c1449SAlex Lorenz } 138345c1449SAlex Lorenz }; 139345c1449SAlex Lorenz 140345c1449SAlex Lorenz } // end namespace yaml 141345c1449SAlex Lorenz } // end namespace llvm 142345c1449SAlex Lorenz 14315a00a85SAlex Lorenz static void printReg(unsigned Reg, raw_ostream &OS, 14415a00a85SAlex Lorenz const TargetRegisterInfo *TRI) { 14515a00a85SAlex Lorenz // TODO: Print Stack Slots. 14615a00a85SAlex Lorenz if (!Reg) 14715a00a85SAlex Lorenz OS << '_'; 14815a00a85SAlex Lorenz else if (TargetRegisterInfo::isVirtualRegister(Reg)) 14915a00a85SAlex Lorenz OS << '%' << TargetRegisterInfo::virtReg2Index(Reg); 15015a00a85SAlex Lorenz else if (Reg < TRI->getNumRegs()) 15115a00a85SAlex Lorenz OS << '%' << StringRef(TRI->getName(Reg)).lower(); 15215a00a85SAlex Lorenz else 15315a00a85SAlex Lorenz llvm_unreachable("Can't print this kind of register yet"); 15415a00a85SAlex Lorenz } 15515a00a85SAlex Lorenz 156ab4cbcfdSAlex Lorenz static void printReg(unsigned Reg, yaml::StringValue &Dest, 157ab4cbcfdSAlex Lorenz const TargetRegisterInfo *TRI) { 158ab4cbcfdSAlex Lorenz raw_string_ostream OS(Dest.Value); 159ab4cbcfdSAlex Lorenz printReg(Reg, OS, TRI); 160ab4cbcfdSAlex Lorenz } 161ab4cbcfdSAlex Lorenz 162345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) { 1638f6f4285SAlex Lorenz initRegisterMaskIds(MF); 1648f6f4285SAlex Lorenz 165345c1449SAlex Lorenz yaml::MachineFunction YamlMF; 166345c1449SAlex Lorenz YamlMF.Name = MF.getName(); 1675b5f9753SAlex Lorenz YamlMF.Alignment = MF.getAlignment(); 1685b5f9753SAlex Lorenz YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice(); 1695b5f9753SAlex Lorenz YamlMF.HasInlineAsm = MF.hasInlineAsm(); 17028148ba8SAlex Lorenz convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo()); 171a6f9a37dSAlex Lorenz ModuleSlotTracker MST(MF.getFunction()->getParent()); 172a6f9a37dSAlex Lorenz MST.incorporateFunction(*MF.getFunction()); 173a6f9a37dSAlex Lorenz convert(MST, YamlMF.FrameInfo, *MF.getFrameInfo()); 1741bb48de1SAlex Lorenz convertStackObjects(YamlMF, *MF.getFrameInfo(), 1751bb48de1SAlex Lorenz MF.getSubtarget().getRegisterInfo()); 176ab980499SAlex Lorenz if (const auto *ConstantPool = MF.getConstantPool()) 177ab980499SAlex Lorenz convert(YamlMF, *ConstantPool); 1786799e9b3SAlex Lorenz if (const auto *JumpTableInfo = MF.getJumpTableInfo()) 1796799e9b3SAlex Lorenz convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo); 1805022f6bbSAlex Lorenz raw_string_ostream StrOS(YamlMF.Body.Value.Value); 1815022f6bbSAlex Lorenz bool IsNewlineNeeded = false; 1824f093bf1SAlex Lorenz for (const auto &MBB : MF) { 1835022f6bbSAlex Lorenz if (IsNewlineNeeded) 1845022f6bbSAlex Lorenz StrOS << "\n"; 1855022f6bbSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 1865022f6bbSAlex Lorenz .print(MBB); 1875022f6bbSAlex Lorenz IsNewlineNeeded = true; 1884f093bf1SAlex Lorenz } 1895022f6bbSAlex Lorenz StrOS.flush(); 190345c1449SAlex Lorenz yaml::Output Out(OS); 191345c1449SAlex Lorenz Out << YamlMF; 192345c1449SAlex Lorenz } 193345c1449SAlex Lorenz 19454565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 19528148ba8SAlex Lorenz const MachineRegisterInfo &RegInfo, 19628148ba8SAlex Lorenz const TargetRegisterInfo *TRI) { 19754565cf0SAlex Lorenz MF.IsSSA = RegInfo.isSSA(); 19854565cf0SAlex Lorenz MF.TracksRegLiveness = RegInfo.tracksLiveness(); 19954565cf0SAlex Lorenz MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled(); 20028148ba8SAlex Lorenz 20128148ba8SAlex Lorenz // Print the virtual register definitions. 20228148ba8SAlex Lorenz for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) { 20328148ba8SAlex Lorenz unsigned Reg = TargetRegisterInfo::index2VirtReg(I); 20428148ba8SAlex Lorenz yaml::VirtualRegisterDefinition VReg; 20528148ba8SAlex Lorenz VReg.ID = I; 20628148ba8SAlex Lorenz VReg.Class = 20728148ba8SAlex Lorenz StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower(); 208ab4cbcfdSAlex Lorenz unsigned PreferredReg = RegInfo.getSimpleHint(Reg); 209ab4cbcfdSAlex Lorenz if (PreferredReg) 210ab4cbcfdSAlex Lorenz printReg(PreferredReg, VReg.PreferredRegister, TRI); 21128148ba8SAlex Lorenz MF.VirtualRegisters.push_back(VReg); 21228148ba8SAlex Lorenz } 21312045a4bSAlex Lorenz 21412045a4bSAlex Lorenz // Print the live ins. 21512045a4bSAlex Lorenz for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) { 21612045a4bSAlex Lorenz yaml::MachineFunctionLiveIn LiveIn; 21712045a4bSAlex Lorenz printReg(I->first, LiveIn.Register, TRI); 21812045a4bSAlex Lorenz if (I->second) 21912045a4bSAlex Lorenz printReg(I->second, LiveIn.VirtualRegister, TRI); 22012045a4bSAlex Lorenz MF.LiveIns.push_back(LiveIn); 22112045a4bSAlex Lorenz } 222c4838087SAlex Lorenz // The used physical register mask is printed as an inverted callee saved 223c4838087SAlex Lorenz // register mask. 224c4838087SAlex Lorenz const BitVector &UsedPhysRegMask = RegInfo.getUsedPhysRegsMask(); 225c4838087SAlex Lorenz if (UsedPhysRegMask.none()) 226c4838087SAlex Lorenz return; 227c4838087SAlex Lorenz std::vector<yaml::FlowStringValue> CalleeSavedRegisters; 228c4838087SAlex Lorenz for (unsigned I = 0, E = UsedPhysRegMask.size(); I != E; ++I) { 229c4838087SAlex Lorenz if (!UsedPhysRegMask[I]) { 230c4838087SAlex Lorenz yaml::FlowStringValue Reg; 231c4838087SAlex Lorenz printReg(I, Reg, TRI); 232c4838087SAlex Lorenz CalleeSavedRegisters.push_back(Reg); 233c4838087SAlex Lorenz } 234c4838087SAlex Lorenz } 235c4838087SAlex Lorenz MF.CalleeSavedRegisters = CalleeSavedRegisters; 23654565cf0SAlex Lorenz } 23754565cf0SAlex Lorenz 238a6f9a37dSAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 239a6f9a37dSAlex Lorenz yaml::MachineFrameInfo &YamlMFI, 24060541c1dSAlex Lorenz const MachineFrameInfo &MFI) { 24160541c1dSAlex Lorenz YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken(); 24260541c1dSAlex Lorenz YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken(); 24360541c1dSAlex Lorenz YamlMFI.HasStackMap = MFI.hasStackMap(); 24460541c1dSAlex Lorenz YamlMFI.HasPatchPoint = MFI.hasPatchPoint(); 24560541c1dSAlex Lorenz YamlMFI.StackSize = MFI.getStackSize(); 24660541c1dSAlex Lorenz YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment(); 24760541c1dSAlex Lorenz YamlMFI.MaxAlignment = MFI.getMaxAlignment(); 24860541c1dSAlex Lorenz YamlMFI.AdjustsStack = MFI.adjustsStack(); 24960541c1dSAlex Lorenz YamlMFI.HasCalls = MFI.hasCalls(); 25060541c1dSAlex Lorenz YamlMFI.MaxCallFrameSize = MFI.getMaxCallFrameSize(); 25160541c1dSAlex Lorenz YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment(); 25260541c1dSAlex Lorenz YamlMFI.HasVAStart = MFI.hasVAStart(); 25360541c1dSAlex Lorenz YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc(); 254a6f9a37dSAlex Lorenz if (MFI.getSavePoint()) { 255a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.SavePoint.Value); 256a6f9a37dSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 257a6f9a37dSAlex Lorenz .printMBBReference(*MFI.getSavePoint()); 258a6f9a37dSAlex Lorenz } 259a6f9a37dSAlex Lorenz if (MFI.getRestorePoint()) { 260a6f9a37dSAlex Lorenz raw_string_ostream StrOS(YamlMFI.RestorePoint.Value); 261a6f9a37dSAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 262a6f9a37dSAlex Lorenz .printMBBReference(*MFI.getRestorePoint()); 263a6f9a37dSAlex Lorenz } 26460541c1dSAlex Lorenz } 26560541c1dSAlex Lorenz 266f6bc8667SAlex Lorenz void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF, 2671bb48de1SAlex Lorenz const MachineFrameInfo &MFI, 2681bb48de1SAlex Lorenz const TargetRegisterInfo *TRI) { 269de491f05SAlex Lorenz // Process fixed stack objects. 270f6bc8667SAlex Lorenz unsigned ID = 0; 271de491f05SAlex Lorenz for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) { 272de491f05SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 273de491f05SAlex Lorenz continue; 274de491f05SAlex Lorenz 275de491f05SAlex Lorenz yaml::FixedMachineStackObject YamlObject; 2767feaf7c6SAlex Lorenz YamlObject.ID = ID; 277de491f05SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 278de491f05SAlex Lorenz ? yaml::FixedMachineStackObject::SpillSlot 279de491f05SAlex Lorenz : yaml::FixedMachineStackObject::DefaultType; 280de491f05SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 281de491f05SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 282de491f05SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 283de491f05SAlex Lorenz YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I); 284de491f05SAlex Lorenz YamlObject.IsAliased = MFI.isAliasedObjectIndex(I); 285de491f05SAlex Lorenz MF.FixedStackObjects.push_back(YamlObject); 2867feaf7c6SAlex Lorenz StackObjectOperandMapping.insert( 2877feaf7c6SAlex Lorenz std::make_pair(I, FrameIndexOperand::createFixed(ID++))); 288de491f05SAlex Lorenz } 289de491f05SAlex Lorenz 290de491f05SAlex Lorenz // Process ordinary stack objects. 291de491f05SAlex Lorenz ID = 0; 292f6bc8667SAlex Lorenz for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) { 293f6bc8667SAlex Lorenz if (MFI.isDeadObjectIndex(I)) 294f6bc8667SAlex Lorenz continue; 295f6bc8667SAlex Lorenz 296f6bc8667SAlex Lorenz yaml::MachineStackObject YamlObject; 2977feaf7c6SAlex Lorenz YamlObject.ID = ID; 29837643a04SAlex Lorenz if (const auto *Alloca = MFI.getObjectAllocation(I)) 29937643a04SAlex Lorenz YamlObject.Name.Value = 30037643a04SAlex Lorenz Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>"; 301f6bc8667SAlex Lorenz YamlObject.Type = MFI.isSpillSlotObjectIndex(I) 302f6bc8667SAlex Lorenz ? yaml::MachineStackObject::SpillSlot 303418f3ec1SAlex Lorenz : MFI.isVariableSizedObjectIndex(I) 304418f3ec1SAlex Lorenz ? yaml::MachineStackObject::VariableSized 305f6bc8667SAlex Lorenz : yaml::MachineStackObject::DefaultType; 306f6bc8667SAlex Lorenz YamlObject.Offset = MFI.getObjectOffset(I); 307f6bc8667SAlex Lorenz YamlObject.Size = MFI.getObjectSize(I); 308f6bc8667SAlex Lorenz YamlObject.Alignment = MFI.getObjectAlignment(I); 309f6bc8667SAlex Lorenz 310f6bc8667SAlex Lorenz MF.StackObjects.push_back(YamlObject); 3117feaf7c6SAlex Lorenz StackObjectOperandMapping.insert(std::make_pair( 3127feaf7c6SAlex Lorenz I, FrameIndexOperand::create(YamlObject.Name.Value, ID++))); 313f6bc8667SAlex Lorenz } 3141bb48de1SAlex Lorenz 3151bb48de1SAlex Lorenz for (const auto &CSInfo : MFI.getCalleeSavedInfo()) { 3161bb48de1SAlex Lorenz yaml::StringValue Reg; 3171bb48de1SAlex Lorenz printReg(CSInfo.getReg(), Reg, TRI); 3181bb48de1SAlex Lorenz auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx()); 3191bb48de1SAlex Lorenz assert(StackObjectInfo != StackObjectOperandMapping.end() && 3201bb48de1SAlex Lorenz "Invalid stack object index"); 3211bb48de1SAlex Lorenz const FrameIndexOperand &StackObject = StackObjectInfo->second; 3221bb48de1SAlex Lorenz if (StackObject.IsFixed) 3231bb48de1SAlex Lorenz MF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg; 3241bb48de1SAlex Lorenz else 3251bb48de1SAlex Lorenz MF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg; 3261bb48de1SAlex Lorenz } 327f6bc8667SAlex Lorenz } 328f6bc8667SAlex Lorenz 329ab980499SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 330ab980499SAlex Lorenz const MachineConstantPool &ConstantPool) { 331ab980499SAlex Lorenz unsigned ID = 0; 332ab980499SAlex Lorenz for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) { 333ab980499SAlex Lorenz // TODO: Serialize target specific constant pool entries. 334ab980499SAlex Lorenz if (Constant.isMachineConstantPoolEntry()) 335ab980499SAlex Lorenz llvm_unreachable("Can't print target specific constant pool entries yet"); 336ab980499SAlex Lorenz 337ab980499SAlex Lorenz yaml::MachineConstantPoolValue YamlConstant; 338ab980499SAlex Lorenz std::string Str; 339ab980499SAlex Lorenz raw_string_ostream StrOS(Str); 340ab980499SAlex Lorenz Constant.Val.ConstVal->printAsOperand(StrOS); 341ab980499SAlex Lorenz YamlConstant.ID = ID++; 342ab980499SAlex Lorenz YamlConstant.Value = StrOS.str(); 343ab980499SAlex Lorenz YamlConstant.Alignment = Constant.getAlignment(); 344ab980499SAlex Lorenz MF.Constants.push_back(YamlConstant); 345ab980499SAlex Lorenz } 346ab980499SAlex Lorenz } 347ab980499SAlex Lorenz 348900b5cb2SAlex Lorenz void MIRPrinter::convert(ModuleSlotTracker &MST, 3496799e9b3SAlex Lorenz yaml::MachineJumpTable &YamlJTI, 3506799e9b3SAlex Lorenz const MachineJumpTableInfo &JTI) { 3516799e9b3SAlex Lorenz YamlJTI.Kind = JTI.getEntryKind(); 3526799e9b3SAlex Lorenz unsigned ID = 0; 3536799e9b3SAlex Lorenz for (const auto &Table : JTI.getJumpTables()) { 3546799e9b3SAlex Lorenz std::string Str; 3556799e9b3SAlex Lorenz yaml::MachineJumpTable::Entry Entry; 3566799e9b3SAlex Lorenz Entry.ID = ID++; 3576799e9b3SAlex Lorenz for (const auto *MBB : Table.MBBs) { 3586799e9b3SAlex Lorenz raw_string_ostream StrOS(Str); 3597feaf7c6SAlex Lorenz MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping) 3607feaf7c6SAlex Lorenz .printMBBReference(*MBB); 3616799e9b3SAlex Lorenz Entry.Blocks.push_back(StrOS.str()); 3626799e9b3SAlex Lorenz Str.clear(); 3636799e9b3SAlex Lorenz } 3646799e9b3SAlex Lorenz YamlJTI.Entries.push_back(Entry); 3656799e9b3SAlex Lorenz } 3666799e9b3SAlex Lorenz } 3676799e9b3SAlex Lorenz 3688f6f4285SAlex Lorenz void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) { 3698f6f4285SAlex Lorenz const auto *TRI = MF.getSubtarget().getRegisterInfo(); 3708f6f4285SAlex Lorenz unsigned I = 0; 3718f6f4285SAlex Lorenz for (const uint32_t *Mask : TRI->getRegMasks()) 3728f6f4285SAlex Lorenz RegisterMaskIds.insert(std::make_pair(Mask, I++)); 3738f6f4285SAlex Lorenz } 3748f6f4285SAlex Lorenz 3755022f6bbSAlex Lorenz void MIPrinter::print(const MachineBasicBlock &MBB) { 3765022f6bbSAlex Lorenz assert(MBB.getNumber() >= 0 && "Invalid MBB number"); 3775022f6bbSAlex Lorenz OS << "bb." << MBB.getNumber(); 3785022f6bbSAlex Lorenz bool HasAttributes = false; 3795022f6bbSAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 3805022f6bbSAlex Lorenz if (BB->hasName()) { 3815022f6bbSAlex Lorenz OS << "." << BB->getName(); 3825022f6bbSAlex Lorenz } else { 3835022f6bbSAlex Lorenz HasAttributes = true; 3845022f6bbSAlex Lorenz OS << " ("; 3855022f6bbSAlex Lorenz int Slot = MST.getLocalSlot(BB); 3865022f6bbSAlex Lorenz if (Slot == -1) 3875022f6bbSAlex Lorenz OS << "<ir-block badref>"; 3885022f6bbSAlex Lorenz else 3895022f6bbSAlex Lorenz OS << (Twine("%ir-block.") + Twine(Slot)).str(); 3905022f6bbSAlex Lorenz } 3915022f6bbSAlex Lorenz } 3925022f6bbSAlex Lorenz if (MBB.hasAddressTaken()) { 3935022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 3945022f6bbSAlex Lorenz OS << "address-taken"; 3955022f6bbSAlex Lorenz HasAttributes = true; 3965022f6bbSAlex Lorenz } 3975022f6bbSAlex Lorenz if (MBB.isLandingPad()) { 3985022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 3995022f6bbSAlex Lorenz OS << "landing-pad"; 4005022f6bbSAlex Lorenz HasAttributes = true; 4015022f6bbSAlex Lorenz } 4025022f6bbSAlex Lorenz if (MBB.getAlignment()) { 4035022f6bbSAlex Lorenz OS << (HasAttributes ? ", " : " ("); 4045022f6bbSAlex Lorenz OS << "align " << MBB.getAlignment(); 4055022f6bbSAlex Lorenz HasAttributes = true; 4065022f6bbSAlex Lorenz } 4075022f6bbSAlex Lorenz if (HasAttributes) 4085022f6bbSAlex Lorenz OS << ")"; 4095022f6bbSAlex Lorenz OS << ":\n"; 4105022f6bbSAlex Lorenz 4115022f6bbSAlex Lorenz bool HasLineAttributes = false; 4125022f6bbSAlex Lorenz // Print the successors 4135022f6bbSAlex Lorenz if (!MBB.succ_empty()) { 4145022f6bbSAlex Lorenz OS.indent(2) << "successors: "; 4155022f6bbSAlex Lorenz for (auto I = MBB.succ_begin(), E = MBB.succ_end(); I != E; ++I) { 4165022f6bbSAlex Lorenz if (I != MBB.succ_begin()) 4175022f6bbSAlex Lorenz OS << ", "; 4185022f6bbSAlex Lorenz printMBBReference(**I); 4195022f6bbSAlex Lorenz if (MBB.hasSuccessorWeights()) 4205022f6bbSAlex Lorenz OS << '(' << MBB.getSuccWeight(I) << ')'; 4215022f6bbSAlex Lorenz } 4225022f6bbSAlex Lorenz OS << "\n"; 4235022f6bbSAlex Lorenz HasLineAttributes = true; 4245022f6bbSAlex Lorenz } 4255022f6bbSAlex Lorenz 4265022f6bbSAlex Lorenz // Print the live in registers. 4275022f6bbSAlex Lorenz const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo(); 4285022f6bbSAlex Lorenz assert(TRI && "Expected target register info"); 4295022f6bbSAlex Lorenz if (!MBB.livein_empty()) { 4305022f6bbSAlex Lorenz OS.indent(2) << "liveins: "; 4315022f6bbSAlex Lorenz for (auto I = MBB.livein_begin(), E = MBB.livein_end(); I != E; ++I) { 4325022f6bbSAlex Lorenz if (I != MBB.livein_begin()) 4335022f6bbSAlex Lorenz OS << ", "; 4345022f6bbSAlex Lorenz printReg(*I, OS, TRI); 4355022f6bbSAlex Lorenz } 4365022f6bbSAlex Lorenz OS << "\n"; 4375022f6bbSAlex Lorenz HasLineAttributes = true; 4385022f6bbSAlex Lorenz } 4395022f6bbSAlex Lorenz 4405022f6bbSAlex Lorenz if (HasLineAttributes) 4415022f6bbSAlex Lorenz OS << "\n"; 442f9a2b123SAlex Lorenz bool IsInBundle = false; 443f9a2b123SAlex Lorenz for (auto I = MBB.instr_begin(), E = MBB.instr_end(); I != E; ++I) { 444f9a2b123SAlex Lorenz const MachineInstr &MI = *I; 445f9a2b123SAlex Lorenz if (IsInBundle && !MI.isInsideBundle()) { 446f9a2b123SAlex Lorenz OS.indent(2) << "}\n"; 447f9a2b123SAlex Lorenz IsInBundle = false; 448f9a2b123SAlex Lorenz } 449f9a2b123SAlex Lorenz OS.indent(IsInBundle ? 4 : 2); 4505022f6bbSAlex Lorenz print(MI); 451f9a2b123SAlex Lorenz if (!IsInBundle && MI.getFlag(MachineInstr::BundledSucc)) { 452f9a2b123SAlex Lorenz OS << " {"; 453f9a2b123SAlex Lorenz IsInBundle = true; 454f9a2b123SAlex Lorenz } 4555022f6bbSAlex Lorenz OS << "\n"; 4565022f6bbSAlex Lorenz } 457f9a2b123SAlex Lorenz if (IsInBundle) 458f9a2b123SAlex Lorenz OS.indent(2) << "}\n"; 4595022f6bbSAlex Lorenz } 4605022f6bbSAlex Lorenz 4618e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) { 4628e0a1b48SAlex Lorenz const auto &SubTarget = MI.getParent()->getParent()->getSubtarget(); 463f3db51deSAlex Lorenz const auto *TRI = SubTarget.getRegisterInfo(); 464f3db51deSAlex Lorenz assert(TRI && "Expected target register info"); 4658e0a1b48SAlex Lorenz const auto *TII = SubTarget.getInstrInfo(); 4668e0a1b48SAlex Lorenz assert(TII && "Expected target instruction info"); 467f4baeb51SAlex Lorenz if (MI.isCFIInstruction()) 468f4baeb51SAlex Lorenz assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction"); 4698e0a1b48SAlex Lorenz 470f3db51deSAlex Lorenz unsigned I = 0, E = MI.getNumOperands(); 471f3db51deSAlex Lorenz for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() && 472f3db51deSAlex Lorenz !MI.getOperand(I).isImplicit(); 473f3db51deSAlex Lorenz ++I) { 474f3db51deSAlex Lorenz if (I) 475f3db51deSAlex Lorenz OS << ", "; 476f3db51deSAlex Lorenz print(MI.getOperand(I), TRI); 477f3db51deSAlex Lorenz } 478f3db51deSAlex Lorenz 479f3db51deSAlex Lorenz if (I) 480f3db51deSAlex Lorenz OS << " = "; 481e5a44660SAlex Lorenz if (MI.getFlag(MachineInstr::FrameSetup)) 482e5a44660SAlex Lorenz OS << "frame-setup "; 4838e0a1b48SAlex Lorenz OS << TII->getName(MI.getOpcode()); 484f3db51deSAlex Lorenz if (I < E) 485f3db51deSAlex Lorenz OS << ' '; 486f3db51deSAlex Lorenz 487f3db51deSAlex Lorenz bool NeedComma = false; 488f3db51deSAlex Lorenz for (; I < E; ++I) { 489f3db51deSAlex Lorenz if (NeedComma) 490f3db51deSAlex Lorenz OS << ", "; 491f3db51deSAlex Lorenz print(MI.getOperand(I), TRI); 492f3db51deSAlex Lorenz NeedComma = true; 493f3db51deSAlex Lorenz } 49446d760d1SAlex Lorenz 49546d760d1SAlex Lorenz if (MI.getDebugLoc()) { 49646d760d1SAlex Lorenz if (NeedComma) 49746d760d1SAlex Lorenz OS << ','; 49846d760d1SAlex Lorenz OS << " debug-location "; 49946d760d1SAlex Lorenz MI.getDebugLoc()->printAsOperand(OS, MST); 50046d760d1SAlex Lorenz } 5014af7e610SAlex Lorenz 5024af7e610SAlex Lorenz if (!MI.memoperands_empty()) { 5034af7e610SAlex Lorenz OS << " :: "; 5044af7e610SAlex Lorenz bool NeedComma = false; 5054af7e610SAlex Lorenz for (const auto *Op : MI.memoperands()) { 5064af7e610SAlex Lorenz if (NeedComma) 5074af7e610SAlex Lorenz OS << ", "; 5084af7e610SAlex Lorenz print(*Op); 5094af7e610SAlex Lorenz NeedComma = true; 5104af7e610SAlex Lorenz } 5114af7e610SAlex Lorenz } 512f3db51deSAlex Lorenz } 513f3db51deSAlex Lorenz 5145d26fa83SAlex Lorenz void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) { 5155d26fa83SAlex Lorenz OS << "%bb." << MBB.getNumber(); 5165d26fa83SAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) { 5175d26fa83SAlex Lorenz if (BB->hasName()) 5185d26fa83SAlex Lorenz OS << '.' << BB->getName(); 5195d26fa83SAlex Lorenz } 5205d26fa83SAlex Lorenz } 5215d26fa83SAlex Lorenz 522deb53490SAlex Lorenz void MIPrinter::printIRBlockReference(const BasicBlock &BB) { 523deb53490SAlex Lorenz OS << "%ir-block."; 524deb53490SAlex Lorenz if (BB.hasName()) { 525deb53490SAlex Lorenz printLLVMNameWithoutPrefix(OS, BB.getName()); 526deb53490SAlex Lorenz return; 527deb53490SAlex Lorenz } 528cba8c5feSAlex Lorenz const Function *F = BB.getParent(); 529cba8c5feSAlex Lorenz int Slot; 530cba8c5feSAlex Lorenz if (F == MST.getCurrentFunction()) { 531cba8c5feSAlex Lorenz Slot = MST.getLocalSlot(&BB); 532cba8c5feSAlex Lorenz } else { 533cba8c5feSAlex Lorenz ModuleSlotTracker CustomMST(F->getParent(), 534cba8c5feSAlex Lorenz /*ShouldInitializeAllMetadata=*/false); 535cba8c5feSAlex Lorenz CustomMST.incorporateFunction(*F); 536cba8c5feSAlex Lorenz Slot = CustomMST.getLocalSlot(&BB); 537cba8c5feSAlex Lorenz } 538deb53490SAlex Lorenz if (Slot == -1) 539deb53490SAlex Lorenz OS << "<badref>"; 540deb53490SAlex Lorenz else 541deb53490SAlex Lorenz OS << Slot; 542deb53490SAlex Lorenz } 543deb53490SAlex Lorenz 5444af7e610SAlex Lorenz void MIPrinter::printIRValueReference(const Value &V) { 5454af7e610SAlex Lorenz OS << "%ir."; 5464af7e610SAlex Lorenz if (V.hasName()) { 5474af7e610SAlex Lorenz printLLVMNameWithoutPrefix(OS, V.getName()); 5484af7e610SAlex Lorenz return; 5494af7e610SAlex Lorenz } 5504af7e610SAlex Lorenz // TODO: Serialize the unnamed IR value references. 5514af7e610SAlex Lorenz OS << "<unserializable ir value>"; 5524af7e610SAlex Lorenz } 5534af7e610SAlex Lorenz 5547feaf7c6SAlex Lorenz void MIPrinter::printStackObjectReference(int FrameIndex) { 5557feaf7c6SAlex Lorenz auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex); 5567feaf7c6SAlex Lorenz assert(ObjectInfo != StackObjectOperandMapping.end() && 5577feaf7c6SAlex Lorenz "Invalid frame index"); 5587feaf7c6SAlex Lorenz const FrameIndexOperand &Operand = ObjectInfo->second; 5597feaf7c6SAlex Lorenz if (Operand.IsFixed) { 5607feaf7c6SAlex Lorenz OS << "%fixed-stack." << Operand.ID; 5617feaf7c6SAlex Lorenz return; 5627feaf7c6SAlex Lorenz } 5637feaf7c6SAlex Lorenz OS << "%stack." << Operand.ID; 5647feaf7c6SAlex Lorenz if (!Operand.Name.empty()) 5657feaf7c6SAlex Lorenz OS << '.' << Operand.Name; 5667feaf7c6SAlex Lorenz } 5677feaf7c6SAlex Lorenz 5685672a893SAlex Lorenz void MIPrinter::printOffset(int64_t Offset) { 5695672a893SAlex Lorenz if (Offset == 0) 5705672a893SAlex Lorenz return; 5715672a893SAlex Lorenz if (Offset < 0) { 5725672a893SAlex Lorenz OS << " - " << -Offset; 5735672a893SAlex Lorenz return; 5745672a893SAlex Lorenz } 5755672a893SAlex Lorenz OS << " + " << Offset; 5765672a893SAlex Lorenz } 5775672a893SAlex Lorenz 57849873a83SAlex Lorenz static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) { 57949873a83SAlex Lorenz auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); 58049873a83SAlex Lorenz for (const auto &I : Flags) { 58149873a83SAlex Lorenz if (I.first == TF) { 58249873a83SAlex Lorenz return I.second; 58349873a83SAlex Lorenz } 58449873a83SAlex Lorenz } 58549873a83SAlex Lorenz return nullptr; 58649873a83SAlex Lorenz } 58749873a83SAlex Lorenz 58849873a83SAlex Lorenz void MIPrinter::printTargetFlags(const MachineOperand &Op) { 58949873a83SAlex Lorenz if (!Op.getTargetFlags()) 59049873a83SAlex Lorenz return; 59149873a83SAlex Lorenz const auto *TII = 59249873a83SAlex Lorenz Op.getParent()->getParent()->getParent()->getSubtarget().getInstrInfo(); 59349873a83SAlex Lorenz assert(TII && "expected instruction info"); 59449873a83SAlex Lorenz auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags()); 59549873a83SAlex Lorenz OS << "target-flags("; 59649873a83SAlex Lorenz if (const auto *Name = getTargetFlagName(TII, Flags.first)) 59749873a83SAlex Lorenz OS << Name; 59849873a83SAlex Lorenz else 59949873a83SAlex Lorenz OS << "<unknown target flag>"; 60049873a83SAlex Lorenz // TODO: Print the target's bit flags. 60149873a83SAlex Lorenz OS << ") "; 60249873a83SAlex Lorenz } 60349873a83SAlex Lorenz 604ef5c196fSAlex Lorenz static const char *getTargetIndexName(const MachineFunction &MF, int Index) { 605ef5c196fSAlex Lorenz const auto *TII = MF.getSubtarget().getInstrInfo(); 606ef5c196fSAlex Lorenz assert(TII && "expected instruction info"); 607ef5c196fSAlex Lorenz auto Indices = TII->getSerializableTargetIndices(); 608ef5c196fSAlex Lorenz for (const auto &I : Indices) { 609ef5c196fSAlex Lorenz if (I.first == Index) { 610ef5c196fSAlex Lorenz return I.second; 611ef5c196fSAlex Lorenz } 612ef5c196fSAlex Lorenz } 613ef5c196fSAlex Lorenz return nullptr; 614ef5c196fSAlex Lorenz } 615ef5c196fSAlex Lorenz 616f3db51deSAlex Lorenz void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { 61749873a83SAlex Lorenz printTargetFlags(Op); 618f3db51deSAlex Lorenz switch (Op.getType()) { 619f3db51deSAlex Lorenz case MachineOperand::MO_Register: 6201039fd1aSAlex Lorenz // FIXME: Serialize the tied register. 621cb268d46SAlex Lorenz if (Op.isImplicit()) 622cb268d46SAlex Lorenz OS << (Op.isDef() ? "implicit-def " : "implicit "); 6231039fd1aSAlex Lorenz if (Op.isInternalRead()) 6241039fd1aSAlex Lorenz OS << "internal "; 625cbbfd0b1SAlex Lorenz if (Op.isDead()) 626cbbfd0b1SAlex Lorenz OS << "dead "; 627495ad879SAlex Lorenz if (Op.isKill()) 628495ad879SAlex Lorenz OS << "killed "; 6294d026b89SAlex Lorenz if (Op.isUndef()) 6304d026b89SAlex Lorenz OS << "undef "; 63101c1a5eeSAlex Lorenz if (Op.isEarlyClobber()) 63201c1a5eeSAlex Lorenz OS << "early-clobber "; 6339075258bSAlex Lorenz if (Op.isDebug()) 6349075258bSAlex Lorenz OS << "debug-use "; 635f3db51deSAlex Lorenz printReg(Op.getReg(), OS, TRI); 6362eacca86SAlex Lorenz // Print the sub register. 6372eacca86SAlex Lorenz if (Op.getSubReg() != 0) 6382eacca86SAlex Lorenz OS << ':' << TRI->getSubRegIndexName(Op.getSubReg()); 639f3db51deSAlex Lorenz break; 640240fc1e0SAlex Lorenz case MachineOperand::MO_Immediate: 641240fc1e0SAlex Lorenz OS << Op.getImm(); 642240fc1e0SAlex Lorenz break; 64305e3882eSAlex Lorenz case MachineOperand::MO_CImmediate: 64405e3882eSAlex Lorenz Op.getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); 64505e3882eSAlex Lorenz break; 646ad156fb6SAlex Lorenz case MachineOperand::MO_FPImmediate: 647ad156fb6SAlex Lorenz Op.getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); 648ad156fb6SAlex Lorenz break; 64933f0aef3SAlex Lorenz case MachineOperand::MO_MachineBasicBlock: 6505d26fa83SAlex Lorenz printMBBReference(*Op.getMBB()); 65133f0aef3SAlex Lorenz break; 6527feaf7c6SAlex Lorenz case MachineOperand::MO_FrameIndex: 6537feaf7c6SAlex Lorenz printStackObjectReference(Op.getIndex()); 6547feaf7c6SAlex Lorenz break; 655ab980499SAlex Lorenz case MachineOperand::MO_ConstantPoolIndex: 656ab980499SAlex Lorenz OS << "%const." << Op.getIndex(); 6575672a893SAlex Lorenz printOffset(Op.getOffset()); 658ab980499SAlex Lorenz break; 659ef5c196fSAlex Lorenz case MachineOperand::MO_TargetIndex: { 660ef5c196fSAlex Lorenz OS << "target-index("; 661ef5c196fSAlex Lorenz if (const auto *Name = getTargetIndexName( 662ef5c196fSAlex Lorenz *Op.getParent()->getParent()->getParent(), Op.getIndex())) 663ef5c196fSAlex Lorenz OS << Name; 664ef5c196fSAlex Lorenz else 665ef5c196fSAlex Lorenz OS << "<unknown>"; 666ef5c196fSAlex Lorenz OS << ')'; 6675672a893SAlex Lorenz printOffset(Op.getOffset()); 668ef5c196fSAlex Lorenz break; 669ef5c196fSAlex Lorenz } 67031d70683SAlex Lorenz case MachineOperand::MO_JumpTableIndex: 67131d70683SAlex Lorenz OS << "%jump-table." << Op.getIndex(); 67231d70683SAlex Lorenz break; 6736ede3744SAlex Lorenz case MachineOperand::MO_ExternalSymbol: 6746ede3744SAlex Lorenz OS << '$'; 6756ede3744SAlex Lorenz printLLVMNameWithoutPrefix(OS, Op.getSymbolName()); 6765672a893SAlex Lorenz printOffset(Op.getOffset()); 6776ede3744SAlex Lorenz break; 6785d6108e4SAlex Lorenz case MachineOperand::MO_GlobalAddress: 679900b5cb2SAlex Lorenz Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 6805672a893SAlex Lorenz printOffset(Op.getOffset()); 6815d6108e4SAlex Lorenz break; 682deb53490SAlex Lorenz case MachineOperand::MO_BlockAddress: 683deb53490SAlex Lorenz OS << "blockaddress("; 684deb53490SAlex Lorenz Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, 685deb53490SAlex Lorenz MST); 686deb53490SAlex Lorenz OS << ", "; 687deb53490SAlex Lorenz printIRBlockReference(*Op.getBlockAddress()->getBasicBlock()); 688deb53490SAlex Lorenz OS << ')'; 6895672a893SAlex Lorenz printOffset(Op.getOffset()); 690deb53490SAlex Lorenz break; 6918f6f4285SAlex Lorenz case MachineOperand::MO_RegisterMask: { 6928f6f4285SAlex Lorenz auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask()); 6938f6f4285SAlex Lorenz if (RegMaskInfo != RegisterMaskIds.end()) 6948f6f4285SAlex Lorenz OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower(); 6958f6f4285SAlex Lorenz else 6968f6f4285SAlex Lorenz llvm_unreachable("Can't print this machine register mask yet."); 6978f6f4285SAlex Lorenz break; 6988f6f4285SAlex Lorenz } 699b97c9ef4SAlex Lorenz case MachineOperand::MO_RegisterLiveOut: { 700b97c9ef4SAlex Lorenz const uint32_t *RegMask = Op.getRegLiveOut(); 701b97c9ef4SAlex Lorenz OS << "liveout("; 702b97c9ef4SAlex Lorenz bool IsCommaNeeded = false; 703b97c9ef4SAlex Lorenz for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { 704b97c9ef4SAlex Lorenz if (RegMask[Reg / 32] & (1U << (Reg % 32))) { 705b97c9ef4SAlex Lorenz if (IsCommaNeeded) 706b97c9ef4SAlex Lorenz OS << ", "; 707b97c9ef4SAlex Lorenz printReg(Reg, OS, TRI); 708b97c9ef4SAlex Lorenz IsCommaNeeded = true; 709b97c9ef4SAlex Lorenz } 710b97c9ef4SAlex Lorenz } 711b97c9ef4SAlex Lorenz OS << ")"; 712b97c9ef4SAlex Lorenz break; 713b97c9ef4SAlex Lorenz } 71435e44469SAlex Lorenz case MachineOperand::MO_Metadata: 71535e44469SAlex Lorenz Op.getMetadata()->printAsOperand(OS, MST); 71635e44469SAlex Lorenz break; 717f4baeb51SAlex Lorenz case MachineOperand::MO_CFIIndex: { 718f4baeb51SAlex Lorenz const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI(); 7198cfc6867SAlex Lorenz print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI); 720f4baeb51SAlex Lorenz break; 721f4baeb51SAlex Lorenz } 722f3db51deSAlex Lorenz default: 723f3db51deSAlex Lorenz // TODO: Print the other machine operands. 724f3db51deSAlex Lorenz llvm_unreachable("Can't print this machine operand at the moment"); 725f3db51deSAlex Lorenz } 7264f093bf1SAlex Lorenz } 7274f093bf1SAlex Lorenz 7284af7e610SAlex Lorenz void MIPrinter::print(const MachineMemOperand &Op) { 7294af7e610SAlex Lorenz OS << '('; 730dc8de2a6SAlex Lorenz // TODO: Print operand's target specific flags. 731a518b796SAlex Lorenz if (Op.isVolatile()) 732a518b796SAlex Lorenz OS << "volatile "; 73310fd0385SAlex Lorenz if (Op.isNonTemporal()) 73410fd0385SAlex Lorenz OS << "non-temporal "; 735dc8de2a6SAlex Lorenz if (Op.isInvariant()) 736dc8de2a6SAlex Lorenz OS << "invariant "; 7374af7e610SAlex Lorenz if (Op.isLoad()) 7384af7e610SAlex Lorenz OS << "load "; 7394af7e610SAlex Lorenz else { 7404af7e610SAlex Lorenz assert(Op.isStore() && "Non load machine operand must be a store"); 7414af7e610SAlex Lorenz OS << "store "; 7424af7e610SAlex Lorenz } 7434af7e610SAlex Lorenz OS << Op.getSize() << (Op.isLoad() ? " from " : " into "); 74491097a3fSAlex Lorenz if (const Value *Val = Op.getValue()) { 7454af7e610SAlex Lorenz printIRValueReference(*Val); 74691097a3fSAlex Lorenz } else { 74791097a3fSAlex Lorenz const PseudoSourceValue *PVal = Op.getPseudoValue(); 74891097a3fSAlex Lorenz assert(PVal && "Expected a pseudo source value"); 74991097a3fSAlex Lorenz switch (PVal->kind()) { 75046e9558aSAlex Lorenz case PseudoSourceValue::Stack: 75146e9558aSAlex Lorenz OS << "stack"; 75246e9558aSAlex Lorenz break; 753d858f874SAlex Lorenz case PseudoSourceValue::GOT: 754d858f874SAlex Lorenz OS << "got"; 755d858f874SAlex Lorenz break; 7564be56e93SAlex Lorenz case PseudoSourceValue::JumpTable: 7574be56e93SAlex Lorenz OS << "jump-table"; 7584be56e93SAlex Lorenz break; 75991097a3fSAlex Lorenz case PseudoSourceValue::ConstantPool: 76091097a3fSAlex Lorenz OS << "constant-pool"; 76191097a3fSAlex Lorenz break; 7620cc671bfSAlex Lorenz case PseudoSourceValue::FixedStack: 7630cc671bfSAlex Lorenz printStackObjectReference( 7640cc671bfSAlex Lorenz cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex()); 7650cc671bfSAlex Lorenz break; 76650b826fbSAlex Lorenz case PseudoSourceValue::GlobalValueCallEntry: 76750b826fbSAlex Lorenz cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand( 76850b826fbSAlex Lorenz OS, /*PrintType=*/false, MST); 76950b826fbSAlex Lorenz break; 770c3ba7508SAlex Lorenz case PseudoSourceValue::ExternalSymbolCallEntry: 771c3ba7508SAlex Lorenz OS << '$'; 772c3ba7508SAlex Lorenz printLLVMNameWithoutPrefix( 773c3ba7508SAlex Lorenz OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol()); 77491097a3fSAlex Lorenz break; 77591097a3fSAlex Lorenz } 77691097a3fSAlex Lorenz } 77783127739SAlex Lorenz printOffset(Op.getOffset()); 77861420f79SAlex Lorenz if (Op.getBaseAlignment() != Op.getSize()) 77961420f79SAlex Lorenz OS << ", align " << Op.getBaseAlignment(); 7804af7e610SAlex Lorenz // TODO: Print the metadata attributes. 7814af7e610SAlex Lorenz OS << ')'; 7824af7e610SAlex Lorenz } 7834af7e610SAlex Lorenz 7848cfc6867SAlex Lorenz static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS, 7858cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 7868cfc6867SAlex Lorenz int Reg = TRI->getLLVMRegNum(DwarfReg, true); 7878cfc6867SAlex Lorenz if (Reg == -1) { 7888cfc6867SAlex Lorenz OS << "<badreg>"; 7898cfc6867SAlex Lorenz return; 7908cfc6867SAlex Lorenz } 7918cfc6867SAlex Lorenz printReg(Reg, OS, TRI); 7928cfc6867SAlex Lorenz } 7938cfc6867SAlex Lorenz 7948cfc6867SAlex Lorenz void MIPrinter::print(const MCCFIInstruction &CFI, 7958cfc6867SAlex Lorenz const TargetRegisterInfo *TRI) { 796f4baeb51SAlex Lorenz switch (CFI.getOperation()) { 797*577d271aSAlex Lorenz case MCCFIInstruction::OpSameValue: 798*577d271aSAlex Lorenz OS << ".cfi_same_value "; 799*577d271aSAlex Lorenz if (CFI.getLabel()) 800*577d271aSAlex Lorenz OS << "<mcsymbol> "; 801*577d271aSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 802*577d271aSAlex Lorenz break; 8038cfc6867SAlex Lorenz case MCCFIInstruction::OpOffset: 8048cfc6867SAlex Lorenz OS << ".cfi_offset "; 8058cfc6867SAlex Lorenz if (CFI.getLabel()) 8068cfc6867SAlex Lorenz OS << "<mcsymbol> "; 8078cfc6867SAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 8088cfc6867SAlex Lorenz OS << ", " << CFI.getOffset(); 8098cfc6867SAlex Lorenz break; 8105b0d5f6fSAlex Lorenz case MCCFIInstruction::OpDefCfaRegister: 8115b0d5f6fSAlex Lorenz OS << ".cfi_def_cfa_register "; 8125b0d5f6fSAlex Lorenz if (CFI.getLabel()) 8135b0d5f6fSAlex Lorenz OS << "<mcsymbol> "; 8145b0d5f6fSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 8155b0d5f6fSAlex Lorenz break; 816f4baeb51SAlex Lorenz case MCCFIInstruction::OpDefCfaOffset: 817f4baeb51SAlex Lorenz OS << ".cfi_def_cfa_offset "; 818f4baeb51SAlex Lorenz if (CFI.getLabel()) 819f4baeb51SAlex Lorenz OS << "<mcsymbol> "; 820f4baeb51SAlex Lorenz OS << CFI.getOffset(); 821f4baeb51SAlex Lorenz break; 822b139323fSAlex Lorenz case MCCFIInstruction::OpDefCfa: 823b139323fSAlex Lorenz OS << ".cfi_def_cfa "; 824b139323fSAlex Lorenz if (CFI.getLabel()) 825b139323fSAlex Lorenz OS << "<mcsymbol> "; 826b139323fSAlex Lorenz printCFIRegister(CFI.getRegister(), OS, TRI); 827b139323fSAlex Lorenz OS << ", " << CFI.getOffset(); 828b139323fSAlex Lorenz break; 829f4baeb51SAlex Lorenz default: 830f4baeb51SAlex Lorenz // TODO: Print the other CFI Operations. 831f4baeb51SAlex Lorenz OS << "<unserializable cfi operation>"; 832f4baeb51SAlex Lorenz break; 833f4baeb51SAlex Lorenz } 834f4baeb51SAlex Lorenz } 835f4baeb51SAlex Lorenz 836345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) { 837345c1449SAlex Lorenz yaml::Output Out(OS); 838345c1449SAlex Lorenz Out << const_cast<Module &>(M); 839345c1449SAlex Lorenz } 840345c1449SAlex Lorenz 841345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) { 842345c1449SAlex Lorenz MIRPrinter Printer(OS); 843345c1449SAlex Lorenz Printer.print(MF); 844345c1449SAlex Lorenz } 845