[llvm] r245021 - [PM/AA] Extract the interface for GlobalsModRef into a header along with

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 13 20:48:21 PDT 2015


Author: chandlerc
Date: Thu Aug 13 22:48:20 2015
New Revision: 245021

URL: http://llvm.org/viewvc/llvm-project?rev=245021&view=rev
Log:
[PM/AA] Extract the interface for GlobalsModRef into a header along with
its creation function.

This required shifting a bunch of method definitions to be out-of-line
so that we could leave most of the implementation guts in the .cpp file.

Added:
    llvm/trunk/include/llvm/Analysis/GlobalsModRef.h
Modified:
    llvm/trunk/include/llvm/Analysis/Passes.h
    llvm/trunk/include/llvm/LinkAllPasses.h
    llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp
    llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp

Added: llvm/trunk/include/llvm/Analysis/GlobalsModRef.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/GlobalsModRef.h?rev=245021&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Analysis/GlobalsModRef.h (added)
+++ llvm/trunk/include/llvm/Analysis/GlobalsModRef.h Thu Aug 13 22:48:20 2015
@@ -0,0 +1,139 @@
+//===- GlobalsModRef.h - Simple Mod/Ref AA for Globals ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This is the interface for a simple mod/ref and alias analysis over globlas.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_GLOBALSMODREF_H
+#define LLVM_ANALYSIS_GLOBALSMODREF_H
+
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Pass.h"
+#include <list>
+
+namespace llvm {
+
+/// GlobalsModRef - The actual analysis pass.
+class GlobalsModRef : public ModulePass, public AliasAnalysis {
+  class FunctionInfo;
+
+  /// The globals that do not have their addresses taken.
+  SmallPtrSet<const GlobalValue *, 8> NonAddressTakenGlobals;
+
+  /// IndirectGlobals - The memory pointed to by this global is known to be
+  /// 'owned' by the global.
+  SmallPtrSet<const GlobalValue *, 8> IndirectGlobals;
+
+  /// AllocsForIndirectGlobals - If an instruction allocates memory for an
+  /// indirect global, this map indicates which one.
+  DenseMap<const Value *, const GlobalValue *> AllocsForIndirectGlobals;
+
+  /// For each function, keep track of what globals are modified or read.
+  DenseMap<const Function *, FunctionInfo> FunctionInfos;
+
+  /// Handle to clear this analysis on deletion of values.
+  struct DeletionCallbackHandle final : CallbackVH {
+    GlobalsModRef &GMR;
+    std::list<DeletionCallbackHandle>::iterator I;
+
+    DeletionCallbackHandle(GlobalsModRef &GMR, Value *V)
+        : CallbackVH(V), GMR(GMR) {}
+
+    void deleted() override;
+  };
+
+  /// List of callbacks for globals being tracked by this analysis. Note that
+  /// these objects are quite large, but we only anticipate having one per
+  /// global tracked by this analysis. There are numerous optimizations we
+  /// could perform to the memory utilization here if this becomes a problem.
+  std::list<DeletionCallbackHandle> Handles;
+
+public:
+  static char ID;
+  GlobalsModRef();
+
+  bool runOnModule(Module &M) override {
+    InitializeAliasAnalysis(this, &M.getDataLayout());
+
+    // Find non-addr taken globals.
+    AnalyzeGlobals(M);
+
+    // Propagate on CG.
+    AnalyzeCallGraph(getAnalysis<CallGraphWrapperPass>().getCallGraph(), M);
+    return false;
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AliasAnalysis::getAnalysisUsage(AU);
+    AU.addRequired<CallGraphWrapperPass>();
+    AU.setPreservesAll(); // Does not transform code
+  }
+
+  /// getAdjustedAnalysisPointer - This method is used when a pass implements
+  /// an analysis interface through multiple inheritance.  If needed, it
+  /// should override this to adjust the this pointer as needed for the
+  /// specified pass info.
+  void *getAdjustedAnalysisPointer(AnalysisID PI) override {
+    if (PI == &AliasAnalysis::ID)
+      return (AliasAnalysis *)this;
+    return this;
+  }
+
+  //------------------------------------------------
+  // Implement the AliasAnalysis API
+  //
+  AliasResult alias(const MemoryLocation &LocA,
+                    const MemoryLocation &LocB) override;
+  ModRefInfo getModRefInfo(ImmutableCallSite CS,
+                           const MemoryLocation &Loc) override;
+  ModRefInfo getModRefInfo(ImmutableCallSite CS1,
+                           ImmutableCallSite CS2) override {
+    return AliasAnalysis::getModRefInfo(CS1, CS2);
+  }
+
+  /// getModRefBehavior - Return the behavior of the specified function if
+  /// called from the specified call site.  The call site may be null in which
+  /// case the most generic behavior of this function should be returned.
+  FunctionModRefBehavior getModRefBehavior(const Function *F) override;
+
+  /// getModRefBehavior - Return the behavior of the specified function if
+  /// called from the specified call site.  The call site may be null in which
+  /// case the most generic behavior of this function should be returned.
+  FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
+
+private:
+  FunctionInfo *getFunctionInfo(const Function *F);
+
+  void AnalyzeGlobals(Module &M);
+  void AnalyzeCallGraph(CallGraph &CG, Module &M);
+  bool AnalyzeUsesOfPointer(Value *V,
+                            SmallPtrSetImpl<Function *> *Readers = nullptr,
+                            SmallPtrSetImpl<Function *> *Writers = nullptr,
+                            GlobalValue *OkayStoreDest = nullptr);
+  bool AnalyzeIndirectGlobalMemory(GlobalValue *GV);
+
+  bool isNonEscapingGlobalNoAlias(const GlobalValue *GV, const Value *V);
+};
+
+//===--------------------------------------------------------------------===//
+//
+// createGlobalsModRefPass - This pass provides alias and mod/ref info for
+// global values that do not have their addresses taken.
+//
+Pass *createGlobalsModRefPass();
+
+}
+
+#endif

