llvm-6502/include/llvm/CallGraphSCCPass.h
Chris Lattner 5095e3d1d1 Fix some nasty callgraph dangling pointer problems in
argpromotion and structretpromote.  Basically, when replacing
a function, they used the 'changeFunction' api which changes
the entry in the function map (and steals/reuses the callgraph
node).

This has some interesting effects: first, the problem is that it doesn't
update the "callee" edges in any callees of the function in the call graph.
Second, this covers for a major problem in all the CGSCC pass stuff, which 
is that it is completely broken when functions are deleted if they *don't*
reuse a CGN.  (there is a cute little fixme about this though :).

This patch changes the protocol that CGSCC passes must obey: now the CGSCC 
pass manager copies the SCC and preincrements its iterator to avoid passes
invalidating it.  This allows CGSCC passes to mutate the current SCC.  However
multiple passes may be run on that SCC, so if passes do this, they are now
required to *update* the SCC to be current when they return.

Other less interesting parts of this patch are that it makes passes update
the CG more directly, eliminates changeFunction, and requires clients of
replaceCallSite to specify the new callee CGN if they are changing it.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80527 91177308-0d34-0410-b5e6-96231b3b80d8
2009-08-31 00:19:58 +00:00

78 lines
2.9 KiB
C++

//===- CallGraphSCCPass.h - Pass that operates BU on call graph -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the CallGraphSCCPass class, which is used for passes which
// are implemented as bottom-up traversals on the call graph. Because there may
// be cycles in the call graph, passes of this type operate on the call-graph in
// SCC order: that is, they process function bottom-up, except for recursive
// functions, which they process all at once.
//
// These passes are inherently interprocedural, and are required to keep the
// call graph up-to-date if they do anything which could modify it.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CALL_GRAPH_SCC_PASS_H
#define LLVM_CALL_GRAPH_SCC_PASS_H
#include "llvm/Pass.h"
#include "llvm/Analysis/CallGraph.h"
namespace llvm {
class CallGraphNode;
class CallGraph;
class PMStack;
struct CallGraphSCCPass : public Pass {
explicit CallGraphSCCPass(intptr_t pid) : Pass(pid) {}
explicit CallGraphSCCPass(void *pid) : Pass(pid) {}
/// doInitialization - This method is called before the SCC's of the program
/// has been processed, allowing the pass to do initialization as necessary.
virtual bool doInitialization(CallGraph &CG) {
return false;
}
/// runOnSCC - This method should be implemented by the subclass to perform
/// whatever action is necessary for the specified SCC. Note that
/// non-recursive (or only self-recursive) functions will have an SCC size of
/// 1, where recursive portions of the call graph will have SCC size > 1.
///
/// SCC passes that add or delete functions to the SCC are required to update
/// the SCC list, otherwise stale pointers may be dereferenced.
///
virtual bool runOnSCC(std::vector<CallGraphNode *> &SCC) = 0;
/// doFinalization - This method is called after the SCC's of the program has
/// been processed, allowing the pass to do final cleanup as necessary.
virtual bool doFinalization(CallGraph &CG) {
return false;
}
/// Assign pass manager to manager this pass
virtual void assignPassManager(PMStack &PMS,
PassManagerType PMT = PMT_CallGraphPassManager);
/// Return what kind of Pass Manager can manage this pass.
virtual PassManagerType getPotentialPassManagerType() const {
return PMT_CallGraphPassManager;
}
/// getAnalysisUsage - For this class, we declare that we require and preserve
/// the call graph. If the derived class implements this method, it should
/// always explicitly call the implementation here.
virtual void getAnalysisUsage(AnalysisUsage &Info) const;
};
} // End llvm namespace
#endif