Home | History | Annotate | Download | only in Analysis
      1 //===- GlobalsModRef.h - Simple Mod/Ref AA for Globals ----------*- 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 a simple mod/ref and alias analysis over globals.
     11 ///
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_ANALYSIS_GLOBALSMODREF_H
     15 #define LLVM_ANALYSIS_GLOBALSMODREF_H
     16 
     17 #include "llvm/Analysis/AliasAnalysis.h"
     18 #include "llvm/Analysis/CallGraph.h"
     19 #include "llvm/IR/Constants.h"
     20 #include "llvm/IR/Function.h"
     21 #include "llvm/IR/Module.h"
     22 #include "llvm/IR/ValueHandle.h"
     23 #include "llvm/Pass.h"
     24 #include <list>
     25 
     26 namespace llvm {
     27 
     28 /// An alias analysis result set for globals.
     29 ///
     30 /// This focuses on handling aliasing properties of globals and interprocedural
     31 /// function call mod/ref information.
     32 class GlobalsAAResult : public AAResultBase<GlobalsAAResult> {
     33   friend AAResultBase<GlobalsAAResult>;
     34 
     35   class FunctionInfo;
     36 
     37   const DataLayout &DL;
     38   const TargetLibraryInfo &TLI;
     39 
     40   /// The globals that do not have their addresses taken.
     41   SmallPtrSet<const GlobalValue *, 8> NonAddressTakenGlobals;
     42 
     43   /// IndirectGlobals - The memory pointed to by this global is known to be
     44   /// 'owned' by the global.
     45   SmallPtrSet<const GlobalValue *, 8> IndirectGlobals;
     46 
     47   /// AllocsForIndirectGlobals - If an instruction allocates memory for an
     48   /// indirect global, this map indicates which one.
     49   DenseMap<const Value *, const GlobalValue *> AllocsForIndirectGlobals;
     50 
     51   /// For each function, keep track of what globals are modified or read.
     52   DenseMap<const Function *, FunctionInfo> FunctionInfos;
     53 
     54   /// A map of functions to SCC. The SCCs are described by a simple integer
     55   /// ID that is only useful for comparing for equality (are two functions
     56   /// in the same SCC or not?)
     57   DenseMap<const Function *, unsigned> FunctionToSCCMap;
     58 
     59   /// Handle to clear this analysis on deletion of values.
     60   struct DeletionCallbackHandle final : CallbackVH {
     61     GlobalsAAResult *GAR;
     62     std::list<DeletionCallbackHandle>::iterator I;
     63 
     64     DeletionCallbackHandle(GlobalsAAResult &GAR, Value *V)
     65         : CallbackVH(V), GAR(&GAR) {}
     66 
     67     void deleted() override;
     68   };
     69 
     70   /// List of callbacks for globals being tracked by this analysis. Note that
     71   /// these objects are quite large, but we only anticipate having one per
     72   /// global tracked by this analysis. There are numerous optimizations we
     73   /// could perform to the memory utilization here if this becomes a problem.
     74   std::list<DeletionCallbackHandle> Handles;
     75 
     76   explicit GlobalsAAResult(const DataLayout &DL, const TargetLibraryInfo &TLI);
     77 
     78 public:
     79   GlobalsAAResult(GlobalsAAResult &&Arg);
     80   ~GlobalsAAResult();
     81 
     82   static GlobalsAAResult analyzeModule(Module &M, const TargetLibraryInfo &TLI,
     83                                        CallGraph &CG);
     84 
     85   //------------------------------------------------
     86   // Implement the AliasAnalysis API
     87   //
     88   AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
     89 
     90   using AAResultBase::getModRefInfo;
     91   ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc);
     92 
     93   /// getModRefBehavior - Return the behavior of the specified function if
     94   /// called from the specified call site.  The call site may be null in which
     95   /// case the most generic behavior of this function should be returned.
     96   FunctionModRefBehavior getModRefBehavior(const Function *F);
     97 
     98   /// getModRefBehavior - Return the behavior of the specified function if
     99   /// called from the specified call site.  The call site may be null in which
    100   /// case the most generic behavior of this function should be returned.
    101   FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS);
    102 
    103 private:
    104   FunctionInfo *getFunctionInfo(const Function *F);
    105 
    106   void AnalyzeGlobals(Module &M);
    107   void AnalyzeCallGraph(CallGraph &CG, Module &M);
    108   bool AnalyzeUsesOfPointer(Value *V,
    109                             SmallPtrSetImpl<Function *> *Readers = nullptr,
    110                             SmallPtrSetImpl<Function *> *Writers = nullptr,
    111                             GlobalValue *OkayStoreDest = nullptr);
    112   bool AnalyzeIndirectGlobalMemory(GlobalVariable *GV);
    113   void CollectSCCMembership(CallGraph &CG);
    114 
    115   bool isNonEscapingGlobalNoAlias(const GlobalValue *GV, const Value *V);
    116   ModRefInfo getModRefInfoForArgument(ImmutableCallSite CS,
    117                                       const GlobalValue *GV);
    118 };
    119 
    120 /// Analysis pass providing a never-invalidated alias analysis result.
    121 class GlobalsAA : public AnalysisInfoMixin<GlobalsAA> {
    122   friend AnalysisInfoMixin<GlobalsAA>;
    123   static AnalysisKey Key;
    124 
    125 public:
    126   typedef GlobalsAAResult Result;
    127 
    128   GlobalsAAResult run(Module &M, ModuleAnalysisManager &AM);
    129 };
    130 
    131 /// Legacy wrapper pass to provide the GlobalsAAResult object.
    132 class GlobalsAAWrapperPass : public ModulePass {
    133   std::unique_ptr<GlobalsAAResult> Result;
    134 
    135 public:
    136   static char ID;
    137 
    138   GlobalsAAWrapperPass();
    139 
    140   GlobalsAAResult &getResult() { return *Result; }
    141   const GlobalsAAResult &getResult() const { return *Result; }
    142 
    143   bool runOnModule(Module &M) override;
    144   bool doFinalization(Module &M) override;
    145   void getAnalysisUsage(AnalysisUsage &AU) const override;
    146 };
    147 
    148 //===--------------------------------------------------------------------===//
    149 //
    150 // createGlobalsAAWrapperPass - This pass provides alias and mod/ref info for
    151 // global values that do not have their addresses taken.
    152 //
    153 ModulePass *createGlobalsAAWrapperPass();
    154 }
    155 
    156 #endif
    157