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