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