xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/MIRParser/MIRParser.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===- MIRParser.cpp - MIR serialization format parser implementation -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the class that parses the optional LLVM IR and machine
10 // functions that are stored in MIR files.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/CodeGen/MIRParser/MIRParser.h"
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/AsmParser/Parser.h"
18 #include "llvm/AsmParser/SlotMapping.h"
19 #include "llvm/CodeGen/MIRParser/MIParser.h"
20 #include "llvm/CodeGen/MIRYamlMapping.h"
21 #include "llvm/CodeGen/MachineConstantPool.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
25 #include "llvm/CodeGen/MachineModuleInfo.h"
26 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 #include "llvm/CodeGen/TargetFrameLowering.h"
28 #include "llvm/IR/BasicBlock.h"
29 #include "llvm/IR/DebugInfoMetadata.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/MemoryBuffer.h"
37 #include "llvm/Support/SMLoc.h"
38 #include "llvm/Support/SourceMgr.h"
39 #include "llvm/Support/YAMLTraits.h"
40 #include "llvm/Target/TargetMachine.h"
41 #include <memory>
42 
43 using namespace llvm;
44 
45 namespace llvm {
46 class MDNode;
47 class RegisterBank;
48 
49 /// This class implements the parsing of LLVM IR that's embedded inside a MIR
50 /// file.
51 class MIRParserImpl {
52   SourceMgr SM;
53   LLVMContext &Context;
54   yaml::Input In;
55   StringRef Filename;
56   SlotMapping IRSlots;
57   std::unique_ptr<PerTargetMIParsingState> Target;
58 
59   /// True when the MIR file doesn't have LLVM IR. Dummy IR functions are
60   /// created and inserted into the given module when this is true.
61   bool NoLLVMIR = false;
62   /// True when a well formed MIR file does not contain any MIR/machine function
63   /// parts.
64   bool NoMIRDocuments = false;
65 
66   std::function<void(Function &)> ProcessIRFunction;
67 
68 public:
69   MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
70                 LLVMContext &Context,
71                 std::function<void(Function &)> ProcessIRFunction);
72 
73   void reportDiagnostic(const SMDiagnostic &Diag);
74 
75   /// Report an error with the given message at unknown location.
76   ///
77   /// Always returns true.
78   bool error(const Twine &Message);
79 
80   /// Report an error with the given message at the given location.
81   ///
82   /// Always returns true.
83   bool error(SMLoc Loc, const Twine &Message);
84 
85   /// Report a given error with the location translated from the location in an
86   /// embedded string literal to a location in the MIR file.
87   ///
88   /// Always returns true.
89   bool error(const SMDiagnostic &Error, SMRange SourceRange);
90 
91   /// Try to parse the optional LLVM module and the machine functions in the MIR
92   /// file.
93   ///
94   /// Return null if an error occurred.
95   std::unique_ptr<Module>
96   parseIRModule(DataLayoutCallbackTy DataLayoutCallback);
97 
98   /// Create an empty function with the given name.
99   Function *createDummyFunction(StringRef Name, Module &M);
100 
101   bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI,
102                              ModuleAnalysisManager *FAM = nullptr);
103 
104   /// Parse the machine function in the current YAML document.
105   ///
106   ///
107   /// Return true if an error occurred.
108   bool parseMachineFunction(Module &M, MachineModuleInfo &MMI,
109                             ModuleAnalysisManager *FAM);
110 
111   /// Initialize the machine function to the state that's described in the MIR
112   /// file.
113   ///
114   /// Return true if error occurred.
115   bool initializeMachineFunction(const yaml::MachineFunction &YamlMF,
116                                  MachineFunction &MF);
117 
118   bool parseRegisterInfo(PerFunctionMIParsingState &PFS,
119                          const yaml::MachineFunction &YamlMF);
120 
121   bool setupRegisterInfo(const PerFunctionMIParsingState &PFS,
122                          const yaml::MachineFunction &YamlMF);
123 
124   bool initializeFrameInfo(PerFunctionMIParsingState &PFS,
125                            const yaml::MachineFunction &YamlMF);
126 
127   bool initializeCallSiteInfo(PerFunctionMIParsingState &PFS,
128                               const yaml::MachineFunction &YamlMF);
129 
130   bool parseCalleeSavedRegister(PerFunctionMIParsingState &PFS,
131                                 std::vector<CalleeSavedInfo> &CSIInfo,
132                                 const yaml::StringValue &RegisterSource,
133                                 bool IsRestored, int FrameIdx);
134 
135   struct VarExprLoc {
136     DILocalVariable *DIVar = nullptr;
137     DIExpression *DIExpr = nullptr;
138     DILocation *DILoc = nullptr;
139   };
140 
141   std::optional<VarExprLoc> parseVarExprLoc(PerFunctionMIParsingState &PFS,
142                                             const yaml::StringValue &VarStr,
143                                             const yaml::StringValue &ExprStr,
144                                             const yaml::StringValue &LocStr);
145   template <typename T>
146   bool parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS,
147                                   const T &Object,
148                                   int FrameIdx);
149 
150   bool initializeConstantPool(PerFunctionMIParsingState &PFS,
151                               MachineConstantPool &ConstantPool,
152                               const yaml::MachineFunction &YamlMF);
153 
154   bool initializeJumpTableInfo(PerFunctionMIParsingState &PFS,
155                                const yaml::MachineJumpTable &YamlJTI);
156 
157   bool parseMachineMetadataNodes(PerFunctionMIParsingState &PFS,
158                                  MachineFunction &MF,
159                                  const yaml::MachineFunction &YMF);
160 
161 private:
162   bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node,
163                    const yaml::StringValue &Source);
164 
165   bool parseMBBReference(PerFunctionMIParsingState &PFS,
166                          MachineBasicBlock *&MBB,
167                          const yaml::StringValue &Source);
168 
169   bool parseMachineMetadata(PerFunctionMIParsingState &PFS,
170                             const yaml::StringValue &Source);
171 
172   /// Return a MIR diagnostic converted from an MI string diagnostic.
173   SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
174                                     SMRange SourceRange);
175 
176   /// Return a MIR diagnostic converted from a diagnostic located in a YAML
177   /// block scalar string.
178   SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error,
179                                        SMRange SourceRange);
180 
181   void computeFunctionProperties(MachineFunction &MF);
182 
183   void setupDebugValueTracking(MachineFunction &MF,
184     PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF);
185 };
186 
187 } // end namespace llvm
188 
handleYAMLDiag(const SMDiagnostic & Diag,void * Context)189 static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
190   reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
191 }
192 
MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,StringRef Filename,LLVMContext & Context,std::function<void (Function &)> Callback)193 MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
194                              StringRef Filename, LLVMContext &Context,
195                              std::function<void(Function &)> Callback)
196     : Context(Context),
197       In(SM.getMemoryBuffer(SM.AddNewSourceBuffer(std::move(Contents), SMLoc()))
198              ->getBuffer(),
199          nullptr, handleYAMLDiag, this),
200       Filename(Filename), ProcessIRFunction(Callback) {
201   In.setContext(&In);
202 }
203 
error(const Twine & Message)204 bool MIRParserImpl::error(const Twine &Message) {
205   Context.diagnose(DiagnosticInfoMIRParser(
206       DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));
207   return true;
208 }
209 
error(SMLoc Loc,const Twine & Message)210 bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) {
211   Context.diagnose(DiagnosticInfoMIRParser(
212       DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message)));
213   return true;
214 }
215 
error(const SMDiagnostic & Error,SMRange SourceRange)216 bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) {
217   assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");
218   reportDiagnostic(diagFromMIStringDiag(Error, SourceRange));
219   return true;
220 }
221 
reportDiagnostic(const SMDiagnostic & Diag)222 void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
223   DiagnosticSeverity Kind;
224   switch (Diag.getKind()) {
225   case SourceMgr::DK_Error:
226     Kind = DS_Error;
227     break;
228   case SourceMgr::DK_Warning:
229     Kind = DS_Warning;
230     break;
231   case SourceMgr::DK_Note:
232     Kind = DS_Note;
233     break;
234   case SourceMgr::DK_Remark:
235     llvm_unreachable("remark unexpected");
236     break;
237   }
238   Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
239 }
240 
241 std::unique_ptr<Module>
parseIRModule(DataLayoutCallbackTy DataLayoutCallback)242 MIRParserImpl::parseIRModule(DataLayoutCallbackTy DataLayoutCallback) {
243   if (!In.setCurrentDocument()) {
244     if (In.error())
245       return nullptr;
246     // Create an empty module when the MIR file is empty.
247     NoMIRDocuments = true;
248     auto M = std::make_unique<Module>(Filename, Context);
249     if (auto LayoutOverride =
250             DataLayoutCallback(M->getTargetTriple(), M->getDataLayoutStr()))
251       M->setDataLayout(*LayoutOverride);
252     return M;
253   }
254 
255   std::unique_ptr<Module> M;
256   // Parse the block scalar manually so that we can return unique pointer
257   // without having to go trough YAML traits.
258   if (const auto *BSN =
259           dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
260     SMDiagnostic Error;
261     M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
262                       Context, &IRSlots, DataLayoutCallback);
263     if (!M) {
264       reportDiagnostic(diagFromBlockStringDiag(Error, BSN->getSourceRange()));
265       return nullptr;
266     }
267     In.nextDocument();
268     if (!In.setCurrentDocument())
269       NoMIRDocuments = true;
270   } else {
271     // Create an new, empty module.
272     M = std::make_unique<Module>(Filename, Context);
273     if (auto LayoutOverride =
274             DataLayoutCallback(M->getTargetTriple(), M->getDataLayoutStr()))
275       M->setDataLayout(*LayoutOverride);
276     NoLLVMIR = true;
277   }
278   return M;
279 }
280 
parseMachineFunctions(Module & M,MachineModuleInfo & MMI,ModuleAnalysisManager * MAM)281 bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI,
282                                           ModuleAnalysisManager *MAM) {
283   if (NoMIRDocuments)
284     return false;
285 
286   // Parse the machine functions.
287   do {
288     if (parseMachineFunction(M, MMI, MAM))
289       return true;
290     In.nextDocument();
291   } while (In.setCurrentDocument());
292 
293   return false;
294 }
295 
createDummyFunction(StringRef Name,Module & M)296 Function *MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
297   auto &Context = M.getContext();
298   Function *F =
299       Function::Create(FunctionType::get(Type::getVoidTy(Context), false),
300                        Function::ExternalLinkage, Name, M);
301   BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
302   new UnreachableInst(Context, BB);
303 
304   if (ProcessIRFunction)
305     ProcessIRFunction(*F);
306 
307   return F;
308 }
309 
parseMachineFunction(Module & M,MachineModuleInfo & MMI,ModuleAnalysisManager * MAM)310 bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI,
311                                          ModuleAnalysisManager *MAM) {
312   // Parse the yaml.
313   yaml::MachineFunction YamlMF;
314   yaml::EmptyContext Ctx;
315 
316   const LLVMTargetMachine &TM = MMI.getTarget();
317   YamlMF.MachineFuncInfo = std::unique_ptr<yaml::MachineFunctionInfo>(
318       TM.createDefaultFuncInfoYAML());
319 
320   yaml::yamlize(In, YamlMF, false, Ctx);
321   if (In.error())
322     return true;
323 
324   // Search for the corresponding IR function.
325   StringRef FunctionName = YamlMF.Name;
326   Function *F = M.getFunction(FunctionName);
327   if (!F) {
328     if (NoLLVMIR) {
329       F = createDummyFunction(FunctionName, M);
330     } else {
331       return error(Twine("function '") + FunctionName +
332                    "' isn't defined in the provided LLVM IR");
333     }
334   }
335 
336   if (!MAM) {
337     if (MMI.getMachineFunction(*F) != nullptr)
338       return error(Twine("redefinition of machine function '") + FunctionName +
339                    "'");
340 
341     // Create the MachineFunction.
342     MachineFunction &MF = MMI.getOrCreateMachineFunction(*F);
343     if (initializeMachineFunction(YamlMF, MF))
344       return true;
345   } else {
346     auto &FAM =
347         MAM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
348     if (FAM.getCachedResult<MachineFunctionAnalysis>(*F))
349       return error(Twine("redefinition of machine function '") + FunctionName +
350                    "'");
351 
352     // Create the MachineFunction.
353     MachineFunction &MF = FAM.getResult<MachineFunctionAnalysis>(*F).getMF();
354     if (initializeMachineFunction(YamlMF, MF))
355       return true;
356   }
357 
358   return false;
359 }
360 
isSSA(const MachineFunction & MF)361 static bool isSSA(const MachineFunction &MF) {
362   const MachineRegisterInfo &MRI = MF.getRegInfo();
363   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
364     Register Reg = Register::index2VirtReg(I);
365     if (!MRI.hasOneDef(Reg) && !MRI.def_empty(Reg))
366       return false;
367 
368     // Subregister defs are invalid in SSA.
369     const MachineOperand *RegDef = MRI.getOneDef(Reg);
370     if (RegDef && RegDef->getSubReg() != 0)
371       return false;
372   }
373   return true;
374 }
375 
computeFunctionProperties(MachineFunction & MF)376 void MIRParserImpl::computeFunctionProperties(MachineFunction &MF) {
377   MachineFunctionProperties &Properties = MF.getProperties();
378 
379   bool HasPHI = false;
380   bool HasInlineAsm = false;
381   bool AllTiedOpsRewritten = true, HasTiedOps = false;
382   for (const MachineBasicBlock &MBB : MF) {
383     for (const MachineInstr &MI : MBB) {
384       if (MI.isPHI())
385         HasPHI = true;
386       if (MI.isInlineAsm())
387         HasInlineAsm = true;
388       for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
389         const MachineOperand &MO = MI.getOperand(I);
390         if (!MO.isReg() || !MO.getReg())
391           continue;
392         unsigned DefIdx;
393         if (MO.isUse() && MI.isRegTiedToDefOperand(I, &DefIdx)) {
394           HasTiedOps = true;
395           if (MO.getReg() != MI.getOperand(DefIdx).getReg())
396             AllTiedOpsRewritten = false;
397         }
398       }
399     }
400   }
401   if (!HasPHI)
402     Properties.set(MachineFunctionProperties::Property::NoPHIs);
403   MF.setHasInlineAsm(HasInlineAsm);
404 
405   if (HasTiedOps && AllTiedOpsRewritten)
406     Properties.set(MachineFunctionProperties::Property::TiedOpsRewritten);
407 
408   if (isSSA(MF))
409     Properties.set(MachineFunctionProperties::Property::IsSSA);
410   else
411     Properties.reset(MachineFunctionProperties::Property::IsSSA);
412 
413   const MachineRegisterInfo &MRI = MF.getRegInfo();
414   if (MRI.getNumVirtRegs() == 0)
415     Properties.set(MachineFunctionProperties::Property::NoVRegs);
416 }
417 
initializeCallSiteInfo(PerFunctionMIParsingState & PFS,const yaml::MachineFunction & YamlMF)418 bool MIRParserImpl::initializeCallSiteInfo(
419     PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF) {
420   MachineFunction &MF = PFS.MF;
421   SMDiagnostic Error;
422   const LLVMTargetMachine &TM = MF.getTarget();
423   for (auto &YamlCSInfo : YamlMF.CallSitesInfo) {
424     yaml::CallSiteInfo::MachineInstrLoc MILoc = YamlCSInfo.CallLocation;
425     if (MILoc.BlockNum >= MF.size())
426       return error(Twine(MF.getName()) +
427                    Twine(" call instruction block out of range.") +
428                    " Unable to reference bb:" + Twine(MILoc.BlockNum));
429     auto CallB = std::next(MF.begin(), MILoc.BlockNum);
430     if (MILoc.Offset >= CallB->size())
431       return error(Twine(MF.getName()) +
432                    Twine(" call instruction offset out of range.") +
433                    " Unable to reference instruction at bb: " +
434                    Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset));
435     auto CallI = std::next(CallB->instr_begin(), MILoc.Offset);
436     if (!CallI->isCall(MachineInstr::IgnoreBundle))
437       return error(Twine(MF.getName()) +
438                    Twine(" call site info should reference call "
439                          "instruction. Instruction at bb:") +
440                    Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset) +
441                    " is not a call instruction");
442     MachineFunction::CallSiteInfo CSInfo;
443     for (auto ArgRegPair : YamlCSInfo.ArgForwardingRegs) {
444       Register Reg;
445       if (parseNamedRegisterReference(PFS, Reg, ArgRegPair.Reg.Value, Error))
446         return error(Error, ArgRegPair.Reg.SourceRange);
447       CSInfo.ArgRegPairs.emplace_back(Reg, ArgRegPair.ArgNo);
448     }
449 
450     if (TM.Options.EmitCallSiteInfo)
451       MF.addCallSiteInfo(&*CallI, std::move(CSInfo));
452   }
453 
454   if (YamlMF.CallSitesInfo.size() && !TM.Options.EmitCallSiteInfo)
455     return error(Twine("Call site info provided but not used"));
456   return false;
457 }
458 
setupDebugValueTracking(MachineFunction & MF,PerFunctionMIParsingState & PFS,const yaml::MachineFunction & YamlMF)459 void MIRParserImpl::setupDebugValueTracking(
460     MachineFunction &MF, PerFunctionMIParsingState &PFS,
461     const yaml::MachineFunction &YamlMF) {
462   // Compute the value of the "next instruction number" field.
463   unsigned MaxInstrNum = 0;
464   for (auto &MBB : MF)
465     for (auto &MI : MBB)
466       MaxInstrNum = std::max((unsigned)MI.peekDebugInstrNum(), MaxInstrNum);
467   MF.setDebugInstrNumberingCount(MaxInstrNum);
468 
469   // Load any substitutions.
470   for (const auto &Sub : YamlMF.DebugValueSubstitutions) {
471     MF.makeDebugValueSubstitution({Sub.SrcInst, Sub.SrcOp},
472                                   {Sub.DstInst, Sub.DstOp}, Sub.Subreg);
473   }
474 
475   // Flag for whether we're supposed to be using DBG_INSTR_REF.
476   MF.setUseDebugInstrRef(YamlMF.UseDebugInstrRef);
477 }
478 
479 bool
initializeMachineFunction(const yaml::MachineFunction & YamlMF,MachineFunction & MF)480 MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
481                                          MachineFunction &MF) {
482   // TODO: Recreate the machine function.
483   if (Target) {
484     // Avoid clearing state if we're using the same subtarget again.
485     Target->setTarget(MF.getSubtarget());
486   } else {
487     Target.reset(new PerTargetMIParsingState(MF.getSubtarget()));
488   }
489 
490   MF.setAlignment(YamlMF.Alignment.valueOrOne());
491   MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
492   MF.setHasWinCFI(YamlMF.HasWinCFI);
493 
494   MF.setCallsEHReturn(YamlMF.CallsEHReturn);
495   MF.setCallsUnwindInit(YamlMF.CallsUnwindInit);
496   MF.setHasEHCatchret(YamlMF.HasEHCatchret);
497   MF.setHasEHScopes(YamlMF.HasEHScopes);
498   MF.setHasEHFunclets(YamlMF.HasEHFunclets);
499   MF.setIsOutlined(YamlMF.IsOutlined);
500 
501   if (YamlMF.Legalized)
502     MF.getProperties().set(MachineFunctionProperties::Property::Legalized);
503   if (YamlMF.RegBankSelected)
504     MF.getProperties().set(
505         MachineFunctionProperties::Property::RegBankSelected);
506   if (YamlMF.Selected)
507     MF.getProperties().set(MachineFunctionProperties::Property::Selected);
508   if (YamlMF.FailedISel)
509     MF.getProperties().set(MachineFunctionProperties::Property::FailedISel);
510   if (YamlMF.FailsVerification)
511     MF.getProperties().set(
512         MachineFunctionProperties::Property::FailsVerification);
513   if (YamlMF.TracksDebugUserValues)
514     MF.getProperties().set(
515         MachineFunctionProperties::Property::TracksDebugUserValues);
516 
517   PerFunctionMIParsingState PFS(MF, SM, IRSlots, *Target);
518   if (parseRegisterInfo(PFS, YamlMF))
519     return true;
520   if (!YamlMF.Constants.empty()) {
521     auto *ConstantPool = MF.getConstantPool();
522     assert(ConstantPool && "Constant pool must be created");
523     if (initializeConstantPool(PFS, *ConstantPool, YamlMF))
524       return true;
525   }
526   if (!YamlMF.MachineMetadataNodes.empty() &&
527       parseMachineMetadataNodes(PFS, MF, YamlMF))
528     return true;
529 
530   StringRef BlockStr = YamlMF.Body.Value.Value;
531   SMDiagnostic Error;
532   SourceMgr BlockSM;
533   BlockSM.AddNewSourceBuffer(
534       MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false),
535       SMLoc());
536   PFS.SM = &BlockSM;
537   if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)) {
538     reportDiagnostic(
539         diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
540     return true;
541   }
542   // Check Basic Block Section Flags.
543   if (MF.getTarget().getBBSectionsType() == BasicBlockSection::Labels) {
544     MF.setBBSectionsType(BasicBlockSection::Labels);
545   } else if (MF.hasBBSections()) {
546     MF.assignBeginEndSections();
547   }
548   PFS.SM = &SM;
549 
550   // Initialize the frame information after creating all the MBBs so that the
551   // MBB references in the frame information can be resolved.
552   if (initializeFrameInfo(PFS, YamlMF))
553     return true;
554   // Initialize the jump table after creating all the MBBs so that the MBB
555   // references can be resolved.
556   if (!YamlMF.JumpTableInfo.Entries.empty() &&
557       initializeJumpTableInfo(PFS, YamlMF.JumpTableInfo))
558     return true;
559   // Parse the machine instructions after creating all of the MBBs so that the
560   // parser can resolve the MBB references.
561   StringRef InsnStr = YamlMF.Body.Value.Value;
562   SourceMgr InsnSM;
563   InsnSM.AddNewSourceBuffer(
564       MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false),
565       SMLoc());
566   PFS.SM = &InsnSM;
567   if (parseMachineInstructions(PFS, InsnStr, Error)) {
568     reportDiagnostic(
569         diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
570     return true;
571   }
572   PFS.SM = &SM;
573 
574   if (setupRegisterInfo(PFS, YamlMF))
575     return true;
576 
577   if (YamlMF.MachineFuncInfo) {
578     const LLVMTargetMachine &TM = MF.getTarget();
579     // Note this is called after the initial constructor of the
580     // MachineFunctionInfo based on the MachineFunction, which may depend on the
581     // IR.
582 
583     SMRange SrcRange;
584     if (TM.parseMachineFunctionInfo(*YamlMF.MachineFuncInfo, PFS, Error,
585                                     SrcRange)) {
586       return error(Error, SrcRange);
587     }
588   }
589 
590   // Set the reserved registers after parsing MachineFuncInfo. The target may
591   // have been recording information used to select the reserved registers
592   // there.
593   // FIXME: This is a temporary workaround until the reserved registers can be
594   // serialized.
595   MachineRegisterInfo &MRI = MF.getRegInfo();
596   MRI.freezeReservedRegs();
597 
598   computeFunctionProperties(MF);
599 
600   if (initializeCallSiteInfo(PFS, YamlMF))
601     return false;
602 
603   setupDebugValueTracking(MF, PFS, YamlMF);
604 
605   MF.getSubtarget().mirFileLoaded(MF);
606 
607   MF.verify();
608   return false;
609 }
610 
parseRegisterInfo(PerFunctionMIParsingState & PFS,const yaml::MachineFunction & YamlMF)611 bool MIRParserImpl::parseRegisterInfo(PerFunctionMIParsingState &PFS,
612                                       const yaml::MachineFunction &YamlMF) {
613   MachineFunction &MF = PFS.MF;
614   MachineRegisterInfo &RegInfo = MF.getRegInfo();
615   assert(RegInfo.tracksLiveness());
616   if (!YamlMF.TracksRegLiveness)
617     RegInfo.invalidateLiveness();
618 
619   SMDiagnostic Error;
620   // Parse the virtual register information.
621   for (const auto &VReg : YamlMF.VirtualRegisters) {
622     VRegInfo &Info = PFS.getVRegInfo(VReg.ID.Value);
623     if (Info.Explicit)
624       return error(VReg.ID.SourceRange.Start,
625                    Twine("redefinition of virtual register '%") +
626                        Twine(VReg.ID.Value) + "'");
627     Info.Explicit = true;
628 
629     if (VReg.Class.Value == "_") {
630       Info.Kind = VRegInfo::GENERIC;
631       Info.D.RegBank = nullptr;
632     } else {
633       const auto *RC = Target->getRegClass(VReg.Class.Value);
634       if (RC) {
635         Info.Kind = VRegInfo::NORMAL;
636         Info.D.RC = RC;
637       } else {
638         const RegisterBank *RegBank = Target->getRegBank(VReg.Class.Value);
639         if (!RegBank)
640           return error(
641               VReg.Class.SourceRange.Start,
642               Twine("use of undefined register class or register bank '") +
643                   VReg.Class.Value + "'");
644         Info.Kind = VRegInfo::REGBANK;
645         Info.D.RegBank = RegBank;
646       }
647     }
648 
649     if (!VReg.PreferredRegister.Value.empty()) {
650       if (Info.Kind != VRegInfo::NORMAL)
651         return error(VReg.Class.SourceRange.Start,
652               Twine("preferred register can only be set for normal vregs"));
653 
654       if (parseRegisterReference(PFS, Info.PreferredReg,
655                                  VReg.PreferredRegister.Value, Error))
656         return error(Error, VReg.PreferredRegister.SourceRange);
657     }
658   }
659 
660   // Parse the liveins.
661   for (const auto &LiveIn : YamlMF.LiveIns) {
662     Register Reg;
663     if (parseNamedRegisterReference(PFS, Reg, LiveIn.Register.Value, Error))
664       return error(Error, LiveIn.Register.SourceRange);
665     Register VReg;
666     if (!LiveIn.VirtualRegister.Value.empty()) {
667       VRegInfo *Info;
668       if (parseVirtualRegisterReference(PFS, Info, LiveIn.VirtualRegister.Value,
669                                         Error))
670         return error(Error, LiveIn.VirtualRegister.SourceRange);
671       VReg = Info->VReg;
672     }
673     RegInfo.addLiveIn(Reg, VReg);
674   }
675 
676   // Parse the callee saved registers (Registers that will
677   // be saved for the caller).
678   if (YamlMF.CalleeSavedRegisters) {
679     SmallVector<MCPhysReg, 16> CalleeSavedRegisters;
680     for (const auto &RegSource : *YamlMF.CalleeSavedRegisters) {
681       Register Reg;
682       if (parseNamedRegisterReference(PFS, Reg, RegSource.Value, Error))
683         return error(Error, RegSource.SourceRange);
684       CalleeSavedRegisters.push_back(Reg);
685     }
686     RegInfo.setCalleeSavedRegs(CalleeSavedRegisters);
687   }
688 
689   return false;
690 }
691 
setupRegisterInfo(const PerFunctionMIParsingState & PFS,const yaml::MachineFunction & YamlMF)692 bool MIRParserImpl::setupRegisterInfo(const PerFunctionMIParsingState &PFS,
693                                       const yaml::MachineFunction &YamlMF) {
694   MachineFunction &MF = PFS.MF;
695   MachineRegisterInfo &MRI = MF.getRegInfo();
696   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
697 
698   bool Error = false;
699   // Create VRegs
700   auto populateVRegInfo = [&](const VRegInfo &Info, Twine Name) {
701     Register Reg = Info.VReg;
702     switch (Info.Kind) {
703     case VRegInfo::UNKNOWN:
704       error(Twine("Cannot determine class/bank of virtual register ") +
705             Name + " in function '" + MF.getName() + "'");
706       Error = true;
707       break;
708     case VRegInfo::NORMAL:
709       if (!Info.D.RC->isAllocatable()) {
710         error(Twine("Cannot use non-allocatable class '") +
711               TRI->getRegClassName(Info.D.RC) + "' for virtual register " +
712               Name + " in function '" + MF.getName() + "'");
713         Error = true;
714         break;
715       }
716 
717       MRI.setRegClass(Reg, Info.D.RC);
718       if (Info.PreferredReg != 0)
719         MRI.setSimpleHint(Reg, Info.PreferredReg);
720       break;
721     case VRegInfo::GENERIC:
722       break;
723     case VRegInfo::REGBANK:
724       MRI.setRegBank(Reg, *Info.D.RegBank);
725       break;
726     }
727   };
728 
729   for (const auto &P : PFS.VRegInfosNamed) {
730     const VRegInfo &Info = *P.second;
731     populateVRegInfo(Info, Twine(P.first()));
732   }
733 
734   for (auto P : PFS.VRegInfos) {
735     const VRegInfo &Info = *P.second;
736     populateVRegInfo(Info, Twine(P.first));
737   }
738 
739   // Compute MachineRegisterInfo::UsedPhysRegMask
740   for (const MachineBasicBlock &MBB : MF) {
741     // Make sure MRI knows about registers clobbered by unwinder.
742     if (MBB.isEHPad())
743       if (auto *RegMask = TRI->getCustomEHPadPreservedMask(MF))
744         MRI.addPhysRegsUsedFromRegMask(RegMask);
745 
746     for (const MachineInstr &MI : MBB) {
747       for (const MachineOperand &MO : MI.operands()) {
748         if (!MO.isRegMask())
749           continue;
750         MRI.addPhysRegsUsedFromRegMask(MO.getRegMask());
751       }
752     }
753   }
754 
755   return Error;
756 }
757 
initializeFrameInfo(PerFunctionMIParsingState & PFS,const yaml::MachineFunction & YamlMF)758 bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS,
759                                         const yaml::MachineFunction &YamlMF) {
760   MachineFunction &MF = PFS.MF;
761   MachineFrameInfo &MFI = MF.getFrameInfo();
762   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
763   const Function &F = MF.getFunction();
764   const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
765   MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
766   MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
767   MFI.setHasStackMap(YamlMFI.HasStackMap);
768   MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);
769   MFI.setStackSize(YamlMFI.StackSize);
770   MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment);
771   if (YamlMFI.MaxAlignment)
772     MFI.ensureMaxAlignment(Align(YamlMFI.MaxAlignment));
773   MFI.setAdjustsStack(YamlMFI.AdjustsStack);
774   MFI.setHasCalls(YamlMFI.HasCalls);
775   if (YamlMFI.MaxCallFrameSize != ~0u)
776     MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize);
777   MFI.setCVBytesOfCalleeSavedRegisters(YamlMFI.CVBytesOfCalleeSavedRegisters);
778   MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);
779   MFI.setHasVAStart(YamlMFI.HasVAStart);
780   MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
781   MFI.setHasTailCall(YamlMFI.HasTailCall);
782   MFI.setCalleeSavedInfoValid(YamlMFI.IsCalleeSavedInfoValid);
783   MFI.setLocalFrameSize(YamlMFI.LocalFrameSize);
784   if (!YamlMFI.SavePoint.Value.empty()) {
785     MachineBasicBlock *MBB = nullptr;
786     if (parseMBBReference(PFS, MBB, YamlMFI.SavePoint))
787       return true;
788     MFI.setSavePoint(MBB);
789   }
790   if (!YamlMFI.RestorePoint.Value.empty()) {
791     MachineBasicBlock *MBB = nullptr;
792     if (parseMBBReference(PFS, MBB, YamlMFI.RestorePoint))
793       return true;
794     MFI.setRestorePoint(MBB);
795   }
796 
797   std::vector<CalleeSavedInfo> CSIInfo;
798   // Initialize the fixed frame objects.
799   for (const auto &Object : YamlMF.FixedStackObjects) {
800     int ObjectIdx;
801     if (Object.Type != yaml::FixedMachineStackObject::SpillSlot)
802       ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset,
803                                         Object.IsImmutable, Object.IsAliased);
804     else
805       ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
806 
807     if (!TFI->isSupportedStackID(Object.StackID))
808       return error(Object.ID.SourceRange.Start,
809                    Twine("StackID is not supported by target"));
810     MFI.setStackID(ObjectIdx, Object.StackID);
811     MFI.setObjectAlignment(ObjectIdx, Object.Alignment.valueOrOne());
812     if (!PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID.Value,
813                                                          ObjectIdx))
814              .second)
815       return error(Object.ID.SourceRange.Start,
816                    Twine("redefinition of fixed stack object '%fixed-stack.") +
817                        Twine(Object.ID.Value) + "'");
818     if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister,
819                                  Object.CalleeSavedRestored, ObjectIdx))
820       return true;
821     if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx))
822       return true;
823   }
824 
825   for (const auto &Object : YamlMF.EntryValueObjects) {
826     SMDiagnostic Error;
827     Register Reg;
828     if (parseNamedRegisterReference(PFS, Reg, Object.EntryValueRegister.Value,
829                                     Error))
830       return error(Error, Object.EntryValueRegister.SourceRange);
831     if (!Reg.isPhysical())
832       return error(Object.EntryValueRegister.SourceRange.Start,
833                    "Expected physical register for entry value field");
834     std::optional<VarExprLoc> MaybeInfo = parseVarExprLoc(
835         PFS, Object.DebugVar, Object.DebugExpr, Object.DebugLoc);
836     if (!MaybeInfo)
837       return true;
838     if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc)
839       PFS.MF.setVariableDbgInfo(MaybeInfo->DIVar, MaybeInfo->DIExpr,
840                                 Reg.asMCReg(), MaybeInfo->DILoc);
841   }
842 
843   // Initialize the ordinary frame objects.
844   for (const auto &Object : YamlMF.StackObjects) {
845     int ObjectIdx;
846     const AllocaInst *Alloca = nullptr;
847     const yaml::StringValue &Name = Object.Name;
848     if (!Name.Value.empty()) {
849       Alloca = dyn_cast_or_null<AllocaInst>(
850           F.getValueSymbolTable()->lookup(Name.Value));
851       if (!Alloca)
852         return error(Name.SourceRange.Start,
853                      "alloca instruction named '" + Name.Value +
854                          "' isn't defined in the function '" + F.getName() +
855                          "'");
856     }
857     if (!TFI->isSupportedStackID(Object.StackID))
858       return error(Object.ID.SourceRange.Start,
859                    Twine("StackID is not supported by target"));
860     if (Object.Type == yaml::MachineStackObject::VariableSized)
861       ObjectIdx =
862           MFI.CreateVariableSizedObject(Object.Alignment.valueOrOne(), Alloca);
863     else
864       ObjectIdx = MFI.CreateStackObject(
865           Object.Size, Object.Alignment.valueOrOne(),
866           Object.Type == yaml::MachineStackObject::SpillSlot, Alloca,
867           Object.StackID);
868     MFI.setObjectOffset(ObjectIdx, Object.Offset);
869 
870     if (!PFS.StackObjectSlots.insert(std::make_pair(Object.ID.Value, ObjectIdx))
871              .second)
872       return error(Object.ID.SourceRange.Start,
873                    Twine("redefinition of stack object '%stack.") +
874                        Twine(Object.ID.Value) + "'");
875     if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister,
876                                  Object.CalleeSavedRestored, ObjectIdx))
877       return true;
878     if (Object.LocalOffset)
879       MFI.mapLocalFrameObject(ObjectIdx, *Object.LocalOffset);
880     if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx))
881       return true;
882   }
883   MFI.setCalleeSavedInfo(CSIInfo);
884   if (!CSIInfo.empty())
885     MFI.setCalleeSavedInfoValid(true);
886 
887   // Initialize the various stack object references after initializing the
888   // stack objects.
889   if (!YamlMFI.StackProtector.Value.empty()) {
890     SMDiagnostic Error;
891     int FI;
892     if (parseStackObjectReference(PFS, FI, YamlMFI.StackProtector.Value, Error))
893       return error(Error, YamlMFI.StackProtector.SourceRange);
894     MFI.setStackProtectorIndex(FI);
895   }
896 
897   if (!YamlMFI.FunctionContext.Value.empty()) {
898     SMDiagnostic Error;
899     int FI;
900     if (parseStackObjectReference(PFS, FI, YamlMFI.FunctionContext.Value, Error))
901       return error(Error, YamlMFI.FunctionContext.SourceRange);
902     MFI.setFunctionContextIndex(FI);
903   }
904 
905   return false;
906 }
907 
parseCalleeSavedRegister(PerFunctionMIParsingState & PFS,std::vector<CalleeSavedInfo> & CSIInfo,const yaml::StringValue & RegisterSource,bool IsRestored,int FrameIdx)908 bool MIRParserImpl::parseCalleeSavedRegister(PerFunctionMIParsingState &PFS,
909     std::vector<CalleeSavedInfo> &CSIInfo,
910     const yaml::StringValue &RegisterSource, bool IsRestored, int FrameIdx) {
911   if (RegisterSource.Value.empty())
912     return false;
913   Register Reg;
914   SMDiagnostic Error;
915   if (parseNamedRegisterReference(PFS, Reg, RegisterSource.Value, Error))
916     return error(Error, RegisterSource.SourceRange);
917   CalleeSavedInfo CSI(Reg, FrameIdx);
918   CSI.setRestored(IsRestored);
919   CSIInfo.push_back(CSI);
920   return false;
921 }
922 
923 /// Verify that given node is of a certain type. Return true on error.
924 template <typename T>
typecheckMDNode(T * & Result,MDNode * Node,const yaml::StringValue & Source,StringRef TypeString,MIRParserImpl & Parser)925 static bool typecheckMDNode(T *&Result, MDNode *Node,
926                             const yaml::StringValue &Source,
927                             StringRef TypeString, MIRParserImpl &Parser) {
928   if (!Node)
929     return false;
930   Result = dyn_cast<T>(Node);
931   if (!Result)
932     return Parser.error(Source.SourceRange.Start,
933                         "expected a reference to a '" + TypeString +
934                             "' metadata node");
935   return false;
936 }
937 
parseVarExprLoc(PerFunctionMIParsingState & PFS,const yaml::StringValue & VarStr,const yaml::StringValue & ExprStr,const yaml::StringValue & LocStr)938 std::optional<MIRParserImpl::VarExprLoc> MIRParserImpl::parseVarExprLoc(
939     PerFunctionMIParsingState &PFS, const yaml::StringValue &VarStr,
940     const yaml::StringValue &ExprStr, const yaml::StringValue &LocStr) {
941   MDNode *Var = nullptr;
942   MDNode *Expr = nullptr;
943   MDNode *Loc = nullptr;
944   if (parseMDNode(PFS, Var, VarStr) || parseMDNode(PFS, Expr, ExprStr) ||
945       parseMDNode(PFS, Loc, LocStr))
946     return std::nullopt;
947   DILocalVariable *DIVar = nullptr;
948   DIExpression *DIExpr = nullptr;
949   DILocation *DILoc = nullptr;
950   if (typecheckMDNode(DIVar, Var, VarStr, "DILocalVariable", *this) ||
951       typecheckMDNode(DIExpr, Expr, ExprStr, "DIExpression", *this) ||
952       typecheckMDNode(DILoc, Loc, LocStr, "DILocation", *this))
953     return std::nullopt;
954   return VarExprLoc{DIVar, DIExpr, DILoc};
955 }
956 
957 template <typename T>
parseStackObjectsDebugInfo(PerFunctionMIParsingState & PFS,const T & Object,int FrameIdx)958 bool MIRParserImpl::parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS,
959                                                const T &Object, int FrameIdx) {
960   std::optional<VarExprLoc> MaybeInfo =
961       parseVarExprLoc(PFS, Object.DebugVar, Object.DebugExpr, Object.DebugLoc);
962   if (!MaybeInfo)
963     return true;
964   // Debug information can only be attached to stack objects; Fixed stack
965   // objects aren't supported.
966   if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc)
967     PFS.MF.setVariableDbgInfo(MaybeInfo->DIVar, MaybeInfo->DIExpr, FrameIdx,
968                               MaybeInfo->DILoc);
969   return false;
970 }
971 
parseMDNode(PerFunctionMIParsingState & PFS,MDNode * & Node,const yaml::StringValue & Source)972 bool MIRParserImpl::parseMDNode(PerFunctionMIParsingState &PFS,
973     MDNode *&Node, const yaml::StringValue &Source) {
974   if (Source.Value.empty())
975     return false;
976   SMDiagnostic Error;
977   if (llvm::parseMDNode(PFS, Node, Source.Value, Error))
978     return error(Error, Source.SourceRange);
979   return false;
980 }
981 
initializeConstantPool(PerFunctionMIParsingState & PFS,MachineConstantPool & ConstantPool,const yaml::MachineFunction & YamlMF)982 bool MIRParserImpl::initializeConstantPool(PerFunctionMIParsingState &PFS,
983     MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF) {
984   DenseMap<unsigned, unsigned> &ConstantPoolSlots = PFS.ConstantPoolSlots;
985   const MachineFunction &MF = PFS.MF;
986   const auto &M = *MF.getFunction().getParent();
987   SMDiagnostic Error;
988   for (const auto &YamlConstant : YamlMF.Constants) {
989     if (YamlConstant.IsTargetSpecific)
990       // FIXME: Support target-specific constant pools
991       return error(YamlConstant.Value.SourceRange.Start,
992                    "Can't parse target-specific constant pool entries yet");
993     const Constant *Value = dyn_cast_or_null<Constant>(
994         parseConstantValue(YamlConstant.Value.Value, Error, M));
995     if (!Value)
996       return error(Error, YamlConstant.Value.SourceRange);
997     const Align PrefTypeAlign =
998         M.getDataLayout().getPrefTypeAlign(Value->getType());
999     const Align Alignment = YamlConstant.Alignment.value_or(PrefTypeAlign);
1000     unsigned Index = ConstantPool.getConstantPoolIndex(Value, Alignment);
1001     if (!ConstantPoolSlots.insert(std::make_pair(YamlConstant.ID.Value, Index))
1002              .second)
1003       return error(YamlConstant.ID.SourceRange.Start,
1004                    Twine("redefinition of constant pool item '%const.") +
1005                        Twine(YamlConstant.ID.Value) + "'");
1006   }
1007   return false;
1008 }
1009 
initializeJumpTableInfo(PerFunctionMIParsingState & PFS,const yaml::MachineJumpTable & YamlJTI)1010 bool MIRParserImpl::initializeJumpTableInfo(PerFunctionMIParsingState &PFS,
1011     const yaml::MachineJumpTable &YamlJTI) {
1012   MachineJumpTableInfo *JTI = PFS.MF.getOrCreateJumpTableInfo(YamlJTI.Kind);
1013   for (const auto &Entry : YamlJTI.Entries) {
1014     std::vector<MachineBasicBlock *> Blocks;
1015     for (const auto &MBBSource : Entry.Blocks) {
1016       MachineBasicBlock *MBB = nullptr;
1017       if (parseMBBReference(PFS, MBB, MBBSource.Value))
1018         return true;
1019       Blocks.push_back(MBB);
1020     }
1021     unsigned Index = JTI->createJumpTableIndex(Blocks);
1022     if (!PFS.JumpTableSlots.insert(std::make_pair(Entry.ID.Value, Index))
1023              .second)
1024       return error(Entry.ID.SourceRange.Start,
1025                    Twine("redefinition of jump table entry '%jump-table.") +
1026                        Twine(Entry.ID.Value) + "'");
1027   }
1028   return false;
1029 }
1030 
parseMBBReference(PerFunctionMIParsingState & PFS,MachineBasicBlock * & MBB,const yaml::StringValue & Source)1031 bool MIRParserImpl::parseMBBReference(PerFunctionMIParsingState &PFS,
1032                                       MachineBasicBlock *&MBB,
1033                                       const yaml::StringValue &Source) {
1034   SMDiagnostic Error;
1035   if (llvm::parseMBBReference(PFS, MBB, Source.Value, Error))
1036     return error(Error, Source.SourceRange);
1037   return false;
1038 }
1039 
parseMachineMetadata(PerFunctionMIParsingState & PFS,const yaml::StringValue & Source)1040 bool MIRParserImpl::parseMachineMetadata(PerFunctionMIParsingState &PFS,
1041                                          const yaml::StringValue &Source) {
1042   SMDiagnostic Error;
1043   if (llvm::parseMachineMetadata(PFS, Source.Value, Source.SourceRange, Error))
1044     return error(Error, Source.SourceRange);
1045   return false;
1046 }
1047 
parseMachineMetadataNodes(PerFunctionMIParsingState & PFS,MachineFunction & MF,const yaml::MachineFunction & YMF)1048 bool MIRParserImpl::parseMachineMetadataNodes(
1049     PerFunctionMIParsingState &PFS, MachineFunction &MF,
1050     const yaml::MachineFunction &YMF) {
1051   for (const auto &MDS : YMF.MachineMetadataNodes) {
1052     if (parseMachineMetadata(PFS, MDS))
1053       return true;
1054   }
1055   // Report missing definitions from forward referenced nodes.
1056   if (!PFS.MachineForwardRefMDNodes.empty())
1057     return error(PFS.MachineForwardRefMDNodes.begin()->second.second,
1058                  "use of undefined metadata '!" +
1059                      Twine(PFS.MachineForwardRefMDNodes.begin()->first) + "'");
1060   return false;
1061 }
1062 
diagFromMIStringDiag(const SMDiagnostic & Error,SMRange SourceRange)1063 SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
1064                                                  SMRange SourceRange) {
1065   assert(SourceRange.isValid() && "Invalid source range");
1066   SMLoc Loc = SourceRange.Start;
1067   bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
1068                   *Loc.getPointer() == '\'';
1069   // Translate the location of the error from the location in the MI string to
1070   // the corresponding location in the MIR file.
1071   Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
1072                            (HasQuote ? 1 : 0));
1073 
1074   // TODO: Translate any source ranges as well.
1075   return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), std::nullopt,
1076                        Error.getFixIts());
1077 }
1078 
diagFromBlockStringDiag(const SMDiagnostic & Error,SMRange SourceRange)1079 SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error,
1080                                                     SMRange SourceRange) {
1081   assert(SourceRange.isValid());
1082 
1083   // Translate the location of the error from the location in the llvm IR string
1084   // to the corresponding location in the MIR file.
1085   auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
1086   unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
1087   unsigned Column = Error.getColumnNo();
1088   StringRef LineStr = Error.getLineContents();
1089   SMLoc Loc = Error.getLoc();
1090 
1091   // Get the full line and adjust the column number by taking the indentation of
1092   // LLVM IR into account.
1093   for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
1094        L != E; ++L) {
1095     if (L.line_number() == Line) {
1096       LineStr = *L;
1097       Loc = SMLoc::getFromPointer(LineStr.data());
1098       auto Indent = LineStr.find(Error.getLineContents());
1099       if (Indent != StringRef::npos)
1100         Column += Indent;
1101       break;
1102     }
1103   }
1104 
1105   return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
1106                       Error.getMessage(), LineStr, Error.getRanges(),
1107                       Error.getFixIts());
1108 }
1109 
MIRParser(std::unique_ptr<MIRParserImpl> Impl)1110 MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
1111     : Impl(std::move(Impl)) {}
1112 
1113 MIRParser::~MIRParser() = default;
1114 
1115 std::unique_ptr<Module>
parseIRModule(DataLayoutCallbackTy DataLayoutCallback)1116 MIRParser::parseIRModule(DataLayoutCallbackTy DataLayoutCallback) {
1117   return Impl->parseIRModule(DataLayoutCallback);
1118 }
1119 
parseMachineFunctions(Module & M,MachineModuleInfo & MMI)1120 bool MIRParser::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
1121   return Impl->parseMachineFunctions(M, MMI);
1122 }
1123 
parseMachineFunctions(Module & M,ModuleAnalysisManager & MAM)1124 bool MIRParser::parseMachineFunctions(Module &M, ModuleAnalysisManager &MAM) {
1125   auto &MMI = MAM.getResult<MachineModuleAnalysis>(M).getMMI();
1126   return Impl->parseMachineFunctions(M, MMI, &MAM);
1127 }
1128 
createMIRParserFromFile(StringRef Filename,SMDiagnostic & Error,LLVMContext & Context,std::function<void (Function &)> ProcessIRFunction)1129 std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(
1130     StringRef Filename, SMDiagnostic &Error, LLVMContext &Context,
1131     std::function<void(Function &)> ProcessIRFunction) {
1132   auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
1133   if (std::error_code EC = FileOrErr.getError()) {
1134     Error = SMDiagnostic(Filename, SourceMgr::DK_Error,
1135                          "Could not open input file: " + EC.message());
1136     return nullptr;
1137   }
1138   return createMIRParser(std::move(FileOrErr.get()), Context,
1139                          ProcessIRFunction);
1140 }
1141 
1142 std::unique_ptr<MIRParser>
createMIRParser(std::unique_ptr<MemoryBuffer> Contents,LLVMContext & Context,std::function<void (Function &)> ProcessIRFunction)1143 llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
1144                       LLVMContext &Context,
1145                       std::function<void(Function &)> ProcessIRFunction) {
1146   auto Filename = Contents->getBufferIdentifier();
1147   if (Context.shouldDiscardValueNames()) {
1148     Context.diagnose(DiagnosticInfoMIRParser(
1149         DS_Error,
1150         SMDiagnostic(
1151             Filename, SourceMgr::DK_Error,
1152             "Can't read MIR with a Context that discards named Values")));
1153     return nullptr;
1154   }
1155   return std::make_unique<MIRParser>(std::make_unique<MIRParserImpl>(
1156       std::move(Contents), Filename, Context, ProcessIRFunction));
1157 }
1158