blob: 99fcf91212908fe782a038369b9f51ce4c08a306 [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/STLExtras.h"
Quentin Colombet876ddf82016-04-08 16:40:43 +000019#include "llvm/ADT/StringMap.h"
20#include "llvm/ADT/StringRef.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000021#include "llvm/AsmParser/Parser.h"
Alex Lorenz5d6108e2015-06-26 22:56:48 +000022#include "llvm/AsmParser/SlotMapping.h"
Quentin Colombet876ddf82016-04-08 16:40:43 +000023#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
24#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
25#include "llvm/CodeGen/MIRYamlMapping.h"
Alex Lorenzab980492015-07-20 20:51:18 +000026#include "llvm/CodeGen/MachineConstantPool.h"
Alex Lorenz60541c12015-07-09 19:55:27 +000027#include "llvm/CodeGen/MachineFrameInfo.h"
Quentin Colombet876ddf82016-04-08 16:40:43 +000028#include "llvm/CodeGen/MachineFunction.h"
Alex Lorenzdf9e3c62015-08-19 00:13:25 +000029#include "llvm/CodeGen/MachineModuleInfo.h"
Alex Lorenz54565cf2015-06-24 19:56:10 +000030#include "llvm/CodeGen/MachineRegisterInfo.h"
Alex Lorenz4f093bf2015-06-19 17:43:07 +000031#include "llvm/IR/BasicBlock.h"
Alex Lorenz735c47e2015-06-15 20:30:22 +000032#include "llvm/IR/DiagnosticInfo.h"
Alex Lorenz8e7a58d72015-06-15 23:07:38 +000033#include "llvm/IR/Instructions.h"
Alex Lorenz735c47e2015-06-15 20:30:22 +000034#include "llvm/IR/LLVMContext.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000035#include "llvm/IR/Module.h"
Alex Lorenz4f093bf2015-06-19 17:43:07 +000036#include "llvm/IR/ValueSymbolTable.h"
Alex Lorenz09b832c2015-05-29 17:05:41 +000037#include "llvm/Support/LineIterator.h"
Quentin Colombet876ddf82016-04-08 16:40:43 +000038#include "llvm/Support/MemoryBuffer.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000039#include "llvm/Support/SMLoc.h"
40#include "llvm/Support/SourceMgr.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000041#include "llvm/Support/YAMLTraits.h"
42#include <memory>
43
44using namespace llvm;
45
Alex Lorenz735c47e2015-06-15 20:30:22 +000046namespace llvm {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000047
48/// This class implements the parsing of LLVM IR that's embedded inside a MIR
49/// file.
50class MIRParserImpl {
51 SourceMgr SM;
52 StringRef Filename;
53 LLVMContext &Context;
Alex Lorenz735c47e2015-06-15 20:30:22 +000054 StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;
Alex Lorenz5d6108e2015-06-26 22:56:48 +000055 SlotMapping IRSlots;
Alex Lorenz28148ba2015-07-09 22:23:13 +000056 /// Maps from register class names to register classes.
57 StringMap<const TargetRegisterClass *> Names2RegClasses;
Quentin Colombet876ddf82016-04-08 16:40:43 +000058 /// Maps from register bank names to register banks.
59 StringMap<const RegisterBank *> Names2RegBanks;
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000060
61public:
62 MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
63 LLVMContext &Context);
64
Alex Lorenz735c47e2015-06-15 20:30:22 +000065 void reportDiagnostic(const SMDiagnostic &Diag);
66
67 /// Report an error with the given message at unknown location.
68 ///
69 /// Always returns true.
70 bool error(const Twine &Message);
71
Alex Lorenzb1f9ce82015-07-08 20:22:20 +000072 /// Report an error with the given message at the given location.
73 ///
74 /// Always returns true.
75 bool error(SMLoc Loc, const Twine &Message);
76
Alex Lorenz0fd7c622015-06-30 17:55:00 +000077 /// Report a given error with the location translated from the location in an
78 /// embedded string literal to a location in the MIR file.
79 ///
80 /// Always returns true.
81 bool error(const SMDiagnostic &Error, SMRange SourceRange);
82
Alex Lorenz78d78312015-05-28 22:41:12 +000083 /// Try to parse the optional LLVM module and the machine functions in the MIR
84 /// file.
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000085 ///
Alex Lorenz78d78312015-05-28 22:41:12 +000086 /// Return null if an error occurred.
Alex Lorenz735c47e2015-06-15 20:30:22 +000087 std::unique_ptr<Module> parse();
Alex Lorenz78d78312015-05-28 22:41:12 +000088
89 /// Parse the machine function in the current YAML document.
90 ///
Alex Lorenz8e7a58d72015-06-15 23:07:38 +000091 /// \param NoLLVMIR - set to true when the MIR file doesn't have LLVM IR.
92 /// A dummy IR function is created and inserted into the given module when
93 /// this parameter is true.
94 ///
Alex Lorenz78d78312015-05-28 22:41:12 +000095 /// Return true if an error occurred.
Alex Lorenz8e7a58d72015-06-15 23:07:38 +000096 bool parseMachineFunction(yaml::Input &In, Module &M, bool NoLLVMIR);
Alex Lorenz09b832c2015-05-29 17:05:41 +000097
Alex Lorenz735c47e2015-06-15 20:30:22 +000098 /// Initialize the machine function to the state that's described in the MIR
99 /// file.
100 ///
101 /// Return true if error occurred.
102 bool initializeMachineFunction(MachineFunction &MF);
103
Alex Lorenzdb07c402015-07-28 16:48:37 +0000104 bool initializeRegisterInfo(MachineFunction &MF,
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000105 const yaml::MachineFunction &YamlMF,
106 PerFunctionMIParsingState &PFS);
Alex Lorenz54565cf2015-06-24 19:56:10 +0000107
Alex Lorenzc4838082015-08-11 00:32:49 +0000108 void inferRegisterInfo(MachineFunction &MF,
109 const yaml::MachineFunction &YamlMF);
110
Alex Lorenzdb07c402015-07-28 16:48:37 +0000111 bool initializeFrameInfo(MachineFunction &MF,
Alex Lorenz7feaf7c2015-07-16 23:37:45 +0000112 const yaml::MachineFunction &YamlMF,
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000113 PerFunctionMIParsingState &PFS);
114
115 bool parseCalleeSavedRegister(MachineFunction &MF,
116 PerFunctionMIParsingState &PFS,
117 std::vector<CalleeSavedInfo> &CSIInfo,
118 const yaml::StringValue &RegisterSource,
119 int FrameIdx);
Alex Lorenz60541c12015-07-09 19:55:27 +0000120
Alex Lorenzdf9e3c62015-08-19 00:13:25 +0000121 bool parseStackObjectsDebugInfo(MachineFunction &MF,
122 PerFunctionMIParsingState &PFS,
123 const yaml::MachineStackObject &Object,
124 int FrameIdx);
125
Alex Lorenzab980492015-07-20 20:51:18 +0000126 bool initializeConstantPool(MachineConstantPool &ConstantPool,
127 const yaml::MachineFunction &YamlMF,
128 const MachineFunction &MF,
129 DenseMap<unsigned, unsigned> &ConstantPoolSlots);
130
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000131 bool initializeJumpTableInfo(MachineFunction &MF,
132 const yaml::MachineJumpTable &YamlJTI,
Alex Lorenz31d70682015-07-15 23:38:35 +0000133 PerFunctionMIParsingState &PFS);
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000134
Alex Lorenz09b832c2015-05-29 17:05:41 +0000135private:
Alex Lorenzdf9e3c62015-08-19 00:13:25 +0000136 bool parseMDNode(MDNode *&Node, const yaml::StringValue &Source,
137 MachineFunction &MF, const PerFunctionMIParsingState &PFS);
138
Alex Lorenz05fa73b2015-07-29 20:57:11 +0000139 bool parseMBBReference(MachineBasicBlock *&MBB,
140 const yaml::StringValue &Source, MachineFunction &MF,
141 const PerFunctionMIParsingState &PFS);
142
Alex Lorenz51af1602015-06-23 22:39:23 +0000143 /// Return a MIR diagnostic converted from an MI string diagnostic.
144 SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
145 SMRange SourceRange);
146
Alex Lorenz9b62cf62015-08-13 20:30:11 +0000147 /// Return a MIR diagnostic converted from a diagnostic located in a YAML
148 /// block scalar string.
149 SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error,
150 SMRange SourceRange);
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000151
152 /// Create an empty function with the given name.
153 void createDummyFunction(StringRef Name, Module &M);
Alex Lorenz28148ba2015-07-09 22:23:13 +0000154
155 void initNames2RegClasses(const MachineFunction &MF);
Quentin Colombet876ddf82016-04-08 16:40:43 +0000156 void initNames2RegBanks(const MachineFunction &MF);
Alex Lorenz28148ba2015-07-09 22:23:13 +0000157
158 /// Check if the given identifier is a name of a register class.
159 ///
160 /// Return null if the name isn't a register class.
161 const TargetRegisterClass *getRegClass(const MachineFunction &MF,
162 StringRef Name);
Quentin Colombet876ddf82016-04-08 16:40:43 +0000163
164 /// Check if the given identifier is a name of a register bank.
165 ///
166 /// Return null if the name isn't a register bank.
167 const RegisterBank *getRegBank(const MachineFunction &MF, StringRef Name);
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000168};
169
Alex Lorenz735c47e2015-06-15 20:30:22 +0000170} // end namespace llvm
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000171
172MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
173 StringRef Filename, LLVMContext &Context)
174 : SM(), Filename(Filename), Context(Context) {
175 SM.AddNewSourceBuffer(std::move(Contents), SMLoc());
176}
177
Alex Lorenz735c47e2015-06-15 20:30:22 +0000178bool MIRParserImpl::error(const Twine &Message) {
179 Context.diagnose(DiagnosticInfoMIRParser(
180 DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));
181 return true;
Alex Lorenz78d78312015-05-28 22:41:12 +0000182}
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000183
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000184bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) {
185 Context.diagnose(DiagnosticInfoMIRParser(
186 DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message)));
187 return true;
188}
189
Alex Lorenz0fd7c622015-06-30 17:55:00 +0000190bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) {
191 assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");
192 reportDiagnostic(diagFromMIStringDiag(Error, SourceRange));
193 return true;
194}
195
Alex Lorenz735c47e2015-06-15 20:30:22 +0000196void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
197 DiagnosticSeverity Kind;
198 switch (Diag.getKind()) {
199 case SourceMgr::DK_Error:
200 Kind = DS_Error;
201 break;
202 case SourceMgr::DK_Warning:
203 Kind = DS_Warning;
204 break;
205 case SourceMgr::DK_Note:
206 Kind = DS_Note;
207 break;
208 }
209 Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
210}
211
212static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
213 reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
214}
215
216std::unique_ptr<Module> MIRParserImpl::parse() {
Alex Lorenz78d78312015-05-28 22:41:12 +0000217 yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(),
Alex Lorenz735c47e2015-06-15 20:30:22 +0000218 /*Ctxt=*/nullptr, handleYAMLDiag, this);
Alex Lorenz51af1602015-06-23 22:39:23 +0000219 In.setContext(&In);
Alex Lorenz78d78312015-05-28 22:41:12 +0000220
221 if (!In.setCurrentDocument()) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000222 if (In.error())
Alex Lorenz78d78312015-05-28 22:41:12 +0000223 return nullptr;
224 // Create an empty module when the MIR file is empty.
225 return llvm::make_unique<Module>(Filename, Context);
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000226 }
227
Alex Lorenz78d78312015-05-28 22:41:12 +0000228 std::unique_ptr<Module> M;
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000229 bool NoLLVMIR = false;
Alex Lorenz78d78312015-05-28 22:41:12 +0000230 // Parse the block scalar manually so that we can return unique pointer
231 // without having to go trough YAML traits.
232 if (const auto *BSN =
233 dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000234 SMDiagnostic Error;
Alex Lorenz78d78312015-05-28 22:41:12 +0000235 M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
Alex Lorenz5d6108e2015-06-26 22:56:48 +0000236 Context, &IRSlots);
Alex Lorenz09b832c2015-05-29 17:05:41 +0000237 if (!M) {
Alex Lorenz9b62cf62015-08-13 20:30:11 +0000238 reportDiagnostic(diagFromBlockStringDiag(Error, BSN->getSourceRange()));
Alex Lorenz78d78312015-05-28 22:41:12 +0000239 return M;
Alex Lorenz09b832c2015-05-29 17:05:41 +0000240 }
Alex Lorenz78d78312015-05-28 22:41:12 +0000241 In.nextDocument();
242 if (!In.setCurrentDocument())
243 return M;
244 } else {
245 // Create an new, empty module.
246 M = llvm::make_unique<Module>(Filename, Context);
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000247 NoLLVMIR = true;
Alex Lorenz78d78312015-05-28 22:41:12 +0000248 }
249
250 // Parse the machine functions.
251 do {
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000252 if (parseMachineFunction(In, *M, NoLLVMIR))
Alex Lorenz78d78312015-05-28 22:41:12 +0000253 return nullptr;
254 In.nextDocument();
255 } while (In.setCurrentDocument());
256
257 return M;
258}
259
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000260bool MIRParserImpl::parseMachineFunction(yaml::Input &In, Module &M,
261 bool NoLLVMIR) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000262 auto MF = llvm::make_unique<yaml::MachineFunction>();
263 yaml::yamlize(In, *MF, false);
Alex Lorenz78d78312015-05-28 22:41:12 +0000264 if (In.error())
265 return true;
Alex Lorenz735c47e2015-06-15 20:30:22 +0000266 auto FunctionName = MF->Name;
Alex Lorenzfe2aa972015-06-15 22:23:23 +0000267 if (Functions.find(FunctionName) != Functions.end())
268 return error(Twine("redefinition of machine function '") + FunctionName +
269 "'");
Alex Lorenz735c47e2015-06-15 20:30:22 +0000270 Functions.insert(std::make_pair(FunctionName, std::move(MF)));
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000271 if (NoLLVMIR)
272 createDummyFunction(FunctionName, M);
Alex Lorenz5ef16b82015-06-16 17:06:29 +0000273 else if (!M.getFunction(FunctionName))
274 return error(Twine("function '") + FunctionName +
275 "' isn't defined in the provided LLVM IR");
Alex Lorenz735c47e2015-06-15 20:30:22 +0000276 return false;
277}
278
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000279void MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
280 auto &Context = M.getContext();
281 Function *F = cast<Function>(M.getOrInsertFunction(
282 Name, FunctionType::get(Type::getVoidTy(Context), false)));
283 BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
284 new UnreachableInst(Context, BB);
285}
286
Alex Lorenz735c47e2015-06-15 20:30:22 +0000287bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
288 auto It = Functions.find(MF.getName());
289 if (It == Functions.end())
290 return error(Twine("no machine function information for function '") +
291 MF.getName() + "' in the MIR file");
292 // TODO: Recreate the machine function.
Alex Lorenz5b5f9752015-06-16 00:10:47 +0000293 const yaml::MachineFunction &YamlMF = *It->getValue();
294 if (YamlMF.Alignment)
295 MF.setAlignment(YamlMF.Alignment);
296 MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
297 MF.setHasInlineAsm(YamlMF.HasInlineAsm);
Derek Schuffad154c82016-03-28 17:05:30 +0000298 if (YamlMF.AllVRegsAllocated)
299 MF.getProperties().set(MachineFunctionProperties::Property::AllVRegsAllocated);
Alex Lorenz53464512015-07-10 22:51:20 +0000300 PerFunctionMIParsingState PFS;
Alex Lorenzdb07c402015-07-28 16:48:37 +0000301 if (initializeRegisterInfo(MF, YamlMF, PFS))
Alex Lorenz54565cf2015-06-24 19:56:10 +0000302 return true;
Alex Lorenzab980492015-07-20 20:51:18 +0000303 if (!YamlMF.Constants.empty()) {
304 auto *ConstantPool = MF.getConstantPool();
305 assert(ConstantPool && "Constant pool must be created");
306 if (initializeConstantPool(*ConstantPool, YamlMF, MF,
307 PFS.ConstantPoolSlots))
308 return true;
309 }
Alex Lorenz54565cf2015-06-24 19:56:10 +0000310
Alex Lorenz5022f6b2015-08-13 23:10:16 +0000311 SMDiagnostic Error;
312 if (parseMachineBasicBlockDefinitions(MF, YamlMF.Body.Value.Value, PFS,
313 IRSlots, Error)) {
314 reportDiagnostic(
315 diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
316 return true;
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000317 }
318
Alex Lorenz5022f6b2015-08-13 23:10:16 +0000319 if (MF.empty())
Alex Lorenzc8704b02015-07-09 21:21:33 +0000320 return error(Twine("machine function '") + Twine(MF.getName()) +
321 "' requires at least one machine basic block in its body");
Alex Lorenza6f9a372015-07-29 21:09:09 +0000322 // Initialize the frame information after creating all the MBBs so that the
323 // MBB references in the frame information can be resolved.
324 if (initializeFrameInfo(MF, YamlMF, PFS))
325 return true;
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000326 // Initialize the jump table after creating all the MBBs so that the MBB
327 // references can be resolved.
328 if (!YamlMF.JumpTableInfo.Entries.empty() &&
329 initializeJumpTableInfo(MF, YamlMF.JumpTableInfo, PFS))
330 return true;
Alex Lorenz5022f6b2015-08-13 23:10:16 +0000331 // Parse the machine instructions after creating all of the MBBs so that the
332 // parser can resolve the MBB references.
333 if (parseMachineInstructions(MF, YamlMF.Body.Value.Value, PFS, IRSlots,
334 Error)) {
335 reportDiagnostic(
336 diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
337 return true;
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000338 }
Alex Lorenzc4838082015-08-11 00:32:49 +0000339 inferRegisterInfo(MF, YamlMF);
Alex Lorenzc7bf2042015-07-24 17:44:49 +0000340 // FIXME: This is a temporary workaround until the reserved registers can be
341 // serialized.
342 MF.getRegInfo().freezeReservedRegs(MF);
343 MF.verify();
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000344 return false;
345}
346
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000347bool MIRParserImpl::initializeRegisterInfo(MachineFunction &MF,
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000348 const yaml::MachineFunction &YamlMF,
349 PerFunctionMIParsingState &PFS) {
Alex Lorenzdb07c402015-07-28 16:48:37 +0000350 MachineRegisterInfo &RegInfo = MF.getRegInfo();
Alex Lorenz54565cf2015-06-24 19:56:10 +0000351 assert(RegInfo.isSSA());
352 if (!YamlMF.IsSSA)
353 RegInfo.leaveSSA();
354 assert(RegInfo.tracksLiveness());
355 if (!YamlMF.TracksRegLiveness)
356 RegInfo.invalidateLiveness();
357 RegInfo.enableSubRegLiveness(YamlMF.TracksSubRegLiveness);
Alex Lorenz28148ba2015-07-09 22:23:13 +0000358
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000359 SMDiagnostic Error;
Alex Lorenz28148ba2015-07-09 22:23:13 +0000360 // Parse the virtual register information.
361 for (const auto &VReg : YamlMF.VirtualRegisters) {
Quentin Colombet050b2112016-03-08 01:17:03 +0000362 unsigned Reg;
363 if (StringRef(VReg.Class.Value).equals("_")) {
364 // This is a generic virtual register.
365 // The size will be set appropriately when we reach the definition.
366 Reg = RegInfo.createGenericVirtualRegister(/*Size*/ 1);
367 } else {
368 const auto *RC = getRegClass(MF, VReg.Class.Value);
Quentin Colombet876ddf82016-04-08 16:40:43 +0000369 if (RC) {
370 Reg = RegInfo.createVirtualRegister(RC);
371 } else {
372 const auto *RegBank = getRegBank(MF, VReg.Class.Value);
373 if (!RegBank)
374 return error(
375 VReg.Class.SourceRange.Start,
376 Twine("use of undefined register class or register bank '") +
377 VReg.Class.Value + "'");
378 Reg = RegInfo.createGenericVirtualRegister(/*Size*/ 1);
379 RegInfo.setRegBank(Reg, *RegBank);
380 }
Quentin Colombet050b2112016-03-08 01:17:03 +0000381 }
Alex Lorenza06c0c62015-07-30 21:54:10 +0000382 if (!PFS.VirtualRegisterSlots.insert(std::make_pair(VReg.ID.Value, Reg))
383 .second)
384 return error(VReg.ID.SourceRange.Start,
385 Twine("redefinition of virtual register '%") +
386 Twine(VReg.ID.Value) + "'");
Alex Lorenzab4cbcf2015-07-24 20:35:40 +0000387 if (!VReg.PreferredRegister.Value.empty()) {
388 unsigned PreferredReg = 0;
389 if (parseNamedRegisterReference(PreferredReg, SM, MF,
390 VReg.PreferredRegister.Value, PFS,
391 IRSlots, Error))
392 return error(Error, VReg.PreferredRegister.SourceRange);
393 RegInfo.setSimpleHint(Reg, PreferredReg);
394 }
Alex Lorenz28148ba2015-07-09 22:23:13 +0000395 }
Alex Lorenz12045a42015-07-27 17:42:45 +0000396
397 // Parse the liveins.
398 for (const auto &LiveIn : YamlMF.LiveIns) {
399 unsigned Reg = 0;
400 if (parseNamedRegisterReference(Reg, SM, MF, LiveIn.Register.Value, PFS,
401 IRSlots, Error))
402 return error(Error, LiveIn.Register.SourceRange);
403 unsigned VReg = 0;
404 if (!LiveIn.VirtualRegister.Value.empty()) {
405 if (parseVirtualRegisterReference(
406 VReg, SM, MF, LiveIn.VirtualRegister.Value, PFS, IRSlots, Error))
407 return error(Error, LiveIn.VirtualRegister.SourceRange);
408 }
409 RegInfo.addLiveIn(Reg, VReg);
410 }
Alex Lorenzc4838082015-08-11 00:32:49 +0000411
412 // Parse the callee saved register mask.
413 BitVector CalleeSavedRegisterMask(RegInfo.getUsedPhysRegsMask().size());
414 if (!YamlMF.CalleeSavedRegisters)
415 return false;
416 for (const auto &RegSource : YamlMF.CalleeSavedRegisters.getValue()) {
417 unsigned Reg = 0;
418 if (parseNamedRegisterReference(Reg, SM, MF, RegSource.Value, PFS, IRSlots,
419 Error))
420 return error(Error, RegSource.SourceRange);
421 CalleeSavedRegisterMask[Reg] = true;
422 }
423 RegInfo.setUsedPhysRegMask(CalleeSavedRegisterMask.flip());
Alex Lorenz54565cf2015-06-24 19:56:10 +0000424 return false;
425}
426
Alex Lorenzc4838082015-08-11 00:32:49 +0000427void MIRParserImpl::inferRegisterInfo(MachineFunction &MF,
428 const yaml::MachineFunction &YamlMF) {
429 if (YamlMF.CalleeSavedRegisters)
430 return;
431 for (const MachineBasicBlock &MBB : MF) {
432 for (const MachineInstr &MI : MBB) {
433 for (const MachineOperand &MO : MI.operands()) {
434 if (!MO.isRegMask())
435 continue;
436 MF.getRegInfo().addPhysRegsUsedFromRegMask(MO.getRegMask());
437 }
438 }
439 }
440}
441
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000442bool MIRParserImpl::initializeFrameInfo(MachineFunction &MF,
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000443 const yaml::MachineFunction &YamlMF,
444 PerFunctionMIParsingState &PFS) {
Alex Lorenzdb07c402015-07-28 16:48:37 +0000445 MachineFrameInfo &MFI = *MF.getFrameInfo();
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000446 const Function &F = *MF.getFunction();
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000447 const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
Alex Lorenz60541c12015-07-09 19:55:27 +0000448 MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
449 MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
450 MFI.setHasStackMap(YamlMFI.HasStackMap);
451 MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);
452 MFI.setStackSize(YamlMFI.StackSize);
453 MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment);
454 if (YamlMFI.MaxAlignment)
455 MFI.ensureMaxAlignment(YamlMFI.MaxAlignment);
456 MFI.setAdjustsStack(YamlMFI.AdjustsStack);
457 MFI.setHasCalls(YamlMFI.HasCalls);
458 MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize);
459 MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);
460 MFI.setHasVAStart(YamlMFI.HasVAStart);
461 MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
Alex Lorenza6f9a372015-07-29 21:09:09 +0000462 if (!YamlMFI.SavePoint.Value.empty()) {
463 MachineBasicBlock *MBB = nullptr;
464 if (parseMBBReference(MBB, YamlMFI.SavePoint, MF, PFS))
465 return true;
466 MFI.setSavePoint(MBB);
467 }
468 if (!YamlMFI.RestorePoint.Value.empty()) {
469 MachineBasicBlock *MBB = nullptr;
470 if (parseMBBReference(MBB, YamlMFI.RestorePoint, MF, PFS))
471 return true;
472 MFI.setRestorePoint(MBB);
473 }
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000474
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000475 std::vector<CalleeSavedInfo> CSIInfo;
Alex Lorenzde491f02015-07-13 18:07:26 +0000476 // Initialize the fixed frame objects.
477 for (const auto &Object : YamlMF.FixedStackObjects) {
478 int ObjectIdx;
479 if (Object.Type != yaml::FixedMachineStackObject::SpillSlot)
480 ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset,
481 Object.IsImmutable, Object.IsAliased);
482 else
483 ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset);
484 MFI.setObjectAlignment(ObjectIdx, Object.Alignment);
Alex Lorenz1d9a3032015-08-10 23:45:02 +0000485 if (!PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID.Value,
486 ObjectIdx))
487 .second)
488 return error(Object.ID.SourceRange.Start,
489 Twine("redefinition of fixed stack object '%fixed-stack.") +
490 Twine(Object.ID.Value) + "'");
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000491 if (parseCalleeSavedRegister(MF, PFS, CSIInfo, Object.CalleeSavedRegister,
492 ObjectIdx))
493 return true;
Alex Lorenzde491f02015-07-13 18:07:26 +0000494 }
495
496 // Initialize the ordinary frame objects.
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000497 for (const auto &Object : YamlMF.StackObjects) {
Alex Lorenz418f3ec2015-07-14 00:26:26 +0000498 int ObjectIdx;
Alex Lorenz37643a02015-07-15 22:14:49 +0000499 const AllocaInst *Alloca = nullptr;
500 const yaml::StringValue &Name = Object.Name;
501 if (!Name.Value.empty()) {
502 Alloca = dyn_cast_or_null<AllocaInst>(
503 F.getValueSymbolTable().lookup(Name.Value));
504 if (!Alloca)
505 return error(Name.SourceRange.Start,
506 "alloca instruction named '" + Name.Value +
507 "' isn't defined in the function '" + F.getName() +
508 "'");
509 }
Alex Lorenz418f3ec2015-07-14 00:26:26 +0000510 if (Object.Type == yaml::MachineStackObject::VariableSized)
Alex Lorenz37643a02015-07-15 22:14:49 +0000511 ObjectIdx = MFI.CreateVariableSizedObject(Object.Alignment, Alloca);
Alex Lorenz418f3ec2015-07-14 00:26:26 +0000512 else
513 ObjectIdx = MFI.CreateStackObject(
514 Object.Size, Object.Alignment,
Alex Lorenz37643a02015-07-15 22:14:49 +0000515 Object.Type == yaml::MachineStackObject::SpillSlot, Alloca);
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000516 MFI.setObjectOffset(ObjectIdx, Object.Offset);
Alex Lorenzc5d35ba2015-08-10 23:50:41 +0000517 if (!PFS.StackObjectSlots.insert(std::make_pair(Object.ID.Value, ObjectIdx))
518 .second)
519 return error(Object.ID.SourceRange.Start,
520 Twine("redefinition of stack object '%stack.") +
521 Twine(Object.ID.Value) + "'");
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000522 if (parseCalleeSavedRegister(MF, PFS, CSIInfo, Object.CalleeSavedRegister,
523 ObjectIdx))
524 return true;
Alex Lorenza56ba6a2015-08-17 22:17:42 +0000525 if (Object.LocalOffset)
526 MFI.mapLocalFrameObject(ObjectIdx, Object.LocalOffset.getValue());
Alex Lorenzdf9e3c62015-08-19 00:13:25 +0000527 if (parseStackObjectsDebugInfo(MF, PFS, Object, ObjectIdx))
528 return true;
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000529 }
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000530 MFI.setCalleeSavedInfo(CSIInfo);
531 if (!CSIInfo.empty())
532 MFI.setCalleeSavedInfoValid(true);
Alex Lorenza314d812015-08-18 22:26:26 +0000533
534 // Initialize the various stack object references after initializing the
535 // stack objects.
536 if (!YamlMFI.StackProtector.Value.empty()) {
537 SMDiagnostic Error;
538 int FI;
539 if (parseStackObjectReference(FI, SM, MF, YamlMFI.StackProtector.Value, PFS,
540 IRSlots, Error))
541 return error(Error, YamlMFI.StackProtector.SourceRange);
542 MFI.setStackProtectorIndex(FI);
543 }
Alex Lorenz1bb48de2015-07-24 22:22:50 +0000544 return false;
545}
546
547bool MIRParserImpl::parseCalleeSavedRegister(
548 MachineFunction &MF, PerFunctionMIParsingState &PFS,
549 std::vector<CalleeSavedInfo> &CSIInfo,
550 const yaml::StringValue &RegisterSource, int FrameIdx) {
551 if (RegisterSource.Value.empty())
552 return false;
553 unsigned Reg = 0;
554 SMDiagnostic Error;
555 if (parseNamedRegisterReference(Reg, SM, MF, RegisterSource.Value, PFS,
556 IRSlots, Error))
557 return error(Error, RegisterSource.SourceRange);
558 CSIInfo.push_back(CalleeSavedInfo(Reg, FrameIdx));
Alex Lorenz60541c12015-07-09 19:55:27 +0000559 return false;
560}
561
Alex Lorenzdf9e3c62015-08-19 00:13:25 +0000562/// Verify that given node is of a certain type. Return true on error.
563template <typename T>
564static bool typecheckMDNode(T *&Result, MDNode *Node,
565 const yaml::StringValue &Source,
566 StringRef TypeString, MIRParserImpl &Parser) {
567 if (!Node)
568 return false;
569 Result = dyn_cast<T>(Node);
570 if (!Result)
571 return Parser.error(Source.SourceRange.Start,
572 "expected a reference to a '" + TypeString +
573 "' metadata node");
574 return false;
575}
576
577bool MIRParserImpl::parseStackObjectsDebugInfo(
578 MachineFunction &MF, PerFunctionMIParsingState &PFS,
579 const yaml::MachineStackObject &Object, int FrameIdx) {
580 // Debug information can only be attached to stack objects; Fixed stack
581 // objects aren't supported.
582 assert(FrameIdx >= 0 && "Expected a stack object frame index");
583 MDNode *Var = nullptr, *Expr = nullptr, *Loc = nullptr;
584 if (parseMDNode(Var, Object.DebugVar, MF, PFS) ||
585 parseMDNode(Expr, Object.DebugExpr, MF, PFS) ||
586 parseMDNode(Loc, Object.DebugLoc, MF, PFS))
587 return true;
588 if (!Var && !Expr && !Loc)
589 return false;
590 DILocalVariable *DIVar = nullptr;
591 DIExpression *DIExpr = nullptr;
592 DILocation *DILoc = nullptr;
593 if (typecheckMDNode(DIVar, Var, Object.DebugVar, "DILocalVariable", *this) ||
594 typecheckMDNode(DIExpr, Expr, Object.DebugExpr, "DIExpression", *this) ||
595 typecheckMDNode(DILoc, Loc, Object.DebugLoc, "DILocation", *this))
596 return true;
597 MF.getMMI().setVariableDbgInfo(DIVar, DIExpr, unsigned(FrameIdx), DILoc);
598 return false;
599}
600
601bool MIRParserImpl::parseMDNode(MDNode *&Node, const yaml::StringValue &Source,
602 MachineFunction &MF,
603 const PerFunctionMIParsingState &PFS) {
604 if (Source.Value.empty())
605 return false;
606 SMDiagnostic Error;
607 if (llvm::parseMDNode(Node, SM, MF, Source.Value, PFS, IRSlots, Error))
608 return error(Error, Source.SourceRange);
609 return false;
610}
611
Alex Lorenzab980492015-07-20 20:51:18 +0000612bool MIRParserImpl::initializeConstantPool(
613 MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF,
614 const MachineFunction &MF,
615 DenseMap<unsigned, unsigned> &ConstantPoolSlots) {
616 const auto &M = *MF.getFunction()->getParent();
617 SMDiagnostic Error;
618 for (const auto &YamlConstant : YamlMF.Constants) {
619 const Constant *Value = dyn_cast_or_null<Constant>(
620 parseConstantValue(YamlConstant.Value.Value, Error, M));
621 if (!Value)
622 return error(Error, YamlConstant.Value.SourceRange);
623 unsigned Alignment =
624 YamlConstant.Alignment
625 ? YamlConstant.Alignment
626 : M.getDataLayout().getPrefTypeAlignment(Value->getType());
Alex Lorenz60bf5992015-07-30 22:00:17 +0000627 unsigned Index = ConstantPool.getConstantPoolIndex(Value, Alignment);
628 if (!ConstantPoolSlots.insert(std::make_pair(YamlConstant.ID.Value, Index))
629 .second)
630 return error(YamlConstant.ID.SourceRange.Start,
631 Twine("redefinition of constant pool item '%const.") +
632 Twine(YamlConstant.ID.Value) + "'");
Alex Lorenzab980492015-07-20 20:51:18 +0000633 }
634 return false;
635}
636
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000637bool MIRParserImpl::initializeJumpTableInfo(
638 MachineFunction &MF, const yaml::MachineJumpTable &YamlJTI,
Alex Lorenz31d70682015-07-15 23:38:35 +0000639 PerFunctionMIParsingState &PFS) {
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000640 MachineJumpTableInfo *JTI = MF.getOrCreateJumpTableInfo(YamlJTI.Kind);
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000641 for (const auto &Entry : YamlJTI.Entries) {
642 std::vector<MachineBasicBlock *> Blocks;
643 for (const auto &MBBSource : Entry.Blocks) {
644 MachineBasicBlock *MBB = nullptr;
Alex Lorenz05fa73b2015-07-29 20:57:11 +0000645 if (parseMBBReference(MBB, MBBSource.Value, MF, PFS))
646 return true;
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000647 Blocks.push_back(MBB);
648 }
Alex Lorenz31d70682015-07-15 23:38:35 +0000649 unsigned Index = JTI->createJumpTableIndex(Blocks);
Alex Lorenz59ed5912015-07-31 23:13:23 +0000650 if (!PFS.JumpTableSlots.insert(std::make_pair(Entry.ID.Value, Index))
651 .second)
652 return error(Entry.ID.SourceRange.Start,
653 Twine("redefinition of jump table entry '%jump-table.") +
654 Twine(Entry.ID.Value) + "'");
Alex Lorenz6799e9b2015-07-15 23:31:07 +0000655 }
656 return false;
657}
658
Alex Lorenz05fa73b2015-07-29 20:57:11 +0000659bool MIRParserImpl::parseMBBReference(MachineBasicBlock *&MBB,
660 const yaml::StringValue &Source,
661 MachineFunction &MF,
662 const PerFunctionMIParsingState &PFS) {
663 SMDiagnostic Error;
664 if (llvm::parseMBBReference(MBB, SM, MF, Source.Value, PFS, IRSlots, Error))
665 return error(Error, Source.SourceRange);
666 return false;
667}
668
Alex Lorenz51af1602015-06-23 22:39:23 +0000669SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
670 SMRange SourceRange) {
671 assert(SourceRange.isValid() && "Invalid source range");
672 SMLoc Loc = SourceRange.Start;
673 bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
674 *Loc.getPointer() == '\'';
675 // Translate the location of the error from the location in the MI string to
676 // the corresponding location in the MIR file.
677 Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
678 (HasQuote ? 1 : 0));
679
680 // TODO: Translate any source ranges as well.
681 return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None,
682 Error.getFixIts());
683}
684
Alex Lorenz9b62cf62015-08-13 20:30:11 +0000685SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error,
686 SMRange SourceRange) {
Alex Lorenz09b832c2015-05-29 17:05:41 +0000687 assert(SourceRange.isValid());
688
689 // Translate the location of the error from the location in the llvm IR string
690 // to the corresponding location in the MIR file.
691 auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
692 unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
693 unsigned Column = Error.getColumnNo();
694 StringRef LineStr = Error.getLineContents();
695 SMLoc Loc = Error.getLoc();
696
697 // Get the full line and adjust the column number by taking the indentation of
698 // LLVM IR into account.
699 for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
700 L != E; ++L) {
701 if (L.line_number() == Line) {
702 LineStr = *L;
703 Loc = SMLoc::getFromPointer(LineStr.data());
704 auto Indent = LineStr.find(Error.getLineContents());
705 if (Indent != StringRef::npos)
706 Column += Indent;
707 break;
708 }
709 }
710
711 return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
712 Error.getMessage(), LineStr, Error.getRanges(),
713 Error.getFixIts());
714}
715
Alex Lorenz28148ba2015-07-09 22:23:13 +0000716void MIRParserImpl::initNames2RegClasses(const MachineFunction &MF) {
717 if (!Names2RegClasses.empty())
718 return;
719 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
720 for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) {
721 const auto *RC = TRI->getRegClass(I);
722 Names2RegClasses.insert(
723 std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC));
724 }
725}
726
Quentin Colombet876ddf82016-04-08 16:40:43 +0000727void MIRParserImpl::initNames2RegBanks(const MachineFunction &MF) {
728 if (!Names2RegBanks.empty())
729 return;
730 const RegisterBankInfo *RBI = MF.getSubtarget().getRegBankInfo();
731 // If the target does not support GlobalISel, we may not have a
732 // register bank info.
733 if (!RBI)
734 return;
735 for (unsigned I = 0, E = RBI->getNumRegBanks(); I < E; ++I) {
736 const auto &RegBank = RBI->getRegBank(I);
737 Names2RegBanks.insert(
738 std::make_pair(StringRef(RegBank.getName()).lower(), &RegBank));
739 }
740}
741
Alex Lorenz28148ba2015-07-09 22:23:13 +0000742const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF,
743 StringRef Name) {
744 initNames2RegClasses(MF);
745 auto RegClassInfo = Names2RegClasses.find(Name);
746 if (RegClassInfo == Names2RegClasses.end())
747 return nullptr;
748 return RegClassInfo->getValue();
749}
750
Quentin Colombet876ddf82016-04-08 16:40:43 +0000751const RegisterBank *MIRParserImpl::getRegBank(const MachineFunction &MF,
752 StringRef Name) {
753 initNames2RegBanks(MF);
754 auto RegBankInfo = Names2RegBanks.find(Name);
755 if (RegBankInfo == Names2RegBanks.end())
756 return nullptr;
757 return RegBankInfo->getValue();
758}
759
Alex Lorenz735c47e2015-06-15 20:30:22 +0000760MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
761 : Impl(std::move(Impl)) {}
762
763MIRParser::~MIRParser() {}
764
765std::unique_ptr<Module> MIRParser::parseLLVMModule() { return Impl->parse(); }
766
767bool MIRParser::initializeMachineFunction(MachineFunction &MF) {
768 return Impl->initializeMachineFunction(MF);
769}
770
771std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename,
772 SMDiagnostic &Error,
773 LLVMContext &Context) {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000774 auto FileOrErr = MemoryBuffer::getFile(Filename);
775 if (std::error_code EC = FileOrErr.getError()) {
776 Error = SMDiagnostic(Filename, SourceMgr::DK_Error,
777 "Could not open input file: " + EC.message());
Alex Lorenz735c47e2015-06-15 20:30:22 +0000778 return nullptr;
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000779 }
Alex Lorenz735c47e2015-06-15 20:30:22 +0000780 return createMIRParser(std::move(FileOrErr.get()), Context);
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000781}
782
Alex Lorenz735c47e2015-06-15 20:30:22 +0000783std::unique_ptr<MIRParser>
784llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
785 LLVMContext &Context) {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000786 auto Filename = Contents->getBufferIdentifier();
Alex Lorenz735c47e2015-06-15 20:30:22 +0000787 return llvm::make_unique<MIRParser>(
788 llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context));
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000789}