[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