xref: /openbsd-src/gnu/llvm/llvm/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
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