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