Home | History | Annotate | Download | only in Analysis
      1 //=- CFLSteensAliasAnalysis.h - Unification-based Alias Analysis ---*- C++-*-=//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 /// \file
     10 /// This is the interface for LLVM's unification-based alias analysis
     11 /// implemented with CFL graph reachability.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_ANALYSIS_CFLSTEENSALIASANALYSIS_H
     16 #define LLVM_ANALYSIS_CFLSTEENSALIASANALYSIS_H
     17 
     18 #include "llvm/ADT/DenseMap.h"
     19 #include "llvm/ADT/None.h"
     20 #include "llvm/ADT/Optional.h"
     21 #include "llvm/Analysis/AliasAnalysis.h"
     22 #include "llvm/IR/Function.h"
     23 #include "llvm/IR/Module.h"
     24 #include "llvm/IR/ValueHandle.h"
     25 #include "llvm/Pass.h"
     26 #include <forward_list>
     27 
     28 namespace llvm {
     29 
     30 class TargetLibraryInfo;
     31 
     32 namespace cflaa {
     33 struct AliasSummary;
     34 }
     35 
     36 class CFLSteensAAResult : public AAResultBase<CFLSteensAAResult> {
     37   friend AAResultBase<CFLSteensAAResult>;
     38   class FunctionInfo;
     39 
     40 public:
     41   explicit CFLSteensAAResult(const TargetLibraryInfo &);
     42   CFLSteensAAResult(CFLSteensAAResult &&Arg);
     43   ~CFLSteensAAResult();
     44 
     45   /// Handle invalidation events from the new pass manager.
     46   ///
     47   /// By definition, this result is stateless and so remains valid.
     48   bool invalidate(Function &, const PreservedAnalyses &,
     49                   FunctionAnalysisManager::Invalidator &) {
     50     return false;
     51   }
     52 
     53   /// \brief Inserts the given Function into the cache.
     54   void scan(Function *Fn);
     55 
     56   void evict(Function *Fn);
     57 
     58   /// \brief Ensures that the given function is available in the cache.
     59   /// Returns the appropriate entry from the cache.
     60   const Optional<FunctionInfo> &ensureCached(Function *Fn);
     61 
     62   /// \brief Get the alias summary for the given function
     63   /// Return nullptr if the summary is not found or not available
     64   const cflaa::AliasSummary *getAliasSummary(Function &Fn);
     65 
     66   AliasResult query(const MemoryLocation &LocA, const MemoryLocation &LocB);
     67 
     68   AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
     69     if (LocA.Ptr == LocB.Ptr)
     70       return LocA.Size == LocB.Size ? MustAlias : PartialAlias;
     71 
     72     // Comparisons between global variables and other constants should be
     73     // handled by BasicAA.
     74     // CFLSteensAA may report NoAlias when comparing a GlobalValue and
     75     // ConstantExpr, but every query needs to have at least one Value tied to a
     76     // Function, and neither GlobalValues nor ConstantExprs are.
     77     if (isa<Constant>(LocA.Ptr) && isa<Constant>(LocB.Ptr))
     78       return AAResultBase::alias(LocA, LocB);
     79 
     80     AliasResult QueryResult = query(LocA, LocB);
     81     if (QueryResult == MayAlias)
     82       return AAResultBase::alias(LocA, LocB);
     83 
     84     return QueryResult;
     85   }
     86 
     87 private:
     88   struct FunctionHandle final : public CallbackVH {
     89     FunctionHandle(Function *Fn, CFLSteensAAResult *Result)
     90         : CallbackVH(Fn), Result(Result) {
     91       assert(Fn != nullptr);
     92       assert(Result != nullptr);
     93     }
     94 
     95     void deleted() override { removeSelfFromCache(); }
     96     void allUsesReplacedWith(Value *) override { removeSelfFromCache(); }
     97 
     98   private:
     99     CFLSteensAAResult *Result;
    100 
    101     void removeSelfFromCache() {
    102       assert(Result != nullptr);
    103       auto *Val = getValPtr();
    104       Result->evict(cast<Function>(Val));
    105       setValPtr(nullptr);
    106     }
    107   };
    108 
    109   const TargetLibraryInfo &TLI;
    110 
    111   /// \brief Cached mapping of Functions to their StratifiedSets.
    112   /// If a function's sets are currently being built, it is marked
    113   /// in the cache as an Optional without a value. This way, if we
    114   /// have any kind of recursion, it is discernable from a function
    115   /// that simply has empty sets.
    116   DenseMap<Function *, Optional<FunctionInfo>> Cache;
    117   std::forward_list<FunctionHandle> Handles;
    118 
    119   FunctionInfo buildSetsFrom(Function *F);
    120 };
    121 
    122 /// Analysis pass providing a never-invalidated alias analysis result.
    123 ///
    124 /// FIXME: We really should refactor CFL to use the analysis more heavily, and
    125 /// in particular to leverage invalidation to trigger re-computation of sets.
    126 class CFLSteensAA : public AnalysisInfoMixin<CFLSteensAA> {
    127   friend AnalysisInfoMixin<CFLSteensAA>;
    128   static AnalysisKey Key;
    129 
    130 public:
    131   typedef CFLSteensAAResult Result;
    132 
    133   CFLSteensAAResult run(Function &F, FunctionAnalysisManager &AM);
    134 };
    135 
    136 /// Legacy wrapper pass to provide the CFLSteensAAResult object.
    137 class CFLSteensAAWrapperPass : public ImmutablePass {
    138   std::unique_ptr<CFLSteensAAResult> Result;
    139 
    140 public:
    141   static char ID;
    142 
    143   CFLSteensAAWrapperPass();
    144 
    145   CFLSteensAAResult &getResult() { return *Result; }
    146   const CFLSteensAAResult &getResult() const { return *Result; }
    147 
    148   void initializePass() override;
    149   void getAnalysisUsage(AnalysisUsage &AU) const override;
    150 };
    151 
    152 //===--------------------------------------------------------------------===//
    153 //
    154 // createCFLSteensAAWrapperPass - This pass implements a set-based approach to
    155 // alias analysis.
    156 //
    157 ImmutablePass *createCFLSteensAAWrapperPass();
    158 }
    159 
    160 #endif
    161