blob: 422efbc5ce573fc25261f7214410aa9fc8d6c66b [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) {
350 const auto *RC = getRegClass(MF, VReg.Class.Value);
351 if (!RC)
352 return error(VReg.Class.SourceRange.Start,
353 Twine("use of undefined register class '") +
354 VReg.Class.Value + "'");
Alex Lorenz53464512015-07-10 22:51:20 +0000355 unsigned Reg = RegInfo.createVirtualRegister(RC);
Alex Lorenza06c0c62015-07-30 21:54:10 +0000356 if (!PFS.VirtualRegisterSlots.insert(std::make_pair(VReg.ID.Value, Reg))
357 .second)
358 return error(VReg.ID.SourceRange.Start,
359 Twine("redefinition of virtual register '%") +
360 Twine(VReg.ID.Value) + "'");
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000361 if (!VReg.PreferredRegister.Value.empty()) {
362 unsigned PreferredReg = 0;
363 if (parseNamedRegisterReference(PreferredReg, SM, MF,
364 VReg.PreferredRegister.Value, PFS,
365 IRSlots, Error))
366 return error(Error, VReg.PreferredRegister.SourceRange);
367 RegInfo.setSimpleHint(Reg, PreferredReg);
368 }
Alex Lorenz28148ba2015-07-09 22:23:13 +0000369 }
Alex Lorenz12045a42015-07-27 17:42:45 +0000370
371 // Parse the liveins.
372 for (const auto &LiveIn : YamlMF.LiveIns) {
373 unsigned Reg = 0;
374 if (parseNamedRegisterReference(Reg, SM, MF, LiveIn.Register.Value, PFS,
375 IRSlots, Error))
376 return error(Error, LiveIn.Register.SourceRange);
377 unsigned VReg = 0;
378 if (!LiveIn.VirtualRegister.Value.empty()) {
379 if (parseVirtualRegisterReference(
380 VReg, SM, MF, LiveIn.VirtualRegister.Value, PFS, IRSlots, Error))
381 return error(Error, LiveIn.VirtualRegister.SourceRange);
382 }
383 RegInfo.addLiveIn(Reg, VReg);
384 }
Alex Lorenzc4838082015-08-11 00:32:49 +0000385
386 // Parse the callee saved register mask.
387 BitVector CalleeSavedRegisterMask(RegInfo.getUsedPhysRegsMask().size());
388 if (!YamlMF.CalleeSavedRegisters)
389 return false;
390 for (const auto &RegSource : YamlMF.CalleeSavedRegisters.getValue()) {
391 unsigned Reg = 0;
392 if (parseNamedRegisterReference(Reg, SM, MF, RegSource.Value, PFS, IRSlots,
393 Error))
394 return error(Error, RegSource.SourceRange);
395 CalleeSavedRegisterMask[Reg] = true;
396 }
397 RegInfo.setUsedPhysRegMask(CalleeSavedRegisterMask.flip());
Alex Lorenz54565cf2015-06-24 19:56:10 +0000398 return false;
399}
400
Alex Lorenzc4838082015-08-11 00:32:49 +0000401void MIRParserImpl::inferRegisterInfo(MachineFunction &MF,
402 const yaml::MachineFunction &YamlMF) {
403 if (YamlMF.CalleeSavedRegisters)
404 return;
405 for (const MachineBasicBlock &MBB : MF) {
406 for (const MachineInstr &MI : MBB) {
407 for (const MachineOperand &MO : MI.operands()) {
408 if (!MO.isRegMask())
409 continue;
410 MF.getRegInfo().addPhysRegsUsedFromRegMask(MO.getRegMask());
411 }
412 }
413 }
414}
415
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000416bool MIRParserImpl::initializeFrameInfo(MachineFunction &MF,
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000417 const yaml::MachineFunction &YamlMF,
418 PerFunctionMIParsingState &PFS) {
Alex Lorenzdb07c402015-07-28 16:48:37 +0000419 MachineFrameInfo &MFI = *MF.getFrameInfo();
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000420 const Function &F = *MF.getFunction();
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000421 const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
Alex Lorenz60541c12015-07-09 19:55:27 +0000422 MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
423 MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
424 MFI.setHasStackMap(YamlMFI.HasStackMap);
425 MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);
426 MFI.setStackSize(YamlMFI.StackSize);
427 MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment);
428 if (YamlMFI.MaxAlignment)
429 MFI.ensureMaxAlignment(YamlMFI.MaxAlignment);
430 MFI.setAdjustsStack(YamlMFI.AdjustsStack);
431 MFI.setHasCalls(YamlMFI.HasCalls);
432 MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize);
433 MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);
434 MFI.setHasVAStart(YamlMFI.HasVAStart);
435 MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
Alex Lorenza6f9a372015-07-29 21:09:09 +0000436 if (!YamlMFI.SavePoint.Value.empty()) {
437 MachineBasicBlock *MBB = nullptr;
438 if (parseMBBReference(MBB, YamlMFI.SavePoint, MF, PFS))
439 return true;
440 MFI.setSavePoint(MBB);
441 }
442 if (!YamlMFI.RestorePoint.Value.empty()) {
443 MachineBasicBlock *MBB = nullptr;
444 if (parseMBBReference(MBB, YamlMFI.RestorePoint, MF, PFS))
445 return true;
446 MFI.setRestorePoint(MBB);
447 }
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000448
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000449 std::vector<CalleeSavedInfo> CSIInfo;
Alex Lorenzde491f02015-07-13 18:07:26 +0000450 // Initialize the fixed frame objects.
451 for (const auto &Object : YamlMF.FixedStackObjects) {
452 int ObjectIdx;
453 if (Object.Type != yaml::FixedMachineStackObject::SpillSlot)
454 ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset,
455 Object.IsImmutable, Object.IsAliased);
456 else
457 ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
458 MFI.setObjectAlignment(ObjectIdx, Object.Alignment);
Alex Lorenz1d9a3032015-08-10 23:45:02 +0000459 if (!PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID.Value,
460 ObjectIdx))
461 .second)
462 return error(Object.ID.SourceRange.Start,
463 Twine("redefinition of fixed stack object '%fixed-stack.") +
464 Twine(Object.ID.Value) + "'");
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000465 if (parseCalleeSavedRegister(MF, PFS, CSIInfo, Object.CalleeSavedRegister,
466 ObjectIdx))
467 return true;
Alex Lorenzde491f02015-07-13 18:07:26 +0000468 }
469
470 // Initialize the ordinary frame objects.
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000471 for (const auto &Object : YamlMF.StackObjects) {
Alex Lorenz418f3ec2015-07-14 00:26:26 +0000472 int ObjectIdx;
Alex Lorenz37643a02015-07-15 22:14:49 +0000473 const AllocaInst *Alloca = nullptr;
474 const yaml::StringValue &Name = Object.Name;
475 if (!Name.Value.empty()) {
476 Alloca = dyn_cast_or_null<AllocaInst>(
477 F.getValueSymbolTable().lookup(Name.Value));
478 if (!Alloca)
479 return error(Name.SourceRange.Start,
480 "alloca instruction named '" + Name.Value +
481 "' isn't defined in the function '" + F.getName() +
482 "'");
483 }
Alex Lorenz418f3ec2015-07-14 00:26:26 +0000484 if (Object.Type == yaml::MachineStackObject::VariableSized)
Alex Lorenz37643a02015-07-15 22:14:49 +0000485 ObjectIdx = MFI.CreateVariableSizedObject(Object.Alignment, Alloca);
Alex Lorenz418f3ec2015-07-14 00:26:26 +0000486 else
487 ObjectIdx = MFI.CreateStackObject(
488 Object.Size, Object.Alignment,
Alex Lorenz37643a02015-07-15 22:14:49 +0000489 Object.Type == yaml::MachineStackObject::SpillSlot, Alloca);
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000490 MFI.setObjectOffset(ObjectIdx, Object.Offset);
Alex Lorenzc5d35ba2015-08-10 23:50:41 +0000491 if (!PFS.StackObjectSlots.insert(std::make_pair(Object.ID.Value, ObjectIdx))
492 .second)
493 return error(Object.ID.SourceRange.Start,
494 Twine("redefinition of stack object '%stack.") +
495 Twine(Object.ID.Value) + "'");
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000496 if (parseCalleeSavedRegister(MF, PFS, CSIInfo, Object.CalleeSavedRegister,
497 ObjectIdx))
498 return true;
Alex Lorenza56ba6a2015-08-17 22:17:42 +0000499 if (Object.LocalOffset)
500 MFI.mapLocalFrameObject(ObjectIdx, Object.LocalOffset.getValue());
Alex Lorenzdf9e3c62015-08-19 00:13:25 +0000501 if (parseStackObjectsDebugInfo(MF, PFS, Object, ObjectIdx))
502 return true;
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000503 }
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000504 MFI.setCalleeSavedInfo(CSIInfo);
505 if (!CSIInfo.empty())
506 MFI.setCalleeSavedInfoValid(true);
Alex Lorenza314d812015-08-18 22:26:26 +0000507
508 // Initialize the various stack object references after initializing the
509 // stack objects.
510 if (!YamlMFI.StackProtector.Value.empty()) {
511 SMDiagnostic Error;
512 int FI;
513 if (parseStackObjectReference(FI, SM, MF, YamlMFI.StackProtector.Value, PFS,
514 IRSlots, Error))
515 return error(Error, YamlMFI.StackProtector.SourceRange);
516 MFI.setStackProtectorIndex(FI);
517 }
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000518 return false;
519}
520
521bool MIRParserImpl::parseCalleeSavedRegister(
522 MachineFunction &MF, PerFunctionMIParsingState &PFS,
523 std::vector<CalleeSavedInfo> &CSIInfo,
524 const yaml::StringValue &RegisterSource, int FrameIdx) {
525 if (RegisterSource.Value.empty())
526 return false;
527 unsigned Reg = 0;
528 SMDiagnostic Error;
529 if (parseNamedRegisterReference(Reg, SM, MF, RegisterSource.Value, PFS,
530 IRSlots, Error))
531 return error(Error, RegisterSource.SourceRange);
532 CSIInfo.push_back(CalleeSavedInfo(Reg, FrameIdx));
Alex Lorenz60541c12015-07-09 19:55:27 +0000533 return false;
534}
535
Alex Lorenzdf9e3c62015-08-19 00:13:25 +0000536/// Verify that given node is of a certain type. Return true on error.
537template <typename T>
538static bool typecheckMDNode(T *&Result, MDNode *Node,
539 const yaml::StringValue &Source,
540 StringRef TypeString, MIRParserImpl &Parser) {
541 if (!Node)
542 return false;
543 Result = dyn_cast<T>(Node);
544 if (!Result)
545 return Parser.error(Source.SourceRange.Start,
546 "expected a reference to a '" + TypeString +
547 "' metadata node");
548 return false;
549}
550
551bool MIRParserImpl::parseStackObjectsDebugInfo(
552 MachineFunction &MF, PerFunctionMIParsingState &PFS,
553 const yaml::MachineStackObject &Object, int FrameIdx) {
554 // Debug information can only be attached to stack objects; Fixed stack
555 // objects aren't supported.
556 assert(FrameIdx >= 0 && "Expected a stack object frame index");
557 MDNode *Var = nullptr, *Expr = nullptr, *Loc = nullptr;
558 if (parseMDNode(Var, Object.DebugVar, MF, PFS) ||
559 parseMDNode(Expr, Object.DebugExpr, MF, PFS) ||
560 parseMDNode(Loc, Object.DebugLoc, MF, PFS))
561 return true;
562 if (!Var && !Expr && !Loc)
563 return false;
564 DILocalVariable *DIVar = nullptr;
565 DIExpression *DIExpr = nullptr;
566 DILocation *DILoc = nullptr;
567 if (typecheckMDNode(DIVar, Var, Object.DebugVar, "DILocalVariable", *this) ||
568 typecheckMDNode(DIExpr, Expr, Object.DebugExpr, "DIExpression", *this) ||
569 typecheckMDNode(DILoc, Loc, Object.DebugLoc, "DILocation", *this))
570 return true;
571 MF.getMMI().setVariableDbgInfo(DIVar, DIExpr, unsigned(FrameIdx), DILoc);
572 return false;
573}
574
575bool MIRParserImpl::parseMDNode(MDNode *&Node, const yaml::StringValue &Source,
576 MachineFunction &MF,
577 const PerFunctionMIParsingState &PFS) {
578 if (Source.Value.empty())
579 return false;
580 SMDiagnostic Error;
581 if (llvm::parseMDNode(Node, SM, MF, Source.Value, PFS, IRSlots, Error))
582 return error(Error, Source.SourceRange);
583 return false;
584}
585
Alex Lorenzab980492015-07-20 20:51:18 +0000586bool MIRParserImpl::initializeConstantPool(
587 MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF,
588 const MachineFunction &MF,
589 DenseMap<unsigned, unsigned> &ConstantPoolSlots) {
590 const auto &M = *MF.getFunction()->getParent();
591 SMDiagnostic Error;
592 for (const auto &YamlConstant : YamlMF.Constants) {
593 const Constant *Value = dyn_cast_or_null<Constant>(
594 parseConstantValue(YamlConstant.Value.Value, Error, M));
595 if (!Value)
596 return error(Error, YamlConstant.Value.SourceRange);
597 unsigned Alignment =
598 YamlConstant.Alignment
599 ? YamlConstant.Alignment
600 : M.getDataLayout().getPrefTypeAlignment(Value->getType());
Alex Lorenz60bf5992015-07-30 22:00:17 +0000601 unsigned Index = ConstantPool.getConstantPoolIndex(Value, Alignment);
602 if (!ConstantPoolSlots.insert(std::make_pair(YamlConstant.ID.Value, Index))
603 .second)
604 return error(YamlConstant.ID.SourceRange.Start,
605 Twine("redefinition of constant pool item '%const.") +
606 Twine(YamlConstant.ID.Value) + "'");
Alex Lorenzab980492015-07-20 20:51:18 +0000607 }
608 return false;
609}
610
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000611bool MIRParserImpl::initializeJumpTableInfo(
612 MachineFunction &MF, const yaml::MachineJumpTable &YamlJTI,
Alex Lorenz31d70682015-07-15 23:38:35 +0000613 PerFunctionMIParsingState &PFS) {
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000614 MachineJumpTableInfo *JTI = MF.getOrCreateJumpTableInfo(YamlJTI.Kind);
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000615 for (const auto &Entry : YamlJTI.Entries) {
616 std::vector<MachineBasicBlock *> Blocks;
617 for (const auto &MBBSource : Entry.Blocks) {
618 MachineBasicBlock *MBB = nullptr;
Alex Lorenz05fa73b2015-07-29 20:57:11 +0000619 if (parseMBBReference(MBB, MBBSource.Value, MF, PFS))
620 return true;
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000621 Blocks.push_back(MBB);
622 }
Alex Lorenz31d70682015-07-15 23:38:35 +0000623 unsigned Index = JTI->createJumpTableIndex(Blocks);
Alex Lorenz59ed5912015-07-31 23:13:23 +0000624 if (!PFS.JumpTableSlots.insert(std::make_pair(Entry.ID.Value, Index))
625 .second)
626 return error(Entry.ID.SourceRange.Start,
627 Twine("redefinition of jump table entry '%jump-table.") +
628 Twine(Entry.ID.Value) + "'");
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000629 }
630 return false;
631}
632
Alex Lorenz05fa73b2015-07-29 20:57:11 +0000633bool MIRParserImpl::parseMBBReference(MachineBasicBlock *&MBB,
634 const yaml::StringValue &Source,
635 MachineFunction &MF,
636 const PerFunctionMIParsingState &PFS) {
637 SMDiagnostic Error;
638 if (llvm::parseMBBReference(MBB, SM, MF, Source.Value, PFS, IRSlots, Error))
639 return error(Error, Source.SourceRange);
640 return false;
641}
642
Alex Lorenz51af1602015-06-23 22:39:23 +0000643SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
644 SMRange SourceRange) {
645 assert(SourceRange.isValid() && "Invalid source range");
646 SMLoc Loc = SourceRange.Start;
647 bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
648 *Loc.getPointer() == '\'';
649 // Translate the location of the error from the location in the MI string to
650 // the corresponding location in the MIR file.
651 Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
652 (HasQuote ? 1 : 0));
653
654 // TODO: Translate any source ranges as well.
655 return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None,
656 Error.getFixIts());
657}
658
Alex Lorenz9b62cf62015-08-13 20:30:11 +0000659SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error,
660 SMRange SourceRange) {
Alex Lorenz09b832c2015-05-29 17:05:41 +0000661 assert(SourceRange.isValid());
662
663 // Translate the location of the error from the location in the llvm IR string
664 // to the corresponding location in the MIR file.
665 auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
666 unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
667 unsigned Column = Error.getColumnNo();
668 StringRef LineStr = Error.getLineContents();
669 SMLoc Loc = Error.getLoc();
670
671 // Get the full line and adjust the column number by taking the indentation of
672 // LLVM IR into account.
673 for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
674 L != E; ++L) {
675 if (L.line_number() == Line) {
676 LineStr = *L;
677 Loc = SMLoc::getFromPointer(LineStr.data());
678 auto Indent = LineStr.find(Error.getLineContents());
679 if (Indent != StringRef::npos)
680 Column += Indent;
681 break;
682 }
683 }
684
685 return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
686 Error.getMessage(), LineStr, Error.getRanges(),
687 Error.getFixIts());
688}
689
Alex Lorenz28148ba2015-07-09 22:23:13 +0000690void MIRParserImpl::initNames2RegClasses(const MachineFunction &MF) {
691 if (!Names2RegClasses.empty())
692 return;
693 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
694 for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) {
695 const auto *RC = TRI->getRegClass(I);
696 Names2RegClasses.insert(
697 std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC));
698 }
699}
700
701const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF,
702 StringRef Name) {
703 initNames2RegClasses(MF);
704 auto RegClassInfo = Names2RegClasses.find(Name);
705 if (RegClassInfo == Names2RegClasses.end())
706 return nullptr;
707 return RegClassInfo->getValue();
708}
709
Alex Lorenz735c47e2015-06-15 20:30:22 +0000710MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
711 : Impl(std::move(Impl)) {}
712
713MIRParser::~MIRParser() {}
714
715std::unique_ptr<Module> MIRParser::parseLLVMModule() { return Impl->parse(); }
716
717bool MIRParser::initializeMachineFunction(MachineFunction &MF) {
718 return Impl->initializeMachineFunction(MF);
719}
720
721std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename,
722 SMDiagnostic &Error,
723 LLVMContext &Context) {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000724 auto FileOrErr = MemoryBuffer::getFile(Filename);
725 if (std::error_code EC = FileOrErr.getError()) {
726 Error = SMDiagnostic(Filename, SourceMgr::DK_Error,
727 "Could not open input file: " + EC.message());
Alex Lorenz735c47e2015-06-15 20:30:22 +0000728 return nullptr;
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000729 }
Alex Lorenz735c47e2015-06-15 20:30:22 +0000730 return createMIRParser(std::move(FileOrErr.get()), Context);
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000731}
732
Alex Lorenz735c47e2015-06-15 20:30:22 +0000733std::unique_ptr<MIRParser>
734llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
735 LLVMContext &Context) {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000736 auto Filename = Contents->getBufferIdentifier();
Alex Lorenz735c47e2015-06-15 20:30:22 +0000737 return llvm::make_unique<MIRParser>(
738 llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context));
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000739}