diff options
Diffstat (limited to 'contrib/llvm/lib/Analysis/IPA')
-rw-r--r-- | contrib/llvm/lib/Analysis/IPA/CallGraph.cpp | 24 | ||||
-rw-r--r-- | contrib/llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp | 1 | ||||
-rw-r--r-- | contrib/llvm/lib/Analysis/IPA/FindUsedTypes.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/lib/Analysis/IPA/GlobalsModRef.cpp | 77 | ||||
-rw-r--r-- | contrib/llvm/lib/Analysis/IPA/IPA.cpp | 29 |
5 files changed, 100 insertions, 33 deletions
diff --git a/contrib/llvm/lib/Analysis/IPA/CallGraph.cpp b/contrib/llvm/lib/Analysis/IPA/CallGraph.cpp index b363528..690c4b4 100644 --- a/contrib/llvm/lib/Analysis/IPA/CallGraph.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp b/contrib/llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp index b7a27cb..725ab72 100644 --- a/contrib/llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/Analysis/IPA/FindUsedTypes.cpp b/contrib/llvm/lib/Analysis/IPA/FindUsedTypes.cpp index 8eed9d6..06ae34c 100644 --- a/contrib/llvm/lib/Analysis/IPA/FindUsedTypes.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/Analysis/IPA/GlobalsModRef.cpp b/contrib/llvm/lib/Analysis/IPA/GlobalsModRef.cpp index 6759b0a..116aaf4 100644 --- a/contrib/llvm/lib/Analysis/IPA/GlobalsModRef.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/Analysis/IPA/IPA.cpp b/contrib/llvm/lib/Analysis/IPA/IPA.cpp new file mode 100644 index 0000000..0ba2e04 --- /dev/null +++ b/contrib/llvm/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)); +} |