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/MachineConstantPool.h"
24 #include "llvm/CodeGen/MachineFunction.h"
25 #include "llvm/CodeGen/MachineFrameInfo.h"
26 #include "llvm/CodeGen/MachineModuleInfo.h"
27 #include "llvm/CodeGen/MachineRegisterInfo.h"
28 #include "llvm/CodeGen/MIRYamlMapping.h"
29 #include "llvm/IR/BasicBlock.h"
30 #include "llvm/IR/DiagnosticInfo.h"
31 #include "llvm/IR/Instructions.h"
32 #include "llvm/IR/LLVMContext.h"
33 #include "llvm/IR/Module.h"
34 #include "llvm/IR/ValueSymbolTable.h"
35 #include "llvm/Support/LineIterator.h"
36 #include "llvm/Support/SMLoc.h"
37 #include "llvm/Support/SourceMgr.h"
38 #include "llvm/Support/MemoryBuffer.h"
39 #include "llvm/Support/YAMLTraits.h"
40 #include <memory>
41 
42 using namespace llvm;
43 
44 namespace llvm {
45 
46 /// This class implements the parsing of LLVM IR that's embedded inside a MIR
47 /// file.
48 class MIRParserImpl {
49   SourceMgr SM;
50   StringRef Filename;
51   LLVMContext &Context;
52   StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;
53   SlotMapping IRSlots;
54   /// Maps from register class names to register classes.
55   StringMap<const TargetRegisterClass *> Names2RegClasses;
56 
57 public:
58   MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
59                 LLVMContext &Context);
60 
61   void reportDiagnostic(const SMDiagnostic &Diag);
62 
63   /// Report an error with the given message at unknown location.
64   ///
65   /// Always returns true.
66   bool error(const Twine &Message);
67 
68   /// Report an error with the given message at the given location.
69   ///
70   /// Always returns true.
71   bool error(SMLoc Loc, const Twine &Message);
72 
73   /// Report a given error with the location translated from the location in an
74   /// embedded string literal to a location in the MIR file.
75   ///
76   /// Always returns true.
77   bool error(const SMDiagnostic &Error, SMRange SourceRange);
78 
79   /// Try to parse the optional LLVM module and the machine functions in the MIR
80   /// file.
81   ///
82   /// Return null if an error occurred.
83   std::unique_ptr<Module> parse();
84 
85   /// Parse the machine function in the current YAML document.
86   ///
87   /// \param NoLLVMIR - set to true when the MIR file doesn't have LLVM IR.
88   /// A dummy IR function is created and inserted into the given module when
89   /// this parameter is true.
90   ///
91   /// Return true if an error occurred.
92   bool parseMachineFunction(yaml::Input &In, Module &M, bool NoLLVMIR);
93 
94   /// Initialize the machine function to the state that's described in the MIR
95   /// file.
96   ///
97   /// Return true if error occurred.
98   bool initializeMachineFunction(MachineFunction &MF);
99 
100   bool initializeRegisterInfo(MachineFunction &MF,
101                               const yaml::MachineFunction &YamlMF,
102                               PerFunctionMIParsingState &PFS);
103 
104   void inferRegisterInfo(MachineFunction &MF,
105                          const yaml::MachineFunction &YamlMF);
106 
107   bool initializeFrameInfo(MachineFunction &MF,
108                            const yaml::MachineFunction &YamlMF,
109                            PerFunctionMIParsingState &PFS);
110 
111   bool parseCalleeSavedRegister(MachineFunction &MF,
112                                 PerFunctionMIParsingState &PFS,
113                                 std::vector<CalleeSavedInfo> &CSIInfo,
114                                 const yaml::StringValue &RegisterSource,
115                                 int FrameIdx);
116 
117   bool parseStackObjectsDebugInfo(MachineFunction &MF,
118                                   PerFunctionMIParsingState &PFS,
119                                   const yaml::MachineStackObject &Object,
120                                   int FrameIdx);
121 
122   bool initializeConstantPool(MachineConstantPool &ConstantPool,
123                               const yaml::MachineFunction &YamlMF,
124                               const MachineFunction &MF,
125                               DenseMap<unsigned, unsigned> &ConstantPoolSlots);
126 
127   bool initializeJumpTableInfo(MachineFunction &MF,
128                                const yaml::MachineJumpTable &YamlJTI,
129                                PerFunctionMIParsingState &PFS);
130 
131 private:
132   bool parseMDNode(MDNode *&Node, const yaml::StringValue &Source,
133                    MachineFunction &MF, const PerFunctionMIParsingState &PFS);
134 
135   bool parseMBBReference(MachineBasicBlock *&MBB,
136                          const yaml::StringValue &Source, MachineFunction &MF,
137                          const PerFunctionMIParsingState &PFS);
138 
139   /// Return a MIR diagnostic converted from an MI string diagnostic.
140   SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
141                                     SMRange SourceRange);
142 
143   /// Return a MIR diagnostic converted from a diagnostic located in a YAML
144   /// block scalar string.
145   SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error,
146                                        SMRange SourceRange);
147 
148   /// Create an empty function with the given name.
149   void createDummyFunction(StringRef Name, Module &M);
150 
151   void initNames2RegClasses(const MachineFunction &MF);
152 
153   /// Check if the given identifier is a name of a register class.
154   ///
155   /// Return null if the name isn't a register class.
156   const TargetRegisterClass *getRegClass(const MachineFunction &MF,
157                                          StringRef Name);
158 };
159 
160 } // end namespace llvm
161 
MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,StringRef Filename,LLVMContext & Context)162 MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
163                              StringRef Filename, LLVMContext &Context)
164     : SM(), Filename(Filename), Context(Context) {
165   SM.AddNewSourceBuffer(std::move(Contents), SMLoc());
166 }
167 
error(const Twine & Message)168 bool MIRParserImpl::error(const Twine &Message) {
169   Context.diagnose(DiagnosticInfoMIRParser(
170       DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));
171   return true;
172 }
173 
error(SMLoc Loc,const Twine & Message)174 bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) {
175   Context.diagnose(DiagnosticInfoMIRParser(
176       DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message)));
177   return true;
178 }
179 
error(const SMDiagnostic & Error,SMRange SourceRange)180 bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) {
181   assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");
182   reportDiagnostic(diagFromMIStringDiag(Error, SourceRange));
183   return true;
184 }
185 
reportDiagnostic(const SMDiagnostic & Diag)186 void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
187   DiagnosticSeverity Kind;
188   switch (Diag.getKind()) {
189   case SourceMgr::DK_Error:
190     Kind = DS_Error;
191     break;
192   case SourceMgr::DK_Warning:
193     Kind = DS_Warning;
194     break;
195   case SourceMgr::DK_Note:
196     Kind = DS_Note;
197     break;
198   }
199   Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
200 }
201 
handleYAMLDiag(const SMDiagnostic & Diag,void * Context)202 static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
203   reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
204 }
205 
parse()206 std::unique_ptr<Module> MIRParserImpl::parse() {
207   yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(),
208                  /*Ctxt=*/nullptr, handleYAMLDiag, this);
209   In.setContext(&In);
210 
211   if (!In.setCurrentDocument()) {
212     if (In.error())
213       return nullptr;
214     // Create an empty module when the MIR file is empty.
215     return llvm::make_unique<Module>(Filename, Context);
216   }
217 
218   std::unique_ptr<Module> M;
219   bool NoLLVMIR = false;
220   // Parse the block scalar manually so that we can return unique pointer
221   // without having to go trough YAML traits.
222   if (const auto *BSN =
223           dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
224     SMDiagnostic Error;
225     M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
226                       Context, &IRSlots);
227     if (!M) {
228       reportDiagnostic(diagFromBlockStringDiag(Error, BSN->getSourceRange()));
229       return M;
230     }
231     In.nextDocument();
232     if (!In.setCurrentDocument())
233       return M;
234   } else {
235     // Create an new, empty module.
236     M = llvm::make_unique<Module>(Filename, Context);
237     NoLLVMIR = true;
238   }
239 
240   // Parse the machine functions.
241   do {
242     if (parseMachineFunction(In, *M, NoLLVMIR))
243       return nullptr;
244     In.nextDocument();
245   } while (In.setCurrentDocument());
246 
247   return M;
248 }
249 
parseMachineFunction(yaml::Input & In,Module & M,bool NoLLVMIR)250 bool MIRParserImpl::parseMachineFunction(yaml::Input &In, Module &M,
251                                          bool NoLLVMIR) {
252   auto MF = llvm::make_unique<yaml::MachineFunction>();
253   yaml::yamlize(In, *MF, false);
254   if (In.error())
255     return true;
256   auto FunctionName = MF->Name;
257   if (Functions.find(FunctionName) != Functions.end())
258     return error(Twine("redefinition of machine function '") + FunctionName +
259                  "'");
260   Functions.insert(std::make_pair(FunctionName, std::move(MF)));
261   if (NoLLVMIR)
262     createDummyFunction(FunctionName, M);
263   else if (!M.getFunction(FunctionName))
264     return error(Twine("function '") + FunctionName +
265                  "' isn't defined in the provided LLVM IR");
266   return false;
267 }
268 
createDummyFunction(StringRef Name,Module & M)269 void MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
270   auto &Context = M.getContext();
271   Function *F = cast<Function>(M.getOrInsertFunction(
272       Name, FunctionType::get(Type::getVoidTy(Context), false)));
273   BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
274   new UnreachableInst(Context, BB);
275 }
276 
initializeMachineFunction(MachineFunction & MF)277 bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
278   auto It = Functions.find(MF.getName());
279   if (It == Functions.end())
280     return error(Twine("no machine function information for function '") +
281                  MF.getName() + "' in the MIR file");
282   // TODO: Recreate the machine function.
283   const yaml::MachineFunction &YamlMF = *It->getValue();
284   if (YamlMF.Alignment)
285     MF.setAlignment(YamlMF.Alignment);
286   MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
287   MF.setHasInlineAsm(YamlMF.HasInlineAsm);
288   PerFunctionMIParsingState PFS;
289   if (initializeRegisterInfo(MF, YamlMF, PFS))
290     return true;
291   if (!YamlMF.Constants.empty()) {
292     auto *ConstantPool = MF.getConstantPool();
293     assert(ConstantPool && "Constant pool must be created");
294     if (initializeConstantPool(*ConstantPool, YamlMF, MF,
295                                PFS.ConstantPoolSlots))
296       return true;
297   }
298 
299   SMDiagnostic Error;
300   if (parseMachineBasicBlockDefinitions(MF, YamlMF.Body.Value.Value, PFS,
301                                         IRSlots, Error)) {
302     reportDiagnostic(
303         diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
304     return true;
305   }
306 
307   if (MF.empty())
308     return error(Twine("machine function '") + Twine(MF.getName()) +
309                  "' requires at least one machine basic block in its body");
310   // Initialize the frame information after creating all the MBBs so that the
311   // MBB references in the frame information can be resolved.
312   if (initializeFrameInfo(MF, YamlMF, PFS))
313     return true;
314   // Initialize the jump table after creating all the MBBs so that the MBB
315   // references can be resolved.
316   if (!YamlMF.JumpTableInfo.Entries.empty() &&
317       initializeJumpTableInfo(MF, YamlMF.JumpTableInfo, PFS))
318     return true;
319   // Parse the machine instructions after creating all of the MBBs so that the
320   // parser can resolve the MBB references.
321   if (parseMachineInstructions(MF, YamlMF.Body.Value.Value, PFS, IRSlots,
322                                Error)) {
323     reportDiagnostic(
324         diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
325     return true;
326   }
327   inferRegisterInfo(MF, YamlMF);
328   // FIXME: This is a temporary workaround until the reserved registers can be
329   // serialized.
330   MF.getRegInfo().freezeReservedRegs(MF);
331   MF.verify();
332   return false;
333 }
334 
initializeRegisterInfo(MachineFunction & MF,const yaml::MachineFunction & YamlMF,PerFunctionMIParsingState & PFS)335 bool MIRParserImpl::initializeRegisterInfo(MachineFunction &MF,
336                                            const yaml::MachineFunction &YamlMF,
337                                            PerFunctionMIParsingState &PFS) {
338   MachineRegisterInfo &RegInfo = MF.getRegInfo();
339   assert(RegInfo.isSSA());
340   if (!YamlMF.IsSSA)
341     RegInfo.leaveSSA();
342   assert(RegInfo.tracksLiveness());
343   if (!YamlMF.TracksRegLiveness)
344     RegInfo.invalidateLiveness();
345   RegInfo.enableSubRegLiveness(YamlMF.TracksSubRegLiveness);
346 
347   SMDiagnostic Error;
348   // Parse the virtual register information.
349   for (const auto &VReg : YamlMF.VirtualRegisters) {
350     const auto *RC = getRegClass(MF, VReg.Class.Value);
351     if (!RC)
352       return error(VReg.Class.SourceRange.Start,
353                    Twine("use of undefined register class '") +
354                        VReg.Class.Value + "'");
355     unsigned Reg = RegInfo.createVirtualRegister(RC);
356     if (!PFS.VirtualRegisterSlots.insert(std::make_pair(VReg.ID.Value, Reg))
357              .second)
358       return error(VReg.ID.SourceRange.Start,
359                    Twine("redefinition of virtual register '%") +
360                        Twine(VReg.ID.Value) + "'");
361     if (!VReg.PreferredRegister.Value.empty()) {
362       unsigned PreferredReg = 0;
363       if (parseNamedRegisterReference(PreferredReg, SM, MF,
364                                       VReg.PreferredRegister.Value, PFS,
365                                       IRSlots, Error))
366         return error(Error, VReg.PreferredRegister.SourceRange);
367       RegInfo.setSimpleHint(Reg, PreferredReg);
368     }
369   }
370 
371   // Parse the liveins.
372   for (const auto &LiveIn : YamlMF.LiveIns) {
373     unsigned Reg = 0;
374     if (parseNamedRegisterReference(Reg, SM, MF, LiveIn.Register.Value, PFS,
375                                     IRSlots, Error))
376       return error(Error, LiveIn.Register.SourceRange);
377     unsigned VReg = 0;
378     if (!LiveIn.VirtualRegister.Value.empty()) {
379       if (parseVirtualRegisterReference(
380               VReg, SM, MF, LiveIn.VirtualRegister.Value, PFS, IRSlots, Error))
381         return error(Error, LiveIn.VirtualRegister.SourceRange);
382     }
383     RegInfo.addLiveIn(Reg, VReg);
384   }
385 
386   // Parse the callee saved register mask.
387   BitVector CalleeSavedRegisterMask(RegInfo.getUsedPhysRegsMask().size());
388   if (!YamlMF.CalleeSavedRegisters)
389     return false;
390   for (const auto &RegSource : YamlMF.CalleeSavedRegisters.getValue()) {
391     unsigned Reg = 0;
392     if (parseNamedRegisterReference(Reg, SM, MF, RegSource.Value, PFS, IRSlots,
393                                     Error))
394       return error(Error, RegSource.SourceRange);
395     CalleeSavedRegisterMask[Reg] = true;
396   }
397   RegInfo.setUsedPhysRegMask(CalleeSavedRegisterMask.flip());
398   return false;
399 }
400 
inferRegisterInfo(MachineFunction & MF,const yaml::MachineFunction & YamlMF)401 void MIRParserImpl::inferRegisterInfo(MachineFunction &MF,
402                                       const yaml::MachineFunction &YamlMF) {
403   if (YamlMF.CalleeSavedRegisters)
404     return;
405   for (const MachineBasicBlock &MBB : MF) {
406     for (const MachineInstr &MI : MBB) {
407       for (const MachineOperand &MO : MI.operands()) {
408         if (!MO.isRegMask())
409           continue;
410         MF.getRegInfo().addPhysRegsUsedFromRegMask(MO.getRegMask());
411       }
412     }
413   }
414 }
415 
initializeFrameInfo(MachineFunction & MF,const yaml::MachineFunction & YamlMF,PerFunctionMIParsingState & PFS)416 bool MIRParserImpl::initializeFrameInfo(MachineFunction &MF,
417                                         const yaml::MachineFunction &YamlMF,
418                                         PerFunctionMIParsingState &PFS) {
419   MachineFrameInfo &MFI = *MF.getFrameInfo();
420   const Function &F = *MF.getFunction();
421   const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
422   MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
423   MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
424   MFI.setHasStackMap(YamlMFI.HasStackMap);
425   MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);
426   MFI.setStackSize(YamlMFI.StackSize);
427   MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment);
428   if (YamlMFI.MaxAlignment)
429     MFI.ensureMaxAlignment(YamlMFI.MaxAlignment);
430   MFI.setAdjustsStack(YamlMFI.AdjustsStack);
431   MFI.setHasCalls(YamlMFI.HasCalls);
432   MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize);
433   MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);
434   MFI.setHasVAStart(YamlMFI.HasVAStart);
435   MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
436   if (!YamlMFI.SavePoint.Value.empty()) {
437     MachineBasicBlock *MBB = nullptr;
438     if (parseMBBReference(MBB, YamlMFI.SavePoint, MF, PFS))
439       return true;
440     MFI.setSavePoint(MBB);
441   }
442   if (!YamlMFI.RestorePoint.Value.empty()) {
443     MachineBasicBlock *MBB = nullptr;
444     if (parseMBBReference(MBB, YamlMFI.RestorePoint, MF, PFS))
445       return true;
446     MFI.setRestorePoint(MBB);
447   }
448 
449   std::vector<CalleeSavedInfo> CSIInfo;
450   // Initialize the fixed frame objects.
451   for (const auto &Object : YamlMF.FixedStackObjects) {
452     int ObjectIdx;
453     if (Object.Type != yaml::FixedMachineStackObject::SpillSlot)
454       ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset,
455                                         Object.IsImmutable, Object.IsAliased);
456     else
457       ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
458     MFI.setObjectAlignment(ObjectIdx, Object.Alignment);
459     if (!PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID.Value,
460                                                          ObjectIdx))
461              .second)
462       return error(Object.ID.SourceRange.Start,
463                    Twine("redefinition of fixed stack object '%fixed-stack.") +
464                        Twine(Object.ID.Value) + "'");
465     if (parseCalleeSavedRegister(MF, PFS, CSIInfo, Object.CalleeSavedRegister,
466                                  ObjectIdx))
467       return true;
468   }
469 
470   // Initialize the ordinary frame objects.
471   for (const auto &Object : YamlMF.StackObjects) {
472     int ObjectIdx;
473     const AllocaInst *Alloca = nullptr;
474     const yaml::StringValue &Name = Object.Name;
475     if (!Name.Value.empty()) {
476       Alloca = dyn_cast_or_null<AllocaInst>(
477           F.getValueSymbolTable().lookup(Name.Value));
478       if (!Alloca)
479         return error(Name.SourceRange.Start,
480                      "alloca instruction named '" + Name.Value +
481                          "' isn't defined in the function '" + F.getName() +
482                          "'");
483     }
484     if (Object.Type == yaml::MachineStackObject::VariableSized)
485       ObjectIdx = MFI.CreateVariableSizedObject(Object.Alignment, Alloca);
486     else
487       ObjectIdx = MFI.CreateStackObject(
488           Object.Size, Object.Alignment,
489           Object.Type == yaml::MachineStackObject::SpillSlot, Alloca);
490     MFI.setObjectOffset(ObjectIdx, Object.Offset);
491     if (!PFS.StackObjectSlots.insert(std::make_pair(Object.ID.Value, ObjectIdx))
492              .second)
493       return error(Object.ID.SourceRange.Start,
494                    Twine("redefinition of stack object '%stack.") +
495                        Twine(Object.ID.Value) + "'");
496     if (parseCalleeSavedRegister(MF, PFS, CSIInfo, Object.CalleeSavedRegister,
497                                  ObjectIdx))
498       return true;
499     if (Object.LocalOffset)
500       MFI.mapLocalFrameObject(ObjectIdx, Object.LocalOffset.getValue());
501     if (parseStackObjectsDebugInfo(MF, PFS, Object, ObjectIdx))
502       return true;
503   }
504   MFI.setCalleeSavedInfo(CSIInfo);
505   if (!CSIInfo.empty())
506     MFI.setCalleeSavedInfoValid(true);
507 
508   // Initialize the various stack object references after initializing the
509   // stack objects.
510   if (!YamlMFI.StackProtector.Value.empty()) {
511     SMDiagnostic Error;
512     int FI;
513     if (parseStackObjectReference(FI, SM, MF, YamlMFI.StackProtector.Value, PFS,
514                                   IRSlots, Error))
515       return error(Error, YamlMFI.StackProtector.SourceRange);
516     MFI.setStackProtectorIndex(FI);
517   }
518   return false;
519 }
520 
parseCalleeSavedRegister(MachineFunction & MF,PerFunctionMIParsingState & PFS,std::vector<CalleeSavedInfo> & CSIInfo,const yaml::StringValue & RegisterSource,int FrameIdx)521 bool MIRParserImpl::parseCalleeSavedRegister(
522     MachineFunction &MF, PerFunctionMIParsingState &PFS,
523     std::vector<CalleeSavedInfo> &CSIInfo,
524     const yaml::StringValue &RegisterSource, int FrameIdx) {
525   if (RegisterSource.Value.empty())
526     return false;
527   unsigned Reg = 0;
528   SMDiagnostic Error;
529   if (parseNamedRegisterReference(Reg, SM, MF, RegisterSource.Value, PFS,
530                                   IRSlots, Error))
531     return error(Error, RegisterSource.SourceRange);
532   CSIInfo.push_back(CalleeSavedInfo(Reg, FrameIdx));
533   return false;
534 }
535 
536 /// Verify that given node is of a certain type. Return true on error.
537 template <typename T>
typecheckMDNode(T * & Result,MDNode * Node,const yaml::StringValue & Source,StringRef TypeString,MIRParserImpl & Parser)538 static bool typecheckMDNode(T *&Result, MDNode *Node,
539                             const yaml::StringValue &Source,
540                             StringRef TypeString, MIRParserImpl &Parser) {
541   if (!Node)
542     return false;
543   Result = dyn_cast<T>(Node);
544   if (!Result)
545     return Parser.error(Source.SourceRange.Start,
546                         "expected a reference to a '" + TypeString +
547                             "' metadata node");
548   return false;
549 }
550 
parseStackObjectsDebugInfo(MachineFunction & MF,PerFunctionMIParsingState & PFS,const yaml::MachineStackObject & Object,int FrameIdx)551 bool MIRParserImpl::parseStackObjectsDebugInfo(
552     MachineFunction &MF, PerFunctionMIParsingState &PFS,
553     const yaml::MachineStackObject &Object, int FrameIdx) {
554   // Debug information can only be attached to stack objects; Fixed stack
555   // objects aren't supported.
556   assert(FrameIdx >= 0 && "Expected a stack object frame index");
557   MDNode *Var = nullptr, *Expr = nullptr, *Loc = nullptr;
558   if (parseMDNode(Var, Object.DebugVar, MF, PFS) ||
559       parseMDNode(Expr, Object.DebugExpr, MF, PFS) ||
560       parseMDNode(Loc, Object.DebugLoc, MF, PFS))
561     return true;
562   if (!Var && !Expr && !Loc)
563     return false;
564   DILocalVariable *DIVar = nullptr;
565   DIExpression *DIExpr = nullptr;
566   DILocation *DILoc = nullptr;
567   if (typecheckMDNode(DIVar, Var, Object.DebugVar, "DILocalVariable", *this) ||
568       typecheckMDNode(DIExpr, Expr, Object.DebugExpr, "DIExpression", *this) ||
569       typecheckMDNode(DILoc, Loc, Object.DebugLoc, "DILocation", *this))
570     return true;
571   MF.getMMI().setVariableDbgInfo(DIVar, DIExpr, unsigned(FrameIdx), DILoc);
572   return false;
573 }
574 
parseMDNode(MDNode * & Node,const yaml::StringValue & Source,MachineFunction & MF,const PerFunctionMIParsingState & PFS)575 bool MIRParserImpl::parseMDNode(MDNode *&Node, const yaml::StringValue &Source,
576                                 MachineFunction &MF,
577                                 const PerFunctionMIParsingState &PFS) {
578   if (Source.Value.empty())
579     return false;
580   SMDiagnostic Error;
581   if (llvm::parseMDNode(Node, SM, MF, Source.Value, PFS, IRSlots, Error))
582     return error(Error, Source.SourceRange);
583   return false;
584 }
585 
initializeConstantPool(MachineConstantPool & ConstantPool,const yaml::MachineFunction & YamlMF,const MachineFunction & MF,DenseMap<unsigned,unsigned> & ConstantPoolSlots)586 bool MIRParserImpl::initializeConstantPool(
587     MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF,
588     const MachineFunction &MF,
589     DenseMap<unsigned, unsigned> &ConstantPoolSlots) {
590   const auto &M = *MF.getFunction()->getParent();
591   SMDiagnostic Error;
592   for (const auto &YamlConstant : YamlMF.Constants) {
593     const Constant *Value = dyn_cast_or_null<Constant>(
594         parseConstantValue(YamlConstant.Value.Value, Error, M));
595     if (!Value)
596       return error(Error, YamlConstant.Value.SourceRange);
597     unsigned Alignment =
598         YamlConstant.Alignment
599             ? YamlConstant.Alignment
600             : M.getDataLayout().getPrefTypeAlignment(Value->getType());
601     unsigned Index = ConstantPool.getConstantPoolIndex(Value, Alignment);
602     if (!ConstantPoolSlots.insert(std::make_pair(YamlConstant.ID.Value, Index))
603              .second)
604       return error(YamlConstant.ID.SourceRange.Start,
605                    Twine("redefinition of constant pool item '%const.") +
606                        Twine(YamlConstant.ID.Value) + "'");
607   }
608   return false;
609 }
610 
initializeJumpTableInfo(MachineFunction & MF,const yaml::MachineJumpTable & YamlJTI,PerFunctionMIParsingState & PFS)611 bool MIRParserImpl::initializeJumpTableInfo(
612     MachineFunction &MF, const yaml::MachineJumpTable &YamlJTI,
613     PerFunctionMIParsingState &PFS) {
614   MachineJumpTableInfo *JTI = MF.getOrCreateJumpTableInfo(YamlJTI.Kind);
615   for (const auto &Entry : YamlJTI.Entries) {
616     std::vector<MachineBasicBlock *> Blocks;
617     for (const auto &MBBSource : Entry.Blocks) {
618       MachineBasicBlock *MBB = nullptr;
619       if (parseMBBReference(MBB, MBBSource.Value, MF, PFS))
620         return true;
621       Blocks.push_back(MBB);
622     }
623     unsigned Index = JTI->createJumpTableIndex(Blocks);
624     if (!PFS.JumpTableSlots.insert(std::make_pair(Entry.ID.Value, Index))
625              .second)
626       return error(Entry.ID.SourceRange.Start,
627                    Twine("redefinition of jump table entry '%jump-table.") +
628                        Twine(Entry.ID.Value) + "'");
629   }
630   return false;
631 }
632 
parseMBBReference(MachineBasicBlock * & MBB,const yaml::StringValue & Source,MachineFunction & MF,const PerFunctionMIParsingState & PFS)633 bool MIRParserImpl::parseMBBReference(MachineBasicBlock *&MBB,
634                                       const yaml::StringValue &Source,
635                                       MachineFunction &MF,
636                                       const PerFunctionMIParsingState &PFS) {
637   SMDiagnostic Error;
638   if (llvm::parseMBBReference(MBB, SM, MF, Source.Value, PFS, IRSlots, Error))
639     return error(Error, Source.SourceRange);
640   return false;
641 }
642 
diagFromMIStringDiag(const SMDiagnostic & Error,SMRange SourceRange)643 SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
644                                                  SMRange SourceRange) {
645   assert(SourceRange.isValid() && "Invalid source range");
646   SMLoc Loc = SourceRange.Start;
647   bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
648                   *Loc.getPointer() == '\'';
649   // Translate the location of the error from the location in the MI string to
650   // the corresponding location in the MIR file.
651   Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
652                            (HasQuote ? 1 : 0));
653 
654   // TODO: Translate any source ranges as well.
655   return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None,
656                        Error.getFixIts());
657 }
658 
diagFromBlockStringDiag(const SMDiagnostic & Error,SMRange SourceRange)659 SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error,
660                                                     SMRange SourceRange) {
661   assert(SourceRange.isValid());
662 
663   // Translate the location of the error from the location in the llvm IR string
664   // to the corresponding location in the MIR file.
665   auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
666   unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
667   unsigned Column = Error.getColumnNo();
668   StringRef LineStr = Error.getLineContents();
669   SMLoc Loc = Error.getLoc();
670 
671   // Get the full line and adjust the column number by taking the indentation of
672   // LLVM IR into account.
673   for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
674        L != E; ++L) {
675     if (L.line_number() == Line) {
676       LineStr = *L;
677       Loc = SMLoc::getFromPointer(LineStr.data());
678       auto Indent = LineStr.find(Error.getLineContents());
679       if (Indent != StringRef::npos)
680         Column += Indent;
681       break;
682     }
683   }
684 
685   return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
686                       Error.getMessage(), LineStr, Error.getRanges(),
687                       Error.getFixIts());
688 }
689 
initNames2RegClasses(const MachineFunction & MF)690 void MIRParserImpl::initNames2RegClasses(const MachineFunction &MF) {
691   if (!Names2RegClasses.empty())
692     return;
693   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
694   for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) {
695     const auto *RC = TRI->getRegClass(I);
696     Names2RegClasses.insert(
697         std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC));
698   }
699 }
700 
getRegClass(const MachineFunction & MF,StringRef Name)701 const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF,
702                                                       StringRef Name) {
703   initNames2RegClasses(MF);
704   auto RegClassInfo = Names2RegClasses.find(Name);
705   if (RegClassInfo == Names2RegClasses.end())
706     return nullptr;
707   return RegClassInfo->getValue();
708 }
709 
MIRParser(std::unique_ptr<MIRParserImpl> Impl)710 MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
711     : Impl(std::move(Impl)) {}
712 
~MIRParser()713 MIRParser::~MIRParser() {}
714 
parseLLVMModule()715 std::unique_ptr<Module> MIRParser::parseLLVMModule() { return Impl->parse(); }
716 
initializeMachineFunction(MachineFunction & MF)717 bool MIRParser::initializeMachineFunction(MachineFunction &MF) {
718   return Impl->initializeMachineFunction(MF);
719 }
720 
createMIRParserFromFile(StringRef Filename,SMDiagnostic & Error,LLVMContext & Context)721 std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename,
722                                                          SMDiagnostic &Error,
723                                                          LLVMContext &Context) {
724   auto FileOrErr = MemoryBuffer::getFile(Filename);
725   if (std::error_code EC = FileOrErr.getError()) {
726     Error = SMDiagnostic(Filename, SourceMgr::DK_Error,
727                          "Could not open input file: " + EC.message());
728     return nullptr;
729   }
730   return createMIRParser(std::move(FileOrErr.get()), Context);
731 }
732 
733 std::unique_ptr<MIRParser>
createMIRParser(std::unique_ptr<MemoryBuffer> Contents,LLVMContext & Context)734 llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
735                       LLVMContext &Context) {
736   auto Filename = Contents->getBufferIdentifier();
737   return llvm::make_unique<MIRParser>(
738       llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context));
739 }
740