summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2013-11-26 04:19:30 +0000
committerChandler Carruth <chandlerc@gmail.com>2013-11-26 04:19:30 +0000
commit54fec07ec00b4449393a66e8e2e62fd241781f80 (patch)
tree6bbf30c8cf3c092fe0c5035e0705c6aa912eada3 /include
parentbdd300b22cec875c3400378b1badd943988b3f9d (diff)
downloadllvm-54fec07ec00b4449393a66e8e2e62fd241781f80.tar.gz
llvm-54fec07ec00b4449393a66e8e2e62fd241781f80.tar.bz2
llvm-54fec07ec00b4449393a66e8e2e62fd241781f80.tar.xz
[PM] Split the CallGraph out from the ModulePass which creates the
CallGraph. This makes the CallGraph a totally generic analysis object that is the container for the graph data structure and the primary interface for querying and manipulating it. The pass logic is separated into its own class. For compatibility reasons, the pass provides wrapper methods for most of the methods on CallGraph -- they all just forward. This will allow the new pass manager infrastructure to provide its own analysis pass that constructs the same CallGraph object and makes it available. The idea is that in the new pass manager, the analysis pass's 'run' method returns a concrete analysis 'result'. Here, that result is a 'CallGraph'. The 'run' method will typically do only minimal work, deferring much of the work into the implementation of the result object in order to be lazy about computing things, but when (like DomTree) there is *some* up-front computation, the analysis does it prior to handing the result back to the querying pass. I know some of this is fairly ugly. I'm happy to change it around if folks can suggest a cleaner interim state, but there is going to be some amount of unavoidable ugliness during the transition period. The good thing is that this is very limited and will naturally go away when the old pass infrastructure goes away. It won't hang around to bother us later. Next up is the initial new-PM-style call graph analysis. =] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195722 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/Analysis/CallGraph.h121
-rw-r--r--include/llvm/InitializePasses.h2
2 files changed, 100 insertions, 23 deletions
diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h
index c7255e2bde..803c0dfaab 100644
--- a/include/llvm/Analysis/CallGraph.h
+++ b/include/llvm/Analysis/CallGraph.h
@@ -53,6 +53,7 @@
#define LLVM_ANALYSIS_CALLGRAPH_H
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
@@ -67,15 +68,13 @@ class Function;
class Module;
class CallGraphNode;
-/// \brief The basic data container for the call graph and the \c ModulePass
-/// which produces it.
+/// \brief The basic data container for the call graph of a \c Module of IR.
///
-/// This class exposes both the interface to the call graph container and the
-/// module pass which runs over a module of IR and produces the call graph.
+/// This class exposes both the interface to the call graph for a module of IR.
///
/// The core call graph itself can also be updated to reflect changes to the IR.
-class CallGraph : public ModulePass {
- Module *M;
+class CallGraph {
+ Module &M;
typedef std::map<const Function *, CallGraphNode *> FunctionMapTy;
@@ -106,13 +105,17 @@ class CallGraph : public ModulePass {
void addToCallGraph(Function *F);
public:
- static char ID; // Class identification, replacement for typeinfo
+ CallGraph(Module &M);
+ ~CallGraph();
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
typedef FunctionMapTy::iterator iterator;
typedef FunctionMapTy::const_iterator const_iterator;
/// \brief Returns the module the call graph corresponds to.
- Module &getModule() const { return *M; }
+ Module &getModule() const { return M; }
inline iterator begin() { return FunctionMap.begin(); }
inline iterator end() { return FunctionMap.end(); }
@@ -160,20 +163,6 @@ public:
/// \brief Similar to operator[], but this will insert a new CallGraphNode for
/// \c F if one does not already exist.
CallGraphNode *getOrInsertFunction(const Function *F);
-
- CallGraph();
- virtual ~CallGraph() { releaseMemory(); }
-
- //===---------------------------------------------------------------------
- // Implementation of the ModulePass interface needed here.
- //
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
- virtual bool runOnModule(Module &M);
- virtual void releaseMemory();
-
- void print(raw_ostream &o, const Module *) const;
- void dump() const;
};
/// \brief A node in the call graph for a module.
@@ -303,6 +292,94 @@ public:
void allReferencesDropped() { NumReferences = 0; }
};
+/// \brief The \c ModulePass which wraps up a \c CallGraph and the logic to
+/// build it.
+///
+/// This class exposes both the interface to the call graph container and the
+/// module pass which runs over a module of IR and produces the call graph. The
+/// call graph interface is entirelly a wrapper around a \c CallGraph object
+/// which is stored internally for each module.
+class CallGraphWrapperPass : public ModulePass {
+ OwningPtr<CallGraph> G;
+
+public:
+ static char ID; // Class identification, replacement for typeinfo
+
+ CallGraphWrapperPass();
+ virtual ~CallGraphWrapperPass();
+
+ /// \brief The internal \c CallGraph around which the rest of this interface
+ /// is wrapped.
+ const CallGraph &getCallGraph() const { return *G; }
+ CallGraph &getCallGraph() { return *G; }
+
+ typedef CallGraph::iterator iterator;
+ typedef CallGraph::const_iterator const_iterator;
+
+ /// \brief Returns the module the call graph corresponds to.
+ Module &getModule() const { return G->getModule(); }
+
+ inline iterator begin() { return G->begin(); }
+ inline iterator end() { return G->end(); }
+ inline const_iterator begin() const { return G->begin(); }
+ inline const_iterator end() const { return G->end(); }
+
+ /// \brief Returns the call graph node for the provided function.
+ inline const CallGraphNode *operator[](const Function *F) const {
+ return (*G)[F];
+ }
+
+ /// \brief Returns the call graph node for the provided function.
+ inline CallGraphNode *operator[](const Function *F) { return (*G)[F]; }
+
+ /// \brief Returns the \c CallGraphNode which is used to represent
+ /// undetermined calls into the callgraph.
+ CallGraphNode *getExternalCallingNode() const {
+ return G->getExternalCallingNode();
+ }
+
+ CallGraphNode *getCallsExternalNode() const {
+ return G->getCallsExternalNode();
+ }
+
+ /// \brief Returns the root/main method in the module, or some other root
+ /// node, such as the externalcallingnode.
+ CallGraphNode *getRoot() { return G->getRoot(); }
+ const CallGraphNode *getRoot() const { return G->getRoot(); }
+
+ //===---------------------------------------------------------------------
+ // Functions to keep a call graph up to date with a function that has been
+ // modified.
+ //
+
+ /// \brief Unlink the function from this module, returning it.
+ ///
+ /// Because this removes the function from the module, the call graph node is
+ /// destroyed. This is only valid if the function does not call any other
+ /// functions (ie, there are no edges in it's CGN). The easiest way to do
+ /// this is to dropAllReferences before calling this.
+ Function *removeFunctionFromModule(CallGraphNode *CGN) {
+ return G->removeFunctionFromModule(CGN);
+ }
+
+ /// \brief Similar to operator[], but this will insert a new CallGraphNode for
+ /// \c F if one does not already exist.
+ CallGraphNode *getOrInsertFunction(const Function *F) {
+ return G->getOrInsertFunction(F);
+ }
+
+ //===---------------------------------------------------------------------
+ // Implementation of the ModulePass interface needed here.
+ //
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual bool runOnModule(Module &M);
+ virtual void releaseMemory();
+
+ void print(raw_ostream &o, const Module *) const;
+ void dump() const;
+};
+
//===----------------------------------------------------------------------===//
// GraphTraits specializations for call graphs so that they can be treated as
// graphs by the generic graph algorithms.
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index 68916b1f47..029ae30859 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -73,7 +73,7 @@ void initializeArgPromotionPass(PassRegistry&);
void initializeSampleProfileLoaderPass(PassRegistry&);
void initializeBarrierNoopPass(PassRegistry&);
void initializeBasicAliasAnalysisPass(PassRegistry&);
-void initializeCallGraphPass(PassRegistry&);
+void initializeCallGraphWrapperPassPass(PassRegistry &);
void initializeBasicTTIPass(PassRegistry&);
void initializeBlockExtractorPassPass(PassRegistry&);
void initializeBlockFrequencyInfoPass(PassRegistry&);