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" 17345c1449SAlex Lorenz #include "llvm/CodeGen/MachineFunction.h" 1854565cf0SAlex Lorenz #include "llvm/CodeGen/MachineRegisterInfo.h" 19345c1449SAlex Lorenz #include "llvm/CodeGen/MIRYamlMapping.h" 204f093bf1SAlex Lorenz #include "llvm/IR/BasicBlock.h" 21345c1449SAlex Lorenz #include "llvm/IR/Module.h" 22345c1449SAlex Lorenz #include "llvm/Support/MemoryBuffer.h" 23345c1449SAlex Lorenz #include "llvm/Support/raw_ostream.h" 24345c1449SAlex Lorenz #include "llvm/Support/YAMLTraits.h" 258e0a1b48SAlex Lorenz #include "llvm/Target/TargetInstrInfo.h" 268e0a1b48SAlex Lorenz #include "llvm/Target/TargetSubtargetInfo.h" 27345c1449SAlex Lorenz 28345c1449SAlex Lorenz using namespace llvm; 29345c1449SAlex Lorenz 30345c1449SAlex Lorenz namespace { 31345c1449SAlex Lorenz 32345c1449SAlex Lorenz /// This class prints out the machine functions using the MIR serialization 33345c1449SAlex Lorenz /// format. 34345c1449SAlex Lorenz class MIRPrinter { 35345c1449SAlex Lorenz raw_ostream &OS; 36345c1449SAlex Lorenz 37345c1449SAlex Lorenz public: 38345c1449SAlex Lorenz MIRPrinter(raw_ostream &OS) : OS(OS) {} 39345c1449SAlex Lorenz 40345c1449SAlex Lorenz void print(const MachineFunction &MF); 414f093bf1SAlex Lorenz 4254565cf0SAlex Lorenz void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo); 434f093bf1SAlex Lorenz void convert(yaml::MachineBasicBlock &YamlMBB, const MachineBasicBlock &MBB); 44345c1449SAlex Lorenz }; 45345c1449SAlex Lorenz 468e0a1b48SAlex Lorenz /// This class prints out the machine instructions using the MIR serialization 478e0a1b48SAlex Lorenz /// format. 488e0a1b48SAlex Lorenz class MIPrinter { 498e0a1b48SAlex Lorenz raw_ostream &OS; 508e0a1b48SAlex Lorenz 518e0a1b48SAlex Lorenz public: 528e0a1b48SAlex Lorenz MIPrinter(raw_ostream &OS) : OS(OS) {} 538e0a1b48SAlex Lorenz 548e0a1b48SAlex Lorenz void print(const MachineInstr &MI); 55f3db51deSAlex Lorenz void print(const MachineOperand &Op, const TargetRegisterInfo *TRI); 568e0a1b48SAlex Lorenz }; 578e0a1b48SAlex Lorenz 58345c1449SAlex Lorenz } // end anonymous namespace 59345c1449SAlex Lorenz 60345c1449SAlex Lorenz namespace llvm { 61345c1449SAlex Lorenz namespace yaml { 62345c1449SAlex Lorenz 63345c1449SAlex Lorenz /// This struct serializes the LLVM IR module. 64345c1449SAlex Lorenz template <> struct BlockScalarTraits<Module> { 65345c1449SAlex Lorenz static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) { 66345c1449SAlex Lorenz Mod.print(OS, nullptr); 67345c1449SAlex Lorenz } 68345c1449SAlex Lorenz static StringRef input(StringRef Str, void *Ctxt, Module &Mod) { 69345c1449SAlex Lorenz llvm_unreachable("LLVM Module is supposed to be parsed separately"); 70345c1449SAlex Lorenz return ""; 71345c1449SAlex Lorenz } 72345c1449SAlex Lorenz }; 73345c1449SAlex Lorenz 74345c1449SAlex Lorenz } // end namespace yaml 75345c1449SAlex Lorenz } // end namespace llvm 76345c1449SAlex Lorenz 77345c1449SAlex Lorenz void MIRPrinter::print(const MachineFunction &MF) { 78345c1449SAlex Lorenz yaml::MachineFunction YamlMF; 79345c1449SAlex Lorenz YamlMF.Name = MF.getName(); 805b5f9753SAlex Lorenz YamlMF.Alignment = MF.getAlignment(); 815b5f9753SAlex Lorenz YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice(); 825b5f9753SAlex Lorenz YamlMF.HasInlineAsm = MF.hasInlineAsm(); 8354565cf0SAlex Lorenz convert(YamlMF, MF.getRegInfo()); 84*33f0aef3SAlex Lorenz 85*33f0aef3SAlex Lorenz int I = 0; 864f093bf1SAlex Lorenz for (const auto &MBB : MF) { 87*33f0aef3SAlex Lorenz // TODO: Allow printing of non sequentially numbered MBBs. 88*33f0aef3SAlex Lorenz // This is currently needed as the basic block references get their index 89*33f0aef3SAlex Lorenz // from MBB.getNumber(), thus it should be sequential so that the parser can 90*33f0aef3SAlex Lorenz // map back to the correct MBBs when parsing the output. 91*33f0aef3SAlex Lorenz assert(MBB.getNumber() == I++ && 92*33f0aef3SAlex Lorenz "Can't print MBBs that aren't sequentially numbered"); 934f093bf1SAlex Lorenz yaml::MachineBasicBlock YamlMBB; 944f093bf1SAlex Lorenz convert(YamlMBB, MBB); 954f093bf1SAlex Lorenz YamlMF.BasicBlocks.push_back(YamlMBB); 964f093bf1SAlex Lorenz } 97345c1449SAlex Lorenz yaml::Output Out(OS); 98345c1449SAlex Lorenz Out << YamlMF; 99345c1449SAlex Lorenz } 100345c1449SAlex Lorenz 10154565cf0SAlex Lorenz void MIRPrinter::convert(yaml::MachineFunction &MF, 10254565cf0SAlex Lorenz const MachineRegisterInfo &RegInfo) { 10354565cf0SAlex Lorenz MF.IsSSA = RegInfo.isSSA(); 10454565cf0SAlex Lorenz MF.TracksRegLiveness = RegInfo.tracksLiveness(); 10554565cf0SAlex Lorenz MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled(); 10654565cf0SAlex Lorenz } 10754565cf0SAlex Lorenz 1084f093bf1SAlex Lorenz void MIRPrinter::convert(yaml::MachineBasicBlock &YamlMBB, 1094f093bf1SAlex Lorenz const MachineBasicBlock &MBB) { 110*33f0aef3SAlex Lorenz assert(MBB.getNumber() >= 0 && "Invalid MBB number"); 111*33f0aef3SAlex Lorenz YamlMBB.ID = (unsigned)MBB.getNumber(); 1124f093bf1SAlex Lorenz // TODO: Serialize unnamed BB references. 1134f093bf1SAlex Lorenz if (const auto *BB = MBB.getBasicBlock()) 1144f093bf1SAlex Lorenz YamlMBB.Name = BB->hasName() ? BB->getName() : "<unnamed bb>"; 1154f093bf1SAlex Lorenz else 1164f093bf1SAlex Lorenz YamlMBB.Name = ""; 1174f093bf1SAlex Lorenz YamlMBB.Alignment = MBB.getAlignment(); 1184f093bf1SAlex Lorenz YamlMBB.AddressTaken = MBB.hasAddressTaken(); 1194f093bf1SAlex Lorenz YamlMBB.IsLandingPad = MBB.isLandingPad(); 1208e0a1b48SAlex Lorenz 1218e0a1b48SAlex Lorenz // Print the machine instructions. 1228e0a1b48SAlex Lorenz YamlMBB.Instructions.reserve(MBB.size()); 1238e0a1b48SAlex Lorenz std::string Str; 1248e0a1b48SAlex Lorenz for (const auto &MI : MBB) { 1258e0a1b48SAlex Lorenz raw_string_ostream StrOS(Str); 1268e0a1b48SAlex Lorenz MIPrinter(StrOS).print(MI); 1278e0a1b48SAlex Lorenz YamlMBB.Instructions.push_back(StrOS.str()); 1288e0a1b48SAlex Lorenz Str.clear(); 1298e0a1b48SAlex Lorenz } 1308e0a1b48SAlex Lorenz } 1318e0a1b48SAlex Lorenz 1328e0a1b48SAlex Lorenz void MIPrinter::print(const MachineInstr &MI) { 1338e0a1b48SAlex Lorenz const auto &SubTarget = MI.getParent()->getParent()->getSubtarget(); 134f3db51deSAlex Lorenz const auto *TRI = SubTarget.getRegisterInfo(); 135f3db51deSAlex Lorenz assert(TRI && "Expected target register info"); 1368e0a1b48SAlex Lorenz const auto *TII = SubTarget.getInstrInfo(); 1378e0a1b48SAlex Lorenz assert(TII && "Expected target instruction info"); 1388e0a1b48SAlex Lorenz 139f3db51deSAlex Lorenz unsigned I = 0, E = MI.getNumOperands(); 140f3db51deSAlex Lorenz for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() && 141f3db51deSAlex Lorenz !MI.getOperand(I).isImplicit(); 142f3db51deSAlex Lorenz ++I) { 143f3db51deSAlex Lorenz if (I) 144f3db51deSAlex Lorenz OS << ", "; 145f3db51deSAlex Lorenz print(MI.getOperand(I), TRI); 146f3db51deSAlex Lorenz } 147f3db51deSAlex Lorenz 148f3db51deSAlex Lorenz if (I) 149f3db51deSAlex Lorenz OS << " = "; 1508e0a1b48SAlex Lorenz OS << TII->getName(MI.getOpcode()); 151f3db51deSAlex Lorenz // TODO: Print the instruction flags, machine mem operands. 152f3db51deSAlex Lorenz if (I < E) 153f3db51deSAlex Lorenz OS << ' '; 154f3db51deSAlex Lorenz 155f3db51deSAlex Lorenz bool NeedComma = false; 156f3db51deSAlex Lorenz for (; I < E; ++I) { 157f3db51deSAlex Lorenz if (NeedComma) 158f3db51deSAlex Lorenz OS << ", "; 159f3db51deSAlex Lorenz print(MI.getOperand(I), TRI); 160f3db51deSAlex Lorenz NeedComma = true; 161f3db51deSAlex Lorenz } 162f3db51deSAlex Lorenz } 163f3db51deSAlex Lorenz 164f3db51deSAlex Lorenz static void printReg(unsigned Reg, raw_ostream &OS, 165f3db51deSAlex Lorenz const TargetRegisterInfo *TRI) { 166f3db51deSAlex Lorenz // TODO: Print Stack Slots. 167f3db51deSAlex Lorenz // TODO: Print virtual registers. 16812b554e6SAlex Lorenz if (!Reg) 16912b554e6SAlex Lorenz OS << '_'; 17012b554e6SAlex Lorenz else if (Reg < TRI->getNumRegs()) 171f3db51deSAlex Lorenz OS << '%' << StringRef(TRI->getName(Reg)).lower(); 172f3db51deSAlex Lorenz else 173f3db51deSAlex Lorenz llvm_unreachable("Can't print this kind of register yet"); 174f3db51deSAlex Lorenz } 175f3db51deSAlex Lorenz 176f3db51deSAlex Lorenz void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { 177f3db51deSAlex Lorenz switch (Op.getType()) { 178f3db51deSAlex Lorenz case MachineOperand::MO_Register: 179f3db51deSAlex Lorenz // TODO: Print register flags. 180f3db51deSAlex Lorenz printReg(Op.getReg(), OS, TRI); 181f3db51deSAlex Lorenz // TODO: Print sub register. 182f3db51deSAlex Lorenz break; 183240fc1e0SAlex Lorenz case MachineOperand::MO_Immediate: 184240fc1e0SAlex Lorenz OS << Op.getImm(); 185240fc1e0SAlex Lorenz break; 186*33f0aef3SAlex Lorenz case MachineOperand::MO_MachineBasicBlock: 187*33f0aef3SAlex Lorenz OS << "%bb." << Op.getMBB()->getNumber(); 188*33f0aef3SAlex Lorenz if (const auto *BB = Op.getMBB()->getBasicBlock()) { 189*33f0aef3SAlex Lorenz if (BB->hasName()) 190*33f0aef3SAlex Lorenz OS << '.' << BB->getName(); 191*33f0aef3SAlex Lorenz } 192*33f0aef3SAlex Lorenz break; 193f3db51deSAlex Lorenz default: 194f3db51deSAlex Lorenz // TODO: Print the other machine operands. 195f3db51deSAlex Lorenz llvm_unreachable("Can't print this machine operand at the moment"); 196f3db51deSAlex Lorenz } 1974f093bf1SAlex Lorenz } 1984f093bf1SAlex Lorenz 199345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const Module &M) { 200345c1449SAlex Lorenz yaml::Output Out(OS); 201345c1449SAlex Lorenz Out << const_cast<Module &>(M); 202345c1449SAlex Lorenz } 203345c1449SAlex Lorenz 204345c1449SAlex Lorenz void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) { 205345c1449SAlex Lorenz MIRPrinter Printer(OS); 206345c1449SAlex Lorenz Printer.print(MF); 207345c1449SAlex Lorenz } 208