10b57cec5SDimitry Andric //===- MIRParser.cpp - MIR serialization format parser implementation -----===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the class that parses the optional LLVM IR and machine 100b57cec5SDimitry Andric // functions that are stored in MIR files. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/CodeGen/MIRParser/MIRParser.h" 150b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 160b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 170b57cec5SDimitry Andric #include "llvm/AsmParser/Parser.h" 180b57cec5SDimitry Andric #include "llvm/AsmParser/SlotMapping.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MIRParser/MIParser.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/MIRYamlMapping.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 24*0fca6ea1SDimitry Andric #include "llvm/CodeGen/MachineFunctionAnalysis.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 260b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 270b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h" 280b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 2981ad6265SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 300b57cec5SDimitry Andric #include "llvm/IR/DiagnosticInfo.h" 310b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 320b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 330b57cec5SDimitry Andric #include "llvm/IR/Module.h" 340b57cec5SDimitry Andric #include "llvm/IR/ValueSymbolTable.h" 350b57cec5SDimitry Andric #include "llvm/Support/LineIterator.h" 360b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 370b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h" 380b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h" 390b57cec5SDimitry Andric #include "llvm/Support/YAMLTraits.h" 400b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 410b57cec5SDimitry Andric #include <memory> 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric using namespace llvm; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric namespace llvm { 4681ad6265SDimitry Andric class MDNode; 4781ad6265SDimitry Andric class RegisterBank; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric /// This class implements the parsing of LLVM IR that's embedded inside a MIR 500b57cec5SDimitry Andric /// file. 510b57cec5SDimitry Andric class MIRParserImpl { 520b57cec5SDimitry Andric SourceMgr SM; 53fe6060f1SDimitry Andric LLVMContext &Context; 540b57cec5SDimitry Andric yaml::Input In; 550b57cec5SDimitry Andric StringRef Filename; 560b57cec5SDimitry Andric SlotMapping IRSlots; 570b57cec5SDimitry Andric std::unique_ptr<PerTargetMIParsingState> Target; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric /// True when the MIR file doesn't have LLVM IR. Dummy IR functions are 600b57cec5SDimitry Andric /// created and inserted into the given module when this is true. 610b57cec5SDimitry Andric bool NoLLVMIR = false; 620b57cec5SDimitry Andric /// True when a well formed MIR file does not contain any MIR/machine function 630b57cec5SDimitry Andric /// parts. 640b57cec5SDimitry Andric bool NoMIRDocuments = false; 650b57cec5SDimitry Andric 66480093f4SDimitry Andric std::function<void(Function &)> ProcessIRFunction; 67480093f4SDimitry Andric 680b57cec5SDimitry Andric public: 69480093f4SDimitry Andric MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename, 70480093f4SDimitry Andric LLVMContext &Context, 71480093f4SDimitry Andric std::function<void(Function &)> ProcessIRFunction); 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric void reportDiagnostic(const SMDiagnostic &Diag); 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric /// Report an error with the given message at unknown location. 760b57cec5SDimitry Andric /// 770b57cec5SDimitry Andric /// Always returns true. 780b57cec5SDimitry Andric bool error(const Twine &Message); 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric /// Report an error with the given message at the given location. 810b57cec5SDimitry Andric /// 820b57cec5SDimitry Andric /// Always returns true. 830b57cec5SDimitry Andric bool error(SMLoc Loc, const Twine &Message); 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric /// Report a given error with the location translated from the location in an 860b57cec5SDimitry Andric /// embedded string literal to a location in the MIR file. 870b57cec5SDimitry Andric /// 880b57cec5SDimitry Andric /// Always returns true. 890b57cec5SDimitry Andric bool error(const SMDiagnostic &Error, SMRange SourceRange); 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric /// Try to parse the optional LLVM module and the machine functions in the MIR 920b57cec5SDimitry Andric /// file. 930b57cec5SDimitry Andric /// 940b57cec5SDimitry Andric /// Return null if an error occurred. 955ffd83dbSDimitry Andric std::unique_ptr<Module> 965ffd83dbSDimitry Andric parseIRModule(DataLayoutCallbackTy DataLayoutCallback); 970b57cec5SDimitry Andric 98480093f4SDimitry Andric /// Create an empty function with the given name. 99480093f4SDimitry Andric Function *createDummyFunction(StringRef Name, Module &M); 100480093f4SDimitry Andric 101*0fca6ea1SDimitry Andric bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI, 102*0fca6ea1SDimitry Andric ModuleAnalysisManager *FAM = nullptr); 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric /// Parse the machine function in the current YAML document. 1050b57cec5SDimitry Andric /// 1060b57cec5SDimitry Andric /// 1070b57cec5SDimitry Andric /// Return true if an error occurred. 108*0fca6ea1SDimitry Andric bool parseMachineFunction(Module &M, MachineModuleInfo &MMI, 109*0fca6ea1SDimitry Andric ModuleAnalysisManager *FAM); 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric /// Initialize the machine function to the state that's described in the MIR 1120b57cec5SDimitry Andric /// file. 1130b57cec5SDimitry Andric /// 1140b57cec5SDimitry Andric /// Return true if error occurred. 1150b57cec5SDimitry Andric bool initializeMachineFunction(const yaml::MachineFunction &YamlMF, 1160b57cec5SDimitry Andric MachineFunction &MF); 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric bool parseRegisterInfo(PerFunctionMIParsingState &PFS, 1190b57cec5SDimitry Andric const yaml::MachineFunction &YamlMF); 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric bool setupRegisterInfo(const PerFunctionMIParsingState &PFS, 1220b57cec5SDimitry Andric const yaml::MachineFunction &YamlMF); 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric bool initializeFrameInfo(PerFunctionMIParsingState &PFS, 1250b57cec5SDimitry Andric const yaml::MachineFunction &YamlMF); 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric bool initializeCallSiteInfo(PerFunctionMIParsingState &PFS, 1280b57cec5SDimitry Andric const yaml::MachineFunction &YamlMF); 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric bool parseCalleeSavedRegister(PerFunctionMIParsingState &PFS, 1310b57cec5SDimitry Andric std::vector<CalleeSavedInfo> &CSIInfo, 1320b57cec5SDimitry Andric const yaml::StringValue &RegisterSource, 1330b57cec5SDimitry Andric bool IsRestored, int FrameIdx); 1340b57cec5SDimitry Andric 13506c3fb27SDimitry Andric struct VarExprLoc { 13606c3fb27SDimitry Andric DILocalVariable *DIVar = nullptr; 13706c3fb27SDimitry Andric DIExpression *DIExpr = nullptr; 13806c3fb27SDimitry Andric DILocation *DILoc = nullptr; 13906c3fb27SDimitry Andric }; 14006c3fb27SDimitry Andric 14106c3fb27SDimitry Andric std::optional<VarExprLoc> parseVarExprLoc(PerFunctionMIParsingState &PFS, 14206c3fb27SDimitry Andric const yaml::StringValue &VarStr, 14306c3fb27SDimitry Andric const yaml::StringValue &ExprStr, 14406c3fb27SDimitry Andric const yaml::StringValue &LocStr); 1450b57cec5SDimitry Andric template <typename T> 1460b57cec5SDimitry Andric bool parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS, 1470b57cec5SDimitry Andric const T &Object, 1480b57cec5SDimitry Andric int FrameIdx); 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric bool initializeConstantPool(PerFunctionMIParsingState &PFS, 1510b57cec5SDimitry Andric MachineConstantPool &ConstantPool, 1520b57cec5SDimitry Andric const yaml::MachineFunction &YamlMF); 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric bool initializeJumpTableInfo(PerFunctionMIParsingState &PFS, 1550b57cec5SDimitry Andric const yaml::MachineJumpTable &YamlJTI); 1560b57cec5SDimitry Andric 157fe6060f1SDimitry Andric bool parseMachineMetadataNodes(PerFunctionMIParsingState &PFS, 158fe6060f1SDimitry Andric MachineFunction &MF, 159fe6060f1SDimitry Andric const yaml::MachineFunction &YMF); 160fe6060f1SDimitry Andric 1610b57cec5SDimitry Andric private: 1620b57cec5SDimitry Andric bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node, 1630b57cec5SDimitry Andric const yaml::StringValue &Source); 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric bool parseMBBReference(PerFunctionMIParsingState &PFS, 1660b57cec5SDimitry Andric MachineBasicBlock *&MBB, 1670b57cec5SDimitry Andric const yaml::StringValue &Source); 1680b57cec5SDimitry Andric 169fe6060f1SDimitry Andric bool parseMachineMetadata(PerFunctionMIParsingState &PFS, 170fe6060f1SDimitry Andric const yaml::StringValue &Source); 171fe6060f1SDimitry Andric 1720b57cec5SDimitry Andric /// Return a MIR diagnostic converted from an MI string diagnostic. 1730b57cec5SDimitry Andric SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error, 1740b57cec5SDimitry Andric SMRange SourceRange); 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric /// Return a MIR diagnostic converted from a diagnostic located in a YAML 1770b57cec5SDimitry Andric /// block scalar string. 1780b57cec5SDimitry Andric SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error, 1790b57cec5SDimitry Andric SMRange SourceRange); 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric void computeFunctionProperties(MachineFunction &MF); 182e8d8bef9SDimitry Andric 183e8d8bef9SDimitry Andric void setupDebugValueTracking(MachineFunction &MF, 184e8d8bef9SDimitry Andric PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF); 1850b57cec5SDimitry Andric }; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric } // end namespace llvm 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) { 1900b57cec5SDimitry Andric reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag); 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, 194480093f4SDimitry Andric StringRef Filename, LLVMContext &Context, 195480093f4SDimitry Andric std::function<void(Function &)> Callback) 19604eeddc0SDimitry Andric : Context(Context), 197480093f4SDimitry Andric In(SM.getMemoryBuffer(SM.AddNewSourceBuffer(std::move(Contents), SMLoc())) 198480093f4SDimitry Andric ->getBuffer(), 1990b57cec5SDimitry Andric nullptr, handleYAMLDiag, this), 200fe6060f1SDimitry Andric Filename(Filename), ProcessIRFunction(Callback) { 2010b57cec5SDimitry Andric In.setContext(&In); 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric bool MIRParserImpl::error(const Twine &Message) { 2050b57cec5SDimitry Andric Context.diagnose(DiagnosticInfoMIRParser( 2060b57cec5SDimitry Andric DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str()))); 2070b57cec5SDimitry Andric return true; 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) { 2110b57cec5SDimitry Andric Context.diagnose(DiagnosticInfoMIRParser( 2120b57cec5SDimitry Andric DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message))); 2130b57cec5SDimitry Andric return true; 2140b57cec5SDimitry Andric } 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) { 2170b57cec5SDimitry Andric assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error"); 2180b57cec5SDimitry Andric reportDiagnostic(diagFromMIStringDiag(Error, SourceRange)); 2190b57cec5SDimitry Andric return true; 2200b57cec5SDimitry Andric } 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) { 2230b57cec5SDimitry Andric DiagnosticSeverity Kind; 2240b57cec5SDimitry Andric switch (Diag.getKind()) { 2250b57cec5SDimitry Andric case SourceMgr::DK_Error: 2260b57cec5SDimitry Andric Kind = DS_Error; 2270b57cec5SDimitry Andric break; 2280b57cec5SDimitry Andric case SourceMgr::DK_Warning: 2290b57cec5SDimitry Andric Kind = DS_Warning; 2300b57cec5SDimitry Andric break; 2310b57cec5SDimitry Andric case SourceMgr::DK_Note: 2320b57cec5SDimitry Andric Kind = DS_Note; 2330b57cec5SDimitry Andric break; 2340b57cec5SDimitry Andric case SourceMgr::DK_Remark: 2350b57cec5SDimitry Andric llvm_unreachable("remark unexpected"); 2360b57cec5SDimitry Andric break; 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag)); 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric 2415ffd83dbSDimitry Andric std::unique_ptr<Module> 2425ffd83dbSDimitry Andric MIRParserImpl::parseIRModule(DataLayoutCallbackTy DataLayoutCallback) { 2430b57cec5SDimitry Andric if (!In.setCurrentDocument()) { 2440b57cec5SDimitry Andric if (In.error()) 2450b57cec5SDimitry Andric return nullptr; 2460b57cec5SDimitry Andric // Create an empty module when the MIR file is empty. 2470b57cec5SDimitry Andric NoMIRDocuments = true; 2485ffd83dbSDimitry Andric auto M = std::make_unique<Module>(Filename, Context); 249bdd1243dSDimitry Andric if (auto LayoutOverride = 250bdd1243dSDimitry Andric DataLayoutCallback(M->getTargetTriple(), M->getDataLayoutStr())) 2515ffd83dbSDimitry Andric M->setDataLayout(*LayoutOverride); 2525ffd83dbSDimitry Andric return M; 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric std::unique_ptr<Module> M; 2560b57cec5SDimitry Andric // Parse the block scalar manually so that we can return unique pointer 2570b57cec5SDimitry Andric // without having to go trough YAML traits. 2580b57cec5SDimitry Andric if (const auto *BSN = 2590b57cec5SDimitry Andric dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) { 2600b57cec5SDimitry Andric SMDiagnostic Error; 2610b57cec5SDimitry Andric M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error, 2625ffd83dbSDimitry Andric Context, &IRSlots, DataLayoutCallback); 2630b57cec5SDimitry Andric if (!M) { 2640b57cec5SDimitry Andric reportDiagnostic(diagFromBlockStringDiag(Error, BSN->getSourceRange())); 2650b57cec5SDimitry Andric return nullptr; 2660b57cec5SDimitry Andric } 2670b57cec5SDimitry Andric In.nextDocument(); 2680b57cec5SDimitry Andric if (!In.setCurrentDocument()) 2690b57cec5SDimitry Andric NoMIRDocuments = true; 2700b57cec5SDimitry Andric } else { 2710b57cec5SDimitry Andric // Create an new, empty module. 2728bcb0991SDimitry Andric M = std::make_unique<Module>(Filename, Context); 273bdd1243dSDimitry Andric if (auto LayoutOverride = 274bdd1243dSDimitry Andric DataLayoutCallback(M->getTargetTriple(), M->getDataLayoutStr())) 2755ffd83dbSDimitry Andric M->setDataLayout(*LayoutOverride); 2760b57cec5SDimitry Andric NoLLVMIR = true; 2770b57cec5SDimitry Andric } 2780b57cec5SDimitry Andric return M; 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric 281*0fca6ea1SDimitry Andric bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI, 282*0fca6ea1SDimitry Andric ModuleAnalysisManager *MAM) { 2830b57cec5SDimitry Andric if (NoMIRDocuments) 2840b57cec5SDimitry Andric return false; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric // Parse the machine functions. 2870b57cec5SDimitry Andric do { 288*0fca6ea1SDimitry Andric if (parseMachineFunction(M, MMI, MAM)) 2890b57cec5SDimitry Andric return true; 2900b57cec5SDimitry Andric In.nextDocument(); 2910b57cec5SDimitry Andric } while (In.setCurrentDocument()); 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric return false; 2940b57cec5SDimitry Andric } 2950b57cec5SDimitry Andric 296480093f4SDimitry Andric Function *MIRParserImpl::createDummyFunction(StringRef Name, Module &M) { 2970b57cec5SDimitry Andric auto &Context = M.getContext(); 2980b57cec5SDimitry Andric Function *F = 2990b57cec5SDimitry Andric Function::Create(FunctionType::get(Type::getVoidTy(Context), false), 3000b57cec5SDimitry Andric Function::ExternalLinkage, Name, M); 3010b57cec5SDimitry Andric BasicBlock *BB = BasicBlock::Create(Context, "entry", F); 3020b57cec5SDimitry Andric new UnreachableInst(Context, BB); 303480093f4SDimitry Andric 304480093f4SDimitry Andric if (ProcessIRFunction) 305480093f4SDimitry Andric ProcessIRFunction(*F); 306480093f4SDimitry Andric 3070b57cec5SDimitry Andric return F; 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric 310*0fca6ea1SDimitry Andric bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI, 311*0fca6ea1SDimitry Andric ModuleAnalysisManager *MAM) { 3120b57cec5SDimitry Andric // Parse the yaml. 3130b57cec5SDimitry Andric yaml::MachineFunction YamlMF; 3140b57cec5SDimitry Andric yaml::EmptyContext Ctx; 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric const LLVMTargetMachine &TM = MMI.getTarget(); 3170b57cec5SDimitry Andric YamlMF.MachineFuncInfo = std::unique_ptr<yaml::MachineFunctionInfo>( 3180b57cec5SDimitry Andric TM.createDefaultFuncInfoYAML()); 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric yaml::yamlize(In, YamlMF, false, Ctx); 3210b57cec5SDimitry Andric if (In.error()) 3220b57cec5SDimitry Andric return true; 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric // Search for the corresponding IR function. 3250b57cec5SDimitry Andric StringRef FunctionName = YamlMF.Name; 3260b57cec5SDimitry Andric Function *F = M.getFunction(FunctionName); 3270b57cec5SDimitry Andric if (!F) { 3280b57cec5SDimitry Andric if (NoLLVMIR) { 3290b57cec5SDimitry Andric F = createDummyFunction(FunctionName, M); 3300b57cec5SDimitry Andric } else { 3310b57cec5SDimitry Andric return error(Twine("function '") + FunctionName + 3320b57cec5SDimitry Andric "' isn't defined in the provided LLVM IR"); 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric } 335*0fca6ea1SDimitry Andric 336*0fca6ea1SDimitry Andric if (!MAM) { 3370b57cec5SDimitry Andric if (MMI.getMachineFunction(*F) != nullptr) 3380b57cec5SDimitry Andric return error(Twine("redefinition of machine function '") + FunctionName + 3390b57cec5SDimitry Andric "'"); 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric // Create the MachineFunction. 3420b57cec5SDimitry Andric MachineFunction &MF = MMI.getOrCreateMachineFunction(*F); 3430b57cec5SDimitry Andric if (initializeMachineFunction(YamlMF, MF)) 3440b57cec5SDimitry Andric return true; 345*0fca6ea1SDimitry Andric } else { 346*0fca6ea1SDimitry Andric auto &FAM = 347*0fca6ea1SDimitry Andric MAM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); 348*0fca6ea1SDimitry Andric if (FAM.getCachedResult<MachineFunctionAnalysis>(*F)) 349*0fca6ea1SDimitry Andric return error(Twine("redefinition of machine function '") + FunctionName + 350*0fca6ea1SDimitry Andric "'"); 351*0fca6ea1SDimitry Andric 352*0fca6ea1SDimitry Andric // Create the MachineFunction. 353*0fca6ea1SDimitry Andric MachineFunction &MF = FAM.getResult<MachineFunctionAnalysis>(*F).getMF(); 354*0fca6ea1SDimitry Andric if (initializeMachineFunction(YamlMF, MF)) 355*0fca6ea1SDimitry Andric return true; 356*0fca6ea1SDimitry Andric } 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric return false; 3590b57cec5SDimitry Andric } 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric static bool isSSA(const MachineFunction &MF) { 3620b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo(); 3630b57cec5SDimitry Andric for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { 364e8d8bef9SDimitry Andric Register Reg = Register::index2VirtReg(I); 3650b57cec5SDimitry Andric if (!MRI.hasOneDef(Reg) && !MRI.def_empty(Reg)) 3660b57cec5SDimitry Andric return false; 367e8d8bef9SDimitry Andric 368e8d8bef9SDimitry Andric // Subregister defs are invalid in SSA. 369e8d8bef9SDimitry Andric const MachineOperand *RegDef = MRI.getOneDef(Reg); 370e8d8bef9SDimitry Andric if (RegDef && RegDef->getSubReg() != 0) 371e8d8bef9SDimitry Andric return false; 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric return true; 3740b57cec5SDimitry Andric } 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric void MIRParserImpl::computeFunctionProperties(MachineFunction &MF) { 3770b57cec5SDimitry Andric MachineFunctionProperties &Properties = MF.getProperties(); 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric bool HasPHI = false; 3800b57cec5SDimitry Andric bool HasInlineAsm = false; 3810eae32dcSDimitry Andric bool AllTiedOpsRewritten = true, HasTiedOps = false; 3820b57cec5SDimitry Andric for (const MachineBasicBlock &MBB : MF) { 3830b57cec5SDimitry Andric for (const MachineInstr &MI : MBB) { 3840b57cec5SDimitry Andric if (MI.isPHI()) 3850b57cec5SDimitry Andric HasPHI = true; 3860b57cec5SDimitry Andric if (MI.isInlineAsm()) 3870b57cec5SDimitry Andric HasInlineAsm = true; 3880eae32dcSDimitry Andric for (unsigned I = 0; I < MI.getNumOperands(); ++I) { 3890eae32dcSDimitry Andric const MachineOperand &MO = MI.getOperand(I); 3900eae32dcSDimitry Andric if (!MO.isReg() || !MO.getReg()) 3910eae32dcSDimitry Andric continue; 3920eae32dcSDimitry Andric unsigned DefIdx; 3930eae32dcSDimitry Andric if (MO.isUse() && MI.isRegTiedToDefOperand(I, &DefIdx)) { 3940eae32dcSDimitry Andric HasTiedOps = true; 3950eae32dcSDimitry Andric if (MO.getReg() != MI.getOperand(DefIdx).getReg()) 3960eae32dcSDimitry Andric AllTiedOpsRewritten = false; 3970eae32dcSDimitry Andric } 3980eae32dcSDimitry Andric } 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric } 4010b57cec5SDimitry Andric if (!HasPHI) 4020b57cec5SDimitry Andric Properties.set(MachineFunctionProperties::Property::NoPHIs); 4030b57cec5SDimitry Andric MF.setHasInlineAsm(HasInlineAsm); 4040b57cec5SDimitry Andric 4050eae32dcSDimitry Andric if (HasTiedOps && AllTiedOpsRewritten) 4060eae32dcSDimitry Andric Properties.set(MachineFunctionProperties::Property::TiedOpsRewritten); 4070eae32dcSDimitry Andric 4080b57cec5SDimitry Andric if (isSSA(MF)) 4090b57cec5SDimitry Andric Properties.set(MachineFunctionProperties::Property::IsSSA); 4100b57cec5SDimitry Andric else 4110b57cec5SDimitry Andric Properties.reset(MachineFunctionProperties::Property::IsSSA); 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo(); 4140b57cec5SDimitry Andric if (MRI.getNumVirtRegs() == 0) 4150b57cec5SDimitry Andric Properties.set(MachineFunctionProperties::Property::NoVRegs); 4160b57cec5SDimitry Andric } 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric bool MIRParserImpl::initializeCallSiteInfo( 4190b57cec5SDimitry Andric PerFunctionMIParsingState &PFS, const yaml::MachineFunction &YamlMF) { 4200b57cec5SDimitry Andric MachineFunction &MF = PFS.MF; 4210b57cec5SDimitry Andric SMDiagnostic Error; 4220b57cec5SDimitry Andric const LLVMTargetMachine &TM = MF.getTarget(); 42306c3fb27SDimitry Andric for (auto &YamlCSInfo : YamlMF.CallSitesInfo) { 4240b57cec5SDimitry Andric yaml::CallSiteInfo::MachineInstrLoc MILoc = YamlCSInfo.CallLocation; 4250b57cec5SDimitry Andric if (MILoc.BlockNum >= MF.size()) 4260b57cec5SDimitry Andric return error(Twine(MF.getName()) + 4270b57cec5SDimitry Andric Twine(" call instruction block out of range.") + 4280b57cec5SDimitry Andric " Unable to reference bb:" + Twine(MILoc.BlockNum)); 4290b57cec5SDimitry Andric auto CallB = std::next(MF.begin(), MILoc.BlockNum); 4300b57cec5SDimitry Andric if (MILoc.Offset >= CallB->size()) 4310b57cec5SDimitry Andric return error(Twine(MF.getName()) + 4320b57cec5SDimitry Andric Twine(" call instruction offset out of range.") + 4330b57cec5SDimitry Andric " Unable to reference instruction at bb: " + 4340b57cec5SDimitry Andric Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset)); 4358bcb0991SDimitry Andric auto CallI = std::next(CallB->instr_begin(), MILoc.Offset); 4368bcb0991SDimitry Andric if (!CallI->isCall(MachineInstr::IgnoreBundle)) 4370b57cec5SDimitry Andric return error(Twine(MF.getName()) + 4380b57cec5SDimitry Andric Twine(" call site info should reference call " 4390b57cec5SDimitry Andric "instruction. Instruction at bb:") + 4400b57cec5SDimitry Andric Twine(MILoc.BlockNum) + " at offset:" + Twine(MILoc.Offset) + 4410b57cec5SDimitry Andric " is not a call instruction"); 4420b57cec5SDimitry Andric MachineFunction::CallSiteInfo CSInfo; 4430b57cec5SDimitry Andric for (auto ArgRegPair : YamlCSInfo.ArgForwardingRegs) { 4445ffd83dbSDimitry Andric Register Reg; 4450b57cec5SDimitry Andric if (parseNamedRegisterReference(PFS, Reg, ArgRegPair.Reg.Value, Error)) 4460b57cec5SDimitry Andric return error(Error, ArgRegPair.Reg.SourceRange); 447*0fca6ea1SDimitry Andric CSInfo.ArgRegPairs.emplace_back(Reg, ArgRegPair.ArgNo); 4480b57cec5SDimitry Andric } 4490b57cec5SDimitry Andric 4505ffd83dbSDimitry Andric if (TM.Options.EmitCallSiteInfo) 451*0fca6ea1SDimitry Andric MF.addCallSiteInfo(&*CallI, std::move(CSInfo)); 4520b57cec5SDimitry Andric } 4530b57cec5SDimitry Andric 4545ffd83dbSDimitry Andric if (YamlMF.CallSitesInfo.size() && !TM.Options.EmitCallSiteInfo) 4550b57cec5SDimitry Andric return error(Twine("Call site info provided but not used")); 4560b57cec5SDimitry Andric return false; 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric 459e8d8bef9SDimitry Andric void MIRParserImpl::setupDebugValueTracking( 460e8d8bef9SDimitry Andric MachineFunction &MF, PerFunctionMIParsingState &PFS, 461e8d8bef9SDimitry Andric const yaml::MachineFunction &YamlMF) { 462e8d8bef9SDimitry Andric // Compute the value of the "next instruction number" field. 463e8d8bef9SDimitry Andric unsigned MaxInstrNum = 0; 464e8d8bef9SDimitry Andric for (auto &MBB : MF) 465e8d8bef9SDimitry Andric for (auto &MI : MBB) 466e8d8bef9SDimitry Andric MaxInstrNum = std::max((unsigned)MI.peekDebugInstrNum(), MaxInstrNum); 467e8d8bef9SDimitry Andric MF.setDebugInstrNumberingCount(MaxInstrNum); 468e8d8bef9SDimitry Andric 469e8d8bef9SDimitry Andric // Load any substitutions. 470fcaf7f86SDimitry Andric for (const auto &Sub : YamlMF.DebugValueSubstitutions) { 471fe6060f1SDimitry Andric MF.makeDebugValueSubstitution({Sub.SrcInst, Sub.SrcOp}, 472fe6060f1SDimitry Andric {Sub.DstInst, Sub.DstOp}, Sub.Subreg); 473e8d8bef9SDimitry Andric } 474bdd1243dSDimitry Andric 475bdd1243dSDimitry Andric // Flag for whether we're supposed to be using DBG_INSTR_REF. 476bdd1243dSDimitry Andric MF.setUseDebugInstrRef(YamlMF.UseDebugInstrRef); 477e8d8bef9SDimitry Andric } 478e8d8bef9SDimitry Andric 4790b57cec5SDimitry Andric bool 4800b57cec5SDimitry Andric MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF, 4810b57cec5SDimitry Andric MachineFunction &MF) { 4820b57cec5SDimitry Andric // TODO: Recreate the machine function. 4830b57cec5SDimitry Andric if (Target) { 4840b57cec5SDimitry Andric // Avoid clearing state if we're using the same subtarget again. 4850b57cec5SDimitry Andric Target->setTarget(MF.getSubtarget()); 4860b57cec5SDimitry Andric } else { 4870b57cec5SDimitry Andric Target.reset(new PerTargetMIParsingState(MF.getSubtarget())); 4880b57cec5SDimitry Andric } 4890b57cec5SDimitry Andric 4905ffd83dbSDimitry Andric MF.setAlignment(YamlMF.Alignment.valueOrOne()); 4910b57cec5SDimitry Andric MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice); 4920b57cec5SDimitry Andric MF.setHasWinCFI(YamlMF.HasWinCFI); 4930b57cec5SDimitry Andric 49481ad6265SDimitry Andric MF.setCallsEHReturn(YamlMF.CallsEHReturn); 49581ad6265SDimitry Andric MF.setCallsUnwindInit(YamlMF.CallsUnwindInit); 49681ad6265SDimitry Andric MF.setHasEHCatchret(YamlMF.HasEHCatchret); 49781ad6265SDimitry Andric MF.setHasEHScopes(YamlMF.HasEHScopes); 49881ad6265SDimitry Andric MF.setHasEHFunclets(YamlMF.HasEHFunclets); 49906c3fb27SDimitry Andric MF.setIsOutlined(YamlMF.IsOutlined); 50081ad6265SDimitry Andric 5010b57cec5SDimitry Andric if (YamlMF.Legalized) 5020b57cec5SDimitry Andric MF.getProperties().set(MachineFunctionProperties::Property::Legalized); 5030b57cec5SDimitry Andric if (YamlMF.RegBankSelected) 5040b57cec5SDimitry Andric MF.getProperties().set( 5050b57cec5SDimitry Andric MachineFunctionProperties::Property::RegBankSelected); 5060b57cec5SDimitry Andric if (YamlMF.Selected) 5070b57cec5SDimitry Andric MF.getProperties().set(MachineFunctionProperties::Property::Selected); 5080b57cec5SDimitry Andric if (YamlMF.FailedISel) 5090b57cec5SDimitry Andric MF.getProperties().set(MachineFunctionProperties::Property::FailedISel); 510349cc55cSDimitry Andric if (YamlMF.FailsVerification) 511349cc55cSDimitry Andric MF.getProperties().set( 512349cc55cSDimitry Andric MachineFunctionProperties::Property::FailsVerification); 5130eae32dcSDimitry Andric if (YamlMF.TracksDebugUserValues) 5140eae32dcSDimitry Andric MF.getProperties().set( 5150eae32dcSDimitry Andric MachineFunctionProperties::Property::TracksDebugUserValues); 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric PerFunctionMIParsingState PFS(MF, SM, IRSlots, *Target); 5180b57cec5SDimitry Andric if (parseRegisterInfo(PFS, YamlMF)) 5190b57cec5SDimitry Andric return true; 5200b57cec5SDimitry Andric if (!YamlMF.Constants.empty()) { 5210b57cec5SDimitry Andric auto *ConstantPool = MF.getConstantPool(); 5220b57cec5SDimitry Andric assert(ConstantPool && "Constant pool must be created"); 5230b57cec5SDimitry Andric if (initializeConstantPool(PFS, *ConstantPool, YamlMF)) 5240b57cec5SDimitry Andric return true; 5250b57cec5SDimitry Andric } 526fe6060f1SDimitry Andric if (!YamlMF.MachineMetadataNodes.empty() && 527fe6060f1SDimitry Andric parseMachineMetadataNodes(PFS, MF, YamlMF)) 528fe6060f1SDimitry Andric return true; 5290b57cec5SDimitry Andric 5300b57cec5SDimitry Andric StringRef BlockStr = YamlMF.Body.Value.Value; 5310b57cec5SDimitry Andric SMDiagnostic Error; 5320b57cec5SDimitry Andric SourceMgr BlockSM; 5330b57cec5SDimitry Andric BlockSM.AddNewSourceBuffer( 5340b57cec5SDimitry Andric MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false), 5350b57cec5SDimitry Andric SMLoc()); 5360b57cec5SDimitry Andric PFS.SM = &BlockSM; 5370b57cec5SDimitry Andric if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)) { 5380b57cec5SDimitry Andric reportDiagnostic( 5390b57cec5SDimitry Andric diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange)); 5400b57cec5SDimitry Andric return true; 5410b57cec5SDimitry Andric } 5425ffd83dbSDimitry Andric // Check Basic Block Section Flags. 5435ffd83dbSDimitry Andric if (MF.getTarget().getBBSectionsType() == BasicBlockSection::Labels) { 5445ffd83dbSDimitry Andric MF.setBBSectionsType(BasicBlockSection::Labels); 5455ffd83dbSDimitry Andric } else if (MF.hasBBSections()) { 5465ffd83dbSDimitry Andric MF.assignBeginEndSections(); 5475ffd83dbSDimitry Andric } 5480b57cec5SDimitry Andric PFS.SM = &SM; 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric // Initialize the frame information after creating all the MBBs so that the 5510b57cec5SDimitry Andric // MBB references in the frame information can be resolved. 5520b57cec5SDimitry Andric if (initializeFrameInfo(PFS, YamlMF)) 5530b57cec5SDimitry Andric return true; 5540b57cec5SDimitry Andric // Initialize the jump table after creating all the MBBs so that the MBB 5550b57cec5SDimitry Andric // references can be resolved. 5560b57cec5SDimitry Andric if (!YamlMF.JumpTableInfo.Entries.empty() && 5570b57cec5SDimitry Andric initializeJumpTableInfo(PFS, YamlMF.JumpTableInfo)) 5580b57cec5SDimitry Andric return true; 5590b57cec5SDimitry Andric // Parse the machine instructions after creating all of the MBBs so that the 5600b57cec5SDimitry Andric // parser can resolve the MBB references. 5610b57cec5SDimitry Andric StringRef InsnStr = YamlMF.Body.Value.Value; 5620b57cec5SDimitry Andric SourceMgr InsnSM; 5630b57cec5SDimitry Andric InsnSM.AddNewSourceBuffer( 5640b57cec5SDimitry Andric MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false), 5650b57cec5SDimitry Andric SMLoc()); 5660b57cec5SDimitry Andric PFS.SM = &InsnSM; 5670b57cec5SDimitry Andric if (parseMachineInstructions(PFS, InsnStr, Error)) { 5680b57cec5SDimitry Andric reportDiagnostic( 5690b57cec5SDimitry Andric diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange)); 5700b57cec5SDimitry Andric return true; 5710b57cec5SDimitry Andric } 5720b57cec5SDimitry Andric PFS.SM = &SM; 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric if (setupRegisterInfo(PFS, YamlMF)) 5750b57cec5SDimitry Andric return true; 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric if (YamlMF.MachineFuncInfo) { 5780b57cec5SDimitry Andric const LLVMTargetMachine &TM = MF.getTarget(); 5790b57cec5SDimitry Andric // Note this is called after the initial constructor of the 5800b57cec5SDimitry Andric // MachineFunctionInfo based on the MachineFunction, which may depend on the 5810b57cec5SDimitry Andric // IR. 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric SMRange SrcRange; 5840b57cec5SDimitry Andric if (TM.parseMachineFunctionInfo(*YamlMF.MachineFuncInfo, PFS, Error, 5850b57cec5SDimitry Andric SrcRange)) { 5860b57cec5SDimitry Andric return error(Error, SrcRange); 5870b57cec5SDimitry Andric } 5880b57cec5SDimitry Andric } 5890b57cec5SDimitry Andric 5900b57cec5SDimitry Andric // Set the reserved registers after parsing MachineFuncInfo. The target may 5910b57cec5SDimitry Andric // have been recording information used to select the reserved registers 5920b57cec5SDimitry Andric // there. 5930b57cec5SDimitry Andric // FIXME: This is a temporary workaround until the reserved registers can be 5940b57cec5SDimitry Andric // serialized. 5950b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo(); 596*0fca6ea1SDimitry Andric MRI.freezeReservedRegs(); 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric computeFunctionProperties(MF); 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andric if (initializeCallSiteInfo(PFS, YamlMF)) 6010b57cec5SDimitry Andric return false; 6020b57cec5SDimitry Andric 603e8d8bef9SDimitry Andric setupDebugValueTracking(MF, PFS, YamlMF); 604e8d8bef9SDimitry Andric 6050b57cec5SDimitry Andric MF.getSubtarget().mirFileLoaded(MF); 6060b57cec5SDimitry Andric 6070b57cec5SDimitry Andric MF.verify(); 6080b57cec5SDimitry Andric return false; 6090b57cec5SDimitry Andric } 6100b57cec5SDimitry Andric 6110b57cec5SDimitry Andric bool MIRParserImpl::parseRegisterInfo(PerFunctionMIParsingState &PFS, 6120b57cec5SDimitry Andric const yaml::MachineFunction &YamlMF) { 6130b57cec5SDimitry Andric MachineFunction &MF = PFS.MF; 6140b57cec5SDimitry Andric MachineRegisterInfo &RegInfo = MF.getRegInfo(); 6150b57cec5SDimitry Andric assert(RegInfo.tracksLiveness()); 6160b57cec5SDimitry Andric if (!YamlMF.TracksRegLiveness) 6170b57cec5SDimitry Andric RegInfo.invalidateLiveness(); 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric SMDiagnostic Error; 6200b57cec5SDimitry Andric // Parse the virtual register information. 6210b57cec5SDimitry Andric for (const auto &VReg : YamlMF.VirtualRegisters) { 6220b57cec5SDimitry Andric VRegInfo &Info = PFS.getVRegInfo(VReg.ID.Value); 6230b57cec5SDimitry Andric if (Info.Explicit) 6240b57cec5SDimitry Andric return error(VReg.ID.SourceRange.Start, 6250b57cec5SDimitry Andric Twine("redefinition of virtual register '%") + 6260b57cec5SDimitry Andric Twine(VReg.ID.Value) + "'"); 6270b57cec5SDimitry Andric Info.Explicit = true; 6280b57cec5SDimitry Andric 629*0fca6ea1SDimitry Andric if (VReg.Class.Value == "_") { 6300b57cec5SDimitry Andric Info.Kind = VRegInfo::GENERIC; 6310b57cec5SDimitry Andric Info.D.RegBank = nullptr; 6320b57cec5SDimitry Andric } else { 6330b57cec5SDimitry Andric const auto *RC = Target->getRegClass(VReg.Class.Value); 6340b57cec5SDimitry Andric if (RC) { 6350b57cec5SDimitry Andric Info.Kind = VRegInfo::NORMAL; 6360b57cec5SDimitry Andric Info.D.RC = RC; 6370b57cec5SDimitry Andric } else { 6380b57cec5SDimitry Andric const RegisterBank *RegBank = Target->getRegBank(VReg.Class.Value); 6390b57cec5SDimitry Andric if (!RegBank) 6400b57cec5SDimitry Andric return error( 6410b57cec5SDimitry Andric VReg.Class.SourceRange.Start, 6420b57cec5SDimitry Andric Twine("use of undefined register class or register bank '") + 6430b57cec5SDimitry Andric VReg.Class.Value + "'"); 6440b57cec5SDimitry Andric Info.Kind = VRegInfo::REGBANK; 6450b57cec5SDimitry Andric Info.D.RegBank = RegBank; 6460b57cec5SDimitry Andric } 6470b57cec5SDimitry Andric } 6480b57cec5SDimitry Andric 6490b57cec5SDimitry Andric if (!VReg.PreferredRegister.Value.empty()) { 6500b57cec5SDimitry Andric if (Info.Kind != VRegInfo::NORMAL) 6510b57cec5SDimitry Andric return error(VReg.Class.SourceRange.Start, 6520b57cec5SDimitry Andric Twine("preferred register can only be set for normal vregs")); 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric if (parseRegisterReference(PFS, Info.PreferredReg, 6550b57cec5SDimitry Andric VReg.PreferredRegister.Value, Error)) 6560b57cec5SDimitry Andric return error(Error, VReg.PreferredRegister.SourceRange); 6570b57cec5SDimitry Andric } 6580b57cec5SDimitry Andric } 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andric // Parse the liveins. 6610b57cec5SDimitry Andric for (const auto &LiveIn : YamlMF.LiveIns) { 6625ffd83dbSDimitry Andric Register Reg; 6630b57cec5SDimitry Andric if (parseNamedRegisterReference(PFS, Reg, LiveIn.Register.Value, Error)) 6640b57cec5SDimitry Andric return error(Error, LiveIn.Register.SourceRange); 6655ffd83dbSDimitry Andric Register VReg; 6660b57cec5SDimitry Andric if (!LiveIn.VirtualRegister.Value.empty()) { 6670b57cec5SDimitry Andric VRegInfo *Info; 6680b57cec5SDimitry Andric if (parseVirtualRegisterReference(PFS, Info, LiveIn.VirtualRegister.Value, 6690b57cec5SDimitry Andric Error)) 6700b57cec5SDimitry Andric return error(Error, LiveIn.VirtualRegister.SourceRange); 6710b57cec5SDimitry Andric VReg = Info->VReg; 6720b57cec5SDimitry Andric } 6730b57cec5SDimitry Andric RegInfo.addLiveIn(Reg, VReg); 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric // Parse the callee saved registers (Registers that will 6770b57cec5SDimitry Andric // be saved for the caller). 6780b57cec5SDimitry Andric if (YamlMF.CalleeSavedRegisters) { 6790b57cec5SDimitry Andric SmallVector<MCPhysReg, 16> CalleeSavedRegisters; 68081ad6265SDimitry Andric for (const auto &RegSource : *YamlMF.CalleeSavedRegisters) { 6815ffd83dbSDimitry Andric Register Reg; 6820b57cec5SDimitry Andric if (parseNamedRegisterReference(PFS, Reg, RegSource.Value, Error)) 6830b57cec5SDimitry Andric return error(Error, RegSource.SourceRange); 6840b57cec5SDimitry Andric CalleeSavedRegisters.push_back(Reg); 6850b57cec5SDimitry Andric } 6860b57cec5SDimitry Andric RegInfo.setCalleeSavedRegs(CalleeSavedRegisters); 6870b57cec5SDimitry Andric } 6880b57cec5SDimitry Andric 6890b57cec5SDimitry Andric return false; 6900b57cec5SDimitry Andric } 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric bool MIRParserImpl::setupRegisterInfo(const PerFunctionMIParsingState &PFS, 6930b57cec5SDimitry Andric const yaml::MachineFunction &YamlMF) { 6940b57cec5SDimitry Andric MachineFunction &MF = PFS.MF; 6950b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo(); 696bdd1243dSDimitry Andric const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 697bdd1243dSDimitry Andric 6980b57cec5SDimitry Andric bool Error = false; 6990b57cec5SDimitry Andric // Create VRegs 7000b57cec5SDimitry Andric auto populateVRegInfo = [&](const VRegInfo &Info, Twine Name) { 7015ffd83dbSDimitry Andric Register Reg = Info.VReg; 7020b57cec5SDimitry Andric switch (Info.Kind) { 7030b57cec5SDimitry Andric case VRegInfo::UNKNOWN: 7040b57cec5SDimitry Andric error(Twine("Cannot determine class/bank of virtual register ") + 7050b57cec5SDimitry Andric Name + " in function '" + MF.getName() + "'"); 7060b57cec5SDimitry Andric Error = true; 7070b57cec5SDimitry Andric break; 7080b57cec5SDimitry Andric case VRegInfo::NORMAL: 709bdd1243dSDimitry Andric if (!Info.D.RC->isAllocatable()) { 710bdd1243dSDimitry Andric error(Twine("Cannot use non-allocatable class '") + 711bdd1243dSDimitry Andric TRI->getRegClassName(Info.D.RC) + "' for virtual register " + 712bdd1243dSDimitry Andric Name + " in function '" + MF.getName() + "'"); 713bdd1243dSDimitry Andric Error = true; 714bdd1243dSDimitry Andric break; 715bdd1243dSDimitry Andric } 716bdd1243dSDimitry Andric 7170b57cec5SDimitry Andric MRI.setRegClass(Reg, Info.D.RC); 7180b57cec5SDimitry Andric if (Info.PreferredReg != 0) 7190b57cec5SDimitry Andric MRI.setSimpleHint(Reg, Info.PreferredReg); 7200b57cec5SDimitry Andric break; 7210b57cec5SDimitry Andric case VRegInfo::GENERIC: 7220b57cec5SDimitry Andric break; 7230b57cec5SDimitry Andric case VRegInfo::REGBANK: 7240b57cec5SDimitry Andric MRI.setRegBank(Reg, *Info.D.RegBank); 7250b57cec5SDimitry Andric break; 7260b57cec5SDimitry Andric } 7270b57cec5SDimitry Andric }; 7280b57cec5SDimitry Andric 729fe6060f1SDimitry Andric for (const auto &P : PFS.VRegInfosNamed) { 730fe6060f1SDimitry Andric const VRegInfo &Info = *P.second; 731fe6060f1SDimitry Andric populateVRegInfo(Info, Twine(P.first())); 7320b57cec5SDimitry Andric } 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric for (auto P : PFS.VRegInfos) { 7350b57cec5SDimitry Andric const VRegInfo &Info = *P.second; 7360b57cec5SDimitry Andric populateVRegInfo(Info, Twine(P.first)); 7370b57cec5SDimitry Andric } 7380b57cec5SDimitry Andric 7390b57cec5SDimitry Andric // Compute MachineRegisterInfo::UsedPhysRegMask 7400b57cec5SDimitry Andric for (const MachineBasicBlock &MBB : MF) { 741e8d8bef9SDimitry Andric // Make sure MRI knows about registers clobbered by unwinder. 742e8d8bef9SDimitry Andric if (MBB.isEHPad()) 743e8d8bef9SDimitry Andric if (auto *RegMask = TRI->getCustomEHPadPreservedMask(MF)) 744e8d8bef9SDimitry Andric MRI.addPhysRegsUsedFromRegMask(RegMask); 745e8d8bef9SDimitry Andric 7460b57cec5SDimitry Andric for (const MachineInstr &MI : MBB) { 7470b57cec5SDimitry Andric for (const MachineOperand &MO : MI.operands()) { 7480b57cec5SDimitry Andric if (!MO.isRegMask()) 7490b57cec5SDimitry Andric continue; 7500b57cec5SDimitry Andric MRI.addPhysRegsUsedFromRegMask(MO.getRegMask()); 7510b57cec5SDimitry Andric } 7520b57cec5SDimitry Andric } 7530b57cec5SDimitry Andric } 7540b57cec5SDimitry Andric 7550b57cec5SDimitry Andric return Error; 7560b57cec5SDimitry Andric } 7570b57cec5SDimitry Andric 7580b57cec5SDimitry Andric bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS, 7590b57cec5SDimitry Andric const yaml::MachineFunction &YamlMF) { 7600b57cec5SDimitry Andric MachineFunction &MF = PFS.MF; 7610b57cec5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo(); 7620b57cec5SDimitry Andric const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); 7630b57cec5SDimitry Andric const Function &F = MF.getFunction(); 7640b57cec5SDimitry Andric const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo; 7650b57cec5SDimitry Andric MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken); 7660b57cec5SDimitry Andric MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken); 7670b57cec5SDimitry Andric MFI.setHasStackMap(YamlMFI.HasStackMap); 7680b57cec5SDimitry Andric MFI.setHasPatchPoint(YamlMFI.HasPatchPoint); 7690b57cec5SDimitry Andric MFI.setStackSize(YamlMFI.StackSize); 7700b57cec5SDimitry Andric MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment); 7710b57cec5SDimitry Andric if (YamlMFI.MaxAlignment) 7725ffd83dbSDimitry Andric MFI.ensureMaxAlignment(Align(YamlMFI.MaxAlignment)); 7730b57cec5SDimitry Andric MFI.setAdjustsStack(YamlMFI.AdjustsStack); 7740b57cec5SDimitry Andric MFI.setHasCalls(YamlMFI.HasCalls); 7750b57cec5SDimitry Andric if (YamlMFI.MaxCallFrameSize != ~0u) 7760b57cec5SDimitry Andric MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize); 7770b57cec5SDimitry Andric MFI.setCVBytesOfCalleeSavedRegisters(YamlMFI.CVBytesOfCalleeSavedRegisters); 7780b57cec5SDimitry Andric MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment); 7790b57cec5SDimitry Andric MFI.setHasVAStart(YamlMFI.HasVAStart); 7800b57cec5SDimitry Andric MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc); 781fe6060f1SDimitry Andric MFI.setHasTailCall(YamlMFI.HasTailCall); 782*0fca6ea1SDimitry Andric MFI.setCalleeSavedInfoValid(YamlMFI.IsCalleeSavedInfoValid); 7830b57cec5SDimitry Andric MFI.setLocalFrameSize(YamlMFI.LocalFrameSize); 7840b57cec5SDimitry Andric if (!YamlMFI.SavePoint.Value.empty()) { 7850b57cec5SDimitry Andric MachineBasicBlock *MBB = nullptr; 7860b57cec5SDimitry Andric if (parseMBBReference(PFS, MBB, YamlMFI.SavePoint)) 7870b57cec5SDimitry Andric return true; 7880b57cec5SDimitry Andric MFI.setSavePoint(MBB); 7890b57cec5SDimitry Andric } 7900b57cec5SDimitry Andric if (!YamlMFI.RestorePoint.Value.empty()) { 7910b57cec5SDimitry Andric MachineBasicBlock *MBB = nullptr; 7920b57cec5SDimitry Andric if (parseMBBReference(PFS, MBB, YamlMFI.RestorePoint)) 7930b57cec5SDimitry Andric return true; 7940b57cec5SDimitry Andric MFI.setRestorePoint(MBB); 7950b57cec5SDimitry Andric } 7960b57cec5SDimitry Andric 7970b57cec5SDimitry Andric std::vector<CalleeSavedInfo> CSIInfo; 7980b57cec5SDimitry Andric // Initialize the fixed frame objects. 7990b57cec5SDimitry Andric for (const auto &Object : YamlMF.FixedStackObjects) { 8000b57cec5SDimitry Andric int ObjectIdx; 8010b57cec5SDimitry Andric if (Object.Type != yaml::FixedMachineStackObject::SpillSlot) 8020b57cec5SDimitry Andric ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset, 8030b57cec5SDimitry Andric Object.IsImmutable, Object.IsAliased); 8040b57cec5SDimitry Andric else 8050b57cec5SDimitry Andric ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset); 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric if (!TFI->isSupportedStackID(Object.StackID)) 8080b57cec5SDimitry Andric return error(Object.ID.SourceRange.Start, 8090b57cec5SDimitry Andric Twine("StackID is not supported by target")); 8100b57cec5SDimitry Andric MFI.setStackID(ObjectIdx, Object.StackID); 8115ffd83dbSDimitry Andric MFI.setObjectAlignment(ObjectIdx, Object.Alignment.valueOrOne()); 8120b57cec5SDimitry Andric if (!PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID.Value, 8130b57cec5SDimitry Andric ObjectIdx)) 8140b57cec5SDimitry Andric .second) 8150b57cec5SDimitry Andric return error(Object.ID.SourceRange.Start, 8160b57cec5SDimitry Andric Twine("redefinition of fixed stack object '%fixed-stack.") + 8170b57cec5SDimitry Andric Twine(Object.ID.Value) + "'"); 8180b57cec5SDimitry Andric if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister, 8190b57cec5SDimitry Andric Object.CalleeSavedRestored, ObjectIdx)) 8200b57cec5SDimitry Andric return true; 8210b57cec5SDimitry Andric if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx)) 8220b57cec5SDimitry Andric return true; 8230b57cec5SDimitry Andric } 8240b57cec5SDimitry Andric 82506c3fb27SDimitry Andric for (const auto &Object : YamlMF.EntryValueObjects) { 82606c3fb27SDimitry Andric SMDiagnostic Error; 82706c3fb27SDimitry Andric Register Reg; 82806c3fb27SDimitry Andric if (parseNamedRegisterReference(PFS, Reg, Object.EntryValueRegister.Value, 82906c3fb27SDimitry Andric Error)) 83006c3fb27SDimitry Andric return error(Error, Object.EntryValueRegister.SourceRange); 83106c3fb27SDimitry Andric if (!Reg.isPhysical()) 83206c3fb27SDimitry Andric return error(Object.EntryValueRegister.SourceRange.Start, 83306c3fb27SDimitry Andric "Expected physical register for entry value field"); 83406c3fb27SDimitry Andric std::optional<VarExprLoc> MaybeInfo = parseVarExprLoc( 83506c3fb27SDimitry Andric PFS, Object.DebugVar, Object.DebugExpr, Object.DebugLoc); 83606c3fb27SDimitry Andric if (!MaybeInfo) 83706c3fb27SDimitry Andric return true; 83806c3fb27SDimitry Andric if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc) 83906c3fb27SDimitry Andric PFS.MF.setVariableDbgInfo(MaybeInfo->DIVar, MaybeInfo->DIExpr, 84006c3fb27SDimitry Andric Reg.asMCReg(), MaybeInfo->DILoc); 84106c3fb27SDimitry Andric } 84206c3fb27SDimitry Andric 8430b57cec5SDimitry Andric // Initialize the ordinary frame objects. 8440b57cec5SDimitry Andric for (const auto &Object : YamlMF.StackObjects) { 8450b57cec5SDimitry Andric int ObjectIdx; 8460b57cec5SDimitry Andric const AllocaInst *Alloca = nullptr; 8470b57cec5SDimitry Andric const yaml::StringValue &Name = Object.Name; 8480b57cec5SDimitry Andric if (!Name.Value.empty()) { 8490b57cec5SDimitry Andric Alloca = dyn_cast_or_null<AllocaInst>( 8500b57cec5SDimitry Andric F.getValueSymbolTable()->lookup(Name.Value)); 8510b57cec5SDimitry Andric if (!Alloca) 8520b57cec5SDimitry Andric return error(Name.SourceRange.Start, 8530b57cec5SDimitry Andric "alloca instruction named '" + Name.Value + 8540b57cec5SDimitry Andric "' isn't defined in the function '" + F.getName() + 8550b57cec5SDimitry Andric "'"); 8560b57cec5SDimitry Andric } 8570b57cec5SDimitry Andric if (!TFI->isSupportedStackID(Object.StackID)) 8580b57cec5SDimitry Andric return error(Object.ID.SourceRange.Start, 8590b57cec5SDimitry Andric Twine("StackID is not supported by target")); 8600b57cec5SDimitry Andric if (Object.Type == yaml::MachineStackObject::VariableSized) 8615ffd83dbSDimitry Andric ObjectIdx = 8625ffd83dbSDimitry Andric MFI.CreateVariableSizedObject(Object.Alignment.valueOrOne(), Alloca); 8630b57cec5SDimitry Andric else 8640b57cec5SDimitry Andric ObjectIdx = MFI.CreateStackObject( 8655ffd83dbSDimitry Andric Object.Size, Object.Alignment.valueOrOne(), 8660b57cec5SDimitry Andric Object.Type == yaml::MachineStackObject::SpillSlot, Alloca, 8670b57cec5SDimitry Andric Object.StackID); 8680b57cec5SDimitry Andric MFI.setObjectOffset(ObjectIdx, Object.Offset); 8690b57cec5SDimitry Andric 8700b57cec5SDimitry Andric if (!PFS.StackObjectSlots.insert(std::make_pair(Object.ID.Value, ObjectIdx)) 8710b57cec5SDimitry Andric .second) 8720b57cec5SDimitry Andric return error(Object.ID.SourceRange.Start, 8730b57cec5SDimitry Andric Twine("redefinition of stack object '%stack.") + 8740b57cec5SDimitry Andric Twine(Object.ID.Value) + "'"); 8750b57cec5SDimitry Andric if (parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister, 8760b57cec5SDimitry Andric Object.CalleeSavedRestored, ObjectIdx)) 8770b57cec5SDimitry Andric return true; 8780b57cec5SDimitry Andric if (Object.LocalOffset) 87981ad6265SDimitry Andric MFI.mapLocalFrameObject(ObjectIdx, *Object.LocalOffset); 8800b57cec5SDimitry Andric if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx)) 8810b57cec5SDimitry Andric return true; 8820b57cec5SDimitry Andric } 8830b57cec5SDimitry Andric MFI.setCalleeSavedInfo(CSIInfo); 8840b57cec5SDimitry Andric if (!CSIInfo.empty()) 8850b57cec5SDimitry Andric MFI.setCalleeSavedInfoValid(true); 8860b57cec5SDimitry Andric 8870b57cec5SDimitry Andric // Initialize the various stack object references after initializing the 8880b57cec5SDimitry Andric // stack objects. 8890b57cec5SDimitry Andric if (!YamlMFI.StackProtector.Value.empty()) { 8900b57cec5SDimitry Andric SMDiagnostic Error; 8910b57cec5SDimitry Andric int FI; 8920b57cec5SDimitry Andric if (parseStackObjectReference(PFS, FI, YamlMFI.StackProtector.Value, Error)) 8930b57cec5SDimitry Andric return error(Error, YamlMFI.StackProtector.SourceRange); 8940b57cec5SDimitry Andric MFI.setStackProtectorIndex(FI); 8950b57cec5SDimitry Andric } 89681ad6265SDimitry Andric 89781ad6265SDimitry Andric if (!YamlMFI.FunctionContext.Value.empty()) { 89881ad6265SDimitry Andric SMDiagnostic Error; 89981ad6265SDimitry Andric int FI; 90081ad6265SDimitry Andric if (parseStackObjectReference(PFS, FI, YamlMFI.FunctionContext.Value, Error)) 90181ad6265SDimitry Andric return error(Error, YamlMFI.FunctionContext.SourceRange); 90281ad6265SDimitry Andric MFI.setFunctionContextIndex(FI); 90381ad6265SDimitry Andric } 90481ad6265SDimitry Andric 9050b57cec5SDimitry Andric return false; 9060b57cec5SDimitry Andric } 9070b57cec5SDimitry Andric 9080b57cec5SDimitry Andric bool MIRParserImpl::parseCalleeSavedRegister(PerFunctionMIParsingState &PFS, 9090b57cec5SDimitry Andric std::vector<CalleeSavedInfo> &CSIInfo, 9100b57cec5SDimitry Andric const yaml::StringValue &RegisterSource, bool IsRestored, int FrameIdx) { 9110b57cec5SDimitry Andric if (RegisterSource.Value.empty()) 9120b57cec5SDimitry Andric return false; 9135ffd83dbSDimitry Andric Register Reg; 9140b57cec5SDimitry Andric SMDiagnostic Error; 9150b57cec5SDimitry Andric if (parseNamedRegisterReference(PFS, Reg, RegisterSource.Value, Error)) 9160b57cec5SDimitry Andric return error(Error, RegisterSource.SourceRange); 9170b57cec5SDimitry Andric CalleeSavedInfo CSI(Reg, FrameIdx); 9180b57cec5SDimitry Andric CSI.setRestored(IsRestored); 9190b57cec5SDimitry Andric CSIInfo.push_back(CSI); 9200b57cec5SDimitry Andric return false; 9210b57cec5SDimitry Andric } 9220b57cec5SDimitry Andric 9230b57cec5SDimitry Andric /// Verify that given node is of a certain type. Return true on error. 9240b57cec5SDimitry Andric template <typename T> 9250b57cec5SDimitry Andric static bool typecheckMDNode(T *&Result, MDNode *Node, 9260b57cec5SDimitry Andric const yaml::StringValue &Source, 9270b57cec5SDimitry Andric StringRef TypeString, MIRParserImpl &Parser) { 9280b57cec5SDimitry Andric if (!Node) 9290b57cec5SDimitry Andric return false; 9300b57cec5SDimitry Andric Result = dyn_cast<T>(Node); 9310b57cec5SDimitry Andric if (!Result) 9320b57cec5SDimitry Andric return Parser.error(Source.SourceRange.Start, 9330b57cec5SDimitry Andric "expected a reference to a '" + TypeString + 9340b57cec5SDimitry Andric "' metadata node"); 9350b57cec5SDimitry Andric return false; 9360b57cec5SDimitry Andric } 9370b57cec5SDimitry Andric 93806c3fb27SDimitry Andric std::optional<MIRParserImpl::VarExprLoc> MIRParserImpl::parseVarExprLoc( 93906c3fb27SDimitry Andric PerFunctionMIParsingState &PFS, const yaml::StringValue &VarStr, 94006c3fb27SDimitry Andric const yaml::StringValue &ExprStr, const yaml::StringValue &LocStr) { 94106c3fb27SDimitry Andric MDNode *Var = nullptr; 94206c3fb27SDimitry Andric MDNode *Expr = nullptr; 94306c3fb27SDimitry Andric MDNode *Loc = nullptr; 94406c3fb27SDimitry Andric if (parseMDNode(PFS, Var, VarStr) || parseMDNode(PFS, Expr, ExprStr) || 94506c3fb27SDimitry Andric parseMDNode(PFS, Loc, LocStr)) 94606c3fb27SDimitry Andric return std::nullopt; 9470b57cec5SDimitry Andric DILocalVariable *DIVar = nullptr; 9480b57cec5SDimitry Andric DIExpression *DIExpr = nullptr; 9490b57cec5SDimitry Andric DILocation *DILoc = nullptr; 95006c3fb27SDimitry Andric if (typecheckMDNode(DIVar, Var, VarStr, "DILocalVariable", *this) || 95106c3fb27SDimitry Andric typecheckMDNode(DIExpr, Expr, ExprStr, "DIExpression", *this) || 95206c3fb27SDimitry Andric typecheckMDNode(DILoc, Loc, LocStr, "DILocation", *this)) 95306c3fb27SDimitry Andric return std::nullopt; 95406c3fb27SDimitry Andric return VarExprLoc{DIVar, DIExpr, DILoc}; 95506c3fb27SDimitry Andric } 95606c3fb27SDimitry Andric 95706c3fb27SDimitry Andric template <typename T> 95806c3fb27SDimitry Andric bool MIRParserImpl::parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS, 95906c3fb27SDimitry Andric const T &Object, int FrameIdx) { 96006c3fb27SDimitry Andric std::optional<VarExprLoc> MaybeInfo = 96106c3fb27SDimitry Andric parseVarExprLoc(PFS, Object.DebugVar, Object.DebugExpr, Object.DebugLoc); 96206c3fb27SDimitry Andric if (!MaybeInfo) 9630b57cec5SDimitry Andric return true; 96406c3fb27SDimitry Andric // Debug information can only be attached to stack objects; Fixed stack 96506c3fb27SDimitry Andric // objects aren't supported. 96606c3fb27SDimitry Andric if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc) 96706c3fb27SDimitry Andric PFS.MF.setVariableDbgInfo(MaybeInfo->DIVar, MaybeInfo->DIExpr, FrameIdx, 96806c3fb27SDimitry Andric MaybeInfo->DILoc); 9690b57cec5SDimitry Andric return false; 9700b57cec5SDimitry Andric } 9710b57cec5SDimitry Andric 9720b57cec5SDimitry Andric bool MIRParserImpl::parseMDNode(PerFunctionMIParsingState &PFS, 9730b57cec5SDimitry Andric MDNode *&Node, const yaml::StringValue &Source) { 9740b57cec5SDimitry Andric if (Source.Value.empty()) 9750b57cec5SDimitry Andric return false; 9760b57cec5SDimitry Andric SMDiagnostic Error; 9770b57cec5SDimitry Andric if (llvm::parseMDNode(PFS, Node, Source.Value, Error)) 9780b57cec5SDimitry Andric return error(Error, Source.SourceRange); 9790b57cec5SDimitry Andric return false; 9800b57cec5SDimitry Andric } 9810b57cec5SDimitry Andric 9820b57cec5SDimitry Andric bool MIRParserImpl::initializeConstantPool(PerFunctionMIParsingState &PFS, 9830b57cec5SDimitry Andric MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF) { 9840b57cec5SDimitry Andric DenseMap<unsigned, unsigned> &ConstantPoolSlots = PFS.ConstantPoolSlots; 9850b57cec5SDimitry Andric const MachineFunction &MF = PFS.MF; 9860b57cec5SDimitry Andric const auto &M = *MF.getFunction().getParent(); 9870b57cec5SDimitry Andric SMDiagnostic Error; 9880b57cec5SDimitry Andric for (const auto &YamlConstant : YamlMF.Constants) { 9890b57cec5SDimitry Andric if (YamlConstant.IsTargetSpecific) 9900b57cec5SDimitry Andric // FIXME: Support target-specific constant pools 9910b57cec5SDimitry Andric return error(YamlConstant.Value.SourceRange.Start, 9920b57cec5SDimitry Andric "Can't parse target-specific constant pool entries yet"); 9930b57cec5SDimitry Andric const Constant *Value = dyn_cast_or_null<Constant>( 9940b57cec5SDimitry Andric parseConstantValue(YamlConstant.Value.Value, Error, M)); 9950b57cec5SDimitry Andric if (!Value) 9960b57cec5SDimitry Andric return error(Error, YamlConstant.Value.SourceRange); 9975ffd83dbSDimitry Andric const Align PrefTypeAlign = 9985ffd83dbSDimitry Andric M.getDataLayout().getPrefTypeAlign(Value->getType()); 99981ad6265SDimitry Andric const Align Alignment = YamlConstant.Alignment.value_or(PrefTypeAlign); 10000b57cec5SDimitry Andric unsigned Index = ConstantPool.getConstantPoolIndex(Value, Alignment); 10010b57cec5SDimitry Andric if (!ConstantPoolSlots.insert(std::make_pair(YamlConstant.ID.Value, Index)) 10020b57cec5SDimitry Andric .second) 10030b57cec5SDimitry Andric return error(YamlConstant.ID.SourceRange.Start, 10040b57cec5SDimitry Andric Twine("redefinition of constant pool item '%const.") + 10050b57cec5SDimitry Andric Twine(YamlConstant.ID.Value) + "'"); 10060b57cec5SDimitry Andric } 10070b57cec5SDimitry Andric return false; 10080b57cec5SDimitry Andric } 10090b57cec5SDimitry Andric 10100b57cec5SDimitry Andric bool MIRParserImpl::initializeJumpTableInfo(PerFunctionMIParsingState &PFS, 10110b57cec5SDimitry Andric const yaml::MachineJumpTable &YamlJTI) { 10120b57cec5SDimitry Andric MachineJumpTableInfo *JTI = PFS.MF.getOrCreateJumpTableInfo(YamlJTI.Kind); 10130b57cec5SDimitry Andric for (const auto &Entry : YamlJTI.Entries) { 10140b57cec5SDimitry Andric std::vector<MachineBasicBlock *> Blocks; 10150b57cec5SDimitry Andric for (const auto &MBBSource : Entry.Blocks) { 10160b57cec5SDimitry Andric MachineBasicBlock *MBB = nullptr; 10170b57cec5SDimitry Andric if (parseMBBReference(PFS, MBB, MBBSource.Value)) 10180b57cec5SDimitry Andric return true; 10190b57cec5SDimitry Andric Blocks.push_back(MBB); 10200b57cec5SDimitry Andric } 10210b57cec5SDimitry Andric unsigned Index = JTI->createJumpTableIndex(Blocks); 10220b57cec5SDimitry Andric if (!PFS.JumpTableSlots.insert(std::make_pair(Entry.ID.Value, Index)) 10230b57cec5SDimitry Andric .second) 10240b57cec5SDimitry Andric return error(Entry.ID.SourceRange.Start, 10250b57cec5SDimitry Andric Twine("redefinition of jump table entry '%jump-table.") + 10260b57cec5SDimitry Andric Twine(Entry.ID.Value) + "'"); 10270b57cec5SDimitry Andric } 10280b57cec5SDimitry Andric return false; 10290b57cec5SDimitry Andric } 10300b57cec5SDimitry Andric 10310b57cec5SDimitry Andric bool MIRParserImpl::parseMBBReference(PerFunctionMIParsingState &PFS, 10320b57cec5SDimitry Andric MachineBasicBlock *&MBB, 10330b57cec5SDimitry Andric const yaml::StringValue &Source) { 10340b57cec5SDimitry Andric SMDiagnostic Error; 10350b57cec5SDimitry Andric if (llvm::parseMBBReference(PFS, MBB, Source.Value, Error)) 10360b57cec5SDimitry Andric return error(Error, Source.SourceRange); 10370b57cec5SDimitry Andric return false; 10380b57cec5SDimitry Andric } 10390b57cec5SDimitry Andric 1040fe6060f1SDimitry Andric bool MIRParserImpl::parseMachineMetadata(PerFunctionMIParsingState &PFS, 1041fe6060f1SDimitry Andric const yaml::StringValue &Source) { 1042fe6060f1SDimitry Andric SMDiagnostic Error; 1043fe6060f1SDimitry Andric if (llvm::parseMachineMetadata(PFS, Source.Value, Source.SourceRange, Error)) 1044fe6060f1SDimitry Andric return error(Error, Source.SourceRange); 1045fe6060f1SDimitry Andric return false; 1046fe6060f1SDimitry Andric } 1047fe6060f1SDimitry Andric 1048fe6060f1SDimitry Andric bool MIRParserImpl::parseMachineMetadataNodes( 1049fe6060f1SDimitry Andric PerFunctionMIParsingState &PFS, MachineFunction &MF, 1050fe6060f1SDimitry Andric const yaml::MachineFunction &YMF) { 1051fcaf7f86SDimitry Andric for (const auto &MDS : YMF.MachineMetadataNodes) { 1052fe6060f1SDimitry Andric if (parseMachineMetadata(PFS, MDS)) 1053fe6060f1SDimitry Andric return true; 1054fe6060f1SDimitry Andric } 1055fe6060f1SDimitry Andric // Report missing definitions from forward referenced nodes. 1056fe6060f1SDimitry Andric if (!PFS.MachineForwardRefMDNodes.empty()) 1057fe6060f1SDimitry Andric return error(PFS.MachineForwardRefMDNodes.begin()->second.second, 1058fe6060f1SDimitry Andric "use of undefined metadata '!" + 1059fe6060f1SDimitry Andric Twine(PFS.MachineForwardRefMDNodes.begin()->first) + "'"); 1060fe6060f1SDimitry Andric return false; 1061fe6060f1SDimitry Andric } 1062fe6060f1SDimitry Andric 10630b57cec5SDimitry Andric SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error, 10640b57cec5SDimitry Andric SMRange SourceRange) { 10650b57cec5SDimitry Andric assert(SourceRange.isValid() && "Invalid source range"); 10660b57cec5SDimitry Andric SMLoc Loc = SourceRange.Start; 10670b57cec5SDimitry Andric bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() && 10680b57cec5SDimitry Andric *Loc.getPointer() == '\''; 10690b57cec5SDimitry Andric // Translate the location of the error from the location in the MI string to 10700b57cec5SDimitry Andric // the corresponding location in the MIR file. 10710b57cec5SDimitry Andric Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() + 10720b57cec5SDimitry Andric (HasQuote ? 1 : 0)); 10730b57cec5SDimitry Andric 10740b57cec5SDimitry Andric // TODO: Translate any source ranges as well. 1075bdd1243dSDimitry Andric return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), std::nullopt, 10760b57cec5SDimitry Andric Error.getFixIts()); 10770b57cec5SDimitry Andric } 10780b57cec5SDimitry Andric 10790b57cec5SDimitry Andric SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error, 10800b57cec5SDimitry Andric SMRange SourceRange) { 10810b57cec5SDimitry Andric assert(SourceRange.isValid()); 10820b57cec5SDimitry Andric 10830b57cec5SDimitry Andric // Translate the location of the error from the location in the llvm IR string 10840b57cec5SDimitry Andric // to the corresponding location in the MIR file. 10850b57cec5SDimitry Andric auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start); 10860b57cec5SDimitry Andric unsigned Line = LineAndColumn.first + Error.getLineNo() - 1; 10870b57cec5SDimitry Andric unsigned Column = Error.getColumnNo(); 10880b57cec5SDimitry Andric StringRef LineStr = Error.getLineContents(); 10890b57cec5SDimitry Andric SMLoc Loc = Error.getLoc(); 10900b57cec5SDimitry Andric 10910b57cec5SDimitry Andric // Get the full line and adjust the column number by taking the indentation of 10920b57cec5SDimitry Andric // LLVM IR into account. 10930b57cec5SDimitry Andric for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E; 10940b57cec5SDimitry Andric L != E; ++L) { 10950b57cec5SDimitry Andric if (L.line_number() == Line) { 10960b57cec5SDimitry Andric LineStr = *L; 10970b57cec5SDimitry Andric Loc = SMLoc::getFromPointer(LineStr.data()); 10980b57cec5SDimitry Andric auto Indent = LineStr.find(Error.getLineContents()); 10990b57cec5SDimitry Andric if (Indent != StringRef::npos) 11000b57cec5SDimitry Andric Column += Indent; 11010b57cec5SDimitry Andric break; 11020b57cec5SDimitry Andric } 11030b57cec5SDimitry Andric } 11040b57cec5SDimitry Andric 11050b57cec5SDimitry Andric return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(), 11060b57cec5SDimitry Andric Error.getMessage(), LineStr, Error.getRanges(), 11070b57cec5SDimitry Andric Error.getFixIts()); 11080b57cec5SDimitry Andric } 11090b57cec5SDimitry Andric 11100b57cec5SDimitry Andric MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl) 11110b57cec5SDimitry Andric : Impl(std::move(Impl)) {} 11120b57cec5SDimitry Andric 111381ad6265SDimitry Andric MIRParser::~MIRParser() = default; 11140b57cec5SDimitry Andric 11155ffd83dbSDimitry Andric std::unique_ptr<Module> 11165ffd83dbSDimitry Andric MIRParser::parseIRModule(DataLayoutCallbackTy DataLayoutCallback) { 11175ffd83dbSDimitry Andric return Impl->parseIRModule(DataLayoutCallback); 11180b57cec5SDimitry Andric } 11190b57cec5SDimitry Andric 11200b57cec5SDimitry Andric bool MIRParser::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) { 11210b57cec5SDimitry Andric return Impl->parseMachineFunctions(M, MMI); 11220b57cec5SDimitry Andric } 11230b57cec5SDimitry Andric 1124*0fca6ea1SDimitry Andric bool MIRParser::parseMachineFunctions(Module &M, ModuleAnalysisManager &MAM) { 1125*0fca6ea1SDimitry Andric auto &MMI = MAM.getResult<MachineModuleAnalysis>(M).getMMI(); 1126*0fca6ea1SDimitry Andric return Impl->parseMachineFunctions(M, MMI, &MAM); 1127*0fca6ea1SDimitry Andric } 1128*0fca6ea1SDimitry Andric 1129480093f4SDimitry Andric std::unique_ptr<MIRParser> llvm::createMIRParserFromFile( 1130480093f4SDimitry Andric StringRef Filename, SMDiagnostic &Error, LLVMContext &Context, 1131480093f4SDimitry Andric std::function<void(Function &)> ProcessIRFunction) { 1132fe6060f1SDimitry Andric auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true); 11330b57cec5SDimitry Andric if (std::error_code EC = FileOrErr.getError()) { 11340b57cec5SDimitry Andric Error = SMDiagnostic(Filename, SourceMgr::DK_Error, 11350b57cec5SDimitry Andric "Could not open input file: " + EC.message()); 11360b57cec5SDimitry Andric return nullptr; 11370b57cec5SDimitry Andric } 1138480093f4SDimitry Andric return createMIRParser(std::move(FileOrErr.get()), Context, 1139480093f4SDimitry Andric ProcessIRFunction); 11400b57cec5SDimitry Andric } 11410b57cec5SDimitry Andric 11420b57cec5SDimitry Andric std::unique_ptr<MIRParser> 11430b57cec5SDimitry Andric llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents, 1144480093f4SDimitry Andric LLVMContext &Context, 1145480093f4SDimitry Andric std::function<void(Function &)> ProcessIRFunction) { 11460b57cec5SDimitry Andric auto Filename = Contents->getBufferIdentifier(); 11470b57cec5SDimitry Andric if (Context.shouldDiscardValueNames()) { 11480b57cec5SDimitry Andric Context.diagnose(DiagnosticInfoMIRParser( 11490b57cec5SDimitry Andric DS_Error, 11500b57cec5SDimitry Andric SMDiagnostic( 11510b57cec5SDimitry Andric Filename, SourceMgr::DK_Error, 11520b57cec5SDimitry Andric "Can't read MIR with a Context that discards named Values"))); 11530b57cec5SDimitry Andric return nullptr; 11540b57cec5SDimitry Andric } 1155480093f4SDimitry Andric return std::make_unique<MIRParser>(std::make_unique<MIRParserImpl>( 1156480093f4SDimitry Andric std::move(Contents), Filename, Context, ProcessIRFunction)); 11570b57cec5SDimitry Andric } 1158