diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2011-02-20 12:57:14 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2011-02-20 12:57:14 +0000 | 
| commit | cf099d11218cb6f6c5cce947d6738e347f07fb12 (patch) | |
| tree | d2b61ce94e654cb01a254d2195259db5f9cc3f3c /lib/Analysis/IPA | |
| parent | 49011b52fcba02a6051957b84705159f52fae4e4 (diff) | |
Notes
Diffstat (limited to 'lib/Analysis/IPA')
| -rw-r--r-- | lib/Analysis/IPA/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | lib/Analysis/IPA/CallGraph.cpp | 24 | ||||
| -rw-r--r-- | lib/Analysis/IPA/CallGraphSCCPass.cpp | 1 | ||||
| -rw-r--r-- | lib/Analysis/IPA/FindUsedTypes.cpp | 2 | ||||
| -rw-r--r-- | lib/Analysis/IPA/GlobalsModRef.cpp | 77 | ||||
| -rw-r--r-- | lib/Analysis/IPA/IPA.cpp | 29 | 
6 files changed, 101 insertions, 33 deletions
diff --git a/lib/Analysis/IPA/CMakeLists.txt b/lib/Analysis/IPA/CMakeLists.txt index 007ad228ae56..8ffef29870ae 100644 --- a/lib/Analysis/IPA/CMakeLists.txt +++ b/lib/Analysis/IPA/CMakeLists.txt @@ -3,4 +3,5 @@ add_llvm_library(LLVMipa    CallGraphSCCPass.cpp    FindUsedTypes.cpp    GlobalsModRef.cpp +  IPA.cpp    ) diff --git a/lib/Analysis/IPA/CallGraph.cpp b/lib/Analysis/IPA/CallGraph.cpp index b3635283fda5..690c4b4b6f1a 100644 --- a/lib/Analysis/IPA/CallGraph.cpp +++ b/lib/Analysis/IPA/CallGraph.cpp @@ -43,7 +43,9 @@ class BasicCallGraph : public ModulePass, public CallGraph {  public:    static char ID; // Class identification, replacement for typeinfo    BasicCallGraph() : ModulePass(ID), Root(0),  -    ExternalCallingNode(0), CallsExternalNode(0) {} +    ExternalCallingNode(0), CallsExternalNode(0) { +      initializeBasicCallGraphPass(*PassRegistry::getPassRegistry()); +    }    // runOnModule - Compute the call graph for the specified module.    virtual bool runOnModule(Module &M) { @@ -171,9 +173,9 @@ private:  } //End anonymous namespace -static RegisterAnalysisGroup<CallGraph> X("Call Graph"); +INITIALIZE_ANALYSIS_GROUP(CallGraph, "Call Graph", BasicCallGraph)  INITIALIZE_AG_PASS(BasicCallGraph, CallGraph, "basiccg", -                   "Basic CallGraph Construction", false, true, true); +                   "Basic CallGraph Construction", false, true, true)  char CallGraph::ID = 0;  char BasicCallGraph::ID = 0; @@ -228,6 +230,21 @@ Function *CallGraph::removeFunctionFromModule(CallGraphNode *CGN) {    return F;  } +/// spliceFunction - Replace the function represented by this node by another. +/// This does not rescan the body of the function, so it is suitable when +/// splicing the body of the old function to the new while also updating all +/// callers from old to new. +/// +void CallGraph::spliceFunction(const Function *From, const Function *To) { +  assert(FunctionMap.count(From) && "No CallGraphNode for function!"); +  assert(!FunctionMap.count(To) && +         "Pointing CallGraphNode at a function that already exists"); +  FunctionMapTy::iterator I = FunctionMap.find(From); +  I->second->F = const_cast<Function*>(To); +  FunctionMap[To] = I->second; +  FunctionMap.erase(I); +} +  // getOrInsertFunction - This method is identical to calling operator[], but  // it will insert a new CallGraphNode for the specified function if one does  // not already exist. @@ -274,7 +291,6 @@ void CallGraphNode::removeCallEdgeFor(CallSite CS) {    }  } -  // removeAnyCallEdgeTo - This method removes any call edges from this node to  // the specified callee function.  This takes more time to execute than  // removeCallEdgeTo, so it should not be used unless necessary. diff --git a/lib/Analysis/IPA/CallGraphSCCPass.cpp b/lib/Analysis/IPA/CallGraphSCCPass.cpp index b7a27cb288d9..725ab72f5595 100644 --- a/lib/Analysis/IPA/CallGraphSCCPass.cpp +++ b/lib/Analysis/IPA/CallGraphSCCPass.cpp @@ -582,7 +582,6 @@ namespace {    public:      static char ID; -    PrintCallGraphPass() : CallGraphSCCPass(ID), Out(dbgs()) {}      PrintCallGraphPass(const std::string &B, raw_ostream &o)        : CallGraphSCCPass(ID), Banner(B), Out(o) {} diff --git a/lib/Analysis/IPA/FindUsedTypes.cpp b/lib/Analysis/IPA/FindUsedTypes.cpp index 8eed9d6f68bc..06ae34cfd989 100644 --- a/lib/Analysis/IPA/FindUsedTypes.cpp +++ b/lib/Analysis/IPA/FindUsedTypes.cpp @@ -24,7 +24,7 @@ using namespace llvm;  char FindUsedTypes::ID = 0;  INITIALIZE_PASS(FindUsedTypes, "print-used-types", -                "Find Used Types", false, true); +                "Find Used Types", false, true)  // IncorporateType - Incorporate one type and all of its subtypes into the  // collection of used types. diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp index 6759b0afdce3..116aaf418ea0 100644 --- a/lib/Analysis/IPA/GlobalsModRef.cpp +++ b/lib/Analysis/IPA/GlobalsModRef.cpp @@ -24,6 +24,7 @@  #include "llvm/Analysis/AliasAnalysis.h"  #include "llvm/Analysis/CallGraph.h"  #include "llvm/Analysis/MemoryBuiltins.h" +#include "llvm/Analysis/ValueTracking.h"  #include "llvm/Support/CommandLine.h"  #include "llvm/Support/InstIterator.h"  #include "llvm/ADT/Statistic.h" @@ -88,7 +89,9 @@ namespace {    public:      static char ID; -    GlobalsModRef() : ModulePass(ID) {} +    GlobalsModRef() : ModulePass(ID) { +      initializeGlobalsModRefPass(*PassRegistry::getPassRegistry()); +    }      bool runOnModule(Module &M) {        InitializeAliasAnalysis(this);                 // set up super class @@ -106,10 +109,9 @@ namespace {      //------------------------------------------------      // Implement the AliasAnalysis API      // -    AliasResult alias(const Value *V1, unsigned V1Size, -                      const Value *V2, unsigned V2Size); +    AliasResult alias(const Location &LocA, const Location &LocB);      ModRefResult getModRefInfo(ImmutableCallSite CS, -                               const Value *P, unsigned Size); +                               const Location &Loc);      ModRefResult getModRefInfo(ImmutableCallSite CS1,                                 ImmutableCallSite CS2) {        return AliasAnalysis::getModRefInfo(CS1, CS2); @@ -119,32 +121,38 @@ namespace {      /// 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.      ModRefBehavior getModRefBehavior(const Function *F) { +      ModRefBehavior Min = UnknownModRefBehavior; +        if (FunctionRecord *FR = getFunctionInfo(F)) {          if (FR->FunctionEffect == 0) -          return DoesNotAccessMemory; +          Min = DoesNotAccessMemory;          else if ((FR->FunctionEffect & Mod) == 0) -          return OnlyReadsMemory; +          Min = OnlyReadsMemory;        } -      return AliasAnalysis::getModRefBehavior(F); + +      return ModRefBehavior(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.      ModRefBehavior getModRefBehavior(ImmutableCallSite CS) { -      const Function* F = CS.getCalledFunction(); -      if (!F) return AliasAnalysis::getModRefBehavior(CS); -      if (FunctionRecord *FR = getFunctionInfo(F)) { -        if (FR->FunctionEffect == 0) -          return DoesNotAccessMemory; -        else if ((FR->FunctionEffect & Mod) == 0) -          return OnlyReadsMemory; -      } -      return AliasAnalysis::getModRefBehavior(CS); +      ModRefBehavior Min = UnknownModRefBehavior; + +      if (const Function* F = CS.getCalledFunction()) +        if (FunctionRecord *FR = getFunctionInfo(F)) { +          if (FR->FunctionEffect == 0) +            Min = DoesNotAccessMemory; +          else if ((FR->FunctionEffect & Mod) == 0) +            Min = OnlyReadsMemory; +        } + +      return ModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min);      }      virtual void deleteValue(Value *V);      virtual void copyValue(Value *From, Value *To); +    virtual void addEscapingUse(Use &U);      /// getAdjustedAnalysisPointer - This method is used when a pass implements      /// an analysis interface through multiple inheritance.  If needed, it @@ -177,9 +185,13 @@ namespace {  }  char GlobalsModRef::ID = 0; -INITIALIZE_AG_PASS(GlobalsModRef, AliasAnalysis, +INITIALIZE_AG_PASS_BEGIN(GlobalsModRef, AliasAnalysis,                  "globalsmodref-aa", "Simple mod/ref analysis for globals",     -                false, true, false); +                false, true, false) +INITIALIZE_AG_DEPENDENCY(CallGraph) +INITIALIZE_AG_PASS_END(GlobalsModRef, AliasAnalysis, +                "globalsmodref-aa", "Simple mod/ref analysis for globals",     +                false, true, false)  Pass *llvm::createGlobalsModRefPass() { return new GlobalsModRef(); } @@ -314,7 +326,7 @@ bool GlobalsModRef::AnalyzeIndirectGlobalMemory(GlobalValue *GV) {          continue;        // Check the value being stored. -      Value *Ptr = SI->getOperand(0)->getUnderlyingObject(); +      Value *Ptr = GetUnderlyingObject(SI->getOperand(0));        if (isMalloc(Ptr)) {          // Okay, easy case. @@ -476,11 +488,11 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {  /// other is some random pointer, we know there cannot be an alias, because the  /// address of the global isn't taken.  AliasAnalysis::AliasResult -GlobalsModRef::alias(const Value *V1, unsigned V1Size, -                     const Value *V2, unsigned V2Size) { +GlobalsModRef::alias(const Location &LocA, +                     const Location &LocB) {    // Get the base object these pointers point to. -  const Value *UV1 = V1->getUnderlyingObject(); -  const Value *UV2 = V2->getUnderlyingObject(); +  const Value *UV1 = GetUnderlyingObject(LocA.Ptr); +  const Value *UV2 = GetUnderlyingObject(LocB.Ptr);    // If either of the underlying values is a global, they may be non-addr-taken    // globals, which we can answer queries about. @@ -528,17 +540,18 @@ GlobalsModRef::alias(const Value *V1, unsigned V1Size,    if ((GV1 || GV2) && GV1 != GV2)      return NoAlias; -  return AliasAnalysis::alias(V1, V1Size, V2, V2Size); +  return AliasAnalysis::alias(LocA, LocB);  }  AliasAnalysis::ModRefResult  GlobalsModRef::getModRefInfo(ImmutableCallSite CS, -                             const Value *P, unsigned Size) { +                             const Location &Loc) {    unsigned Known = ModRef;    // If we are asking for mod/ref info of a direct call with a pointer to a    // global we are tracking, return information if we have it. -  if (const GlobalValue *GV = dyn_cast<GlobalValue>(P->getUnderlyingObject())) +  if (const GlobalValue *GV = +        dyn_cast<GlobalValue>(GetUnderlyingObject(Loc.Ptr)))      if (GV->hasLocalLinkage())        if (const Function *F = CS.getCalledFunction())          if (NonAddressTakenGlobals.count(GV)) @@ -547,7 +560,7 @@ GlobalsModRef::getModRefInfo(ImmutableCallSite CS,    if (Known == NoModRef)      return NoModRef; // No need to query other mod/ref analyses -  return ModRefResult(Known & AliasAnalysis::getModRefInfo(CS, P, Size)); +  return ModRefResult(Known & AliasAnalysis::getModRefInfo(CS, Loc));  } @@ -584,3 +597,13 @@ void GlobalsModRef::deleteValue(Value *V) {  void GlobalsModRef::copyValue(Value *From, Value *To) {    AliasAnalysis::copyValue(From, To);  } + +void GlobalsModRef::addEscapingUse(Use &U) { +  // For the purposes of this analysis, it is conservatively correct to treat +  // a newly escaping value equivalently to a deleted one.  We could perhaps +  // be more precise by processing the new use and attempting to update our +  // saved analysis results to accomodate it. +  deleteValue(U); +   +  AliasAnalysis::addEscapingUse(U); +} diff --git a/lib/Analysis/IPA/IPA.cpp b/lib/Analysis/IPA/IPA.cpp new file mode 100644 index 000000000000..0ba2e04c6302 --- /dev/null +++ b/lib/Analysis/IPA/IPA.cpp @@ -0,0 +1,29 @@ +//===-- IPA.cpp -----------------------------------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the common initialization routines for the IPA library. +// +//===----------------------------------------------------------------------===// + +#include "llvm/InitializePasses.h" +#include "llvm-c/Initialization.h" + +using namespace llvm; + +/// initializeIPA - Initialize all passes linked into the IPA library. +void llvm::initializeIPA(PassRegistry &Registry) { +  initializeBasicCallGraphPass(Registry); +  initializeCallGraphAnalysisGroup(Registry); +  initializeFindUsedTypesPass(Registry); +  initializeGlobalsModRefPass(Registry); +} + +void LLVMInitializeIPA(LLVMPassRegistryRef R) { +  initializeIPA(*unwrap(R)); +}  | 
