blob: ac37e323487353408bd5058cc650d3d9bd7e73c7 [file] [log] [blame]
Alex Lorenz345c1442015-06-15 23:52:35 +00001//===- MIRPrinter.cpp - MIR serialization format printer ------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the class that prints out the LLVM IR and machine
11// functions using the MIR serialization format.
12//
13//===----------------------------------------------------------------------===//
14
15#include "MIRPrinter.h"
16#include "llvm/ADT/STLExtras.h"
Alex Lorenzab980492015-07-20 20:51:18 +000017#include "llvm/CodeGen/MachineConstantPool.h"
Alex Lorenz345c1442015-06-15 23:52:35 +000018#include "llvm/CodeGen/MachineFunction.h"
Alex Lorenz60541c12015-07-09 19:55:27 +000019#include "llvm/CodeGen/MachineFrameInfo.h"
Alex Lorenzf4baeb52015-07-21 22:28:27 +000020#include "llvm/CodeGen/MachineModuleInfo.h"
Alex Lorenz54565cf2015-06-24 19:56:10 +000021#include "llvm/CodeGen/MachineRegisterInfo.h"
Alex Lorenz345c1442015-06-15 23:52:35 +000022#include "llvm/CodeGen/MIRYamlMapping.h"
Alex Lorenz4f093bf2015-06-19 17:43:07 +000023#include "llvm/IR/BasicBlock.h"
Alex Lorenz37643a02015-07-15 22:14:49 +000024#include "llvm/IR/Instructions.h"
Alex Lorenz6ede3742015-07-21 16:59:53 +000025#include "llvm/IR/IRPrintingPasses.h"
Alex Lorenz345c1442015-06-15 23:52:35 +000026#include "llvm/IR/Module.h"
Alex Lorenz900b5cb2015-07-07 23:27:53 +000027#include "llvm/IR/ModuleSlotTracker.h"
Alex Lorenz345c1442015-06-15 23:52:35 +000028#include "llvm/Support/MemoryBuffer.h"
29#include "llvm/Support/raw_ostream.h"
30#include "llvm/Support/YAMLTraits.h"
Alex Lorenz8e0a1b42015-06-22 17:02:30 +000031#include "llvm/Target/TargetInstrInfo.h"
32#include "llvm/Target/TargetSubtargetInfo.h"
Alex Lorenz345c1442015-06-15 23:52:35 +000033
34using namespace llvm;
35
36namespace {
37
Alex Lorenz7feaf7c2015-07-16 23:37:45 +000038/// This structure describes how to print out stack object references.
39struct FrameIndexOperand {
40 std::string Name;
41 unsigned ID;
42 bool IsFixed;
43
44 FrameIndexOperand(StringRef Name, unsigned ID, bool IsFixed)
45 : Name(Name.str()), ID(ID), IsFixed(IsFixed) {}
46
47 /// Return an ordinary stack object reference.
48 static FrameIndexOperand create(StringRef Name, unsigned ID) {
49 return FrameIndexOperand(Name, ID, /*IsFixed=*/false);
50 }
51
52 /// Return a fixed stack object reference.
53 static FrameIndexOperand createFixed(unsigned ID) {
54 return FrameIndexOperand("", ID, /*IsFixed=*/true);
55 }
56};
57
Alex Lorenz345c1442015-06-15 23:52:35 +000058/// This class prints out the machine functions using the MIR serialization
59/// format.
60class MIRPrinter {
61 raw_ostream &OS;
Alex Lorenz8f6f4282015-06-29 16:57:06 +000062 DenseMap<const uint32_t *, unsigned> RegisterMaskIds;
Alex Lorenz7feaf7c2015-07-16 23:37:45 +000063 /// Maps from stack object indices to operand indices which will be used when
64 /// printing frame index machine operands.
65 DenseMap<int, FrameIndexOperand> StackObjectOperandMapping;
Alex Lorenz345c1442015-06-15 23:52:35 +000066
67public:
68 MIRPrinter(raw_ostream &OS) : OS(OS) {}
69
70 void print(const MachineFunction &MF);
Alex Lorenz4f093bf2015-06-19 17:43:07 +000071
Alex Lorenz28148ba2015-07-09 22:23:13 +000072 void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo,
73 const TargetRegisterInfo *TRI);
Alex Lorenz60541c12015-07-09 19:55:27 +000074 void convert(yaml::MachineFrameInfo &YamlMFI, const MachineFrameInfo &MFI);
Alex Lorenzab980492015-07-20 20:51:18 +000075 void convert(yaml::MachineFunction &MF,
76 const MachineConstantPool &ConstantPool);
Alex Lorenz6799e9b2015-07-15 23:31:07 +000077 void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
78 const MachineJumpTableInfo &JTI);
Alex Lorenz900b5cb2015-07-07 23:27:53 +000079 void convert(ModuleSlotTracker &MST, yaml::MachineBasicBlock &YamlMBB,
Alex Lorenz5d6108e2015-06-26 22:56:48 +000080 const MachineBasicBlock &MBB);
Alex Lorenzf6bc8662015-07-10 18:13:57 +000081 void convertStackObjects(yaml::MachineFunction &MF,
Alex Lorenz1bb48de2015-07-24 22:22:50 +000082 const MachineFrameInfo &MFI,
83 const TargetRegisterInfo *TRI);
Alex Lorenz8f6f4282015-06-29 16:57:06 +000084
85private:
86 void initRegisterMaskIds(const MachineFunction &MF);
Alex Lorenz345c1442015-06-15 23:52:35 +000087};
88
Alex Lorenz8e0a1b42015-06-22 17:02:30 +000089/// This class prints out the machine instructions using the MIR serialization
90/// format.
91class MIPrinter {
92 raw_ostream &OS;
Alex Lorenz900b5cb2015-07-07 23:27:53 +000093 ModuleSlotTracker &MST;
Alex Lorenz8f6f4282015-06-29 16:57:06 +000094 const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
Alex Lorenz7feaf7c2015-07-16 23:37:45 +000095 const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping;
Alex Lorenz8e0a1b42015-06-22 17:02:30 +000096
97public:
Alex Lorenz900b5cb2015-07-07 23:27:53 +000098 MIPrinter(raw_ostream &OS, ModuleSlotTracker &MST,
Alex Lorenz7feaf7c2015-07-16 23:37:45 +000099 const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds,
100 const DenseMap<int, FrameIndexOperand> &StackObjectOperandMapping)
101 : OS(OS), MST(MST), RegisterMaskIds(RegisterMaskIds),
102 StackObjectOperandMapping(StackObjectOperandMapping) {}
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000103
104 void print(const MachineInstr &MI);
Alex Lorenz5d26fa82015-06-30 18:00:16 +0000105 void printMBBReference(const MachineBasicBlock &MBB);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000106 void printStackObjectReference(int FrameIndex);
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000107 void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000108
Alex Lorenz8cfc6862015-07-23 23:09:07 +0000109 void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI);
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000110};
111
Alex Lorenz345c1442015-06-15 23:52:35 +0000112} // end anonymous namespace
113
114namespace llvm {
115namespace yaml {
116
117/// This struct serializes the LLVM IR module.
118template <> struct BlockScalarTraits<Module> {
119 static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
120 Mod.print(OS, nullptr);
121 }
122 static StringRef input(StringRef Str, void *Ctxt, Module &Mod) {
123 llvm_unreachable("LLVM Module is supposed to be parsed separately");
124 return "";
125 }
126};
127
128} // end namespace yaml
129} // end namespace llvm
130
Alex Lorenz15a00a82015-07-14 21:18:25 +0000131static void printReg(unsigned Reg, raw_ostream &OS,
132 const TargetRegisterInfo *TRI) {
133 // TODO: Print Stack Slots.
134 if (!Reg)
135 OS << '_';
136 else if (TargetRegisterInfo::isVirtualRegister(Reg))
137 OS << '%' << TargetRegisterInfo::virtReg2Index(Reg);
138 else if (Reg < TRI->getNumRegs())
139 OS << '%' << StringRef(TRI->getName(Reg)).lower();
140 else
141 llvm_unreachable("Can't print this kind of register yet");
142}
143
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000144static void printReg(unsigned Reg, yaml::StringValue &Dest,
145 const TargetRegisterInfo *TRI) {
146 raw_string_ostream OS(Dest.Value);
147 printReg(Reg, OS, TRI);
148}
149
Alex Lorenz345c1442015-06-15 23:52:35 +0000150void MIRPrinter::print(const MachineFunction &MF) {
Alex Lorenz8f6f4282015-06-29 16:57:06 +0000151 initRegisterMaskIds(MF);
152
Alex Lorenz345c1442015-06-15 23:52:35 +0000153 yaml::MachineFunction YamlMF;
154 YamlMF.Name = MF.getName();
Alex Lorenz5b5f9752015-06-16 00:10:47 +0000155 YamlMF.Alignment = MF.getAlignment();
156 YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
157 YamlMF.HasInlineAsm = MF.hasInlineAsm();
Alex Lorenz28148ba2015-07-09 22:23:13 +0000158 convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
Alex Lorenz60541c12015-07-09 19:55:27 +0000159 convert(YamlMF.FrameInfo, *MF.getFrameInfo());
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000160 convertStackObjects(YamlMF, *MF.getFrameInfo(),
161 MF.getSubtarget().getRegisterInfo());
Alex Lorenzab980492015-07-20 20:51:18 +0000162 if (const auto *ConstantPool = MF.getConstantPool())
163 convert(YamlMF, *ConstantPool);
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000164
Alex Lorenz900b5cb2015-07-07 23:27:53 +0000165 ModuleSlotTracker MST(MF.getFunction()->getParent());
Alex Lorenz8a1915b2015-07-27 22:42:41 +0000166 MST.incorporateFunction(*MF.getFunction());
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000167 if (const auto *JumpTableInfo = MF.getJumpTableInfo())
168 convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo);
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000169 for (const auto &MBB : MF) {
170 yaml::MachineBasicBlock YamlMBB;
Alex Lorenz900b5cb2015-07-07 23:27:53 +0000171 convert(MST, YamlMBB, MBB);
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000172 YamlMF.BasicBlocks.push_back(YamlMBB);
173 }
Alex Lorenz345c1442015-06-15 23:52:35 +0000174 yaml::Output Out(OS);
175 Out << YamlMF;
176}
177
Alex Lorenz54565cf2015-06-24 19:56:10 +0000178void MIRPrinter::convert(yaml::MachineFunction &MF,
Alex Lorenz28148ba2015-07-09 22:23:13 +0000179 const MachineRegisterInfo &RegInfo,
180 const TargetRegisterInfo *TRI) {
Alex Lorenz54565cf2015-06-24 19:56:10 +0000181 MF.IsSSA = RegInfo.isSSA();
182 MF.TracksRegLiveness = RegInfo.tracksLiveness();
183 MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled();
Alex Lorenz28148ba2015-07-09 22:23:13 +0000184
185 // Print the virtual register definitions.
186 for (unsigned I = 0, E = RegInfo.getNumVirtRegs(); I < E; ++I) {
187 unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
188 yaml::VirtualRegisterDefinition VReg;
189 VReg.ID = I;
190 VReg.Class =
191 StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower();
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000192 unsigned PreferredReg = RegInfo.getSimpleHint(Reg);
193 if (PreferredReg)
194 printReg(PreferredReg, VReg.PreferredRegister, TRI);
Alex Lorenz28148ba2015-07-09 22:23:13 +0000195 MF.VirtualRegisters.push_back(VReg);
196 }
Alex Lorenz12045a42015-07-27 17:42:45 +0000197
198 // Print the live ins.
199 for (auto I = RegInfo.livein_begin(), E = RegInfo.livein_end(); I != E; ++I) {
200 yaml::MachineFunctionLiveIn LiveIn;
201 printReg(I->first, LiveIn.Register, TRI);
202 if (I->second)
203 printReg(I->second, LiveIn.VirtualRegister, TRI);
204 MF.LiveIns.push_back(LiveIn);
205 }
Alex Lorenz54565cf2015-06-24 19:56:10 +0000206}
207
Alex Lorenz60541c12015-07-09 19:55:27 +0000208void MIRPrinter::convert(yaml::MachineFrameInfo &YamlMFI,
209 const MachineFrameInfo &MFI) {
210 YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
211 YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
212 YamlMFI.HasStackMap = MFI.hasStackMap();
213 YamlMFI.HasPatchPoint = MFI.hasPatchPoint();
214 YamlMFI.StackSize = MFI.getStackSize();
215 YamlMFI.OffsetAdjustment = MFI.getOffsetAdjustment();
216 YamlMFI.MaxAlignment = MFI.getMaxAlignment();
217 YamlMFI.AdjustsStack = MFI.adjustsStack();
218 YamlMFI.HasCalls = MFI.hasCalls();
219 YamlMFI.MaxCallFrameSize = MFI.getMaxCallFrameSize();
220 YamlMFI.HasOpaqueSPAdjustment = MFI.hasOpaqueSPAdjustment();
221 YamlMFI.HasVAStart = MFI.hasVAStart();
222 YamlMFI.HasMustTailInVarArgFunc = MFI.hasMustTailInVarArgFunc();
223}
224
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000225void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000226 const MachineFrameInfo &MFI,
227 const TargetRegisterInfo *TRI) {
Alex Lorenzde491f02015-07-13 18:07:26 +0000228 // Process fixed stack objects.
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000229 unsigned ID = 0;
Alex Lorenzde491f02015-07-13 18:07:26 +0000230 for (int I = MFI.getObjectIndexBegin(); I < 0; ++I) {
231 if (MFI.isDeadObjectIndex(I))
232 continue;
233
234 yaml::FixedMachineStackObject YamlObject;
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000235 YamlObject.ID = ID;
Alex Lorenzde491f02015-07-13 18:07:26 +0000236 YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
237 ? yaml::FixedMachineStackObject::SpillSlot
238 : yaml::FixedMachineStackObject::DefaultType;
239 YamlObject.Offset = MFI.getObjectOffset(I);
240 YamlObject.Size = MFI.getObjectSize(I);
241 YamlObject.Alignment = MFI.getObjectAlignment(I);
242 YamlObject.IsImmutable = MFI.isImmutableObjectIndex(I);
243 YamlObject.IsAliased = MFI.isAliasedObjectIndex(I);
244 MF.FixedStackObjects.push_back(YamlObject);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000245 StackObjectOperandMapping.insert(
246 std::make_pair(I, FrameIndexOperand::createFixed(ID++)));
Alex Lorenzde491f02015-07-13 18:07:26 +0000247 }
248
249 // Process ordinary stack objects.
250 ID = 0;
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000251 for (int I = 0, E = MFI.getObjectIndexEnd(); I < E; ++I) {
252 if (MFI.isDeadObjectIndex(I))
253 continue;
254
255 yaml::MachineStackObject YamlObject;
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000256 YamlObject.ID = ID;
Alex Lorenz37643a02015-07-15 22:14:49 +0000257 if (const auto *Alloca = MFI.getObjectAllocation(I))
258 YamlObject.Name.Value =
259 Alloca->hasName() ? Alloca->getName() : "<unnamed alloca>";
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000260 YamlObject.Type = MFI.isSpillSlotObjectIndex(I)
261 ? yaml::MachineStackObject::SpillSlot
Alex Lorenz418f3ec2015-07-14 00:26:26 +0000262 : MFI.isVariableSizedObjectIndex(I)
263 ? yaml::MachineStackObject::VariableSized
264 : yaml::MachineStackObject::DefaultType;
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000265 YamlObject.Offset = MFI.getObjectOffset(I);
266 YamlObject.Size = MFI.getObjectSize(I);
267 YamlObject.Alignment = MFI.getObjectAlignment(I);
268
269 MF.StackObjects.push_back(YamlObject);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000270 StackObjectOperandMapping.insert(std::make_pair(
271 I, FrameIndexOperand::create(YamlObject.Name.Value, ID++)));
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000272 }
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000273
274 for (const auto &CSInfo : MFI.getCalleeSavedInfo()) {
275 yaml::StringValue Reg;
276 printReg(CSInfo.getReg(), Reg, TRI);
277 auto StackObjectInfo = StackObjectOperandMapping.find(CSInfo.getFrameIdx());
278 assert(StackObjectInfo != StackObjectOperandMapping.end() &&
279 "Invalid stack object index");
280 const FrameIndexOperand &StackObject = StackObjectInfo->second;
281 if (StackObject.IsFixed)
282 MF.FixedStackObjects[StackObject.ID].CalleeSavedRegister = Reg;
283 else
284 MF.StackObjects[StackObject.ID].CalleeSavedRegister = Reg;
285 }
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000286}
287
Alex Lorenzab980492015-07-20 20:51:18 +0000288void MIRPrinter::convert(yaml::MachineFunction &MF,
289 const MachineConstantPool &ConstantPool) {
290 unsigned ID = 0;
291 for (const MachineConstantPoolEntry &Constant : ConstantPool.getConstants()) {
292 // TODO: Serialize target specific constant pool entries.
293 if (Constant.isMachineConstantPoolEntry())
294 llvm_unreachable("Can't print target specific constant pool entries yet");
295
296 yaml::MachineConstantPoolValue YamlConstant;
297 std::string Str;
298 raw_string_ostream StrOS(Str);
299 Constant.Val.ConstVal->printAsOperand(StrOS);
300 YamlConstant.ID = ID++;
301 YamlConstant.Value = StrOS.str();
302 YamlConstant.Alignment = Constant.getAlignment();
303 MF.Constants.push_back(YamlConstant);
304 }
305}
306
Alex Lorenz900b5cb2015-07-07 23:27:53 +0000307void MIRPrinter::convert(ModuleSlotTracker &MST,
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000308 yaml::MachineJumpTable &YamlJTI,
309 const MachineJumpTableInfo &JTI) {
310 YamlJTI.Kind = JTI.getEntryKind();
311 unsigned ID = 0;
312 for (const auto &Table : JTI.getJumpTables()) {
313 std::string Str;
314 yaml::MachineJumpTable::Entry Entry;
315 Entry.ID = ID++;
316 for (const auto *MBB : Table.MBBs) {
317 raw_string_ostream StrOS(Str);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000318 MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
319 .printMBBReference(*MBB);
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000320 Entry.Blocks.push_back(StrOS.str());
321 Str.clear();
322 }
323 YamlJTI.Entries.push_back(Entry);
324 }
325}
326
327void MIRPrinter::convert(ModuleSlotTracker &MST,
Alex Lorenz900b5cb2015-07-07 23:27:53 +0000328 yaml::MachineBasicBlock &YamlMBB,
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000329 const MachineBasicBlock &MBB) {
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000330 assert(MBB.getNumber() >= 0 && "Invalid MBB number");
331 YamlMBB.ID = (unsigned)MBB.getNumber();
Alex Lorenz8a1915b2015-07-27 22:42:41 +0000332 if (const auto *BB = MBB.getBasicBlock()) {
333 if (BB->hasName()) {
334 YamlMBB.Name.Value = BB->getName();
335 } else {
336 int Slot = MST.getLocalSlot(BB);
337 if (Slot == -1)
338 YamlMBB.IRBlock.Value = "<badref>";
339 else
340 YamlMBB.IRBlock.Value = (Twine("%ir-block.") + Twine(Slot)).str();
341 }
342 }
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000343 YamlMBB.Alignment = MBB.getAlignment();
344 YamlMBB.AddressTaken = MBB.hasAddressTaken();
345 YamlMBB.IsLandingPad = MBB.isLandingPad();
Alex Lorenzeb5112b2015-06-30 18:32:02 +0000346 for (const auto *SuccMBB : MBB.successors()) {
Alex Lorenzf09df002015-06-30 18:16:42 +0000347 std::string Str;
348 raw_string_ostream StrOS(Str);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000349 MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
350 .printMBBReference(*SuccMBB);
Alex Lorenzf09df002015-06-30 18:16:42 +0000351 YamlMBB.Successors.push_back(StrOS.str());
352 }
Alex Lorenz9fab3702015-07-14 21:24:41 +0000353 // Print the live in registers.
354 const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
355 assert(TRI && "Expected target register info");
356 for (auto I = MBB.livein_begin(), E = MBB.livein_end(); I != E; ++I) {
357 std::string Str;
358 raw_string_ostream StrOS(Str);
359 printReg(*I, StrOS, TRI);
360 YamlMBB.LiveIns.push_back(StrOS.str());
361 }
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000362 // Print the machine instructions.
363 YamlMBB.Instructions.reserve(MBB.size());
364 std::string Str;
365 for (const auto &MI : MBB) {
366 raw_string_ostream StrOS(Str);
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000367 MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping).print(MI);
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000368 YamlMBB.Instructions.push_back(StrOS.str());
369 Str.clear();
370 }
371}
372
Alex Lorenz8f6f4282015-06-29 16:57:06 +0000373void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
374 const auto *TRI = MF.getSubtarget().getRegisterInfo();
375 unsigned I = 0;
376 for (const uint32_t *Mask : TRI->getRegMasks())
377 RegisterMaskIds.insert(std::make_pair(Mask, I++));
378}
379
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000380void MIPrinter::print(const MachineInstr &MI) {
381 const auto &SubTarget = MI.getParent()->getParent()->getSubtarget();
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000382 const auto *TRI = SubTarget.getRegisterInfo();
383 assert(TRI && "Expected target register info");
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000384 const auto *TII = SubTarget.getInstrInfo();
385 assert(TII && "Expected target instruction info");
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000386 if (MI.isCFIInstruction())
387 assert(MI.getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000388
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000389 unsigned I = 0, E = MI.getNumOperands();
390 for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
391 !MI.getOperand(I).isImplicit();
392 ++I) {
393 if (I)
394 OS << ", ";
395 print(MI.getOperand(I), TRI);
396 }
397
398 if (I)
399 OS << " = ";
Alex Lorenze5a44662015-07-17 00:24:15 +0000400 if (MI.getFlag(MachineInstr::FrameSetup))
401 OS << "frame-setup ";
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000402 OS << TII->getName(MI.getOpcode());
Alex Lorenze5a44662015-07-17 00:24:15 +0000403 // TODO: Print the bundling instruction flags, machine mem operands.
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000404 if (I < E)
405 OS << ' ';
406
407 bool NeedComma = false;
408 for (; I < E; ++I) {
409 if (NeedComma)
410 OS << ", ";
411 print(MI.getOperand(I), TRI);
412 NeedComma = true;
413 }
Alex Lorenz46d760d2015-07-22 21:15:11 +0000414
415 if (MI.getDebugLoc()) {
416 if (NeedComma)
417 OS << ',';
418 OS << " debug-location ";
419 MI.getDebugLoc()->printAsOperand(OS, MST);
420 }
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000421}
422
Alex Lorenz5d26fa82015-06-30 18:00:16 +0000423void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) {
424 OS << "%bb." << MBB.getNumber();
425 if (const auto *BB = MBB.getBasicBlock()) {
426 if (BB->hasName())
427 OS << '.' << BB->getName();
428 }
429}
430
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000431void MIPrinter::printStackObjectReference(int FrameIndex) {
432 auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
433 assert(ObjectInfo != StackObjectOperandMapping.end() &&
434 "Invalid frame index");
435 const FrameIndexOperand &Operand = ObjectInfo->second;
436 if (Operand.IsFixed) {
437 OS << "%fixed-stack." << Operand.ID;
438 return;
439 }
440 OS << "%stack." << Operand.ID;
441 if (!Operand.Name.empty())
442 OS << '.' << Operand.Name;
443}
444
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000445void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
446 switch (Op.getType()) {
447 case MachineOperand::MO_Register:
Alex Lorenzcb268d42015-07-06 23:07:26 +0000448 // TODO: Print the other register flags.
449 if (Op.isImplicit())
450 OS << (Op.isDef() ? "implicit-def " : "implicit ");
Alex Lorenzcbbfd0b2015-07-07 20:34:53 +0000451 if (Op.isDead())
452 OS << "dead ";
Alex Lorenz495ad872015-07-08 21:23:34 +0000453 if (Op.isKill())
454 OS << "killed ";
Alex Lorenz4d026b892015-07-08 23:58:31 +0000455 if (Op.isUndef())
456 OS << "undef ";
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000457 printReg(Op.getReg(), OS, TRI);
Alex Lorenz2eacca82015-07-13 23:24:34 +0000458 // Print the sub register.
459 if (Op.getSubReg() != 0)
460 OS << ':' << TRI->getSubRegIndexName(Op.getSubReg());
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000461 break;
Alex Lorenz240fc1e2015-06-23 23:42:28 +0000462 case MachineOperand::MO_Immediate:
463 OS << Op.getImm();
464 break;
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000465 case MachineOperand::MO_MachineBasicBlock:
Alex Lorenz5d26fa82015-06-30 18:00:16 +0000466 printMBBReference(*Op.getMBB());
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000467 break;
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000468 case MachineOperand::MO_FrameIndex:
469 printStackObjectReference(Op.getIndex());
470 break;
Alex Lorenzab980492015-07-20 20:51:18 +0000471 case MachineOperand::MO_ConstantPoolIndex:
472 OS << "%const." << Op.getIndex();
473 // TODO: Print offset and target flags.
474 break;
Alex Lorenz31d70682015-07-15 23:38:35 +0000475 case MachineOperand::MO_JumpTableIndex:
476 OS << "%jump-table." << Op.getIndex();
477 // TODO: Print target flags.
478 break;
Alex Lorenz6ede3742015-07-21 16:59:53 +0000479 case MachineOperand::MO_ExternalSymbol:
480 OS << '$';
481 printLLVMNameWithoutPrefix(OS, Op.getSymbolName());
482 // TODO: Print the target flags.
483 break;
Alex Lorenz5d6108e2015-06-26 22:56:48 +0000484 case MachineOperand::MO_GlobalAddress:
Alex Lorenz900b5cb2015-07-07 23:27:53 +0000485 Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
Alex Lorenz5d6108e2015-06-26 22:56:48 +0000486 // TODO: Print offset and target flags.
487 break;
Alex Lorenz8f6f4282015-06-29 16:57:06 +0000488 case MachineOperand::MO_RegisterMask: {
489 auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
490 if (RegMaskInfo != RegisterMaskIds.end())
491 OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
492 else
493 llvm_unreachable("Can't print this machine register mask yet.");
494 break;
495 }
Alex Lorenz35e44462015-07-22 17:58:46 +0000496 case MachineOperand::MO_Metadata:
497 Op.getMetadata()->printAsOperand(OS, MST);
498 break;
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000499 case MachineOperand::MO_CFIIndex: {
500 const auto &MMI = Op.getParent()->getParent()->getParent()->getMMI();
Alex Lorenz8cfc6862015-07-23 23:09:07 +0000501 print(MMI.getFrameInstructions()[Op.getCFIIndex()], TRI);
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000502 break;
503 }
Alex Lorenzf3db51de2015-06-23 16:35:26 +0000504 default:
505 // TODO: Print the other machine operands.
506 llvm_unreachable("Can't print this machine operand at the moment");
507 }
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000508}
509
Alex Lorenz8cfc6862015-07-23 23:09:07 +0000510static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
511 const TargetRegisterInfo *TRI) {
512 int Reg = TRI->getLLVMRegNum(DwarfReg, true);
513 if (Reg == -1) {
514 OS << "<badreg>";
515 return;
516 }
517 printReg(Reg, OS, TRI);
518}
519
520void MIPrinter::print(const MCCFIInstruction &CFI,
521 const TargetRegisterInfo *TRI) {
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000522 switch (CFI.getOperation()) {
Alex Lorenz8cfc6862015-07-23 23:09:07 +0000523 case MCCFIInstruction::OpOffset:
524 OS << ".cfi_offset ";
525 if (CFI.getLabel())
526 OS << "<mcsymbol> ";
527 printCFIRegister(CFI.getRegister(), OS, TRI);
528 OS << ", " << CFI.getOffset();
529 break;
Alex Lorenz5b0d5f62015-07-27 20:39:03 +0000530 case MCCFIInstruction::OpDefCfaRegister:
531 OS << ".cfi_def_cfa_register ";
532 if (CFI.getLabel())
533 OS << "<mcsymbol> ";
534 printCFIRegister(CFI.getRegister(), OS, TRI);
535 break;
Alex Lorenzf4baeb52015-07-21 22:28:27 +0000536 case MCCFIInstruction::OpDefCfaOffset:
537 OS << ".cfi_def_cfa_offset ";
538 if (CFI.getLabel())
539 OS << "<mcsymbol> ";
540 OS << CFI.getOffset();
541 break;
542 default:
543 // TODO: Print the other CFI Operations.
544 OS << "<unserializable cfi operation>";
545 break;
546 }
547}
548
Alex Lorenz345c1442015-06-15 23:52:35 +0000549void llvm::printMIR(raw_ostream &OS, const Module &M) {
550 yaml::Output Out(OS);
551 Out << const_cast<Module &>(M);
552}
553
554void llvm::printMIR(raw_ostream &OS, const MachineFunction &MF) {
555 MIRPrinter Printer(OS);
556 Printer.print(MF);
557}