MIR Serialization: Serialize the jump table index operands.
[oota-llvm.git] / lib / CodeGen / MIRParser / MIRParser.cpp
1 //===- MIRParser.cpp - MIR serialization format parser implementation -----===//
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 parses the optional LLVM IR and machine
11 // functions that are stored in MIR files.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/CodeGen/MIRParser/MIRParser.h"
16 #include "MIParser.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/StringMap.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/AsmParser/Parser.h"
22 #include "llvm/AsmParser/SlotMapping.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineFrameInfo.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/MIRYamlMapping.h"
27 #include "llvm/IR/BasicBlock.h"
28 #include "llvm/IR/DiagnosticInfo.h"
29 #include "llvm/IR/Instructions.h"
30 #include "llvm/IR/LLVMContext.h"
31 #include "llvm/IR/Module.h"
32 #include "llvm/IR/ValueSymbolTable.h"
33 #include "llvm/Support/LineIterator.h"
34 #include "llvm/Support/SMLoc.h"
35 #include "llvm/Support/SourceMgr.h"
36 #include "llvm/Support/MemoryBuffer.h"
37 #include "llvm/Support/YAMLTraits.h"
38 #include <memory>
39
40 using namespace llvm;
41
42 namespace llvm {
43
44 /// This class implements the parsing of LLVM IR that's embedded inside a MIR
45 /// file.
46 class MIRParserImpl {
47   SourceMgr SM;
48   StringRef Filename;
49   LLVMContext &Context;
50   StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;
51   SlotMapping IRSlots;
52   /// Maps from register class names to register classes.
53   StringMap<const TargetRegisterClass *> Names2RegClasses;
54
55 public:
56   MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
57                 LLVMContext &Context);
58
59   void reportDiagnostic(const SMDiagnostic &Diag);
60
61   /// Report an error with the given message at unknown location.
62   ///
63   /// Always returns true.
64   bool error(const Twine &Message);
65
66   /// Report an error with the given message at the given location.
67   ///
68   /// Always returns true.
69   bool error(SMLoc Loc, const Twine &Message);
70
71   /// Report a given error with the location translated from the location in an
72   /// embedded string literal to a location in the MIR file.
73   ///
74   /// Always returns true.
75   bool error(const SMDiagnostic &Error, SMRange SourceRange);
76
77   /// Try to parse the optional LLVM module and the machine functions in the MIR
78   /// file.
79   ///
80   /// Return null if an error occurred.
81   std::unique_ptr<Module> parse();
82
83   /// Parse the machine function in the current YAML document.
84   ///
85   /// \param NoLLVMIR - set to true when the MIR file doesn't have LLVM IR.
86   /// A dummy IR function is created and inserted into the given module when
87   /// this parameter is true.
88   ///
89   /// Return true if an error occurred.
90   bool parseMachineFunction(yaml::Input &In, Module &M, bool NoLLVMIR);
91
92   /// Initialize the machine function to the state that's described in the MIR
93   /// file.
94   ///
95   /// Return true if error occurred.
96   bool initializeMachineFunction(MachineFunction &MF);
97
98   /// Initialize the machine basic block using it's YAML representation.
99   ///
100   /// Return true if an error occurred.
101   bool initializeMachineBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB,
102                                    const yaml::MachineBasicBlock &YamlMBB,
103                                    const PerFunctionMIParsingState &PFS);
104
105   bool
106   initializeRegisterInfo(const MachineFunction &MF,
107                          MachineRegisterInfo &RegInfo,
108                          const yaml::MachineFunction &YamlMF,
109                          DenseMap<unsigned, unsigned> &VirtualRegisterSlots);
110
111   bool initializeFrameInfo(const Function &F, MachineFrameInfo &MFI,
112                            const yaml::MachineFunction &YamlMF);
113
114   bool initializeJumpTableInfo(MachineFunction &MF,
115                                const yaml::MachineJumpTable &YamlJTI,
116                                PerFunctionMIParsingState &PFS);
117
118 private:
119   /// Return a MIR diagnostic converted from an MI string diagnostic.
120   SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
121                                     SMRange SourceRange);
122
123   /// Return a MIR diagnostic converted from an LLVM assembly diagnostic.
124   SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
125                                         SMRange SourceRange);
126
127   /// Create an empty function with the given name.
128   void createDummyFunction(StringRef Name, Module &M);
129
130   void initNames2RegClasses(const MachineFunction &MF);
131
132   /// Check if the given identifier is a name of a register class.
133   ///
134   /// Return null if the name isn't a register class.
135   const TargetRegisterClass *getRegClass(const MachineFunction &MF,
136                                          StringRef Name);
137 };
138
139 } // end namespace llvm
140
141 MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
142                              StringRef Filename, LLVMContext &Context)
143     : SM(), Filename(Filename), Context(Context) {
144   SM.AddNewSourceBuffer(std::move(Contents), SMLoc());
145 }
146
147 bool MIRParserImpl::error(const Twine &Message) {
148   Context.diagnose(DiagnosticInfoMIRParser(
149       DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));
150   return true;
151 }
152
153 bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) {
154   Context.diagnose(DiagnosticInfoMIRParser(
155       DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message)));
156   return true;
157 }
158
159 bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) {
160   assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");
161   reportDiagnostic(diagFromMIStringDiag(Error, SourceRange));
162   return true;
163 }
164
165 void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
166   DiagnosticSeverity Kind;
167   switch (Diag.getKind()) {
168   case SourceMgr::DK_Error:
169     Kind = DS_Error;
170     break;
171   case SourceMgr::DK_Warning:
172     Kind = DS_Warning;
173     break;
174   case SourceMgr::DK_Note:
175     Kind = DS_Note;
176     break;
177   }
178   Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
179 }
180
181 static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
182   reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
183 }
184
185 std::unique_ptr<Module> MIRParserImpl::parse() {
186   yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(),
187                  /*Ctxt=*/nullptr, handleYAMLDiag, this);
188   In.setContext(&In);
189
190   if (!In.setCurrentDocument()) {
191     if (In.error())
192       return nullptr;
193     // Create an empty module when the MIR file is empty.
194     return llvm::make_unique<Module>(Filename, Context);
195   }
196
197   std::unique_ptr<Module> M;
198   bool NoLLVMIR = false;
199   // Parse the block scalar manually so that we can return unique pointer
200   // without having to go trough YAML traits.
201   if (const auto *BSN =
202           dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
203     SMDiagnostic Error;
204     M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
205                       Context, &IRSlots);
206     if (!M) {
207       reportDiagnostic(diagFromLLVMAssemblyDiag(Error, BSN->getSourceRange()));
208       return M;
209     }
210     In.nextDocument();
211     if (!In.setCurrentDocument())
212       return M;
213   } else {
214     // Create an new, empty module.
215     M = llvm::make_unique<Module>(Filename, Context);
216     NoLLVMIR = true;
217   }
218
219   // Parse the machine functions.
220   do {
221     if (parseMachineFunction(In, *M, NoLLVMIR))
222       return nullptr;
223     In.nextDocument();
224   } while (In.setCurrentDocument());
225
226   return M;
227 }
228
229 bool MIRParserImpl::parseMachineFunction(yaml::Input &In, Module &M,
230                                          bool NoLLVMIR) {
231   auto MF = llvm::make_unique<yaml::MachineFunction>();
232   yaml::yamlize(In, *MF, false);
233   if (In.error())
234     return true;
235   auto FunctionName = MF->Name;
236   if (Functions.find(FunctionName) != Functions.end())
237     return error(Twine("redefinition of machine function '") + FunctionName +
238                  "'");
239   Functions.insert(std::make_pair(FunctionName, std::move(MF)));
240   if (NoLLVMIR)
241     createDummyFunction(FunctionName, M);
242   else if (!M.getFunction(FunctionName))
243     return error(Twine("function '") + FunctionName +
244                  "' isn't defined in the provided LLVM IR");
245   return false;
246 }
247
248 void MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
249   auto &Context = M.getContext();
250   Function *F = cast<Function>(M.getOrInsertFunction(
251       Name, FunctionType::get(Type::getVoidTy(Context), false)));
252   BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
253   new UnreachableInst(Context, BB);
254 }
255
256 bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
257   auto It = Functions.find(MF.getName());
258   if (It == Functions.end())
259     return error(Twine("no machine function information for function '") +
260                  MF.getName() + "' in the MIR file");
261   // TODO: Recreate the machine function.
262   const yaml::MachineFunction &YamlMF = *It->getValue();
263   if (YamlMF.Alignment)
264     MF.setAlignment(YamlMF.Alignment);
265   MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
266   MF.setHasInlineAsm(YamlMF.HasInlineAsm);
267   PerFunctionMIParsingState PFS;
268   if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF,
269                              PFS.VirtualRegisterSlots))
270     return true;
271   if (initializeFrameInfo(*MF.getFunction(), *MF.getFrameInfo(), YamlMF))
272     return true;
273
274   const auto &F = *MF.getFunction();
275   for (const auto &YamlMBB : YamlMF.BasicBlocks) {
276     const BasicBlock *BB = nullptr;
277     const yaml::StringValue &Name = YamlMBB.Name;
278     if (!Name.Value.empty()) {
279       BB = dyn_cast_or_null<BasicBlock>(
280           F.getValueSymbolTable().lookup(Name.Value));
281       if (!BB)
282         return error(Name.SourceRange.Start,
283                      Twine("basic block '") + Name.Value +
284                          "' is not defined in the function '" + MF.getName() +
285                          "'");
286     }
287     auto *MBB = MF.CreateMachineBasicBlock(BB);
288     MF.insert(MF.end(), MBB);
289     bool WasInserted =
290         PFS.MBBSlots.insert(std::make_pair(YamlMBB.ID, MBB)).second;
291     if (!WasInserted)
292       return error(Twine("redefinition of machine basic block with id #") +
293                    Twine(YamlMBB.ID));
294   }
295
296   if (YamlMF.BasicBlocks.empty())
297     return error(Twine("machine function '") + Twine(MF.getName()) +
298                  "' requires at least one machine basic block in its body");
299   // Initialize the jump table after creating all the MBBs so that the MBB
300   // references can be resolved.
301   if (!YamlMF.JumpTableInfo.Entries.empty() &&
302       initializeJumpTableInfo(MF, YamlMF.JumpTableInfo, PFS))
303     return true;
304   // Initialize the machine basic blocks after creating them all so that the
305   // machine instructions parser can resolve the MBB references.
306   unsigned I = 0;
307   for (const auto &YamlMBB : YamlMF.BasicBlocks) {
308     if (initializeMachineBasicBlock(MF, *MF.getBlockNumbered(I++), YamlMBB,
309                                     PFS))
310       return true;
311   }
312   return false;
313 }
314
315 bool MIRParserImpl::initializeMachineBasicBlock(
316     MachineFunction &MF, MachineBasicBlock &MBB,
317     const yaml::MachineBasicBlock &YamlMBB,
318     const PerFunctionMIParsingState &PFS) {
319   MBB.setAlignment(YamlMBB.Alignment);
320   if (YamlMBB.AddressTaken)
321     MBB.setHasAddressTaken();
322   MBB.setIsLandingPad(YamlMBB.IsLandingPad);
323   SMDiagnostic Error;
324   // Parse the successors.
325   for (const auto &MBBSource : YamlMBB.Successors) {
326     MachineBasicBlock *SuccMBB = nullptr;
327     if (parseMBBReference(SuccMBB, SM, MF, MBBSource.Value, PFS, IRSlots,
328                           Error))
329       return error(Error, MBBSource.SourceRange);
330     // TODO: Report an error when adding the same successor more than once.
331     MBB.addSuccessor(SuccMBB);
332   }
333   // Parse the liveins.
334   for (const auto &LiveInSource : YamlMBB.LiveIns) {
335     unsigned Reg = 0;
336     if (parseNamedRegisterReference(Reg, SM, MF, LiveInSource.Value, PFS,
337                                     IRSlots, Error))
338       return error(Error, LiveInSource.SourceRange);
339     MBB.addLiveIn(Reg);
340   }
341   // Parse the instructions.
342   for (const auto &MISource : YamlMBB.Instructions) {
343     MachineInstr *MI = nullptr;
344     if (parseMachineInstr(MI, SM, MF, MISource.Value, PFS, IRSlots, Error))
345       return error(Error, MISource.SourceRange);
346     MBB.insert(MBB.end(), MI);
347   }
348   return false;
349 }
350
351 bool MIRParserImpl::initializeRegisterInfo(
352     const MachineFunction &MF, MachineRegisterInfo &RegInfo,
353     const yaml::MachineFunction &YamlMF,
354     DenseMap<unsigned, unsigned> &VirtualRegisterSlots) {
355   assert(RegInfo.isSSA());
356   if (!YamlMF.IsSSA)
357     RegInfo.leaveSSA();
358   assert(RegInfo.tracksLiveness());
359   if (!YamlMF.TracksRegLiveness)
360     RegInfo.invalidateLiveness();
361   RegInfo.enableSubRegLiveness(YamlMF.TracksSubRegLiveness);
362
363   // Parse the virtual register information.
364   for (const auto &VReg : YamlMF.VirtualRegisters) {
365     const auto *RC = getRegClass(MF, VReg.Class.Value);
366     if (!RC)
367       return error(VReg.Class.SourceRange.Start,
368                    Twine("use of undefined register class '") +
369                        VReg.Class.Value + "'");
370     unsigned Reg = RegInfo.createVirtualRegister(RC);
371     // TODO: Report an error when the same virtual register with the same ID is
372     // redefined.
373     VirtualRegisterSlots.insert(std::make_pair(VReg.ID, Reg));
374   }
375   return false;
376 }
377
378 bool MIRParserImpl::initializeFrameInfo(const Function &F,
379                                         MachineFrameInfo &MFI,
380                                         const yaml::MachineFunction &YamlMF) {
381   const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
382   MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
383   MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
384   MFI.setHasStackMap(YamlMFI.HasStackMap);
385   MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);
386   MFI.setStackSize(YamlMFI.StackSize);
387   MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment);
388   if (YamlMFI.MaxAlignment)
389     MFI.ensureMaxAlignment(YamlMFI.MaxAlignment);
390   MFI.setAdjustsStack(YamlMFI.AdjustsStack);
391   MFI.setHasCalls(YamlMFI.HasCalls);
392   MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize);
393   MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);
394   MFI.setHasVAStart(YamlMFI.HasVAStart);
395   MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
396
397   // Initialize the fixed frame objects.
398   for (const auto &Object : YamlMF.FixedStackObjects) {
399     int ObjectIdx;
400     if (Object.Type != yaml::FixedMachineStackObject::SpillSlot)
401       ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset,
402                                         Object.IsImmutable, Object.IsAliased);
403     else
404       ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
405     MFI.setObjectAlignment(ObjectIdx, Object.Alignment);
406     // TODO: Store the mapping between fixed object IDs and object indices to
407     // parse fixed stack object references correctly.
408   }
409
410   // Initialize the ordinary frame objects.
411   for (const auto &Object : YamlMF.StackObjects) {
412     int ObjectIdx;
413     const AllocaInst *Alloca = nullptr;
414     const yaml::StringValue &Name = Object.Name;
415     if (!Name.Value.empty()) {
416       Alloca = dyn_cast_or_null<AllocaInst>(
417           F.getValueSymbolTable().lookup(Name.Value));
418       if (!Alloca)
419         return error(Name.SourceRange.Start,
420                      "alloca instruction named '" + Name.Value +
421                          "' isn't defined in the function '" + F.getName() +
422                          "'");
423     }
424     if (Object.Type == yaml::MachineStackObject::VariableSized)
425       ObjectIdx = MFI.CreateVariableSizedObject(Object.Alignment, Alloca);
426     else
427       ObjectIdx = MFI.CreateStackObject(
428           Object.Size, Object.Alignment,
429           Object.Type == yaml::MachineStackObject::SpillSlot, Alloca);
430     MFI.setObjectOffset(ObjectIdx, Object.Offset);
431     // TODO: Store the mapping between object IDs and object indices to parse
432     // stack object references correctly.
433   }
434   return false;
435 }
436
437 bool MIRParserImpl::initializeJumpTableInfo(
438     MachineFunction &MF, const yaml::MachineJumpTable &YamlJTI,
439     PerFunctionMIParsingState &PFS) {
440   MachineJumpTableInfo *JTI = MF.getOrCreateJumpTableInfo(YamlJTI.Kind);
441   SMDiagnostic Error;
442   for (const auto &Entry : YamlJTI.Entries) {
443     std::vector<MachineBasicBlock *> Blocks;
444     for (const auto &MBBSource : Entry.Blocks) {
445       MachineBasicBlock *MBB = nullptr;
446       if (parseMBBReference(MBB, SM, MF, MBBSource.Value, PFS, IRSlots, Error))
447         return error(Error, MBBSource.SourceRange);
448       Blocks.push_back(MBB);
449     }
450     unsigned Index = JTI->createJumpTableIndex(Blocks);
451     // TODO: Report an error when the same jump table slot ID is redefined.
452     PFS.JumpTableSlots.insert(std::make_pair(Entry.ID, Index));
453   }
454   return false;
455 }
456
457 SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
458                                                  SMRange SourceRange) {
459   assert(SourceRange.isValid() && "Invalid source range");
460   SMLoc Loc = SourceRange.Start;
461   bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
462                   *Loc.getPointer() == '\'';
463   // Translate the location of the error from the location in the MI string to
464   // the corresponding location in the MIR file.
465   Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
466                            (HasQuote ? 1 : 0));
467
468   // TODO: Translate any source ranges as well.
469   return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None,
470                        Error.getFixIts());
471 }
472
473 SMDiagnostic MIRParserImpl::diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
474                                                      SMRange SourceRange) {
475   assert(SourceRange.isValid());
476
477   // Translate the location of the error from the location in the llvm IR string
478   // to the corresponding location in the MIR file.
479   auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
480   unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
481   unsigned Column = Error.getColumnNo();
482   StringRef LineStr = Error.getLineContents();
483   SMLoc Loc = Error.getLoc();
484
485   // Get the full line and adjust the column number by taking the indentation of
486   // LLVM IR into account.
487   for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
488        L != E; ++L) {
489     if (L.line_number() == Line) {
490       LineStr = *L;
491       Loc = SMLoc::getFromPointer(LineStr.data());
492       auto Indent = LineStr.find(Error.getLineContents());
493       if (Indent != StringRef::npos)
494         Column += Indent;
495       break;
496     }
497   }
498
499   return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
500                       Error.getMessage(), LineStr, Error.getRanges(),
501                       Error.getFixIts());
502 }
503
504 void MIRParserImpl::initNames2RegClasses(const MachineFunction &MF) {
505   if (!Names2RegClasses.empty())
506     return;
507   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
508   for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) {
509     const auto *RC = TRI->getRegClass(I);
510     Names2RegClasses.insert(
511         std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC));
512   }
513 }
514
515 const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF,
516                                                       StringRef Name) {
517   initNames2RegClasses(MF);
518   auto RegClassInfo = Names2RegClasses.find(Name);
519   if (RegClassInfo == Names2RegClasses.end())
520     return nullptr;
521   return RegClassInfo->getValue();
522 }
523
524 MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
525     : Impl(std::move(Impl)) {}
526
527 MIRParser::~MIRParser() {}
528
529 std::unique_ptr<Module> MIRParser::parseLLVMModule() { return Impl->parse(); }
530
531 bool MIRParser::initializeMachineFunction(MachineFunction &MF) {
532   return Impl->initializeMachineFunction(MF);
533 }
534
535 std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename,
536                                                          SMDiagnostic &Error,
537                                                          LLVMContext &Context) {
538   auto FileOrErr = MemoryBuffer::getFile(Filename);
539   if (std::error_code EC = FileOrErr.getError()) {
540     Error = SMDiagnostic(Filename, SourceMgr::DK_Error,
541                          "Could not open input file: " + EC.message());
542     return nullptr;
543   }
544   return createMIRParser(std::move(FileOrErr.get()), Context);
545 }
546
547 std::unique_ptr<MIRParser>
548 llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
549                       LLVMContext &Context) {
550   auto Filename = Contents->getBufferIdentifier();
551   return llvm::make_unique<MIRParser>(
552       llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context));
553 }