Modified: llvm/trunk/include/llvm/Analysis/Passes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Passes.h?rev=245021&r1=245020&r2=245021&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/Passes.h (original)
+++ llvm/trunk/include/llvm/Analysis/Passes.h Thu Aug 13 22:48:20 2015
@@ -26,13 +26,6 @@ namespace llvm {
 
   //===--------------------------------------------------------------------===//
   //
-  // createGlobalsModRefPass - This pass provides alias and mod/ref info for
-  // global values that do not have their addresses taken.
-  //
-  Pass *createGlobalsModRefPass();
-
-  //===--------------------------------------------------------------------===//
-  //
   // createAAEvalPass - This pass implements a simple N^2 alias analysis
   // accuracy evaluator.
   //

Modified: llvm/trunk/include/llvm/LinkAllPasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=245021&r1=245020&r2=245021&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LinkAllPasses.h (original)
+++ llvm/trunk/include/llvm/LinkAllPasses.h Thu Aug 13 22:48:20 2015
@@ -22,6 +22,7 @@
 #include "llvm/Analysis/CFLAliasAnalysis.h"
 #include "llvm/Analysis/CallPrinter.h"
 #include "llvm/Analysis/DomPrinter.h"
+#include "llvm/Analysis/GlobalsModRef.h"
 #include "llvm/Analysis/IntervalPartition.h"
 #include "llvm/Analysis/LibCallAliasAnalysis.h"
 #include "llvm/Analysis/Lint.h"

Modified: llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp?rev=245021&r1=245020&r2=245021&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp (original)
+++ llvm/trunk/lib/Analysis/IPA/GlobalsModRef.cpp Thu Aug 13 22:48:20 2015
@@ -14,15 +14,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/GlobalsModRef.h"
 #include "llvm/ADT/SCCIterator.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/CallGraph.h"
 #include "llvm/Analysis/MemoryBuiltins.h"
 #include "llvm/Analysis/ValueTracking.h"
-#include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/InstIterator.h"
 #include "llvm/IR/Instructions.h"
@@ -30,7 +27,6 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CommandLine.h"
-#include <list>
 using namespace llvm;
 
 #define DEBUG_TYPE "globalsmodref-aa"
@@ -56,14 +52,13 @@ STATISTIC(NumIndirectGlobalVars, "Number
 static cl::opt<bool> EnableUnsafeGlobalsModRefAliasResults(
     "enable-unsafe-globalsmodref-alias-results", cl::init(false), cl::Hidden);
 
-namespace {
 /// The mod/ref information collected for a particular function.
 ///
 /// We collect information about mod/ref behavior of a function here, both in
 /// general and as pertains to specific globals. We only have this detailed
 /// information when we know *something* useful about the behavior. If we
 /// saturate to fully general mod/ref, we remove the info for the function.
-class FunctionInfo {
+class GlobalsModRef::FunctionInfo {
   typedef SmallDenseMap<const GlobalValue *, ModRefInfo, 16> GlobalInfoMapType;
 
   /// Build a wrapper struct that has 8-byte alignment. All heap allocations
@@ -196,169 +191,38 @@ private:
   PointerIntPair<AlignedMap *, 3, unsigned, AlignedMapPointerTraits> Info;
 };
 
-/// GlobalsModRef - The actual analysis pass.
-class GlobalsModRef : public ModulePass, public AliasAnalysis {
-  /// The globals that do not have their addresses taken.
-  SmallPtrSet<const GlobalValue *, 8> NonAddressTakenGlobals;
-
-  /// IndirectGlobals - The memory pointed to by this global is known to be
-  /// 'owned' by the global.
-  SmallPtrSet<const GlobalValue *, 8> IndirectGlobals;
-
-  /// AllocsForIndirectGlobals - If an instruction allocates memory for an
-  /// indirect global, this map indicates which one.
-  DenseMap<const Value *, const GlobalValue *> AllocsForIndirectGlobals;
-
-  /// For each function, keep track of what globals are modified or read.
-  DenseMap<const Function *, FunctionInfo> FunctionInfos;
-
-  /// Handle to clear this analysis on deletion of values.
-  struct DeletionCallbackHandle final : CallbackVH {
-    GlobalsModRef &GMR;
-    std::list<DeletionCallbackHandle>::iterator I;
-
-    DeletionCallbackHandle(GlobalsModRef &GMR, Value *V)
-        : CallbackVH(V), GMR(GMR) {}
-
-    void deleted() override {
-      Value *V = getValPtr();
-      if (auto *F = dyn_cast<Function>(V))
-        GMR.FunctionInfos.erase(F);
-
-      if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
-        if (GMR.NonAddressTakenGlobals.erase(GV)) {
-          // This global might be an indirect global.  If so, remove it and
-          // remove any AllocRelatedValues for it.
-          if (GMR.IndirectGlobals.erase(GV)) {
-            // Remove any entries in AllocsForIndirectGlobals for this global.
-            for (auto I = GMR.AllocsForIndirectGlobals.begin(),
-                      E = GMR.AllocsForIndirectGlobals.end();
-                 I != E; ++I)
-              if (I->second == GV)
-                GMR.AllocsForIndirectGlobals.erase(I);
-          }
-
-          // Scan the function info we have collected and remove this global
-          // from all of them.
-          for (auto &FIPair : GMR.FunctionInfos)
-            FIPair.second.eraseModRefInfoForGlobal(*GV);
-        }
+void GlobalsModRef::DeletionCallbackHandle::deleted() {
+  Value *V = getValPtr();
+  if (auto *F = dyn_cast<Function>(V))
+    GMR.FunctionInfos.erase(F);
+
+  if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+    if (GMR.NonAddressTakenGlobals.erase(GV)) {
+      // This global might be an indirect global.  If so, remove it and
+      // remove any AllocRelatedValues for it.
+      if (GMR.IndirectGlobals.erase(GV)) {
+        // Remove any entries in AllocsForIndirectGlobals for this global.
+        for (auto I = GMR.AllocsForIndirectGlobals.begin(),
+                  E = GMR.AllocsForIndirectGlobals.end();
+             I != E; ++I)
+          if (I->second == GV)
+            GMR.AllocsForIndirectGlobals.erase(I);
       }
 
-      // If this is an allocation related to an indirect global, remove it.
-      GMR.AllocsForIndirectGlobals.erase(V);
-
-      // And clear out the handle.
-      setValPtr(nullptr);
-      GMR.Handles.erase(I);
-      // This object is now destroyed!
+      // Scan the function info we have collected and remove this global
+      // from all of them.
+      for (auto &FIPair : GMR.FunctionInfos)
+        FIPair.second.eraseModRefInfoForGlobal(*GV);
     }
-  };
-
-  /// List of callbacks for globals being tracked by this analysis. Note that
-  /// these objects are quite large, but we only anticipate having one per
-  /// global tracked by this analysis. There are numerous optimizations we
-  /// could perform to the memory utilization here if this becomes a problem.
-  std::list<DeletionCallbackHandle> Handles;
-
-public:
-  static char ID;
-  GlobalsModRef() : ModulePass(ID) {
-    initializeGlobalsModRefPass(*PassRegistry::getPassRegistry());
-  }
-
-  bool runOnModule(Module &M) override {
-    InitializeAliasAnalysis(this, &M.getDataLayout());
-
-    // Find non-addr taken globals.
-    AnalyzeGlobals(M);
-
-    // Propagate on CG.
-    AnalyzeCallGraph(getAnalysis<CallGraphWrapperPass>().getCallGraph(), M);
-    return false;
-  }
-
-  void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AliasAnalysis::getAnalysisUsage(AU);
-    AU.addRequired<CallGraphWrapperPass>();
-    AU.setPreservesAll(); // Does not transform code
-  }
-
-  /// getAdjustedAnalysisPointer - This method is used when a pass implements
-  /// an analysis interface through multiple inheritance.  If needed, it
-  /// should override this to adjust the this pointer as needed for the
-  /// specified pass info.
-  void *getAdjustedAnalysisPointer(AnalysisID PI) override {
-    if (PI == &AliasAnalysis::ID)
-      return (AliasAnalysis *)this;
-    return this;
-  }
-
-  //------------------------------------------------
-  // Implement the AliasAnalysis API
-  //
-  AliasResult alias(const MemoryLocation &LocA,
-                    const MemoryLocation &LocB) override;
-  ModRefInfo getModRefInfo(ImmutableCallSite CS,
-                           const MemoryLocation &Loc) override;
-  ModRefInfo getModRefInfo(ImmutableCallSite CS1,
-                           ImmutableCallSite CS2) override {
-    return AliasAnalysis::getModRefInfo(CS1, CS2);
-  }
-
-  /// getModRefBehavior - Return the behavior of the specified function if
-  /// called from the specified call site.  The call site may be null in which
-  /// case the most generic behavior of this function should be returned.
-  FunctionModRefBehavior getModRefBehavior(const Function *F) override {
-    FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
-
-    if (FunctionInfo *FI = getFunctionInfo(F)) {
-      if (FI->getModRefInfo() == MRI_NoModRef)
-        Min = FMRB_DoesNotAccessMemory;
-      else if ((FI->getModRefInfo() & MRI_Mod) == 0)
-        Min = FMRB_OnlyReadsMemory;
-    }
-
-    return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
   }
 
-  /// getModRefBehavior - Return the behavior of the specified function if
-  /// called from the specified call site.  The call site may be null in which
-  /// case the most generic behavior of this function should be returned.
-  FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override {
-    FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
-
-    if (const Function *F = CS.getCalledFunction())
-      if (FunctionInfo *FI = getFunctionInfo(F)) {
-        if (FI->getModRefInfo() == MRI_NoModRef)
-          Min = FMRB_DoesNotAccessMemory;
-        else if ((FI->getModRefInfo() & MRI_Mod) == 0)
-          Min = FMRB_OnlyReadsMemory;
-      }
+  // If this is an allocation related to an indirect global, remove it.
+  GMR.AllocsForIndirectGlobals.erase(V);
 
-    return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
-  }
-
-private:
-  /// Returns the function info for the function, or null if we don't have
-  /// anything useful to say about it.
-  FunctionInfo *getFunctionInfo(const Function *F) {
-    auto I = FunctionInfos.find(F);
-    if (I != FunctionInfos.end())
-      return &I->second;
-    return nullptr;
-  }
-
-  void AnalyzeGlobals(Module &M);
-  void AnalyzeCallGraph(CallGraph &CG, Module &M);
-  bool AnalyzeUsesOfPointer(Value *V,
-                            SmallPtrSetImpl<Function *> *Readers = nullptr,
-                            SmallPtrSetImpl<Function *> *Writers = nullptr,
-                            GlobalValue *OkayStoreDest = nullptr);
-  bool AnalyzeIndirectGlobalMemory(GlobalValue *GV);
-
-  bool isNonEscapingGlobalNoAlias(const GlobalValue *GV, const Value *V);
-};
+  // And clear out the handle.
+  setValPtr(nullptr);
+  GMR.Handles.erase(I);
+  // This object is now destroyed!
 }
 
 char GlobalsModRef::ID = 0;
@@ -372,6 +236,46 @@ INITIALIZE_AG_PASS_END(GlobalsModRef, Al
 
 Pass *llvm::createGlobalsModRefPass() { return new GlobalsModRef(); }
 
+GlobalsModRef::GlobalsModRef() : ModulePass(ID) {
+  initializeGlobalsModRefPass(*PassRegistry::getPassRegistry());
+}
+
+FunctionModRefBehavior GlobalsModRef::getModRefBehavior(const Function *F) {
+  FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
+
+  if (FunctionInfo *FI = getFunctionInfo(F)) {
+    if (FI->getModRefInfo() == MRI_NoModRef)
+      Min = FMRB_DoesNotAccessMemory;
+    else if ((FI->getModRefInfo() & MRI_Mod) == 0)
+      Min = FMRB_OnlyReadsMemory;
+  }
+
+  return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
+}
+
+FunctionModRefBehavior GlobalsModRef::getModRefBehavior(ImmutableCallSite CS) {
+  FunctionModRefBehavior Min = FMRB_UnknownModRefBehavior;
+
+  if (const Function *F = CS.getCalledFunction())
+    if (FunctionInfo *FI = getFunctionInfo(F)) {
+      if (FI->getModRefInfo() == MRI_NoModRef)
+        Min = FMRB_DoesNotAccessMemory;
+      else if ((FI->getModRefInfo() & MRI_Mod) == 0)
+        Min = FMRB_OnlyReadsMemory;
+    }
+
+  return FunctionModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);
+}
+
+/// Returns the function info for the function, or null if we don't have
+/// anything useful to say about it.
+GlobalsModRef::FunctionInfo *GlobalsModRef::getFunctionInfo(const Function *F) {
+  auto I = FunctionInfos.find(F);
+  if (I != FunctionInfos.end())
+    return &I->second;
+  return nullptr;
+}
+
 /// AnalyzeGlobals - Scan through the users of all of the internal
 /// GlobalValue's in the program.  If none of them have their "address taken"
 /// (really, their address passed to something nontrivial), record this fact,

Modified: llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp?rev=245021&r1=245020&r2=245021&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp Thu Aug 13 22:48:20 2015
@@ -24,6 +24,7 @@
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Analysis/BasicAliasAnalysis.h"
 #include "llvm/Analysis/CFLAliasAnalysis.h"
+#include "llvm/Analysis/GlobalsModRef.h"
 #include "llvm/Analysis/ScopedNoAliasAA.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"




More information about the llvm-commits mailing list