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