File indexing completed on 2026-05-10 08:43:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef LLVM_ANALYSIS_ALIASANALYSIS_H
0038 #define LLVM_ANALYSIS_ALIASANALYSIS_H
0039
0040 #include "llvm/ADT/DenseMap.h"
0041 #include "llvm/ADT/SmallVector.h"
0042 #include "llvm/Analysis/MemoryLocation.h"
0043 #include "llvm/IR/Function.h"
0044 #include "llvm/IR/PassManager.h"
0045 #include "llvm/Pass.h"
0046 #include "llvm/Support/ModRef.h"
0047 #include <cstdint>
0048 #include <functional>
0049 #include <memory>
0050 #include <optional>
0051 #include <vector>
0052
0053 namespace llvm {
0054
0055 class AtomicCmpXchgInst;
0056 class BasicBlock;
0057 class CatchPadInst;
0058 class CatchReturnInst;
0059 class DominatorTree;
0060 class FenceInst;
0061 class LoopInfo;
0062 class TargetLibraryInfo;
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 class AliasResult {
0078 private:
0079 static const int OffsetBits = 23;
0080 static const int AliasBits = 8;
0081 static_assert(AliasBits + 1 + OffsetBits <= 32,
0082 "AliasResult size is intended to be 4 bytes!");
0083
0084 unsigned int Alias : AliasBits;
0085 unsigned int HasOffset : 1;
0086 signed int Offset : OffsetBits;
0087
0088 public:
0089 enum Kind : uint8_t {
0090
0091
0092
0093
0094
0095 NoAlias = 0,
0096
0097
0098 MayAlias,
0099
0100 PartialAlias,
0101
0102 MustAlias,
0103 };
0104 static_assert(MustAlias < (1 << AliasBits),
0105 "Not enough bit field size for the enum!");
0106
0107 explicit AliasResult() = delete;
0108 constexpr AliasResult(const Kind &Alias)
0109 : Alias(Alias), HasOffset(false), Offset(0) {}
0110
0111 operator Kind() const { return static_cast<Kind>(Alias); }
0112
0113 bool operator==(const AliasResult &Other) const {
0114 return Alias == Other.Alias && HasOffset == Other.HasOffset &&
0115 Offset == Other.Offset;
0116 }
0117 bool operator!=(const AliasResult &Other) const { return !(*this == Other); }
0118
0119 bool operator==(Kind K) const { return Alias == K; }
0120 bool operator!=(Kind K) const { return !(*this == K); }
0121
0122 constexpr bool hasOffset() const { return HasOffset; }
0123 constexpr int32_t getOffset() const {
0124 assert(HasOffset && "No offset!");
0125 return Offset;
0126 }
0127 void setOffset(int32_t NewOffset) {
0128 if (isInt<OffsetBits>(NewOffset)) {
0129 HasOffset = true;
0130 Offset = NewOffset;
0131 }
0132 }
0133
0134
0135 void swap(bool DoSwap = true) {
0136 if (DoSwap && hasOffset())
0137 setOffset(-getOffset());
0138 }
0139 };
0140
0141 static_assert(sizeof(AliasResult) == 4,
0142 "AliasResult size is intended to be 4 bytes!");
0143
0144
0145 raw_ostream &operator<<(raw_ostream &OS, AliasResult AR);
0146
0147
0148 struct CaptureAnalysis {
0149 virtual ~CaptureAnalysis() = 0;
0150
0151
0152
0153
0154
0155 virtual bool isNotCapturedBefore(const Value *Object, const Instruction *I,
0156 bool OrAt) = 0;
0157 };
0158
0159
0160
0161
0162 class SimpleCaptureAnalysis final : public CaptureAnalysis {
0163 SmallDenseMap<const Value *, bool, 8> IsCapturedCache;
0164
0165 public:
0166 bool isNotCapturedBefore(const Value *Object, const Instruction *I,
0167 bool OrAt) override;
0168 };
0169
0170
0171
0172
0173 class EarliestEscapeAnalysis final : public CaptureAnalysis {
0174 DominatorTree &DT;
0175 const LoopInfo *LI;
0176
0177
0178
0179
0180
0181 DenseMap<const Value *, Instruction *> EarliestEscapes;
0182
0183
0184
0185 DenseMap<Instruction *, TinyPtrVector<const Value *>> Inst2Obj;
0186
0187 public:
0188 EarliestEscapeAnalysis(DominatorTree &DT, const LoopInfo *LI = nullptr)
0189 : DT(DT), LI(LI) {}
0190
0191 bool isNotCapturedBefore(const Value *Object, const Instruction *I,
0192 bool OrAt) override;
0193
0194 void removeInstruction(Instruction *I);
0195 };
0196
0197
0198
0199
0200 struct AACacheLoc {
0201 using PtrTy = PointerIntPair<const Value *, 1, bool>;
0202 PtrTy Ptr;
0203 LocationSize Size;
0204
0205 AACacheLoc(PtrTy Ptr, LocationSize Size) : Ptr(Ptr), Size(Size) {}
0206 AACacheLoc(const Value *Ptr, LocationSize Size, bool MayBeCrossIteration)
0207 : Ptr(Ptr, MayBeCrossIteration), Size(Size) {}
0208 };
0209
0210 template <> struct DenseMapInfo<AACacheLoc> {
0211 static inline AACacheLoc getEmptyKey() {
0212 return {DenseMapInfo<AACacheLoc::PtrTy>::getEmptyKey(),
0213 DenseMapInfo<LocationSize>::getEmptyKey()};
0214 }
0215 static inline AACacheLoc getTombstoneKey() {
0216 return {DenseMapInfo<AACacheLoc::PtrTy>::getTombstoneKey(),
0217 DenseMapInfo<LocationSize>::getTombstoneKey()};
0218 }
0219 static unsigned getHashValue(const AACacheLoc &Val) {
0220 return DenseMapInfo<AACacheLoc::PtrTy>::getHashValue(Val.Ptr) ^
0221 DenseMapInfo<LocationSize>::getHashValue(Val.Size);
0222 }
0223 static bool isEqual(const AACacheLoc &LHS, const AACacheLoc &RHS) {
0224 return LHS.Ptr == RHS.Ptr && LHS.Size == RHS.Size;
0225 }
0226 };
0227
0228 class AAResults;
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238 class AAQueryInfo {
0239 public:
0240 using LocPair = std::pair<AACacheLoc, AACacheLoc>;
0241 struct CacheEntry {
0242
0243
0244 static constexpr int Definitive = -2;
0245
0246
0247 static constexpr int AssumptionBased = -1;
0248
0249 AliasResult Result;
0250
0251
0252
0253 int NumAssumptionUses;
0254
0255
0256 bool isDefinitive() const { return NumAssumptionUses == Definitive; }
0257
0258 bool isAssumption() const { return NumAssumptionUses >= 0; }
0259 };
0260
0261
0262
0263 AAResults &AAR;
0264
0265 using AliasCacheT = SmallDenseMap<LocPair, CacheEntry, 8>;
0266 AliasCacheT AliasCache;
0267
0268 CaptureAnalysis *CA;
0269
0270
0271 unsigned Depth = 0;
0272
0273
0274 int NumAssumptionUses = 0;
0275
0276
0277
0278
0279 SmallVector<AAQueryInfo::LocPair, 4> AssumptionBasedResults;
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295 bool MayBeCrossIteration = false;
0296
0297
0298
0299 bool UseDominatorTree = true;
0300
0301 AAQueryInfo(AAResults &AAR, CaptureAnalysis *CA) : AAR(AAR), CA(CA) {}
0302 };
0303
0304
0305 class SimpleAAQueryInfo : public AAQueryInfo {
0306 SimpleCaptureAnalysis CA;
0307
0308 public:
0309 SimpleAAQueryInfo(AAResults &AAR) : AAQueryInfo(AAR, &CA) {}
0310 };
0311
0312 class BatchAAResults;
0313
0314 class AAResults {
0315 public:
0316
0317
0318 AAResults(const TargetLibraryInfo &TLI);
0319 AAResults(AAResults &&Arg);
0320 ~AAResults();
0321
0322
0323 template <typename AAResultT> void addAAResult(AAResultT &AAResult) {
0324
0325
0326
0327 AAs.emplace_back(new Model<AAResultT>(AAResult, *this));
0328 }
0329
0330
0331
0332
0333
0334
0335 void addAADependencyID(AnalysisKey *ID) { AADeps.push_back(ID); }
0336
0337
0338
0339
0340
0341 bool invalidate(Function &F, const PreservedAnalyses &PA,
0342 FunctionAnalysisManager::Invalidator &Inv);
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352 AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
0353
0354
0355 AliasResult alias(const Value *V1, LocationSize V1Size, const Value *V2,
0356 LocationSize V2Size) {
0357 return alias(MemoryLocation(V1, V1Size), MemoryLocation(V2, V2Size));
0358 }
0359
0360
0361 AliasResult alias(const Value *V1, const Value *V2) {
0362 return alias(MemoryLocation::getBeforeOrAfter(V1),
0363 MemoryLocation::getBeforeOrAfter(V2));
0364 }
0365
0366
0367
0368 bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
0369 return alias(LocA, LocB) == AliasResult::NoAlias;
0370 }
0371
0372
0373 bool isNoAlias(const Value *V1, LocationSize V1Size, const Value *V2,
0374 LocationSize V2Size) {
0375 return isNoAlias(MemoryLocation(V1, V1Size), MemoryLocation(V2, V2Size));
0376 }
0377
0378
0379 bool isNoAlias(const Value *V1, const Value *V2) {
0380 return isNoAlias(MemoryLocation::getBeforeOrAfter(V1),
0381 MemoryLocation::getBeforeOrAfter(V2));
0382 }
0383
0384
0385
0386 bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
0387 return alias(LocA, LocB) == AliasResult::MustAlias;
0388 }
0389
0390
0391 bool isMustAlias(const Value *V1, const Value *V2) {
0392 return alias(V1, LocationSize::precise(1), V2, LocationSize::precise(1)) ==
0393 AliasResult::MustAlias;
0394 }
0395
0396
0397
0398 bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false) {
0399 return isNoModRef(getModRefInfoMask(Loc, OrLocal));
0400 }
0401
0402
0403
0404 bool pointsToConstantMemory(const Value *P, bool OrLocal = false) {
0405 return pointsToConstantMemory(MemoryLocation::getBeforeOrAfter(P), OrLocal);
0406 }
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420 ModRefInfo getModRefInfoMask(const MemoryLocation &Loc,
0421 bool IgnoreLocals = false);
0422
0423
0424
0425 ModRefInfo getModRefInfoMask(const Value *P, bool IgnoreLocals = false) {
0426 return getModRefInfoMask(MemoryLocation::getBeforeOrAfter(P), IgnoreLocals);
0427 }
0428
0429
0430
0431
0432
0433
0434 ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx);
0435
0436
0437 MemoryEffects getMemoryEffects(const CallBase *Call);
0438
0439
0440 MemoryEffects getMemoryEffects(const Function *F);
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453 bool doesNotAccessMemory(const CallBase *Call) {
0454 return getMemoryEffects(Call).doesNotAccessMemory();
0455 }
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468 bool doesNotAccessMemory(const Function *F) {
0469 return getMemoryEffects(F).doesNotAccessMemory();
0470 }
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481 bool onlyReadsMemory(const CallBase *Call) {
0482 return getMemoryEffects(Call).onlyReadsMemory();
0483 }
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494 bool onlyReadsMemory(const Function *F) {
0495 return getMemoryEffects(F).onlyReadsMemory();
0496 }
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508 ModRefInfo getModRefInfo(const Instruction *I,
0509 const std::optional<MemoryLocation> &OptLoc) {
0510 SimpleAAQueryInfo AAQIP(*this);
0511 return getModRefInfo(I, OptLoc, AAQIP);
0512 }
0513
0514
0515 ModRefInfo getModRefInfo(const Instruction *I, const Value *P,
0516 LocationSize Size) {
0517 return getModRefInfo(I, MemoryLocation(P, Size));
0518 }
0519
0520
0521
0522 ModRefInfo getModRefInfo(const Instruction *I, const CallBase *Call);
0523
0524
0525
0526
0527 ModRefInfo callCapturesBefore(const Instruction *I,
0528 const MemoryLocation &MemLoc,
0529 DominatorTree *DT) {
0530 SimpleAAQueryInfo AAQIP(*this);
0531 return callCapturesBefore(I, MemLoc, DT, AAQIP);
0532 }
0533
0534
0535 ModRefInfo callCapturesBefore(const Instruction *I, const Value *P,
0536 LocationSize Size, DominatorTree *DT) {
0537 return callCapturesBefore(I, MemoryLocation(P, Size), DT);
0538 }
0539
0540
0541
0542
0543
0544
0545
0546
0547 bool canBasicBlockModify(const BasicBlock &BB, const MemoryLocation &Loc);
0548
0549
0550 bool canBasicBlockModify(const BasicBlock &BB, const Value *P,
0551 LocationSize Size) {
0552 return canBasicBlockModify(BB, MemoryLocation(P, Size));
0553 }
0554
0555
0556
0557
0558
0559
0560 bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2,
0561 const MemoryLocation &Loc,
0562 const ModRefInfo Mode);
0563
0564
0565 bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2,
0566 const Value *Ptr, LocationSize Size,
0567 const ModRefInfo Mode) {
0568 return canInstructionRangeModRef(I1, I2, MemoryLocation(Ptr, Size), Mode);
0569 }
0570
0571
0572
0573 AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
0574 AAQueryInfo &AAQI, const Instruction *CtxI = nullptr);
0575
0576 ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
0577 bool IgnoreLocals = false);
0578 ModRefInfo getModRefInfo(const Instruction *I, const CallBase *Call2,
0579 AAQueryInfo &AAQIP);
0580 ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
0581 AAQueryInfo &AAQI);
0582 ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
0583 AAQueryInfo &AAQI);
0584 ModRefInfo getModRefInfo(const VAArgInst *V, const MemoryLocation &Loc,
0585 AAQueryInfo &AAQI);
0586 ModRefInfo getModRefInfo(const LoadInst *L, const MemoryLocation &Loc,
0587 AAQueryInfo &AAQI);
0588 ModRefInfo getModRefInfo(const StoreInst *S, const MemoryLocation &Loc,
0589 AAQueryInfo &AAQI);
0590 ModRefInfo getModRefInfo(const FenceInst *S, const MemoryLocation &Loc,
0591 AAQueryInfo &AAQI);
0592 ModRefInfo getModRefInfo(const AtomicCmpXchgInst *CX,
0593 const MemoryLocation &Loc, AAQueryInfo &AAQI);
0594 ModRefInfo getModRefInfo(const AtomicRMWInst *RMW, const MemoryLocation &Loc,
0595 AAQueryInfo &AAQI);
0596 ModRefInfo getModRefInfo(const CatchPadInst *I, const MemoryLocation &Loc,
0597 AAQueryInfo &AAQI);
0598 ModRefInfo getModRefInfo(const CatchReturnInst *I, const MemoryLocation &Loc,
0599 AAQueryInfo &AAQI);
0600 ModRefInfo getModRefInfo(const Instruction *I,
0601 const std::optional<MemoryLocation> &OptLoc,
0602 AAQueryInfo &AAQIP);
0603 ModRefInfo callCapturesBefore(const Instruction *I,
0604 const MemoryLocation &MemLoc, DominatorTree *DT,
0605 AAQueryInfo &AAQIP);
0606 MemoryEffects getMemoryEffects(const CallBase *Call, AAQueryInfo &AAQI);
0607
0608 private:
0609 class Concept;
0610
0611 template <typename T> class Model;
0612
0613 friend class AAResultBase;
0614
0615 const TargetLibraryInfo &TLI;
0616
0617 std::vector<std::unique_ptr<Concept>> AAs;
0618
0619 std::vector<AnalysisKey *> AADeps;
0620
0621 friend class BatchAAResults;
0622 };
0623
0624
0625
0626
0627
0628
0629
0630 class BatchAAResults {
0631 AAResults &AA;
0632 AAQueryInfo AAQI;
0633 SimpleCaptureAnalysis SimpleCA;
0634
0635 public:
0636 BatchAAResults(AAResults &AAR) : AA(AAR), AAQI(AAR, &SimpleCA) {}
0637 BatchAAResults(AAResults &AAR, CaptureAnalysis *CA)
0638 : AA(AAR), AAQI(AAR, CA) {}
0639
0640 AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
0641 return AA.alias(LocA, LocB, AAQI);
0642 }
0643 bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false) {
0644 return isNoModRef(AA.getModRefInfoMask(Loc, AAQI, OrLocal));
0645 }
0646 bool pointsToConstantMemory(const Value *P, bool OrLocal = false) {
0647 return pointsToConstantMemory(MemoryLocation::getBeforeOrAfter(P), OrLocal);
0648 }
0649 ModRefInfo getModRefInfoMask(const MemoryLocation &Loc,
0650 bool IgnoreLocals = false) {
0651 return AA.getModRefInfoMask(Loc, AAQI, IgnoreLocals);
0652 }
0653 ModRefInfo getModRefInfo(const Instruction *I,
0654 const std::optional<MemoryLocation> &OptLoc) {
0655 return AA.getModRefInfo(I, OptLoc, AAQI);
0656 }
0657 ModRefInfo getModRefInfo(const Instruction *I, const CallBase *Call2) {
0658 return AA.getModRefInfo(I, Call2, AAQI);
0659 }
0660 ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) {
0661 return AA.getArgModRefInfo(Call, ArgIdx);
0662 }
0663 MemoryEffects getMemoryEffects(const CallBase *Call) {
0664 return AA.getMemoryEffects(Call, AAQI);
0665 }
0666 bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
0667 return alias(LocA, LocB) == AliasResult::MustAlias;
0668 }
0669 bool isMustAlias(const Value *V1, const Value *V2) {
0670 return alias(MemoryLocation(V1, LocationSize::precise(1)),
0671 MemoryLocation(V2, LocationSize::precise(1))) ==
0672 AliasResult::MustAlias;
0673 }
0674 bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
0675 return alias(LocA, LocB) == AliasResult::NoAlias;
0676 }
0677 ModRefInfo callCapturesBefore(const Instruction *I,
0678 const MemoryLocation &MemLoc,
0679 DominatorTree *DT) {
0680 return AA.callCapturesBefore(I, MemLoc, DT, AAQI);
0681 }
0682
0683
0684 void enableCrossIterationMode() {
0685 AAQI.MayBeCrossIteration = true;
0686 }
0687
0688
0689 void disableDominatorTree() { AAQI.UseDominatorTree = false; }
0690 };
0691
0692
0693
0694 using AliasAnalysis = AAResults;
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705 class AAResults::Concept {
0706 public:
0707 virtual ~Concept() = 0;
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717 virtual AliasResult alias(const MemoryLocation &LocA,
0718 const MemoryLocation &LocB, AAQueryInfo &AAQI,
0719 const Instruction *CtxI) = 0;
0720
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730 virtual ModRefInfo getModRefInfoMask(const MemoryLocation &Loc,
0731 AAQueryInfo &AAQI,
0732 bool IgnoreLocals) = 0;
0733
0734
0735
0736
0737
0738
0739 virtual ModRefInfo getArgModRefInfo(const CallBase *Call,
0740 unsigned ArgIdx) = 0;
0741
0742
0743 virtual MemoryEffects getMemoryEffects(const CallBase *Call,
0744 AAQueryInfo &AAQI) = 0;
0745
0746
0747 virtual MemoryEffects getMemoryEffects(const Function *F) = 0;
0748
0749
0750
0751 virtual ModRefInfo getModRefInfo(const CallBase *Call,
0752 const MemoryLocation &Loc,
0753 AAQueryInfo &AAQI) = 0;
0754
0755
0756
0757
0758 virtual ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
0759 AAQueryInfo &AAQI) = 0;
0760
0761
0762 };
0763
0764
0765
0766
0767
0768
0769
0770 template <typename AAResultT> class AAResults::Model final : public Concept {
0771 AAResultT &Result;
0772
0773 public:
0774 explicit Model(AAResultT &Result, AAResults &AAR) : Result(Result) {}
0775 ~Model() override = default;
0776
0777 AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
0778 AAQueryInfo &AAQI, const Instruction *CtxI) override {
0779 return Result.alias(LocA, LocB, AAQI, CtxI);
0780 }
0781
0782 ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
0783 bool IgnoreLocals) override {
0784 return Result.getModRefInfoMask(Loc, AAQI, IgnoreLocals);
0785 }
0786
0787 ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) override {
0788 return Result.getArgModRefInfo(Call, ArgIdx);
0789 }
0790
0791 MemoryEffects getMemoryEffects(const CallBase *Call,
0792 AAQueryInfo &AAQI) override {
0793 return Result.getMemoryEffects(Call, AAQI);
0794 }
0795
0796 MemoryEffects getMemoryEffects(const Function *F) override {
0797 return Result.getMemoryEffects(F);
0798 }
0799
0800 ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
0801 AAQueryInfo &AAQI) override {
0802 return Result.getModRefInfo(Call, Loc, AAQI);
0803 }
0804
0805 ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
0806 AAQueryInfo &AAQI) override {
0807 return Result.getModRefInfo(Call1, Call2, AAQI);
0808 }
0809 };
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822 class AAResultBase {
0823 protected:
0824 explicit AAResultBase() = default;
0825
0826
0827
0828 AAResultBase(const AAResultBase &Arg) {}
0829 AAResultBase(AAResultBase &&Arg) {}
0830
0831 public:
0832 AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
0833 AAQueryInfo &AAQI, const Instruction *I) {
0834 return AliasResult::MayAlias;
0835 }
0836
0837 ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
0838 bool IgnoreLocals) {
0839 return ModRefInfo::ModRef;
0840 }
0841
0842 ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) {
0843 return ModRefInfo::ModRef;
0844 }
0845
0846 MemoryEffects getMemoryEffects(const CallBase *Call, AAQueryInfo &AAQI) {
0847 return MemoryEffects::unknown();
0848 }
0849
0850 MemoryEffects getMemoryEffects(const Function *F) {
0851 return MemoryEffects::unknown();
0852 }
0853
0854 ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
0855 AAQueryInfo &AAQI) {
0856 return ModRefInfo::ModRef;
0857 }
0858
0859 ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
0860 AAQueryInfo &AAQI) {
0861 return ModRefInfo::ModRef;
0862 }
0863 };
0864
0865
0866 bool isNoAliasCall(const Value *V);
0867
0868
0869
0870
0871
0872
0873
0874
0875 bool isIdentifiedObject(const Value *V);
0876
0877
0878
0879
0880
0881
0882 bool isIdentifiedFunctionLocal(const Value *V);
0883
0884
0885
0886
0887
0888
0889 bool isBaseOfObject(const Value *V);
0890
0891
0892
0893 bool isEscapeSource(const Value *V);
0894
0895
0896
0897
0898
0899
0900 bool isNotVisibleOnUnwind(const Value *Object,
0901 bool &RequiresNoCaptureBeforeUnwind);
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914 bool isWritableObject(const Value *Object, bool &ExplicitlyDereferenceableOnly);
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933 class AAManager : public AnalysisInfoMixin<AAManager> {
0934 public:
0935 using Result = AAResults;
0936
0937
0938 template <typename AnalysisT> void registerFunctionAnalysis() {
0939 ResultGetters.push_back(&getFunctionAAResultImpl<AnalysisT>);
0940 }
0941
0942
0943 template <typename AnalysisT> void registerModuleAnalysis() {
0944 ResultGetters.push_back(&getModuleAAResultImpl<AnalysisT>);
0945 }
0946
0947 Result run(Function &F, FunctionAnalysisManager &AM);
0948
0949 private:
0950 friend AnalysisInfoMixin<AAManager>;
0951
0952 static AnalysisKey Key;
0953
0954 SmallVector<void (*)(Function &F, FunctionAnalysisManager &AM,
0955 AAResults &AAResults),
0956 4> ResultGetters;
0957
0958 template <typename AnalysisT>
0959 static void getFunctionAAResultImpl(Function &F,
0960 FunctionAnalysisManager &AM,
0961 AAResults &AAResults) {
0962 AAResults.addAAResult(AM.template getResult<AnalysisT>(F));
0963 AAResults.addAADependencyID(AnalysisT::ID());
0964 }
0965
0966 template <typename AnalysisT>
0967 static void getModuleAAResultImpl(Function &F, FunctionAnalysisManager &AM,
0968 AAResults &AAResults) {
0969 auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
0970 if (auto *R =
0971 MAMProxy.template getCachedResult<AnalysisT>(*F.getParent())) {
0972 AAResults.addAAResult(*R);
0973 MAMProxy
0974 .template registerOuterAnalysisInvalidation<AnalysisT, AAManager>();
0975 }
0976 }
0977 };
0978
0979
0980
0981 class AAResultsWrapperPass : public FunctionPass {
0982 std::unique_ptr<AAResults> AAR;
0983
0984 public:
0985 static char ID;
0986
0987 AAResultsWrapperPass();
0988
0989 AAResults &getAAResults() { return *AAR; }
0990 const AAResults &getAAResults() const { return *AAR; }
0991
0992 bool runOnFunction(Function &F) override;
0993
0994 void getAnalysisUsage(AnalysisUsage &AU) const override;
0995 };
0996
0997
0998
0999 struct ExternalAAWrapperPass : ImmutablePass {
1000 using CallbackT = std::function<void(Pass &, Function &, AAResults &)>;
1001
1002 CallbackT CB;
1003
1004 static char ID;
1005
1006 ExternalAAWrapperPass();
1007
1008 explicit ExternalAAWrapperPass(CallbackT CB);
1009
1010 void getAnalysisUsage(AnalysisUsage &AU) const override {
1011 AU.setPreservesAll();
1012 }
1013 };
1014
1015
1016
1017
1018
1019
1020
1021
1022 ImmutablePass *createExternalAAWrapperPass(
1023 std::function<void(Pass &, Function &, AAResults &)> Callback);
1024
1025 }
1026
1027 #endif