blob: cfe3ab33116eda50efb1f4c2ec00a186f8982ace [file] [log] [blame]
Alex Lorenz2bdb4e12015-05-27 18:02:19 +00001//===- MIRParser.cpp - MIR serialization format parser implementation -----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the class that parses the optional LLVM IR and machine
11// functions that are stored in MIR files.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/CodeGen/MIRParser/MIRParser.h"
Alex Lorenz8e0a1b42015-06-22 17:02:30 +000016#include "MIParser.h"
Alex Lorenz33f0aef2015-06-26 16:46:11 +000017#include "llvm/ADT/DenseMap.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000018#include "llvm/ADT/StringRef.h"
Alex Lorenz735c47e2015-06-15 20:30:22 +000019#include "llvm/ADT/StringMap.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000020#include "llvm/ADT/STLExtras.h"
21#include "llvm/AsmParser/Parser.h"
Alex Lorenz5d6108e2015-06-26 22:56:48 +000022#include "llvm/AsmParser/SlotMapping.h"
Alex Lorenzab980492015-07-20 20:51:18 +000023#include "llvm/CodeGen/MachineConstantPool.h"
Alex Lorenz735c47e2015-06-15 20:30:22 +000024#include "llvm/CodeGen/MachineFunction.h"
Alex Lorenz60541c12015-07-09 19:55:27 +000025#include "llvm/CodeGen/MachineFrameInfo.h"
Alex Lorenzdf9e3c62015-08-19 00:13:25 +000026#include "llvm/CodeGen/MachineModuleInfo.h"
Alex Lorenz54565cf2015-06-24 19:56:10 +000027#include "llvm/CodeGen/MachineRegisterInfo.h"
Alex Lorenz78d78312015-05-28 22:41:12 +000028#include "llvm/CodeGen/MIRYamlMapping.h"
Alex Lorenz4f093bf2015-06-19 17:43:07 +000029#include "llvm/IR/BasicBlock.h"
Alex Lorenz735c47e2015-06-15 20:30:22 +000030#include "llvm/IR/DiagnosticInfo.h"
Alex Lorenz8e7a58d72015-06-15 23:07:38 +000031#include "llvm/IR/Instructions.h"
Alex Lorenz735c47e2015-06-15 20:30:22 +000032#include "llvm/IR/LLVMContext.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000033#include "llvm/IR/Module.h"
Alex Lorenz4f093bf2015-06-19 17:43:07 +000034#include "llvm/IR/ValueSymbolTable.h"
Alex Lorenz09b832c2015-05-29 17:05:41 +000035#include "llvm/Support/LineIterator.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000036#include "llvm/Support/SMLoc.h"
37#include "llvm/Support/SourceMgr.h"
38#include "llvm/Support/MemoryBuffer.h"
39#include "llvm/Support/YAMLTraits.h"
40#include <memory>
41
42using namespace llvm;
43
Alex Lorenz735c47e2015-06-15 20:30:22 +000044namespace llvm {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000045
46/// This class implements the parsing of LLVM IR that's embedded inside a MIR
47/// file.
48class MIRParserImpl {
49 SourceMgr SM;
50 StringRef Filename;
51 LLVMContext &Context;
Alex Lorenz735c47e2015-06-15 20:30:22 +000052 StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;
Alex Lorenz5d6108e2015-06-26 22:56:48 +000053 SlotMapping IRSlots;
Alex Lorenz28148ba2015-07-09 22:23:13 +000054 /// Maps from register class names to register classes.
55 StringMap<const TargetRegisterClass *> Names2RegClasses;
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000056
57public:
58 MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
59 LLVMContext &Context);
60
Alex Lorenz735c47e2015-06-15 20:30:22 +000061 void reportDiagnostic(const SMDiagnostic &Diag);
62
63 /// Report an error with the given message at unknown location.
64 ///
65 /// Always returns true.
66 bool error(const Twine &Message);
67
Alex Lorenzb1f9ce82015-07-08 20:22:20 +000068 /// Report an error with the given message at the given location.
69 ///
70 /// Always returns true.
71 bool error(SMLoc Loc, const Twine &Message);
72
Alex Lorenz0fd7c622015-06-30 17:55:00 +000073 /// Report a given error with the location translated from the location in an
74 /// embedded string literal to a location in the MIR file.
75 ///
76 /// Always returns true.
77 bool error(const SMDiagnostic &Error, SMRange SourceRange);
78
Alex Lorenz78d78312015-05-28 22:41:12 +000079 /// Try to parse the optional LLVM module and the machine functions in the MIR
80 /// file.
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000081 ///
Alex Lorenz78d78312015-05-28 22:41:12 +000082 /// Return null if an error occurred.
Alex Lorenz735c47e2015-06-15 20:30:22 +000083 std::unique_ptr<Module> parse();
Alex Lorenz78d78312015-05-28 22:41:12 +000084
85 /// Parse the machine function in the current YAML document.
86 ///
Alex Lorenz8e7a58d72015-06-15 23:07:38 +000087 /// \param NoLLVMIR - set to true when the MIR file doesn't have LLVM IR.
88 /// A dummy IR function is created and inserted into the given module when
89 /// this parameter is true.
90 ///
Alex Lorenz78d78312015-05-28 22:41:12 +000091 /// Return true if an error occurred.
Alex Lorenz8e7a58d72015-06-15 23:07:38 +000092 bool parseMachineFunction(yaml::Input &In, Module &M, bool NoLLVMIR);
Alex Lorenz09b832c2015-05-29 17:05:41 +000093
Alex Lorenz735c47e2015-06-15 20:30:22 +000094 /// Initialize the machine function to the state that's described in the MIR
95 /// file.
96 ///
97 /// Return true if error occurred.
98 bool initializeMachineFunction(MachineFunction &MF);
99
Alex Lorenzdb07c402015-07-28 16:48:37 +0000100 bool initializeRegisterInfo(MachineFunction &MF,
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000101 const yaml::MachineFunction &YamlMF,
102 PerFunctionMIParsingState &PFS);
Alex Lorenz54565cf2015-06-24 19:56:10 +0000103
Alex Lorenzc4838082015-08-11 00:32:49 +0000104 void inferRegisterInfo(MachineFunction &MF,
105 const yaml::MachineFunction &YamlMF);
106
Alex Lorenzdb07c402015-07-28 16:48:37 +0000107 bool initializeFrameInfo(MachineFunction &MF,
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000108 const yaml::MachineFunction &YamlMF,
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000109 PerFunctionMIParsingState &PFS);
110
111 bool parseCalleeSavedRegister(MachineFunction &MF,
112 PerFunctionMIParsingState &PFS,
113 std::vector<CalleeSavedInfo> &CSIInfo,
114 const yaml::StringValue &RegisterSource,
115 int FrameIdx);
Alex Lorenz60541c12015-07-09 19:55:27 +0000116
Alex Lorenzdf9e3c62015-08-19 00:13:25 +0000117 bool parseStackObjectsDebugInfo(MachineFunction &MF,
118 PerFunctionMIParsingState &PFS,
119 const yaml::MachineStackObject &Object,
120 int FrameIdx);
121
Alex Lorenzab980492015-07-20 20:51:18 +0000122 bool initializeConstantPool(MachineConstantPool &ConstantPool,
123 const yaml::MachineFunction &YamlMF,
124 const MachineFunction &MF,
125 DenseMap<unsigned, unsigned> &ConstantPoolSlots);
126
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000127 bool initializeJumpTableInfo(MachineFunction &MF,
128 const yaml::MachineJumpTable &YamlJTI,
Alex Lorenz31d70682015-07-15 23:38:35 +0000129 PerFunctionMIParsingState &PFS);
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000130
Alex Lorenz09b832c2015-05-29 17:05:41 +0000131private:
Alex Lorenzdf9e3c62015-08-19 00:13:25 +0000132 bool parseMDNode(MDNode *&Node, const yaml::StringValue &Source,
133 MachineFunction &MF, const PerFunctionMIParsingState &PFS);
134
Alex Lorenz05fa73b2015-07-29 20:57:11 +0000135 bool parseMBBReference(MachineBasicBlock *&MBB,
136 const yaml::StringValue &Source, MachineFunction &MF,
137 const PerFunctionMIParsingState &PFS);
138
Alex Lorenz51af1602015-06-23 22:39:23 +0000139 /// Return a MIR diagnostic converted from an MI string diagnostic.
140 SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
141 SMRange SourceRange);
142
Alex Lorenz9b62cf62015-08-13 20:30:11 +0000143 /// Return a MIR diagnostic converted from a diagnostic located in a YAML
144 /// block scalar string.
145 SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error,
146 SMRange SourceRange);
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000147
148 /// Create an empty function with the given name.
149 void createDummyFunction(StringRef Name, Module &M);
Alex Lorenz28148ba2015-07-09 22:23:13 +0000150
151 void initNames2RegClasses(const MachineFunction &MF);
152
153 /// Check if the given identifier is a name of a register class.
154 ///
155 /// Return null if the name isn't a register class.
156 const TargetRegisterClass *getRegClass(const MachineFunction &MF,
157 StringRef Name);
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000158};
159
Alex Lorenz735c47e2015-06-15 20:30:22 +0000160} // end namespace llvm
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000161
162MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
163 StringRef Filename, LLVMContext &Context)
164 : SM(), Filename(Filename), Context(Context) {
165 SM.AddNewSourceBuffer(std::move(Contents), SMLoc());
166}
167
Alex Lorenz735c47e2015-06-15 20:30:22 +0000168bool MIRParserImpl::error(const Twine &Message) {
169 Context.diagnose(DiagnosticInfoMIRParser(
170 DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));
171 return true;
Alex Lorenz78d78312015-05-28 22:41:12 +0000172}
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000173
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000174bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) {
175 Context.diagnose(DiagnosticInfoMIRParser(
176 DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message)));
177 return true;
178}
179
Alex Lorenz0fd7c622015-06-30 17:55:00 +0000180bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) {
181 assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");
182 reportDiagnostic(diagFromMIStringDiag(Error, SourceRange));
183 return true;
184}
185
Alex Lorenz735c47e2015-06-15 20:30:22 +0000186void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
187 DiagnosticSeverity Kind;
188 switch (Diag.getKind()) {
189 case SourceMgr::DK_Error:
190 Kind = DS_Error;
191 break;
192 case SourceMgr::DK_Warning:
193 Kind = DS_Warning;
194 break;
195 case SourceMgr::DK_Note:
196 Kind = DS_Note;
197 break;
198 }
199 Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
200}
201
202static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
203 reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
204}
205
206std::unique_ptr<Module> MIRParserImpl::parse() {
Alex Lorenz78d78312015-05-28 22:41:12 +0000207 yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(),
Alex Lorenz735c47e2015-06-15 20:30:22 +0000208 /*Ctxt=*/nullptr, handleYAMLDiag, this);
Alex Lorenz51af1602015-06-23 22:39:23 +0000209 In.setContext(&In);
Alex Lorenz78d78312015-05-28 22:41:12 +0000210
211 if (!In.setCurrentDocument()) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000212 if (In.error())
Alex Lorenz78d78312015-05-28 22:41:12 +0000213 return nullptr;
214 // Create an empty module when the MIR file is empty.
215 return llvm::make_unique<Module>(Filename, Context);
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000216 }
217
Alex Lorenz78d78312015-05-28 22:41:12 +0000218 std::unique_ptr<Module> M;
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000219 bool NoLLVMIR = false;
Alex Lorenz78d78312015-05-28 22:41:12 +0000220 // Parse the block scalar manually so that we can return unique pointer
221 // without having to go trough YAML traits.
222 if (const auto *BSN =
223 dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000224 SMDiagnostic Error;
Alex Lorenz78d78312015-05-28 22:41:12 +0000225 M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
Alex Lorenz5d6108e2015-06-26 22:56:48 +0000226 Context, &IRSlots);
Alex Lorenz09b832c2015-05-29 17:05:41 +0000227 if (!M) {
Alex Lorenz9b62cf62015-08-13 20:30:11 +0000228 reportDiagnostic(diagFromBlockStringDiag(Error, BSN->getSourceRange()));
Alex Lorenz78d78312015-05-28 22:41:12 +0000229 return M;
Alex Lorenz09b832c2015-05-29 17:05:41 +0000230 }
Alex Lorenz78d78312015-05-28 22:41:12 +0000231 In.nextDocument();
232 if (!In.setCurrentDocument())
233 return M;
234 } else {
235 // Create an new, empty module.
236 M = llvm::make_unique<Module>(Filename, Context);
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000237 NoLLVMIR = true;
Alex Lorenz78d78312015-05-28 22:41:12 +0000238 }
239
240 // Parse the machine functions.
241 do {
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000242 if (parseMachineFunction(In, *M, NoLLVMIR))
Alex Lorenz78d78312015-05-28 22:41:12 +0000243 return nullptr;
244 In.nextDocument();
245 } while (In.setCurrentDocument());
246
247 return M;
248}
249
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000250bool MIRParserImpl::parseMachineFunction(yaml::Input &In, Module &M,
251 bool NoLLVMIR) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000252 auto MF = llvm::make_unique<yaml::MachineFunction>();
253 yaml::yamlize(In, *MF, false);
Alex Lorenz78d78312015-05-28 22:41:12 +0000254 if (In.error())
255 return true;
Alex Lorenz735c47e2015-06-15 20:30:22 +0000256 auto FunctionName = MF->Name;
Alex Lorenzfe2aa972015-06-15 22:23:23 +0000257 if (Functions.find(FunctionName) != Functions.end())
258 return error(Twine("redefinition of machine function '") + FunctionName +
259 "'");
Alex Lorenz735c47e2015-06-15 20:30:22 +0000260 Functions.insert(std::make_pair(FunctionName, std::move(MF)));
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000261 if (NoLLVMIR)
262 createDummyFunction(FunctionName, M);
Alex Lorenz5ef16b82015-06-16 17:06:29 +0000263 else if (!M.getFunction(FunctionName))
264 return error(Twine("function '") + FunctionName +
265 "' isn't defined in the provided LLVM IR");
Alex Lorenz735c47e2015-06-15 20:30:22 +0000266 return false;
267}
268
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000269void MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
270 auto &Context = M.getContext();
271 Function *F = cast<Function>(M.getOrInsertFunction(
272 Name, FunctionType::get(Type::getVoidTy(Context), false)));
273 BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
274 new UnreachableInst(Context, BB);
275}
276
Alex Lorenz735c47e2015-06-15 20:30:22 +0000277bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
278 auto It = Functions.find(MF.getName());
279 if (It == Functions.end())
280 return error(Twine("no machine function information for function '") +
281 MF.getName() + "' in the MIR file");
282 // TODO: Recreate the machine function.
Alex Lorenz5b5f9752015-06-16 00:10:47 +0000283 const yaml::MachineFunction &YamlMF = *It->getValue();
284 if (YamlMF.Alignment)
285 MF.setAlignment(YamlMF.Alignment);
286 MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
287 MF.setHasInlineAsm(YamlMF.HasInlineAsm);
Alex Lorenz53464512015-07-10 22:51:20 +0000288 PerFunctionMIParsingState PFS;
Alex Lorenzdb07c402015-07-28 16:48:37 +0000289 if (initializeRegisterInfo(MF, YamlMF, PFS))
Alex Lorenz54565cf2015-06-24 19:56:10 +0000290 return true;
Alex Lorenzab980492015-07-20 20:51:18 +0000291 if (!YamlMF.Constants.empty()) {
292 auto *ConstantPool = MF.getConstantPool();
293 assert(ConstantPool && "Constant pool must be created");
294 if (initializeConstantPool(*ConstantPool, YamlMF, MF,
295 PFS.ConstantPoolSlots))
296 return true;
297 }
Alex Lorenz54565cf2015-06-24 19:56:10 +0000298
Alex Lorenz5022f6b2015-08-13 23:10:16 +0000299 SMDiagnostic Error;
300 if (parseMachineBasicBlockDefinitions(MF, YamlMF.Body.Value.Value, PFS,
301 IRSlots, Error)) {
302 reportDiagnostic(
303 diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
304 return true;
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000305 }
306
Alex Lorenz5022f6b2015-08-13 23:10:16 +0000307 if (MF.empty())
Alex Lorenzc8704b02015-07-09 21:21:33 +0000308 return error(Twine("machine function '") + Twine(MF.getName()) +
309 "' requires at least one machine basic block in its body");
Alex Lorenza6f9a372015-07-29 21:09:09 +0000310 // Initialize the frame information after creating all the MBBs so that the
311 // MBB references in the frame information can be resolved.
312 if (initializeFrameInfo(MF, YamlMF, PFS))
313 return true;
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000314 // Initialize the jump table after creating all the MBBs so that the MBB
315 // references can be resolved.
316 if (!YamlMF.JumpTableInfo.Entries.empty() &&
317 initializeJumpTableInfo(MF, YamlMF.JumpTableInfo, PFS))
318 return true;
Alex Lorenz5022f6b2015-08-13 23:10:16 +0000319 // Parse the machine instructions after creating all of the MBBs so that the
320 // parser can resolve the MBB references.
321 if (parseMachineInstructions(MF, YamlMF.Body.Value.Value, PFS, IRSlots,
322 Error)) {
323 reportDiagnostic(
324 diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
325 return true;
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000326 }
Alex Lorenzc4838082015-08-11 00:32:49 +0000327 inferRegisterInfo(MF, YamlMF);
Alex Lorenzc7bf2042015-07-24 17:44:49 +0000328 // FIXME: This is a temporary workaround until the reserved registers can be
329 // serialized.
330 MF.getRegInfo().freezeReservedRegs(MF);
331 MF.verify();
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000332 return false;
333}
334
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000335bool MIRParserImpl::initializeRegisterInfo(MachineFunction &MF,
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000336 const yaml::MachineFunction &YamlMF,
337 PerFunctionMIParsingState &PFS) {
Alex Lorenzdb07c402015-07-28 16:48:37 +0000338 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Alex Lorenz54565cf2015-06-24 19:56:10 +0000339 assert(RegInfo.isSSA());
340 if (!YamlMF.IsSSA)
341 RegInfo.leaveSSA();
342 assert(RegInfo.tracksLiveness());
343 if (!YamlMF.TracksRegLiveness)
344 RegInfo.invalidateLiveness();
345 RegInfo.enableSubRegLiveness(YamlMF.TracksSubRegLiveness);
Alex Lorenz28148ba2015-07-09 22:23:13 +0000346
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000347 SMDiagnostic Error;
Alex Lorenz28148ba2015-07-09 22:23:13 +0000348 // Parse the virtual register information.
349 for (const auto &VReg : YamlMF.VirtualRegisters) {
Quentin Colombet050b2112016-03-08 01:17:03 +0000350 unsigned Reg;
351 if (StringRef(VReg.Class.Value).equals("_")) {
352 // This is a generic virtual register.
353 // The size will be set appropriately when we reach the definition.
354 Reg = RegInfo.createGenericVirtualRegister(/*Size*/ 1);
355 } else {
356 const auto *RC = getRegClass(MF, VReg.Class.Value);
357 if (!RC)
358 return error(VReg.Class.SourceRange.Start,
359 Twine("use of undefined register class '") +
360 VReg.Class.Value + "'");
361 Reg = RegInfo.createVirtualRegister(RC);
362 }
Alex Lorenza06c0c62015-07-30 21:54:10 +0000363 if (!PFS.VirtualRegisterSlots.insert(std::make_pair(VReg.ID.Value, Reg))
364 .second)
365 return error(VReg.ID.SourceRange.Start,
366 Twine("redefinition of virtual register '%") +
367 Twine(VReg.ID.Value) + "'");
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000368 if (!VReg.PreferredRegister.Value.empty()) {
369 unsigned PreferredReg = 0;
370 if (parseNamedRegisterReference(PreferredReg, SM, MF,
371 VReg.PreferredRegister.Value, PFS,
372 IRSlots, Error))
373 return error(Error, VReg.PreferredRegister.SourceRange);
374 RegInfo.setSimpleHint(Reg, PreferredReg);
375 }
Alex Lorenz28148ba2015-07-09 22:23:13 +0000376 }
Alex Lorenz12045a42015-07-27 17:42:45 +0000377
378 // Parse the liveins.
379 for (const auto &LiveIn : YamlMF.LiveIns) {
380 unsigned Reg = 0;
381 if (parseNamedRegisterReference(Reg, SM, MF, LiveIn.Register.Value, PFS,
382 IRSlots, Error))
383 return error(Error, LiveIn.Register.SourceRange);
384 unsigned VReg = 0;
385 if (!LiveIn.VirtualRegister.Value.empty()) {
386 if (parseVirtualRegisterReference(
387 VReg, SM, MF, LiveIn.VirtualRegister.Value, PFS, IRSlots, Error))
388 return error(Error, LiveIn.VirtualRegister.SourceRange);
389 }
390 RegInfo.addLiveIn(Reg, VReg);
391 }
Alex Lorenzc4838082015-08-11 00:32:49 +0000392
393 // Parse the callee saved register mask.
394 BitVector CalleeSavedRegisterMask(RegInfo.getUsedPhysRegsMask().size());
395 if (!YamlMF.CalleeSavedRegisters)
396 return false;
397 for (const auto &RegSource : YamlMF.CalleeSavedRegisters.getValue()) {
398 unsigned Reg = 0;
399 if (parseNamedRegisterReference(Reg, SM, MF, RegSource.Value, PFS, IRSlots,
400 Error))
401 return error(Error, RegSource.SourceRange);
402 CalleeSavedRegisterMask[Reg] = true;
403 }
404 RegInfo.setUsedPhysRegMask(CalleeSavedRegisterMask.flip());
Alex Lorenz54565cf2015-06-24 19:56:10 +0000405 return false;
406}
407
Alex Lorenzc4838082015-08-11 00:32:49 +0000408void MIRParserImpl::inferRegisterInfo(MachineFunction &MF,
409 const yaml::MachineFunction &YamlMF) {
410 if (YamlMF.CalleeSavedRegisters)
411 return;
412 for (const MachineBasicBlock &MBB : MF) {
413 for (const MachineInstr &MI : MBB) {
414 for (const MachineOperand &MO : MI.operands()) {
415 if (!MO.isRegMask())
416 continue;
417 MF.getRegInfo().addPhysRegsUsedFromRegMask(MO.getRegMask());
418 }
419 }
420 }
421}
422
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000423bool MIRParserImpl::initializeFrameInfo(MachineFunction &MF,
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000424 const yaml::MachineFunction &YamlMF,
425 PerFunctionMIParsingState &PFS) {
Alex Lorenzdb07c402015-07-28 16:48:37 +0000426 MachineFrameInfo &MFI = *MF.getFrameInfo();
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000427 const Function &F = *MF.getFunction();
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000428 const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
Alex Lorenz60541c12015-07-09 19:55:27 +0000429 MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
430 MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
431 MFI.setHasStackMap(YamlMFI.HasStackMap);
432 MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);
433 MFI.setStackSize(YamlMFI.StackSize);
434 MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment);
435 if (YamlMFI.MaxAlignment)
436 MFI.ensureMaxAlignment(YamlMFI.MaxAlignment);
437 MFI.setAdjustsStack(YamlMFI.AdjustsStack);
438 MFI.setHasCalls(YamlMFI.HasCalls);
439 MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize);
440 MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);
441 MFI.setHasVAStart(YamlMFI.HasVAStart);
442 MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
Alex Lorenza6f9a372015-07-29 21:09:09 +0000443 if (!YamlMFI.SavePoint.Value.empty()) {
444 MachineBasicBlock *MBB = nullptr;
445 if (parseMBBReference(MBB, YamlMFI.SavePoint, MF, PFS))
446 return true;
447 MFI.setSavePoint(MBB);
448 }
449 if (!YamlMFI.RestorePoint.Value.empty()) {
450 MachineBasicBlock *MBB = nullptr;
451 if (parseMBBReference(MBB, YamlMFI.RestorePoint, MF, PFS))
452 return true;
453 MFI.setRestorePoint(MBB);
454 }
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000455
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000456 std::vector<CalleeSavedInfo> CSIInfo;
Alex Lorenzde491f02015-07-13 18:07:26 +0000457 // Initialize the fixed frame objects.
458 for (const auto &Object : YamlMF.FixedStackObjects) {
459 int ObjectIdx;
460 if (Object.Type != yaml::FixedMachineStackObject::SpillSlot)
461 ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset,
462 Object.IsImmutable, Object.IsAliased);
463 else
464 ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
465 MFI.setObjectAlignment(ObjectIdx, Object.Alignment);
Alex Lorenz1d9a3032015-08-10 23:45:02 +0000466 if (!PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID.Value,
467 ObjectIdx))
468 .second)
469 return error(Object.ID.SourceRange.Start,
470 Twine("redefinition of fixed stack object '%fixed-stack.") +
471 Twine(Object.ID.Value) + "'");
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000472 if (parseCalleeSavedRegister(MF, PFS, CSIInfo, Object.CalleeSavedRegister,
473 ObjectIdx))
474 return true;
Alex Lorenzde491f02015-07-13 18:07:26 +0000475 }
476
477 // Initialize the ordinary frame objects.
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000478 for (const auto &Object : YamlMF.StackObjects) {
Alex Lorenz418f3ec2015-07-14 00:26:26 +0000479 int ObjectIdx;
Alex Lorenz37643a02015-07-15 22:14:49 +0000480 const AllocaInst *Alloca = nullptr;
481 const yaml::StringValue &Name = Object.Name;
482 if (!Name.Value.empty()) {
483 Alloca = dyn_cast_or_null<AllocaInst>(
484 F.getValueSymbolTable().lookup(Name.Value));
485 if (!Alloca)
486 return error(Name.SourceRange.Start,
487 "alloca instruction named '" + Name.Value +
488 "' isn't defined in the function '" + F.getName() +
489 "'");
490 }
Alex Lorenz418f3ec2015-07-14 00:26:26 +0000491 if (Object.Type == yaml::MachineStackObject::VariableSized)
Alex Lorenz37643a02015-07-15 22:14:49 +0000492 ObjectIdx = MFI.CreateVariableSizedObject(Object.Alignment, Alloca);
Alex Lorenz418f3ec2015-07-14 00:26:26 +0000493 else
494 ObjectIdx = MFI.CreateStackObject(
495 Object.Size, Object.Alignment,
Alex Lorenz37643a02015-07-15 22:14:49 +0000496 Object.Type == yaml::MachineStackObject::SpillSlot, Alloca);
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000497 MFI.setObjectOffset(ObjectIdx, Object.Offset);
Alex Lorenzc5d35ba2015-08-10 23:50:41 +0000498 if (!PFS.StackObjectSlots.insert(std::make_pair(Object.ID.Value, ObjectIdx))
499 .second)
500 return error(Object.ID.SourceRange.Start,
501 Twine("redefinition of stack object '%stack.") +
502 Twine(Object.ID.Value) + "'");
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000503 if (parseCalleeSavedRegister(MF, PFS, CSIInfo, Object.CalleeSavedRegister,
504 ObjectIdx))
505 return true;
Alex Lorenza56ba6a2015-08-17 22:17:42 +0000506 if (Object.LocalOffset)
507 MFI.mapLocalFrameObject(ObjectIdx, Object.LocalOffset.getValue());
Alex Lorenzdf9e3c62015-08-19 00:13:25 +0000508 if (parseStackObjectsDebugInfo(MF, PFS, Object, ObjectIdx))
509 return true;
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000510 }
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000511 MFI.setCalleeSavedInfo(CSIInfo);
512 if (!CSIInfo.empty())
513 MFI.setCalleeSavedInfoValid(true);
Alex Lorenza314d812015-08-18 22:26:26 +0000514
515 // Initialize the various stack object references after initializing the
516 // stack objects.
517 if (!YamlMFI.StackProtector.Value.empty()) {
518 SMDiagnostic Error;
519 int FI;
520 if (parseStackObjectReference(FI, SM, MF, YamlMFI.StackProtector.Value, PFS,
521 IRSlots, Error))
522 return error(Error, YamlMFI.StackProtector.SourceRange);
523 MFI.setStackProtectorIndex(FI);
524 }
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000525 return false;
526}
527
528bool MIRParserImpl::parseCalleeSavedRegister(
529 MachineFunction &MF, PerFunctionMIParsingState &PFS,
530 std::vector<CalleeSavedInfo> &CSIInfo,
531 const yaml::StringValue &RegisterSource, int FrameIdx) {
532 if (RegisterSource.Value.empty())
533 return false;
534 unsigned Reg = 0;
535 SMDiagnostic Error;
536 if (parseNamedRegisterReference(Reg, SM, MF, RegisterSource.Value, PFS,
537 IRSlots, Error))
538 return error(Error, RegisterSource.SourceRange);
539 CSIInfo.push_back(CalleeSavedInfo(Reg, FrameIdx));
Alex Lorenz60541c12015-07-09 19:55:27 +0000540 return false;
541}
542
Alex Lorenzdf9e3c62015-08-19 00:13:25 +0000543/// Verify that given node is of a certain type. Return true on error.
544template <typename T>
545static bool typecheckMDNode(T *&Result, MDNode *Node,
546 const yaml::StringValue &Source,
547 StringRef TypeString, MIRParserImpl &Parser) {
548 if (!Node)
549 return false;
550 Result = dyn_cast<T>(Node);
551 if (!Result)
552 return Parser.error(Source.SourceRange.Start,
553 "expected a reference to a '" + TypeString +
554 "' metadata node");
555 return false;
556}
557
558bool MIRParserImpl::parseStackObjectsDebugInfo(
559 MachineFunction &MF, PerFunctionMIParsingState &PFS,
560 const yaml::MachineStackObject &Object, int FrameIdx) {
561 // Debug information can only be attached to stack objects; Fixed stack
562 // objects aren't supported.
563 assert(FrameIdx >= 0 && "Expected a stack object frame index");
564 MDNode *Var = nullptr, *Expr = nullptr, *Loc = nullptr;
565 if (parseMDNode(Var, Object.DebugVar, MF, PFS) ||
566 parseMDNode(Expr, Object.DebugExpr, MF, PFS) ||
567 parseMDNode(Loc, Object.DebugLoc, MF, PFS))
568 return true;
569 if (!Var && !Expr && !Loc)
570 return false;
571 DILocalVariable *DIVar = nullptr;
572 DIExpression *DIExpr = nullptr;
573 DILocation *DILoc = nullptr;
574 if (typecheckMDNode(DIVar, Var, Object.DebugVar, "DILocalVariable", *this) ||
575 typecheckMDNode(DIExpr, Expr, Object.DebugExpr, "DIExpression", *this) ||
576 typecheckMDNode(DILoc, Loc, Object.DebugLoc, "DILocation", *this))
577 return true;
578 MF.getMMI().setVariableDbgInfo(DIVar, DIExpr, unsigned(FrameIdx), DILoc);
579 return false;
580}
581
582bool MIRParserImpl::parseMDNode(MDNode *&Node, const yaml::StringValue &Source,
583 MachineFunction &MF,
584 const PerFunctionMIParsingState &PFS) {
585 if (Source.Value.empty())
586 return false;
587 SMDiagnostic Error;
588 if (llvm::parseMDNode(Node, SM, MF, Source.Value, PFS, IRSlots, Error))
589 return error(Error, Source.SourceRange);
590 return false;
591}
592
Alex Lorenzab980492015-07-20 20:51:18 +0000593bool MIRParserImpl::initializeConstantPool(
594 MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF,
595 const MachineFunction &MF,
596 DenseMap<unsigned, unsigned> &ConstantPoolSlots) {
597 const auto &M = *MF.getFunction()->getParent();
598 SMDiagnostic Error;
599 for (const auto &YamlConstant : YamlMF.Constants) {
600 const Constant *Value = dyn_cast_or_null<Constant>(
601 parseConstantValue(YamlConstant.Value.Value, Error, M));
602 if (!Value)
603 return error(Error, YamlConstant.Value.SourceRange);
604 unsigned Alignment =
605 YamlConstant.Alignment
606 ? YamlConstant.Alignment
607 : M.getDataLayout().getPrefTypeAlignment(Value->getType());
Alex Lorenz60bf5992015-07-30 22:00:17 +0000608 unsigned Index = ConstantPool.getConstantPoolIndex(Value, Alignment);
609 if (!ConstantPoolSlots.insert(std::make_pair(YamlConstant.ID.Value, Index))
610 .second)
611 return error(YamlConstant.ID.SourceRange.Start,
612 Twine("redefinition of constant pool item '%const.") +
613 Twine(YamlConstant.ID.Value) + "'");
Alex Lorenzab980492015-07-20 20:51:18 +0000614 }
615 return false;
616}
617
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000618bool MIRParserImpl::initializeJumpTableInfo(
619 MachineFunction &MF, const yaml::MachineJumpTable &YamlJTI,
Alex Lorenz31d70682015-07-15 23:38:35 +0000620 PerFunctionMIParsingState &PFS) {
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000621 MachineJumpTableInfo *JTI = MF.getOrCreateJumpTableInfo(YamlJTI.Kind);
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000622 for (const auto &Entry : YamlJTI.Entries) {
623 std::vector<MachineBasicBlock *> Blocks;
624 for (const auto &MBBSource : Entry.Blocks) {
625 MachineBasicBlock *MBB = nullptr;
Alex Lorenz05fa73b2015-07-29 20:57:11 +0000626 if (parseMBBReference(MBB, MBBSource.Value, MF, PFS))
627 return true;
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000628 Blocks.push_back(MBB);
629 }
Alex Lorenz31d70682015-07-15 23:38:35 +0000630 unsigned Index = JTI->createJumpTableIndex(Blocks);
Alex Lorenz59ed5912015-07-31 23:13:23 +0000631 if (!PFS.JumpTableSlots.insert(std::make_pair(Entry.ID.Value, Index))
632 .second)
633 return error(Entry.ID.SourceRange.Start,
634 Twine("redefinition of jump table entry '%jump-table.") +
635 Twine(Entry.ID.Value) + "'");
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000636 }
637 return false;
638}
639
Alex Lorenz05fa73b2015-07-29 20:57:11 +0000640bool MIRParserImpl::parseMBBReference(MachineBasicBlock *&MBB,
641 const yaml::StringValue &Source,
642 MachineFunction &MF,
643 const PerFunctionMIParsingState &PFS) {
644 SMDiagnostic Error;
645 if (llvm::parseMBBReference(MBB, SM, MF, Source.Value, PFS, IRSlots, Error))
646 return error(Error, Source.SourceRange);
647 return false;
648}
649
Alex Lorenz51af1602015-06-23 22:39:23 +0000650SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
651 SMRange SourceRange) {
652 assert(SourceRange.isValid() && "Invalid source range");
653 SMLoc Loc = SourceRange.Start;
654 bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
655 *Loc.getPointer() == '\'';
656 // Translate the location of the error from the location in the MI string to
657 // the corresponding location in the MIR file.
658 Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
659 (HasQuote ? 1 : 0));
660
661 // TODO: Translate any source ranges as well.
662 return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None,
663 Error.getFixIts());
664}
665
Alex Lorenz9b62cf62015-08-13 20:30:11 +0000666SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error,
667 SMRange SourceRange) {
Alex Lorenz09b832c2015-05-29 17:05:41 +0000668 assert(SourceRange.isValid());
669
670 // Translate the location of the error from the location in the llvm IR string
671 // to the corresponding location in the MIR file.
672 auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
673 unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
674 unsigned Column = Error.getColumnNo();
675 StringRef LineStr = Error.getLineContents();
676 SMLoc Loc = Error.getLoc();
677
678 // Get the full line and adjust the column number by taking the indentation of
679 // LLVM IR into account.
680 for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
681 L != E; ++L) {
682 if (L.line_number() == Line) {
683 LineStr = *L;
684 Loc = SMLoc::getFromPointer(LineStr.data());
685 auto Indent = LineStr.find(Error.getLineContents());
686 if (Indent != StringRef::npos)
687 Column += Indent;
688 break;
689 }
690 }
691
692 return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
693 Error.getMessage(), LineStr, Error.getRanges(),
694 Error.getFixIts());
695}
696
Alex Lorenz28148ba2015-07-09 22:23:13 +0000697void MIRParserImpl::initNames2RegClasses(const MachineFunction &MF) {
698 if (!Names2RegClasses.empty())
699 return;
700 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
701 for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) {
702 const auto *RC = TRI->getRegClass(I);
703 Names2RegClasses.insert(
704 std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC));
705 }
706}
707
708const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF,
709 StringRef Name) {
710 initNames2RegClasses(MF);
711 auto RegClassInfo = Names2RegClasses.find(Name);
712 if (RegClassInfo == Names2RegClasses.end())
713 return nullptr;
714 return RegClassInfo->getValue();
715}
716
Alex Lorenz735c47e2015-06-15 20:30:22 +0000717MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
718 : Impl(std::move(Impl)) {}
719
720MIRParser::~MIRParser() {}
721
722std::unique_ptr<Module> MIRParser::parseLLVMModule() { return Impl->parse(); }
723
724bool MIRParser::initializeMachineFunction(MachineFunction &MF) {
725 return Impl->initializeMachineFunction(MF);
726}
727
728std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename,
729 SMDiagnostic &Error,
730 LLVMContext &Context) {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000731 auto FileOrErr = MemoryBuffer::getFile(Filename);
732 if (std::error_code EC = FileOrErr.getError()) {
733 Error = SMDiagnostic(Filename, SourceMgr::DK_Error,
734 "Could not open input file: " + EC.message());
Alex Lorenz735c47e2015-06-15 20:30:22 +0000735 return nullptr;
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000736 }
Alex Lorenz735c47e2015-06-15 20:30:22 +0000737 return createMIRParser(std::move(FileOrErr.get()), Context);
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000738}
739
Alex Lorenz735c47e2015-06-15 20:30:22 +0000740std::unique_ptr<MIRParser>
741llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
742 LLVMContext &Context) {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000743 auto Filename = Contents->getBufferIdentifier();
Alex Lorenz735c47e2015-06-15 20:30:22 +0000744 return llvm::make_unique<MIRParser>(
745 llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context));
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000746}