[llvm-commits] [poolalloc] r57375 - in /poolalloc/trunk: include/dsa/DSGraph.h include/dsa/DataStructure.h include/poolalloc/PoolAllocate.h lib/DSA/BottomUpClosure.cpp lib/DSA/CompleteBottomUp.cpp lib/DSA/DataStructure.cpp lib/DSA/EquivClassGraphs.cpp lib/DSA/Printer.cpp lib/DSA/StdLibPass.cpp lib/DSA/TopDownClosure.cpp lib/PoolAllocate/AccessTrace.cpp lib/PoolAllocate/PASimple.cpp lib/PoolAllocate/PointerCompress.cpp lib/PoolAllocate/PoolAllocate.cpp lib/PoolAllocate/TransformFunctionBody.cpp
Andrew Lenharth
alenhar2 at cs.uiuc.edu
Sat Oct 11 09:52:05 PDT 2008
Author: alenhar2
Date: Sat Oct 11 11:52:04 2008
New Revision: 57375
URL: http://llvm.org/viewvc/llvm-project?rev=57375&view=rev
Log:
Getting closer. Equiv was redundant with CBU when doing unresolved call merging in Globals during BU due to GlobalEQs.
Removed:
poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp
Modified:
poolalloc/trunk/include/dsa/DSGraph.h
poolalloc/trunk/include/dsa/DataStructure.h
poolalloc/trunk/include/poolalloc/PoolAllocate.h
poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp
poolalloc/trunk/lib/DSA/DataStructure.cpp
poolalloc/trunk/lib/DSA/Printer.cpp
poolalloc/trunk/lib/DSA/StdLibPass.cpp
poolalloc/trunk/lib/DSA/TopDownClosure.cpp
poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp
poolalloc/trunk/lib/PoolAllocate/PASimple.cpp
poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp
poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp
Modified: poolalloc/trunk/include/dsa/DSGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraph.h?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSGraph.h Sat Oct 11 11:52:04 2008
@@ -327,9 +327,12 @@
// Aux Function Call iteration
- typedef std::list<DSCallSite>::const_iterator afc_iterator;
- afc_iterator afc_begin() const { return AuxFunctionCalls.begin(); }
- afc_iterator afc_end() const { return AuxFunctionCalls.end(); }
+ typedef std::list<DSCallSite>::iterator afc_iterator;
+ afc_iterator afc_begin() { return AuxFunctionCalls.begin(); }
+ afc_iterator afc_end() { return AuxFunctionCalls.end(); }
+ typedef std::list<DSCallSite>::const_iterator afc_const_iterator;
+ afc_const_iterator afc_begin() const { return AuxFunctionCalls.begin(); }
+ afc_const_iterator afc_end() const { return AuxFunctionCalls.end(); }
/// getNodeForValue - Given a value that is used or defined in the body of the
/// current function, return the DSNode that it points to.
Modified: poolalloc/trunk/include/dsa/DataStructure.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DataStructure.h?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DataStructure.h (original)
+++ poolalloc/trunk/include/dsa/DataStructure.h Sat Oct 11 11:52:04 2008
@@ -72,7 +72,7 @@
EquivalenceClasses<const GlobalValue*> GlobalECs;
- void init(DataStructures* D, bool clone, bool printAuxCalls);
+ void init(DataStructures* D, bool clone, bool printAuxCalls, bool copyGlobalAuxCalls);
void init(TargetData* T);
void formGlobalECs();
@@ -83,18 +83,23 @@
}
DataStructures(intptr_t id)
- :ModulePass(id), TD(0), GraphSource(0), GlobalsGraph(0) {}
+ :ModulePass(id), TD(0), GraphSource(0), GlobalsGraph(0) {
+ //a dummy node for empty call sites
+ ActualCallees[0];
+ }
public:
callee_iterator callee_begin(const Instruction *I) const {
ActualCalleesTy::const_iterator ii = ActualCallees.find(I);
- assert(ii != ActualCallees.end() && "No calls for instruction");
+ if (ii == ActualCallees.end())
+ ii = ActualCallees.find(0);
return ii->second.begin();
}
callee_iterator callee_end(const Instruction *I) const {
ActualCalleesTy::const_iterator ii = ActualCallees.find(I);
- assert(ii != ActualCallees.end() && "No calls for instruction");
+ if (ii == ActualCallees.end())
+ ii = ActualCallees.find(0);
return ii->second.end();
}
@@ -127,7 +132,6 @@
}
void setDSGraph(const Function& F, DSGraph* G) {
- assert(!DSInfo[&F] && "DSGraph already exists");
DSInfo[&F] = G;
}
@@ -204,10 +208,16 @@
std::map<std::vector<const Function*>,
std::pair<DSGraph*, std::vector<DSNodeHandle> > > IndCallGraphMap;
- BUDataStructures(intptr_t id) : DataStructures(id) {}
+ const char* debugname;
+
public:
static char ID;
- BUDataStructures() : DataStructures((intptr_t)&ID) {}
+ //Child constructor
+ BUDataStructures(intptr_t CID, const char* name)
+ : DataStructures(CID), debugname(name) {}
+ //main constructor
+ BUDataStructures()
+ : DataStructures((intptr_t)&ID), debugname("dsa-bu") {}
~BUDataStructures() { releaseMemory(); }
virtual bool runOnModule(Module &M);
@@ -225,6 +235,9 @@
AU.addRequired<StdLibDataStructures>();
}
+protected:
+ bool runOnModuleInternal(Module &M);
+
private:
void calculateGraph(DSGraph &G);
@@ -247,7 +260,6 @@
///
class TDDataStructures : public DataStructures {
hash_set<const Function*> ArgsRemainIncomplete;
- BUDataStructures *BUInfo;
/// CallerCallEdges - For a particular graph, we keep a list of these records
/// which indicates which graphs call this function and from where.
@@ -307,10 +319,12 @@
/// their callers graphs, making the result more useful for things like pool
/// allocation.
///
-class CompleteBUDataStructures : public DataStructures {
+class CompleteBUDataStructures : public BUDataStructures {
+ void buildIndirectFunctionSets(Module &M);
public:
static char ID;
- CompleteBUDataStructures() : DataStructures((intptr_t)&ID) {}
+ CompleteBUDataStructures()
+ : BUDataStructures((intptr_t)&ID, "dsa-cbu") {}
~CompleteBUDataStructures() { releaseMemory(); }
virtual bool runOnModule(Module &M);
@@ -322,64 +336,6 @@
/// print - Print out the analysis results...
///
void print(std::ostream &O, const Module *M) const;
-
- virtual void releaseMemory();
-
-private:
- unsigned calculateSCCGraphs(DSGraph &FG, std::vector<DSGraph*> &Stack,
- unsigned &NextID,
- hash_map<DSGraph*, unsigned> &ValMap);
- void processGraph(DSGraph &G);
-};
-
-
-/// EquivClassGraphs - This is the same as the complete bottom-up graphs, but
-/// with functions partitioned into equivalence classes and a single merged
-/// DS graph for all functions in an equivalence class. After this merging,
-/// graphs are inlined bottom-up on the SCCs of the final (CBU) call graph.
-///
-struct EquivClassGraphs : public DataStructures {
-
- // Equivalence class where functions that can potentially be called via the
- // same function pointer are in the same class.
- EquivalenceClasses<const Function*> FuncECs;
-
- /// OneCalledFunction - For each indirect call, we keep track of one
- /// target of the call. This is used to find equivalence class called by
- /// a call site.
- std::map<DSNode*, const Function *> OneCalledFunction;
-
-public:
- static char ID;
- EquivClassGraphs();
-
- /// EquivClassGraphs - Computes the equivalence classes and then the
- /// folded DS graphs for each class.
- ///
-
- virtual bool runOnModule(Module &M);
-
- /// print - Print out the analysis results...
- ///
- void print(std::ostream &O, const Module *M) const;
-
- /// getSomeCalleeForCallSite - Return any one callee function at
- /// a call site.
- ///
- const Function *getSomeCalleeForCallSite(const CallSite &CS) const;
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<CompleteBUDataStructures>();
- }
-
-private:
- void buildIndirectFunctionSets(Module &M);
-
- unsigned processSCC(DSGraph &FG, std::vector<DSGraph*> &Stack,
- unsigned &NextID,
- std::map<DSGraph*, unsigned> &ValMap);
- void processGraph(DSGraph &FG);
-
};
} // End llvm namespace
Modified: poolalloc/trunk/include/poolalloc/PoolAllocate.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/poolalloc/PoolAllocate.h?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/include/poolalloc/PoolAllocate.h (original)
+++ poolalloc/trunk/include/poolalloc/PoolAllocate.h Sat Oct 11 11:52:04 2008
@@ -34,7 +34,6 @@
class DSGraph;
class Type;
class AllocaInst;
-class EquivClassGraphs;
class CallTargetFinder;
namespace PA {
@@ -103,8 +102,7 @@
class PoolAllocateGroup {
protected:
- EquivClassGraphs *ECGraphs;
- TDDataStructures *TDGraphs;
+ DataStructures *Graphs;
public:
static char ID;
@@ -120,23 +118,23 @@
virtual const Type * getPoolType() {return 0;}
virtual bool hasDSGraph (const Function & F) const {
- return ECGraphs->hasDSGraph (F);
+ return Graphs->hasDSGraph (F);
}
virtual DSGraph & getDSGraph (const Function & F) const {
- return ECGraphs->getDSGraph (F);
+ return Graphs->getDSGraph (F);
}
virtual DSGraph & getGlobalsGraph () const {
- return ECGraphs->getGlobalsGraph ();
+ return Graphs->getGlobalsGraph ();
}
virtual Value * getPool (const DSNode * N, Function & F) {return 0;}
virtual Value * getGlobalPool (const DSNode * Node) {return 0;}
- virtual CompleteBUDataStructures::callee_iterator callee_begin (Instruction *I) { return ECGraphs->callee_begin(I);}
- virtual CompleteBUDataStructures::callee_iterator callee_end (Instruction *I) { return ECGraphs->callee_end(I);}
+ virtual DataStructures::callee_iterator callee_begin (Instruction *I) { return Graphs->callee_begin(I);}
+ virtual DataStructures::callee_iterator callee_end (Instruction *I) { return Graphs->callee_end(I);}
};
/// PoolAllocate - The main pool allocation pass
@@ -183,7 +181,7 @@
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
- EquivClassGraphs &getECGraphs() const { return *ECGraphs; }
+ DataStructures &getGraphs() const { return *Graphs; }
/// getOrigFunctionFromClone - Given a pointer to a function that was cloned
/// from another function, return the original function. If the argument
@@ -240,11 +238,11 @@
}
virtual DSGraph & getDSGraph (const Function & F) const {
- return ECGraphs->getDSGraph (F);
+ return Graphs->getDSGraph (F);
}
virtual DSGraph & getGlobalsGraph () const {
- return ECGraphs->getGlobalsGraph ();
+ return Graphs->getGlobalsGraph ();
}
virtual Value * getPool (const DSNode * N, Function & F) {
@@ -265,14 +263,14 @@
return I->second;
}
- virtual CompleteBUDataStructures::callee_iterator
+ virtual DataStructures::callee_iterator
callee_begin (Instruction * I) {
- return ECGraphs->callee_begin(I);
+ return Graphs->callee_begin(I);
}
- virtual CompleteBUDataStructures::callee_iterator
+ virtual DataStructures::callee_iterator
callee_end (Instruction * I) {
- return ECGraphs->callee_end(I);
+ return Graphs->callee_end(I);
}
protected:
Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Sat Oct 11 11:52:04 2008
@@ -18,16 +18,13 @@
#include "dsa/DataStructure.h"
#include "dsa/DSGraph.h"
#include "llvm/Module.h"
-#include "llvm/DerivedTypes.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/Timer.h"
using namespace llvm;
namespace {
STATISTIC (MaxSCC, "Maximum SCC Size in Call Graph");
- STATISTIC (NumBUInlines, "Number of graphs inlined");
+ STATISTIC (NumInlines, "Number of graphs inlined");
STATISTIC (NumCallEdges, "Number of 'actual' call edges");
RegisterPass<BUDataStructures>
@@ -40,8 +37,12 @@
// program.
//
bool BUDataStructures::runOnModule(Module &M) {
- init(&getAnalysis<StdLibDataStructures>(), false, true);
+ init(&getAnalysis<StdLibDataStructures>(), false, true, false);
+ return runOnModuleInternal(M);
+}
+
+bool BUDataStructures::runOnModuleInternal(Module& M) {
std::vector<const Function*> Stack;
hash_map<const Function*, unsigned> ValMap;
unsigned NextID = 1;
@@ -50,13 +51,15 @@
if (MainFunc) {
calculateGraphs(MainFunc, Stack, NextID, ValMap);
CloneAuxIntoGlobal(getDSGraph(*MainFunc));
+ } else {
+ DOUT << debugname << ": No 'main' function found!\n";
}
// Calculate the graphs for any functions that are unreachable from main...
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isDeclaration() && !hasDSGraph(*I)) {
if (MainFunc)
- DOUT << "*** BU: Function unreachable from main: "
+ DOUT << debugname << ": Function unreachable from main: "
<< I->getName() << "\n";
calculateGraphs(I, Stack, NextID, ValMap); // Calculate all graphs.
CloneAuxIntoGlobal(getDSGraph(*I));
@@ -348,8 +351,20 @@
ReachabilityCloner RC(GG, G, 0);
for(DSGraph::afc_iterator ii = G.afc_begin(), ee = G.afc_end();
- ii != ee; ++ii)
- GG.getAuxFunctionCalls().push_front(RC.cloneCallSite(*ii));
+ ii != ee; ++ii) {
+ //If we can, merge with an existing call site for this instruction
+ if (GG.hasNodeForValue(ii->getCallSite().getInstruction()->getOperand(0))) {
+ DSGraph::afc_iterator GGii;
+ for(GGii = GG.afc_begin(); GGii != GG.afc_end(); ++GGii)
+ if (GGii->getCallSite().getInstruction()->getOperand(0) ==
+ ii->getCallSite().getInstruction()->getOperand(0))
+ break;
+ assert (GGii != GG.afc_end() && "Callsite should exist but doesn't");
+ RC.cloneCallSite(*ii).mergeWith(*GGii);
+ } else {
+ GG.getAuxFunctionCalls().push_front(RC.cloneCallSite(*ii));
+ }
+ }
}
void BUDataStructures::calculateGraph(DSGraph &Graph) {
@@ -432,7 +447,7 @@
Graph.mergeInGraph(CS, *Callee, *GI,
DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes|
(isComplete?0:DSGraph::DontCloneAuxCallNodes));
- ++NumBUInlines;
+ ++NumInlines;
} else {
DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
DEBUG(std::cerr << " calls " << CalledFuncs.size()
@@ -484,7 +499,7 @@
// bother merging it in again.
if (!GI->containsFunction(*I)) {
GI->cloneInto(getDSGraph(**I));
- ++NumBUInlines;
+ ++NumInlines;
}
std::vector<DSNodeHandle> NextArgs;
@@ -517,7 +532,7 @@
DSGraph::StripAllocaBit |
DSGraph::DontCloneCallNodes|
(isComplete?0:DSGraph::DontCloneAuxCallNodes));
- ++NumBUInlines;
+ ++NumInlines;
}
if (isComplete)
TempFCs.erase(TempFCs.begin());
@@ -575,7 +590,7 @@
<< Graph.getAuxFunctionCalls().size() << "]\n";
Graph.mergeInGraph(CS, *Callee, *GI,
DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes);
- ++NumBUInlines;
+ ++NumInlines;
} else {
DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
DEBUG(std::cerr << " calls " << CalledFuncs.size()
@@ -627,7 +642,7 @@
// bother merging it in again.
if (!GI->containsFunction(*I)) {
GI->cloneInto(getDSGraph(**I));
- ++NumBUInlines;
+ ++NumInlines;
}
std::vector<DSNodeHandle> NextArgs;
@@ -659,7 +674,7 @@
Graph.mergeInGraph(CS, IndCallGraph.second, *GI,
DSGraph::StripAllocaBit |
DSGraph::DontCloneCallNodes);
- ++NumBUInlines;
+ ++NumInlines;
}
}
Modified: poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp (original)
+++ poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp Sat Oct 11 11:52:04 2008
@@ -15,18 +15,15 @@
#define DEBUG_TYPE "dsa-cbu"
#include "dsa/DataStructure.h"
-#include "llvm/Module.h"
#include "dsa/DSGraph.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/ADT/SCCIterator.h"
+#include "llvm/Module.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Debug.h"
using namespace llvm;
namespace {
RegisterPass<CompleteBUDataStructures>
X("dsa-cbu", "'Complete' Bottom-up Data Structure Analysis");
- STATISTIC (NumCBUInlines, "Number of graphs inlined");
}
char CompleteBUDataStructures::ID;
@@ -35,177 +32,28 @@
// program.
//
bool CompleteBUDataStructures::runOnModule(Module &M) {
- init(&getAnalysis<BUDataStructures>(), false, true);
-
- std::vector<DSGraph*> Stack;
- hash_map<DSGraph*, unsigned> ValMap;
- unsigned NextID = 1;
-
- Function *MainFunc = M.getFunction("main");
- if (MainFunc) {
- if (!MainFunc->isDeclaration())
- calculateSCCGraphs(getOrCreateGraph(MainFunc), Stack, NextID, ValMap);
- } else {
- DOUT << "CBU-DSA: No 'main' function found!\n";
- }
+ init(&getAnalysis<BUDataStructures>(), false, true, false);
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
- if (!I->isDeclaration() && !hasDSGraph(*I)) {
- if (MainFunc) {
- DOUT << "*** CBU: Function unreachable from main: "
- << I->getName() << "\n";
- }
- calculateSCCGraphs(getOrCreateGraph(I), Stack, NextID, ValMap);
- }
-
- GlobalsGraph->removeTriviallyDeadNodes();
-
-
- // Merge the globals variables (not the calls) from the globals graph back
- // into the main function's graph so that the main function contains all of
- // the information about global pools and GV usage in the program.
- if (MainFunc && !MainFunc->isDeclaration()) {
- DSGraph &MainGraph = getOrCreateGraph(MainFunc);
- const DSGraph &GG = *MainGraph.getGlobalsGraph();
- ReachabilityCloner RC(MainGraph, GG,
- DSGraph::DontCloneCallNodes |
- DSGraph::DontCloneAuxCallNodes);
-
- // Clone the global nodes into this graph.
- for (DSScalarMap::global_iterator I = GG.getScalarMap().global_begin(),
- E = GG.getScalarMap().global_end(); I != E; ++I)
- if (isa<GlobalVariable>(*I))
- RC.getClonedNH(GG.getNodeForValue(*I));
-
- MainGraph.maskIncompleteMarkers();
- MainGraph.markIncompleteNodes(DSGraph::MarkFormalArgs |
- DSGraph::IgnoreGlobals);
- }
+ buildIndirectFunctionSets(M);
- return false;
+ return runOnModuleInternal(M);
}
-unsigned CompleteBUDataStructures::calculateSCCGraphs(DSGraph &FG,
- std::vector<DSGraph*> &Stack,
- unsigned &NextID,
- hash_map<DSGraph*, unsigned> &ValMap) {
- assert(!ValMap.count(&FG) && "Shouldn't revisit functions!");
- unsigned Min = NextID++, MyID = Min;
- ValMap[&FG] = Min;
- Stack.push_back(&FG);
-
- // The edges out of the current node are the call site targets...
- for (DSGraph::fc_iterator CI = FG.fc_begin(), CE = FG.fc_end();
- CI != CE; ++CI) {
- Instruction *Call = CI->getCallSite().getInstruction();
-
- // Loop over all of the actually called functions...
- for (callee_iterator I = callee_begin(Call), E = callee_end(Call);
- I != E ; ++I) {
- if (!(*I)->isDeclaration()) {
- DSGraph &Callee = getOrCreateGraph(*I);
- unsigned M;
- // Have we visited the destination function yet?
- hash_map<DSGraph*, unsigned>::iterator It = ValMap.find(&Callee);
- if (It == ValMap.end()) // No, visit it now.
- M = calculateSCCGraphs(Callee, Stack, NextID, ValMap);
- else // Yes, get it's number.
- M = It->second;
- if (M < Min) Min = M;
- }
+void CompleteBUDataStructures::buildIndirectFunctionSets(Module &M) {
+ // Loop over all of the indirect calls in the program. If a call site can
+ // call multiple different functions, we need to unify all of the callees into
+ // the same equivalence class.
+ std::vector<const Instruction*> keys;
+ callee_get_keys(keys);
+
+ //mege nodes in the global graph for these functions
+ for (std::vector<const Instruction*>::iterator ii = keys.begin(), ee = keys.end();
+ ii != ee; ++ii) {
+ callee_iterator base = callee_begin(*ii);
+ for (callee_iterator csi = callee_begin(*ii), cse = callee_end(*ii);
+ csi != cse; ++csi) {
+ GlobalECs.unionSets(*base, *csi);
+ GlobalsGraph->getNodeForValue(*base).mergeWith(GlobalsGraph->getNodeForValue(*csi));
}
}
-
- assert(ValMap[&FG] == MyID && "SCC construction assumption wrong!");
- if (Min != MyID)
- return Min; // This is part of a larger SCC!
-
- // If this is a new SCC, process it now.
- bool IsMultiNodeSCC = false;
- while (Stack.back() != &FG) {
- DSGraph *NG = Stack.back();
- ValMap[NG] = ~0U;
-
- FG.cloneInto(*NG);
-
- // Update the DSInfo map and delete the old graph...
- for (DSGraph::retnodes_iterator I = NG->retnodes_begin();
- I != NG->retnodes_end(); ++I)
- setDSGraph(*I->first, &FG);
-
- // Remove NG from the ValMap since the pointer may get recycled.
- ValMap.erase(NG);
- delete NG;
-
- Stack.pop_back();
- IsMultiNodeSCC = true;
- }
-
- // Clean up the graph before we start inlining a bunch again...
- if (IsMultiNodeSCC)
- FG.removeTriviallyDeadNodes();
-
- Stack.pop_back();
- processGraph(FG);
- ValMap[&FG] = ~0U;
- return MyID;
-}
-
-
-/// processGraph - Process the BU graphs for the program in bottom-up order on
-/// the SCC of the __ACTUAL__ call graph. This builds "complete" BU graphs.
-void CompleteBUDataStructures::processGraph(DSGraph &G) {
- hash_set<Instruction*> calls;
-
- // The edges out of the current node are the call site targets...
- unsigned i = 0;
- for (DSGraph::fc_iterator CI = G.fc_begin(), CE = G.fc_end(); CI != CE;
- ++CI, ++i) {
- const DSCallSite &CS = *CI;
- Instruction *TheCall = CS.getCallSite().getInstruction();
-
- assert(calls.insert(TheCall).second &&
- "Call instruction occurs multiple times in graph??");
-
- // Fast path for noop calls. Note that we don't care about merging globals
- // in the callee with nodes in the caller here.
- if (CS.getRetVal().isNull() && CS.getNumPtrArgs() == 0)
- continue;
-
- // Loop over all of the potentially called functions...
- // Inline direct calls as well as indirect calls because the direct
- // callee may have indirect callees and so may have changed.
- //
- unsigned TNum = 0, Num = 0;
- DEBUG(Num = std::distance(callee_begin(TheCall), callee_end(TheCall)));
- for (callee_iterator I = callee_begin(TheCall), E = callee_end(TheCall);
- I != E; ++I, ++TNum) {
- const Function *CalleeFunc = *I;
- if (!CalleeFunc->isDeclaration()) {
- // Merge the callee's graph into this graph. This works for normal
- // calls or for self recursion within an SCC.
- DSGraph &GI = getOrCreateGraph(CalleeFunc);
- ++NumCBUInlines;
- G.mergeInGraph(CS, *CalleeFunc, GI,
- DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes |
- DSGraph::DontCloneAuxCallNodes);
- DOUT << " Inlining graph [" << i << "/"
- << G.getFunctionCalls().size()-1
- << ":" << TNum << "/" << Num-1 << "] for "
- << CalleeFunc->getName() << "["
- << GI.getGraphSize() << "+" << GI.getAuxFunctionCalls().size()
- << "] into '" /*<< G.getFunctionNames()*/ << "' ["
- << G.getGraphSize() << "+" << G.getAuxFunctionCalls().size()
- << "]\n";
- }
- }
- }
-
- // Recompute the Incomplete markers
- G.maskIncompleteMarkers();
- G.markIncompleteNodes(DSGraph::MarkFormalArgs);
-
- // Delete dead nodes. Treat globals that are unreachable but that can
- // reach live nodes as live.
- G.removeDeadNodes(DSGraph::KeepUnreachableGlobals);
}
Modified: poolalloc/trunk/lib/DSA/DataStructure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructure.cpp?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructure.cpp Sat Oct 11 11:52:04 2008
@@ -1607,7 +1607,7 @@
RHS.ReturnNodes.clear();
}
- // Merge the scalar map in.
+ // Merge the scalar map in.
ScalarMap.spliceFrom(RHS.ScalarMap);
}
@@ -1810,7 +1810,7 @@
HackedGraphSCCFinder SCCFinder(RC);
if (!(CloneFlags & DontCloneAuxCallNodes))
- for (afc_iterator I = Graph.afc_begin(), E = Graph.afc_end(); I!=E; ++I)
+ for (afc_const_iterator I = Graph.afc_begin(), E = Graph.afc_end(); I!=E; ++I)
if (SCCFinder.PathExistsToClonedNode(*I))
AuxCallToCopy.push_back(&*I);
// else if (I->isIndirectCall()){
@@ -2493,7 +2493,7 @@
AssertCallSiteInGraph(*I);
}
void DSGraph::AssertAuxCallNodesInGraph() const {
- for (afc_iterator I = afc_begin(), E = afc_end(); I != E; ++I)
+ for (afc_const_iterator I = afc_begin(), E = afc_end(); I != E; ++I)
AssertCallSiteInGraph(*I);
}
@@ -2840,14 +2840,16 @@
DEBUG(if(MadeChange) G.AssertGraphOK());
}
-void DataStructures::init(DataStructures* D, bool clone, bool printAuxCalls) {
+void DataStructures::init(DataStructures* D, bool clone, bool printAuxCalls,
+ bool copyGlobalAuxCalls) {
assert (!GraphSource && "Already init");
GraphSource = D;
Clone = clone;
TD = D->TD;
ActualCallees = D->ActualCallees;
GlobalECs = D->getGlobalECs();
- GlobalsGraph = new DSGraph(D->getGlobalsGraph(), GlobalECs);
+ GlobalsGraph = new DSGraph(D->getGlobalsGraph(), GlobalECs,
+ copyGlobalAuxCalls?0:DSGraph::DontCloneAuxCallNodes);
if (printAuxCalls) GlobalsGraph->setPrintAuxCalls();
}
Removed: poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp?rev=57374&view=auto
==============================================================================
--- poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp (original)
+++ poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp (removed)
@@ -1,427 +0,0 @@
-//===- EquivClassGraphs.cpp - Merge equiv-class graphs & inline bottom-up -===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass is the same as the complete bottom-up graphs, but
-// with functions partitioned into equivalence classes and a single merged
-// DS graph for all functions in an equivalence class. After this merging,
-// graphs are inlined bottom-up on the SCCs of the final (CBU) call graph.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "ECGraphs"
-#include "dsa/DataStructure.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
-#include "dsa/DSGraph.h"
-#include "llvm/Support/CallSite.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/ADT/SCCIterator.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/EquivalenceClasses.h"
-#include "llvm/ADT/STLExtras.h"
-using namespace llvm;
-
-namespace {
- RegisterPass<EquivClassGraphs> X("dsa-eq",
- "Equivalence-class Bottom-up Data Structure Analysis");
- STATISTIC (NumEquivBUInlines,
- "Number of graphs inlined");
- STATISTIC (NumFoldGraphInlines,
- "Number of graphs inlined");
-}
-
-char EquivClassGraphs::ID = 0;
-
-EquivClassGraphs::EquivClassGraphs() : DataStructures((intptr_t)&ID) {}
-
-#ifndef NDEBUG
-template<typename GT>
-static void CheckAllGraphs(Module *M, GT &ECGraphs) {
- for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
- if (!I->isDeclaration()) {
- DSGraph &G = ECGraphs.getDSGraph(*I);
- if (G.retnodes_begin()->first != I)
- continue; // Only check a graph once.
-
- DSGraph::NodeMapTy GlobalsGraphNodeMapping;
- G.computeGToGGMapping(GlobalsGraphNodeMapping);
- }
-}
-#endif
-
-// getSomeCalleeForCallSite - Return any one callee function at a call site.
-//
-const Function *EquivClassGraphs::getSomeCalleeForCallSite(const CallSite &CS) const{
- Function *thisFunc = CS.getCaller();
- assert(thisFunc && "getSomeCalleeForCallSite(): Not a valid call site?");
- DSGraph &DSG = getDSGraph(*thisFunc);
- DSNode *calleeNode = DSG.getNodeForValue(CS.getCalledValue()).getNode();
- std::map<DSNode*, const Function *>::const_iterator I =
- OneCalledFunction.find(calleeNode);
- return (I == OneCalledFunction.end())? NULL : I->second;
-}
-
-// runOnModule - Calculate the bottom up data structure graphs for each function
-// in the program.
-//
-bool EquivClassGraphs::runOnModule(Module &M) {
- init(&getAnalysis<CompleteBUDataStructures>(), false, true);
-
- // Find equivalence classes of functions called from common call sites.
- // Fold the CBU graphs for all functions in an equivalence class.
- buildIndirectFunctionSets(M);
-
- // Stack of functions used for Tarjan's SCC-finding algorithm.
- std::vector<DSGraph*> Stack;
- std::map<DSGraph*, unsigned> ValMap;
- unsigned NextID = 1;
-
- const Function *MainFunc = M.getFunction("main");
- if (MainFunc && !MainFunc->isDeclaration()) {
- processSCC(getOrCreateGraph(MainFunc), Stack, NextID, ValMap);
- } else {
- cerr << "Fold Graphs: No 'main' function found!\n";
- }
-
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
- if (!I->isDeclaration())
- processSCC(getOrCreateGraph(I), Stack, NextID, ValMap);
-
- DEBUG(CheckAllGraphs(&M, *this));
-
- getGlobalsGraph().removeTriviallyDeadNodes();
- getGlobalsGraph().markIncompleteNodes(DSGraph::IgnoreGlobals);
-
- // Merge the globals variables (not the calls) from the globals graph back
- // into the main function's graph so that the main function contains all of
- // the information about global pools and GV usage in the program.
- if (MainFunc && !MainFunc->isDeclaration()) {
- DSGraph &MainGraph = getOrCreateGraph(MainFunc);
- const DSGraph &GG = *MainGraph.getGlobalsGraph();
- ReachabilityCloner RC(MainGraph, GG,
- DSGraph::DontCloneCallNodes |
- DSGraph::DontCloneAuxCallNodes);
-
- // Clone the global nodes into this graph.
- for (DSScalarMap::global_iterator I = GG.getScalarMap().global_begin(),
- E = GG.getScalarMap().global_end(); I != E; ++I)
- if (isa<GlobalVariable>(*I))
- RC.getClonedNH(GG.getNodeForValue(*I));
-
- MainGraph.maskIncompleteMarkers();
- MainGraph.markIncompleteNodes(DSGraph::MarkFormalArgs |
- DSGraph::IgnoreGlobals);
- }
-
- // Final processing. Note that dead node elimination may actually remove
- // globals from a function graph that are immediately used. If there are no
- // scalars pointing to the node (e.g. because the only use is a direct store
- // to a scalar global) we have to make sure to rematerialize the globals back
- // into the graphs here, or clients will break!
- for (Module::global_iterator GI = M.global_begin(), E = M.global_end();
- GI != E; ++GI)
- // This only happens to first class typed globals.
- if (GI->getType()->getElementType()->isFirstClassType())
- for (Value::use_iterator UI = GI->use_begin(), E = GI->use_end();
- UI != E; ++UI)
- // This only happens to direct uses by instructions.
- if (Instruction *User = dyn_cast<Instruction>(*UI)) {
- DSGraph &DSG = getOrCreateGraph(User->getParent()->getParent());
- if (!DSG.getScalarMap().count(GI)) {
- // If this global does not exist in the graph, but it is immediately
- // used by an instruction in the graph, clone it over from the
- // globals graph.
- ReachabilityCloner RC(DSG, *GlobalsGraph, 0);
- RC.getClonedNH(GlobalsGraph->getNodeForValue(GI));
- }
- }
-
- return false;
-}
-
-
-// buildIndirectFunctionSets - Iterate over the module looking for indirect
-// calls to functions. If a call site can invoke any functions [F1, F2... FN],
-// unify the N functions together in the FuncECs set.
-//
-void EquivClassGraphs::buildIndirectFunctionSets(Module &M) {
- // Loop over all of the indirect calls in the program. If a call site can
- // call multiple different functions, we need to unify all of the callees into
- // the same equivalence class.
- std::vector<const Instruction*> keys;
- callee_get_keys(keys);
-
- for (std::vector<const Instruction*>::iterator ii = keys.begin(), ee = keys.end();
- ii != ee; ++ii) {
- const Function* F = 0;
- for (callee_iterator csi = callee_begin(*ii), cse = callee_end(*ii);
- csi != cse; ++csi) {
- if (F != *csi) {
- F = *csi;
- FuncECs.insert(*csi);
- const Function *thisFunc = (*ii)->getParent()->getParent();
- DSGraph &TFG = getOrCreateGraph(thisFunc);
- DSNode *calleeNode = TFG.getNodeForValue((*ii)->getOperand(0)).getNode();
- OneCalledFunction[calleeNode] = *csi;
- } else {
- FuncECs.unionSets(*csi, F);
- }
- }
-
- // Now include all functions that share a graph with any function in the
- // equivalence class. More precisely, if F is in the class, and G(F) is
- // its graph, then we include all other functions that are also in G(F).
- // Currently, that is just the functions in the same call-graph-SCC as F.
- //
- DSGraph& funcDSGraph = getOrCreateGraph(F);
- for (DSGraph::retnodes_iterator RI = funcDSGraph.retnodes_begin(),
- RE = funcDSGraph.retnodes_end(); RI != RE; ++RI)
- FuncECs.unionSets(F, RI->first);
- }
-
- // Now that all of the equivalences have been built, merge the graphs for
- // each equivalence class.
- //
- DOUT << "\nIndirect Function Equivalence Sets:\n";
- for (EquivalenceClasses<const Function*>::iterator EQSI = FuncECs.begin(), E =
- FuncECs.end(); EQSI != E; ++EQSI) {
- if (!EQSI->isLeader()) continue;
-
- EquivalenceClasses<const Function*>::member_iterator SI =
- FuncECs.member_begin(EQSI);
- assert(SI != FuncECs.member_end() && "Empty equiv set??");
- EquivalenceClasses<const Function*>::member_iterator SN = SI;
- ++SN;
- if (SN == FuncECs.member_end())
- continue; // Single function equivalence set, no merging to do.
-
- const Function* LF = *SI;
-
-#ifndef NDEBUG
- DOUT <<" Equivalence set for leader " << LF->getName() <<" = ";
- for (SN = SI; SN != FuncECs.member_end(); ++SN)
- DOUT << " " << (*SN)->getName() << "," ;
- DOUT << "\n";
-#endif
-
- // This equiv class has multiple functions: merge their graphs. First,
- // clone the CBU graph for the leader and make it the common graph for the
- // equivalence graph.
- DSGraph &MergedG = getOrCreateGraph(LF);
-
- // Record the argument nodes for use in merging later below.
- std::vector<DSNodeHandle> ArgNodes;
-
- for (Function::const_arg_iterator AI = LF->arg_begin(), E = LF->arg_end();
- AI != E; ++AI)
- if (DS::isPointerType(AI->getType()))
- ArgNodes.push_back(MergedG.getNodeForValue(AI));
-
- // Merge in the graphs of all other functions in this equiv. class. Note
- // that two or more functions may have the same graph, and it only needs
- // to be merged in once.
- std::set<DSGraph*> GraphsMerged;
- GraphsMerged.insert(&getOrCreateGraph(LF));
-
- for (++SI; SI != FuncECs.member_end(); ++SI) {
- const Function *F = *SI;
- DSGraph &CBUGraph = getOrCreateGraph(F);
- if (GraphsMerged.insert(&CBUGraph).second) {
- // Record the "folded" graph for the function.
- for (DSGraph::retnodes_iterator I = CBUGraph.retnodes_begin(),
- E = CBUGraph.retnodes_end(); I != E; ++I)
- setDSGraph(*I->first, &MergedG);
-
- // Clone this member of the equivalence class into MergedG.
- MergedG.cloneInto(CBUGraph);
- }
-
- // Merge the return nodes of all functions together.
- MergedG.getReturnNodes()[LF].mergeWith(MergedG.getReturnNodes()[F]);
-
- // Merge the function arguments with all argument nodes found so far.
- // If there are extra function args, add them to the vector of argNodes
- Function::const_arg_iterator AI2 = F->arg_begin(), AI2end = F->arg_end();
- for (unsigned arg = 0, numArgs = ArgNodes.size();
- arg != numArgs && AI2 != AI2end; ++AI2, ++arg)
- if (DS::isPointerType(AI2->getType()))
- ArgNodes[arg].mergeWith(MergedG.getNodeForValue(AI2));
-
- for ( ; AI2 != AI2end; ++AI2)
- if (DS::isPointerType(AI2->getType()))
- ArgNodes.push_back(MergedG.getNodeForValue(AI2));
- DEBUG(MergedG.AssertGraphOK());
- }
- }
- DOUT << "\n";
-}
-
-
-unsigned EquivClassGraphs::
-processSCC(DSGraph &FG, std::vector<DSGraph*> &Stack, unsigned &NextID,
- std::map<DSGraph*, unsigned> &ValMap) {
- std::map<DSGraph*, unsigned>::iterator It = ValMap.lower_bound(&FG);
- if (It != ValMap.end() && It->first == &FG)
- return It->second;
-
- DOUT << " ProcessSCC for function " << FG.getFunctionNames() << "\n";
-
- unsigned Min = NextID++, MyID = Min;
- ValMap[&FG] = Min;
- Stack.push_back(&FG);
-
- // The edges out of the current node are the call site targets...
- for (DSGraph::fc_iterator CI = FG.fc_begin(), CE = FG.fc_end();
- CI != CE; ++CI) {
- Instruction *Call = CI->getCallSite().getInstruction();
-
- // Loop over all of the actually called functions...
- for (callee_iterator I = callee_begin(Call), E = callee_end(Call);
- I != E; ++I)
- if (!(*I)->isDeclaration()) {
- // Process the callee as necessary.
- unsigned M = processSCC(getOrCreateGraph(*I),
- Stack, NextID, ValMap);
- if (M < Min) Min = M;
- }
- }
-
- assert(ValMap[&FG] == MyID && "SCC construction assumption wrong!");
- if (Min != MyID)
- return Min; // This is part of a larger SCC!
-
- // If this is a new SCC, process it now.
- bool MergedGraphs = false;
- while (Stack.back() != &FG) {
- DSGraph *NG = Stack.back();
- ValMap[NG] = ~0U;
-
- // If the SCC found is not the same as those found in CBU, make sure to
- // merge the graphs as appropriate.
- FG.cloneInto(*NG);
-
- // Update the DSInfo map and delete the old graph...
- for (DSGraph::retnodes_iterator I = NG->retnodes_begin();
- I != NG->retnodes_end(); ++I)
- setDSGraph(*I->first, &FG);
-
- // Remove NG from the ValMap since the pointer may get recycled.
- ValMap.erase(NG);
- delete NG;
- MergedGraphs = true;
- Stack.pop_back();
- }
-
- // Clean up the graph before we start inlining a bunch again.
- if (MergedGraphs)
- FG.removeTriviallyDeadNodes();
-
- Stack.pop_back();
-
- processGraph(FG);
- ValMap[&FG] = ~0U;
- return MyID;
-}
-
-
-/// processGraph - Process the CBU graphs for the program in bottom-up order on
-/// the SCC of the __ACTUAL__ call graph. This builds final folded CBU graphs.
-void EquivClassGraphs::processGraph(DSGraph &G) {
- DOUT << " ProcessGraph for function " << G.getFunctionNames() << "\n";
-
- hash_set<Instruction*> calls;
-
- // Else we need to inline some callee graph. Visit all call sites.
- // The edges out of the current node are the call site targets...
- unsigned i = 0;
- for (DSGraph::fc_iterator CI = G.fc_begin(), CE = G.fc_end(); CI != CE;
- ++CI, ++i) {
- const DSCallSite &CS = *CI;
- Instruction *TheCall = CS.getCallSite().getInstruction();
-
- assert(calls.insert(TheCall).second &&
- "Call instruction occurs multiple times in graph??");
-
- if (CS.getRetVal().isNull() && CS.getNumPtrArgs() == 0)
- continue;
-
- // Inline the common callee graph into the current graph, if the callee
- // graph has not changed. Note that all callees should have the same
- // graph so we only need to do this once.
- //
- DSGraph* CalleeGraph = NULL;
- callee_iterator I = callee_begin(TheCall), E = callee_end(TheCall);
- unsigned TNum, Num;
-
- // Loop over all potential callees to find the first non-external callee.
- for (TNum = 0, Num = std::distance(I, E); I != E; ++I, ++TNum)
- if (!(*I)->isDeclaration())
- break;
-
- // Now check if the graph has changed and if so, clone and inline it.
- if (I != E) {
- const Function *CalleeFunc = *I;
-
- // Merge the callee's graph into this graph, if not already the same.
- // Callees in the same equivalence class (which subsumes those
- // in the same SCCs) have the same graph. Note that all recursion
- // including self-recursion have been folded in the equiv classes.
- //
- CalleeGraph = &getOrCreateGraph(CalleeFunc);
- if (CalleeGraph != &G) {
- ++NumFoldGraphInlines;
- G.mergeInGraph(CS, *CalleeFunc, *CalleeGraph,
- DSGraph::StripAllocaBit |
- DSGraph::DontCloneCallNodes |
- DSGraph::DontCloneAuxCallNodes);
- DOUT << " Inlining graph [" << i << "/"
- << G.getFunctionCalls().size()-1
- << ":" << TNum << "/" << Num-1 << "] for "
- << CalleeFunc->getName() << "["
- << CalleeGraph->getGraphSize() << "+"
- << CalleeGraph->getAuxFunctionCalls().size()
- << "] into '" /*<< G.getFunctionNames()*/ << "' ["
- << G.getGraphSize() << "+" << G.getAuxFunctionCalls().size()
- << "]\n";
- }
- }
-
-#ifndef NDEBUG
- // Now loop over the rest of the callees and make sure they have the
- // same graph as the one inlined above.
- if (CalleeGraph)
- for (++I, ++TNum; I != E; ++I, ++TNum)
- if (!(*I)->isDeclaration())
- assert(CalleeGraph == &getOrCreateGraph(*I) &&
- "Callees at a call site have different graphs?");
-#endif
- }
-
- // Recompute the Incomplete markers.
- G.maskIncompleteMarkers();
- G.markIncompleteNodes(DSGraph::MarkFormalArgs);
-
- // Delete dead nodes. Treat globals that are unreachable but that can
- // reach live nodes as live.
- G.removeDeadNodes(DSGraph::KeepUnreachableGlobals);
-
- // When this graph is finalized, clone the globals in the graph into the
- // globals graph to make sure it has everything, from all graphs.
- ReachabilityCloner RC(*G.getGlobalsGraph(), G, DSGraph::StripAllocaBit);
-
- // Clone everything reachable from globals in the function graph into the
- // globals graph.
- DSScalarMap &MainSM = G.getScalarMap();
- for (DSScalarMap::global_iterator I = MainSM.global_begin(),
- E = MainSM.global_end(); I != E; ++I)
- RC.getClonedNH(MainSM[*I]);
-
- DOUT << " -- DONE ProcessGraph for function " << G.getFunctionNames() <<"\n";
-}
Modified: poolalloc/trunk/lib/DSA/Printer.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Printer.cpp?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Printer.cpp (original)
+++ poolalloc/trunk/lib/DSA/Printer.cpp Sat Oct 11 11:52:04 2008
@@ -358,10 +358,3 @@
if (DontPrintAnything) return;
printCollection(*this, O, M, "cbu.");
}
-
-
-void EquivClassGraphs::print(std::ostream &O, const Module *M) const {
- if (DontPrintAnything) return;
- printCollection(*this, O, M, "eq.");
-}
-
Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/StdLibPass.cpp?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original)
+++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Sat Oct 11 11:52:04 2008
@@ -164,7 +164,7 @@
}
bool StdLibDataStructures::runOnModule(Module &M) {
- init(&getAnalysis<LocalDataStructures>(), false, true);
+ init(&getAnalysis<LocalDataStructures>(), false, true, false);
//Clone Module
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
Modified: poolalloc/trunk/lib/DSA/TopDownClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/TopDownClosure.cpp?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/TopDownClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/TopDownClosure.cpp Sat Oct 11 11:52:04 2008
@@ -61,7 +61,7 @@
// program.
//
bool TDDataStructures::runOnModule(Module &M) {
- init(&getAnalysis<BUDataStructures>(), true, true);
+ init(&getAnalysis<BUDataStructures>(), true, true, true);
// Figure out which functions must not mark their arguments complete because
// they are accessible outside this compilation unit. Currently, these
Modified: poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp Sat Oct 11 11:52:04 2008
@@ -27,7 +27,7 @@
/// descriptor loaded from.
class PoolAccessTrace : public ModulePass {
PoolAllocate *PoolAlloc;
- EquivClassGraphs *ECG;
+ DataStructures *G;
Constant *AccessTraceInitFn, *PoolAccessTraceFn;
const Type *VoidPtrTy;
public:
@@ -39,7 +39,7 @@
void getAnalysisUsage(AnalysisUsage &AU) const;
const DSGraph &getGraphForFunc(PA::FuncInfo *FI) const {
- return ECG->getDSGraph(FI->F);
+ return G->getDSGraph(FI->F);
}
static char ID;
@@ -59,7 +59,7 @@
AU.addRequired<PoolAllocatePassAllPools>();
// Need information from DSA.
- AU.addRequired<EquivClassGraphs>();
+ AU.addRequired<CompleteBUDataStructures>();
}
void PoolAccessTrace::InitializeLibraryFunctions(Module &M) {
@@ -100,7 +100,7 @@
bool PoolAccessTrace::runOnModule(Module &M) {
PoolAlloc = &getAnalysis<PoolAllocatePassAllPools>();
- ECG = &getAnalysis<EquivClassGraphs>();
+ G = &getAnalysis<CompleteBUDataStructures>();
// Create the function prototypes for runtime library.
InitializeLibraryFunctions(M);
@@ -124,7 +124,7 @@
continue;
// Get the DSGraph for this function.
- DSGraph &DSG = ECG->getDSGraph(FI->F);
+ DSGraph &DSG = G->getDSGraph(FI->F);
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
Modified: poolalloc/trunk/lib/PoolAllocate/PASimple.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PASimple.cpp?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PASimple.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PASimple.cpp Sat Oct 11 11:52:04 2008
@@ -73,9 +73,9 @@
void PoolAllocateSimple::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<TargetData>();
- AU.addRequiredTransitive<EquivClassGraphs>();
+ AU.addRequiredTransitive<CompleteBUDataStructures>();
- AU.addPreserved<EquivClassGraphs>();
+ AU.addPreserved<CompleteBUDataStructures>();
AU.setPreservesAll();
}
@@ -100,9 +100,9 @@
bool PoolAllocateSimple::runOnModule(Module &M) {
if (M.begin() == M.end()) return false;
- // Get the Target Data information and the ECGraphs
- ECGraphs = &getAnalysis<EquivClassGraphs>(); // folded inlined CBU graphs
- assert (ECGraphs && "No ECGraphs pass available!\n");
+ // Get the Target Data information and the Graphs
+ Graphs = &getAnalysis<CompleteBUDataStructures>(); // folded inlined CBU graphs
+ assert (Graphs && "No ECGraphs pass available!\n");
TargetData & TD = getAnalysis<TargetData>();
// Add the pool* prototypes to the module
@@ -120,14 +120,14 @@
//
// Merge all of the DSNodes in the DSGraphs.
//
- GlobalECs = ECGraphs->getGlobalECs();
- CombinedDSGraph = new DSGraph (GlobalECs, TD, &(ECGraphs->getGlobalsGraph()));
+ GlobalECs = Graphs->getGlobalECs();
+ CombinedDSGraph = new DSGraph (GlobalECs, TD, &(Graphs->getGlobalsGraph()));
//CombinedDSGraph.cloneInto (getGlobalsGraph());
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
- if (ECGraphs->hasDSGraph (*I))
- CombinedDSGraph->cloneInto (ECGraphs->getDSGraph(*I));
+ if (Graphs->hasDSGraph (*I))
+ CombinedDSGraph->cloneInto (Graphs->getDSGraph(*I));
}
- CombinedDSGraph->cloneInto (ECGraphs->getGlobalsGraph());
+ CombinedDSGraph->cloneInto (Graphs->getGlobalsGraph());
MergeNodesInDSGraph (*CombinedDSGraph);
//
@@ -161,7 +161,7 @@
//
// Get the DSGraph for this function.
//
- DSGraph &ECG = ECGraphs->getDSGraph(F);
+ DSGraph &ECG = Graphs->getDSGraph(F);
for (Function::iterator i = F.begin(), e = F.end(); i != e; ++i)
for (BasicBlock::iterator ii = i->begin(), ee = i->end(); ii != ee; ++ii) {
Modified: poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp Sat Oct 11 11:52:04 2008
@@ -95,7 +95,7 @@
/// data structures to reduce the size of pointers in the program.
class PointerCompress : public ModulePass {
PoolAllocate *PoolAlloc;
- EquivClassGraphs *ECG;
+ CompleteBUDataStructures *ECG;
/// ClonedFunctionMap - Every time we clone a function to compress its
/// arguments, keep track of the clone and which arguments are compressed.
@@ -918,7 +918,7 @@
void InstructionRewriter::visitCallInst(CallInst &CI) {
- if (Function *F = CI.getCalledFunction())
+ if (Function *F = CI.getCalledFunction()) {
// These functions are handled specially.
if (F->getName() == "poolinit") {
visitPoolInit(CI);
@@ -930,7 +930,8 @@
visitPoolAlloc(CI);
return;
}
-
+ }
+
// Normal function call: check to see if this call produces or uses a pointer
// into a compressed pool. If so, we will need to transform the callee or use
// a previously transformed version.
@@ -1136,7 +1137,7 @@
AU.addRequired<PoolAllocatePassAllPools>();
// Need information from DSA.
- AU.addRequired<EquivClassGraphs>();
+ AU.addRequired<CompleteBUDataStructures>();
}
/// PoolIsCompressible - Return true if we can pointer compress this node.
@@ -1190,7 +1191,7 @@
// Ignore potential pools that the pool allocation heuristic decided not to
// pool allocated.
- if (!isa<ConstantPointerNull>(FI->PoolDescriptors[N]))
+ if (!isa<ConstantPointerNull>(FI->PoolDescriptors[N])) {
if (PoolIsCompressible(N)) {
Pools.insert(N);
++NumCompressed;
@@ -1198,6 +1199,7 @@
DEBUG(std::cerr << "PCF: "; N->dump());
++NumNotCompressed;
}
+ }
}
// If there are no compressed global pools, don't bother to look for them.
@@ -1482,7 +1484,7 @@
// Ignore potential pools that the pool allocation heuristic decided not to
// pool allocated.
- if (!isa<ConstantPointerNull>(I->second))
+ if (!isa<ConstantPointerNull>(I->second)) {
if (PoolIsCompressible(N)) {
CompressedGlobalPools.insert(std::make_pair(N,
cast<GlobalValue>(I->second)));
@@ -1491,6 +1493,7 @@
DEBUG(std::cerr << "PCF: "; N->dump());
++NumNotCompressed;
}
+ }
}
}
@@ -1512,7 +1515,7 @@
bool PointerCompress::runOnModule(Module &M) {
PoolAlloc = &getAnalysis<PoolAllocatePassAllPools>();
- ECG = &getAnalysis<EquivClassGraphs>();
+ ECG = &getAnalysis<CompleteBUDataStructures>();
if (SmallIntCompress)
MEMUINTTYPE = Type::Int16Ty;
Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Sat Oct 11 11:52:04 2008
@@ -85,35 +85,26 @@
DisablePoolFreeOpt("poolalloc-force-all-poolfrees",
cl::desc("Do not try to elide poolfree's where possible"));
- cl::opt<bool>
- UseTDResolve("poolalloc-usetd-resolve",
- cl::desc("Use Top-Down Graph as a resolve source"));
}
void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequiredTransitive<EquivClassGraphs>();
- AU.addPreserved<EquivClassGraphs>();
+ AU.addRequiredTransitive<CompleteBUDataStructures>();
+ AU.addPreserved<CompleteBUDataStructures>();
// Preserve the pool information across passes
if (SAFECodeEnabled)
AU.setPreservesAll();
AU.addRequired<TargetData>();
- if (UseTDResolve)
- AU.addRequired<CallTargetFinder>();
}
bool PoolAllocate::runOnModule(Module &M) {
if (M.begin() == M.end()) return false;
CurModule = &M;
- ECGraphs = &getAnalysis<EquivClassGraphs>(); // folded inlined CBU graphs
- if (UseTDResolve)
- CTF = &getAnalysis<CallTargetFinder>();
- else
- CTF = 0;
+ Graphs = &getAnalysis<CompleteBUDataStructures>(); // folded inlined CBU graphs
CurHeuristic = Heuristic::create();
- CurHeuristic->Initialize(M, ECGraphs->getGlobalsGraph(), *this);
+ CurHeuristic->Initialize(M, Graphs->getGlobalsGraph(), *this);
// Add the pool* prototypes to the module
AddPoolPrototypes(&M);
@@ -125,7 +116,7 @@
// Loop over the functions in the original program finding the pool desc.
// arguments necessary for each function that is indirectly callable.
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
- if (!I->isDeclaration() && ECGraphs->hasDSGraph(*I))
+ if (!I->isDeclaration() && Graphs->hasDSGraph(*I))
FindFunctionPoolArgs(*I);
std::map<Function*, Function*> FuncMap;
@@ -138,7 +129,7 @@
{TIME_REGION(X, "MakeFunctionClone");
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isDeclaration() && !ClonedFunctions.count(I) &&
- ECGraphs->hasDSGraph(*I))
+ Graphs->hasDSGraph(*I))
if (Function *Clone = MakeFunctionClone(*I)) {
FuncMap[I] = Clone;
ClonedFunctions.insert(Clone);
@@ -150,7 +141,7 @@
{TIME_REGION(X, "ProcessFunctionBody");
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isDeclaration() && !ClonedFunctions.count(I) &&
- ECGraphs->hasDSGraph(*I)) {
+ Graphs->hasDSGraph(*I)) {
std::map<Function*, Function*>::iterator FI = FuncMap.find(I);
ProcessFunctionBody(*I, FI != FuncMap.end() ? *FI->second : *I);
}
@@ -344,7 +335,7 @@
/// arguments will have to be added for each function, build the FunctionInfo
/// map and recording this info in the ArgNodes set.
void PoolAllocate::FindFunctionPoolArgs(Function &F) {
- DSGraph &G = ECGraphs->getDSGraph(F);
+ DSGraph &G = Graphs->getDSGraph(F);
// Create a new entry for F.
FuncInfo &FI =
@@ -367,7 +358,7 @@
// necessary, and return it. If not, just return null.
//
Function *PoolAllocate::MakeFunctionClone(Function &F) {
- DSGraph &G = ECGraphs->getDSGraph(F);
+ DSGraph &G = Graphs->getDSGraph(F);
if (G.node_begin() == G.node_end()) return 0;
FuncInfo &FI = *getFuncInfo(F);
@@ -472,7 +463,7 @@
//
bool PoolAllocate::SetupGlobalPools(Module &M) {
// Get the globals graph for the program.
- DSGraph &GG = ECGraphs->getGlobalsGraph();
+ DSGraph &GG = Graphs->getGlobalsGraph();
// Get all of the nodes reachable from globals.
hash_set<const DSNode*> GlobalHeapNodes;
@@ -558,7 +549,7 @@
CurModule);
// Update the global DSGraph to include this.
- DSNode *GNode = ECGraphs->getGlobalsGraph().addObjectToGraph(GV);
+ DSNode *GNode = Graphs->getGlobalsGraph().addObjectToGraph(GV);
GNode->setModifiedMarker()->setReadMarker();
Function *MainFunc = CurModule->getFunction("main");
@@ -648,7 +639,7 @@
// the specified function.
//
void PoolAllocate::ProcessFunctionBody(Function &F, Function &NewF) {
- DSGraph &G = ECGraphs->getDSGraph(F);
+ DSGraph &G = Graphs->getDSGraph(F);
if (G.node_begin() == G.node_end()) return; // Quick exit if nothing to do.
@@ -658,7 +649,7 @@
// Calculate which DSNodes are reachable from globals. If a node is reachable
// from a global, we will create a global pool for it, so no argument passage
// is required.
- ECGraphs->getGlobalsGraph();
+ Graphs->getGlobalsGraph();
// Map all node reachable from this global to the corresponding nodes in
// the globals graph.
@@ -670,7 +661,7 @@
for (DSGraph::node_iterator I = G.node_begin(), E = G.node_end(); I != E;++I){
// We only need to make a pool if there is a heap object in it...
DSNode *N = I;
- if ((N->isHeapNode()) || (BoundsChecksEnabled && (N->isArray())))
+ if ((N->isHeapNode()) || (BoundsChecksEnabled && (N->isArray()))) {
if (GlobalsGraphNodeMapping.count(N)) {
// If it is a global pool, set up the pool descriptor appropriately.
DSNode *GGN = GlobalsGraphNodeMapping[N].getNode();
@@ -682,6 +673,7 @@
assert(!N->isGlobalNode() && "Should be in global mapping!");
FI.NodesToPA.push_back(N);
}
+ }
}
if (!FI.NodesToPA.empty()) {
Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp?rev=57375&r1=57374&r2=57375&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Sat Oct 11 11:52:04 2008
@@ -556,7 +556,7 @@
// If this function is one of the memory manipulating functions built into
// libc, emulate it with pool calls as appropriate.
- if (CF && CF->isDeclaration())
+ if (CF && CF->isDeclaration()) {
if (CF->getName() == "calloc") {
visitCallocCall(CS);
return;
@@ -576,6 +576,7 @@
std::cerr << "VALLOC USED BUT NOT HANDLED!\n";
abort();
}
+ }
// We need to figure out which local pool descriptors correspond to the pool
// descriptor arguments passed into the function call. Calculate a mapping
@@ -583,7 +584,7 @@
// between the graphs to figure out which pool descriptors need to be passed
// in. The roots of this mapping is found from arguments and return values.
//
- EquivClassGraphs& ECGraphs = PAInfo.getECGraphs();
+ DataStructures& Graphs = PAInfo.getGraphs();
DSGraph::NodeMapTy NodeMapping;
Instruction *NewCall;
Value *NewCallee;
@@ -602,8 +603,8 @@
NewCallee = CFI->Clone;
ArgNodes = CFI->ArgNodes;
- assert ((ECGraphs.hasDSGraph (*CF)) && "Function has no ECGraph!\n");
- CalleeGraph = &ECGraphs.getDSGraph(*CF);
+ assert ((Graphs.hasDSGraph (*CF)) && "Function has no ECGraph!\n");
+ CalleeGraph = &Graphs.getDSGraph(*CF);
} else {
DEBUG(std::cerr << " Handling indirect call: " << *TheCall);
@@ -614,28 +615,24 @@
// in CS back to the original call instruction.)
Instruction *OrigInst =
cast<Instruction>(getOldValueIfAvailable(CS.getInstruction()));
- CF = isa<CallInst>(OrigInst)?
- ECGraphs.getSomeCalleeForCallSite(cast<CallInst>(OrigInst)) :
- ECGraphs.getSomeCalleeForCallSite(cast<InvokeInst>(OrigInst));
-
- if (!CF)
- for (EquivClassGraphs::callee_iterator I = ECGraphs.callee_begin(OrigInst),
- E = ECGraphs.callee_end(OrigInst); I != E; ++I) {
- CF = *I;
- break;
- }
+
+ for (DataStructures::callee_iterator I = Graphs.callee_begin(OrigInst),
+ E = Graphs.callee_end(OrigInst); I != E; ++I) {
+ CF = *I;
+ break;
+ }
// If we didn't find the callee in the constructed call graph, try
// checking in the DSNode itself.
// This isn't ideal as it means that this call site didn't have inlining
// happen.
if (!CF) {
- DSGraph* dg = &ECGraphs.getDSGraph(*OrigInst->getParent()->getParent());
+ DSGraph* dg = &Graphs.getDSGraph(*OrigInst->getParent()->getParent());
DSNode* d = dg->getNodeForValue(OrigInst->getOperand(0)).getNode();
const std::vector<const GlobalValue*> &g = d->getGlobalsList();
for(std::vector<const GlobalValue*>::const_iterator ii = g.begin(), ee = g.end();
!CF && ii != ee; ++ii) {
- EquivalenceClasses< const GlobalValue *> & EC = ECGraphs.getGlobalECs();
+ EquivalenceClasses< const GlobalValue *> & EC = Graphs.getGlobalECs();
for (EquivalenceClasses<const GlobalValue *>::member_iterator MI = EC.findLeader(*ii);
MI != EC.member_end(); ++MI) // Loop over members in this set.
if ((CF = dyn_cast<Function>(*MI))) {
@@ -664,15 +661,15 @@
}
// Get the common graph for the set of functions this call may invoke.
- CalleeGraph = &ECGraphs.getDSGraph(*CF);
+ CalleeGraph = &Graphs.getDSGraph(*CF);
#ifndef NDEBUG
// Verify that all potential callees at call site have the same DS graph.
- EquivClassGraphs::callee_iterator I =
- ECGraphs.callee_begin(OrigInst), E = ECGraphs.callee_end(OrigInst);
+ DataStructures::callee_iterator I =
+ Graphs.callee_begin(OrigInst), E = Graphs.callee_end(OrigInst);
for (; I != E; ++I)
if (!(*I)->isDeclaration())
- assert(CalleeGraph == &ECGraphs.getDSGraph(**I) &&
+ assert(CalleeGraph == &Graphs.getDSGraph(**I) &&
"Callees at call site do not have a common graph!");
#endif
More information about the llvm-commits
mailing list