LCOV - code coverage report
Current view: top level - lib/CodeGen/MIRParser - MIRParser.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 412 430 95.8 %
Date: 2017-09-14 15:23:50 Functions: 38 38 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- MIRParser.cpp - MIR serialization format parser implementation -----===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file implements the class that parses the optional LLVM IR and machine
      11             : // functions that are stored in MIR files.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #include "llvm/CodeGen/MIRParser/MIRParser.h"
      16             : #include "MIParser.h"
      17             : #include "llvm/ADT/DenseMap.h"
      18             : #include "llvm/ADT/STLExtras.h"
      19             : #include "llvm/ADT/StringMap.h"
      20             : #include "llvm/ADT/StringRef.h"
      21             : #include "llvm/AsmParser/Parser.h"
      22             : #include "llvm/AsmParser/SlotMapping.h"
      23             : #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
      24             : #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
      25             : #include "llvm/CodeGen/MIRYamlMapping.h"
      26             : #include "llvm/CodeGen/MachineConstantPool.h"
      27             : #include "llvm/CodeGen/MachineFrameInfo.h"
      28             : #include "llvm/CodeGen/MachineFunction.h"
      29             : #include "llvm/CodeGen/MachineModuleInfo.h"
      30             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      31             : #include "llvm/IR/BasicBlock.h"
      32             : #include "llvm/IR/DebugInfo.h"
      33             : #include "llvm/IR/DiagnosticInfo.h"
      34             : #include "llvm/IR/Instructions.h"
      35             : #include "llvm/IR/LLVMContext.h"
      36             : #include "llvm/IR/Module.h"
      37             : #include "llvm/IR/ValueSymbolTable.h"
      38             : #include "llvm/Support/LineIterator.h"
      39             : #include "llvm/Support/MemoryBuffer.h"
      40             : #include "llvm/Support/SMLoc.h"
      41             : #include "llvm/Support/SourceMgr.h"
      42             : #include "llvm/Support/YAMLTraits.h"
      43             : #include <memory>
      44             : 
      45             : using namespace llvm;
      46             : 
      47             : namespace llvm {
      48             : 
      49             : /// This class implements the parsing of LLVM IR that's embedded inside a MIR
      50             : /// file.
      51         684 : class MIRParserImpl {
      52             :   SourceMgr SM;
      53             :   yaml::Input In;
      54             :   StringRef Filename;
      55             :   LLVMContext &Context;
      56             :   SlotMapping IRSlots;
      57             :   /// Maps from register class names to register classes.
      58             :   Name2RegClassMap Names2RegClasses;
      59             :   /// Maps from register bank names to register banks.
      60             :   Name2RegBankMap Names2RegBanks;
      61             :   /// True when the MIR file doesn't have LLVM IR. Dummy IR functions are
      62             :   /// created and inserted into the given module when this is true.
      63             :   bool NoLLVMIR = false;
      64             :   /// True when a well formed MIR file does not contain any MIR/machine function
      65             :   /// parts.
      66             :   bool NoMIRDocuments = false;
      67             : 
      68             : public:
      69             :   MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
      70             :                 StringRef Filename, LLVMContext &Context);
      71             : 
      72             :   void reportDiagnostic(const SMDiagnostic &Diag);
      73             : 
      74             :   /// Report an error with the given message at unknown location.
      75             :   ///
      76             :   /// Always returns true.
      77             :   bool error(const Twine &Message);
      78             : 
      79             :   /// Report an error with the given message at the given location.
      80             :   ///
      81             :   /// Always returns true.
      82             :   bool error(SMLoc Loc, const Twine &Message);
      83             : 
      84             :   /// Report a given error with the location translated from the location in an
      85             :   /// embedded string literal to a location in the MIR file.
      86             :   ///
      87             :   /// Always returns true.
      88             :   bool error(const SMDiagnostic &Error, SMRange SourceRange);
      89             : 
      90             :   /// Try to parse the optional LLVM module and the machine functions in the MIR
      91             :   /// file.
      92             :   ///
      93             :   /// Return null if an error occurred.
      94             :   std::unique_ptr<Module> parseIRModule();
      95             : 
      96             :   bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI);
      97             : 
      98             :   /// Parse the machine function in the current YAML document.
      99             :   ///
     100             :   ///
     101             :   /// Return true if an error occurred.
     102             :   bool parseMachineFunction(Module &M, MachineModuleInfo &MMI);
     103             : 
     104             :   /// Initialize the machine function to the state that's described in the MIR
     105             :   /// file.
     106             :   ///
     107             :   /// Return true if error occurred.
     108             :   bool initializeMachineFunction(const yaml::MachineFunction &YamlMF,
     109             :                                  MachineFunction &MF);
     110             : 
     111             :   bool parseRegisterInfo(PerFunctionMIParsingState &PFS,
     112             :                          const yaml::MachineFunction &YamlMF);
     113             : 
     114             :   bool setupRegisterInfo(const PerFunctionMIParsingState &PFS,
     115             :                          const yaml::MachineFunction &YamlMF);
     116             : 
     117             :   bool initializeFrameInfo(PerFunctionMIParsingState &PFS,
     118             :                            const yaml::MachineFunction &YamlMF);
     119             : 
     120             :   bool parseCalleeSavedRegister(PerFunctionMIParsingState &PFS,
     121             :                                 std::vector<CalleeSavedInfo> &CSIInfo,
     122             :                                 const yaml::StringValue &RegisterSource,
     123             :                                 int FrameIdx);
     124             : 
     125             :   bool parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS,
     126             :                                   const yaml::MachineStackObject &Object,
     127             :                                   int FrameIdx);
     128             : 
     129             :   bool initializeConstantPool(PerFunctionMIParsingState &PFS,
     130             :                               MachineConstantPool &ConstantPool,
     131             :                               const yaml::MachineFunction &YamlMF);
     132             : 
     133             :   bool initializeJumpTableInfo(PerFunctionMIParsingState &PFS,
     134             :                                const yaml::MachineJumpTable &YamlJTI);
     135             : 
     136             : private:
     137             :   bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node,
     138             :                    const yaml::StringValue &Source);
     139             : 
     140             :   bool parseMBBReference(PerFunctionMIParsingState &PFS,
     141             :                          MachineBasicBlock *&MBB,
     142             :                          const yaml::StringValue &Source);
     143             : 
     144             :   /// Return a MIR diagnostic converted from an MI string diagnostic.
     145             :   SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
     146             :                                     SMRange SourceRange);
     147             : 
     148             :   /// Return a MIR diagnostic converted from a diagnostic located in a YAML
     149             :   /// block scalar string.
     150             :   SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error,
     151             :                                        SMRange SourceRange);
     152             : 
     153             :   void initNames2RegClasses(const MachineFunction &MF);
     154             :   void initNames2RegBanks(const MachineFunction &MF);
     155             : 
     156             :   /// Check if the given identifier is a name of a register class.
     157             :   ///
     158             :   /// Return null if the name isn't a register class.
     159             :   const TargetRegisterClass *getRegClass(const MachineFunction &MF,
     160             :                                          StringRef Name);
     161             : 
     162             :   /// Check if the given identifier is a name of a register bank.
     163             :   ///
     164             :   /// Return null if the name isn't a register bank.
     165             :   const RegisterBank *getRegBank(const MachineFunction &MF, StringRef Name);
     166             : 
     167             :   void computeFunctionProperties(MachineFunction &MF);
     168             : };
     169             : 
     170             : } // end namespace llvm
     171             : 
     172           5 : static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
     173           5 :   reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
     174           5 : }
     175             : 
     176         689 : MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
     177         689 :                              StringRef Filename, LLVMContext &Context)
     178             :     : SM(),
     179             :       In(SM.getMemoryBuffer(
     180         689 :             SM.AddNewSourceBuffer(std::move(Contents), SMLoc()))->getBuffer(),
     181             :             nullptr, handleYAMLDiag, this),
     182             :       Filename(Filename),
     183        6201 :       Context(Context) {
     184         689 :   In.setContext(&In);
     185         689 : }
     186             : 
     187           3 : bool MIRParserImpl::error(const Twine &Message) {
     188           9 :   Context.diagnose(DiagnosticInfoMIRParser(
     189          12 :       DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));
     190           3 :   return true;
     191             : }
     192             : 
     193           9 : bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) {
     194          27 :   Context.diagnose(DiagnosticInfoMIRParser(
     195          36 :       DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message)));
     196           9 :   return true;
     197             : }
     198             : 
     199           7 : bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) {
     200             :   assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");
     201           7 :   reportDiagnostic(diagFromMIStringDiag(Error, SourceRange));
     202           7 :   return true;
     203             : }
     204             : 
     205         100 : void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
     206             :   DiagnosticSeverity Kind;
     207         100 :   switch (Diag.getKind()) {
     208         100 :   case SourceMgr::DK_Error:
     209         100 :     Kind = DS_Error;
     210         100 :     break;
     211           0 :   case SourceMgr::DK_Warning:
     212           0 :     Kind = DS_Warning;
     213           0 :     break;
     214           0 :   case SourceMgr::DK_Note:
     215           0 :     Kind = DS_Note;
     216           0 :     break;
     217             :   }
     218         300 :   Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
     219         100 : }
     220             : 
     221         689 : std::unique_ptr<Module> MIRParserImpl::parseIRModule() {
     222         689 :   if (!In.setCurrentDocument()) {
     223           2 :     if (In.error())
     224             :       return nullptr;
     225             :     // Create an empty module when the MIR file is empty.
     226           2 :     NoMIRDocuments = true;
     227           2 :     return llvm::make_unique<Module>(Filename, Context);
     228             :   }
     229             : 
     230        1374 :   std::unique_ptr<Module> M;
     231             :   // Parse the block scalar manually so that we can return unique pointer
     232             :   // without having to go trough YAML traits.
     233             :   if (const auto *BSN =
     234        1266 :           dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
     235        1157 :     SMDiagnostic Error;
     236        1158 :     M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
     237             :                       Context, &IRSlots);
     238         579 :     if (!M) {
     239           1 :       reportDiagnostic(diagFromBlockStringDiag(Error, BSN->getSourceRange()));
     240           1 :       return nullptr;
     241             :     }
     242         578 :     In.nextDocument();
     243         578 :     if (!In.setCurrentDocument())
     244           1 :       NoMIRDocuments = true;
     245             :   } else {
     246             :     // Create an new, empty module.
     247         108 :     M = llvm::make_unique<Module>(Filename, Context);
     248         108 :     NoLLVMIR = true;
     249             :   }
     250             :   return M;
     251             : }
     252             : 
     253         688 : bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
     254         688 :   if (NoMIRDocuments)
     255             :     return false;
     256             : 
     257             :   // Parse the machine functions.
     258             :   do {
     259        2255 :     if (parseMachineFunction(M, MMI))
     260             :       return true;
     261        2139 :     In.nextDocument();
     262        2139 :   } while (In.setCurrentDocument());
     263             : 
     264             :   return false;
     265             : }
     266             : 
     267             : /// Create an empty function with the given name.
     268         266 : static Function *createDummyFunction(StringRef Name, Module &M) {
     269         266 :   auto &Context = M.getContext();
     270         266 :   Function *F = cast<Function>(M.getOrInsertFunction(
     271         266 :       Name, FunctionType::get(Type::getVoidTy(Context), false)));
     272         532 :   BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
     273         266 :   new UnreachableInst(Context, BB);
     274         266 :   return F;
     275             : }
     276             : 
     277        2255 : bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI) {
     278             :   // Parse the yaml.
     279        4505 :   yaml::MachineFunction YamlMF;
     280             :   yaml::EmptyContext Ctx;
     281        2255 :   yaml::yamlize(In, YamlMF, false, Ctx);
     282        2255 :   if (In.error())
     283             :     return true;
     284             : 
     285             :   // Search for the corresponding IR function.
     286        2250 :   StringRef FunctionName = YamlMF.Name;
     287        2250 :   Function *F = M.getFunction(FunctionName);
     288        2250 :   if (!F) {
     289         267 :     if (NoLLVMIR) {
     290         266 :       F = createDummyFunction(FunctionName, M);
     291             :     } else {
     292           5 :       return error(Twine("function '") + FunctionName +
     293           3 :                    "' isn't defined in the provided LLVM IR");
     294             :     }
     295             :   }
     296        2249 :   if (MMI.getMachineFunction(*F) != nullptr)
     297           5 :     return error(Twine("redefinition of machine function '") + FunctionName +
     298           3 :                  "'");
     299             : 
     300             :   // Create the MachineFunction.
     301        2248 :   MachineFunction &MF = MMI.getOrCreateMachineFunction(*F);
     302        2248 :   if (initializeMachineFunction(YamlMF, MF))
     303             :     return true;
     304             : 
     305        2139 :   return false;
     306             : }
     307             : 
     308        2144 : static bool isSSA(const MachineFunction &MF) {
     309        2144 :   const MachineRegisterInfo &MRI = MF.getRegInfo();
     310       11284 :   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
     311        7042 :     unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
     312        7753 :     if (!MRI.hasOneDef(Reg) && !MRI.def_empty(Reg))
     313             :       return false;
     314             :   }
     315             :   return true;
     316             : }
     317             : 
     318        2144 : void MIRParserImpl::computeFunctionProperties(MachineFunction &MF) {
     319        2144 :   MachineFunctionProperties &Properties = MF.getProperties();
     320             : 
     321        2144 :   bool HasPHI = false;
     322        2144 :   bool HasInlineAsm = false;
     323        9408 :   for (const MachineBasicBlock &MBB : MF) {
     324       44768 :     for (const MachineInstr &MI : MBB) {
     325       16368 :       if (MI.isPHI())
     326             :         HasPHI = true;
     327       16432 :       if (MI.isInlineAsm())
     328          15 :         HasInlineAsm = true;
     329             :     }
     330             :   }
     331        2144 :   if (!HasPHI)
     332             :     Properties.set(MachineFunctionProperties::Property::NoPHIs);
     333        4288 :   MF.setHasInlineAsm(HasInlineAsm);
     334             : 
     335        2144 :   if (isSSA(MF))
     336             :     Properties.set(MachineFunctionProperties::Property::IsSSA);
     337             :   else
     338             :     Properties.reset(MachineFunctionProperties::Property::IsSSA);
     339             : 
     340        2144 :   const MachineRegisterInfo &MRI = MF.getRegInfo();
     341        2144 :   if (MRI.getNumVirtRegs() == 0)
     342             :     Properties.set(MachineFunctionProperties::Property::NoVRegs);
     343        2144 : }
     344             : 
     345             : bool
     346        2248 : MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
     347             :                                          MachineFunction &MF) {
     348             :   // TODO: Recreate the machine function.
     349        2248 :   initNames2RegClasses(MF);
     350        2248 :   initNames2RegBanks(MF);
     351        2248 :   if (YamlMF.Alignment)
     352         795 :     MF.setAlignment(YamlMF.Alignment);
     353        4496 :   MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
     354             : 
     355        2248 :   if (YamlMF.Legalized)
     356         974 :     MF.getProperties().set(MachineFunctionProperties::Property::Legalized);
     357        2248 :   if (YamlMF.RegBankSelected)
     358         742 :     MF.getProperties().set(
     359             :         MachineFunctionProperties::Property::RegBankSelected);
     360        2248 :   if (YamlMF.Selected)
     361           2 :     MF.getProperties().set(MachineFunctionProperties::Property::Selected);
     362             : 
     363             :   PerFunctionMIParsingState PFS(MF, SM, IRSlots, Names2RegClasses,
     364        4491 :                                 Names2RegBanks);
     365        2248 :   if (parseRegisterInfo(PFS, YamlMF))
     366             :     return true;
     367        4486 :   if (!YamlMF.Constants.empty()) {
     368          13 :     auto *ConstantPool = MF.getConstantPool();
     369             :     assert(ConstantPool && "Constant pool must be created");
     370          13 :     if (initializeConstantPool(PFS, *ConstantPool, YamlMF))
     371             :       return true;
     372             :   }
     373             : 
     374        4480 :   StringRef BlockStr = YamlMF.Body.Value.Value;
     375        4475 :   SMDiagnostic Error;
     376        4475 :   SourceMgr BlockSM;
     377        4480 :   BlockSM.AddNewSourceBuffer(
     378        4480 :       MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false),
     379        2240 :       SMLoc());
     380        2240 :   PFS.SM = &BlockSM;
     381        2240 :   if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)) {
     382          12 :     reportDiagnostic(
     383          24 :         diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
     384          12 :     return true;
     385             :   }
     386        2228 :   PFS.SM = &SM;
     387             : 
     388             :   // Initialize the frame information after creating all the MBBs so that the
     389             :   // MBB references in the frame information can be resolved.
     390        2228 :   if (initializeFrameInfo(PFS, YamlMF))
     391             :     return true;
     392             :   // Initialize the jump table after creating all the MBBs so that the MBB
     393             :   // references can be resolved.
     394        4451 :   if (!YamlMF.JumpTableInfo.Entries.empty() &&
     395           9 :       initializeJumpTableInfo(PFS, YamlMF.JumpTableInfo))
     396             :     return true;
     397             :   // Parse the machine instructions after creating all of the MBBs so that the
     398             :   // parser can resolve the MBB references.
     399        4440 :   StringRef InsnStr = YamlMF.Body.Value.Value;
     400        4435 :   SourceMgr InsnSM;
     401        4440 :   InsnSM.AddNewSourceBuffer(
     402        4440 :       MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false),
     403        2220 :       SMLoc());
     404        2220 :   PFS.SM = &InsnSM;
     405        2220 :   if (parseMachineInstructions(PFS, InsnStr, Error)) {
     406          75 :     reportDiagnostic(
     407         150 :         diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
     408          75 :     return true;
     409             :   }
     410        2145 :   PFS.SM = &SM;
     411             : 
     412        2145 :   if (setupRegisterInfo(PFS, YamlMF))
     413             :     return true;
     414             : 
     415        2144 :   computeFunctionProperties(MF);
     416             : 
     417        2144 :   MF.verify();
     418        2139 :   return false;
     419             : }
     420             : 
     421        2248 : bool MIRParserImpl::parseRegisterInfo(PerFunctionMIParsingState &PFS,
     422             :                                       const yaml::MachineFunction &YamlMF) {
     423        2248 :   MachineFunction &MF = PFS.MF;
     424        2248 :   MachineRegisterInfo &RegInfo = MF.getRegInfo();
     425             :   assert(RegInfo.tracksLiveness());
     426        2248 :   if (!YamlMF.TracksRegLiveness)
     427             :     RegInfo.invalidateLiveness();
     428             : 
     429        4496 :   SMDiagnostic Error;
     430             :   // Parse the virtual register information.
     431       16051 :   for (const auto &VReg : YamlMF.VirtualRegisters) {
     432        7061 :     VRegInfo &Info = PFS.getVRegInfo(VReg.ID.Value);
     433        7061 :     if (Info.Explicit)
     434             :       return error(VReg.ID.SourceRange.Start,
     435           3 :                    Twine("redefinition of virtual register '%") +
     436           4 :                        Twine(VReg.ID.Value) + "'");
     437        7060 :     Info.Explicit = true;
     438             : 
     439       18829 :     if (StringRef(VReg.Class.Value).equals("_")) {
     440        2351 :       Info.Kind = VRegInfo::GENERIC;
     441             :     } else {
     442        9418 :       const auto *RC = getRegClass(MF, VReg.Class.Value);
     443        4709 :       if (RC) {
     444        2665 :         Info.Kind = VRegInfo::NORMAL;
     445        2665 :         Info.D.RC = RC;
     446             :       } else {
     447        4088 :         const RegisterBank *RegBank = getRegBank(MF, VReg.Class.Value);
     448        2044 :         if (!RegBank)
     449             :           return error(
     450             :               VReg.Class.SourceRange.Start,
     451           3 :               Twine("use of undefined register class or register bank '") +
     452           4 :                   VReg.Class.Value + "'");
     453        2043 :         Info.Kind = VRegInfo::REGBANK;
     454        2043 :         Info.D.RegBank = RegBank;
     455             :       }
     456             :     }
     457             : 
     458       14118 :     if (!VReg.PreferredRegister.Value.empty()) {
     459           9 :       if (Info.Kind != VRegInfo::NORMAL)
     460             :         return error(VReg.Class.SourceRange.Start,
     461           0 :               Twine("preferred register can only be set for normal vregs"));
     462             : 
     463          18 :       if (parseRegisterReference(PFS, Info.PreferredReg,
     464             :                                  VReg.PreferredRegister.Value, Error))
     465           0 :         return error(Error, VReg.PreferredRegister.SourceRange);
     466             :     }
     467             :   }
     468             : 
     469             :   // Parse the liveins.
     470        9468 :   for (const auto &LiveIn : YamlMF.LiveIns) {
     471         487 :     unsigned Reg = 0;
     472         974 :     if (parseNamedRegisterReference(PFS, Reg, LiveIn.Register.Value, Error))
     473           5 :       return error(Error, LiveIn.Register.SourceRange);
     474         485 :     unsigned VReg = 0;
     475         970 :     if (!LiveIn.VirtualRegister.Value.empty()) {
     476             :       VRegInfo *Info;
     477         264 :       if (parseVirtualRegisterReference(PFS, Info, LiveIn.VirtualRegister.Value,
     478             :                                         Error))
     479           1 :         return error(Error, LiveIn.VirtualRegister.SourceRange);
     480         131 :       VReg = Info->VReg;
     481             :     }
     482         968 :     RegInfo.addLiveIn(Reg, VReg);
     483             :   }
     484             : 
     485             :   // Parse the callee saved registers (Registers that will
     486             :   // be saved for the caller).
     487        2243 :   if (YamlMF.CalleeSavedRegisters) {
     488          34 :     SmallVector<MCPhysReg, 16> CalleeSavedRegisters;
     489         822 :     for (const auto &RegSource : YamlMF.CalleeSavedRegisters.getValue()) {
     490         737 :       unsigned Reg = 0;
     491        1474 :       if (parseNamedRegisterReference(PFS, Reg, RegSource.Value, Error))
     492           0 :         return error(Error, RegSource.SourceRange);
     493         737 :       CalleeSavedRegisters.push_back(Reg);
     494             :     }
     495          17 :     RegInfo.setCalleeSavedRegs(CalleeSavedRegisters);
     496             :   }
     497             : 
     498             :   return false;
     499             : }
     500             : 
     501        2145 : bool MIRParserImpl::setupRegisterInfo(const PerFunctionMIParsingState &PFS,
     502             :                                       const yaml::MachineFunction &YamlMF) {
     503        2145 :   MachineFunction &MF = PFS.MF;
     504        2145 :   MachineRegisterInfo &MRI = MF.getRegInfo();
     505        2145 :   bool Error = false;
     506             :   // Create VRegs
     507        4290 :   for (auto P : PFS.VRegInfos) {
     508        7430 :     const VRegInfo &Info = *P.second;
     509        7430 :     unsigned Reg = Info.VReg;
     510        7430 :     switch (Info.Kind) {
     511           1 :     case VRegInfo::UNKNOWN:
     512           4 :       error(Twine("Cannot determine class/bank of virtual register ") +
     513           9 :             Twine(P.first) + " in function '" + MF.getName() + "'");
     514           1 :       Error = true;
     515           1 :       break;
     516        2723 :     case VRegInfo::NORMAL:
     517        2723 :       MRI.setRegClass(Reg, Info.D.RC);
     518        2723 :       if (Info.PreferredReg != 0)
     519           9 :         MRI.setSimpleHint(Reg, Info.PreferredReg);
     520             :       break;
     521             :     case VRegInfo::GENERIC:
     522             :       break;
     523        2175 :     case VRegInfo::REGBANK:
     524        2175 :       MRI.setRegBank(Reg, *Info.D.RegBank);
     525        2175 :       break;
     526             :     }
     527             :   }
     528             : 
     529             :   // Compute MachineRegisterInfo::UsedPhysRegMask
     530        9412 :   for (const MachineBasicBlock &MBB : MF) {
     531       44778 :     for (const MachineInstr &MI : MBB) {
     532       66861 :       for (const MachineOperand &MO : MI.operands()) {
     533       50426 :         if (!MO.isRegMask())
     534       50318 :           continue;
     535         108 :         MRI.addPhysRegsUsedFromRegMask(MO.getRegMask());
     536             :       }
     537             :     }
     538             :   }
     539             : 
     540             :   // FIXME: This is a temporary workaround until the reserved registers can be
     541             :   // serialized.
     542        2145 :   MRI.freezeReservedRegs(MF);
     543        2145 :   return Error;
     544             : }
     545             : 
     546        2228 : bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS,
     547             :                                         const yaml::MachineFunction &YamlMF) {
     548        2228 :   MachineFunction &MF = PFS.MF;
     549        2228 :   MachineFrameInfo &MFI = MF.getFrameInfo();
     550        2228 :   const Function &F = *MF.getFunction();
     551        2228 :   const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
     552        4456 :   MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
     553        4456 :   MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
     554        4456 :   MFI.setHasStackMap(YamlMFI.HasStackMap);
     555        4456 :   MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);
     556        4456 :   MFI.setStackSize(YamlMFI.StackSize);
     557        4456 :   MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment);
     558        2228 :   if (YamlMFI.MaxAlignment)
     559          67 :     MFI.ensureMaxAlignment(YamlMFI.MaxAlignment);
     560        4456 :   MFI.setAdjustsStack(YamlMFI.AdjustsStack);
     561        4456 :   MFI.setHasCalls(YamlMFI.HasCalls);
     562        2228 :   if (YamlMFI.MaxCallFrameSize != ~0u)
     563         146 :     MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize);
     564        4456 :   MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);
     565        4456 :   MFI.setHasVAStart(YamlMFI.HasVAStart);
     566        4456 :   MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
     567        4456 :   if (!YamlMFI.SavePoint.Value.empty()) {
     568           1 :     MachineBasicBlock *MBB = nullptr;
     569           1 :     if (parseMBBReference(PFS, MBB, YamlMFI.SavePoint))
     570           0 :       return true;
     571           2 :     MFI.setSavePoint(MBB);
     572             :   }
     573        4456 :   if (!YamlMFI.RestorePoint.Value.empty()) {
     574           1 :     MachineBasicBlock *MBB = nullptr;
     575           1 :     if (parseMBBReference(PFS, MBB, YamlMFI.RestorePoint))
     576           0 :       return true;
     577           2 :     MFI.setRestorePoint(MBB);
     578             :   }
     579             : 
     580        2228 :   std::vector<CalleeSavedInfo> CSIInfo;
     581             :   // Initialize the fixed frame objects.
     582        9002 :   for (const auto &Object : YamlMF.FixedStackObjects) {
     583             :     int ObjectIdx;
     584          92 :     if (Object.Type != yaml::FixedMachineStackObject::SpillSlot)
     585          84 :       ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset,
     586          84 :                                         Object.IsImmutable, Object.IsAliased);
     587             :     else
     588          50 :       ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
     589         184 :     MFI.setObjectAlignment(ObjectIdx, Object.Alignment);
     590         184 :     MFI.setStackID(ObjectIdx, Object.StackID);
     591         368 :     if (!PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID.Value,
     592          92 :                                                          ObjectIdx))
     593          92 :              .second)
     594             :       return error(Object.ID.SourceRange.Start,
     595           3 :                    Twine("redefinition of fixed stack object '%fixed-stack.") +
     596           4 :                        Twine(Object.ID.Value) + "'");
     597          91 :     if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister,
     598             :                                  ObjectIdx))
     599             :       return true;
     600             :   }
     601             : 
     602             :   // Initialize the ordinary frame objects.
     603        9046 :   for (const auto &Object : YamlMF.StackObjects) {
     604             :     int ObjectIdx;
     605         146 :     const AllocaInst *Alloca = nullptr;
     606         146 :     const yaml::StringValue &Name = Object.Name;
     607         292 :     if (!Name.Value.empty()) {
     608         213 :       Alloca = dyn_cast_or_null<AllocaInst>(
     609             :           F.getValueSymbolTable()->lookup(Name.Value));
     610             :       if (!Alloca)
     611             :         return error(Name.SourceRange.Start,
     612           3 :                      "alloca instruction named '" + Name.Value +
     613           7 :                          "' isn't defined in the function '" + F.getName() +
     614           3 :                          "'");
     615             :     }
     616         145 :     if (Object.Type == yaml::MachineStackObject::VariableSized)
     617           3 :       ObjectIdx = MFI.CreateVariableSizedObject(Object.Alignment, Alloca);
     618             :     else
     619         284 :       ObjectIdx = MFI.CreateStackObject(
     620         142 :           Object.Size, Object.Alignment,
     621             :           Object.Type == yaml::MachineStackObject::SpillSlot, Alloca);
     622         290 :     MFI.setObjectOffset(ObjectIdx, Object.Offset);
     623         290 :     MFI.setStackID(ObjectIdx, Object.StackID);
     624             : 
     625         580 :     if (!PFS.StackObjectSlots.insert(std::make_pair(Object.ID.Value, ObjectIdx))
     626         145 :              .second)
     627             :       return error(Object.ID.SourceRange.Start,
     628           3 :                    Twine("redefinition of stack object '%stack.") +
     629           4 :                        Twine(Object.ID.Value) + "'");
     630         144 :     if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister,
     631             :                                  ObjectIdx))
     632             :       return true;
     633         144 :     if (Object.LocalOffset)
     634          44 :       MFI.mapLocalFrameObject(ObjectIdx, Object.LocalOffset.getValue());
     635         144 :     if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx))
     636             :       return true;
     637             :   }
     638        2222 :   MFI.setCalleeSavedInfo(CSIInfo);
     639        2222 :   if (!CSIInfo.empty())
     640             :     MFI.setCalleeSavedInfoValid(true);
     641             : 
     642             :   // Initialize the various stack object references after initializing the
     643             :   // stack objects.
     644        4444 :   if (!YamlMFI.StackProtector.Value.empty()) {
     645           3 :     SMDiagnostic Error;
     646             :     int FI;
     647           4 :     if (parseStackObjectReference(PFS, FI, YamlMFI.StackProtector.Value, Error))
     648           1 :       return error(Error, YamlMFI.StackProtector.SourceRange);
     649           2 :     MFI.setStackProtectorIndex(FI);
     650             :   }
     651             :   return false;
     652             : }
     653             : 
     654         235 : bool MIRParserImpl::parseCalleeSavedRegister(PerFunctionMIParsingState &PFS,
     655             :     std::vector<CalleeSavedInfo> &CSIInfo,
     656             :     const yaml::StringValue &RegisterSource, int FrameIdx) {
     657         470 :   if (RegisterSource.Value.empty())
     658             :     return false;
     659          65 :   unsigned Reg = 0;
     660         130 :   SMDiagnostic Error;
     661         130 :   if (parseNamedRegisterReference(PFS, Reg, RegisterSource.Value, Error))
     662           1 :     return error(Error, RegisterSource.SourceRange);
     663         192 :   CSIInfo.push_back(CalleeSavedInfo(Reg, FrameIdx));
     664          64 :   return false;
     665             : }
     666             : 
     667             : /// Verify that given node is of a certain type. Return true on error.
     668             : template <typename T>
     669           4 : static bool typecheckMDNode(T *&Result, MDNode *Node,
     670             :                             const yaml::StringValue &Source,
     671             :                             StringRef TypeString, MIRParserImpl &Parser) {
     672           4 :   if (!Node)
     673             :     return false;
     674           4 :   Result = dyn_cast<T>(Node);
     675           4 :   if (!Result)
     676             :     return Parser.error(Source.SourceRange.Start,
     677           4 :                         "expected a reference to a '" + TypeString +
     678           1 :                             "' metadata node");
     679             :   return false;
     680             : }
     681             : 
     682         144 : bool MIRParserImpl::parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS,
     683             :     const yaml::MachineStackObject &Object, int FrameIdx) {
     684             :   // Debug information can only be attached to stack objects; Fixed stack
     685             :   // objects aren't supported.
     686             :   assert(FrameIdx >= 0 && "Expected a stack object frame index");
     687         144 :   MDNode *Var = nullptr, *Expr = nullptr, *Loc = nullptr;
     688         287 :   if (parseMDNode(PFS, Var, Object.DebugVar) ||
     689         287 :       parseMDNode(PFS, Expr, Object.DebugExpr) ||
     690         143 :       parseMDNode(PFS, Loc, Object.DebugLoc))
     691             :     return true;
     692         143 :   if (!Var && !Expr && !Loc)
     693             :     return false;
     694           2 :   DILocalVariable *DIVar = nullptr;
     695           2 :   DIExpression *DIExpr = nullptr;
     696           2 :   DILocation *DILoc = nullptr;
     697           5 :   if (typecheckMDNode(DIVar, Var, Object.DebugVar, "DILocalVariable", *this) ||
     698           6 :       typecheckMDNode(DIExpr, Expr, Object.DebugExpr, "DIExpression", *this) ||
     699           3 :       typecheckMDNode(DILoc, Loc, Object.DebugLoc, "DILocation", *this))
     700             :     return true;
     701           2 :   PFS.MF.setVariableDbgInfo(DIVar, DIExpr, unsigned(FrameIdx), DILoc);
     702           1 :   return false;
     703             : }
     704             : 
     705         430 : bool MIRParserImpl::parseMDNode(PerFunctionMIParsingState &PFS,
     706             :     MDNode *&Node, const yaml::StringValue &Source) {
     707         860 :   if (Source.Value.empty())
     708             :     return false;
     709          14 :   SMDiagnostic Error;
     710          14 :   if (llvm::parseMDNode(PFS, Node, Source.Value, Error))
     711           1 :     return error(Error, Source.SourceRange);
     712             :   return false;
     713             : }
     714             : 
     715          13 : bool MIRParserImpl::initializeConstantPool(PerFunctionMIParsingState &PFS,
     716             :     MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF) {
     717          13 :   DenseMap<unsigned, unsigned> &ConstantPoolSlots = PFS.ConstantPoolSlots;
     718          13 :   const MachineFunction &MF = PFS.MF;
     719          13 :   const auto &M = *MF.getFunction()->getParent();
     720          26 :   SMDiagnostic Error;
     721          67 :   for (const auto &YamlConstant : YamlMF.Constants) {
     722          18 :     if (YamlConstant.IsTargetSpecific)
     723             :       // FIXME: Support target-specific constant pools
     724           2 :       return error(YamlConstant.Value.SourceRange.Start,
     725           1 :                    "Can't parse target-specific constant pool entries yet");
     726          51 :     const Constant *Value = dyn_cast_or_null<Constant>(
     727          17 :         parseConstantValue(YamlConstant.Value.Value, Error, M));
     728             :     if (!Value)
     729           1 :       return error(Error, YamlConstant.Value.SourceRange);
     730             :     unsigned Alignment =
     731          16 :         YamlConstant.Alignment
     732          24 :             ? YamlConstant.Alignment
     733          24 :             : M.getDataLayout().getPrefTypeAlignment(Value->getType());
     734          16 :     unsigned Index = ConstantPool.getConstantPoolIndex(Value, Alignment);
     735          64 :     if (!ConstantPoolSlots.insert(std::make_pair(YamlConstant.ID.Value, Index))
     736          16 :              .second)
     737             :       return error(YamlConstant.ID.SourceRange.Start,
     738           3 :                    Twine("redefinition of constant pool item '%const.") +
     739           4 :                        Twine(YamlConstant.ID.Value) + "'");
     740             :   }
     741             :   return false;
     742             : }
     743             : 
     744           9 : bool MIRParserImpl::initializeJumpTableInfo(PerFunctionMIParsingState &PFS,
     745             :     const yaml::MachineJumpTable &YamlJTI) {
     746           9 :   MachineJumpTableInfo *JTI = PFS.MF.getOrCreateJumpTableInfo(YamlJTI.Kind);
     747          45 :   for (const auto &Entry : YamlJTI.Entries) {
     748          19 :     std::vector<MachineBasicBlock *> Blocks;
     749         125 :     for (const auto &MBBSource : Entry.Blocks) {
     750          85 :       MachineBasicBlock *MBB = nullptr;
     751         425 :       if (parseMBBReference(PFS, MBB, MBBSource.Value))
     752           0 :         return true;
     753          85 :       Blocks.push_back(MBB);
     754             :     }
     755          10 :     unsigned Index = JTI->createJumpTableIndex(Blocks);
     756          40 :     if (!PFS.JumpTableSlots.insert(std::make_pair(Entry.ID.Value, Index))
     757          10 :              .second)
     758             :       return error(Entry.ID.SourceRange.Start,
     759           3 :                    Twine("redefinition of jump table entry '%jump-table.") +
     760           4 :                        Twine(Entry.ID.Value) + "'");
     761             :   }
     762             :   return false;
     763             : }
     764             : 
     765          87 : bool MIRParserImpl::parseMBBReference(PerFunctionMIParsingState &PFS,
     766             :                                       MachineBasicBlock *&MBB,
     767             :                                       const yaml::StringValue &Source) {
     768         174 :   SMDiagnostic Error;
     769         174 :   if (llvm::parseMBBReference(PFS, MBB, Source.Value, Error))
     770           0 :     return error(Error, Source.SourceRange);
     771             :   return false;
     772             : }
     773             : 
     774           7 : SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
     775             :                                                  SMRange SourceRange) {
     776             :   assert(SourceRange.isValid() && "Invalid source range");
     777           7 :   SMLoc Loc = SourceRange.Start;
     778          21 :   bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
     779          14 :                   *Loc.getPointer() == '\'';
     780             :   // Translate the location of the error from the location in the MI string to
     781             :   // the corresponding location in the MIR file.
     782          14 :   Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
     783           7 :                            (HasQuote ? 1 : 0));
     784             : 
     785             :   // TODO: Translate any source ranges as well.
     786          14 :   return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None,
     787          35 :                        Error.getFixIts());
     788             : }
     789             : 
     790          88 : SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error,
     791             :                                                     SMRange SourceRange) {
     792             :   assert(SourceRange.isValid());
     793             : 
     794             :   // Translate the location of the error from the location in the llvm IR string
     795             :   // to the corresponding location in the MIR file.
     796          88 :   auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
     797          88 :   unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
     798          88 :   unsigned Column = Error.getColumnNo();
     799          88 :   StringRef LineStr = Error.getLineContents();
     800          88 :   SMLoc Loc = Error.getLoc();
     801             : 
     802             :   // Get the full line and adjust the column number by taking the indentation of
     803             :   // LLVM IR into account.
     804         176 :   for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
     805             :        L != E; ++L) {
     806        2078 :     if (L.line_number() == Line) {
     807          88 :       LineStr = *L;
     808         176 :       Loc = SMLoc::getFromPointer(LineStr.data());
     809          88 :       auto Indent = LineStr.find(Error.getLineContents());
     810          88 :       if (Indent != StringRef::npos)
     811          88 :         Column += Indent;
     812             :       break;
     813             :     }
     814             :   }
     815             : 
     816             :   return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
     817             :                       Error.getMessage(), LineStr, Error.getRanges(),
     818         264 :                       Error.getFixIts());
     819             : }
     820             : 
     821        2248 : void MIRParserImpl::initNames2RegClasses(const MachineFunction &MF) {
     822        2248 :   if (!Names2RegClasses.empty())
     823             :     return;
     824         680 :   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
     825       57249 :   for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) {
     826      111778 :     const auto *RC = TRI->getRegClass(I);
     827       55889 :     Names2RegClasses.insert(
     828      447112 :         std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC));
     829             :   }
     830             : }
     831             : 
     832        2248 : void MIRParserImpl::initNames2RegBanks(const MachineFunction &MF) {
     833        2248 :   if (!Names2RegBanks.empty())
     834             :     return;
     835         695 :   const RegisterBankInfo *RBI = MF.getSubtarget().getRegBankInfo();
     836             :   // If the target does not support GlobalISel, we may not have a
     837             :   // register bank info.
     838         695 :   if (!RBI)
     839             :     return;
     840        1965 :   for (unsigned I = 0, E = RBI->getNumRegBanks(); I < E; ++I) {
     841        1345 :     const auto &RegBank = RBI->getRegBank(I);
     842        1345 :     Names2RegBanks.insert(
     843        9415 :         std::make_pair(StringRef(RegBank.getName()).lower(), &RegBank));
     844             :   }
     845             : }
     846             : 
     847        4709 : const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF,
     848             :                                                       StringRef Name) {
     849        4709 :   auto RegClassInfo = Names2RegClasses.find(Name);
     850        9418 :   if (RegClassInfo == Names2RegClasses.end())
     851             :     return nullptr;
     852        2665 :   return RegClassInfo->getValue();
     853             : }
     854             : 
     855        2044 : const RegisterBank *MIRParserImpl::getRegBank(const MachineFunction &MF,
     856             :                                               StringRef Name) {
     857        2044 :   auto RegBankInfo = Names2RegBanks.find(Name);
     858        4088 :   if (RegBankInfo == Names2RegBanks.end())
     859             :     return nullptr;
     860        2043 :   return RegBankInfo->getValue();
     861             : }
     862             : 
     863         689 : MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
     864        1378 :     : Impl(std::move(Impl)) {}
     865             : 
     866         684 : MIRParser::~MIRParser() {}
     867             : 
     868         689 : std::unique_ptr<Module> MIRParser::parseIRModule() {
     869        1378 :   return Impl->parseIRModule();
     870             : }
     871             : 
     872         688 : bool MIRParser::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
     873        1376 :   return Impl->parseMachineFunctions(M, MMI);
     874             : }
     875             : 
     876         668 : std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename,
     877             :                                                          SMDiagnostic &Error,
     878             :                                                          LLVMContext &Context) {
     879        1336 :   auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename);
     880         668 :   if (std::error_code EC = FileOrErr.getError()) {
     881           0 :     Error = SMDiagnostic(Filename, SourceMgr::DK_Error,
     882           0 :                          "Could not open input file: " + EC.message());
     883           0 :     return nullptr;
     884             :   }
     885        2004 :   return createMIRParser(std::move(FileOrErr.get()), Context);
     886             : }
     887             : 
     888             : std::unique_ptr<MIRParser>
     889         689 : llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
     890             :                       LLVMContext &Context) {
     891         689 :   auto Filename = Contents->getBufferIdentifier();
     892         689 :   if (Context.shouldDiscardValueNames()) {
     893           0 :     Context.diagnose(DiagnosticInfoMIRParser(
     894             :         DS_Error,
     895           0 :         SMDiagnostic(
     896             :             Filename, SourceMgr::DK_Error,
     897             :             "Can't read MIR with a Context that discards named Values")));
     898             :     return nullptr;
     899             :   }
     900             :   return llvm::make_unique<MIRParser>(
     901         689 :       llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context));
     902             : }

Generated by: LCOV version 1.13