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