/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/polly/include/polly/ScopDetectionDiagnostic.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- ScopDetectionDiagnostic.h - Diagnostic for ScopDetection -*- C++ -*-===// |
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 | | // Small set of diagnostic helper classes to encapsulate any errors occurred |
11 | | // during the detection of Scops. |
12 | | // |
13 | | // The ScopDetection defines a set of error classes (via Statistic variables) |
14 | | // that groups a number of individual errors into a group, e.g. non-affinity |
15 | | // related errors. |
16 | | // On error we generate an object that carries enough additional information |
17 | | // to diagnose the error and generate a helpful error message. |
18 | | // |
19 | | //===----------------------------------------------------------------------===// |
20 | | |
21 | | #ifndef POLLY_SCOPDETECTIONDIAGNOSTIC_H |
22 | | #define POLLY_SCOPDETECTIONDIAGNOSTIC_H |
23 | | |
24 | | #include "llvm/ADT/SmallVector.h" |
25 | | #include "llvm/Analysis/LoopInfo.h" |
26 | | #include "llvm/IR/DebugLoc.h" |
27 | | #include "llvm/IR/Instruction.h" |
28 | | #include <cstddef> |
29 | | #include <memory> |
30 | | #include <string> |
31 | | #include <utility> |
32 | | #include <vector> |
33 | | |
34 | | using namespace llvm; |
35 | | |
36 | | namespace llvm { |
37 | | |
38 | | class AliasSet; |
39 | | class BasicBlock; |
40 | | class OptimizationRemarkEmitter; |
41 | | class raw_ostream; |
42 | | class Region; |
43 | | class SCEV; |
44 | | class Value; |
45 | | |
46 | | } // namespace llvm |
47 | | |
48 | | namespace polly { |
49 | | |
50 | | /// Type to hold region delimiters (entry & exit block). |
51 | | using BBPair = std::pair<BasicBlock *, BasicBlock *>; |
52 | | |
53 | | /// Return the region delimiters (entry & exit block) of @p R. |
54 | | BBPair getBBPairForRegion(const Region *R); |
55 | | |
56 | | /// Set the begin and end source location for the region limited by @p P. |
57 | | void getDebugLocations(const BBPair &P, DebugLoc &Begin, DebugLoc &End); |
58 | | |
59 | | class RejectLog; |
60 | | |
61 | | /// Emit optimization remarks about the rejected regions to the user. |
62 | | /// |
63 | | /// This emits the content of the reject log as optimization remarks. |
64 | | /// Remember to at least track failures (-polly-detect-track-failures). |
65 | | /// @param P The region delimiters (entry & exit) we emit remarks for. |
66 | | /// @param Log The error log containing all messages being emitted as remark. |
67 | | void emitRejectionRemarks(const BBPair &P, const RejectLog &Log, |
68 | | OptimizationRemarkEmitter &ORE); |
69 | | |
70 | | // Discriminator for LLVM-style RTTI (dyn_cast<> et al.) |
71 | | enum class RejectReasonKind { |
72 | | // CFG Category |
73 | | CFG, |
74 | | InvalidTerminator, |
75 | | IrreducibleRegion, |
76 | | UnreachableInExit, |
77 | | LastCFG, |
78 | | |
79 | | // Non-Affinity |
80 | | AffFunc, |
81 | | UndefCond, |
82 | | InvalidCond, |
83 | | UndefOperand, |
84 | | NonAffBranch, |
85 | | NoBasePtr, |
86 | | UndefBasePtr, |
87 | | VariantBasePtr, |
88 | | NonAffineAccess, |
89 | | DifferentElementSize, |
90 | | LastAffFunc, |
91 | | |
92 | | LoopBound, |
93 | | LoopHasNoExit, |
94 | | LoopOnlySomeLatches, |
95 | | |
96 | | FuncCall, |
97 | | NonSimpleMemoryAccess, |
98 | | |
99 | | Alias, |
100 | | |
101 | | // Other |
102 | | Other, |
103 | | IntToPtr, |
104 | | Alloca, |
105 | | UnknownInst, |
106 | | Entry, |
107 | | Unprofitable, |
108 | | LastOther |
109 | | }; |
110 | | |
111 | | //===----------------------------------------------------------------------===// |
112 | | /// Base class of all reject reasons found during Scop detection. |
113 | | /// |
114 | | /// Subclasses of RejectReason should provide means to capture enough |
115 | | /// diagnostic information to help clients figure out what and where something |
116 | | /// went wrong in the Scop detection. |
117 | | class RejectReason { |
118 | | private: |
119 | | const RejectReasonKind Kind; |
120 | | |
121 | | protected: |
122 | | static const DebugLoc Unknown; |
123 | | |
124 | | public: |
125 | | RejectReason(RejectReasonKind K); |
126 | | |
127 | 591 | virtual ~RejectReason() = default; |
128 | | |
129 | 0 | RejectReasonKind getKind() const { return Kind; } |
130 | | |
131 | | /// Generate the remark name to identify this remark. |
132 | | /// |
133 | | /// @return A short string that identifies the error. |
134 | | virtual std::string getRemarkName() const = 0; |
135 | | |
136 | | /// Get the Basic Block containing this remark. |
137 | | /// |
138 | | /// @return The Basic Block containing this remark. |
139 | | virtual const Value *getRemarkBB() const = 0; |
140 | | |
141 | | /// Generate a reasonable diagnostic message describing this error. |
142 | | /// |
143 | | /// @return A debug message representing this error. |
144 | | virtual std::string getMessage() const = 0; |
145 | | |
146 | | /// Generate a message for the end-user describing this error. |
147 | | /// |
148 | | /// The message provided has to be suitable for the end-user. So it should |
149 | | /// not reference any LLVM internal data structures or terminology. |
150 | | /// Ideally, the message helps the end-user to increase the size of the |
151 | | /// regions amenable to Polly. |
152 | | /// |
153 | | /// @return A short message representing this error. |
154 | 187 | virtual std::string getEndUserMessage() const { return "Unspecified error."; } |
155 | | |
156 | | /// Get the source location of this error. |
157 | | /// |
158 | | /// @return The debug location for this error. |
159 | | virtual const DebugLoc &getDebugLoc() const; |
160 | | }; |
161 | | |
162 | | using RejectReasonPtr = std::shared_ptr<RejectReason>; |
163 | | |
164 | | /// Stores all errors that occurred during the detection. |
165 | | class RejectLog { |
166 | | Region *R; |
167 | | SmallVector<RejectReasonPtr, 1> ErrorReports; |
168 | | |
169 | | public: |
170 | 4.97k | explicit RejectLog(Region *R) : R(R) {} |
171 | | |
172 | | using iterator = SmallVector<RejectReasonPtr, 1>::const_iterator; |
173 | | |
174 | 430 | iterator begin() const { return ErrorReports.begin(); } |
175 | 430 | iterator end() const { return ErrorReports.end(); } |
176 | 10.9k | size_t size() const { return ErrorReports.size(); } |
177 | | |
178 | | /// Returns true, if we store at least one error. |
179 | | /// |
180 | | /// @return true, if we store at least one error. |
181 | 9.47k | bool hasErrors() const { return size() > 0; } |
182 | | |
183 | | void print(raw_ostream &OS, int level = 0) const; |
184 | | |
185 | 0 | const Region *region() const { return R; } |
186 | 591 | void report(RejectReasonPtr Reject) { ErrorReports.push_back(Reject); } |
187 | | }; |
188 | | |
189 | | //===----------------------------------------------------------------------===// |
190 | | /// Base class for CFG related reject reasons. |
191 | | /// |
192 | | /// Scop candidates that violate structural restrictions can be grouped under |
193 | | /// this reject reason class. |
194 | | class ReportCFG : public RejectReason { |
195 | | public: |
196 | | ReportCFG(const RejectReasonKind K); |
197 | | |
198 | | /// @name LLVM-RTTI interface |
199 | | //@{ |
200 | | static bool classof(const RejectReason *RR); |
201 | | //@} |
202 | | }; |
203 | | |
204 | | //===----------------------------------------------------------------------===// |
205 | | /// Captures bad terminator within a Scop candidate. |
206 | | class ReportInvalidTerminator : public ReportCFG { |
207 | | BasicBlock *BB; |
208 | | |
209 | | public: |
210 | | ReportInvalidTerminator(BasicBlock *BB) |
211 | 0 | : ReportCFG(RejectReasonKind::InvalidTerminator), BB(BB) {} |
212 | | |
213 | | /// @name LLVM-RTTI interface |
214 | | //@{ |
215 | | static bool classof(const RejectReason *RR); |
216 | | //@} |
217 | | |
218 | | /// @name RejectReason interface |
219 | | //@{ |
220 | | std::string getRemarkName() const override; |
221 | | const Value *getRemarkBB() const override; |
222 | | std::string getMessage() const override; |
223 | | const DebugLoc &getDebugLoc() const override; |
224 | | //@} |
225 | | }; |
226 | | |
227 | | //===----------------------------------------------------------------------===// |
228 | | /// Captures irreducible regions in CFG. |
229 | | class ReportIrreducibleRegion : public ReportCFG { |
230 | | Region *R; |
231 | | DebugLoc DbgLoc; |
232 | | |
233 | | public: |
234 | | ReportIrreducibleRegion(Region *R, DebugLoc DbgLoc) |
235 | 3 | : ReportCFG(RejectReasonKind::IrreducibleRegion), R(R), DbgLoc(DbgLoc) {} |
236 | | |
237 | | /// @name LLVM-RTTI interface |
238 | | //@{ |
239 | | static bool classof(const RejectReason *RR); |
240 | | //@} |
241 | | |
242 | | /// @name RejectReason interface |
243 | | //@{ |
244 | | std::string getRemarkName() const override; |
245 | | const Value *getRemarkBB() const override; |
246 | | std::string getMessage() const override; |
247 | | std::string getEndUserMessage() const override; |
248 | | const DebugLoc &getDebugLoc() const override; |
249 | | //@} |
250 | | }; |
251 | | |
252 | | //===----------------------------------------------------------------------===// |
253 | | /// Captures regions with an unreachable in the exit block. |
254 | | class ReportUnreachableInExit : public ReportCFG { |
255 | | BasicBlock *BB; |
256 | | DebugLoc DbgLoc; |
257 | | |
258 | | public: |
259 | | ReportUnreachableInExit(BasicBlock *BB, DebugLoc DbgLoc) |
260 | 23 | : ReportCFG(RejectReasonKind::UnreachableInExit), BB(BB), DbgLoc(DbgLoc) { |
261 | 23 | } |
262 | | |
263 | | /// @name LLVM-RTTI interface |
264 | | //@{ |
265 | | static bool classof(const RejectReason *RR); |
266 | | //@} |
267 | | |
268 | | /// @name RejectReason interface |
269 | | //@{ |
270 | | std::string getRemarkName() const override; |
271 | | const Value *getRemarkBB() const override; |
272 | | std::string getMessage() const override; |
273 | | std::string getEndUserMessage() const override; |
274 | | const DebugLoc &getDebugLoc() const override; |
275 | | //@} |
276 | | }; |
277 | | |
278 | | //===----------------------------------------------------------------------===// |
279 | | /// Base class for non-affine reject reasons. |
280 | | /// |
281 | | /// Scop candidates that violate restrictions to affinity are reported under |
282 | | /// this class. |
283 | | class ReportAffFunc : public RejectReason { |
284 | | protected: |
285 | | // The instruction that caused non-affinity to occur. |
286 | | const Instruction *Inst; |
287 | | |
288 | | public: |
289 | | ReportAffFunc(const RejectReasonKind K, const Instruction *Inst); |
290 | | |
291 | | /// @name LLVM-RTTI interface |
292 | | //@{ |
293 | | static bool classof(const RejectReason *RR); |
294 | | //@} |
295 | | |
296 | | /// @name RejectReason interface |
297 | | //@{ |
298 | 224 | const DebugLoc &getDebugLoc() const override { return Inst->getDebugLoc(); } |
299 | | //@} |
300 | | }; |
301 | | |
302 | | //===----------------------------------------------------------------------===// |
303 | | /// Captures a condition that is based on an 'undef' value. |
304 | | class ReportUndefCond : public ReportAffFunc { |
305 | | // The BasicBlock we found the broken condition in. |
306 | | BasicBlock *BB; |
307 | | |
308 | | public: |
309 | | ReportUndefCond(const Instruction *Inst, BasicBlock *BB) |
310 | 159 | : ReportAffFunc(RejectReasonKind::UndefCond, Inst), BB(BB) {} |
311 | | |
312 | | /// @name LLVM-RTTI interface |
313 | | //@{ |
314 | | static bool classof(const RejectReason *RR); |
315 | | //@} |
316 | | |
317 | | /// @name RejectReason interface |
318 | | //@{ |
319 | | std::string getRemarkName() const override; |
320 | | const Value *getRemarkBB() const override; |
321 | | std::string getMessage() const override; |
322 | | //@} |
323 | | }; |
324 | | |
325 | | //===----------------------------------------------------------------------===// |
326 | | /// Captures an invalid condition |
327 | | /// |
328 | | /// Conditions have to be either constants or icmp instructions. |
329 | | class ReportInvalidCond : public ReportAffFunc { |
330 | | // The BasicBlock we found the broken condition in. |
331 | | BasicBlock *BB; |
332 | | |
333 | | public: |
334 | | ReportInvalidCond(const Instruction *Inst, BasicBlock *BB) |
335 | 1 | : ReportAffFunc(RejectReasonKind::InvalidCond, Inst), BB(BB) {} |
336 | | |
337 | | /// @name LLVM-RTTI interface |
338 | | //@{ |
339 | | static bool classof(const RejectReason *RR); |
340 | | //@} |
341 | | |
342 | | /// @name RejectReason interface |
343 | | //@{ |
344 | | std::string getRemarkName() const override; |
345 | | const Value *getRemarkBB() const override; |
346 | | std::string getMessage() const override; |
347 | | //@} |
348 | | }; |
349 | | |
350 | | //===----------------------------------------------------------------------===// |
351 | | /// Captures an undefined operand. |
352 | | class ReportUndefOperand : public ReportAffFunc { |
353 | | // The BasicBlock we found the undefined operand in. |
354 | | BasicBlock *BB; |
355 | | |
356 | | public: |
357 | | ReportUndefOperand(BasicBlock *BB, const Instruction *Inst) |
358 | 5 | : ReportAffFunc(RejectReasonKind::UndefOperand, Inst), BB(BB) {} |
359 | | |
360 | | /// @name LLVM-RTTI interface |
361 | | //@{ |
362 | | static bool classof(const RejectReason *RR); |
363 | | //@} |
364 | | |
365 | | /// @name RejectReason interface |
366 | | //@{ |
367 | | std::string getRemarkName() const override; |
368 | | const Value *getRemarkBB() const override; |
369 | | std::string getMessage() const override; |
370 | | //@} |
371 | | }; |
372 | | |
373 | | //===----------------------------------------------------------------------===// |
374 | | /// Captures a non-affine branch. |
375 | | class ReportNonAffBranch : public ReportAffFunc { |
376 | | // The BasicBlock we found the non-affine branch in. |
377 | | BasicBlock *BB; |
378 | | |
379 | | /// LHS & RHS of the failed condition. |
380 | | //@{ |
381 | | const SCEV *LHS; |
382 | | const SCEV *RHS; |
383 | | //@} |
384 | | |
385 | | public: |
386 | | ReportNonAffBranch(BasicBlock *BB, const SCEV *LHS, const SCEV *RHS, |
387 | | const Instruction *Inst) |
388 | | : ReportAffFunc(RejectReasonKind::NonAffBranch, Inst), BB(BB), LHS(LHS), |
389 | 6 | RHS(RHS) {} |
390 | | |
391 | 0 | const SCEV *lhs() { return LHS; } |
392 | 0 | const SCEV *rhs() { return RHS; } |
393 | | |
394 | | /// @name LLVM-RTTI interface |
395 | | //@{ |
396 | | static bool classof(const RejectReason *RR); |
397 | | //@} |
398 | | |
399 | | /// @name RejectReason interface |
400 | | //@{ |
401 | | std::string getRemarkName() const override; |
402 | | const Value *getRemarkBB() const override; |
403 | | std::string getMessage() const override; |
404 | | //@} |
405 | | }; |
406 | | |
407 | | //===----------------------------------------------------------------------===// |
408 | | /// Captures a missing base pointer. |
409 | | class ReportNoBasePtr : public ReportAffFunc { |
410 | | public: |
411 | | ReportNoBasePtr(const Instruction *Inst) |
412 | 0 | : ReportAffFunc(RejectReasonKind::NoBasePtr, Inst) {} |
413 | | |
414 | | /// @name LLVM-RTTI interface |
415 | | //@{ |
416 | | static bool classof(const RejectReason *RR); |
417 | | //@} |
418 | | |
419 | | /// @name RejectReason interface |
420 | | //@{ |
421 | | std::string getRemarkName() const override; |
422 | | const Value *getRemarkBB() const override; |
423 | | std::string getMessage() const override; |
424 | | //@} |
425 | | }; |
426 | | |
427 | | //===----------------------------------------------------------------------===// |
428 | | /// Captures an undefined base pointer. |
429 | | class ReportUndefBasePtr : public ReportAffFunc { |
430 | | public: |
431 | | ReportUndefBasePtr(const Instruction *Inst) |
432 | 5 | : ReportAffFunc(RejectReasonKind::UndefBasePtr, Inst) {} |
433 | | |
434 | | /// @name LLVM-RTTI interface |
435 | | //@{ |
436 | | static bool classof(const RejectReason *RR); |
437 | | //@} |
438 | | |
439 | | /// @name RejectReason interface |
440 | | //@{ |
441 | | std::string getRemarkName() const override; |
442 | | const Value *getRemarkBB() const override; |
443 | | std::string getMessage() const override; |
444 | | //@} |
445 | | }; |
446 | | |
447 | | //===----------------------------------------------------------------------===// |
448 | | /// Captures a base pointer that is not invariant in the region. |
449 | | class ReportVariantBasePtr : public ReportAffFunc { |
450 | | // The variant base pointer. |
451 | | Value *BaseValue; |
452 | | |
453 | | public: |
454 | | ReportVariantBasePtr(Value *BaseValue, const Instruction *Inst) |
455 | | : ReportAffFunc(RejectReasonKind::VariantBasePtr, Inst), |
456 | 10 | BaseValue(BaseValue) {} |
457 | | |
458 | | /// @name LLVM-RTTI interface |
459 | | //@{ |
460 | | static bool classof(const RejectReason *RR); |
461 | | //@} |
462 | | |
463 | | /// @name RejectReason interface |
464 | | //@{ |
465 | | std::string getRemarkName() const override; |
466 | | const Value *getRemarkBB() const override; |
467 | | std::string getMessage() const override; |
468 | | std::string getEndUserMessage() const override; |
469 | | //@} |
470 | | }; |
471 | | |
472 | | //===----------------------------------------------------------------------===// |
473 | | /// Captures a non-affine access function. |
474 | | class ReportNonAffineAccess : public ReportAffFunc { |
475 | | // The non-affine access function. |
476 | | const SCEV *AccessFunction; |
477 | | |
478 | | // The base pointer of the memory access. |
479 | | const Value *BaseValue; |
480 | | |
481 | | public: |
482 | | ReportNonAffineAccess(const SCEV *AccessFunction, const Instruction *Inst, |
483 | | const Value *V) |
484 | | : ReportAffFunc(RejectReasonKind::NonAffineAccess, Inst), |
485 | 58 | AccessFunction(AccessFunction), BaseValue(V) {} |
486 | | |
487 | 0 | const SCEV *get() { return AccessFunction; } |
488 | | |
489 | | /// @name LLVM-RTTI interface |
490 | | //@{ |
491 | | static bool classof(const RejectReason *RR); |
492 | | //@} |
493 | | |
494 | | /// @name RejectReason interface |
495 | | //@{ |
496 | | std::string getRemarkName() const override; |
497 | | const Value *getRemarkBB() const override; |
498 | | std::string getMessage() const override; |
499 | | std::string getEndUserMessage() const override; |
500 | | //@} |
501 | | }; |
502 | | |
503 | | //===----------------------------------------------------------------------===// |
504 | | /// Report array accesses with differing element size. |
505 | | class ReportDifferentArrayElementSize : public ReportAffFunc { |
506 | | // The base pointer of the memory access. |
507 | | const Value *BaseValue; |
508 | | |
509 | | public: |
510 | | ReportDifferentArrayElementSize(const Instruction *Inst, const Value *V) |
511 | | : ReportAffFunc(RejectReasonKind::DifferentElementSize, Inst), |
512 | 0 | BaseValue(V) {} |
513 | | |
514 | | /// @name LLVM-RTTI interface |
515 | | //@{ |
516 | | static bool classof(const RejectReason *RR); |
517 | | //@} |
518 | | |
519 | | /// @name RejectReason interface |
520 | | //@{ |
521 | | std::string getRemarkName() const override; |
522 | | const Value *getRemarkBB() const override; |
523 | | std::string getMessage() const override; |
524 | | std::string getEndUserMessage() const override; |
525 | | //@} |
526 | | }; |
527 | | |
528 | | //===----------------------------------------------------------------------===// |
529 | | /// Captures errors with non affine loop bounds. |
530 | | class ReportLoopBound : public RejectReason { |
531 | | // The offending loop. |
532 | | Loop *L; |
533 | | |
534 | | // The non-affine loop bound. |
535 | | const SCEV *LoopCount; |
536 | | |
537 | | // A copy of the offending loop's debug location. |
538 | | const DebugLoc Loc; |
539 | | |
540 | | public: |
541 | | ReportLoopBound(Loop *L, const SCEV *LoopCount); |
542 | | |
543 | 0 | const SCEV *loopCount() { return LoopCount; } |
544 | | |
545 | | /// @name LLVM-RTTI interface |
546 | | //@{ |
547 | | static bool classof(const RejectReason *RR); |
548 | | //@} |
549 | | |
550 | | /// @name RejectReason interface |
551 | | //@{ |
552 | | std::string getRemarkName() const override; |
553 | | const Value *getRemarkBB() const override; |
554 | | std::string getMessage() const override; |
555 | | const DebugLoc &getDebugLoc() const override; |
556 | | std::string getEndUserMessage() const override; |
557 | | //@} |
558 | | }; |
559 | | |
560 | | //===----------------------------------------------------------------------===// |
561 | | /// Captures errors when loop has no exit. |
562 | | class ReportLoopHasNoExit : public RejectReason { |
563 | | /// The loop that has no exit. |
564 | | Loop *L; |
565 | | |
566 | | const DebugLoc Loc; |
567 | | |
568 | | public: |
569 | | ReportLoopHasNoExit(Loop *L) |
570 | | : RejectReason(RejectReasonKind::LoopHasNoExit), L(L), |
571 | 0 | Loc(L->getStartLoc()) {} |
572 | | |
573 | | /// @name LLVM-RTTI interface |
574 | | //@{ |
575 | | static bool classof(const RejectReason *RR); |
576 | | //@} |
577 | | |
578 | | /// @name RejectReason interface |
579 | | //@{ |
580 | | std::string getRemarkName() const override; |
581 | | const Value *getRemarkBB() const override; |
582 | | std::string getMessage() const override; |
583 | | const DebugLoc &getDebugLoc() const override; |
584 | | std::string getEndUserMessage() const override; |
585 | | //@} |
586 | | }; |
587 | | |
588 | | //===----------------------------------------------------------------------===// |
589 | | /// Captures errors when not all loop latches are part of the scop. |
590 | | class ReportLoopOnlySomeLatches : public RejectReason { |
591 | | /// The loop for which not all loop latches are part of the scop. |
592 | | Loop *L; |
593 | | |
594 | | const DebugLoc Loc; |
595 | | |
596 | | public: |
597 | | ReportLoopOnlySomeLatches(Loop *L) |
598 | | : RejectReason(RejectReasonKind::LoopOnlySomeLatches), L(L), |
599 | 5 | Loc(L->getStartLoc()) {} |
600 | | |
601 | | /// @name LLVM-RTTI interface |
602 | | //@{ |
603 | | static bool classof(const RejectReason *RR); |
604 | | //@} |
605 | | |
606 | | /// @name RejectReason interface |
607 | | //@{ |
608 | | std::string getRemarkName() const override; |
609 | | const Value *getRemarkBB() const override; |
610 | | std::string getMessage() const override; |
611 | | const DebugLoc &getDebugLoc() const override; |
612 | | std::string getEndUserMessage() const override; |
613 | | //@} |
614 | | }; |
615 | | |
616 | | //===----------------------------------------------------------------------===// |
617 | | /// Captures errors with non-side-effect-known function calls. |
618 | | class ReportFuncCall : public RejectReason { |
619 | | // The offending call instruction. |
620 | | Instruction *Inst; |
621 | | |
622 | | public: |
623 | | ReportFuncCall(Instruction *Inst); |
624 | | |
625 | | /// @name LLVM-RTTI interface |
626 | | //@{ |
627 | | static bool classof(const RejectReason *RR); |
628 | | //@} |
629 | | |
630 | | /// @name RejectReason interface |
631 | | //@{ |
632 | | std::string getRemarkName() const override; |
633 | | const Value *getRemarkBB() const override; |
634 | | std::string getMessage() const override; |
635 | | const DebugLoc &getDebugLoc() const override; |
636 | | std::string getEndUserMessage() const override; |
637 | | //@} |
638 | | }; |
639 | | |
640 | | //===----------------------------------------------------------------------===// |
641 | | /// Captures errors with aliasing. |
642 | | class ReportAlias : public RejectReason { |
643 | | public: |
644 | | using PointerSnapshotTy = std::vector<const Value *>; |
645 | | |
646 | | private: |
647 | | /// Format an invalid alias set. |
648 | | /// |
649 | | // @param Prefix A prefix string to put before the list of aliasing pointers. |
650 | | // @param Suffix A suffix string to put after the list of aliasing pointers. |
651 | | std::string formatInvalidAlias(std::string Prefix = "", |
652 | | std::string Suffix = "") const; |
653 | | |
654 | | Instruction *Inst; |
655 | | |
656 | | // A snapshot of the llvm values that took part in the aliasing error. |
657 | | mutable PointerSnapshotTy Pointers; |
658 | | |
659 | | public: |
660 | | ReportAlias(Instruction *Inst, AliasSet &AS); |
661 | | |
662 | 0 | const PointerSnapshotTy &getPointers() const { return Pointers; } |
663 | | |
664 | | /// @name LLVM-RTTI interface |
665 | | //@{ |
666 | | static bool classof(const RejectReason *RR); |
667 | | //@} |
668 | | |
669 | | /// @name RejectReason interface |
670 | | //@{ |
671 | | std::string getRemarkName() const override; |
672 | | const Value *getRemarkBB() const override; |
673 | | std::string getMessage() const override; |
674 | | const DebugLoc &getDebugLoc() const override; |
675 | | std::string getEndUserMessage() const override; |
676 | | //@} |
677 | | }; |
678 | | |
679 | | //===----------------------------------------------------------------------===// |
680 | | /// Base class for otherwise ungrouped reject reasons. |
681 | | class ReportOther : public RejectReason { |
682 | | public: |
683 | | ReportOther(const RejectReasonKind K); |
684 | | |
685 | | /// @name LLVM-RTTI interface |
686 | | //@{ |
687 | | static bool classof(const RejectReason *RR); |
688 | | //@} |
689 | | |
690 | | /// @name RejectReason interface |
691 | | //@{ |
692 | | std::string getRemarkName() const override; |
693 | | std::string getMessage() const override; |
694 | | //@} |
695 | | }; |
696 | | |
697 | | //===----------------------------------------------------------------------===// |
698 | | /// Captures errors with bad IntToPtr instructions. |
699 | | class ReportIntToPtr : public ReportOther { |
700 | | // The offending base value. |
701 | | Instruction *BaseValue; |
702 | | |
703 | | public: |
704 | | ReportIntToPtr(Instruction *BaseValue); |
705 | | |
706 | | /// @name LLVM-RTTI interface |
707 | | //@{ |
708 | | static bool classof(const RejectReason *RR); |
709 | | //@} |
710 | | |
711 | | /// @name RejectReason interface |
712 | | //@{ |
713 | | std::string getRemarkName() const override; |
714 | | const Value *getRemarkBB() const override; |
715 | | std::string getMessage() const override; |
716 | | const DebugLoc &getDebugLoc() const override; |
717 | | //@} |
718 | | }; |
719 | | |
720 | | //===----------------------------------------------------------------------===// |
721 | | /// Captures errors with alloca instructions. |
722 | | class ReportAlloca : public ReportOther { |
723 | | Instruction *Inst; |
724 | | |
725 | | public: |
726 | | ReportAlloca(Instruction *Inst); |
727 | | |
728 | | /// @name LLVM-RTTI interface |
729 | | //@{ |
730 | | static bool classof(const RejectReason *RR); |
731 | | //@} |
732 | | |
733 | | /// @name RejectReason interface |
734 | | //@{ |
735 | | std::string getRemarkName() const override; |
736 | | const Value *getRemarkBB() const override; |
737 | | std::string getMessage() const override; |
738 | | const DebugLoc &getDebugLoc() const override; |
739 | | //@} |
740 | | }; |
741 | | |
742 | | //===----------------------------------------------------------------------===// |
743 | | /// Captures errors with unknown instructions. |
744 | | class ReportUnknownInst : public ReportOther { |
745 | | Instruction *Inst; |
746 | | |
747 | | public: |
748 | | ReportUnknownInst(Instruction *Inst); |
749 | | |
750 | | /// @name LLVM-RTTI interface |
751 | | //@{ |
752 | | static bool classof(const RejectReason *RR); |
753 | | //@} |
754 | | |
755 | | /// @name RejectReason interface |
756 | | //@{ |
757 | | std::string getRemarkName() const override; |
758 | | const Value *getRemarkBB() const override; |
759 | | std::string getMessage() const override; |
760 | | const DebugLoc &getDebugLoc() const override; |
761 | | //@} |
762 | | }; |
763 | | |
764 | | //===----------------------------------------------------------------------===// |
765 | | /// Captures errors with regions containing the function entry block. |
766 | | class ReportEntry : public ReportOther { |
767 | | BasicBlock *BB; |
768 | | |
769 | | public: |
770 | | ReportEntry(BasicBlock *BB); |
771 | | |
772 | | /// @name LLVM-RTTI interface |
773 | | //@{ |
774 | | static bool classof(const RejectReason *RR); |
775 | | //@} |
776 | | |
777 | | /// @name RejectReason interface |
778 | | //@{ |
779 | | std::string getRemarkName() const override; |
780 | | const Value *getRemarkBB() const override; |
781 | | std::string getMessage() const override; |
782 | | std::string getEndUserMessage() const override; |
783 | | const DebugLoc &getDebugLoc() const override; |
784 | | //@} |
785 | | }; |
786 | | |
787 | | //===----------------------------------------------------------------------===// |
788 | | /// Report regions that seem not profitable to be optimized. |
789 | | class ReportUnprofitable : public ReportOther { |
790 | | Region *R; |
791 | | |
792 | | public: |
793 | | ReportUnprofitable(Region *R); |
794 | | |
795 | | /// @name LLVM-RTTI interface |
796 | | //@{ |
797 | | static bool classof(const RejectReason *RR); |
798 | | //@} |
799 | | |
800 | | /// @name RejectReason interface |
801 | | //@{ |
802 | | std::string getRemarkName() const override; |
803 | | const Value *getRemarkBB() const override; |
804 | | std::string getMessage() const override; |
805 | | std::string getEndUserMessage() const override; |
806 | | const DebugLoc &getDebugLoc() const override; |
807 | | //@} |
808 | | }; |
809 | | |
810 | | //===----------------------------------------------------------------------===// |
811 | | /// Captures errors with non-simple memory accesses. |
812 | | class ReportNonSimpleMemoryAccess : public ReportOther { |
813 | | // The offending call instruction. |
814 | | Instruction *Inst; |
815 | | |
816 | | public: |
817 | | ReportNonSimpleMemoryAccess(Instruction *Inst); |
818 | | |
819 | | /// @name LLVM-RTTI interface |
820 | | //@{ |
821 | | static bool classof(const RejectReason *RR); |
822 | | //@} |
823 | | |
824 | | /// @name RejectReason interface |
825 | | //@{ |
826 | | std::string getRemarkName() const override; |
827 | | const Value *getRemarkBB() const override; |
828 | | std::string getMessage() const override; |
829 | | const DebugLoc &getDebugLoc() const override; |
830 | | std::string getEndUserMessage() const override; |
831 | | //@} |
832 | | }; |
833 | | |
834 | | } // namespace polly |
835 | | |
836 | | #endif // POLLY_SCOPDETECTIONDIAGNOSTIC_H |