blob: 0f7673eea070b6c16a8f9fa49729f242a8813e0f [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 Lorenz735c47e2015-06-15 20:30:22 +000023#include "llvm/CodeGen/MachineFunction.h"
Alex Lorenz60541c12015-07-09 19:55:27 +000024#include "llvm/CodeGen/MachineFrameInfo.h"
Alex Lorenz54565cf2015-06-24 19:56:10 +000025#include "llvm/CodeGen/MachineRegisterInfo.h"
Alex Lorenz78d78312015-05-28 22:41:12 +000026#include "llvm/CodeGen/MIRYamlMapping.h"
Alex Lorenz4f093bf2015-06-19 17:43:07 +000027#include "llvm/IR/BasicBlock.h"
Alex Lorenz735c47e2015-06-15 20:30:22 +000028#include "llvm/IR/DiagnosticInfo.h"
Alex Lorenz8e7a58d72015-06-15 23:07:38 +000029#include "llvm/IR/Instructions.h"
Alex Lorenz735c47e2015-06-15 20:30:22 +000030#include "llvm/IR/LLVMContext.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000031#include "llvm/IR/Module.h"
Alex Lorenz4f093bf2015-06-19 17:43:07 +000032#include "llvm/IR/ValueSymbolTable.h"
Alex Lorenz09b832c2015-05-29 17:05:41 +000033#include "llvm/Support/LineIterator.h"
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000034#include "llvm/Support/SMLoc.h"
35#include "llvm/Support/SourceMgr.h"
36#include "llvm/Support/MemoryBuffer.h"
37#include "llvm/Support/YAMLTraits.h"
38#include <memory>
39
40using namespace llvm;
41
Alex Lorenz735c47e2015-06-15 20:30:22 +000042namespace llvm {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000043
44/// This class implements the parsing of LLVM IR that's embedded inside a MIR
45/// file.
46class MIRParserImpl {
47 SourceMgr SM;
48 StringRef Filename;
49 LLVMContext &Context;
Alex Lorenz735c47e2015-06-15 20:30:22 +000050 StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;
Alex Lorenz5d6108e2015-06-26 22:56:48 +000051 SlotMapping IRSlots;
Alex Lorenz28148ba2015-07-09 22:23:13 +000052 /// Maps from register class names to register classes.
53 StringMap<const TargetRegisterClass *> Names2RegClasses;
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000054
55public:
56 MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
57 LLVMContext &Context);
58
Alex Lorenz735c47e2015-06-15 20:30:22 +000059 void reportDiagnostic(const SMDiagnostic &Diag);
60
61 /// Report an error with the given message at unknown location.
62 ///
63 /// Always returns true.
64 bool error(const Twine &Message);
65
Alex Lorenzb1f9ce82015-07-08 20:22:20 +000066 /// Report an error with the given message at the given location.
67 ///
68 /// Always returns true.
69 bool error(SMLoc Loc, const Twine &Message);
70
Alex Lorenz0fd7c622015-06-30 17:55:00 +000071 /// Report a given error with the location translated from the location in an
72 /// embedded string literal to a location in the MIR file.
73 ///
74 /// Always returns true.
75 bool error(const SMDiagnostic &Error, SMRange SourceRange);
76
Alex Lorenz78d78312015-05-28 22:41:12 +000077 /// Try to parse the optional LLVM module and the machine functions in the MIR
78 /// file.
Alex Lorenz2bdb4e12015-05-27 18:02:19 +000079 ///
Alex Lorenz78d78312015-05-28 22:41:12 +000080 /// Return null if an error occurred.
Alex Lorenz735c47e2015-06-15 20:30:22 +000081 std::unique_ptr<Module> parse();
Alex Lorenz78d78312015-05-28 22:41:12 +000082
83 /// Parse the machine function in the current YAML document.
84 ///
Alex Lorenz8e7a58d72015-06-15 23:07:38 +000085 /// \param NoLLVMIR - set to true when the MIR file doesn't have LLVM IR.
86 /// A dummy IR function is created and inserted into the given module when
87 /// this parameter is true.
88 ///
Alex Lorenz78d78312015-05-28 22:41:12 +000089 /// Return true if an error occurred.
Alex Lorenz8e7a58d72015-06-15 23:07:38 +000090 bool parseMachineFunction(yaml::Input &In, Module &M, bool NoLLVMIR);
Alex Lorenz09b832c2015-05-29 17:05:41 +000091
Alex Lorenz735c47e2015-06-15 20:30:22 +000092 /// Initialize the machine function to the state that's described in the MIR
93 /// file.
94 ///
95 /// Return true if error occurred.
96 bool initializeMachineFunction(MachineFunction &MF);
97
Alex Lorenz4f093bf2015-06-19 17:43:07 +000098 /// Initialize the machine basic block using it's YAML representation.
99 ///
100 /// Return true if an error occurred.
Alex Lorenz7a503fa2015-07-07 17:46:43 +0000101 bool initializeMachineBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB,
102 const yaml::MachineBasicBlock &YamlMBB,
103 const PerFunctionMIParsingState &PFS);
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000104
Alex Lorenz28148ba2015-07-09 22:23:13 +0000105 bool initializeRegisterInfo(const MachineFunction &MF,
106 MachineRegisterInfo &RegInfo,
Alex Lorenz54565cf2015-06-24 19:56:10 +0000107 const yaml::MachineFunction &YamlMF);
108
Alex Lorenz60541c12015-07-09 19:55:27 +0000109 bool initializeFrameInfo(MachineFrameInfo &MFI,
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000110 const yaml::MachineFunction &YamlMF);
Alex Lorenz60541c12015-07-09 19:55:27 +0000111
Alex Lorenz09b832c2015-05-29 17:05:41 +0000112private:
Alex Lorenz51af1602015-06-23 22:39:23 +0000113 /// Return a MIR diagnostic converted from an MI string diagnostic.
114 SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
115 SMRange SourceRange);
116
Alex Lorenz09b832c2015-05-29 17:05:41 +0000117 /// Return a MIR diagnostic converted from an LLVM assembly diagnostic.
118 SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
119 SMRange SourceRange);
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000120
121 /// Create an empty function with the given name.
122 void createDummyFunction(StringRef Name, Module &M);
Alex Lorenz28148ba2015-07-09 22:23:13 +0000123
124 void initNames2RegClasses(const MachineFunction &MF);
125
126 /// Check if the given identifier is a name of a register class.
127 ///
128 /// Return null if the name isn't a register class.
129 const TargetRegisterClass *getRegClass(const MachineFunction &MF,
130 StringRef Name);
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000131};
132
Alex Lorenz735c47e2015-06-15 20:30:22 +0000133} // end namespace llvm
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000134
135MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
136 StringRef Filename, LLVMContext &Context)
137 : SM(), Filename(Filename), Context(Context) {
138 SM.AddNewSourceBuffer(std::move(Contents), SMLoc());
139}
140
Alex Lorenz735c47e2015-06-15 20:30:22 +0000141bool MIRParserImpl::error(const Twine &Message) {
142 Context.diagnose(DiagnosticInfoMIRParser(
143 DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str())));
144 return true;
Alex Lorenz78d78312015-05-28 22:41:12 +0000145}
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000146
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000147bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) {
148 Context.diagnose(DiagnosticInfoMIRParser(
149 DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message)));
150 return true;
151}
152
Alex Lorenz0fd7c622015-06-30 17:55:00 +0000153bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) {
154 assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");
155 reportDiagnostic(diagFromMIStringDiag(Error, SourceRange));
156 return true;
157}
158
Alex Lorenz735c47e2015-06-15 20:30:22 +0000159void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
160 DiagnosticSeverity Kind;
161 switch (Diag.getKind()) {
162 case SourceMgr::DK_Error:
163 Kind = DS_Error;
164 break;
165 case SourceMgr::DK_Warning:
166 Kind = DS_Warning;
167 break;
168 case SourceMgr::DK_Note:
169 Kind = DS_Note;
170 break;
171 }
172 Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag));
173}
174
175static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
176 reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag);
177}
178
179std::unique_ptr<Module> MIRParserImpl::parse() {
Alex Lorenz78d78312015-05-28 22:41:12 +0000180 yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(),
Alex Lorenz735c47e2015-06-15 20:30:22 +0000181 /*Ctxt=*/nullptr, handleYAMLDiag, this);
Alex Lorenz51af1602015-06-23 22:39:23 +0000182 In.setContext(&In);
Alex Lorenz78d78312015-05-28 22:41:12 +0000183
184 if (!In.setCurrentDocument()) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000185 if (In.error())
Alex Lorenz78d78312015-05-28 22:41:12 +0000186 return nullptr;
187 // Create an empty module when the MIR file is empty.
188 return llvm::make_unique<Module>(Filename, Context);
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000189 }
190
Alex Lorenz78d78312015-05-28 22:41:12 +0000191 std::unique_ptr<Module> M;
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000192 bool NoLLVMIR = false;
Alex Lorenz78d78312015-05-28 22:41:12 +0000193 // Parse the block scalar manually so that we can return unique pointer
194 // without having to go trough YAML traits.
195 if (const auto *BSN =
196 dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000197 SMDiagnostic Error;
Alex Lorenz78d78312015-05-28 22:41:12 +0000198 M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
Alex Lorenz5d6108e2015-06-26 22:56:48 +0000199 Context, &IRSlots);
Alex Lorenz09b832c2015-05-29 17:05:41 +0000200 if (!M) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000201 reportDiagnostic(diagFromLLVMAssemblyDiag(Error, BSN->getSourceRange()));
Alex Lorenz78d78312015-05-28 22:41:12 +0000202 return M;
Alex Lorenz09b832c2015-05-29 17:05:41 +0000203 }
Alex Lorenz78d78312015-05-28 22:41:12 +0000204 In.nextDocument();
205 if (!In.setCurrentDocument())
206 return M;
207 } else {
208 // Create an new, empty module.
209 M = llvm::make_unique<Module>(Filename, Context);
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000210 NoLLVMIR = true;
Alex Lorenz78d78312015-05-28 22:41:12 +0000211 }
212
213 // Parse the machine functions.
214 do {
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000215 if (parseMachineFunction(In, *M, NoLLVMIR))
Alex Lorenz78d78312015-05-28 22:41:12 +0000216 return nullptr;
217 In.nextDocument();
218 } while (In.setCurrentDocument());
219
220 return M;
221}
222
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000223bool MIRParserImpl::parseMachineFunction(yaml::Input &In, Module &M,
224 bool NoLLVMIR) {
Alex Lorenz735c47e2015-06-15 20:30:22 +0000225 auto MF = llvm::make_unique<yaml::MachineFunction>();
226 yaml::yamlize(In, *MF, false);
Alex Lorenz78d78312015-05-28 22:41:12 +0000227 if (In.error())
228 return true;
Alex Lorenz735c47e2015-06-15 20:30:22 +0000229 auto FunctionName = MF->Name;
Alex Lorenzfe2aa972015-06-15 22:23:23 +0000230 if (Functions.find(FunctionName) != Functions.end())
231 return error(Twine("redefinition of machine function '") + FunctionName +
232 "'");
Alex Lorenz735c47e2015-06-15 20:30:22 +0000233 Functions.insert(std::make_pair(FunctionName, std::move(MF)));
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000234 if (NoLLVMIR)
235 createDummyFunction(FunctionName, M);
Alex Lorenz5ef16b82015-06-16 17:06:29 +0000236 else if (!M.getFunction(FunctionName))
237 return error(Twine("function '") + FunctionName +
238 "' isn't defined in the provided LLVM IR");
Alex Lorenz735c47e2015-06-15 20:30:22 +0000239 return false;
240}
241
Alex Lorenz8e7a58d72015-06-15 23:07:38 +0000242void MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
243 auto &Context = M.getContext();
244 Function *F = cast<Function>(M.getOrInsertFunction(
245 Name, FunctionType::get(Type::getVoidTy(Context), false)));
246 BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
247 new UnreachableInst(Context, BB);
248}
249
Alex Lorenz735c47e2015-06-15 20:30:22 +0000250bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
251 auto It = Functions.find(MF.getName());
252 if (It == Functions.end())
253 return error(Twine("no machine function information for function '") +
254 MF.getName() + "' in the MIR file");
255 // TODO: Recreate the machine function.
Alex Lorenz5b5f9752015-06-16 00:10:47 +0000256 const yaml::MachineFunction &YamlMF = *It->getValue();
257 if (YamlMF.Alignment)
258 MF.setAlignment(YamlMF.Alignment);
259 MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
260 MF.setHasInlineAsm(YamlMF.HasInlineAsm);
Alex Lorenz28148ba2015-07-09 22:23:13 +0000261 if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF))
Alex Lorenz54565cf2015-06-24 19:56:10 +0000262 return true;
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000263 if (initializeFrameInfo(*MF.getFrameInfo(), YamlMF))
Alex Lorenz60541c12015-07-09 19:55:27 +0000264 return true;
Alex Lorenz54565cf2015-06-24 19:56:10 +0000265
Alex Lorenz7a503fa2015-07-07 17:46:43 +0000266 PerFunctionMIParsingState PFS;
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000267 const auto &F = *MF.getFunction();
268 for (const auto &YamlMBB : YamlMF.BasicBlocks) {
269 const BasicBlock *BB = nullptr;
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000270 const yaml::StringValue &Name = YamlMBB.Name;
271 if (!Name.Value.empty()) {
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000272 BB = dyn_cast_or_null<BasicBlock>(
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000273 F.getValueSymbolTable().lookup(Name.Value));
Alex Lorenz00302df2015-06-19 20:12:03 +0000274 if (!BB)
Alex Lorenzb1f9ce82015-07-08 20:22:20 +0000275 return error(Name.SourceRange.Start,
276 Twine("basic block '") + Name.Value +
277 "' is not defined in the function '" + MF.getName() +
278 "'");
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000279 }
280 auto *MBB = MF.CreateMachineBasicBlock(BB);
281 MF.insert(MF.end(), MBB);
Alex Lorenz7a503fa2015-07-07 17:46:43 +0000282 bool WasInserted =
283 PFS.MBBSlots.insert(std::make_pair(YamlMBB.ID, MBB)).second;
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000284 if (!WasInserted)
285 return error(Twine("redefinition of machine basic block with id #") +
286 Twine(YamlMBB.ID));
287 }
288
Alex Lorenzc8704b02015-07-09 21:21:33 +0000289 if (YamlMF.BasicBlocks.empty())
290 return error(Twine("machine function '") + Twine(MF.getName()) +
291 "' requires at least one machine basic block in its body");
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000292 // Initialize the machine basic blocks after creating them all so that the
293 // machine instructions parser can resolve the MBB references.
294 unsigned I = 0;
295 for (const auto &YamlMBB : YamlMF.BasicBlocks) {
296 if (initializeMachineBasicBlock(MF, *MF.getBlockNumbered(I++), YamlMBB,
Alex Lorenz7a503fa2015-07-07 17:46:43 +0000297 PFS))
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000298 return true;
299 }
300 return false;
301}
302
303bool MIRParserImpl::initializeMachineBasicBlock(
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000304 MachineFunction &MF, MachineBasicBlock &MBB,
Alex Lorenz33f0aef2015-06-26 16:46:11 +0000305 const yaml::MachineBasicBlock &YamlMBB,
Alex Lorenz7a503fa2015-07-07 17:46:43 +0000306 const PerFunctionMIParsingState &PFS) {
Alex Lorenz4f093bf2015-06-19 17:43:07 +0000307 MBB.setAlignment(YamlMBB.Alignment);
308 if (YamlMBB.AddressTaken)
309 MBB.setHasAddressTaken();
310 MBB.setIsLandingPad(YamlMBB.IsLandingPad);
Alex Lorenzf09df002015-06-30 18:16:42 +0000311 SMDiagnostic Error;
312 // Parse the successors.
313 for (const auto &MBBSource : YamlMBB.Successors) {
314 MachineBasicBlock *SuccMBB = nullptr;
Alex Lorenz7a503fa2015-07-07 17:46:43 +0000315 if (parseMBBReference(SuccMBB, SM, MF, MBBSource.Value, PFS, IRSlots,
Alex Lorenzf09df002015-06-30 18:16:42 +0000316 Error))
317 return error(Error, MBBSource.SourceRange);
318 // TODO: Report an error when adding the same successor more than once.
319 MBB.addSuccessor(SuccMBB);
320 }
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000321 // Parse the instructions.
322 for (const auto &MISource : YamlMBB.Instructions) {
Alex Lorenz3708a642015-06-30 17:47:50 +0000323 MachineInstr *MI = nullptr;
Alex Lorenz7a503fa2015-07-07 17:46:43 +0000324 if (parseMachineInstr(MI, SM, MF, MISource.Value, PFS, IRSlots, Error))
Alex Lorenz0fd7c622015-06-30 17:55:00 +0000325 return error(Error, MISource.SourceRange);
Alex Lorenz3708a642015-06-30 17:47:50 +0000326 MBB.insert(MBB.end(), MI);
Alex Lorenz8e0a1b42015-06-22 17:02:30 +0000327 }
Alex Lorenz78d78312015-05-28 22:41:12 +0000328 return false;
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000329}
330
Alex Lorenz54565cf2015-06-24 19:56:10 +0000331bool MIRParserImpl::initializeRegisterInfo(
Alex Lorenz28148ba2015-07-09 22:23:13 +0000332 const MachineFunction &MF, MachineRegisterInfo &RegInfo,
333 const yaml::MachineFunction &YamlMF) {
Alex Lorenz54565cf2015-06-24 19:56:10 +0000334 assert(RegInfo.isSSA());
335 if (!YamlMF.IsSSA)
336 RegInfo.leaveSSA();
337 assert(RegInfo.tracksLiveness());
338 if (!YamlMF.TracksRegLiveness)
339 RegInfo.invalidateLiveness();
340 RegInfo.enableSubRegLiveness(YamlMF.TracksSubRegLiveness);
Alex Lorenz28148ba2015-07-09 22:23:13 +0000341
342 // Parse the virtual register information.
343 for (const auto &VReg : YamlMF.VirtualRegisters) {
344 const auto *RC = getRegClass(MF, VReg.Class.Value);
345 if (!RC)
346 return error(VReg.Class.SourceRange.Start,
347 Twine("use of undefined register class '") +
348 VReg.Class.Value + "'");
349 // TODO: create the mapping from IDs to registers so that the virtual
350 // register references can be parsed correctly.
351 RegInfo.createVirtualRegister(RC);
352 }
Alex Lorenz54565cf2015-06-24 19:56:10 +0000353 return false;
354}
355
Alex Lorenz60541c12015-07-09 19:55:27 +0000356bool MIRParserImpl::initializeFrameInfo(MachineFrameInfo &MFI,
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000357 const yaml::MachineFunction &YamlMF) {
358 const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo;
Alex Lorenz60541c12015-07-09 19:55:27 +0000359 MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken);
360 MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken);
361 MFI.setHasStackMap(YamlMFI.HasStackMap);
362 MFI.setHasPatchPoint(YamlMFI.HasPatchPoint);
363 MFI.setStackSize(YamlMFI.StackSize);
364 MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment);
365 if (YamlMFI.MaxAlignment)
366 MFI.ensureMaxAlignment(YamlMFI.MaxAlignment);
367 MFI.setAdjustsStack(YamlMFI.AdjustsStack);
368 MFI.setHasCalls(YamlMFI.HasCalls);
369 MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize);
370 MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment);
371 MFI.setHasVAStart(YamlMFI.HasVAStart);
372 MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc);
Alex Lorenzf6bc8662015-07-10 18:13:57 +0000373
374 // Initialize the frame objects.
375 for (const auto &Object : YamlMF.StackObjects) {
376 int ObjectIdx = MFI.CreateStackObject(
377 Object.Size, Object.Alignment,
378 Object.Type == yaml::MachineStackObject::SpillSlot);
379 MFI.setObjectOffset(ObjectIdx, Object.Offset);
380 // TODO: Store the mapping between object IDs and object indices to parse
381 // stack object references correctly.
382 }
Alex Lorenz60541c12015-07-09 19:55:27 +0000383 return false;
384}
385
Alex Lorenz51af1602015-06-23 22:39:23 +0000386SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
387 SMRange SourceRange) {
388 assert(SourceRange.isValid() && "Invalid source range");
389 SMLoc Loc = SourceRange.Start;
390 bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
391 *Loc.getPointer() == '\'';
392 // Translate the location of the error from the location in the MI string to
393 // the corresponding location in the MIR file.
394 Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
395 (HasQuote ? 1 : 0));
396
397 // TODO: Translate any source ranges as well.
398 return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None,
399 Error.getFixIts());
400}
401
Alex Lorenz09b832c2015-05-29 17:05:41 +0000402SMDiagnostic MIRParserImpl::diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
403 SMRange SourceRange) {
404 assert(SourceRange.isValid());
405
406 // Translate the location of the error from the location in the llvm IR string
407 // to the corresponding location in the MIR file.
408 auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
409 unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
410 unsigned Column = Error.getColumnNo();
411 StringRef LineStr = Error.getLineContents();
412 SMLoc Loc = Error.getLoc();
413
414 // Get the full line and adjust the column number by taking the indentation of
415 // LLVM IR into account.
416 for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
417 L != E; ++L) {
418 if (L.line_number() == Line) {
419 LineStr = *L;
420 Loc = SMLoc::getFromPointer(LineStr.data());
421 auto Indent = LineStr.find(Error.getLineContents());
422 if (Indent != StringRef::npos)
423 Column += Indent;
424 break;
425 }
426 }
427
428 return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
429 Error.getMessage(), LineStr, Error.getRanges(),
430 Error.getFixIts());
431}
432
Alex Lorenz28148ba2015-07-09 22:23:13 +0000433void MIRParserImpl::initNames2RegClasses(const MachineFunction &MF) {
434 if (!Names2RegClasses.empty())
435 return;
436 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
437 for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) {
438 const auto *RC = TRI->getRegClass(I);
439 Names2RegClasses.insert(
440 std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC));
441 }
442}
443
444const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF,
445 StringRef Name) {
446 initNames2RegClasses(MF);
447 auto RegClassInfo = Names2RegClasses.find(Name);
448 if (RegClassInfo == Names2RegClasses.end())
449 return nullptr;
450 return RegClassInfo->getValue();
451}
452
Alex Lorenz735c47e2015-06-15 20:30:22 +0000453MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl)
454 : Impl(std::move(Impl)) {}
455
456MIRParser::~MIRParser() {}
457
458std::unique_ptr<Module> MIRParser::parseLLVMModule() { return Impl->parse(); }
459
460bool MIRParser::initializeMachineFunction(MachineFunction &MF) {
461 return Impl->initializeMachineFunction(MF);
462}
463
464std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename,
465 SMDiagnostic &Error,
466 LLVMContext &Context) {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000467 auto FileOrErr = MemoryBuffer::getFile(Filename);
468 if (std::error_code EC = FileOrErr.getError()) {
469 Error = SMDiagnostic(Filename, SourceMgr::DK_Error,
470 "Could not open input file: " + EC.message());
Alex Lorenz735c47e2015-06-15 20:30:22 +0000471 return nullptr;
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000472 }
Alex Lorenz735c47e2015-06-15 20:30:22 +0000473 return createMIRParser(std::move(FileOrErr.get()), Context);
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000474}
475
Alex Lorenz735c47e2015-06-15 20:30:22 +0000476std::unique_ptr<MIRParser>
477llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
478 LLVMContext &Context) {
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000479 auto Filename = Contents->getBufferIdentifier();
Alex Lorenz735c47e2015-06-15 20:30:22 +0000480 return llvm::make_unique<MIRParser>(
481 llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context));
Alex Lorenz2bdb4e12015-05-27 18:02:19 +0000482}