File indexing completed on 2026-05-10 08:48:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #ifndef POLLY_SCOPDETECTIONDIAGNOSTIC_H
0021 #define POLLY_SCOPDETECTIONDIAGNOSTIC_H
0022
0023 #include "llvm/Analysis/LoopInfo.h"
0024 #include "llvm/IR/DebugLoc.h"
0025 #include "llvm/IR/Instruction.h"
0026 #include <cstddef>
0027
0028 namespace llvm {
0029 class AliasSet;
0030 class BasicBlock;
0031 class OptimizationRemarkEmitter;
0032 class Region;
0033 class SCEV;
0034 }
0035
0036 namespace polly {
0037 using llvm::AliasSet;
0038 using llvm::BasicBlock;
0039 using llvm::DebugLoc;
0040 using llvm::Instruction;
0041 using llvm::Loop;
0042 using llvm::OptimizationRemarkEmitter;
0043 using llvm::raw_ostream;
0044 using llvm::Region;
0045 using llvm::SCEV;
0046 using llvm::SmallVector;
0047 using llvm::Value;
0048
0049
0050 using BBPair = std::pair<BasicBlock *, BasicBlock *>;
0051
0052
0053 BBPair getBBPairForRegion(const Region *R);
0054
0055
0056 void getDebugLocations(const BBPair &P, DebugLoc &Begin, DebugLoc &End);
0057
0058 class RejectLog;
0059
0060
0061
0062
0063
0064
0065
0066 void emitRejectionRemarks(const BBPair &P, const RejectLog &Log,
0067 OptimizationRemarkEmitter &ORE);
0068
0069
0070 enum class RejectReasonKind {
0071
0072 CFG,
0073 InvalidTerminator,
0074 IrreducibleRegion,
0075 UnreachableInExit,
0076 IndirectPredecessor,
0077 LastCFG,
0078
0079
0080 AffFunc,
0081 UndefCond,
0082 InvalidCond,
0083 UndefOperand,
0084 NonAffBranch,
0085 NoBasePtr,
0086 UndefBasePtr,
0087 VariantBasePtr,
0088 NonAffineAccess,
0089 DifferentElementSize,
0090 LastAffFunc,
0091
0092 LoopBound,
0093 LoopHasNoExit,
0094 LoopHasMultipleExits,
0095 LoopOnlySomeLatches,
0096
0097 FuncCall,
0098 NonSimpleMemoryAccess,
0099
0100 Alias,
0101
0102
0103 Other,
0104 IntToPtr,
0105 Alloca,
0106 UnknownInst,
0107 Entry,
0108 Unprofitable,
0109 LastOther
0110 };
0111
0112
0113
0114
0115
0116
0117
0118 class RejectReason {
0119 private:
0120 const RejectReasonKind Kind;
0121
0122 protected:
0123 static const DebugLoc Unknown;
0124
0125 public:
0126 RejectReason(RejectReasonKind K);
0127
0128 virtual ~RejectReason() = default;
0129
0130 RejectReasonKind getKind() const { return Kind; }
0131
0132
0133
0134
0135 virtual std::string getRemarkName() const = 0;
0136
0137
0138
0139
0140 virtual const Value *getRemarkBB() const = 0;
0141
0142
0143
0144
0145 virtual std::string getMessage() const = 0;
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155 virtual std::string getEndUserMessage() const { return "Unspecified error."; }
0156
0157
0158
0159
0160 virtual const DebugLoc &getDebugLoc() const;
0161 };
0162
0163 using RejectReasonPtr = std::shared_ptr<RejectReason>;
0164
0165
0166 class RejectLog final {
0167 Region *R;
0168 SmallVector<RejectReasonPtr, 1> ErrorReports;
0169
0170 public:
0171 explicit RejectLog(Region *R) : R(R) {}
0172
0173 using iterator = SmallVector<RejectReasonPtr, 1>::const_iterator;
0174
0175 iterator begin() const { return ErrorReports.begin(); }
0176 iterator end() const { return ErrorReports.end(); }
0177 size_t size() const { return ErrorReports.size(); }
0178
0179
0180
0181
0182 bool hasErrors() const { return size() > 0; }
0183
0184 void print(raw_ostream &OS, int level = 0) const;
0185
0186 const Region *region() const { return R; }
0187 void report(RejectReasonPtr Reject) { ErrorReports.push_back(Reject); }
0188 };
0189
0190
0191
0192
0193
0194
0195 class ReportCFG : public RejectReason {
0196 public:
0197 ReportCFG(const RejectReasonKind K);
0198
0199
0200
0201 static bool classof(const RejectReason *RR);
0202
0203 };
0204
0205
0206
0207 class ReportInvalidTerminator final : public ReportCFG {
0208 BasicBlock *BB;
0209
0210 public:
0211 ReportInvalidTerminator(BasicBlock *BB)
0212 : ReportCFG(RejectReasonKind::InvalidTerminator), BB(BB) {}
0213
0214
0215
0216 static bool classof(const RejectReason *RR);
0217
0218
0219
0220
0221 std::string getRemarkName() const override;
0222 const Value *getRemarkBB() const override;
0223 std::string getMessage() const override;
0224 const DebugLoc &getDebugLoc() const override;
0225
0226 };
0227
0228
0229
0230 class ReportIrreducibleRegion final : public ReportCFG {
0231 Region *R;
0232 DebugLoc DbgLoc;
0233
0234 public:
0235 ReportIrreducibleRegion(Region *R, DebugLoc DbgLoc)
0236 : ReportCFG(RejectReasonKind::IrreducibleRegion), R(R), DbgLoc(DbgLoc) {}
0237
0238
0239
0240 static bool classof(const RejectReason *RR);
0241
0242
0243
0244
0245 std::string getRemarkName() const override;
0246 const Value *getRemarkBB() const override;
0247 std::string getMessage() const override;
0248 std::string getEndUserMessage() const override;
0249 const DebugLoc &getDebugLoc() const override;
0250
0251 };
0252
0253
0254
0255 class ReportUnreachableInExit final : public ReportCFG {
0256 BasicBlock *BB;
0257 DebugLoc DbgLoc;
0258
0259 public:
0260 ReportUnreachableInExit(BasicBlock *BB, DebugLoc DbgLoc)
0261 : ReportCFG(RejectReasonKind::UnreachableInExit), BB(BB), DbgLoc(DbgLoc) {
0262 }
0263
0264
0265
0266 static bool classof(const RejectReason *RR);
0267
0268
0269
0270
0271 std::string getRemarkName() const override;
0272 const Value *getRemarkBB() const override;
0273 std::string getMessage() const override;
0274 std::string getEndUserMessage() const override;
0275 const DebugLoc &getDebugLoc() const override;
0276
0277 };
0278
0279
0280
0281 class ReportIndirectPredecessor final : public ReportCFG {
0282 Instruction *Inst;
0283 DebugLoc DbgLoc;
0284
0285 public:
0286 ReportIndirectPredecessor(Instruction *Inst, DebugLoc DbgLoc)
0287 : ReportCFG(RejectReasonKind::IndirectPredecessor), Inst(Inst),
0288 DbgLoc(DbgLoc) {}
0289
0290
0291
0292 static bool classof(const RejectReason *RR);
0293
0294
0295
0296
0297 std::string getRemarkName() const override;
0298 const Value *getRemarkBB() const override;
0299 std::string getMessage() const override;
0300 std::string getEndUserMessage() const override;
0301 const DebugLoc &getDebugLoc() const override;
0302
0303 };
0304
0305
0306
0307
0308
0309
0310 class ReportAffFunc : public RejectReason {
0311 protected:
0312
0313 const Instruction *Inst;
0314
0315 public:
0316 ReportAffFunc(const RejectReasonKind K, const Instruction *Inst);
0317
0318
0319
0320 static bool classof(const RejectReason *RR);
0321
0322
0323
0324
0325 const DebugLoc &getDebugLoc() const override { return Inst->getDebugLoc(); }
0326
0327 };
0328
0329
0330
0331 class ReportUndefCond final : public ReportAffFunc {
0332
0333 BasicBlock *BB;
0334
0335 public:
0336 ReportUndefCond(const Instruction *Inst, BasicBlock *BB)
0337 : ReportAffFunc(RejectReasonKind::UndefCond, Inst), BB(BB) {}
0338
0339
0340
0341 static bool classof(const RejectReason *RR);
0342
0343
0344
0345
0346 std::string getRemarkName() const override;
0347 const Value *getRemarkBB() const override;
0348 std::string getMessage() const override;
0349
0350 };
0351
0352
0353
0354
0355
0356 class ReportInvalidCond final : public ReportAffFunc {
0357
0358 BasicBlock *BB;
0359
0360 public:
0361 ReportInvalidCond(const Instruction *Inst, BasicBlock *BB)
0362 : ReportAffFunc(RejectReasonKind::InvalidCond, Inst), BB(BB) {}
0363
0364
0365
0366 static bool classof(const RejectReason *RR);
0367
0368
0369
0370
0371 std::string getRemarkName() const override;
0372 const Value *getRemarkBB() const override;
0373 std::string getMessage() const override;
0374
0375 };
0376
0377
0378
0379 class ReportUndefOperand final : public ReportAffFunc {
0380
0381 BasicBlock *BB;
0382
0383 public:
0384 ReportUndefOperand(BasicBlock *BB, const Instruction *Inst)
0385 : ReportAffFunc(RejectReasonKind::UndefOperand, Inst), BB(BB) {}
0386
0387
0388
0389 static bool classof(const RejectReason *RR);
0390
0391
0392
0393
0394 std::string getRemarkName() const override;
0395 const Value *getRemarkBB() const override;
0396 std::string getMessage() const override;
0397
0398 };
0399
0400
0401
0402 class ReportNonAffBranch final : public ReportAffFunc {
0403
0404 BasicBlock *BB;
0405
0406
0407
0408 const SCEV *LHS;
0409 const SCEV *RHS;
0410
0411
0412 public:
0413 ReportNonAffBranch(BasicBlock *BB, const SCEV *LHS, const SCEV *RHS,
0414 const Instruction *Inst)
0415 : ReportAffFunc(RejectReasonKind::NonAffBranch, Inst), BB(BB), LHS(LHS),
0416 RHS(RHS) {}
0417
0418 const SCEV *lhs() { return LHS; }
0419 const SCEV *rhs() { return RHS; }
0420
0421
0422
0423 static bool classof(const RejectReason *RR);
0424
0425
0426
0427
0428 std::string getRemarkName() const override;
0429 const Value *getRemarkBB() const override;
0430 std::string getMessage() const override;
0431
0432 };
0433
0434
0435
0436 class ReportNoBasePtr final : public ReportAffFunc {
0437 public:
0438 ReportNoBasePtr(const Instruction *Inst)
0439 : ReportAffFunc(RejectReasonKind::NoBasePtr, Inst) {}
0440
0441
0442
0443 static bool classof(const RejectReason *RR);
0444
0445
0446
0447
0448 std::string getRemarkName() const override;
0449 const Value *getRemarkBB() const override;
0450 std::string getMessage() const override;
0451
0452 };
0453
0454
0455
0456 class ReportUndefBasePtr final : public ReportAffFunc {
0457 public:
0458 ReportUndefBasePtr(const Instruction *Inst)
0459 : ReportAffFunc(RejectReasonKind::UndefBasePtr, Inst) {}
0460
0461
0462
0463 static bool classof(const RejectReason *RR);
0464
0465
0466
0467
0468 std::string getRemarkName() const override;
0469 const Value *getRemarkBB() const override;
0470 std::string getMessage() const override;
0471
0472 };
0473
0474
0475
0476 class ReportVariantBasePtr final : public ReportAffFunc {
0477
0478 Value *BaseValue;
0479
0480 public:
0481 ReportVariantBasePtr(Value *BaseValue, const Instruction *Inst)
0482 : ReportAffFunc(RejectReasonKind::VariantBasePtr, Inst),
0483 BaseValue(BaseValue) {}
0484
0485
0486
0487 static bool classof(const RejectReason *RR);
0488
0489
0490
0491
0492 std::string getRemarkName() const override;
0493 const Value *getRemarkBB() const override;
0494 std::string getMessage() const override;
0495 std::string getEndUserMessage() const override;
0496
0497 };
0498
0499
0500
0501 class ReportNonAffineAccess final : public ReportAffFunc {
0502
0503 const SCEV *AccessFunction;
0504
0505
0506 const Value *BaseValue;
0507
0508 public:
0509 ReportNonAffineAccess(const SCEV *AccessFunction, const Instruction *Inst,
0510 const Value *V)
0511 : ReportAffFunc(RejectReasonKind::NonAffineAccess, Inst),
0512 AccessFunction(AccessFunction), BaseValue(V) {}
0513
0514 const SCEV *get() { return AccessFunction; }
0515
0516
0517
0518 static bool classof(const RejectReason *RR);
0519
0520
0521
0522
0523 std::string getRemarkName() const override;
0524 const Value *getRemarkBB() const override;
0525 std::string getMessage() const override;
0526 std::string getEndUserMessage() const override;
0527
0528 };
0529
0530
0531
0532 class ReportDifferentArrayElementSize final : public ReportAffFunc {
0533
0534 const Value *BaseValue;
0535
0536 public:
0537 ReportDifferentArrayElementSize(const Instruction *Inst, const Value *V)
0538 : ReportAffFunc(RejectReasonKind::DifferentElementSize, Inst),
0539 BaseValue(V) {}
0540
0541
0542
0543 static bool classof(const RejectReason *RR);
0544
0545
0546
0547
0548 std::string getRemarkName() const override;
0549 const Value *getRemarkBB() const override;
0550 std::string getMessage() const override;
0551 std::string getEndUserMessage() const override;
0552
0553 };
0554
0555
0556
0557 class ReportLoopBound final : public RejectReason {
0558
0559 Loop *L;
0560
0561
0562 const SCEV *LoopCount;
0563
0564
0565 const DebugLoc Loc;
0566
0567 public:
0568 ReportLoopBound(Loop *L, const SCEV *LoopCount);
0569
0570 const SCEV *loopCount() { return LoopCount; }
0571
0572
0573
0574 static bool classof(const RejectReason *RR);
0575
0576
0577
0578
0579 std::string getRemarkName() const override;
0580 const Value *getRemarkBB() const override;
0581 std::string getMessage() const override;
0582 const DebugLoc &getDebugLoc() const override;
0583 std::string getEndUserMessage() const override;
0584
0585 };
0586
0587
0588
0589 class ReportLoopHasNoExit final : public RejectReason {
0590
0591 Loop *L;
0592
0593 const DebugLoc Loc;
0594
0595 public:
0596 ReportLoopHasNoExit(Loop *L)
0597 : RejectReason(RejectReasonKind::LoopHasNoExit), L(L),
0598 Loc(L->getStartLoc()) {}
0599
0600
0601
0602 static bool classof(const RejectReason *RR);
0603
0604
0605
0606
0607 std::string getRemarkName() const override;
0608 const Value *getRemarkBB() const override;
0609 std::string getMessage() const override;
0610 const DebugLoc &getDebugLoc() const override;
0611 std::string getEndUserMessage() const override;
0612
0613 };
0614
0615
0616
0617 class ReportLoopHasMultipleExits final : public RejectReason {
0618
0619 Loop *L;
0620
0621 const DebugLoc Loc;
0622
0623 public:
0624 ReportLoopHasMultipleExits(Loop *L)
0625 : RejectReason(RejectReasonKind::LoopHasMultipleExits), L(L),
0626 Loc(L->getStartLoc()) {}
0627
0628
0629
0630 static bool classof(const RejectReason *RR);
0631
0632
0633
0634
0635 std::string getRemarkName() const override;
0636 const Value *getRemarkBB() const override;
0637 std::string getMessage() const override;
0638 const DebugLoc &getDebugLoc() const override;
0639 std::string getEndUserMessage() const override;
0640
0641 };
0642
0643
0644
0645 class ReportLoopOnlySomeLatches final : public RejectReason {
0646
0647 Loop *L;
0648
0649 const DebugLoc Loc;
0650
0651 public:
0652 ReportLoopOnlySomeLatches(Loop *L)
0653 : RejectReason(RejectReasonKind::LoopOnlySomeLatches), L(L),
0654 Loc(L->getStartLoc()) {}
0655
0656
0657
0658 static bool classof(const RejectReason *RR);
0659
0660
0661
0662
0663 std::string getRemarkName() const override;
0664 const Value *getRemarkBB() const override;
0665 std::string getMessage() const override;
0666 const DebugLoc &getDebugLoc() const override;
0667 std::string getEndUserMessage() const override;
0668
0669 };
0670
0671
0672
0673 class ReportFuncCall final : public RejectReason {
0674
0675 Instruction *Inst;
0676
0677 public:
0678 ReportFuncCall(Instruction *Inst);
0679
0680
0681
0682 static bool classof(const RejectReason *RR);
0683
0684
0685
0686
0687 std::string getRemarkName() const override;
0688 const Value *getRemarkBB() const override;
0689 std::string getMessage() const override;
0690 const DebugLoc &getDebugLoc() const override;
0691 std::string getEndUserMessage() const override;
0692
0693 };
0694
0695
0696
0697 class ReportAlias final : public RejectReason {
0698 public:
0699 using PointerSnapshotTy = std::vector<const Value *>;
0700
0701 private:
0702
0703
0704
0705
0706 std::string formatInvalidAlias(std::string Prefix = "",
0707 std::string Suffix = "") const;
0708
0709 Instruction *Inst;
0710
0711
0712 mutable PointerSnapshotTy Pointers;
0713
0714 public:
0715 ReportAlias(Instruction *Inst, AliasSet &AS);
0716
0717 const PointerSnapshotTy &getPointers() const { return Pointers; }
0718
0719
0720
0721 static bool classof(const RejectReason *RR);
0722
0723
0724
0725
0726 std::string getRemarkName() const override;
0727 const Value *getRemarkBB() const override;
0728 std::string getMessage() const override;
0729 const DebugLoc &getDebugLoc() const override;
0730 std::string getEndUserMessage() const override;
0731
0732 };
0733
0734
0735
0736 class ReportOther : public RejectReason {
0737 public:
0738 ReportOther(const RejectReasonKind K);
0739
0740
0741
0742 static bool classof(const RejectReason *RR);
0743
0744
0745
0746
0747 std::string getRemarkName() const override;
0748 std::string getMessage() const override;
0749
0750 };
0751
0752
0753
0754 class ReportIntToPtr final : public ReportOther {
0755
0756 Instruction *BaseValue;
0757
0758 public:
0759 ReportIntToPtr(Instruction *BaseValue);
0760
0761
0762
0763 static bool classof(const RejectReason *RR);
0764
0765
0766
0767
0768 std::string getRemarkName() const override;
0769 const Value *getRemarkBB() const override;
0770 std::string getMessage() const override;
0771 const DebugLoc &getDebugLoc() const override;
0772
0773 };
0774
0775
0776
0777 class ReportAlloca final : public ReportOther {
0778 Instruction *Inst;
0779
0780 public:
0781 ReportAlloca(Instruction *Inst);
0782
0783
0784
0785 static bool classof(const RejectReason *RR);
0786
0787
0788
0789
0790 std::string getRemarkName() const override;
0791 const Value *getRemarkBB() const override;
0792 std::string getMessage() const override;
0793 const DebugLoc &getDebugLoc() const override;
0794
0795 };
0796
0797
0798
0799 class ReportUnknownInst final : public ReportOther {
0800 Instruction *Inst;
0801
0802 public:
0803 ReportUnknownInst(Instruction *Inst);
0804
0805
0806
0807 static bool classof(const RejectReason *RR);
0808
0809
0810
0811
0812 std::string getRemarkName() const override;
0813 const Value *getRemarkBB() const override;
0814 std::string getMessage() const override;
0815 const DebugLoc &getDebugLoc() const override;
0816
0817 };
0818
0819
0820
0821 class ReportEntry final : public ReportOther {
0822 BasicBlock *BB;
0823
0824 public:
0825 ReportEntry(BasicBlock *BB);
0826
0827
0828
0829 static bool classof(const RejectReason *RR);
0830
0831
0832
0833
0834 std::string getRemarkName() const override;
0835 const Value *getRemarkBB() const override;
0836 std::string getMessage() const override;
0837 std::string getEndUserMessage() const override;
0838 const DebugLoc &getDebugLoc() const override;
0839
0840 };
0841
0842
0843
0844 class ReportUnprofitable final : public ReportOther {
0845 Region *R;
0846
0847 public:
0848 ReportUnprofitable(Region *R);
0849
0850
0851
0852 static bool classof(const RejectReason *RR);
0853
0854
0855
0856
0857 std::string getRemarkName() const override;
0858 const Value *getRemarkBB() const override;
0859 std::string getMessage() const override;
0860 std::string getEndUserMessage() const override;
0861 const DebugLoc &getDebugLoc() const override;
0862
0863 };
0864
0865
0866
0867 class ReportNonSimpleMemoryAccess final : public ReportOther {
0868
0869 Instruction *Inst;
0870
0871 public:
0872 ReportNonSimpleMemoryAccess(Instruction *Inst);
0873
0874
0875
0876 static bool classof(const RejectReason *RR);
0877
0878
0879
0880
0881 std::string getRemarkName() const override;
0882 const Value *getRemarkBB() const override;
0883 std::string getMessage() const override;
0884 const DebugLoc &getDebugLoc() const override;
0885 std::string getEndUserMessage() const override;
0886
0887 };
0888 }
0889
0890 #endif