/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- 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" |
16 | | #include "MIParser.h" |
17 | | #include "llvm/ADT/DenseMap.h" |
18 | | #include "llvm/ADT/STLExtras.h" |
19 | | #include "llvm/ADT/StringMap.h" |
20 | | #include "llvm/ADT/StringRef.h" |
21 | | #include "llvm/AsmParser/Parser.h" |
22 | | #include "llvm/AsmParser/SlotMapping.h" |
23 | | #include "llvm/CodeGen/GlobalISel/RegisterBank.h" |
24 | | #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" |
25 | | #include "llvm/CodeGen/MIRYamlMapping.h" |
26 | | #include "llvm/CodeGen/MachineConstantPool.h" |
27 | | #include "llvm/CodeGen/MachineFrameInfo.h" |
28 | | #include "llvm/CodeGen/MachineFunction.h" |
29 | | #include "llvm/CodeGen/MachineModuleInfo.h" |
30 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
31 | | #include "llvm/IR/BasicBlock.h" |
32 | | #include "llvm/IR/DebugInfo.h" |
33 | | #include "llvm/IR/DiagnosticInfo.h" |
34 | | #include "llvm/IR/Instructions.h" |
35 | | #include "llvm/IR/LLVMContext.h" |
36 | | #include "llvm/IR/Module.h" |
37 | | #include "llvm/IR/ValueSymbolTable.h" |
38 | | #include "llvm/Support/LineIterator.h" |
39 | | #include "llvm/Support/MemoryBuffer.h" |
40 | | #include "llvm/Support/SMLoc.h" |
41 | | #include "llvm/Support/SourceMgr.h" |
42 | | #include "llvm/Support/YAMLTraits.h" |
43 | | #include <memory> |
44 | | |
45 | | using namespace llvm; |
46 | | |
47 | | namespace llvm { |
48 | | |
49 | | /// This class implements the parsing of LLVM IR that's embedded inside a MIR |
50 | | /// file. |
51 | | class MIRParserImpl { |
52 | | SourceMgr SM; |
53 | | yaml::Input In; |
54 | | StringRef Filename; |
55 | | LLVMContext &Context; |
56 | | SlotMapping IRSlots; |
57 | | /// Maps from register class names to register classes. |
58 | | Name2RegClassMap Names2RegClasses; |
59 | | /// Maps from register bank names to register banks. |
60 | | Name2RegBankMap Names2RegBanks; |
61 | | /// True when the MIR file doesn't have LLVM IR. Dummy IR functions are |
62 | | /// created and inserted into the given module when this is true. |
63 | | bool NoLLVMIR = false; |
64 | | /// True when a well formed MIR file does not contain any MIR/machine function |
65 | | /// parts. |
66 | | bool NoMIRDocuments = false; |
67 | | |
68 | | public: |
69 | | MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, |
70 | | StringRef Filename, LLVMContext &Context); |
71 | | |
72 | | void reportDiagnostic(const SMDiagnostic &Diag); |
73 | | |
74 | | /// Report an error with the given message at unknown location. |
75 | | /// |
76 | | /// Always returns true. |
77 | | bool error(const Twine &Message); |
78 | | |
79 | | /// Report an error with the given message at the given location. |
80 | | /// |
81 | | /// Always returns true. |
82 | | bool error(SMLoc Loc, const Twine &Message); |
83 | | |
84 | | /// Report a given error with the location translated from the location in an |
85 | | /// embedded string literal to a location in the MIR file. |
86 | | /// |
87 | | /// Always returns true. |
88 | | bool error(const SMDiagnostic &Error, SMRange SourceRange); |
89 | | |
90 | | /// Try to parse the optional LLVM module and the machine functions in the MIR |
91 | | /// file. |
92 | | /// |
93 | | /// Return null if an error occurred. |
94 | | std::unique_ptr<Module> parseIRModule(); |
95 | | |
96 | | bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI); |
97 | | |
98 | | /// Parse the machine function in the current YAML document. |
99 | | /// |
100 | | /// |
101 | | /// Return true if an error occurred. |
102 | | bool parseMachineFunction(Module &M, MachineModuleInfo &MMI); |
103 | | |
104 | | /// Initialize the machine function to the state that's described in the MIR |
105 | | /// file. |
106 | | /// |
107 | | /// Return true if error occurred. |
108 | | bool initializeMachineFunction(const yaml::MachineFunction &YamlMF, |
109 | | MachineFunction &MF); |
110 | | |
111 | | bool parseRegisterInfo(PerFunctionMIParsingState &PFS, |
112 | | const yaml::MachineFunction &YamlMF); |
113 | | |
114 | | bool setupRegisterInfo(const PerFunctionMIParsingState &PFS, |
115 | | const yaml::MachineFunction &YamlMF); |
116 | | |
117 | | bool initializeFrameInfo(PerFunctionMIParsingState &PFS, |
118 | | const yaml::MachineFunction &YamlMF); |
119 | | |
120 | | bool parseCalleeSavedRegister(PerFunctionMIParsingState &PFS, |
121 | | std::vector<CalleeSavedInfo> &CSIInfo, |
122 | | const yaml::StringValue &RegisterSource, |
123 | | bool IsRestored, int FrameIdx); |
124 | | |
125 | | bool parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS, |
126 | | const yaml::MachineStackObject &Object, |
127 | | int FrameIdx); |
128 | | |
129 | | bool initializeConstantPool(PerFunctionMIParsingState &PFS, |
130 | | MachineConstantPool &ConstantPool, |
131 | | const yaml::MachineFunction &YamlMF); |
132 | | |
133 | | bool initializeJumpTableInfo(PerFunctionMIParsingState &PFS, |
134 | | const yaml::MachineJumpTable &YamlJTI); |
135 | | |
136 | | private: |
137 | | bool parseMDNode(PerFunctionMIParsingState &PFS, MDNode *&Node, |
138 | | const yaml::StringValue &Source); |
139 | | |
140 | | bool parseMBBReference(PerFunctionMIParsingState &PFS, |
141 | | MachineBasicBlock *&MBB, |
142 | | const yaml::StringValue &Source); |
143 | | |
144 | | /// Return a MIR diagnostic converted from an MI string diagnostic. |
145 | | SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error, |
146 | | SMRange SourceRange); |
147 | | |
148 | | /// Return a MIR diagnostic converted from a diagnostic located in a YAML |
149 | | /// block scalar string. |
150 | | SMDiagnostic diagFromBlockStringDiag(const SMDiagnostic &Error, |
151 | | SMRange SourceRange); |
152 | | |
153 | | void initNames2RegClasses(const MachineFunction &MF); |
154 | | void initNames2RegBanks(const MachineFunction &MF); |
155 | | |
156 | | /// Check if the given identifier is a name of a register class. |
157 | | /// |
158 | | /// Return null if the name isn't a register class. |
159 | | const TargetRegisterClass *getRegClass(const MachineFunction &MF, |
160 | | StringRef Name); |
161 | | |
162 | | /// Check if the given identifier is a name of a register bank. |
163 | | /// |
164 | | /// Return null if the name isn't a register bank. |
165 | | const RegisterBank *getRegBank(const MachineFunction &MF, StringRef Name); |
166 | | |
167 | | void computeFunctionProperties(MachineFunction &MF); |
168 | | }; |
169 | | |
170 | | } // end namespace llvm |
171 | | |
172 | 5 | static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) { |
173 | 5 | reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag); |
174 | 5 | } |
175 | | |
176 | | MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, |
177 | | StringRef Filename, LLVMContext &Context) |
178 | | : SM(), |
179 | | In(SM.getMemoryBuffer( |
180 | | SM.AddNewSourceBuffer(std::move(Contents), SMLoc()))->getBuffer(), |
181 | | nullptr, handleYAMLDiag, this), |
182 | | Filename(Filename), |
183 | 733 | Context(Context) { |
184 | 733 | In.setContext(&In); |
185 | 733 | } |
186 | | |
187 | 3 | bool MIRParserImpl::error(const Twine &Message) { |
188 | 3 | Context.diagnose(DiagnosticInfoMIRParser( |
189 | 3 | DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str()))); |
190 | 3 | return true; |
191 | 3 | } |
192 | | |
193 | 9 | bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) { |
194 | 9 | Context.diagnose(DiagnosticInfoMIRParser( |
195 | 9 | DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message))); |
196 | 9 | return true; |
197 | 9 | } |
198 | | |
199 | 7 | bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) { |
200 | 7 | assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error"); |
201 | 7 | reportDiagnostic(diagFromMIStringDiag(Error, SourceRange)); |
202 | 7 | return true; |
203 | 7 | } |
204 | | |
205 | 100 | void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) { |
206 | 100 | DiagnosticSeverity Kind; |
207 | 100 | switch (Diag.getKind()) { |
208 | 100 | case SourceMgr::DK_Error: |
209 | 100 | Kind = DS_Error; |
210 | 100 | break; |
211 | 0 | case SourceMgr::DK_Warning: |
212 | 0 | Kind = DS_Warning; |
213 | 0 | break; |
214 | 0 | case SourceMgr::DK_Note: |
215 | 0 | Kind = DS_Note; |
216 | 0 | break; |
217 | 100 | } |
218 | 100 | Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag)); |
219 | 100 | } |
220 | | |
221 | 733 | std::unique_ptr<Module> MIRParserImpl::parseIRModule() { |
222 | 733 | if (!In.setCurrentDocument()733 ) { |
223 | 2 | if (In.error()) |
224 | 0 | return nullptr; |
225 | 2 | // Create an empty module when the MIR file is empty. |
226 | 2 | NoMIRDocuments = true; |
227 | 2 | return llvm::make_unique<Module>(Filename, Context); |
228 | 2 | } |
229 | 731 | |
230 | 731 | std::unique_ptr<Module> M; |
231 | 731 | // Parse the block scalar manually so that we can return unique pointer |
232 | 731 | // without having to go trough YAML traits. |
233 | 731 | if (const auto *BSN = |
234 | 593 | dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) { |
235 | 593 | SMDiagnostic Error; |
236 | 593 | M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error, |
237 | 593 | Context, &IRSlots); |
238 | 593 | if (!M593 ) { |
239 | 1 | reportDiagnostic(diagFromBlockStringDiag(Error, BSN->getSourceRange())); |
240 | 1 | return nullptr; |
241 | 1 | } |
242 | 592 | In.nextDocument(); |
243 | 592 | if (!In.setCurrentDocument()) |
244 | 1 | NoMIRDocuments = true; |
245 | 731 | } else { |
246 | 138 | // Create an new, empty module. |
247 | 138 | M = llvm::make_unique<Module>(Filename, Context); |
248 | 138 | NoLLVMIR = true; |
249 | 138 | } |
250 | 730 | return M; |
251 | 733 | } |
252 | | |
253 | 732 | bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) { |
254 | 732 | if (NoMIRDocuments) |
255 | 3 | return false; |
256 | 729 | |
257 | 729 | // Parse the machine functions. |
258 | 729 | do 729 { |
259 | 2.33k | if (parseMachineFunction(M, MMI)) |
260 | 111 | return true; |
261 | 2.22k | In.nextDocument(); |
262 | 2.22k | } while (In.setCurrentDocument()); |
263 | 729 | |
264 | 618 | return false; |
265 | 732 | } |
266 | | |
267 | | /// Create an empty function with the given name. |
268 | 315 | static Function *createDummyFunction(StringRef Name, Module &M) { |
269 | 315 | auto &Context = M.getContext(); |
270 | 315 | Function *F = cast<Function>(M.getOrInsertFunction( |
271 | 315 | Name, FunctionType::get(Type::getVoidTy(Context), false))); |
272 | 315 | BasicBlock *BB = BasicBlock::Create(Context, "entry", F); |
273 | 315 | new UnreachableInst(Context, BB); |
274 | 315 | return F; |
275 | 315 | } |
276 | | |
277 | 2.33k | bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI) { |
278 | 2.33k | // Parse the yaml. |
279 | 2.33k | yaml::MachineFunction YamlMF; |
280 | 2.33k | yaml::EmptyContext Ctx; |
281 | 2.33k | yaml::yamlize(In, YamlMF, false, Ctx); |
282 | 2.33k | if (In.error()) |
283 | 5 | return true; |
284 | 2.33k | |
285 | 2.33k | // Search for the corresponding IR function. |
286 | 2.33k | StringRef FunctionName = YamlMF.Name; |
287 | 2.33k | Function *F = M.getFunction(FunctionName); |
288 | 2.33k | if (!F2.33k ) { |
289 | 316 | if (NoLLVMIR316 ) { |
290 | 315 | F = createDummyFunction(FunctionName, M); |
291 | 316 | } else { |
292 | 1 | return error(Twine("function '") + FunctionName + |
293 | 1 | "' isn't defined in the provided LLVM IR"); |
294 | 1 | } |
295 | 2.33k | } |
296 | 2.33k | if (2.33k MMI.getMachineFunction(*F) != nullptr2.33k ) |
297 | 1 | return error(Twine("redefinition of machine function '") + FunctionName + |
298 | 1 | "'"); |
299 | 2.33k | |
300 | 2.33k | // Create the MachineFunction. |
301 | 2.33k | MachineFunction &MF = MMI.getOrCreateMachineFunction(*F); |
302 | 2.33k | if (initializeMachineFunction(YamlMF, MF)) |
303 | 104 | return true; |
304 | 2.22k | |
305 | 2.22k | return false; |
306 | 2.22k | } |
307 | | |
308 | 2.22k | static bool isSSA(const MachineFunction &MF) { |
309 | 2.22k | const MachineRegisterInfo &MRI = MF.getRegInfo(); |
310 | 9.35k | for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E9.35k ; ++I7.13k ) { |
311 | 7.17k | unsigned Reg = TargetRegisterInfo::index2VirtReg(I); |
312 | 7.17k | if (!MRI.hasOneDef(Reg) && 7.17k !MRI.def_empty(Reg)724 ) |
313 | 48 | return false; |
314 | 7.17k | } |
315 | 2.17k | return true; |
316 | 2.22k | } |
317 | | |
318 | 2.22k | void MIRParserImpl::computeFunctionProperties(MachineFunction &MF) { |
319 | 2.22k | MachineFunctionProperties &Properties = MF.getProperties(); |
320 | 2.22k | |
321 | 2.22k | bool HasPHI = false; |
322 | 2.22k | bool HasInlineAsm = false; |
323 | 3.15k | for (const MachineBasicBlock &MBB : MF) { |
324 | 17.0k | for (const MachineInstr &MI : MBB) { |
325 | 17.0k | if (MI.isPHI()) |
326 | 64 | HasPHI = true; |
327 | 17.0k | if (MI.isInlineAsm()) |
328 | 16 | HasInlineAsm = true; |
329 | 17.0k | } |
330 | 3.15k | } |
331 | 2.22k | if (!HasPHI) |
332 | 2.17k | Properties.set(MachineFunctionProperties::Property::NoPHIs); |
333 | 2.22k | MF.setHasInlineAsm(HasInlineAsm); |
334 | 2.22k | |
335 | 2.22k | if (isSSA(MF)) |
336 | 2.17k | Properties.set(MachineFunctionProperties::Property::IsSSA); |
337 | 2.22k | else |
338 | 48 | Properties.reset(MachineFunctionProperties::Property::IsSSA); |
339 | 2.22k | |
340 | 2.22k | const MachineRegisterInfo &MRI = MF.getRegInfo(); |
341 | 2.22k | if (MRI.getNumVirtRegs() == 0) |
342 | 524 | Properties.set(MachineFunctionProperties::Property::NoVRegs); |
343 | 2.22k | } |
344 | | |
345 | | bool |
346 | | MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF, |
347 | 2.33k | MachineFunction &MF) { |
348 | 2.33k | // TODO: Recreate the machine function. |
349 | 2.33k | initNames2RegClasses(MF); |
350 | 2.33k | initNames2RegBanks(MF); |
351 | 2.33k | if (YamlMF.Alignment) |
352 | 840 | MF.setAlignment(YamlMF.Alignment); |
353 | 2.33k | MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice); |
354 | 2.33k | |
355 | 2.33k | if (YamlMF.Legalized) |
356 | 990 | MF.getProperties().set(MachineFunctionProperties::Property::Legalized); |
357 | 2.33k | if (YamlMF.RegBankSelected) |
358 | 756 | MF.getProperties().set( |
359 | 756 | MachineFunctionProperties::Property::RegBankSelected); |
360 | 2.33k | if (YamlMF.Selected) |
361 | 2 | MF.getProperties().set(MachineFunctionProperties::Property::Selected); |
362 | 2.33k | |
363 | 2.33k | PerFunctionMIParsingState PFS(MF, SM, IRSlots, Names2RegClasses, |
364 | 2.33k | Names2RegBanks); |
365 | 2.33k | if (parseRegisterInfo(PFS, YamlMF)) |
366 | 5 | return true; |
367 | 2.32k | if (2.32k !YamlMF.Constants.empty()2.32k ) { |
368 | 13 | auto *ConstantPool = MF.getConstantPool(); |
369 | 13 | assert(ConstantPool && "Constant pool must be created"); |
370 | 13 | if (initializeConstantPool(PFS, *ConstantPool, YamlMF)) |
371 | 3 | return true; |
372 | 2.32k | } |
373 | 2.32k | |
374 | 2.32k | StringRef BlockStr = YamlMF.Body.Value.Value; |
375 | 2.32k | SMDiagnostic Error; |
376 | 2.32k | SourceMgr BlockSM; |
377 | 2.32k | BlockSM.AddNewSourceBuffer( |
378 | 2.32k | MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false), |
379 | 2.32k | SMLoc()); |
380 | 2.32k | PFS.SM = &BlockSM; |
381 | 2.32k | if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)2.32k ) { |
382 | 12 | reportDiagnostic( |
383 | 12 | diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange)); |
384 | 12 | return true; |
385 | 12 | } |
386 | 2.31k | PFS.SM = &SM; |
387 | 2.31k | |
388 | 2.31k | // Initialize the frame information after creating all the MBBs so that the |
389 | 2.31k | // MBB references in the frame information can be resolved. |
390 | 2.31k | if (initializeFrameInfo(PFS, YamlMF)) |
391 | 7 | return true; |
392 | 2.30k | // Initialize the jump table after creating all the MBBs so that the MBB |
393 | 2.30k | // references can be resolved. |
394 | 2.30k | if (2.30k !YamlMF.JumpTableInfo.Entries.empty() && |
395 | 9 | initializeJumpTableInfo(PFS, YamlMF.JumpTableInfo)) |
396 | 1 | return true; |
397 | 2.30k | // Parse the machine instructions after creating all of the MBBs so that the |
398 | 2.30k | // parser can resolve the MBB references. |
399 | 2.30k | StringRef InsnStr = YamlMF.Body.Value.Value; |
400 | 2.30k | SourceMgr InsnSM; |
401 | 2.30k | InsnSM.AddNewSourceBuffer( |
402 | 2.30k | MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false), |
403 | 2.30k | SMLoc()); |
404 | 2.30k | PFS.SM = &InsnSM; |
405 | 2.30k | if (parseMachineInstructions(PFS, InsnStr, Error)2.30k ) { |
406 | 75 | reportDiagnostic( |
407 | 75 | diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange)); |
408 | 75 | return true; |
409 | 75 | } |
410 | 2.22k | PFS.SM = &SM; |
411 | 2.22k | |
412 | 2.22k | if (setupRegisterInfo(PFS, YamlMF)) |
413 | 1 | return true; |
414 | 2.22k | |
415 | 2.22k | computeFunctionProperties(MF); |
416 | 2.22k | |
417 | 2.22k | MF.verify(); |
418 | 2.22k | return false; |
419 | 2.22k | } |
420 | | |
421 | | bool MIRParserImpl::parseRegisterInfo(PerFunctionMIParsingState &PFS, |
422 | 2.33k | const yaml::MachineFunction &YamlMF) { |
423 | 2.33k | MachineFunction &MF = PFS.MF; |
424 | 2.33k | MachineRegisterInfo &RegInfo = MF.getRegInfo(); |
425 | 2.33k | assert(RegInfo.tracksLiveness()); |
426 | 2.33k | if (!YamlMF.TracksRegLiveness) |
427 | 1.46k | RegInfo.invalidateLiveness(); |
428 | 2.33k | |
429 | 2.33k | SMDiagnostic Error; |
430 | 2.33k | // Parse the virtual register information. |
431 | 7.32k | for (const auto &VReg : YamlMF.VirtualRegisters) { |
432 | 7.32k | VRegInfo &Info = PFS.getVRegInfo(VReg.ID.Value); |
433 | 7.32k | if (Info.Explicit) |
434 | 1 | return error(VReg.ID.SourceRange.Start, |
435 | 1 | Twine("redefinition of virtual register '%") + |
436 | 1 | Twine(VReg.ID.Value) + "'"); |
437 | 7.32k | Info.Explicit = true; |
438 | 7.32k | |
439 | 7.32k | if (StringRef(VReg.Class.Value).equals("_")7.32k ) { |
440 | 2.38k | Info.Kind = VRegInfo::GENERIC; |
441 | 7.32k | } else { |
442 | 4.94k | const auto *RC = getRegClass(MF, VReg.Class.Value); |
443 | 4.94k | if (RC4.94k ) { |
444 | 2.88k | Info.Kind = VRegInfo::NORMAL; |
445 | 2.88k | Info.D.RC = RC; |
446 | 4.94k | } else { |
447 | 2.06k | const RegisterBank *RegBank = getRegBank(MF, VReg.Class.Value); |
448 | 2.06k | if (!RegBank) |
449 | 1 | return error( |
450 | 1 | VReg.Class.SourceRange.Start, |
451 | 1 | Twine("use of undefined register class or register bank '") + |
452 | 1 | VReg.Class.Value + "'"); |
453 | 2.05k | Info.Kind = VRegInfo::REGBANK; |
454 | 2.05k | Info.D.RegBank = RegBank; |
455 | 2.05k | } |
456 | 4.94k | } |
457 | 7.32k | |
458 | 7.32k | if (7.32k !VReg.PreferredRegister.Value.empty()7.32k ) { |
459 | 9 | if (Info.Kind != VRegInfo::NORMAL) |
460 | 0 | return error(VReg.Class.SourceRange.Start, |
461 | 0 | Twine("preferred register can only be set for normal vregs")); |
462 | 9 | |
463 | 9 | if (9 parseRegisterReference(PFS, Info.PreferredReg, |
464 | 9 | VReg.PreferredRegister.Value, Error)) |
465 | 0 | return error(Error, VReg.PreferredRegister.SourceRange); |
466 | 2.32k | } |
467 | 7.32k | } |
468 | 2.32k | |
469 | 2.32k | // Parse the liveins. |
470 | 2.32k | for (const auto &LiveIn : YamlMF.LiveIns) 2.32k { |
471 | 522 | unsigned Reg = 0; |
472 | 522 | if (parseNamedRegisterReference(PFS, Reg, LiveIn.Register.Value, Error)) |
473 | 2 | return error(Error, LiveIn.Register.SourceRange); |
474 | 520 | unsigned VReg = 0; |
475 | 520 | if (!LiveIn.VirtualRegister.Value.empty()520 ) { |
476 | 161 | VRegInfo *Info; |
477 | 161 | if (parseVirtualRegisterReference(PFS, Info, LiveIn.VirtualRegister.Value, |
478 | 161 | Error)) |
479 | 1 | return error(Error, LiveIn.VirtualRegister.SourceRange); |
480 | 160 | VReg = Info->VReg; |
481 | 160 | } |
482 | 519 | RegInfo.addLiveIn(Reg, VReg); |
483 | 519 | } |
484 | 2.32k | |
485 | 2.32k | // Parse the callee saved registers (Registers that will |
486 | 2.32k | // be saved for the caller). |
487 | 2.32k | if (2.32k YamlMF.CalleeSavedRegisters2.32k ) { |
488 | 17 | SmallVector<MCPhysReg, 16> CalleeSavedRegisters; |
489 | 737 | for (const auto &RegSource : YamlMF.CalleeSavedRegisters.getValue()) { |
490 | 737 | unsigned Reg = 0; |
491 | 737 | if (parseNamedRegisterReference(PFS, Reg, RegSource.Value, Error)) |
492 | 0 | return error(Error, RegSource.SourceRange); |
493 | 737 | CalleeSavedRegisters.push_back(Reg); |
494 | 737 | } |
495 | 17 | RegInfo.setCalleeSavedRegs(CalleeSavedRegisters); |
496 | 17 | } |
497 | 2.32k | |
498 | 2.32k | return false; |
499 | 2.33k | } |
500 | | |
501 | | bool MIRParserImpl::setupRegisterInfo(const PerFunctionMIParsingState &PFS, |
502 | 2.22k | const yaml::MachineFunction &YamlMF) { |
503 | 2.22k | MachineFunction &MF = PFS.MF; |
504 | 2.22k | MachineRegisterInfo &MRI = MF.getRegInfo(); |
505 | 2.22k | bool Error = false; |
506 | 2.22k | // Create VRegs |
507 | 7.69k | for (auto P : PFS.VRegInfos) { |
508 | 7.69k | const VRegInfo &Info = *P.second; |
509 | 7.69k | unsigned Reg = Info.VReg; |
510 | 7.69k | switch (Info.Kind) { |
511 | 1 | case VRegInfo::UNKNOWN: |
512 | 1 | error(Twine("Cannot determine class/bank of virtual register ") + |
513 | 1 | Twine(P.first) + " in function '" + MF.getName() + "'"); |
514 | 1 | Error = true; |
515 | 1 | break; |
516 | 2.94k | case VRegInfo::NORMAL: |
517 | 2.94k | MRI.setRegClass(Reg, Info.D.RC); |
518 | 2.94k | if (Info.PreferredReg != 0) |
519 | 9 | MRI.setSimpleHint(Reg, Info.PreferredReg); |
520 | 2.94k | break; |
521 | 2.56k | case VRegInfo::GENERIC: |
522 | 2.56k | break; |
523 | 2.19k | case VRegInfo::REGBANK: |
524 | 2.19k | MRI.setRegBank(Reg, *Info.D.RegBank); |
525 | 2.19k | break; |
526 | 2.22k | } |
527 | 2.22k | } |
528 | 2.22k | |
529 | 2.22k | // Compute MachineRegisterInfo::UsedPhysRegMask |
530 | 2.22k | for (const MachineBasicBlock &MBB : MF) 2.22k { |
531 | 17.0k | for (const MachineInstr &MI : MBB) { |
532 | 52.1k | for (const MachineOperand &MO : MI.operands()) { |
533 | 52.1k | if (!MO.isRegMask()) |
534 | 52.0k | continue; |
535 | 115 | MRI.addPhysRegsUsedFromRegMask(MO.getRegMask()); |
536 | 115 | } |
537 | 17.0k | } |
538 | 3.15k | } |
539 | 2.22k | |
540 | 2.22k | // FIXME: This is a temporary workaround until the reserved registers can be |
541 | 2.22k | // serialized. |
542 | 2.22k | MRI.freezeReservedRegs(MF); |
543 | 2.22k | return Error; |
544 | 2.22k | } |
545 | | |
546 | | bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS, |
547 | 2.31k | const yaml::MachineFunction &YamlMF) { |
548 | 2.31k | MachineFunction &MF = PFS.MF; |
549 | 2.31k | MachineFrameInfo &MFI = MF.getFrameInfo(); |
550 | 2.31k | const Function &F = *MF.getFunction(); |
551 | 2.31k | const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo; |
552 | 2.31k | MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken); |
553 | 2.31k | MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken); |
554 | 2.31k | MFI.setHasStackMap(YamlMFI.HasStackMap); |
555 | 2.31k | MFI.setHasPatchPoint(YamlMFI.HasPatchPoint); |
556 | 2.31k | MFI.setStackSize(YamlMFI.StackSize); |
557 | 2.31k | MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment); |
558 | 2.31k | if (YamlMFI.MaxAlignment) |
559 | 89 | MFI.ensureMaxAlignment(YamlMFI.MaxAlignment); |
560 | 2.31k | MFI.setAdjustsStack(YamlMFI.AdjustsStack); |
561 | 2.31k | MFI.setHasCalls(YamlMFI.HasCalls); |
562 | 2.31k | if (YamlMFI.MaxCallFrameSize != ~0u) |
563 | 146 | MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize); |
564 | 2.31k | MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment); |
565 | 2.31k | MFI.setHasVAStart(YamlMFI.HasVAStart); |
566 | 2.31k | MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc); |
567 | 2.31k | if (!YamlMFI.SavePoint.Value.empty()2.31k ) { |
568 | 1 | MachineBasicBlock *MBB = nullptr; |
569 | 1 | if (parseMBBReference(PFS, MBB, YamlMFI.SavePoint)) |
570 | 0 | return true; |
571 | 1 | MFI.setSavePoint(MBB); |
572 | 1 | } |
573 | 2.31k | if (2.31k !YamlMFI.RestorePoint.Value.empty()2.31k ) { |
574 | 1 | MachineBasicBlock *MBB = nullptr; |
575 | 1 | if (parseMBBReference(PFS, MBB, YamlMFI.RestorePoint)) |
576 | 0 | return true; |
577 | 1 | MFI.setRestorePoint(MBB); |
578 | 1 | } |
579 | 2.31k | |
580 | 2.31k | std::vector<CalleeSavedInfo> CSIInfo; |
581 | 2.31k | // Initialize the fixed frame objects. |
582 | 92 | for (const auto &Object : YamlMF.FixedStackObjects) { |
583 | 92 | int ObjectIdx; |
584 | 92 | if (Object.Type != yaml::FixedMachineStackObject::SpillSlot) |
585 | 42 | ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset, |
586 | 42 | Object.IsImmutable, Object.IsAliased); |
587 | 92 | else |
588 | 50 | ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset); |
589 | 92 | MFI.setObjectAlignment(ObjectIdx, Object.Alignment); |
590 | 92 | MFI.setStackID(ObjectIdx, Object.StackID); |
591 | 92 | if (!PFS.FixedStackObjectSlots.insert(std::make_pair(Object.ID.Value, |
592 | 92 | ObjectIdx)) |
593 | 92 | .second) |
594 | 1 | return error(Object.ID.SourceRange.Start, |
595 | 1 | Twine("redefinition of fixed stack object '%fixed-stack.") + |
596 | 1 | Twine(Object.ID.Value) + "'"); |
597 | 91 | if (91 parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister, |
598 | 91 | Object.CalleeSavedRestored, ObjectIdx)) |
599 | 1 | return true; |
600 | 2.30k | } |
601 | 2.30k | |
602 | 2.30k | // Initialize the ordinary frame objects. |
603 | 2.30k | for (const auto &Object : YamlMF.StackObjects) 2.30k { |
604 | 147 | int ObjectIdx; |
605 | 147 | const AllocaInst *Alloca = nullptr; |
606 | 147 | const yaml::StringValue &Name = Object.Name; |
607 | 147 | if (!Name.Value.empty()147 ) { |
608 | 71 | Alloca = dyn_cast_or_null<AllocaInst>( |
609 | 71 | F.getValueSymbolTable()->lookup(Name.Value)); |
610 | 71 | if (!Alloca) |
611 | 1 | return error(Name.SourceRange.Start, |
612 | 1 | "alloca instruction named '" + Name.Value + |
613 | 1 | "' isn't defined in the function '" + F.getName() + |
614 | 1 | "'"); |
615 | 146 | } |
616 | 146 | if (146 Object.Type == yaml::MachineStackObject::VariableSized146 ) |
617 | 3 | ObjectIdx = MFI.CreateVariableSizedObject(Object.Alignment, Alloca); |
618 | 146 | else |
619 | 143 | ObjectIdx = MFI.CreateStackObject( |
620 | 143 | Object.Size, Object.Alignment, |
621 | 143 | Object.Type == yaml::MachineStackObject::SpillSlot, Alloca); |
622 | 146 | MFI.setObjectOffset(ObjectIdx, Object.Offset); |
623 | 146 | MFI.setStackID(ObjectIdx, Object.StackID); |
624 | 146 | |
625 | 146 | if (!PFS.StackObjectSlots.insert(std::make_pair(Object.ID.Value, ObjectIdx)) |
626 | 146 | .second) |
627 | 1 | return error(Object.ID.SourceRange.Start, |
628 | 1 | Twine("redefinition of stack object '%stack.") + |
629 | 1 | Twine(Object.ID.Value) + "'"); |
630 | 145 | if (145 parseCalleeSavedRegister(PFS, CSIInfo, Object.CalleeSavedRegister, |
631 | 145 | Object.CalleeSavedRestored, ObjectIdx)) |
632 | 0 | return true; |
633 | 145 | if (145 Object.LocalOffset145 ) |
634 | 23 | MFI.mapLocalFrameObject(ObjectIdx, Object.LocalOffset.getValue()); |
635 | 145 | if (parseStackObjectsDebugInfo(PFS, Object, ObjectIdx)) |
636 | 2 | return true; |
637 | 2.30k | } |
638 | 2.30k | MFI.setCalleeSavedInfo(CSIInfo); |
639 | 2.30k | if (!CSIInfo.empty()) |
640 | 30 | MFI.setCalleeSavedInfoValid(true); |
641 | 2.30k | |
642 | 2.30k | // Initialize the various stack object references after initializing the |
643 | 2.30k | // stack objects. |
644 | 2.30k | if (!YamlMFI.StackProtector.Value.empty()2.30k ) { |
645 | 2 | SMDiagnostic Error; |
646 | 2 | int FI; |
647 | 2 | if (parseStackObjectReference(PFS, FI, YamlMFI.StackProtector.Value, Error)) |
648 | 1 | return error(Error, YamlMFI.StackProtector.SourceRange); |
649 | 1 | MFI.setStackProtectorIndex(FI); |
650 | 1 | } |
651 | 2.30k | return false; |
652 | 2.31k | } |
653 | | |
654 | | bool MIRParserImpl::parseCalleeSavedRegister(PerFunctionMIParsingState &PFS, |
655 | | std::vector<CalleeSavedInfo> &CSIInfo, |
656 | 236 | const yaml::StringValue &RegisterSource, bool IsRestored, int FrameIdx) { |
657 | 236 | if (RegisterSource.Value.empty()) |
658 | 171 | return false; |
659 | 65 | unsigned Reg = 0; |
660 | 65 | SMDiagnostic Error; |
661 | 65 | if (parseNamedRegisterReference(PFS, Reg, RegisterSource.Value, Error)) |
662 | 1 | return error(Error, RegisterSource.SourceRange); |
663 | 64 | CalleeSavedInfo CSI(Reg, FrameIdx); |
664 | 64 | CSI.setRestored(IsRestored); |
665 | 64 | CSIInfo.push_back(CSI); |
666 | 64 | return false; |
667 | 64 | } |
668 | | |
669 | | /// Verify that given node is of a certain type. Return true on error. |
670 | | template <typename T> |
671 | | static bool typecheckMDNode(T *&Result, MDNode *Node, |
672 | | const yaml::StringValue &Source, |
673 | 4 | StringRef TypeString, MIRParserImpl &Parser) { |
674 | 4 | if (!Node) |
675 | 0 | return false; |
676 | 4 | Result = dyn_cast<T>(Node); |
677 | 4 | if (!Result) |
678 | 1 | return Parser.error(Source.SourceRange.Start, |
679 | 1 | "expected a reference to a '" + TypeString + |
680 | 1 | "' metadata node"); |
681 | 3 | return false; |
682 | 3 | } MIRParser.cpp:bool typecheckMDNode<llvm::DILocalVariable>(llvm::DILocalVariable*&, llvm::MDNode*, llvm::yaml::StringValue const&, llvm::StringRef, llvm::MIRParserImpl&) Line | Count | Source | 673 | 2 | StringRef TypeString, MIRParserImpl &Parser) { | 674 | 2 | if (!Node) | 675 | 0 | return false; | 676 | 2 | Result = dyn_cast<T>(Node); | 677 | 2 | if (!Result) | 678 | 1 | return Parser.error(Source.SourceRange.Start, | 679 | 1 | "expected a reference to a '" + TypeString + | 680 | 1 | "' metadata node"); | 681 | 1 | return false; | 682 | 1 | } |
MIRParser.cpp:bool typecheckMDNode<llvm::DIExpression>(llvm::DIExpression*&, llvm::MDNode*, llvm::yaml::StringValue const&, llvm::StringRef, llvm::MIRParserImpl&) Line | Count | Source | 673 | 1 | StringRef TypeString, MIRParserImpl &Parser) { | 674 | 1 | if (!Node) | 675 | 0 | return false; | 676 | 1 | Result = dyn_cast<T>(Node); | 677 | 1 | if (!Result) | 678 | 0 | return Parser.error(Source.SourceRange.Start, | 679 | 0 | "expected a reference to a '" + TypeString + | 680 | 0 | "' metadata node"); | 681 | 1 | return false; | 682 | 1 | } |
MIRParser.cpp:bool typecheckMDNode<llvm::DILocation>(llvm::DILocation*&, llvm::MDNode*, llvm::yaml::StringValue const&, llvm::StringRef, llvm::MIRParserImpl&) Line | Count | Source | 673 | 1 | StringRef TypeString, MIRParserImpl &Parser) { | 674 | 1 | if (!Node) | 675 | 0 | return false; | 676 | 1 | Result = dyn_cast<T>(Node); | 677 | 1 | if (!Result) | 678 | 0 | return Parser.error(Source.SourceRange.Start, | 679 | 0 | "expected a reference to a '" + TypeString + | 680 | 0 | "' metadata node"); | 681 | 1 | return false; | 682 | 1 | } |
|
683 | | |
684 | | bool MIRParserImpl::parseStackObjectsDebugInfo(PerFunctionMIParsingState &PFS, |
685 | 145 | const yaml::MachineStackObject &Object, int FrameIdx) { |
686 | 145 | // Debug information can only be attached to stack objects; Fixed stack |
687 | 145 | // objects aren't supported. |
688 | 145 | assert(FrameIdx >= 0 && "Expected a stack object frame index"); |
689 | 145 | MDNode *Var = nullptr, *Expr = nullptr, *Loc = nullptr; |
690 | 145 | if (parseMDNode(PFS, Var, Object.DebugVar) || |
691 | 144 | parseMDNode(PFS, Expr, Object.DebugExpr) || |
692 | 144 | parseMDNode(PFS, Loc, Object.DebugLoc)) |
693 | 1 | return true; |
694 | 144 | if (144 !Var && 144 !Expr142 && !Loc142 ) |
695 | 142 | return false; |
696 | 2 | DILocalVariable *DIVar = nullptr; |
697 | 2 | DIExpression *DIExpr = nullptr; |
698 | 2 | DILocation *DILoc = nullptr; |
699 | 2 | if (typecheckMDNode(DIVar, Var, Object.DebugVar, "DILocalVariable", *this) || |
700 | 1 | typecheckMDNode(DIExpr, Expr, Object.DebugExpr, "DIExpression", *this) || |
701 | 1 | typecheckMDNode(DILoc, Loc, Object.DebugLoc, "DILocation", *this)) |
702 | 1 | return true; |
703 | 1 | PFS.MF.setVariableDbgInfo(DIVar, DIExpr, unsigned(FrameIdx), DILoc); |
704 | 1 | return false; |
705 | 1 | } |
706 | | |
707 | | bool MIRParserImpl::parseMDNode(PerFunctionMIParsingState &PFS, |
708 | 433 | MDNode *&Node, const yaml::StringValue &Source) { |
709 | 433 | if (Source.Value.empty()) |
710 | 426 | return false; |
711 | 7 | SMDiagnostic Error; |
712 | 7 | if (llvm::parseMDNode(PFS, Node, Source.Value, Error)) |
713 | 1 | return error(Error, Source.SourceRange); |
714 | 6 | return false; |
715 | 6 | } |
716 | | |
717 | | bool MIRParserImpl::initializeConstantPool(PerFunctionMIParsingState &PFS, |
718 | 13 | MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF) { |
719 | 13 | DenseMap<unsigned, unsigned> &ConstantPoolSlots = PFS.ConstantPoolSlots; |
720 | 13 | const MachineFunction &MF = PFS.MF; |
721 | 13 | const auto &M = *MF.getFunction()->getParent(); |
722 | 13 | SMDiagnostic Error; |
723 | 18 | for (const auto &YamlConstant : YamlMF.Constants) { |
724 | 18 | if (YamlConstant.IsTargetSpecific) |
725 | 18 | // FIXME: Support target-specific constant pools |
726 | 1 | return error(YamlConstant.Value.SourceRange.Start, |
727 | 1 | "Can't parse target-specific constant pool entries yet"); |
728 | 17 | const Constant *Value = dyn_cast_or_null<Constant>( |
729 | 17 | parseConstantValue(YamlConstant.Value.Value, Error, M)); |
730 | 17 | if (!Value) |
731 | 1 | return error(Error, YamlConstant.Value.SourceRange); |
732 | 16 | unsigned Alignment = |
733 | 16 | YamlConstant.Alignment |
734 | 8 | ? YamlConstant.Alignment |
735 | 8 | : M.getDataLayout().getPrefTypeAlignment(Value->getType()); |
736 | 16 | unsigned Index = ConstantPool.getConstantPoolIndex(Value, Alignment); |
737 | 16 | if (!ConstantPoolSlots.insert(std::make_pair(YamlConstant.ID.Value, Index)) |
738 | 16 | .second) |
739 | 1 | return error(YamlConstant.ID.SourceRange.Start, |
740 | 1 | Twine("redefinition of constant pool item '%const.") + |
741 | 1 | Twine(YamlConstant.ID.Value) + "'"); |
742 | 10 | } |
743 | 10 | return false; |
744 | 10 | } |
745 | | |
746 | | bool MIRParserImpl::initializeJumpTableInfo(PerFunctionMIParsingState &PFS, |
747 | 9 | const yaml::MachineJumpTable &YamlJTI) { |
748 | 9 | MachineJumpTableInfo *JTI = PFS.MF.getOrCreateJumpTableInfo(YamlJTI.Kind); |
749 | 10 | for (const auto &Entry : YamlJTI.Entries) { |
750 | 10 | std::vector<MachineBasicBlock *> Blocks; |
751 | 85 | for (const auto &MBBSource : Entry.Blocks) { |
752 | 85 | MachineBasicBlock *MBB = nullptr; |
753 | 85 | if (parseMBBReference(PFS, MBB, MBBSource.Value)) |
754 | 0 | return true; |
755 | 85 | Blocks.push_back(MBB); |
756 | 85 | } |
757 | 10 | unsigned Index = JTI->createJumpTableIndex(Blocks); |
758 | 10 | if (!PFS.JumpTableSlots.insert(std::make_pair(Entry.ID.Value, Index)) |
759 | 10 | .second) |
760 | 1 | return error(Entry.ID.SourceRange.Start, |
761 | 1 | Twine("redefinition of jump table entry '%jump-table.") + |
762 | 1 | Twine(Entry.ID.Value) + "'"); |
763 | 8 | } |
764 | 8 | return false; |
765 | 8 | } |
766 | | |
767 | | bool MIRParserImpl::parseMBBReference(PerFunctionMIParsingState &PFS, |
768 | | MachineBasicBlock *&MBB, |
769 | 87 | const yaml::StringValue &Source) { |
770 | 87 | SMDiagnostic Error; |
771 | 87 | if (llvm::parseMBBReference(PFS, MBB, Source.Value, Error)) |
772 | 0 | return error(Error, Source.SourceRange); |
773 | 87 | return false; |
774 | 87 | } |
775 | | |
776 | | SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error, |
777 | 7 | SMRange SourceRange) { |
778 | 7 | assert(SourceRange.isValid() && "Invalid source range"); |
779 | 7 | SMLoc Loc = SourceRange.Start; |
780 | 7 | bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() && |
781 | 7 | *Loc.getPointer() == '\''; |
782 | 7 | // Translate the location of the error from the location in the MI string to |
783 | 7 | // the corresponding location in the MIR file. |
784 | 7 | Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() + |
785 | 7 | (HasQuote ? 17 : 00 )); |
786 | 7 | |
787 | 7 | // TODO: Translate any source ranges as well. |
788 | 7 | return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None, |
789 | 7 | Error.getFixIts()); |
790 | 7 | } |
791 | | |
792 | | SMDiagnostic MIRParserImpl::diagFromBlockStringDiag(const SMDiagnostic &Error, |
793 | 88 | SMRange SourceRange) { |
794 | 88 | assert(SourceRange.isValid()); |
795 | 88 | |
796 | 88 | // Translate the location of the error from the location in the llvm IR string |
797 | 88 | // to the corresponding location in the MIR file. |
798 | 88 | auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start); |
799 | 88 | unsigned Line = LineAndColumn.first + Error.getLineNo() - 1; |
800 | 88 | unsigned Column = Error.getColumnNo(); |
801 | 88 | StringRef LineStr = Error.getLineContents(); |
802 | 88 | SMLoc Loc = Error.getLoc(); |
803 | 88 | |
804 | 88 | // Get the full line and adjust the column number by taking the indentation of |
805 | 88 | // LLVM IR into account. |
806 | 88 | for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E; |
807 | 2.07k | L != E2.07k ; ++L1.99k ) { |
808 | 2.07k | if (L.line_number() == Line2.07k ) { |
809 | 88 | LineStr = *L; |
810 | 88 | Loc = SMLoc::getFromPointer(LineStr.data()); |
811 | 88 | auto Indent = LineStr.find(Error.getLineContents()); |
812 | 88 | if (Indent != StringRef::npos) |
813 | 88 | Column += Indent; |
814 | 88 | break; |
815 | 88 | } |
816 | 2.07k | } |
817 | 88 | |
818 | 88 | return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(), |
819 | 88 | Error.getMessage(), LineStr, Error.getRanges(), |
820 | 88 | Error.getFixIts()); |
821 | 88 | } |
822 | | |
823 | 2.33k | void MIRParserImpl::initNames2RegClasses(const MachineFunction &MF) { |
824 | 2.33k | if (!Names2RegClasses.empty()) |
825 | 1.60k | return; |
826 | 724 | const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); |
827 | 60.1k | for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E60.1k ; ++I59.4k ) { |
828 | 59.4k | const auto *RC = TRI->getRegClass(I); |
829 | 59.4k | Names2RegClasses.insert( |
830 | 59.4k | std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC)); |
831 | 59.4k | } |
832 | 2.33k | } |
833 | | |
834 | 2.33k | void MIRParserImpl::initNames2RegBanks(const MachineFunction &MF) { |
835 | 2.33k | if (!Names2RegBanks.empty()) |
836 | 1.59k | return; |
837 | 739 | const RegisterBankInfo *RBI = MF.getSubtarget().getRegBankInfo(); |
838 | 739 | // If the target does not support GlobalISel, we may not have a |
839 | 739 | // register bank info. |
840 | 739 | if (!RBI) |
841 | 100 | return; |
842 | 2.02k | for (unsigned I = 0, E = RBI->getNumRegBanks(); 639 I < E2.02k ; ++I1.38k ) { |
843 | 1.38k | const auto &RegBank = RBI->getRegBank(I); |
844 | 1.38k | Names2RegBanks.insert( |
845 | 1.38k | std::make_pair(StringRef(RegBank.getName()).lower(), &RegBank)); |
846 | 1.38k | } |
847 | 2.33k | } |
848 | | |
849 | | const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF, |
850 | 4.94k | StringRef Name) { |
851 | 4.94k | auto RegClassInfo = Names2RegClasses.find(Name); |
852 | 4.94k | if (RegClassInfo == Names2RegClasses.end()) |
853 | 2.06k | return nullptr; |
854 | 2.88k | return RegClassInfo->getValue(); |
855 | 2.88k | } |
856 | | |
857 | | const RegisterBank *MIRParserImpl::getRegBank(const MachineFunction &MF, |
858 | 2.06k | StringRef Name) { |
859 | 2.06k | auto RegBankInfo = Names2RegBanks.find(Name); |
860 | 2.06k | if (RegBankInfo == Names2RegBanks.end()) |
861 | 1 | return nullptr; |
862 | 2.05k | return RegBankInfo->getValue(); |
863 | 2.05k | } |
864 | | |
865 | | MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl) |
866 | 733 | : Impl(std::move(Impl)) {} |
867 | | |
868 | 705 | MIRParser::~MIRParser() {} |
869 | | |
870 | 733 | std::unique_ptr<Module> MIRParser::parseIRModule() { |
871 | 733 | return Impl->parseIRModule(); |
872 | 733 | } |
873 | | |
874 | 732 | bool MIRParser::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) { |
875 | 732 | return Impl->parseMachineFunctions(M, MMI); |
876 | 732 | } |
877 | | |
878 | | std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename, |
879 | | SMDiagnostic &Error, |
880 | 712 | LLVMContext &Context) { |
881 | 712 | auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename); |
882 | 712 | if (std::error_code EC712 = FileOrErr.getError()) { |
883 | 0 | Error = SMDiagnostic(Filename, SourceMgr::DK_Error, |
884 | 0 | "Could not open input file: " + EC.message()); |
885 | 0 | return nullptr; |
886 | 0 | } |
887 | 712 | return createMIRParser(std::move(FileOrErr.get()), Context); |
888 | 712 | } |
889 | | |
890 | | std::unique_ptr<MIRParser> |
891 | | llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents, |
892 | 733 | LLVMContext &Context) { |
893 | 733 | auto Filename = Contents->getBufferIdentifier(); |
894 | 733 | if (Context.shouldDiscardValueNames()733 ) { |
895 | 0 | Context.diagnose(DiagnosticInfoMIRParser( |
896 | 0 | DS_Error, |
897 | 0 | SMDiagnostic( |
898 | 0 | Filename, SourceMgr::DK_Error, |
899 | 0 | "Can't read MIR with a Context that discards named Values"))); |
900 | 0 | return nullptr; |
901 | 0 | } |
902 | 733 | return llvm::make_unique<MIRParser>( |
903 | 733 | llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context)); |
904 | 733 | } |