const TargetLibraryInfo &TLI;
AssumptionCache ∾
DominatorTree *DT;
- PhiValues *PV;
public:
BasicAAResult(const DataLayout &DL, const Function &F,
const TargetLibraryInfo &TLI, AssumptionCache &AC,
- DominatorTree *DT = nullptr, PhiValues *PV = nullptr)
- : DL(DL), F(F), TLI(TLI), AC(AC), DT(DT), PV(PV) {}
+ DominatorTree *DT = nullptr)
+ : DL(DL), F(F), TLI(TLI), AC(AC), DT(DT) {}
BasicAAResult(const BasicAAResult &Arg)
: AAResultBase(Arg), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI), AC(Arg.AC),
- DT(Arg.DT), PV(Arg.PV) {}
+ DT(Arg.DT) {}
BasicAAResult(BasicAAResult &&Arg)
: AAResultBase(std::move(Arg)), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI),
- AC(Arg.AC), DT(Arg.DT), PV(Arg.PV) {}
+ AC(Arg.AC), DT(Arg.DT) {}
/// Handle invalidation events in the new pass manager.
bool invalidate(Function &Fn, const PreservedAnalyses &PA,
class BatchAAResults;
class DominatorTree;
class PHITransAddr;
-class PhiValues;
/// A memory dependence query can return one of three different answers.
class MemDepResult {
AssumptionCache ∾
const TargetLibraryInfo &TLI;
DominatorTree &DT;
- PhiValues &PV;
PredIteratorCache PredCache;
unsigned DefaultBlockScanLimit;
public:
MemoryDependenceResults(AAResults &AA, AssumptionCache &AC,
const TargetLibraryInfo &TLI, DominatorTree &DT,
- PhiValues &PV, unsigned DefaultBlockScanLimit)
- : AA(AA), AC(AC), TLI(TLI), DT(DT), PV(PV),
+ unsigned DefaultBlockScanLimit)
+ : AA(AA), AC(AC), TLI(TLI), DT(DT),
DefaultBlockScanLimit(DefaultBlockScanLimit) {}
/// Handle invalidation in the new PM.
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/MemoryLocation.h"
-#include "llvm/Analysis/PhiValues.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Argument.h"
// may be created without handles to some analyses and in that case don't
// depend on them.
if (Inv.invalidate<AssumptionAnalysis>(Fn, PA) ||
- (DT && Inv.invalidate<DominatorTreeAnalysis>(Fn, PA)) ||
- (PV && Inv.invalidate<PhiValuesAnalysis>(Fn, PA)))
+ (DT && Inv.invalidate<DominatorTreeAnalysis>(Fn, PA)))
return true;
// Otherwise this analysis result remains valid.
return false;
};
- if (PV) {
- // If we have PhiValues then use it to get the underlying phi values.
- const PhiValues::ValueSet &PhiValueSet = PV->getValuesForPhi(PN);
- // If we have more phi values than the search depth then return MayAlias
- // conservatively to avoid compile time explosion. The worst possible case
- // is if both sides are PHI nodes. In which case, this is O(m x n) time
- // where 'm' and 'n' are the number of PHI sources.
- if (PhiValueSet.size() > MaxLookupSearchDepth)
- return AliasResult::MayAlias;
- // Add the values to V1Srcs
- for (Value *PV1 : PhiValueSet) {
- if (CheckForRecPhi(PV1))
- continue;
- V1Srcs.push_back(PV1);
- }
- } else {
- // If we don't have PhiInfo then just look at the operands of the phi itself
- // FIXME: Remove this once we can guarantee that we have PhiInfo always
- SmallPtrSet<Value *, 4> UniqueSrc;
- Value *OnePhi = nullptr;
- for (Value *PV1 : PN->incoming_values()) {
- // Skip the phi itself being the incoming value.
- if (PV1 == PN)
- continue;
+ SmallPtrSet<Value *, 4> UniqueSrc;
+ Value *OnePhi = nullptr;
+ for (Value *PV1 : PN->incoming_values()) {
+ // Skip the phi itself being the incoming value.
+ if (PV1 == PN)
+ continue;
- if (isa<PHINode>(PV1)) {
- if (OnePhi && OnePhi != PV1) {
- // To control potential compile time explosion, we choose to be
- // conserviate when we have more than one Phi input. It is important
- // that we handle the single phi case as that lets us handle LCSSA
- // phi nodes and (combined with the recursive phi handling) simple
- // pointer induction variable patterns.
- return AliasResult::MayAlias;
- }
- OnePhi = PV1;
+ if (isa<PHINode>(PV1)) {
+ if (OnePhi && OnePhi != PV1) {
+ // To control potential compile time explosion, we choose to be
+ // conserviate when we have more than one Phi input. It is important
+ // that we handle the single phi case as that lets us handle LCSSA
+ // phi nodes and (combined with the recursive phi handling) simple
+ // pointer induction variable patterns.
+ return AliasResult::MayAlias;
}
-
- if (CheckForRecPhi(PV1))
- continue;
-
- if (UniqueSrc.insert(PV1).second)
- V1Srcs.push_back(PV1);
+ OnePhi = PV1;
}
- if (OnePhi && UniqueSrc.size() > 1)
- // Out of an abundance of caution, allow only the trivial lcssa and
- // recursive phi cases.
- return AliasResult::MayAlias;
+ if (CheckForRecPhi(PV1))
+ continue;
+
+ if (UniqueSrc.insert(PV1).second)
+ V1Srcs.push_back(PV1);
}
+ if (OnePhi && UniqueSrc.size() > 1)
+ // Out of an abundance of caution, allow only the trivial lcssa and
+ // recursive phi cases.
+ return AliasResult::MayAlias;
+
// If V1Srcs is empty then that means that the phi has no underlying non-phi
// value. This should only be possible in blocks unreachable from the entry
// block, but return MayAlias just in case.
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
auto &AC = AM.getResult<AssumptionAnalysis>(F);
auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
- auto *PV = AM.getCachedResult<PhiValuesAnalysis>(F);
- return BasicAAResult(F.getParent()->getDataLayout(), F, TLI, AC, DT, PV);
+ return BasicAAResult(F.getParent()->getDataLayout(), F, TLI, AC, DT);
}
BasicAAWrapperPass::BasicAAWrapperPass() : FunctionPass(ID) {
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(PhiValuesWrapperPass)
INITIALIZE_PASS_END(BasicAAWrapperPass, "basic-aa",
"Basic Alias Analysis (stateless AA impl)", true, true)
auto &ACT = getAnalysis<AssumptionCacheTracker>();
auto &TLIWP = getAnalysis<TargetLibraryInfoWrapperPass>();
auto &DTWP = getAnalysis<DominatorTreeWrapperPass>();
- auto *PVWP = getAnalysisIfAvailable<PhiValuesWrapperPass>();
Result.reset(new BasicAAResult(F.getParent()->getDataLayout(), F,
TLIWP.getTLI(F), ACT.getAssumptionCache(F),
- &DTWP.getDomTree(),
- PVWP ? &PVWP->getResult() : nullptr));
+ &DTWP.getDomTree()));
return false;
}
AU.addRequiredTransitive<AssumptionCacheTracker>();
AU.addRequiredTransitive<DominatorTreeWrapperPass>();
AU.addRequiredTransitive<TargetLibraryInfoWrapperPass>();
- AU.addUsedIfAvailable<PhiValuesWrapperPass>();
}
BasicAAResult llvm::createLegacyPMBasicAAResult(Pass &P, Function &F) {
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/PHITransAddr.h"
-#include "llvm/Analysis/PhiValues.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/BasicBlock.h"
removeCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr, false));
// Flush load info for the pointer.
removeCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr, true));
- // Invalidate phis that use the pointer.
- PV.invalidateValue(Ptr);
}
void MemoryDependenceResults::invalidateCachedPredecessors() {
}
}
- // Invalidate phis that use the removed instruction.
- PV.invalidateValue(RemInst);
-
assert(!NonLocalDepsMap.count(RemInst) && "RemInst got reinserted?");
LLVM_DEBUG(verifyRemoved(RemInst));
}
auto &AC = AM.getResult<AssumptionAnalysis>(F);
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
- auto &PV = AM.getResult<PhiValuesAnalysis>(F);
- return MemoryDependenceResults(AA, AC, TLI, DT, PV, DefaultBlockScanLimit);
+ return MemoryDependenceResults(AA, AC, TLI, DT, DefaultBlockScanLimit);
}
char MemoryDependenceWrapperPass::ID = 0;
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(PhiValuesWrapperPass)
INITIALIZE_PASS_END(MemoryDependenceWrapperPass, "memdep",
"Memory Dependence Analysis", false, true)
AU.setPreservesAll();
AU.addRequired<AssumptionCacheTracker>();
AU.addRequired<DominatorTreeWrapperPass>();
- AU.addRequired<PhiValuesWrapperPass>();
AU.addRequiredTransitive<AAResultsWrapperPass>();
AU.addRequiredTransitive<TargetLibraryInfoWrapperPass>();
}
// Check whether the analyses we depend on became invalid for any reason.
if (Inv.invalidate<AAManager>(F, PA) ||
Inv.invalidate<AssumptionAnalysis>(F, PA) ||
- Inv.invalidate<DominatorTreeAnalysis>(F, PA) ||
- Inv.invalidate<PhiValuesAnalysis>(F, PA))
+ Inv.invalidate<DominatorTreeAnalysis>(F, PA))
return true;
// Otherwise this analysis result remains valid.
auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- auto &PV = getAnalysis<PhiValuesWrapperPass>().getResult();
- MemDep.emplace(AA, AC, TLI, DT, PV, BlockScanLimit);
+ MemDep.emplace(AA, AC, TLI, DT, BlockScanLimit);
return false;
}
; CHECK-DT-INVALIDATE: Running pass: AAEvaluator
; CHECK-DT-INVALIDATE: Running analysis: BasicAA
;
-; Check PhiValues specifically.
-; RUN: opt -disable-output -disable-verify -debug-pass-manager %s 2>&1 \
-; RUN: -passes='require<phi-values>,require<aa>,invalidate<phi-values>,aa-eval' -aa-pipeline='basic-aa' \
-; RUN: | FileCheck %s --check-prefix=CHECK-PV-INVALIDATE
-; CHECK-PV-INVALIDATE: Running pass: RequireAnalysisPass
-; CHECK-PV-INVALIDATE: Running analysis: BasicAA
-; CHECK-PV-INVALIDATE: Running pass: InvalidateAnalysisPass
-; CHECK-PV-INVALIDATE: Invalidating analysis: PhiValuesAnalysis
-; CHECK-PV-INVALIDATE: Invalidating analysis: BasicAA
-; CHECK-PV-INVALIDATE: Running pass: AAEvaluator
-; CHECK-PV-INVALIDATE: Running analysis: BasicAA
-
; Some code that will result in actual AA queries, including inside of a loop.
; FIXME: Sadly, none of these queries managed to use either the domtree or
; loopinfo that basic-aa cache. But nor does any other test in LLVM. It would
-; RUN: opt < %s -aa-pipeline=basic-aa -passes='require<phi-values>,aa-eval' -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; When we have a chain of phis in nested loops we should recognise if there's
; actually only one underlying value.
+; FIXME: All of these could be NoAlias.
; CHECK-LABEL: loop_phi_chain
-; CHECK: NoAlias: i32* %val1, i32* @Y
-; CHECK: NoAlias: i32* %val2, i32* @Y
-; CHECK: NoAlias: i32* %val3, i32* @Y
+; CHECK: MayAlias: i32* %val1, i32* @Y
+; CHECK: MayAlias: i32* %val2, i32* @Y
+; CHECK: MayAlias: i32* %val3, i32* @Y
define void @loop_phi_chain(i32 %a, i32 %b, i32 %c) {
entry:
br label %loop1
-; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s --check-prefixes=CHECK,NO-PHI-VALUES
-; RUN: opt < %s -aa-pipeline=basic-aa -passes='require<phi-values>,aa-eval' -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s --check-prefixes=CHECK,PHI-VALUES
+; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
; CHECK-LABEL: Function: simple: 5 pointers, 0 call sites
; CHECK: NoAlias: float* %src1, float* %src2
ret ptr %result
}
+; FIXME: %a and %p.inner do not alias.
; CHECK-LABEL: Function: nested_loop
; CHECK: NoAlias: i8* %a, i8* %p.base
; CHECK: NoAlias: i8* %a, i8* %p.outer
-; NO-PHI-VALUES: MayAlias: i8* %a, i8* %p.inner
-; PHI-VALUES: NoAlias: i8* %a, i8* %p.inner
+; CHECK: MayAlias: i8* %a, i8* %p.inner
; CHECK: NoAlias: i8* %a, i8* %p.inner.next
; CHECK: NoAlias: i8* %a, i8* %p.outer.next
define void @nested_loop(i1 %c, i1 %c2, ptr noalias %p.base) {
; CHECK: NoAlias: i8* %a, i8* %p.base
; CHECK: NoAlias: i8* %a, i8* %p.outer
; CHECK: NoAlias: i8* %a, i8* %p.outer.next
-; NO-PHI-VALUES: NoAlias: i8* %a, i8* %p.inner
-; PHI-VALUES: MayAlias: i8* %a, i8* %p.inner
+; CHECK: NoAlias: i8* %a, i8* %p.inner
; CHECK: NoAlias: i8* %a, i8* %p.inner.next
define void @nested_loop3(i1 %c, i1 %c2, ptr noalias %p.base) {
entry:
; CHECK: NoAlias: i8* %a, i8* %p.base
; CHECK: NoAlias: i8* %a, i8* %p1
; CHECK: NoAlias: i8* %a, i8* %p1.next
-; NO-PHI-VALUES: NoAlias: i8* %a, i8* %p2
-; PHI-VALUES: MayAlias: i8* %a, i8* %p2
+; CHECK: NoAlias: i8* %a, i8* %p2
; CHECK: NoAlias: i8* %a, i8* %p2.next
define void @sibling_loop2(i1 %c, i1 %c2, ptr noalias %p.base) {
entry:
; GCN-O3-NEXT: Split GEPs to a variadic base and a constant offset for better CSE
; GCN-O3-NEXT: Scalar Evolution Analysis
; GCN-O3-NEXT: Straight line strength reduction
-; GCN-O3-NEXT: Phi Values Analysis
; GCN-O3-NEXT: Function Alias Analysis Results
; GCN-O3-NEXT: Memory Dependence Analysis
; GCN-O3-NEXT: Optimization Remark Emitter
; GCN-O3-NEXT: Expand reduction intrinsics
; GCN-O3-NEXT: Natural Loop Information
; GCN-O3-NEXT: TLS Variable Hoist
-; GCN-O3-NEXT: Phi Values Analysis
; GCN-O3-NEXT: Basic Alias Analysis (stateless AA impl)
; GCN-O3-NEXT: Function Alias Analysis Results
; GCN-O3-NEXT: Memory Dependence Analysis
; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
; CHECK-O23SZ-NEXT: Running pass: GVNPass
; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
-; CHECK-O23SZ-NEXT: Running analysis: PhiValuesAnalysis
; CHECK-O1-NEXT: Running pass: MemCpyOptPass
; CHECK-O-NEXT: Running pass: SCCPPass
; CHECK-O-NEXT: Running pass: BDCEPass
; CHECK-O23SZ-NEXT: Running pass: LICMPass on loop
; CHECK-O23SZ-NEXT: Running pass: GVNPass on foo
; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis on foo
-; CHECK-O23SZ-NEXT: Running analysis: PhiValuesAnalysis on foo
; CHECK-O23SZ-NEXT: Running pass: MemCpyOptPass on foo
; CHECK-O23SZ-NEXT: Running pass: DSEPass on foo
; CHECK-O23SZ-NEXT: Running analysis: PostDominatorTreeAnalysis on foo
; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
; CHECK-O23SZ-NEXT: Running pass: GVNPass
; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
-; CHECK-O23SZ-NEXT: Running analysis: PhiValuesAnalysis
; CHECK-O1-NEXT: Running pass: MemCpyOptPass
; CHECK-O-NEXT: Running pass: SCCPPass
; CHECK-O-NEXT: Running pass: BDCEPass
; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
; CHECK-O23SZ-NEXT: Running pass: GVNPass
; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
-; CHECK-O23SZ-NEXT: Running analysis: PhiValuesAnalysis
; CHECK-O1-NEXT: Running pass: MemCpyOptPass
; CHECK-O-NEXT: Running pass: SCCPPass
; CHECK-O-NEXT: Running pass: BDCEPass
; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
; CHECK-O23SZ-NEXT: Running pass: GVNPass
; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
-; CHECK-O23SZ-NEXT: Running analysis: PhiValuesAnalysis
; CHECK-O1-NEXT: Running pass: MemCpyOptPass
; CHECK-O-NEXT: Running pass: SCCPPass
; CHECK-O-NEXT: Running pass: BDCEPass
; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
; CHECK-O23SZ-NEXT: Running pass: GVNPass
; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
-; CHECK-O23SZ-NEXT: Running analysis: PhiValuesAnalysis
; CHECK-O1-NEXT: Running pass: MemCpyOptPass
; CHECK-O-NEXT: Running pass: SCCPPass
; CHECK-O-NEXT: Running pass: BDCEPass
; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
; CHECK-O23SZ-NEXT: Running pass: GVNPass
; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
-; CHECK-O23SZ-NEXT: Running analysis: PhiValuesAnalysis
; CHECK-O1-NEXT: Running pass: MemCpyOptPass
; CHECK-O-NEXT: Running pass: SCCPPass
; CHECK-O-NEXT: Running pass: BDCEPass