109467b48Spatrick //===- ScalarEvolutionAliasAnalysis.cpp - SCEV-based Alias Analysis -------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file defines the ScalarEvolutionAliasAnalysis pass, which implements a
1009467b48Spatrick // simple alias analysis implemented in terms of ScalarEvolution queries.
1109467b48Spatrick //
1209467b48Spatrick // This differs from traditional loop dependence analysis in that it tests
1309467b48Spatrick // for dependencies within a single iteration of a loop, rather than
1409467b48Spatrick // dependencies between different iterations.
1509467b48Spatrick //
1609467b48Spatrick // ScalarEvolution has a more complete understanding of pointer arithmetic
1709467b48Spatrick // than BasicAliasAnalysis' collection of ad-hoc analyses.
1809467b48Spatrick //
1909467b48Spatrick //===----------------------------------------------------------------------===//
2009467b48Spatrick
2109467b48Spatrick #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
2273471bf0Spatrick #include "llvm/Analysis/ScalarEvolution.h"
23*d415bd75Srobert #include "llvm/Analysis/ScalarEvolutionExpressions.h"
2409467b48Spatrick #include "llvm/InitializePasses.h"
2509467b48Spatrick using namespace llvm;
2609467b48Spatrick
canComputePointerDiff(ScalarEvolution & SE,const SCEV * A,const SCEV * B)27*d415bd75Srobert static bool canComputePointerDiff(ScalarEvolution &SE,
28*d415bd75Srobert const SCEV *A, const SCEV *B) {
29*d415bd75Srobert if (SE.getEffectiveSCEVType(A->getType()) !=
30*d415bd75Srobert SE.getEffectiveSCEVType(B->getType()))
31*d415bd75Srobert return false;
32*d415bd75Srobert
33*d415bd75Srobert return SE.instructionCouldExistWitthOperands(A, B);
34*d415bd75Srobert }
35*d415bd75Srobert
alias(const MemoryLocation & LocA,const MemoryLocation & LocB,AAQueryInfo & AAQI,const Instruction *)3609467b48Spatrick AliasResult SCEVAAResult::alias(const MemoryLocation &LocA,
37*d415bd75Srobert const MemoryLocation &LocB, AAQueryInfo &AAQI,
38*d415bd75Srobert const Instruction *) {
3909467b48Spatrick // If either of the memory references is empty, it doesn't matter what the
4009467b48Spatrick // pointer values are. This allows the code below to ignore this special
4109467b48Spatrick // case.
4209467b48Spatrick if (LocA.Size.isZero() || LocB.Size.isZero())
4373471bf0Spatrick return AliasResult::NoAlias;
4409467b48Spatrick
4509467b48Spatrick // This is SCEVAAResult. Get the SCEVs!
4609467b48Spatrick const SCEV *AS = SE.getSCEV(const_cast<Value *>(LocA.Ptr));
4709467b48Spatrick const SCEV *BS = SE.getSCEV(const_cast<Value *>(LocB.Ptr));
4809467b48Spatrick
4909467b48Spatrick // If they evaluate to the same expression, it's a MustAlias.
5009467b48Spatrick if (AS == BS)
5173471bf0Spatrick return AliasResult::MustAlias;
5209467b48Spatrick
5309467b48Spatrick // If something is known about the difference between the two addresses,
5409467b48Spatrick // see if it's enough to prove a NoAlias.
55*d415bd75Srobert if (canComputePointerDiff(SE, AS, BS)) {
5609467b48Spatrick unsigned BitWidth = SE.getTypeSizeInBits(AS->getType());
5709467b48Spatrick APInt ASizeInt(BitWidth, LocA.Size.hasValue()
5809467b48Spatrick ? LocA.Size.getValue()
5909467b48Spatrick : MemoryLocation::UnknownSize);
6009467b48Spatrick APInt BSizeInt(BitWidth, LocB.Size.hasValue()
6109467b48Spatrick ? LocB.Size.getValue()
6209467b48Spatrick : MemoryLocation::UnknownSize);
6309467b48Spatrick
6409467b48Spatrick // Compute the difference between the two pointers.
6509467b48Spatrick const SCEV *BA = SE.getMinusSCEV(BS, AS);
6609467b48Spatrick
6709467b48Spatrick // Test whether the difference is known to be great enough that memory of
6809467b48Spatrick // the given sizes don't overlap. This assumes that ASizeInt and BSizeInt
6909467b48Spatrick // are non-zero, which is special-cased above.
7073471bf0Spatrick if (!isa<SCEVCouldNotCompute>(BA) &&
7173471bf0Spatrick ASizeInt.ule(SE.getUnsignedRange(BA).getUnsignedMin()) &&
7209467b48Spatrick (-BSizeInt).uge(SE.getUnsignedRange(BA).getUnsignedMax()))
7373471bf0Spatrick return AliasResult::NoAlias;
7409467b48Spatrick
7509467b48Spatrick // Folding the subtraction while preserving range information can be tricky
7609467b48Spatrick // (because of INT_MIN, etc.); if the prior test failed, swap AS and BS
7709467b48Spatrick // and try again to see if things fold better that way.
7809467b48Spatrick
7909467b48Spatrick // Compute the difference between the two pointers.
8009467b48Spatrick const SCEV *AB = SE.getMinusSCEV(AS, BS);
8109467b48Spatrick
8209467b48Spatrick // Test whether the difference is known to be great enough that memory of
8309467b48Spatrick // the given sizes don't overlap. This assumes that ASizeInt and BSizeInt
8409467b48Spatrick // are non-zero, which is special-cased above.
8573471bf0Spatrick if (!isa<SCEVCouldNotCompute>(AB) &&
8673471bf0Spatrick BSizeInt.ule(SE.getUnsignedRange(AB).getUnsignedMin()) &&
8709467b48Spatrick (-ASizeInt).uge(SE.getUnsignedRange(AB).getUnsignedMax()))
8873471bf0Spatrick return AliasResult::NoAlias;
8909467b48Spatrick }
9009467b48Spatrick
9109467b48Spatrick // If ScalarEvolution can find an underlying object, form a new query.
9209467b48Spatrick // The correctness of this depends on ScalarEvolution not recognizing
9309467b48Spatrick // inttoptr and ptrtoint operators.
9409467b48Spatrick Value *AO = GetBaseValue(AS);
9509467b48Spatrick Value *BO = GetBaseValue(BS);
9609467b48Spatrick if ((AO && AO != LocA.Ptr) || (BO && BO != LocB.Ptr))
9709467b48Spatrick if (alias(MemoryLocation(AO ? AO : LocA.Ptr,
9873471bf0Spatrick AO ? LocationSize::beforeOrAfterPointer()
9973471bf0Spatrick : LocA.Size,
10009467b48Spatrick AO ? AAMDNodes() : LocA.AATags),
10109467b48Spatrick MemoryLocation(BO ? BO : LocB.Ptr,
10273471bf0Spatrick BO ? LocationSize::beforeOrAfterPointer()
10373471bf0Spatrick : LocB.Size,
10409467b48Spatrick BO ? AAMDNodes() : LocB.AATags),
105*d415bd75Srobert AAQI, nullptr) == AliasResult::NoAlias)
10673471bf0Spatrick return AliasResult::NoAlias;
10709467b48Spatrick
10809467b48Spatrick // Forward the query to the next analysis.
109*d415bd75Srobert return AAResultBase::alias(LocA, LocB, AAQI, nullptr);
11009467b48Spatrick }
11109467b48Spatrick
11209467b48Spatrick /// Given an expression, try to find a base value.
11309467b48Spatrick ///
11409467b48Spatrick /// Returns null if none was found.
GetBaseValue(const SCEV * S)11509467b48Spatrick Value *SCEVAAResult::GetBaseValue(const SCEV *S) {
11609467b48Spatrick if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
11709467b48Spatrick // In an addrec, assume that the base will be in the start, rather
11809467b48Spatrick // than the step.
11909467b48Spatrick return GetBaseValue(AR->getStart());
12009467b48Spatrick } else if (const SCEVAddExpr *A = dyn_cast<SCEVAddExpr>(S)) {
12109467b48Spatrick // If there's a pointer operand, it'll be sorted at the end of the list.
12209467b48Spatrick const SCEV *Last = A->getOperand(A->getNumOperands() - 1);
12309467b48Spatrick if (Last->getType()->isPointerTy())
12409467b48Spatrick return GetBaseValue(Last);
12509467b48Spatrick } else if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
12609467b48Spatrick // This is a leaf node.
12709467b48Spatrick return U->getValue();
12809467b48Spatrick }
12909467b48Spatrick // No Identified object found.
13009467b48Spatrick return nullptr;
13109467b48Spatrick }
13209467b48Spatrick
invalidate(Function & Fn,const PreservedAnalyses & PA,FunctionAnalysisManager::Invalidator & Inv)13373471bf0Spatrick bool SCEVAAResult::invalidate(Function &Fn, const PreservedAnalyses &PA,
13473471bf0Spatrick FunctionAnalysisManager::Invalidator &Inv) {
13573471bf0Spatrick // We don't care if this analysis itself is preserved, it has no state. But
13673471bf0Spatrick // we need to check that the analyses it depends on have been.
13773471bf0Spatrick return Inv.invalidate<ScalarEvolutionAnalysis>(Fn, PA);
13873471bf0Spatrick }
13973471bf0Spatrick
14009467b48Spatrick AnalysisKey SCEVAA::Key;
14109467b48Spatrick
run(Function & F,FunctionAnalysisManager & AM)14209467b48Spatrick SCEVAAResult SCEVAA::run(Function &F, FunctionAnalysisManager &AM) {
14309467b48Spatrick return SCEVAAResult(AM.getResult<ScalarEvolutionAnalysis>(F));
14409467b48Spatrick }
14509467b48Spatrick
14609467b48Spatrick char SCEVAAWrapperPass::ID = 0;
14709467b48Spatrick INITIALIZE_PASS_BEGIN(SCEVAAWrapperPass, "scev-aa",
14809467b48Spatrick "ScalarEvolution-based Alias Analysis", false, true)
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)14909467b48Spatrick INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
15009467b48Spatrick INITIALIZE_PASS_END(SCEVAAWrapperPass, "scev-aa",
15109467b48Spatrick "ScalarEvolution-based Alias Analysis", false, true)
15209467b48Spatrick
15309467b48Spatrick FunctionPass *llvm::createSCEVAAWrapperPass() {
15409467b48Spatrick return new SCEVAAWrapperPass();
15509467b48Spatrick }
15609467b48Spatrick
SCEVAAWrapperPass()15709467b48Spatrick SCEVAAWrapperPass::SCEVAAWrapperPass() : FunctionPass(ID) {
15809467b48Spatrick initializeSCEVAAWrapperPassPass(*PassRegistry::getPassRegistry());
15909467b48Spatrick }
16009467b48Spatrick
runOnFunction(Function & F)16109467b48Spatrick bool SCEVAAWrapperPass::runOnFunction(Function &F) {
16209467b48Spatrick Result.reset(
16309467b48Spatrick new SCEVAAResult(getAnalysis<ScalarEvolutionWrapperPass>().getSE()));
16409467b48Spatrick return false;
16509467b48Spatrick }
16609467b48Spatrick
getAnalysisUsage(AnalysisUsage & AU) const16709467b48Spatrick void SCEVAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
16809467b48Spatrick AU.setPreservesAll();
16909467b48Spatrick AU.addRequired<ScalarEvolutionWrapperPass>();
17009467b48Spatrick }
171