xref: /src/contrib/llvm-project/llvm/lib/CodeGen/MIRParser/MIRParser.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
185d8b2bbSDimitry Andric //===- MIRParser.cpp - MIR serialization format parser implementation -----===//
285d8b2bbSDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
685d8b2bbSDimitry Andric //
785d8b2bbSDimitry Andric //===----------------------------------------------------------------------===//
885d8b2bbSDimitry Andric //
985d8b2bbSDimitry Andric // This file implements the class that parses the optional LLVM IR and machine
1085d8b2bbSDimitry Andric // functions that are stored in MIR files.
1185d8b2bbSDimitry Andric //
1285d8b2bbSDimitry Andric //===----------------------------------------------------------------------===//
1385d8b2bbSDimitry Andric 
1485d8b2bbSDimitry Andric #include "llvm/CodeGen/MIRParser/MIRParser.h"
151a82d4c0SDimitry Andric #include "llvm/ADT/DenseMap.h"
1601095a5dSDimitry Andric #include "llvm/ADT/StringRef.h"
1785d8b2bbSDimitry Andric #include "llvm/AsmParser/Parser.h"
181a82d4c0SDimitry Andric #include "llvm/AsmParser/SlotMapping.h"
19e6d15924SDimitry Andric #include "llvm/CodeGen/MIRParser/MIParser.h"
2001095a5dSDimitry Andric #include "llvm/CodeGen/MIRYamlMapping.h"
21dd58ef01SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h"
22ee8648bdSDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
2301095a5dSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
24ac9a064cSDimitry Andric #include "llvm/CodeGen/MachineFunctionAnalysis.h"
25dd58ef01SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
261a82d4c0SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
27e6d15924SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
283a0822f0SDimitry Andric #include "llvm/IR/BasicBlock.h"
29145449b1SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
303a0822f0SDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
313a0822f0SDimitry Andric #include "llvm/IR/Instructions.h"
323a0822f0SDimitry Andric #include "llvm/IR/LLVMContext.h"
3385d8b2bbSDimitry Andric #include "llvm/IR/Module.h"
343a0822f0SDimitry Andric #include "llvm/IR/ValueSymbolTable.h"
3585d8b2bbSDimitry Andric #include "llvm/Support/LineIterator.h"
3601095a5dSDimitry Andric #include "llvm/Support/MemoryBuffer.h"
3785d8b2bbSDimitry Andric #include "llvm/Support/SMLoc.h"
3885d8b2bbSDimitry Andric #include "llvm/Support/SourceMgr.h"
3985d8b2bbSDimitry Andric #include "llvm/Support/YAMLTraits.h"
40e6d15924SDimitry Andric #include "llvm/Target/TargetMachine.h"
4185d8b2bbSDimitry Andric #include <memory>
4285d8b2bbSDimitry Andric 
4385d8b2bbSDimitry Andric using namespace llvm;
4485d8b2bbSDimitry Andric 
453a0822f0SDimitry Andric namespace llvm {
46145449b1SDimitry Andric class MDNode;
47145449b1SDimitry Andric class RegisterBank;
4885d8b2bbSDimitry Andric 
4985d8b2bbSDimitry Andric /// This class implements the parsing of LLVM IR that's embedded inside a MIR
5085d8b2bbSDimitry Andric /// file.
5185d8b2bbSDimitry Andric class MIRParserImpl {
5285d8b2bbSDimitry Andric   SourceMgr SM;
53344a3780SDimitry Andric   LLVMContext &Context;
547ab83427SDimitry Andric   yaml::Input In;
5585d8b2bbSDimitry Andric   StringRef Filename;
561a82d4c0SDimitry Andric   SlotMapping IRSlots;
57e6d15924SDimitry Andric   std::unique_ptr<PerTargetMIParsingState> Target;
58e6d15924SDimitry Andric 
597ab83427SDimitry Andric   /// True when the MIR file doesn't have LLVM IR. Dummy IR functions are
607ab83427SDimitry Andric   /// created and inserted into the given module when this is true.
617ab83427SDimitry Andric   bool NoLLVMIR = false;
627ab83427SDimitry Andric   /// True when a well formed MIR file does not contain any MIR/machine function
637ab83427SDimitry Andric   /// parts.
647ab83427SDimitry Andric   bool NoMIRDocuments = false;
6585d8b2bbSDimitry Andric 
66706b4fc4SDimitry Andric   std::function<void(Function &)> ProcessIRFunction;
67706b4fc4SDimitry Andric 
6885d8b2bbSDimitry Andric public:
69706b4fc4SDimitry Andric   MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
70706b4fc4SDimitry Andric                 LLVMContext &Context,
71706b4fc4SDimitry Andric                 std::function<void(Function &)> ProcessIRFunction);
7285d8b2bbSDimitry Andric 
733a0822f0SDimitry Andric   void reportDiagnostic(const SMDiagnostic &Diag);
743a0822f0SDimitry Andric 
753a0822f0SDimitry Andric   /// Report an error with the given message at unknown location.
763a0822f0SDimitry Andric   ///
773a0822f0SDimitry Andric   /// Always returns true.
783a0822f0SDimitry Andric   bool error(const Twine &Message);
793a0822f0SDimitry Andric 
80ee8648bdSDimitry Andric   /// Report an error with the given message at the given location.
81ee8648bdSDimitry Andric   ///
82ee8648bdSDimitry Andric   /// Always returns true.
83ee8648bdSDimitry Andric   bool error(SMLoc Loc, const Twine &Message);
84ee8648bdSDimitry Andric 
851a82d4c0SDimitry Andric   /// Report a given error with the location translated from the location in an
861a82d4c0SDimitry Andric   /// embedded string literal to a location in the MIR file.
871a82d4c0SDimitry Andric   ///
881a82d4c0SDimitry Andric   /// Always returns true.
891a82d4c0SDimitry Andric   bool error(const SMDiagnostic &Error, SMRange SourceRange);
901a82d4c0SDimitry Andric 
9185d8b2bbSDimitry Andric   /// Try to parse the optional LLVM module and the machine functions in the MIR
9285d8b2bbSDimitry Andric   /// file.
9385d8b2bbSDimitry Andric   ///
9485d8b2bbSDimitry Andric   /// Return null if an error occurred.
95cfca06d7SDimitry Andric   std::unique_ptr<Module>
96cfca06d7SDimitry Andric   parseIRModule(DataLayoutCallbackTy DataLayoutCallback);
977ab83427SDimitry Andric 
98706b4fc4SDimitry Andric   /// Create an empty function with the given name.
99706b4fc4SDimitry Andric   Function *createDummyFunction(StringRef Name, Module &M);
100706b4fc4SDimitry Andric 
101ac9a064cSDimitry Andric   bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI,
102ac9a064cSDimitry Andric                              ModuleAnalysisManager *FAM = nullptr);
10385d8b2bbSDimitry Andric 
10485d8b2bbSDimitry Andric   /// Parse the machine function in the current YAML document.
10585d8b2bbSDimitry Andric   ///
1063a0822f0SDimitry Andric   ///
10785d8b2bbSDimitry Andric   /// Return true if an error occurred.
108ac9a064cSDimitry Andric   bool parseMachineFunction(Module &M, MachineModuleInfo &MMI,
109ac9a064cSDimitry Andric                             ModuleAnalysisManager *FAM);
1103a0822f0SDimitry Andric 
1113a0822f0SDimitry Andric   /// Initialize the machine function to the state that's described in the MIR
1123a0822f0SDimitry Andric   /// file.
1133a0822f0SDimitry Andric   ///
1143a0822f0SDimitry Andric   /// Return true if error occurred.
1157ab83427SDimitry Andric   bool initializeMachineFunction(const yaml::MachineFunction &YamlMF,
1167ab83427SDimitry Andric                                  MachineFunction &MF);
1173a0822f0SDimitry Andric 
118b915e9e0SDimitry Andric   bool parseRegisterInfo(PerFunctionMIParsingState &PFS,
1191a82d4c0SDimitry Andric                          const yaml::MachineFunction &YamlMF);
12085d8b2bbSDimitry Andric 
121b915e9e0SDimitry Andric   bool setupRegisterInfo(const PerFunctionMIParsingState &PFS,
12201095a5dSDimitry Andric                          const yaml::MachineFunction &YamlMF);
123dd58ef01SDimitry Andric 
12401095a5dSDimitry Andric   bool initializeFrameInfo(PerFunctionMIParsingState &PFS,
12501095a5dSDimitry Andric                            const yaml::MachineFunction &YamlMF);
12601095a5dSDimitry Andric 
127e6d15924SDimitry Andric   bool initializeCallSiteInfo(PerFunctionMIParsingState &PFS,
128e6d15924SDimitry Andric                               const yaml::MachineFunction &YamlMF);
129e6d15924SDimitry Andric 
13001095a5dSDimitry Andric   bool parseCalleeSavedRegister(PerFunctionMIParsingState &PFS,
131dd58ef01SDimitry Andric                                 std::vector<CalleeSavedInfo> &CSIInfo,
132dd58ef01SDimitry Andric                                 const yaml::StringValue &RegisterSource,
133044eb2f6SDimitry Andric                                 bool IsRestored, int FrameIdx);
134dd58ef01SDimitry Andric 
1357fa27ce4SDimitry Andric   struct VarExprLoc {
1367fa27ce4SDimitry Andric     DILocalVariable *DIVar = nullptr;
1377fa27ce4SDimitry Andric     DIExpression *DIExpr = nullptr;
1387fa27ce4SDimitry Andric     DILocation *DILoc = nullptr;
1397fa27ce4SDimitry Andric   };
1407fa27ce4SDimitry Andric 
1417fa27ce4SDimitry Andric   std::optional<VarExprLoc> parseVarExprLoc(PerFunctionMIParsingState &PFS,
1427fa27ce4SDimitry Andric                                             const yaml::StringValue &VarStr,
1437fa27ce4SDimitry Andric                                             const yaml::StringValue &ExprStr,
1447fa27ce4SDimitry Andric                                             const yaml::StringValue &LocStr);
145eb11fae6SDimitry Andric   template <typename T>
14601095a5dSDimitry Andric   bool parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS,
147eb11fae6SDimitry Andric                                   const T &Object,
148dd58ef01SDimitry Andric                                   int FrameIdx);
149dd58ef01SDimitry Andric 
15001095a5dSDimitry Andric   bool initializeConstantPool(PerFunctionMIParsingState &PFS,
15101095a5dSDimitry Andric                               MachineConstantPool &ConstantPool,
15201095a5dSDimitry Andric                               const yaml::MachineFunction &YamlMF);
153dd58ef01SDimitry Andric 
15401095a5dSDimitry Andric   bool initializeJumpTableInfo(PerFunctionMIParsingState &PFS,
15501095a5dSDimitry Andric                                const yaml::MachineJumpTable &YamlJTI);
156dd58ef01SDimitry Andric 
157344a3780SDimitry Andric   bool parseMachineMetadataNodes(PerFunctionMIParsingState &PFS,
158344a3780SDimitry Andric                                  MachineFunction &MF,
159344a3780SDimitry Andric                                  const yaml::MachineFunction &YMF);
160344a3780SDimitry Andric 
16185d8b2bbSDimitry Andric private:
162b915e9e0SDimitry Andric   bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node,
16301095a5dSDimitry Andric                    const yaml::StringValue &Source);
164dd58ef01SDimitry Andric 
165b915e9e0SDimitry Andric   bool parseMBBReference(PerFunctionMIParsingState &PFS,
16601095a5dSDimitry Andric                          MachineBasicBlock *&MBB,
16701095a5dSDimitry Andric                          const yaml::StringValue &Source);
168dd58ef01SDimitry Andric 
169344a3780SDimitry Andric   bool parseMachineMetadata(PerFunctionMIParsingState &PFS,
170344a3780SDimitry Andric                             const yaml::StringValue &Source);
171344a3780SDimitry Andric 
1721a82d4c0SDimitry Andric   /// Return a MIR diagnostic converted from an MI string diagnostic.
1731a82d4c0SDimitry Andric   SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
1741a82d4c0SDimitry Andric                                     SMRange SourceRange);
1751a82d4c0SDimitry Andric 
176dd58ef01SDimitry Andric   /// Return a MIR diagnostic converted from a diagnostic located in a YAML
177dd58ef01SDimitry Andric   /// block scalar string.
178dd58ef01SDimitry Andric   SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error,
17985d8b2bbSDimitry Andric                                        SMRange SourceRange);
1803a0822f0SDimitry Andric 
181b915e9e0SDimitry Andric   void computeFunctionProperties(MachineFunction &MF);
182b60736ecSDimitry Andric 
183b60736ecSDimitry Andric   void setupDebugValueTracking(MachineFunction &MF,
184b60736ecSDimitry Andric     PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF);
18585d8b2bbSDimitry Andric };
18685d8b2bbSDimitry Andric 
1873a0822f0SDimitry Andric } // end namespace llvm
18885d8b2bbSDimitry Andric 
handleYAMLDiag(const SMDiagnostic & Diag,void * Context)1897ab83427SDimitry Andric static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
1907ab83427SDimitry Andric   reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
1917ab83427SDimitry Andric }
1927ab83427SDimitry Andric 
MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,StringRef Filename,LLVMContext & Context,std::function<void (Function &)> Callback)19385d8b2bbSDimitry Andric MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
194706b4fc4SDimitry Andric                              StringRef Filename, LLVMContext &Context,
195706b4fc4SDimitry Andric                              std::function<void(Function &)> Callback)
1966f8fc217SDimitry Andric     : Context(Context),
197706b4fc4SDimitry Andric       In(SM.getMemoryBuffer(SM.AddNewSourceBuffer(std::move(Contents), SMLoc()))
198706b4fc4SDimitry Andric              ->getBuffer(),
1997ab83427SDimitry Andric          nullptr, handleYAMLDiag, this),
200344a3780SDimitry Andric       Filename(Filename), ProcessIRFunction(Callback) {
2017ab83427SDimitry Andric   In.setContext(&In);
20285d8b2bbSDimitry Andric }
20385d8b2bbSDimitry Andric 
error(const Twine & Message)2043a0822f0SDimitry Andric bool MIRParserImpl::error(const Twine &Message) {
2053a0822f0SDimitry Andric   Context.diagnose(DiagnosticInfoMIRParser(
2063a0822f0SDimitry Andric       DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));
2073a0822f0SDimitry Andric   return true;
20885d8b2bbSDimitry Andric }
20985d8b2bbSDimitry Andric 
error(SMLoc Loc,const Twine & Message)210ee8648bdSDimitry Andric bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) {
211ee8648bdSDimitry Andric   Context.diagnose(DiagnosticInfoMIRParser(
212ee8648bdSDimitry Andric       DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message)));
213ee8648bdSDimitry Andric   return true;
214ee8648bdSDimitry Andric }
215ee8648bdSDimitry Andric 
error(const SMDiagnostic & Error,SMRange SourceRange)2161a82d4c0SDimitry Andric bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) {
2171a82d4c0SDimitry Andric   assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");
2181a82d4c0SDimitry Andric   reportDiagnostic(diagFromMIStringDiag(Error, SourceRange));
2191a82d4c0SDimitry Andric   return true;
2201a82d4c0SDimitry Andric }
2211a82d4c0SDimitry Andric 
reportDiagnostic(const SMDiagnostic & Diag)2223a0822f0SDimitry Andric void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
2233a0822f0SDimitry Andric   DiagnosticSeverity Kind;
2243a0822f0SDimitry Andric   switch (Diag.getKind()) {
2253a0822f0SDimitry Andric   case SourceMgr::DK_Error:
2263a0822f0SDimitry Andric     Kind = DS_Error;
2273a0822f0SDimitry Andric     break;
2283a0822f0SDimitry Andric   case SourceMgr::DK_Warning:
2293a0822f0SDimitry Andric     Kind = DS_Warning;
2303a0822f0SDimitry Andric     break;
2313a0822f0SDimitry Andric   case SourceMgr::DK_Note:
2323a0822f0SDimitry Andric     Kind = DS_Note;
2333a0822f0SDimitry Andric     break;
234044eb2f6SDimitry Andric   case SourceMgr::DK_Remark:
235044eb2f6SDimitry Andric     llvm_unreachable("remark unexpected");
236044eb2f6SDimitry Andric     break;
2373a0822f0SDimitry Andric   }
2383a0822f0SDimitry Andric   Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
2393a0822f0SDimitry Andric }
2403a0822f0SDimitry Andric 
241cfca06d7SDimitry Andric std::unique_ptr<Module>
parseIRModule(DataLayoutCallbackTy DataLayoutCallback)242cfca06d7SDimitry Andric MIRParserImpl::parseIRModule(DataLayoutCallbackTy DataLayoutCallback) {
24385d8b2bbSDimitry Andric   if (!In.setCurrentDocument()) {
2443a0822f0SDimitry Andric     if (In.error())
24585d8b2bbSDimitry Andric       return nullptr;
24685d8b2bbSDimitry Andric     // Create an empty module when the MIR file is empty.
2477ab83427SDimitry Andric     NoMIRDocuments = true;
248cfca06d7SDimitry Andric     auto M = std::make_unique<Module>(Filename, Context);
249e3b55780SDimitry Andric     if (auto LayoutOverride =
250e3b55780SDimitry Andric             DataLayoutCallback(M->getTargetTriple(), M->getDataLayoutStr()))
251cfca06d7SDimitry Andric       M->setDataLayout(*LayoutOverride);
252cfca06d7SDimitry Andric     return M;
25385d8b2bbSDimitry Andric   }
25485d8b2bbSDimitry Andric 
25585d8b2bbSDimitry Andric   std::unique_ptr<Module> M;
25685d8b2bbSDimitry Andric   // Parse the block scalar manually so that we can return unique pointer
25785d8b2bbSDimitry Andric   // without having to go trough YAML traits.
25885d8b2bbSDimitry Andric   if (const auto *BSN =
25985d8b2bbSDimitry Andric           dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
2603a0822f0SDimitry Andric     SMDiagnostic Error;
26185d8b2bbSDimitry Andric     M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
262cfca06d7SDimitry Andric                       Context, &IRSlots, DataLayoutCallback);
26385d8b2bbSDimitry Andric     if (!M) {
264dd58ef01SDimitry Andric       reportDiagnostic(diagFromBlockStringDiag(Error, BSN->getSourceRange()));
26501095a5dSDimitry Andric       return nullptr;
26685d8b2bbSDimitry Andric     }
26785d8b2bbSDimitry Andric     In.nextDocument();
26885d8b2bbSDimitry Andric     if (!In.setCurrentDocument())
2697ab83427SDimitry Andric       NoMIRDocuments = true;
27085d8b2bbSDimitry Andric   } else {
27185d8b2bbSDimitry Andric     // Create an new, empty module.
2721d5ae102SDimitry Andric     M = std::make_unique<Module>(Filename, Context);
273e3b55780SDimitry Andric     if (auto LayoutOverride =
274e3b55780SDimitry Andric             DataLayoutCallback(M->getTargetTriple(), M->getDataLayoutStr()))
275cfca06d7SDimitry Andric       M->setDataLayout(*LayoutOverride);
2763a0822f0SDimitry Andric     NoLLVMIR = true;
27785d8b2bbSDimitry Andric   }
27885d8b2bbSDimitry Andric   return M;
27985d8b2bbSDimitry Andric }
28085d8b2bbSDimitry Andric 
parseMachineFunctions(Module & M,MachineModuleInfo & MMI,ModuleAnalysisManager * MAM)281ac9a064cSDimitry Andric bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI,
282ac9a064cSDimitry Andric                                           ModuleAnalysisManager *MAM) {
2837ab83427SDimitry Andric   if (NoMIRDocuments)
2847ab83427SDimitry Andric     return false;
2857ab83427SDimitry Andric 
2867ab83427SDimitry Andric   // Parse the machine functions.
2877ab83427SDimitry Andric   do {
288ac9a064cSDimitry Andric     if (parseMachineFunction(M, MMI, MAM))
28985d8b2bbSDimitry Andric       return true;
2907ab83427SDimitry Andric     In.nextDocument();
2917ab83427SDimitry Andric   } while (In.setCurrentDocument());
2927ab83427SDimitry Andric 
2933a0822f0SDimitry Andric   return false;
2943a0822f0SDimitry Andric }
2953a0822f0SDimitry Andric 
createDummyFunction(StringRef Name,Module & M)296706b4fc4SDimitry Andric Function *MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
2973a0822f0SDimitry Andric   auto &Context = M.getContext();
298e6d15924SDimitry Andric   Function *F =
299e6d15924SDimitry Andric       Function::Create(FunctionType::get(Type::getVoidTy(Context), false),
300e6d15924SDimitry Andric                        Function::ExternalLinkage, Name, M);
3013a0822f0SDimitry Andric   BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
3023a0822f0SDimitry Andric   new UnreachableInst(Context, BB);
303706b4fc4SDimitry Andric 
304706b4fc4SDimitry Andric   if (ProcessIRFunction)
305706b4fc4SDimitry Andric     ProcessIRFunction(*F);
306706b4fc4SDimitry Andric 
3077ab83427SDimitry Andric   return F;
3087ab83427SDimitry Andric }
3097ab83427SDimitry Andric 
parseMachineFunction(Module & M,MachineModuleInfo & MMI,ModuleAnalysisManager * MAM)310ac9a064cSDimitry Andric bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI,
311ac9a064cSDimitry Andric                                          ModuleAnalysisManager *MAM) {
3127ab83427SDimitry Andric   // Parse the yaml.
3137ab83427SDimitry Andric   yaml::MachineFunction YamlMF;
3147ab83427SDimitry Andric   yaml::EmptyContext Ctx;
315e6d15924SDimitry Andric 
316e6d15924SDimitry Andric   const LLVMTargetMachine &TM = MMI.getTarget();
317e6d15924SDimitry Andric   YamlMF.MachineFuncInfo = std::unique_ptr<yaml::MachineFunctionInfo>(
318e6d15924SDimitry Andric       TM.createDefaultFuncInfoYAML());
319e6d15924SDimitry Andric 
3207ab83427SDimitry Andric   yaml::yamlize(In, YamlMF, false, Ctx);
3217ab83427SDimitry Andric   if (In.error())
3227ab83427SDimitry Andric     return true;
3237ab83427SDimitry Andric 
3247ab83427SDimitry Andric   // Search for the corresponding IR function.
3257ab83427SDimitry Andric   StringRef FunctionName = YamlMF.Name;
3267ab83427SDimitry Andric   Function *F = M.getFunction(FunctionName);
3277ab83427SDimitry Andric   if (!F) {
3287ab83427SDimitry Andric     if (NoLLVMIR) {
3297ab83427SDimitry Andric       F = createDummyFunction(FunctionName, M);
3307ab83427SDimitry Andric     } else {
3317ab83427SDimitry Andric       return error(Twine("function '") + FunctionName +
3327ab83427SDimitry Andric                    "' isn't defined in the provided LLVM IR");
3337ab83427SDimitry Andric     }
3347ab83427SDimitry Andric   }
335ac9a064cSDimitry Andric 
336ac9a064cSDimitry Andric   if (!MAM) {
3377ab83427SDimitry Andric     if (MMI.getMachineFunction(*F) != nullptr)
3387ab83427SDimitry Andric       return error(Twine("redefinition of machine function '") + FunctionName +
3397ab83427SDimitry Andric                    "'");
3407ab83427SDimitry Andric 
3417ab83427SDimitry Andric     // Create the MachineFunction.
3427ab83427SDimitry Andric     MachineFunction &MF = MMI.getOrCreateMachineFunction(*F);
3437ab83427SDimitry Andric     if (initializeMachineFunction(YamlMF, MF))
3447ab83427SDimitry Andric       return true;
345ac9a064cSDimitry Andric   } else {
346ac9a064cSDimitry Andric     auto &FAM =
347ac9a064cSDimitry Andric         MAM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
348ac9a064cSDimitry Andric     if (FAM.getCachedResult<MachineFunctionAnalysis>(*F))
349ac9a064cSDimitry Andric       return error(Twine("redefinition of machine function '") + FunctionName +
350ac9a064cSDimitry Andric                    "'");
351ac9a064cSDimitry Andric 
352ac9a064cSDimitry Andric     // Create the MachineFunction.
353ac9a064cSDimitry Andric     MachineFunction &MF = FAM.getResult<MachineFunctionAnalysis>(*F).getMF();
354ac9a064cSDimitry Andric     if (initializeMachineFunction(YamlMF, MF))
355ac9a064cSDimitry Andric       return true;
356ac9a064cSDimitry Andric   }
3577ab83427SDimitry Andric 
3587ab83427SDimitry Andric   return false;
3593a0822f0SDimitry Andric }
3603a0822f0SDimitry Andric 
isSSA(const MachineFunction & MF)361b915e9e0SDimitry Andric static bool isSSA(const MachineFunction &MF) {
362b915e9e0SDimitry Andric   const MachineRegisterInfo &MRI = MF.getRegInfo();
363b915e9e0SDimitry Andric   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
364b60736ecSDimitry Andric     Register Reg = Register::index2VirtReg(I);
365b915e9e0SDimitry Andric     if (!MRI.hasOneDef(Reg) && !MRI.def_empty(Reg))
366b915e9e0SDimitry Andric       return false;
367b60736ecSDimitry Andric 
368b60736ecSDimitry Andric     // Subregister defs are invalid in SSA.
369b60736ecSDimitry Andric     const MachineOperand *RegDef = MRI.getOneDef(Reg);
370b60736ecSDimitry Andric     if (RegDef && RegDef->getSubReg() != 0)
371b60736ecSDimitry Andric       return false;
372b915e9e0SDimitry Andric   }
373b915e9e0SDimitry Andric   return true;
374b915e9e0SDimitry Andric }
375b915e9e0SDimitry Andric 
computeFunctionProperties(MachineFunction & MF)376b915e9e0SDimitry Andric void MIRParserImpl::computeFunctionProperties(MachineFunction &MF) {
377b915e9e0SDimitry Andric   MachineFunctionProperties &Properties = MF.getProperties();
378b915e9e0SDimitry Andric 
379b915e9e0SDimitry Andric   bool HasPHI = false;
380b915e9e0SDimitry Andric   bool HasInlineAsm = false;
38177fc4c14SDimitry Andric   bool AllTiedOpsRewritten = true, HasTiedOps = false;
382b915e9e0SDimitry Andric   for (const MachineBasicBlock &MBB : MF) {
383b915e9e0SDimitry Andric     for (const MachineInstr &MI : MBB) {
384b915e9e0SDimitry Andric       if (MI.isPHI())
385b915e9e0SDimitry Andric         HasPHI = true;
386b915e9e0SDimitry Andric       if (MI.isInlineAsm())
387b915e9e0SDimitry Andric         HasInlineAsm = true;
38877fc4c14SDimitry Andric       for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
38977fc4c14SDimitry Andric         const MachineOperand &MO = MI.getOperand(I);
39077fc4c14SDimitry Andric         if (!MO.isReg() || !MO.getReg())
39177fc4c14SDimitry Andric           continue;
39277fc4c14SDimitry Andric         unsigned DefIdx;
39377fc4c14SDimitry Andric         if (MO.isUse() && MI.isRegTiedToDefOperand(I, &DefIdx)) {
39477fc4c14SDimitry Andric           HasTiedOps = true;
39577fc4c14SDimitry Andric           if (MO.getReg() != MI.getOperand(DefIdx).getReg())
39677fc4c14SDimitry Andric             AllTiedOpsRewritten = false;
39777fc4c14SDimitry Andric         }
39877fc4c14SDimitry Andric       }
399b915e9e0SDimitry Andric     }
400b915e9e0SDimitry Andric   }
401b915e9e0SDimitry Andric   if (!HasPHI)
402b915e9e0SDimitry Andric     Properties.set(MachineFunctionProperties::Property::NoPHIs);
403b915e9e0SDimitry Andric   MF.setHasInlineAsm(HasInlineAsm);
404b915e9e0SDimitry Andric 
40577fc4c14SDimitry Andric   if (HasTiedOps && AllTiedOpsRewritten)
40677fc4c14SDimitry Andric     Properties.set(MachineFunctionProperties::Property::TiedOpsRewritten);
40777fc4c14SDimitry Andric 
408b915e9e0SDimitry Andric   if (isSSA(MF))
409b915e9e0SDimitry Andric     Properties.set(MachineFunctionProperties::Property::IsSSA);
410b915e9e0SDimitry Andric   else
411b915e9e0SDimitry Andric     Properties.reset(MachineFunctionProperties::Property::IsSSA);
412b915e9e0SDimitry Andric 
413b915e9e0SDimitry Andric   const MachineRegisterInfo &MRI = MF.getRegInfo();
414b915e9e0SDimitry Andric   if (MRI.getNumVirtRegs() == 0)
415b915e9e0SDimitry Andric     Properties.set(MachineFunctionProperties::Property::NoVRegs);
416b915e9e0SDimitry Andric }
417b915e9e0SDimitry Andric 
initializeCallSiteInfo(PerFunctionMIParsingState & PFS,const yaml::MachineFunction & YamlMF)418e6d15924SDimitry Andric bool MIRParserImpl::initializeCallSiteInfo(
419e6d15924SDimitry Andric     PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF) {
420e6d15924SDimitry Andric   MachineFunction &MF = PFS.MF;
421e6d15924SDimitry Andric   SMDiagnostic Error;
422e6d15924SDimitry Andric   const LLVMTargetMachine &TM = MF.getTarget();
4237fa27ce4SDimitry Andric   for (auto &YamlCSInfo : YamlMF.CallSitesInfo) {
424e6d15924SDimitry Andric     yaml::CallSiteInfo::MachineInstrLoc MILoc = YamlCSInfo.CallLocation;
425e6d15924SDimitry Andric     if (MILoc.BlockNum >= MF.size())
426e6d15924SDimitry Andric       return error(Twine(MF.getName()) +
427e6d15924SDimitry Andric                    Twine(" call instruction block out of range.") +
428e6d15924SDimitry Andric                    " Unable to reference bb:" + Twine(MILoc.BlockNum));
429e6d15924SDimitry Andric     auto CallB = std::next(MF.begin(), MILoc.BlockNum);
430e6d15924SDimitry Andric     if (MILoc.Offset >= CallB->size())
431e6d15924SDimitry Andric       return error(Twine(MF.getName()) +
432e6d15924SDimitry Andric                    Twine(" call instruction offset out of range.") +
433e6d15924SDimitry Andric                    " Unable to reference instruction at bb: " +
434e6d15924SDimitry Andric                    Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset));
4351d5ae102SDimitry Andric     auto CallI = std::next(CallB->instr_begin(), MILoc.Offset);
4361d5ae102SDimitry Andric     if (!CallI->isCall(MachineInstr::IgnoreBundle))
437e6d15924SDimitry Andric       return error(Twine(MF.getName()) +
438e6d15924SDimitry Andric                    Twine(" call site info should reference call "
439e6d15924SDimitry Andric                          "instruction. Instruction at bb:") +
440e6d15924SDimitry Andric                    Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset) +
441e6d15924SDimitry Andric                    " is not a call instruction");
442e6d15924SDimitry Andric     MachineFunction::CallSiteInfo CSInfo;
443e6d15924SDimitry Andric     for (auto ArgRegPair : YamlCSInfo.ArgForwardingRegs) {
444cfca06d7SDimitry Andric       Register Reg;
445e6d15924SDimitry Andric       if (parseNamedRegisterReference(PFS, Reg, ArgRegPair.Reg.Value, Error))
446e6d15924SDimitry Andric         return error(Error, ArgRegPair.Reg.SourceRange);
447ac9a064cSDimitry Andric       CSInfo.ArgRegPairs.emplace_back(Reg, ArgRegPair.ArgNo);
448e6d15924SDimitry Andric     }
449e6d15924SDimitry Andric 
450cfca06d7SDimitry Andric     if (TM.Options.EmitCallSiteInfo)
451ac9a064cSDimitry Andric       MF.addCallSiteInfo(&*CallI, std::move(CSInfo));
452e6d15924SDimitry Andric   }
453e6d15924SDimitry Andric 
454cfca06d7SDimitry Andric   if (YamlMF.CallSitesInfo.size() && !TM.Options.EmitCallSiteInfo)
455e6d15924SDimitry Andric     return error(Twine("Call site info provided but not used"));
456e6d15924SDimitry Andric   return false;
457e6d15924SDimitry Andric }
458e6d15924SDimitry Andric 
setupDebugValueTracking(MachineFunction & MF,PerFunctionMIParsingState & PFS,const yaml::MachineFunction & YamlMF)459b60736ecSDimitry Andric void MIRParserImpl::setupDebugValueTracking(
460b60736ecSDimitry Andric     MachineFunction &MF, PerFunctionMIParsingState &PFS,
461b60736ecSDimitry Andric     const yaml::MachineFunction &YamlMF) {
462b60736ecSDimitry Andric   // Compute the value of the "next instruction number" field.
463b60736ecSDimitry Andric   unsigned MaxInstrNum = 0;
464b60736ecSDimitry Andric   for (auto &MBB : MF)
465b60736ecSDimitry Andric     for (auto &MI : MBB)
466b60736ecSDimitry Andric       MaxInstrNum = std::max((unsigned)MI.peekDebugInstrNum(), MaxInstrNum);
467b60736ecSDimitry Andric   MF.setDebugInstrNumberingCount(MaxInstrNum);
468b60736ecSDimitry Andric 
469b60736ecSDimitry Andric   // Load any substitutions.
4704b4fe385SDimitry Andric   for (const auto &Sub : YamlMF.DebugValueSubstitutions) {
471344a3780SDimitry Andric     MF.makeDebugValueSubstitution({Sub.SrcInst, Sub.SrcOp},
472344a3780SDimitry Andric                                   {Sub.DstInst, Sub.DstOp}, Sub.Subreg);
473b60736ecSDimitry Andric   }
474e3b55780SDimitry Andric 
475e3b55780SDimitry Andric   // Flag for whether we're supposed to be using DBG_INSTR_REF.
476e3b55780SDimitry Andric   MF.setUseDebugInstrRef(YamlMF.UseDebugInstrRef);
477b60736ecSDimitry Andric }
478b60736ecSDimitry Andric 
4797ab83427SDimitry Andric bool
initializeMachineFunction(const yaml::MachineFunction & YamlMF,MachineFunction & MF)4807ab83427SDimitry Andric MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
4817ab83427SDimitry Andric                                          MachineFunction &MF) {
4823a0822f0SDimitry Andric   // TODO: Recreate the machine function.
483e6d15924SDimitry Andric   if (Target) {
484e6d15924SDimitry Andric     // Avoid clearing state if we're using the same subtarget again.
485e6d15924SDimitry Andric     Target->setTarget(MF.getSubtarget());
486e6d15924SDimitry Andric   } else {
487e6d15924SDimitry Andric     Target.reset(new PerTargetMIParsingState(MF.getSubtarget()));
488e6d15924SDimitry Andric   }
489e6d15924SDimitry Andric 
490cfca06d7SDimitry Andric   MF.setAlignment(YamlMF.Alignment.valueOrOne());
4913a0822f0SDimitry Andric   MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
492d8e91e46SDimitry Andric   MF.setHasWinCFI(YamlMF.HasWinCFI);
493b915e9e0SDimitry Andric 
494145449b1SDimitry Andric   MF.setCallsEHReturn(YamlMF.CallsEHReturn);
495145449b1SDimitry Andric   MF.setCallsUnwindInit(YamlMF.CallsUnwindInit);
496145449b1SDimitry Andric   MF.setHasEHCatchret(YamlMF.HasEHCatchret);
497145449b1SDimitry Andric   MF.setHasEHScopes(YamlMF.HasEHScopes);
498145449b1SDimitry Andric   MF.setHasEHFunclets(YamlMF.HasEHFunclets);
4997fa27ce4SDimitry Andric   MF.setIsOutlined(YamlMF.IsOutlined);
500145449b1SDimitry Andric 
501b915e9e0SDimitry Andric   if (YamlMF.Legalized)
502b915e9e0SDimitry Andric     MF.getProperties().set(MachineFunctionProperties::Property::Legalized);
503b915e9e0SDimitry Andric   if (YamlMF.RegBankSelected)
504b915e9e0SDimitry Andric     MF.getProperties().set(
505b915e9e0SDimitry Andric         MachineFunctionProperties::Property::RegBankSelected);
506b915e9e0SDimitry Andric   if (YamlMF.Selected)
507b915e9e0SDimitry Andric     MF.getProperties().set(MachineFunctionProperties::Property::Selected);
508eb11fae6SDimitry Andric   if (YamlMF.FailedISel)
509eb11fae6SDimitry Andric     MF.getProperties().set(MachineFunctionProperties::Property::FailedISel);
510c0981da4SDimitry Andric   if (YamlMF.FailsVerification)
511c0981da4SDimitry Andric     MF.getProperties().set(
512c0981da4SDimitry Andric         MachineFunctionProperties::Property::FailsVerification);
51377fc4c14SDimitry Andric   if (YamlMF.TracksDebugUserValues)
51477fc4c14SDimitry Andric     MF.getProperties().set(
51577fc4c14SDimitry Andric         MachineFunctionProperties::Property::TracksDebugUserValues);
516b915e9e0SDimitry Andric 
517e6d15924SDimitry Andric   PerFunctionMIParsingState PFS(MF, SM, IRSlots, *Target);
518b915e9e0SDimitry Andric   if (parseRegisterInfo(PFS, YamlMF))
519ee8648bdSDimitry Andric     return true;
520dd58ef01SDimitry Andric   if (!YamlMF.Constants.empty()) {
521dd58ef01SDimitry Andric     auto *ConstantPool = MF.getConstantPool();
522dd58ef01SDimitry Andric     assert(ConstantPool && "Constant pool must be created");
52301095a5dSDimitry Andric     if (initializeConstantPool(PFS, *ConstantPool, YamlMF))
5241a82d4c0SDimitry Andric       return true;
5251a82d4c0SDimitry Andric   }
526344a3780SDimitry Andric   if (!YamlMF.MachineMetadataNodes.empty() &&
527344a3780SDimitry Andric       parseMachineMetadataNodes(PFS, MF, YamlMF))
528344a3780SDimitry Andric     return true;
5291a82d4c0SDimitry Andric 
53001095a5dSDimitry Andric   StringRef BlockStr = YamlMF.Body.Value.Value;
531dd58ef01SDimitry Andric   SMDiagnostic Error;
53201095a5dSDimitry Andric   SourceMgr BlockSM;
53301095a5dSDimitry Andric   BlockSM.AddNewSourceBuffer(
53401095a5dSDimitry Andric       MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false),
53501095a5dSDimitry Andric       SMLoc());
53601095a5dSDimitry Andric   PFS.SM = &BlockSM;
53701095a5dSDimitry Andric   if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)) {
538dd58ef01SDimitry Andric     reportDiagnostic(
539dd58ef01SDimitry Andric         diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
540dd58ef01SDimitry Andric     return true;
541dd58ef01SDimitry Andric   }
542cfca06d7SDimitry Andric   // Check Basic Block Section Flags.
543cfca06d7SDimitry Andric   if (MF.getTarget().getBBSectionsType() == BasicBlockSection::Labels) {
544cfca06d7SDimitry Andric     MF.setBBSectionsType(BasicBlockSection::Labels);
545cfca06d7SDimitry Andric   } else if (MF.hasBBSections()) {
546cfca06d7SDimitry Andric     MF.assignBeginEndSections();
547cfca06d7SDimitry Andric   }
54801095a5dSDimitry Andric   PFS.SM = &SM;
549dd58ef01SDimitry Andric 
550dd58ef01SDimitry Andric   // Initialize the frame information after creating all the MBBs so that the
551dd58ef01SDimitry Andric   // MBB references in the frame information can be resolved.
55201095a5dSDimitry Andric   if (initializeFrameInfo(PFS, YamlMF))
553dd58ef01SDimitry Andric     return true;
554dd58ef01SDimitry Andric   // Initialize the jump table after creating all the MBBs so that the MBB
555dd58ef01SDimitry Andric   // references can be resolved.
556dd58ef01SDimitry Andric   if (!YamlMF.JumpTableInfo.Entries.empty() &&
55701095a5dSDimitry Andric       initializeJumpTableInfo(PFS, YamlMF.JumpTableInfo))
558dd58ef01SDimitry Andric     return true;
559dd58ef01SDimitry Andric   // Parse the machine instructions after creating all of the MBBs so that the
560dd58ef01SDimitry Andric   // parser can resolve the MBB references.
56101095a5dSDimitry Andric   StringRef InsnStr = YamlMF.Body.Value.Value;
56201095a5dSDimitry Andric   SourceMgr InsnSM;
56301095a5dSDimitry Andric   InsnSM.AddNewSourceBuffer(
56401095a5dSDimitry Andric       MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false),
56501095a5dSDimitry Andric       SMLoc());
56601095a5dSDimitry Andric   PFS.SM = &InsnSM;
56701095a5dSDimitry Andric   if (parseMachineInstructions(PFS, InsnStr, Error)) {
568dd58ef01SDimitry Andric     reportDiagnostic(
569dd58ef01SDimitry Andric         diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
5703a0822f0SDimitry Andric     return true;
5713a0822f0SDimitry Andric   }
57201095a5dSDimitry Andric   PFS.SM = &SM;
57301095a5dSDimitry Andric 
574b915e9e0SDimitry Andric   if (setupRegisterInfo(PFS, YamlMF))
575b915e9e0SDimitry Andric     return true;
576b915e9e0SDimitry Andric 
577e6d15924SDimitry Andric   if (YamlMF.MachineFuncInfo) {
578e6d15924SDimitry Andric     const LLVMTargetMachine &TM = MF.getTarget();
579e6d15924SDimitry Andric     // Note this is called after the initial constructor of the
580e6d15924SDimitry Andric     // MachineFunctionInfo based on the MachineFunction, which may depend on the
581e6d15924SDimitry Andric     // IR.
582e6d15924SDimitry Andric 
583e6d15924SDimitry Andric     SMRange SrcRange;
584e6d15924SDimitry Andric     if (TM.parseMachineFunctionInfo(*YamlMF.MachineFuncInfo, PFS, Error,
585e6d15924SDimitry Andric                                     SrcRange)) {
586e6d15924SDimitry Andric       return error(Error, SrcRange);
587e6d15924SDimitry Andric     }
588e6d15924SDimitry Andric   }
589e6d15924SDimitry Andric 
590e6d15924SDimitry Andric   // Set the reserved registers after parsing MachineFuncInfo. The target may
591e6d15924SDimitry Andric   // have been recording information used to select the reserved registers
592e6d15924SDimitry Andric   // there.
593e6d15924SDimitry Andric   // FIXME: This is a temporary workaround until the reserved registers can be
594e6d15924SDimitry Andric   // serialized.
595e6d15924SDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
596ac9a064cSDimitry Andric   MRI.freezeReservedRegs();
597e6d15924SDimitry Andric 
598b915e9e0SDimitry Andric   computeFunctionProperties(MF);
599b915e9e0SDimitry Andric 
600e6d15924SDimitry Andric   if (initializeCallSiteInfo(PFS, YamlMF))
601e6d15924SDimitry Andric     return false;
602e6d15924SDimitry Andric 
603b60736ecSDimitry Andric   setupDebugValueTracking(MF, PFS, YamlMF);
604b60736ecSDimitry Andric 
605eb11fae6SDimitry Andric   MF.getSubtarget().mirFileLoaded(MF);
606eb11fae6SDimitry Andric 
607dd58ef01SDimitry Andric   MF.verify();
6083a0822f0SDimitry Andric   return false;
6093a0822f0SDimitry Andric }
6103a0822f0SDimitry Andric 
parseRegisterInfo(PerFunctionMIParsingState & PFS,const yaml::MachineFunction & YamlMF)611b915e9e0SDimitry Andric bool MIRParserImpl::parseRegisterInfo(PerFunctionMIParsingState &PFS,
61201095a5dSDimitry Andric                                       const yaml::MachineFunction &YamlMF) {
61301095a5dSDimitry Andric   MachineFunction &MF = PFS.MF;
614dd58ef01SDimitry Andric   MachineRegisterInfo &RegInfo = MF.getRegInfo();
6151a82d4c0SDimitry Andric   assert(RegInfo.tracksLiveness());
6161a82d4c0SDimitry Andric   if (!YamlMF.TracksRegLiveness)
6171a82d4c0SDimitry Andric     RegInfo.invalidateLiveness();
618ee8648bdSDimitry Andric 
619dd58ef01SDimitry Andric   SMDiagnostic Error;
620ee8648bdSDimitry Andric   // Parse the virtual register information.
621ee8648bdSDimitry Andric   for (const auto &VReg : YamlMF.VirtualRegisters) {
622b915e9e0SDimitry Andric     VRegInfo &Info = PFS.getVRegInfo(VReg.ID.Value);
623b915e9e0SDimitry Andric     if (Info.Explicit)
624b915e9e0SDimitry Andric       return error(VReg.ID.SourceRange.Start,
625b915e9e0SDimitry Andric                    Twine("redefinition of virtual register '%") +
626b915e9e0SDimitry Andric                        Twine(VReg.ID.Value) + "'");
627b915e9e0SDimitry Andric     Info.Explicit = true;
628b915e9e0SDimitry Andric 
629ac9a064cSDimitry Andric     if (VReg.Class.Value == "_") {
630b915e9e0SDimitry Andric       Info.Kind = VRegInfo::GENERIC;
631044eb2f6SDimitry Andric       Info.D.RegBank = nullptr;
63201095a5dSDimitry Andric     } else {
633e6d15924SDimitry Andric       const auto *RC = Target->getRegClass(VReg.Class.Value);
63401095a5dSDimitry Andric       if (RC) {
635b915e9e0SDimitry Andric         Info.Kind = VRegInfo::NORMAL;
636b915e9e0SDimitry Andric         Info.D.RC = RC;
63701095a5dSDimitry Andric       } else {
638e6d15924SDimitry Andric         const RegisterBank *RegBank = Target->getRegBank(VReg.Class.Value);
63901095a5dSDimitry Andric         if (!RegBank)
64001095a5dSDimitry Andric           return error(
64101095a5dSDimitry Andric               VReg.Class.SourceRange.Start,
64201095a5dSDimitry Andric               Twine("use of undefined register class or register bank '") +
643ee8648bdSDimitry Andric                   VReg.Class.Value + "'");
644b915e9e0SDimitry Andric         Info.Kind = VRegInfo::REGBANK;
645b915e9e0SDimitry Andric         Info.D.RegBank = RegBank;
64601095a5dSDimitry Andric       }
64701095a5dSDimitry Andric     }
648b915e9e0SDimitry Andric 
649dd58ef01SDimitry Andric     if (!VReg.PreferredRegister.Value.empty()) {
650b915e9e0SDimitry Andric       if (Info.Kind != VRegInfo::NORMAL)
651b915e9e0SDimitry Andric         return error(VReg.Class.SourceRange.Start,
652b915e9e0SDimitry Andric               Twine("preferred register can only be set for normal vregs"));
653b915e9e0SDimitry Andric 
654b915e9e0SDimitry Andric       if (parseRegisterReference(PFS, Info.PreferredReg,
65501095a5dSDimitry Andric                                  VReg.PreferredRegister.Value, Error))
656dd58ef01SDimitry Andric         return error(Error, VReg.PreferredRegister.SourceRange);
657ee8648bdSDimitry Andric     }
658dd58ef01SDimitry Andric   }
659dd58ef01SDimitry Andric 
660dd58ef01SDimitry Andric   // Parse the liveins.
661dd58ef01SDimitry Andric   for (const auto &LiveIn : YamlMF.LiveIns) {
662cfca06d7SDimitry Andric     Register Reg;
66301095a5dSDimitry Andric     if (parseNamedRegisterReference(PFS, Reg, LiveIn.Register.Value, Error))
664dd58ef01SDimitry Andric       return error(Error, LiveIn.Register.SourceRange);
665cfca06d7SDimitry Andric     Register VReg;
666dd58ef01SDimitry Andric     if (!LiveIn.VirtualRegister.Value.empty()) {
667b915e9e0SDimitry Andric       VRegInfo *Info;
668b915e9e0SDimitry Andric       if (parseVirtualRegisterReference(PFS, Info, LiveIn.VirtualRegister.Value,
66901095a5dSDimitry Andric                                         Error))
670dd58ef01SDimitry Andric         return error(Error, LiveIn.VirtualRegister.SourceRange);
671b915e9e0SDimitry Andric       VReg = Info->VReg;
672dd58ef01SDimitry Andric     }
673dd58ef01SDimitry Andric     RegInfo.addLiveIn(Reg, VReg);
674dd58ef01SDimitry Andric   }
675dd58ef01SDimitry Andric 
67671d5a254SDimitry Andric   // Parse the callee saved registers (Registers that will
67771d5a254SDimitry Andric   // be saved for the caller).
67871d5a254SDimitry Andric   if (YamlMF.CalleeSavedRegisters) {
67971d5a254SDimitry Andric     SmallVector<MCPhysReg, 16> CalleeSavedRegisters;
680145449b1SDimitry Andric     for (const auto &RegSource : *YamlMF.CalleeSavedRegisters) {
681cfca06d7SDimitry Andric       Register Reg;
68201095a5dSDimitry Andric       if (parseNamedRegisterReference(PFS, Reg, RegSource.Value, Error))
683dd58ef01SDimitry Andric         return error(Error, RegSource.SourceRange);
68471d5a254SDimitry Andric       CalleeSavedRegisters.push_back(Reg);
685dd58ef01SDimitry Andric     }
68671d5a254SDimitry Andric     RegInfo.setCalleeSavedRegs(CalleeSavedRegisters);
68771d5a254SDimitry Andric   }
68871d5a254SDimitry Andric 
689ee8648bdSDimitry Andric   return false;
690ee8648bdSDimitry Andric }
691ee8648bdSDimitry Andric 
setupRegisterInfo(const PerFunctionMIParsingState & PFS,const yaml::MachineFunction & YamlMF)692b915e9e0SDimitry Andric bool MIRParserImpl::setupRegisterInfo(const PerFunctionMIParsingState &PFS,
693ee8648bdSDimitry Andric                                       const yaml::MachineFunction &YamlMF) {
694b915e9e0SDimitry Andric   MachineFunction &MF = PFS.MF;
695b915e9e0SDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
696e3b55780SDimitry Andric   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
697e3b55780SDimitry Andric 
698b915e9e0SDimitry Andric   bool Error = false;
699b915e9e0SDimitry Andric   // Create VRegs
700eb11fae6SDimitry Andric   auto populateVRegInfo = [&](const VRegInfo &Info, Twine Name) {
701cfca06d7SDimitry Andric     Register Reg = Info.VReg;
702b915e9e0SDimitry Andric     switch (Info.Kind) {
703b915e9e0SDimitry Andric     case VRegInfo::UNKNOWN:
704b915e9e0SDimitry Andric       error(Twine("Cannot determine class/bank of virtual register ") +
705eb11fae6SDimitry Andric             Name + " in function '" + MF.getName() + "'");
706b915e9e0SDimitry Andric       Error = true;
707b915e9e0SDimitry Andric       break;
708b915e9e0SDimitry Andric     case VRegInfo::NORMAL:
709e3b55780SDimitry Andric       if (!Info.D.RC->isAllocatable()) {
710e3b55780SDimitry Andric         error(Twine("Cannot use non-allocatable class '") +
711e3b55780SDimitry Andric               TRI->getRegClassName(Info.D.RC) + "' for virtual register " +
712e3b55780SDimitry Andric               Name + " in function '" + MF.getName() + "'");
713e3b55780SDimitry Andric         Error = true;
714e3b55780SDimitry Andric         break;
715e3b55780SDimitry Andric       }
716e3b55780SDimitry Andric 
717b915e9e0SDimitry Andric       MRI.setRegClass(Reg, Info.D.RC);
718b915e9e0SDimitry Andric       if (Info.PreferredReg != 0)
719b915e9e0SDimitry Andric         MRI.setSimpleHint(Reg, Info.PreferredReg);
720b915e9e0SDimitry Andric       break;
721b915e9e0SDimitry Andric     case VRegInfo::GENERIC:
722b915e9e0SDimitry Andric       break;
723b915e9e0SDimitry Andric     case VRegInfo::REGBANK:
724b915e9e0SDimitry Andric       MRI.setRegBank(Reg, *Info.D.RegBank);
725b915e9e0SDimitry Andric       break;
726b915e9e0SDimitry Andric     }
727eb11fae6SDimitry Andric   };
728eb11fae6SDimitry Andric 
729344a3780SDimitry Andric   for (const auto &P : PFS.VRegInfosNamed) {
730344a3780SDimitry Andric     const VRegInfo &Info = *P.second;
731344a3780SDimitry Andric     populateVRegInfo(Info, Twine(P.first()));
732eb11fae6SDimitry Andric   }
733eb11fae6SDimitry Andric 
734eb11fae6SDimitry Andric   for (auto P : PFS.VRegInfos) {
735eb11fae6SDimitry Andric     const VRegInfo &Info = *P.second;
736eb11fae6SDimitry Andric     populateVRegInfo(Info, Twine(P.first));
737b915e9e0SDimitry Andric   }
738b915e9e0SDimitry Andric 
739b915e9e0SDimitry Andric   // Compute MachineRegisterInfo::UsedPhysRegMask
740b915e9e0SDimitry Andric   for (const MachineBasicBlock &MBB : MF) {
741b60736ecSDimitry Andric     // Make sure MRI knows about registers clobbered by unwinder.
742b60736ecSDimitry Andric     if (MBB.isEHPad())
743b60736ecSDimitry Andric       if (auto *RegMask = TRI->getCustomEHPadPreservedMask(MF))
744b60736ecSDimitry Andric         MRI.addPhysRegsUsedFromRegMask(RegMask);
745b60736ecSDimitry Andric 
746dd58ef01SDimitry Andric     for (const MachineInstr &MI : MBB) {
747dd58ef01SDimitry Andric       for (const MachineOperand &MO : MI.operands()) {
748dd58ef01SDimitry Andric         if (!MO.isRegMask())
749dd58ef01SDimitry Andric           continue;
75001095a5dSDimitry Andric         MRI.addPhysRegsUsedFromRegMask(MO.getRegMask());
751dd58ef01SDimitry Andric       }
752dd58ef01SDimitry Andric     }
753dd58ef01SDimitry Andric   }
754dd58ef01SDimitry Andric 
755b915e9e0SDimitry Andric   return Error;
756b915e9e0SDimitry Andric }
757b915e9e0SDimitry Andric 
initializeFrameInfo(PerFunctionMIParsingState & PFS,const yaml::MachineFunction & YamlMF)75801095a5dSDimitry Andric bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS,
75901095a5dSDimitry Andric                                         const yaml::MachineFunction &YamlMF) {
76001095a5dSDimitry Andric   MachineFunction &MF = PFS.MF;
761b915e9e0SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
762e6d15924SDimitry Andric   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
763044eb2f6SDimitry Andric   const Function &F = MF.getFunction();
764ee8648bdSDimitry Andric   const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
765ee8648bdSDimitry Andric   MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
766ee8648bdSDimitry Andric   MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
767ee8648bdSDimitry Andric   MFI.setHasStackMap(YamlMFI.HasStackMap);
768ee8648bdSDimitry Andric   MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);
769ee8648bdSDimitry Andric   MFI.setStackSize(YamlMFI.StackSize);
770ee8648bdSDimitry Andric   MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment);
771ee8648bdSDimitry Andric   if (YamlMFI.MaxAlignment)
772cfca06d7SDimitry Andric     MFI.ensureMaxAlignment(Align(YamlMFI.MaxAlignment));
773ee8648bdSDimitry Andric   MFI.setAdjustsStack(YamlMFI.AdjustsStack);
774ee8648bdSDimitry Andric   MFI.setHasCalls(YamlMFI.HasCalls);
775a303c417SDimitry Andric   if (YamlMFI.MaxCallFrameSize != ~0u)
776ee8648bdSDimitry Andric     MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize);
777d8e91e46SDimitry Andric   MFI.setCVBytesOfCalleeSavedRegisters(YamlMFI.CVBytesOfCalleeSavedRegisters);
778ee8648bdSDimitry Andric   MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);
779ee8648bdSDimitry Andric   MFI.setHasVAStart(YamlMFI.HasVAStart);
780ee8648bdSDimitry Andric   MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
781344a3780SDimitry Andric   MFI.setHasTailCall(YamlMFI.HasTailCall);
782ac9a064cSDimitry Andric   MFI.setCalleeSavedInfoValid(YamlMFI.IsCalleeSavedInfoValid);
783eb11fae6SDimitry Andric   MFI.setLocalFrameSize(YamlMFI.LocalFrameSize);
784dd58ef01SDimitry Andric   if (!YamlMFI.SavePoint.Value.empty()) {
785dd58ef01SDimitry Andric     MachineBasicBlock *MBB = nullptr;
78601095a5dSDimitry Andric     if (parseMBBReference(PFS, MBB, YamlMFI.SavePoint))
787dd58ef01SDimitry Andric       return true;
788dd58ef01SDimitry Andric     MFI.setSavePoint(MBB);
789dd58ef01SDimitry Andric   }
790dd58ef01SDimitry Andric   if (!YamlMFI.RestorePoint.Value.empty()) {
791dd58ef01SDimitry Andric     MachineBasicBlock *MBB = nullptr;
79201095a5dSDimitry Andric     if (parseMBBReference(PFS, MBB, YamlMFI.RestorePoint))
793dd58ef01SDimitry Andric       return true;
794dd58ef01SDimitry Andric     MFI.setRestorePoint(MBB);
795dd58ef01SDimitry Andric   }
796ee8648bdSDimitry Andric 
797dd58ef01SDimitry Andric   std::vector<CalleeSavedInfo> CSIInfo;
798ee8648bdSDimitry Andric   // Initialize the fixed frame objects.
799ee8648bdSDimitry Andric   for (const auto &Object : YamlMF.FixedStackObjects) {
800ee8648bdSDimitry Andric     int ObjectIdx;
801ee8648bdSDimitry Andric     if (Object.Type != yaml::FixedMachineStackObject::SpillSlot)
802ee8648bdSDimitry Andric       ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset,
803ee8648bdSDimitry Andric                                         Object.IsImmutable, Object.IsAliased);
804ee8648bdSDimitry Andric     else
805ee8648bdSDimitry Andric       ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
806e6d15924SDimitry Andric 
807e6d15924SDimitry Andric     if (!TFI->isSupportedStackID(Object.StackID))
808e6d15924SDimitry Andric       return error(Object.ID.SourceRange.Start,
809e6d15924SDimitry Andric                    Twine("StackID is not supported by target"));
810044eb2f6SDimitry Andric     MFI.setStackID(ObjectIdx, Object.StackID);
811cfca06d7SDimitry Andric     MFI.setObjectAlignment(ObjectIdx, Object.Alignment.valueOrOne());
812dd58ef01SDimitry Andric     if (!PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID.Value,
813dd58ef01SDimitry Andric                                                          ObjectIdx))
814dd58ef01SDimitry Andric              .second)
815dd58ef01SDimitry Andric       return error(Object.ID.SourceRange.Start,
816dd58ef01SDimitry Andric                    Twine("redefinition of fixed stack object '%fixed-stack.") +
817dd58ef01SDimitry Andric                        Twine(Object.ID.Value) + "'");
81801095a5dSDimitry Andric     if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister,
819044eb2f6SDimitry Andric                                  Object.CalleeSavedRestored, ObjectIdx))
820dd58ef01SDimitry Andric       return true;
821eb11fae6SDimitry Andric     if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx))
822eb11fae6SDimitry Andric       return true;
823ee8648bdSDimitry Andric   }
824ee8648bdSDimitry Andric 
8257fa27ce4SDimitry Andric   for (const auto &Object : YamlMF.EntryValueObjects) {
8267fa27ce4SDimitry Andric     SMDiagnostic Error;
8277fa27ce4SDimitry Andric     Register Reg;
8287fa27ce4SDimitry Andric     if (parseNamedRegisterReference(PFS, Reg, Object.EntryValueRegister.Value,
8297fa27ce4SDimitry Andric                                     Error))
8307fa27ce4SDimitry Andric       return error(Error, Object.EntryValueRegister.SourceRange);
8317fa27ce4SDimitry Andric     if (!Reg.isPhysical())
8327fa27ce4SDimitry Andric       return error(Object.EntryValueRegister.SourceRange.Start,
8337fa27ce4SDimitry Andric                    "Expected physical register for entry value field");
8347fa27ce4SDimitry Andric     std::optional<VarExprLoc> MaybeInfo = parseVarExprLoc(
8357fa27ce4SDimitry Andric         PFS, Object.DebugVar, Object.DebugExpr, Object.DebugLoc);
8367fa27ce4SDimitry Andric     if (!MaybeInfo)
8377fa27ce4SDimitry Andric       return true;
8387fa27ce4SDimitry Andric     if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc)
8397fa27ce4SDimitry Andric       PFS.MF.setVariableDbgInfo(MaybeInfo->DIVar, MaybeInfo->DIExpr,
8407fa27ce4SDimitry Andric                                 Reg.asMCReg(), MaybeInfo->DILoc);
8417fa27ce4SDimitry Andric   }
8427fa27ce4SDimitry Andric 
843ee8648bdSDimitry Andric   // Initialize the ordinary frame objects.
844ee8648bdSDimitry Andric   for (const auto &Object : YamlMF.StackObjects) {
845ee8648bdSDimitry Andric     int ObjectIdx;
846dd58ef01SDimitry Andric     const AllocaInst *Alloca = nullptr;
847dd58ef01SDimitry Andric     const yaml::StringValue &Name = Object.Name;
848dd58ef01SDimitry Andric     if (!Name.Value.empty()) {
849dd58ef01SDimitry Andric       Alloca = dyn_cast_or_null<AllocaInst>(
850b915e9e0SDimitry Andric           F.getValueSymbolTable()->lookup(Name.Value));
851dd58ef01SDimitry Andric       if (!Alloca)
852dd58ef01SDimitry Andric         return error(Name.SourceRange.Start,
853dd58ef01SDimitry Andric                      "alloca instruction named '" + Name.Value +
854dd58ef01SDimitry Andric                          "' isn't defined in the function '" + F.getName() +
855dd58ef01SDimitry Andric                          "'");
856dd58ef01SDimitry Andric     }
857e6d15924SDimitry Andric     if (!TFI->isSupportedStackID(Object.StackID))
858e6d15924SDimitry Andric       return error(Object.ID.SourceRange.Start,
859e6d15924SDimitry Andric                    Twine("StackID is not supported by target"));
860ee8648bdSDimitry Andric     if (Object.Type == yaml::MachineStackObject::VariableSized)
861cfca06d7SDimitry Andric       ObjectIdx =
862cfca06d7SDimitry Andric           MFI.CreateVariableSizedObject(Object.Alignment.valueOrOne(), Alloca);
863ee8648bdSDimitry Andric     else
864ee8648bdSDimitry Andric       ObjectIdx = MFI.CreateStackObject(
865cfca06d7SDimitry Andric           Object.Size, Object.Alignment.valueOrOne(),
866e6d15924SDimitry Andric           Object.Type == yaml::MachineStackObject::SpillSlot, Alloca,
867e6d15924SDimitry Andric           Object.StackID);
868ee8648bdSDimitry Andric     MFI.setObjectOffset(ObjectIdx, Object.Offset);
869044eb2f6SDimitry Andric 
870dd58ef01SDimitry Andric     if (!PFS.StackObjectSlots.insert(std::make_pair(Object.ID.Value, ObjectIdx))
871dd58ef01SDimitry Andric              .second)
872dd58ef01SDimitry Andric       return error(Object.ID.SourceRange.Start,
873dd58ef01SDimitry Andric                    Twine("redefinition of stack object '%stack.") +
874dd58ef01SDimitry Andric                        Twine(Object.ID.Value) + "'");
87501095a5dSDimitry Andric     if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister,
876044eb2f6SDimitry Andric                                  Object.CalleeSavedRestored, ObjectIdx))
877dd58ef01SDimitry Andric       return true;
878dd58ef01SDimitry Andric     if (Object.LocalOffset)
879145449b1SDimitry Andric       MFI.mapLocalFrameObject(ObjectIdx, *Object.LocalOffset);
88001095a5dSDimitry Andric     if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx))
881dd58ef01SDimitry Andric       return true;
882ee8648bdSDimitry Andric   }
883dd58ef01SDimitry Andric   MFI.setCalleeSavedInfo(CSIInfo);
884dd58ef01SDimitry Andric   if (!CSIInfo.empty())
885dd58ef01SDimitry Andric     MFI.setCalleeSavedInfoValid(true);
886dd58ef01SDimitry Andric 
887dd58ef01SDimitry Andric   // Initialize the various stack object references after initializing the
888dd58ef01SDimitry Andric   // stack objects.
889dd58ef01SDimitry Andric   if (!YamlMFI.StackProtector.Value.empty()) {
890dd58ef01SDimitry Andric     SMDiagnostic Error;
891dd58ef01SDimitry Andric     int FI;
89201095a5dSDimitry Andric     if (parseStackObjectReference(PFS, FI, YamlMFI.StackProtector.Value, Error))
893dd58ef01SDimitry Andric       return error(Error, YamlMFI.StackProtector.SourceRange);
894dd58ef01SDimitry Andric     MFI.setStackProtectorIndex(FI);
895dd58ef01SDimitry Andric   }
896145449b1SDimitry Andric 
897145449b1SDimitry Andric   if (!YamlMFI.FunctionContext.Value.empty()) {
898145449b1SDimitry Andric     SMDiagnostic Error;
899145449b1SDimitry Andric     int FI;
900145449b1SDimitry Andric     if (parseStackObjectReference(PFS, FI, YamlMFI.FunctionContext.Value, Error))
901145449b1SDimitry Andric       return error(Error, YamlMFI.FunctionContext.SourceRange);
902145449b1SDimitry Andric     MFI.setFunctionContextIndex(FI);
903145449b1SDimitry Andric   }
904145449b1SDimitry Andric 
905dd58ef01SDimitry Andric   return false;
906dd58ef01SDimitry Andric }
907dd58ef01SDimitry Andric 
parseCalleeSavedRegister(PerFunctionMIParsingState & PFS,std::vector<CalleeSavedInfo> & CSIInfo,const yaml::StringValue & RegisterSource,bool IsRestored,int FrameIdx)90801095a5dSDimitry Andric bool MIRParserImpl::parseCalleeSavedRegister(PerFunctionMIParsingState &PFS,
909dd58ef01SDimitry Andric     std::vector<CalleeSavedInfo> &CSIInfo,
910044eb2f6SDimitry Andric     const yaml::StringValue &RegisterSource, bool IsRestored, int FrameIdx) {
911dd58ef01SDimitry Andric   if (RegisterSource.Value.empty())
912dd58ef01SDimitry Andric     return false;
913cfca06d7SDimitry Andric   Register Reg;
914dd58ef01SDimitry Andric   SMDiagnostic Error;
91501095a5dSDimitry Andric   if (parseNamedRegisterReference(PFS, Reg, RegisterSource.Value, Error))
916dd58ef01SDimitry Andric     return error(Error, RegisterSource.SourceRange);
917044eb2f6SDimitry Andric   CalleeSavedInfo CSI(Reg, FrameIdx);
918044eb2f6SDimitry Andric   CSI.setRestored(IsRestored);
919044eb2f6SDimitry Andric   CSIInfo.push_back(CSI);
920dd58ef01SDimitry Andric   return false;
921dd58ef01SDimitry Andric }
922dd58ef01SDimitry Andric 
923dd58ef01SDimitry Andric /// Verify that given node is of a certain type. Return true on error.
924dd58ef01SDimitry Andric template <typename T>
typecheckMDNode(T * & Result,MDNode * Node,const yaml::StringValue & Source,StringRef TypeString,MIRParserImpl & Parser)925dd58ef01SDimitry Andric static bool typecheckMDNode(T *&Result, MDNode *Node,
926dd58ef01SDimitry Andric                             const yaml::StringValue &Source,
927dd58ef01SDimitry Andric                             StringRef TypeString, MIRParserImpl &Parser) {
928dd58ef01SDimitry Andric   if (!Node)
929dd58ef01SDimitry Andric     return false;
930dd58ef01SDimitry Andric   Result = dyn_cast<T>(Node);
931dd58ef01SDimitry Andric   if (!Result)
932dd58ef01SDimitry Andric     return Parser.error(Source.SourceRange.Start,
933dd58ef01SDimitry Andric                         "expected a reference to a '" + TypeString +
934dd58ef01SDimitry Andric                             "' metadata node");
935dd58ef01SDimitry Andric   return false;
936dd58ef01SDimitry Andric }
937dd58ef01SDimitry Andric 
parseVarExprLoc(PerFunctionMIParsingState & PFS,const yaml::StringValue & VarStr,const yaml::StringValue & ExprStr,const yaml::StringValue & LocStr)9387fa27ce4SDimitry Andric std::optional<MIRParserImpl::VarExprLoc> MIRParserImpl::parseVarExprLoc(
9397fa27ce4SDimitry Andric     PerFunctionMIParsingState &PFS, const yaml::StringValue &VarStr,
9407fa27ce4SDimitry Andric     const yaml::StringValue &ExprStr, const yaml::StringValue &LocStr) {
9417fa27ce4SDimitry Andric   MDNode *Var = nullptr;
9427fa27ce4SDimitry Andric   MDNode *Expr = nullptr;
9437fa27ce4SDimitry Andric   MDNode *Loc = nullptr;
9447fa27ce4SDimitry Andric   if (parseMDNode(PFS, Var, VarStr) || parseMDNode(PFS, Expr, ExprStr) ||
9457fa27ce4SDimitry Andric       parseMDNode(PFS, Loc, LocStr))
9467fa27ce4SDimitry Andric     return std::nullopt;
947dd58ef01SDimitry Andric   DILocalVariable *DIVar = nullptr;
948dd58ef01SDimitry Andric   DIExpression *DIExpr = nullptr;
949dd58ef01SDimitry Andric   DILocation *DILoc = nullptr;
9507fa27ce4SDimitry Andric   if (typecheckMDNode(DIVar, Var, VarStr, "DILocalVariable", *this) ||
9517fa27ce4SDimitry Andric       typecheckMDNode(DIExpr, Expr, ExprStr, "DIExpression", *this) ||
9527fa27ce4SDimitry Andric       typecheckMDNode(DILoc, Loc, LocStr, "DILocation", *this))
9537fa27ce4SDimitry Andric     return std::nullopt;
9547fa27ce4SDimitry Andric   return VarExprLoc{DIVar, DIExpr, DILoc};
9557fa27ce4SDimitry Andric }
9567fa27ce4SDimitry Andric 
9577fa27ce4SDimitry Andric template <typename T>
parseStackObjectsDebugInfo(PerFunctionMIParsingState & PFS,const T & Object,int FrameIdx)9587fa27ce4SDimitry Andric bool MIRParserImpl::parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS,
9597fa27ce4SDimitry Andric                                                const T &Object, int FrameIdx) {
9607fa27ce4SDimitry Andric   std::optional<VarExprLoc> MaybeInfo =
9617fa27ce4SDimitry Andric       parseVarExprLoc(PFS, Object.DebugVar, Object.DebugExpr, Object.DebugLoc);
9627fa27ce4SDimitry Andric   if (!MaybeInfo)
963dd58ef01SDimitry Andric     return true;
9647fa27ce4SDimitry Andric   // Debug information can only be attached to stack objects; Fixed stack
9657fa27ce4SDimitry Andric   // objects aren't supported.
9667fa27ce4SDimitry Andric   if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc)
9677fa27ce4SDimitry Andric     PFS.MF.setVariableDbgInfo(MaybeInfo->DIVar, MaybeInfo->DIExpr, FrameIdx,
9687fa27ce4SDimitry Andric                               MaybeInfo->DILoc);
969dd58ef01SDimitry Andric   return false;
970dd58ef01SDimitry Andric }
971dd58ef01SDimitry Andric 
parseMDNode(PerFunctionMIParsingState & PFS,MDNode * & Node,const yaml::StringValue & Source)972b915e9e0SDimitry Andric bool MIRParserImpl::parseMDNode(PerFunctionMIParsingState &PFS,
97301095a5dSDimitry Andric     MDNode *&Node, const yaml::StringValue &Source) {
974dd58ef01SDimitry Andric   if (Source.Value.empty())
975dd58ef01SDimitry Andric     return false;
976dd58ef01SDimitry Andric   SMDiagnostic Error;
97701095a5dSDimitry Andric   if (llvm::parseMDNode(PFS, Node, Source.Value, Error))
978dd58ef01SDimitry Andric     return error(Error, Source.SourceRange);
979dd58ef01SDimitry Andric   return false;
980dd58ef01SDimitry Andric }
981dd58ef01SDimitry Andric 
initializeConstantPool(PerFunctionMIParsingState & PFS,MachineConstantPool & ConstantPool,const yaml::MachineFunction & YamlMF)98201095a5dSDimitry Andric bool MIRParserImpl::initializeConstantPool(PerFunctionMIParsingState &PFS,
98301095a5dSDimitry Andric     MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF) {
98401095a5dSDimitry Andric   DenseMap<unsigned, unsigned> &ConstantPoolSlots = PFS.ConstantPoolSlots;
98501095a5dSDimitry Andric   const MachineFunction &MF = PFS.MF;
986044eb2f6SDimitry Andric   const auto &M = *MF.getFunction().getParent();
987dd58ef01SDimitry Andric   SMDiagnostic Error;
988dd58ef01SDimitry Andric   for (const auto &YamlConstant : YamlMF.Constants) {
989044eb2f6SDimitry Andric     if (YamlConstant.IsTargetSpecific)
990044eb2f6SDimitry Andric       // FIXME: Support target-specific constant pools
991044eb2f6SDimitry Andric       return error(YamlConstant.Value.SourceRange.Start,
992044eb2f6SDimitry Andric                    "Can't parse target-specific constant pool entries yet");
993dd58ef01SDimitry Andric     const Constant *Value = dyn_cast_or_null<Constant>(
994dd58ef01SDimitry Andric         parseConstantValue(YamlConstant.Value.Value, Error, M));
995dd58ef01SDimitry Andric     if (!Value)
996dd58ef01SDimitry Andric       return error(Error, YamlConstant.Value.SourceRange);
997cfca06d7SDimitry Andric     const Align PrefTypeAlign =
998cfca06d7SDimitry Andric         M.getDataLayout().getPrefTypeAlign(Value->getType());
999145449b1SDimitry Andric     const Align Alignment = YamlConstant.Alignment.value_or(PrefTypeAlign);
1000dd58ef01SDimitry Andric     unsigned Index = ConstantPool.getConstantPoolIndex(Value, Alignment);
1001dd58ef01SDimitry Andric     if (!ConstantPoolSlots.insert(std::make_pair(YamlConstant.ID.Value, Index))
1002dd58ef01SDimitry Andric              .second)
1003dd58ef01SDimitry Andric       return error(YamlConstant.ID.SourceRange.Start,
1004dd58ef01SDimitry Andric                    Twine("redefinition of constant pool item '%const.") +
1005dd58ef01SDimitry Andric                        Twine(YamlConstant.ID.Value) + "'");
1006dd58ef01SDimitry Andric   }
1007dd58ef01SDimitry Andric   return false;
1008dd58ef01SDimitry Andric }
1009dd58ef01SDimitry Andric 
initializeJumpTableInfo(PerFunctionMIParsingState & PFS,const yaml::MachineJumpTable & YamlJTI)101001095a5dSDimitry Andric bool MIRParserImpl::initializeJumpTableInfo(PerFunctionMIParsingState &PFS,
101101095a5dSDimitry Andric     const yaml::MachineJumpTable &YamlJTI) {
101201095a5dSDimitry Andric   MachineJumpTableInfo *JTI = PFS.MF.getOrCreateJumpTableInfo(YamlJTI.Kind);
1013dd58ef01SDimitry Andric   for (const auto &Entry : YamlJTI.Entries) {
1014dd58ef01SDimitry Andric     std::vector<MachineBasicBlock *> Blocks;
1015dd58ef01SDimitry Andric     for (const auto &MBBSource : Entry.Blocks) {
1016dd58ef01SDimitry Andric       MachineBasicBlock *MBB = nullptr;
101701095a5dSDimitry Andric       if (parseMBBReference(PFS, MBB, MBBSource.Value))
1018dd58ef01SDimitry Andric         return true;
1019dd58ef01SDimitry Andric       Blocks.push_back(MBB);
1020dd58ef01SDimitry Andric     }
1021dd58ef01SDimitry Andric     unsigned Index = JTI->createJumpTableIndex(Blocks);
1022dd58ef01SDimitry Andric     if (!PFS.JumpTableSlots.insert(std::make_pair(Entry.ID.Value, Index))
1023dd58ef01SDimitry Andric              .second)
1024dd58ef01SDimitry Andric       return error(Entry.ID.SourceRange.Start,
1025dd58ef01SDimitry Andric                    Twine("redefinition of jump table entry '%jump-table.") +
1026dd58ef01SDimitry Andric                        Twine(Entry.ID.Value) + "'");
1027dd58ef01SDimitry Andric   }
1028dd58ef01SDimitry Andric   return false;
1029dd58ef01SDimitry Andric }
1030dd58ef01SDimitry Andric 
parseMBBReference(PerFunctionMIParsingState & PFS,MachineBasicBlock * & MBB,const yaml::StringValue & Source)1031b915e9e0SDimitry Andric bool MIRParserImpl::parseMBBReference(PerFunctionMIParsingState &PFS,
103201095a5dSDimitry Andric                                       MachineBasicBlock *&MBB,
103301095a5dSDimitry Andric                                       const yaml::StringValue &Source) {
1034dd58ef01SDimitry Andric   SMDiagnostic Error;
103501095a5dSDimitry Andric   if (llvm::parseMBBReference(PFS, MBB, Source.Value, Error))
1036dd58ef01SDimitry Andric     return error(Error, Source.SourceRange);
10371a82d4c0SDimitry Andric   return false;
10381a82d4c0SDimitry Andric }
10391a82d4c0SDimitry Andric 
parseMachineMetadata(PerFunctionMIParsingState & PFS,const yaml::StringValue & Source)1040344a3780SDimitry Andric bool MIRParserImpl::parseMachineMetadata(PerFunctionMIParsingState &PFS,
1041344a3780SDimitry Andric                                          const yaml::StringValue &Source) {
1042344a3780SDimitry Andric   SMDiagnostic Error;
1043344a3780SDimitry Andric   if (llvm::parseMachineMetadata(PFS, Source.Value, Source.SourceRange, Error))
1044344a3780SDimitry Andric     return error(Error, Source.SourceRange);
1045344a3780SDimitry Andric   return false;
1046344a3780SDimitry Andric }
1047344a3780SDimitry Andric 
parseMachineMetadataNodes(PerFunctionMIParsingState & PFS,MachineFunction & MF,const yaml::MachineFunction & YMF)1048344a3780SDimitry Andric bool MIRParserImpl::parseMachineMetadataNodes(
1049344a3780SDimitry Andric     PerFunctionMIParsingState &PFS, MachineFunction &MF,
1050344a3780SDimitry Andric     const yaml::MachineFunction &YMF) {
10514b4fe385SDimitry Andric   for (const auto &MDS : YMF.MachineMetadataNodes) {
1052344a3780SDimitry Andric     if (parseMachineMetadata(PFS, MDS))
1053344a3780SDimitry Andric       return true;
1054344a3780SDimitry Andric   }
1055344a3780SDimitry Andric   // Report missing definitions from forward referenced nodes.
1056344a3780SDimitry Andric   if (!PFS.MachineForwardRefMDNodes.empty())
1057344a3780SDimitry Andric     return error(PFS.MachineForwardRefMDNodes.begin()->second.second,
1058344a3780SDimitry Andric                  "use of undefined metadata '!" +
1059344a3780SDimitry Andric                      Twine(PFS.MachineForwardRefMDNodes.begin()->first) + "'");
1060344a3780SDimitry Andric   return false;
1061344a3780SDimitry Andric }
1062344a3780SDimitry Andric 
diagFromMIStringDiag(const SMDiagnostic & Error,SMRange SourceRange)10631a82d4c0SDimitry Andric SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
10641a82d4c0SDimitry Andric                                                  SMRange SourceRange) {
10651a82d4c0SDimitry Andric   assert(SourceRange.isValid() && "Invalid source range");
10661a82d4c0SDimitry Andric   SMLoc Loc = SourceRange.Start;
10671a82d4c0SDimitry Andric   bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
10681a82d4c0SDimitry Andric                   *Loc.getPointer() == '\'';
10691a82d4c0SDimitry Andric   // Translate the location of the error from the location in the MI string to
10701a82d4c0SDimitry Andric   // the corresponding location in the MIR file.
10711a82d4c0SDimitry Andric   Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
10721a82d4c0SDimitry Andric                            (HasQuote ? 1 : 0));
10731a82d4c0SDimitry Andric 
10741a82d4c0SDimitry Andric   // TODO: Translate any source ranges as well.
1075e3b55780SDimitry Andric   return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), std::nullopt,
10761a82d4c0SDimitry Andric                        Error.getFixIts());
10771a82d4c0SDimitry Andric }
10781a82d4c0SDimitry Andric 
diagFromBlockStringDiag(const SMDiagnostic & Error,SMRange SourceRange)1079dd58ef01SDimitry Andric SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error,
108085d8b2bbSDimitry Andric                                                     SMRange SourceRange) {
108185d8b2bbSDimitry Andric   assert(SourceRange.isValid());
108285d8b2bbSDimitry Andric 
108385d8b2bbSDimitry Andric   // Translate the location of the error from the location in the llvm IR string
108485d8b2bbSDimitry Andric   // to the corresponding location in the MIR file.
108585d8b2bbSDimitry Andric   auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
108685d8b2bbSDimitry Andric   unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
108785d8b2bbSDimitry Andric   unsigned Column = Error.getColumnNo();
108885d8b2bbSDimitry Andric   StringRef LineStr = Error.getLineContents();
108985d8b2bbSDimitry Andric   SMLoc Loc = Error.getLoc();
109085d8b2bbSDimitry Andric 
109185d8b2bbSDimitry Andric   // Get the full line and adjust the column number by taking the indentation of
109285d8b2bbSDimitry Andric   // LLVM IR into account.
109385d8b2bbSDimitry Andric   for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
109485d8b2bbSDimitry Andric        L != E; ++L) {
109585d8b2bbSDimitry Andric     if (L.line_number() == Line) {
109685d8b2bbSDimitry Andric       LineStr = *L;
109785d8b2bbSDimitry Andric       Loc = SMLoc::getFromPointer(LineStr.data());
109885d8b2bbSDimitry Andric       auto Indent = LineStr.find(Error.getLineContents());
109985d8b2bbSDimitry Andric       if (Indent != StringRef::npos)
110085d8b2bbSDimitry Andric         Column += Indent;
110185d8b2bbSDimitry Andric       break;
110285d8b2bbSDimitry Andric     }
110385d8b2bbSDimitry Andric   }
110485d8b2bbSDimitry Andric 
110585d8b2bbSDimitry Andric   return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
110685d8b2bbSDimitry Andric                       Error.getMessage(), LineStr, Error.getRanges(),
110785d8b2bbSDimitry Andric                       Error.getFixIts());
110885d8b2bbSDimitry Andric }
110985d8b2bbSDimitry Andric 
MIRParser(std::unique_ptr<MIRParserImpl> Impl)11103a0822f0SDimitry Andric MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
11113a0822f0SDimitry Andric     : Impl(std::move(Impl)) {}
11123a0822f0SDimitry Andric 
1113145449b1SDimitry Andric MIRParser::~MIRParser() = default;
11143a0822f0SDimitry Andric 
1115cfca06d7SDimitry Andric std::unique_ptr<Module>
parseIRModule(DataLayoutCallbackTy DataLayoutCallback)1116cfca06d7SDimitry Andric MIRParser::parseIRModule(DataLayoutCallbackTy DataLayoutCallback) {
1117cfca06d7SDimitry Andric   return Impl->parseIRModule(DataLayoutCallback);
11187ab83427SDimitry Andric }
11193a0822f0SDimitry Andric 
parseMachineFunctions(Module & M,MachineModuleInfo & MMI)11207ab83427SDimitry Andric bool MIRParser::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
11217ab83427SDimitry Andric   return Impl->parseMachineFunctions(M, MMI);
11223a0822f0SDimitry Andric }
11233a0822f0SDimitry Andric 
parseMachineFunctions(Module & M,ModuleAnalysisManager & MAM)1124ac9a064cSDimitry Andric bool MIRParser::parseMachineFunctions(Module &M, ModuleAnalysisManager &MAM) {
1125ac9a064cSDimitry Andric   auto &MMI = MAM.getResult<MachineModuleAnalysis>(M).getMMI();
1126ac9a064cSDimitry Andric   return Impl->parseMachineFunctions(M, MMI, &MAM);
1127ac9a064cSDimitry Andric }
1128ac9a064cSDimitry Andric 
createMIRParserFromFile(StringRef Filename,SMDiagnostic & Error,LLVMContext & Context,std::function<void (Function &)> ProcessIRFunction)1129706b4fc4SDimitry Andric std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(
1130706b4fc4SDimitry Andric     StringRef Filename, SMDiagnostic &Error, LLVMContext &Context,
1131706b4fc4SDimitry Andric     std::function<void(Function &)> ProcessIRFunction) {
1132344a3780SDimitry Andric   auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
113385d8b2bbSDimitry Andric   if (std::error_code EC = FileOrErr.getError()) {
113485d8b2bbSDimitry Andric     Error = SMDiagnostic(Filename, SourceMgr::DK_Error,
113585d8b2bbSDimitry Andric                          "Could not open input file: " + EC.message());
11363a0822f0SDimitry Andric     return nullptr;
113785d8b2bbSDimitry Andric   }
1138706b4fc4SDimitry Andric   return createMIRParser(std::move(FileOrErr.get()), Context,
1139706b4fc4SDimitry Andric                          ProcessIRFunction);
114085d8b2bbSDimitry Andric }
114185d8b2bbSDimitry Andric 
11423a0822f0SDimitry Andric std::unique_ptr<MIRParser>
createMIRParser(std::unique_ptr<MemoryBuffer> Contents,LLVMContext & Context,std::function<void (Function &)> ProcessIRFunction)11433a0822f0SDimitry Andric llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
1144706b4fc4SDimitry Andric                       LLVMContext &Context,
1145706b4fc4SDimitry Andric                       std::function<void(Function &)> ProcessIRFunction) {
114685d8b2bbSDimitry Andric   auto Filename = Contents->getBufferIdentifier();
1147b915e9e0SDimitry Andric   if (Context.shouldDiscardValueNames()) {
1148b915e9e0SDimitry Andric     Context.diagnose(DiagnosticInfoMIRParser(
1149b915e9e0SDimitry Andric         DS_Error,
1150b915e9e0SDimitry Andric         SMDiagnostic(
1151b915e9e0SDimitry Andric             Filename, SourceMgr::DK_Error,
1152b915e9e0SDimitry Andric             "Can't read MIR with a Context that discards named Values")));
1153b915e9e0SDimitry Andric     return nullptr;
1154b915e9e0SDimitry Andric   }
1155706b4fc4SDimitry Andric   return std::make_unique<MIRParser>(std::make_unique<MIRParserImpl>(
1156706b4fc4SDimitry Andric       std::move(Contents), Filename, Context, ProcessIRFunction));
115785d8b2bbSDimitry Andric }
1158