brintos

brintos / llvm-project-archived public Read only

0
0
Text · 47.3 KiB · 0f792b0 Raw
1299 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the class that parses the optional LLVM IR and machine10// 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 43using namespace llvm;44 45namespace llvm {46class MDNode;47class RegisterBank;48 49/// This class implements the parsing of LLVM IR that's embedded inside a MIR50/// file.51class 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 are60  /// 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 function63  /// parts.64  bool NoMIRDocuments = false;65 66  std::function<void(Function &)> ProcessIRFunction;67 68public: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 an86  /// 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 MIR92  /// 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 MIR112  /// 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 initializeSaveRestorePoints(128      PerFunctionMIParsingState &PFS,129      const std::vector<yaml::SaveRestorePointEntry> &YamlSRPoints,130      llvm::SaveRestorePoints &SaveRestorePoints);131 132  bool initializeCallSiteInfo(PerFunctionMIParsingState &PFS,133                              const yaml::MachineFunction &YamlMF);134 135  bool parseCalleeSavedRegister(PerFunctionMIParsingState &PFS,136                                std::vector<CalleeSavedInfo> &CSIInfo,137                                const yaml::StringValue &RegisterSource,138                                bool IsRestored, int FrameIdx);139 140  struct VarExprLoc {141    DILocalVariable *DIVar = nullptr;142    DIExpression *DIExpr = nullptr;143    DILocation *DILoc = nullptr;144  };145 146  std::optional<VarExprLoc> parseVarExprLoc(PerFunctionMIParsingState &PFS,147                                            const yaml::StringValue &VarStr,148                                            const yaml::StringValue &ExprStr,149                                            const yaml::StringValue &LocStr);150  template <typename T>151  bool parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS,152                                  const T &Object,153                                  int FrameIdx);154 155  bool initializeConstantPool(PerFunctionMIParsingState &PFS,156                              MachineConstantPool &ConstantPool,157                              const yaml::MachineFunction &YamlMF);158 159  bool initializeJumpTableInfo(PerFunctionMIParsingState &PFS,160                               const yaml::MachineJumpTable &YamlJTI);161 162  bool parseMachineMetadataNodes(PerFunctionMIParsingState &PFS,163                                 MachineFunction &MF,164                                 const yaml::MachineFunction &YMF);165 166  bool parseCalledGlobals(PerFunctionMIParsingState &PFS, MachineFunction &MF,167                          const yaml::MachineFunction &YMF);168 169private:170  bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node,171                   const yaml::StringValue &Source);172 173  bool parseMBBReference(PerFunctionMIParsingState &PFS,174                         MachineBasicBlock *&MBB,175                         const yaml::StringValue &Source);176 177  bool parseMachineMetadata(PerFunctionMIParsingState &PFS,178                            const yaml::StringValue &Source);179 180  /// Return a MIR diagnostic converted from an MI string diagnostic.181  SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,182                                    SMRange SourceRange);183 184  /// Return a MIR diagnostic converted from a diagnostic located in a YAML185  /// block scalar string.186  SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error,187                                       SMRange SourceRange);188 189  bool computeFunctionProperties(MachineFunction &MF,190                                 const yaml::MachineFunction &YamlMF);191 192  void setupDebugValueTracking(MachineFunction &MF,193    PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF);194 195  bool parseMachineInst(MachineFunction &MF, yaml::MachineInstrLoc MILoc,196                        MachineInstr const *&MI);197};198 199} // end namespace llvm200 201static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {202  reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);203}204 205MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,206                             StringRef Filename, LLVMContext &Context,207                             std::function<void(Function &)> Callback)208    : Context(Context),209      In(SM.getMemoryBuffer(SM.AddNewSourceBuffer(std::move(Contents), SMLoc()))210             ->getBuffer(),211         nullptr, handleYAMLDiag, this),212      Filename(Filename), ProcessIRFunction(Callback) {213  In.setContext(&In);214}215 216bool MIRParserImpl::error(const Twine &Message) {217  Context.diagnose(DiagnosticInfoMIRParser(218      DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));219  return true;220}221 222bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) {223  Context.diagnose(DiagnosticInfoMIRParser(224      DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message)));225  return true;226}227 228bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) {229  assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");230  reportDiagnostic(diagFromMIStringDiag(Error, SourceRange));231  return true;232}233 234void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {235  DiagnosticSeverity Kind;236  switch (Diag.getKind()) {237  case SourceMgr::DK_Error:238    Kind = DS_Error;239    break;240  case SourceMgr::DK_Warning:241    Kind = DS_Warning;242    break;243  case SourceMgr::DK_Note:244    Kind = DS_Note;245    break;246  case SourceMgr::DK_Remark:247    llvm_unreachable("remark unexpected");248    break;249  }250  Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));251}252 253std::unique_ptr<Module>254MIRParserImpl::parseIRModule(DataLayoutCallbackTy DataLayoutCallback) {255  if (!In.setCurrentDocument()) {256    if (In.error())257      return nullptr;258    // Create an empty module when the MIR file is empty.259    NoMIRDocuments = true;260    auto M = std::make_unique<Module>(Filename, Context);261    if (auto LayoutOverride = DataLayoutCallback(M->getTargetTriple().str(),262                                                 M->getDataLayoutStr()))263      M->setDataLayout(*LayoutOverride);264    return M;265  }266 267  std::unique_ptr<Module> M;268  // Parse the block scalar manually so that we can return unique pointer269  // without having to go trough YAML traits.270  if (const auto *BSN =271          dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {272    SMDiagnostic Error;273    M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,274                      Context, &IRSlots, DataLayoutCallback);275    if (!M) {276      reportDiagnostic(diagFromBlockStringDiag(Error, BSN->getSourceRange()));277      return nullptr;278    }279    In.nextDocument();280    if (!In.setCurrentDocument())281      NoMIRDocuments = true;282  } else {283    // Create an new, empty module.284    M = std::make_unique<Module>(Filename, Context);285    if (auto LayoutOverride = DataLayoutCallback(M->getTargetTriple().str(),286                                                 M->getDataLayoutStr()))287      M->setDataLayout(*LayoutOverride);288    NoLLVMIR = true;289  }290  return M;291}292 293bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI,294                                          ModuleAnalysisManager *MAM) {295  if (NoMIRDocuments)296    return false;297 298  // Parse the machine functions.299  do {300    if (parseMachineFunction(M, MMI, MAM))301      return true;302    In.nextDocument();303  } while (In.setCurrentDocument());304 305  return false;306}307 308Function *MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {309  auto &Context = M.getContext();310  Function *F =311      Function::Create(FunctionType::get(Type::getVoidTy(Context), false),312                       Function::ExternalLinkage, Name, M);313  BasicBlock *BB = BasicBlock::Create(Context, "entry", F);314  new UnreachableInst(Context, BB);315 316  if (ProcessIRFunction)317    ProcessIRFunction(*F);318 319  return F;320}321 322bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI,323                                         ModuleAnalysisManager *MAM) {324  // Parse the yaml.325  yaml::MachineFunction YamlMF;326  yaml::EmptyContext Ctx;327 328  const TargetMachine &TM = MMI.getTarget();329  YamlMF.MachineFuncInfo = std::unique_ptr<yaml::MachineFunctionInfo>(330      TM.createDefaultFuncInfoYAML());331 332  yaml::yamlize(In, YamlMF, false, Ctx);333  if (In.error())334    return true;335 336  // Search for the corresponding IR function.337  StringRef FunctionName = YamlMF.Name;338  Function *F = M.getFunction(FunctionName);339  if (!F) {340    if (NoLLVMIR) {341      F = createDummyFunction(FunctionName, M);342    } else {343      return error(Twine("function '") + FunctionName +344                   "' isn't defined in the provided LLVM IR");345    }346  }347 348  if (!MAM) {349    if (MMI.getMachineFunction(*F) != nullptr)350      return error(Twine("redefinition of machine function '") + FunctionName +351                   "'");352 353    // Create the MachineFunction.354    MachineFunction &MF = MMI.getOrCreateMachineFunction(*F);355    if (initializeMachineFunction(YamlMF, MF))356      return true;357  } else {358    auto &FAM =359        MAM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();360    if (FAM.getCachedResult<MachineFunctionAnalysis>(*F))361      return error(Twine("redefinition of machine function '") + FunctionName +362                   "'");363 364    // Create the MachineFunction.365    MachineFunction &MF = FAM.getResult<MachineFunctionAnalysis>(*F).getMF();366    if (initializeMachineFunction(YamlMF, MF))367      return true;368  }369 370  return false;371}372 373static bool isSSA(const MachineFunction &MF) {374  const MachineRegisterInfo &MRI = MF.getRegInfo();375  for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {376    Register Reg = Register::index2VirtReg(I);377    if (!MRI.hasOneDef(Reg) && !MRI.def_empty(Reg))378      return false;379 380    // Subregister defs are invalid in SSA.381    const MachineOperand *RegDef = MRI.getOneDef(Reg);382    if (RegDef && RegDef->getSubReg() != 0)383      return false;384  }385  return true;386}387 388bool MIRParserImpl::computeFunctionProperties(389    MachineFunction &MF, const yaml::MachineFunction &YamlMF) {390  MachineFunctionProperties &Properties = MF.getProperties();391 392  bool HasPHI = false;393  bool HasInlineAsm = false;394  bool HasFakeUses = false;395  bool AllTiedOpsRewritten = true, HasTiedOps = false;396  for (const MachineBasicBlock &MBB : MF) {397    for (const MachineInstr &MI : MBB) {398      if (MI.isPHI())399        HasPHI = true;400      if (MI.isInlineAsm())401        HasInlineAsm = true;402      if (MI.isFakeUse())403        HasFakeUses = true;404      for (unsigned I = 0; I < MI.getNumOperands(); ++I) {405        const MachineOperand &MO = MI.getOperand(I);406        if (!MO.isReg() || !MO.getReg())407          continue;408        unsigned DefIdx;409        if (MO.isUse() && MI.isRegTiedToDefOperand(I, &DefIdx)) {410          HasTiedOps = true;411          if (MO.getReg() != MI.getOperand(DefIdx).getReg())412            AllTiedOpsRewritten = false;413        }414      }415    }416  }417 418  // Helper function to sanity-check and set properties that are computed, but419  // may be explicitly set from the input MIR420  auto ComputedPropertyHelper =421      [&Properties](std::optional<bool> ExplicitProp, bool ComputedProp,422                    MachineFunctionProperties::Property P) -> bool {423    // Prefer explicitly given values over the computed properties424    if (ExplicitProp.value_or(ComputedProp))425      Properties.set(P);426    else427      Properties.reset(P);428 429    // Check for conflict between the explicit values and the computed ones430    return ExplicitProp && *ExplicitProp && !ComputedProp;431  };432 433  if (ComputedPropertyHelper(YamlMF.NoPHIs, !HasPHI,434                             MachineFunctionProperties::Property::NoPHIs)) {435    return error(MF.getName() +436                 " has explicit property NoPhi, but contains at least one PHI");437  }438 439  MF.setHasInlineAsm(HasInlineAsm);440 441  if (HasTiedOps && AllTiedOpsRewritten)442    Properties.setTiedOpsRewritten();443 444  if (ComputedPropertyHelper(YamlMF.IsSSA, isSSA(MF),445                             MachineFunctionProperties::Property::IsSSA)) {446    return error(MF.getName() +447                 " has explicit property IsSSA, but is not valid SSA");448  }449 450  const MachineRegisterInfo &MRI = MF.getRegInfo();451  if (ComputedPropertyHelper(YamlMF.NoVRegs, MRI.getNumVirtRegs() == 0,452                             MachineFunctionProperties::Property::NoVRegs)) {453    return error(454        MF.getName() +455        " has explicit property NoVRegs, but contains virtual registers");456  }457 458  // For hasFakeUses we follow similar logic to the ComputedPropertyHelper,459  // except for caring about the inverse case only, i.e. when the property is460  // explicitly set to false and Fake Uses are present; having HasFakeUses=true461  // on a function without fake uses is harmless.462  if (YamlMF.HasFakeUses && !*YamlMF.HasFakeUses && HasFakeUses)463    return error(464        MF.getName() +465        " has explicit property hasFakeUses=false, but contains fake uses");466  MF.setHasFakeUses(YamlMF.HasFakeUses.value_or(HasFakeUses));467 468  return false;469}470 471bool MIRParserImpl::parseMachineInst(MachineFunction &MF,472                                     yaml::MachineInstrLoc MILoc,473                                     MachineInstr const *&MI) {474  if (MILoc.BlockNum >= MF.size()) {475    return error(Twine(MF.getName()) +476                 Twine(" instruction block out of range.") +477                 " Unable to reference bb:" + Twine(MILoc.BlockNum));478  }479  auto BB = std::next(MF.begin(), MILoc.BlockNum);480  if (MILoc.Offset >= BB->size())481    return error(482        Twine(MF.getName()) + Twine(" instruction offset out of range.") +483        " Unable to reference instruction at bb: " + Twine(MILoc.BlockNum) +484        " at offset:" + Twine(MILoc.Offset));485  MI = &*std::next(BB->instr_begin(), MILoc.Offset);486  return false;487}488 489bool MIRParserImpl::initializeCallSiteInfo(490    PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF) {491  MachineFunction &MF = PFS.MF;492  SMDiagnostic Error;493  const TargetMachine &TM = MF.getTarget();494  for (auto &YamlCSInfo : YamlMF.CallSitesInfo) {495    yaml::MachineInstrLoc MILoc = YamlCSInfo.CallLocation;496    const MachineInstr *CallI;497    if (parseMachineInst(MF, MILoc, CallI))498      return true;499    if (!CallI->isCall(MachineInstr::IgnoreBundle))500      return error(Twine(MF.getName()) +501                   Twine(" call site info should reference call "502                         "instruction. Instruction at bb:") +503                   Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset) +504                   " is not a call instruction");505    MachineFunction::CallSiteInfo CSInfo;506    for (auto ArgRegPair : YamlCSInfo.ArgForwardingRegs) {507      Register Reg;508      if (parseNamedRegisterReference(PFS, Reg, ArgRegPair.Reg.Value, Error))509        return error(Error, ArgRegPair.Reg.SourceRange);510      CSInfo.ArgRegPairs.emplace_back(Reg, ArgRegPair.ArgNo);511    }512    if (!YamlCSInfo.CalleeTypeIds.empty()) {513      for (auto CalleeTypeId : YamlCSInfo.CalleeTypeIds) {514        IntegerType *Int64Ty = Type::getInt64Ty(Context);515        CSInfo.CalleeTypeIds.push_back(ConstantInt::get(Int64Ty, CalleeTypeId,516                                                        /*isSigned=*/false));517      }518    }519 520    if (TM.Options.EmitCallSiteInfo || TM.Options.EmitCallGraphSection)521      MF.addCallSiteInfo(&*CallI, std::move(CSInfo));522  }523 524  if (!YamlMF.CallSitesInfo.empty() &&525      !(TM.Options.EmitCallSiteInfo || TM.Options.EmitCallGraphSection))526    return error("call site info provided but not used");527  return false;528}529 530void MIRParserImpl::setupDebugValueTracking(531    MachineFunction &MF, PerFunctionMIParsingState &PFS,532    const yaml::MachineFunction &YamlMF) {533  // Compute the value of the "next instruction number" field.534  unsigned MaxInstrNum = 0;535  for (auto &MBB : MF)536    for (auto &MI : MBB)537      MaxInstrNum = std::max(MI.peekDebugInstrNum(), MaxInstrNum);538  MF.setDebugInstrNumberingCount(MaxInstrNum);539 540  // Load any substitutions.541  for (const auto &Sub : YamlMF.DebugValueSubstitutions) {542    MF.makeDebugValueSubstitution({Sub.SrcInst, Sub.SrcOp},543                                  {Sub.DstInst, Sub.DstOp}, Sub.Subreg);544  }545 546  // Flag for whether we're supposed to be using DBG_INSTR_REF.547  MF.setUseDebugInstrRef(YamlMF.UseDebugInstrRef);548}549 550bool551MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,552                                         MachineFunction &MF) {553  // TODO: Recreate the machine function.554  if (Target) {555    // Avoid clearing state if we're using the same subtarget again.556    Target->setTarget(MF.getSubtarget());557  } else {558    Target.reset(new PerTargetMIParsingState(MF.getSubtarget()));559  }560 561  MF.setAlignment(YamlMF.Alignment.valueOrOne());562  MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);563  MF.setHasWinCFI(YamlMF.HasWinCFI);564 565  MF.setCallsEHReturn(YamlMF.CallsEHReturn);566  MF.setCallsUnwindInit(YamlMF.CallsUnwindInit);567  MF.setHasEHContTarget(YamlMF.HasEHContTarget);568  MF.setHasEHScopes(YamlMF.HasEHScopes);569  MF.setHasEHFunclets(YamlMF.HasEHFunclets);570  MF.setIsOutlined(YamlMF.IsOutlined);571 572  MachineFunctionProperties &Props = MF.getProperties();573  if (YamlMF.Legalized)574    Props.setLegalized();575  if (YamlMF.RegBankSelected)576    Props.setRegBankSelected();577  if (YamlMF.Selected)578    Props.setSelected();579  if (YamlMF.FailedISel)580    Props.setFailedISel();581  if (YamlMF.FailsVerification)582    Props.setFailsVerification();583  if (YamlMF.TracksDebugUserValues)584    Props.setTracksDebugUserValues();585 586  PerFunctionMIParsingState PFS(MF, SM, IRSlots, *Target);587  if (parseRegisterInfo(PFS, YamlMF))588    return true;589  if (!YamlMF.Constants.empty()) {590    auto *ConstantPool = MF.getConstantPool();591    assert(ConstantPool && "Constant pool must be created");592    if (initializeConstantPool(PFS, *ConstantPool, YamlMF))593      return true;594  }595  if (!YamlMF.MachineMetadataNodes.empty() &&596      parseMachineMetadataNodes(PFS, MF, YamlMF))597    return true;598 599  StringRef BlockStr = YamlMF.Body.Value.Value;600  SMDiagnostic Error;601  SourceMgr BlockSM;602  BlockSM.AddNewSourceBuffer(603      MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false),604      SMLoc());605  PFS.SM = &BlockSM;606  if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)) {607    reportDiagnostic(608        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));609    return true;610  }611  // Check Basic Block Section Flags.612  if (MF.hasBBSections()) {613    MF.assignBeginEndSections();614  }615  PFS.SM = &SM;616 617  // Initialize the frame information after creating all the MBBs so that the618  // MBB references in the frame information can be resolved.619  if (initializeFrameInfo(PFS, YamlMF))620    return true;621  // Initialize the jump table after creating all the MBBs so that the MBB622  // references can be resolved.623  if (!YamlMF.JumpTableInfo.Entries.empty() &&624      initializeJumpTableInfo(PFS, YamlMF.JumpTableInfo))625    return true;626  // Parse the machine instructions after creating all of the MBBs so that the627  // parser can resolve the MBB references.628  StringRef InsnStr = YamlMF.Body.Value.Value;629  SourceMgr InsnSM;630  InsnSM.AddNewSourceBuffer(631      MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false),632      SMLoc());633  PFS.SM = &InsnSM;634  if (parseMachineInstructions(PFS, InsnStr, Error)) {635    reportDiagnostic(636        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));637    return true;638  }639  PFS.SM = &SM;640 641  if (setupRegisterInfo(PFS, YamlMF))642    return true;643 644  if (YamlMF.MachineFuncInfo) {645    const TargetMachine &TM = MF.getTarget();646    // Note this is called after the initial constructor of the647    // MachineFunctionInfo based on the MachineFunction, which may depend on the648    // IR.649 650    SMRange SrcRange;651    if (TM.parseMachineFunctionInfo(*YamlMF.MachineFuncInfo, PFS, Error,652                                    SrcRange)) {653      return error(Error, SrcRange);654    }655  }656 657  // Set the reserved registers after parsing MachineFuncInfo. The target may658  // have been recording information used to select the reserved registers659  // there.660  // FIXME: This is a temporary workaround until the reserved registers can be661  // serialized.662  MachineRegisterInfo &MRI = MF.getRegInfo();663  MRI.freezeReservedRegs();664 665  if (computeFunctionProperties(MF, YamlMF))666    return true;667 668  if (initializeCallSiteInfo(PFS, YamlMF))669    return true;670 671  if (parseCalledGlobals(PFS, MF, YamlMF))672    return true;673 674  setupDebugValueTracking(MF, PFS, YamlMF);675 676  MF.getSubtarget().mirFileLoaded(MF);677 678  MF.verify(nullptr, nullptr, &errs());679  return false;680}681 682bool MIRParserImpl::parseRegisterInfo(PerFunctionMIParsingState &PFS,683                                      const yaml::MachineFunction &YamlMF) {684  MachineFunction &MF = PFS.MF;685  MachineRegisterInfo &RegInfo = MF.getRegInfo();686  assert(RegInfo.tracksLiveness());687  if (!YamlMF.TracksRegLiveness)688    RegInfo.invalidateLiveness();689 690  SMDiagnostic Error;691  // Parse the virtual register information.692  for (const auto &VReg : YamlMF.VirtualRegisters) {693    VRegInfo &Info = PFS.getVRegInfo(VReg.ID.Value);694    if (Info.Explicit)695      return error(VReg.ID.SourceRange.Start,696                   Twine("redefinition of virtual register '%") +697                       Twine(VReg.ID.Value) + "'");698    Info.Explicit = true;699 700    if (VReg.Class.Value == "_") {701      Info.Kind = VRegInfo::GENERIC;702      Info.D.RegBank = nullptr;703    } else {704      const auto *RC = Target->getRegClass(VReg.Class.Value);705      if (RC) {706        Info.Kind = VRegInfo::NORMAL;707        Info.D.RC = RC;708      } else {709        const RegisterBank *RegBank = Target->getRegBank(VReg.Class.Value);710        if (!RegBank)711          return error(712              VReg.Class.SourceRange.Start,713              Twine("use of undefined register class or register bank '") +714                  VReg.Class.Value + "'");715        Info.Kind = VRegInfo::REGBANK;716        Info.D.RegBank = RegBank;717      }718    }719 720    if (!VReg.PreferredRegister.Value.empty()) {721      if (Info.Kind != VRegInfo::NORMAL)722        return error(VReg.Class.SourceRange.Start,723              Twine("preferred register can only be set for normal vregs"));724 725      if (parseRegisterReference(PFS, Info.PreferredReg,726                                 VReg.PreferredRegister.Value, Error))727        return error(Error, VReg.PreferredRegister.SourceRange);728    }729 730    for (const auto &FlagStringValue : VReg.RegisterFlags) {731      uint8_t FlagValue;732      if (Target->getVRegFlagValue(FlagStringValue.Value, FlagValue))733        return error(FlagStringValue.SourceRange.Start,734                     Twine("use of undefined register flag '") +735                         FlagStringValue.Value + "'");736      Info.Flags |= FlagValue;737    }738    RegInfo.noteNewVirtualRegister(Info.VReg);739  }740 741  // Parse the liveins.742  for (const auto &LiveIn : YamlMF.LiveIns) {743    Register Reg;744    if (parseNamedRegisterReference(PFS, Reg, LiveIn.Register.Value, Error))745      return error(Error, LiveIn.Register.SourceRange);746    Register VReg;747    if (!LiveIn.VirtualRegister.Value.empty()) {748      VRegInfo *Info;749      if (parseVirtualRegisterReference(PFS, Info, LiveIn.VirtualRegister.Value,750                                        Error))751        return error(Error, LiveIn.VirtualRegister.SourceRange);752      VReg = Info->VReg;753    }754    RegInfo.addLiveIn(Reg, VReg);755  }756 757  // Parse the callee saved registers (Registers that will758  // be saved for the caller).759  if (YamlMF.CalleeSavedRegisters) {760    SmallVector<MCPhysReg, 16> CalleeSavedRegisters;761    for (const auto &RegSource : *YamlMF.CalleeSavedRegisters) {762      Register Reg;763      if (parseNamedRegisterReference(PFS, Reg, RegSource.Value, Error))764        return error(Error, RegSource.SourceRange);765      CalleeSavedRegisters.push_back(Reg.id());766    }767    RegInfo.setCalleeSavedRegs(CalleeSavedRegisters);768  }769 770  return false;771}772 773bool MIRParserImpl::setupRegisterInfo(const PerFunctionMIParsingState &PFS,774                                      const yaml::MachineFunction &YamlMF) {775  MachineFunction &MF = PFS.MF;776  MachineRegisterInfo &MRI = MF.getRegInfo();777  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();778 779  SmallVector<std::string> Errors;780 781  // Create VRegs782  auto populateVRegInfo = [&](const VRegInfo &Info, const Twine &Name) {783    Register Reg = Info.VReg;784    switch (Info.Kind) {785    case VRegInfo::UNKNOWN:786      Errors.push_back(787          (Twine("Cannot determine class/bank of virtual register ") + Name +788           " in function '" + MF.getName() + "'")789              .str());790      break;791    case VRegInfo::NORMAL:792      if (!Info.D.RC->isAllocatable()) {793        Errors.push_back((Twine("Cannot use non-allocatable class '") +794                          TRI->getRegClassName(Info.D.RC) +795                          "' for virtual register " + Name + " in function '" +796                          MF.getName() + "'")797                             .str());798        break;799      }800 801      MRI.setRegClass(Reg, Info.D.RC);802      if (Info.PreferredReg != 0)803        MRI.setSimpleHint(Reg, Info.PreferredReg);804      break;805    case VRegInfo::GENERIC:806      break;807    case VRegInfo::REGBANK:808      MRI.setRegBank(Reg, *Info.D.RegBank);809      break;810    }811  };812 813  for (const auto &P : PFS.VRegInfosNamed) {814    const VRegInfo &Info = *P.second;815    populateVRegInfo(Info, Twine(P.first()));816  }817 818  for (auto P : PFS.VRegInfos) {819    const VRegInfo &Info = *P.second;820    populateVRegInfo(Info, Twine(P.first.id()));821  }822 823  // Compute MachineRegisterInfo::UsedPhysRegMask824  for (const MachineBasicBlock &MBB : MF) {825    // Make sure MRI knows about registers clobbered by unwinder.826    if (MBB.isEHPad())827      if (auto *RegMask = TRI->getCustomEHPadPreservedMask(MF))828        MRI.addPhysRegsUsedFromRegMask(RegMask);829 830    for (const MachineInstr &MI : MBB) {831      for (const MachineOperand &MO : MI.operands()) {832        if (!MO.isRegMask())833          continue;834        MRI.addPhysRegsUsedFromRegMask(MO.getRegMask());835      }836    }837  }838 839  if (Errors.empty())840    return false;841 842  // Report errors in a deterministic order.843  sort(Errors);844  for (auto &E : Errors)845    error(E);846  return true;847}848 849bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS,850                                        const yaml::MachineFunction &YamlMF) {851  MachineFunction &MF = PFS.MF;852  MachineFrameInfo &MFI = MF.getFrameInfo();853  const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();854  const Function &F = MF.getFunction();855  const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;856  MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);857  MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);858  MFI.setHasStackMap(YamlMFI.HasStackMap);859  MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);860  MFI.setStackSize(YamlMFI.StackSize);861  MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment);862  if (YamlMFI.MaxAlignment)863    MFI.ensureMaxAlignment(Align(YamlMFI.MaxAlignment));864  MFI.setAdjustsStack(YamlMFI.AdjustsStack);865  MFI.setHasCalls(YamlMFI.HasCalls);866  if (YamlMFI.MaxCallFrameSize != ~0u)867    MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize);868  MFI.setCVBytesOfCalleeSavedRegisters(YamlMFI.CVBytesOfCalleeSavedRegisters);869  MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);870  MFI.setHasVAStart(YamlMFI.HasVAStart);871  MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);872  MFI.setHasTailCall(YamlMFI.HasTailCall);873  MFI.setCalleeSavedInfoValid(YamlMFI.IsCalleeSavedInfoValid);874  MFI.setLocalFrameSize(YamlMFI.LocalFrameSize);875  llvm::SaveRestorePoints SavePoints;876  if (initializeSaveRestorePoints(PFS, YamlMFI.SavePoints, SavePoints))877    return true;878  MFI.setSavePoints(SavePoints);879  llvm::SaveRestorePoints RestorePoints;880  if (initializeSaveRestorePoints(PFS, YamlMFI.RestorePoints, RestorePoints))881    return true;882  MFI.setRestorePoints(RestorePoints);883 884  std::vector<CalleeSavedInfo> CSIInfo;885  // Initialize the fixed frame objects.886  for (const auto &Object : YamlMF.FixedStackObjects) {887    int ObjectIdx;888    if (Object.Type != yaml::FixedMachineStackObject::SpillSlot)889      ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset,890                                        Object.IsImmutable, Object.IsAliased);891    else892      ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);893 894    if (!TFI->isSupportedStackID(Object.StackID))895      return error(Object.ID.SourceRange.Start,896                   Twine("StackID is not supported by target"));897    MFI.setStackID(ObjectIdx, Object.StackID);898    MFI.setObjectAlignment(ObjectIdx, Object.Alignment.valueOrOne());899    if (!PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID.Value,900                                                         ObjectIdx))901             .second)902      return error(Object.ID.SourceRange.Start,903                   Twine("redefinition of fixed stack object '%fixed-stack.") +904                       Twine(Object.ID.Value) + "'");905    if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister,906                                 Object.CalleeSavedRestored, ObjectIdx))907      return true;908    if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx))909      return true;910  }911 912  for (const auto &Object : YamlMF.EntryValueObjects) {913    SMDiagnostic Error;914    Register Reg;915    if (parseNamedRegisterReference(PFS, Reg, Object.EntryValueRegister.Value,916                                    Error))917      return error(Error, Object.EntryValueRegister.SourceRange);918    if (!Reg.isPhysical())919      return error(Object.EntryValueRegister.SourceRange.Start,920                   "Expected physical register for entry value field");921    std::optional<VarExprLoc> MaybeInfo = parseVarExprLoc(922        PFS, Object.DebugVar, Object.DebugExpr, Object.DebugLoc);923    if (!MaybeInfo)924      return true;925    if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc)926      PFS.MF.setVariableDbgInfo(MaybeInfo->DIVar, MaybeInfo->DIExpr,927                                Reg.asMCReg(), MaybeInfo->DILoc);928  }929 930  // Initialize the ordinary frame objects.931  for (const auto &Object : YamlMF.StackObjects) {932    int ObjectIdx;933    const AllocaInst *Alloca = nullptr;934    const yaml::StringValue &Name = Object.Name;935    if (!Name.Value.empty()) {936      Alloca = dyn_cast_or_null<AllocaInst>(937          F.getValueSymbolTable()->lookup(Name.Value));938      if (!Alloca)939        return error(Name.SourceRange.Start,940                     "alloca instruction named '" + Name.Value +941                         "' isn't defined in the function '" + F.getName() +942                         "'");943    }944    if (!TFI->isSupportedStackID(Object.StackID))945      return error(Object.ID.SourceRange.Start,946                   Twine("StackID is not supported by target"));947    if (Object.Type == yaml::MachineStackObject::VariableSized)948      ObjectIdx =949          MFI.CreateVariableSizedObject(Object.Alignment.valueOrOne(), Alloca);950    else951      ObjectIdx = MFI.CreateStackObject(952          Object.Size, Object.Alignment.valueOrOne(),953          Object.Type == yaml::MachineStackObject::SpillSlot, Alloca,954          Object.StackID);955    MFI.setObjectOffset(ObjectIdx, Object.Offset);956 957    if (!PFS.StackObjectSlots.insert(std::make_pair(Object.ID.Value, ObjectIdx))958             .second)959      return error(Object.ID.SourceRange.Start,960                   Twine("redefinition of stack object '%stack.") +961                       Twine(Object.ID.Value) + "'");962    if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister,963                                 Object.CalleeSavedRestored, ObjectIdx))964      return true;965    if (Object.LocalOffset)966      MFI.mapLocalFrameObject(ObjectIdx, *Object.LocalOffset);967    if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx))968      return true;969  }970  MFI.setCalleeSavedInfo(CSIInfo);971  if (!CSIInfo.empty())972    MFI.setCalleeSavedInfoValid(true);973 974  // Initialize the various stack object references after initializing the975  // stack objects.976  if (!YamlMFI.StackProtector.Value.empty()) {977    SMDiagnostic Error;978    int FI;979    if (parseStackObjectReference(PFS, FI, YamlMFI.StackProtector.Value, Error))980      return error(Error, YamlMFI.StackProtector.SourceRange);981    MFI.setStackProtectorIndex(FI);982  }983 984  if (!YamlMFI.FunctionContext.Value.empty()) {985    SMDiagnostic Error;986    int FI;987    if (parseStackObjectReference(PFS, FI, YamlMFI.FunctionContext.Value, Error))988      return error(Error, YamlMFI.FunctionContext.SourceRange);989    MFI.setFunctionContextIndex(FI);990  }991 992  return false;993}994 995bool MIRParserImpl::parseCalleeSavedRegister(PerFunctionMIParsingState &PFS,996    std::vector<CalleeSavedInfo> &CSIInfo,997    const yaml::StringValue &RegisterSource, bool IsRestored, int FrameIdx) {998  if (RegisterSource.Value.empty())999    return false;1000  Register Reg;1001  SMDiagnostic Error;1002  if (parseNamedRegisterReference(PFS, Reg, RegisterSource.Value, Error))1003    return error(Error, RegisterSource.SourceRange);1004  CalleeSavedInfo CSI(Reg, FrameIdx);1005  CSI.setRestored(IsRestored);1006  CSIInfo.push_back(CSI);1007  return false;1008}1009 1010/// Verify that given node is of a certain type. Return true on error.1011template <typename T>1012static bool typecheckMDNode(T *&Result, MDNode *Node,1013                            const yaml::StringValue &Source,1014                            StringRef TypeString, MIRParserImpl &Parser) {1015  if (!Node)1016    return false;1017  Result = dyn_cast<T>(Node);1018  if (!Result)1019    return Parser.error(Source.SourceRange.Start,1020                        "expected a reference to a '" + TypeString +1021                            "' metadata node");1022  return false;1023}1024 1025std::optional<MIRParserImpl::VarExprLoc> MIRParserImpl::parseVarExprLoc(1026    PerFunctionMIParsingState &PFS, const yaml::StringValue &VarStr,1027    const yaml::StringValue &ExprStr, const yaml::StringValue &LocStr) {1028  MDNode *Var = nullptr;1029  MDNode *Expr = nullptr;1030  MDNode *Loc = nullptr;1031  if (parseMDNode(PFS, Var, VarStr) || parseMDNode(PFS, Expr, ExprStr) ||1032      parseMDNode(PFS, Loc, LocStr))1033    return std::nullopt;1034  DILocalVariable *DIVar = nullptr;1035  DIExpression *DIExpr = nullptr;1036  DILocation *DILoc = nullptr;1037  if (typecheckMDNode(DIVar, Var, VarStr, "DILocalVariable", *this) ||1038      typecheckMDNode(DIExpr, Expr, ExprStr, "DIExpression", *this) ||1039      typecheckMDNode(DILoc, Loc, LocStr, "DILocation", *this))1040    return std::nullopt;1041  return VarExprLoc{DIVar, DIExpr, DILoc};1042}1043 1044template <typename T>1045bool MIRParserImpl::parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS,1046                                               const T &Object, int FrameIdx) {1047  std::optional<VarExprLoc> MaybeInfo =1048      parseVarExprLoc(PFS, Object.DebugVar, Object.DebugExpr, Object.DebugLoc);1049  if (!MaybeInfo)1050    return true;1051  // Debug information can only be attached to stack objects; Fixed stack1052  // objects aren't supported.1053  if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc)1054    PFS.MF.setVariableDbgInfo(MaybeInfo->DIVar, MaybeInfo->DIExpr, FrameIdx,1055                              MaybeInfo->DILoc);1056  return false;1057}1058 1059bool MIRParserImpl::parseMDNode(PerFunctionMIParsingState &PFS,1060    MDNode *&Node, const yaml::StringValue &Source) {1061  if (Source.Value.empty())1062    return false;1063  SMDiagnostic Error;1064  if (llvm::parseMDNode(PFS, Node, Source.Value, Error))1065    return error(Error, Source.SourceRange);1066  return false;1067}1068 1069bool MIRParserImpl::initializeConstantPool(PerFunctionMIParsingState &PFS,1070    MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF) {1071  DenseMap<unsigned, unsigned> &ConstantPoolSlots = PFS.ConstantPoolSlots;1072  const MachineFunction &MF = PFS.MF;1073  const auto &M = *MF.getFunction().getParent();1074  SMDiagnostic Error;1075  for (const auto &YamlConstant : YamlMF.Constants) {1076    if (YamlConstant.IsTargetSpecific)1077      // FIXME: Support target-specific constant pools1078      return error(YamlConstant.Value.SourceRange.Start,1079                   "Can't parse target-specific constant pool entries yet");1080    const Constant *Value = dyn_cast_or_null<Constant>(1081        parseConstantValue(YamlConstant.Value.Value, Error, M));1082    if (!Value)1083      return error(Error, YamlConstant.Value.SourceRange);1084    const Align PrefTypeAlign =1085        M.getDataLayout().getPrefTypeAlign(Value->getType());1086    const Align Alignment = YamlConstant.Alignment.value_or(PrefTypeAlign);1087    unsigned Index = ConstantPool.getConstantPoolIndex(Value, Alignment);1088    if (!ConstantPoolSlots.insert(std::make_pair(YamlConstant.ID.Value, Index))1089             .second)1090      return error(YamlConstant.ID.SourceRange.Start,1091                   Twine("redefinition of constant pool item '%const.") +1092                       Twine(YamlConstant.ID.Value) + "'");1093  }1094  return false;1095}1096 1097// Return true if basic block was incorrectly specified in MIR1098bool MIRParserImpl::initializeSaveRestorePoints(1099    PerFunctionMIParsingState &PFS,1100    const std::vector<yaml::SaveRestorePointEntry> &YamlSRPoints,1101    llvm::SaveRestorePoints &SaveRestorePoints) {1102  SMDiagnostic Error;1103  MachineBasicBlock *MBB = nullptr;1104  for (const yaml::SaveRestorePointEntry &Entry : YamlSRPoints) {1105    if (parseMBBReference(PFS, MBB, Entry.Point.Value))1106      return true;1107 1108    std::vector<CalleeSavedInfo> Registers;1109    for (auto &RegStr : Entry.Registers) {1110      Register Reg;1111      if (parseNamedRegisterReference(PFS, Reg, RegStr.Value, Error))1112        return error(Error, RegStr.SourceRange);1113      Registers.push_back(CalleeSavedInfo(Reg));1114    }1115    SaveRestorePoints.try_emplace(MBB, std::move(Registers));1116  }1117  return false;1118}1119 1120bool MIRParserImpl::initializeJumpTableInfo(PerFunctionMIParsingState &PFS,1121    const yaml::MachineJumpTable &YamlJTI) {1122  MachineJumpTableInfo *JTI = PFS.MF.getOrCreateJumpTableInfo(YamlJTI.Kind);1123  for (const auto &Entry : YamlJTI.Entries) {1124    std::vector<MachineBasicBlock *> Blocks;1125    for (const auto &MBBSource : Entry.Blocks) {1126      MachineBasicBlock *MBB = nullptr;1127      if (parseMBBReference(PFS, MBB, MBBSource.Value))1128        return true;1129      Blocks.push_back(MBB);1130    }1131    unsigned Index = JTI->createJumpTableIndex(Blocks);1132    if (!PFS.JumpTableSlots.insert(std::make_pair(Entry.ID.Value, Index))1133             .second)1134      return error(Entry.ID.SourceRange.Start,1135                   Twine("redefinition of jump table entry '%jump-table.") +1136                       Twine(Entry.ID.Value) + "'");1137  }1138  return false;1139}1140 1141bool MIRParserImpl::parseMBBReference(PerFunctionMIParsingState &PFS,1142                                      MachineBasicBlock *&MBB,1143                                      const yaml::StringValue &Source) {1144  SMDiagnostic Error;1145  if (llvm::parseMBBReference(PFS, MBB, Source.Value, Error))1146    return error(Error, Source.SourceRange);1147  return false;1148}1149 1150bool MIRParserImpl::parseMachineMetadata(PerFunctionMIParsingState &PFS,1151                                         const yaml::StringValue &Source) {1152  SMDiagnostic Error;1153  if (llvm::parseMachineMetadata(PFS, Source.Value, Source.SourceRange, Error))1154    return error(Error, Source.SourceRange);1155  return false;1156}1157 1158bool MIRParserImpl::parseMachineMetadataNodes(1159    PerFunctionMIParsingState &PFS, MachineFunction &MF,1160    const yaml::MachineFunction &YMF) {1161  for (const auto &MDS : YMF.MachineMetadataNodes) {1162    if (parseMachineMetadata(PFS, MDS))1163      return true;1164  }1165  // Report missing definitions from forward referenced nodes.1166  if (!PFS.MachineForwardRefMDNodes.empty())1167    return error(PFS.MachineForwardRefMDNodes.begin()->second.second,1168                 "use of undefined metadata '!" +1169                     Twine(PFS.MachineForwardRefMDNodes.begin()->first) + "'");1170  return false;1171}1172 1173bool MIRParserImpl::parseCalledGlobals(PerFunctionMIParsingState &PFS,1174                                       MachineFunction &MF,1175                                       const yaml::MachineFunction &YMF) {1176  Function &F = MF.getFunction();1177  for (const auto &YamlCG : YMF.CalledGlobals) {1178    yaml::MachineInstrLoc MILoc = YamlCG.CallSite;1179    const MachineInstr *CallI;1180    if (parseMachineInst(MF, MILoc, CallI))1181      return true;1182    if (!CallI->isCall(MachineInstr::IgnoreBundle))1183      return error(Twine(MF.getName()) +1184                   Twine(" called global should reference call "1185                         "instruction. Instruction at bb:") +1186                   Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset) +1187                   " is not a call instruction");1188 1189    auto Callee =1190        F.getParent()->getValueSymbolTable().lookup(YamlCG.Callee.Value);1191    if (!Callee)1192      return error(YamlCG.Callee.SourceRange.Start,1193                   "use of undefined global '" + YamlCG.Callee.Value + "'");1194    if (!isa<GlobalValue>(Callee))1195      return error(YamlCG.Callee.SourceRange.Start,1196                   "use of non-global value '" + YamlCG.Callee.Value + "'");1197 1198    MF.addCalledGlobal(CallI, {cast<GlobalValue>(Callee), YamlCG.Flags});1199  }1200 1201  return false;1202}1203 1204SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,1205                                                 SMRange SourceRange) {1206  assert(SourceRange.isValid() && "Invalid source range");1207  SMLoc Loc = SourceRange.Start;1208  bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&1209                  *Loc.getPointer() == '\'';1210  // Translate the location of the error from the location in the MI string to1211  // the corresponding location in the MIR file.1212  Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +1213                           (HasQuote ? 1 : 0));1214 1215  // TODO: Translate any source ranges as well.1216  return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), {},1217                       Error.getFixIts());1218}1219 1220SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error,1221                                                    SMRange SourceRange) {1222  assert(SourceRange.isValid());1223 1224  // Translate the location of the error from the location in the llvm IR string1225  // to the corresponding location in the MIR file.1226  auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);1227  unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;1228  unsigned Column = Error.getColumnNo();1229  StringRef LineStr = Error.getLineContents();1230  SMLoc Loc = Error.getLoc();1231 1232  // Get the full line and adjust the column number by taking the indentation of1233  // LLVM IR into account.1234  for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;1235       L != E; ++L) {1236    if (L.line_number() == Line) {1237      LineStr = *L;1238      Loc = SMLoc::getFromPointer(LineStr.data());1239      auto Indent = LineStr.find(Error.getLineContents());1240      if (Indent != StringRef::npos)1241        Column += Indent;1242      break;1243    }1244  }1245 1246  return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),1247                      Error.getMessage(), LineStr, Error.getRanges(),1248                      Error.getFixIts());1249}1250 1251MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)1252    : Impl(std::move(Impl)) {}1253 1254MIRParser::~MIRParser() = default;1255 1256std::unique_ptr<Module>1257MIRParser::parseIRModule(DataLayoutCallbackTy DataLayoutCallback) {1258  return Impl->parseIRModule(DataLayoutCallback);1259}1260 1261bool MIRParser::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {1262  return Impl->parseMachineFunctions(M, MMI);1263}1264 1265bool MIRParser::parseMachineFunctions(Module &M, ModuleAnalysisManager &MAM) {1266  auto &MMI = MAM.getResult<MachineModuleAnalysis>(M).getMMI();1267  return Impl->parseMachineFunctions(M, MMI, &MAM);1268}1269 1270std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(1271    StringRef Filename, SMDiagnostic &Error, LLVMContext &Context,1272    std::function<void(Function &)> ProcessIRFunction) {1273  auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);1274  if (std::error_code EC = FileOrErr.getError()) {1275    Error = SMDiagnostic(Filename, SourceMgr::DK_Error,1276                         "Could not open input file: " + EC.message());1277    return nullptr;1278  }1279  return createMIRParser(std::move(FileOrErr.get()), Context,1280                         ProcessIRFunction);1281}1282 1283std::unique_ptr<MIRParser>1284llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,1285                      LLVMContext &Context,1286                      std::function<void(Function &)> ProcessIRFunction) {1287  auto Filename = Contents->getBufferIdentifier();1288  if (Context.shouldDiscardValueNames()) {1289    Context.diagnose(DiagnosticInfoMIRParser(1290        DS_Error,1291        SMDiagnostic(1292            Filename, SourceMgr::DK_Error,1293            "Can't read MIR with a Context that discards named Values")));1294    return nullptr;1295  }1296  return std::make_unique<MIRParser>(std::make_unique<MIRParserImpl>(1297      std::move(Contents), Filename, Context, ProcessIRFunction));1298}1299