[llvm-commits] [poolalloc] r57319 - in /poolalloc/trunk/lib: DSA/BottomUpClosure.cpp DSA/CallTargets.cpp DSA/CompleteBottomUp.cpp DSA/DataStructure.cpp DSA/DataStructureStats.cpp DSA/EquivClassGraphs.cpp DSA/Local.cpp DSA/Printer.cpp DSA/StdLibPass.cpp DSA/Steensgaard.cpp DSA/TopDownClosure.cpp PoolAllocate/PoolAllocate.cpp PoolAllocate/TransformFunctionBody.cpp
Andrew Lenharth
alenhar2 at cs.uiuc.edu
Wed Oct 8 23:24:33 PDT 2008
Author: alenhar2
Date: Thu Oct 9 01:24:31 2008
New Revision: 57319
URL: http://llvm.org/viewvc/llvm-project?rev=57319&view=rev
Log:
simplify and unify code. EQ pass may be broken
Modified:
poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
poolalloc/trunk/lib/DSA/CallTargets.cpp
poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp
poolalloc/trunk/lib/DSA/DataStructure.cpp
poolalloc/trunk/lib/DSA/DataStructureStats.cpp
poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp
poolalloc/trunk/lib/DSA/Local.cpp
poolalloc/trunk/lib/DSA/Printer.cpp
poolalloc/trunk/lib/DSA/StdLibPass.cpp
poolalloc/trunk/lib/DSA/Steensgaard.cpp
poolalloc/trunk/lib/DSA/TopDownClosure.cpp
poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp
Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=57319&r1=57318&r2=57319&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Thu Oct 9 01:24:31 2008
@@ -14,7 +14,7 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "bu_dsa"
+#define DEBUG_TYPE "dsa-bu"
#include "dsa/DataStructure.h"
#include "dsa/DSGraph.h"
#include "llvm/Module.h"
@@ -40,17 +40,10 @@
// program.
//
bool BUDataStructures::runOnModule(Module &M) {
- StdLibDataStructures &LocalDSA = getAnalysis<StdLibDataStructures>();
- setGraphSource(&LocalDSA);
- setTargetData(LocalDSA.getTargetData());
- setGraphClone(false);
- GlobalECs = LocalDSA.getGlobalECs();
+ init(&getAnalysis<StdLibDataStructures>(), false, true);
- GlobalsGraph = new DSGraph(LocalDSA.getGlobalsGraph(), GlobalECs);
- GlobalsGraph->setPrintAuxCalls();
-
- std::vector<Function*> Stack;
- hash_map<Function*, unsigned> ValMap;
+ std::vector<const Function*> Stack;
+ hash_map<const Function*, unsigned> ValMap;
unsigned NextID = 1;
Function *MainFunc = M.getFunction("main");
@@ -61,7 +54,7 @@
// 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() && !DSInfo.count(I)) {
+ if (!I->isDeclaration() && !hasDSGraph(*I)) {
if (MainFunc)
DOUT << "*** BU: Function unreachable from main: "
<< I->getName() << "\n";
@@ -69,14 +62,8 @@
CloneAuxIntoGlobal(getDSGraph(*I));
}
- //Be sure to get the all unresolved call sites
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
- if (!I->isDeclaration() && InlinedSomewhere.find(I) == InlinedSomewhere.end())
- CloneAuxIntoGlobal(getDSGraph(*I));
- InlinedSomewhere.clear();
-
// If we computed any temporary indcallgraphs, free them now.
- for (std::map<std::vector<Function*>,
+ for (std::map<std::vector<const Function*>,
std::pair<DSGraph*, std::vector<DSNodeHandle> > >::iterator I =
IndCallGraphMap.begin(), E = IndCallGraphMap.end(); I != E; ++I) {
I->second.second.clear(); // Drop arg refs into the graph.
@@ -122,13 +109,13 @@
DSGraph::IgnoreGlobals);
}
- NumCallEdges += ActualCallees.size();
+ NumCallEdges += callee_size();
return false;
}
static inline bool nodeContainsExternalFunction(const DSNode *N) {
- std::vector<Function*> Funcs;
+ std::vector<const Function*> Funcs;
N->addFullFunctionList(Funcs);
for (unsigned i = 0, e = Funcs.size(); i != e; ++i)
if (Funcs[i]->isDeclaration()) return true;
@@ -165,7 +152,7 @@
}
static void GetAllCallees(const DSCallSite &CS,
- std::vector<Function*> &Callees) {
+ std::vector<const Function*> &Callees) {
if (CS.isDirectCall()) {
if (!CS.getCalleeFunc()->isDeclaration())
Callees.push_back(CS.getCalleeFunc());
@@ -184,7 +171,7 @@
}
static void GetAnyCallees(const DSCallSite &CS,
- std::vector<Function*> &Callees) {
+ std::vector<const Function*> &Callees) {
if (CS.isDirectCall()) {
if (!CS.getCalleeFunc()->isDeclaration())
Callees.push_back(CS.getCalleeFunc());
@@ -204,7 +191,7 @@
/// GetAllAuxCallees - Return a list containing all of the resolvable callees in
/// the aux list for the specified graph in the Callees vector.
-static void GetAllAuxCallees(DSGraph &G, std::vector<Function*> &Callees) {
+static void GetAllAuxCallees(DSGraph &G, std::vector<const Function*> &Callees) {
Callees.clear();
for (DSGraph::afc_iterator I = G.afc_begin(), E = G.afc_end(); I != E; ++I)
GetAllCallees(*I, Callees);
@@ -212,16 +199,16 @@
/// GetAnyAuxCallees - Return a list containing all of the callees in
/// the aux list for the specified graph in the Callees vector.
-static void GetAnyAuxCallees(DSGraph &G, std::vector<Function*> &Callees) {
+static void GetAnyAuxCallees(DSGraph &G, std::vector<const Function*> &Callees) {
Callees.clear();
for (DSGraph::afc_iterator I = G.afc_begin(), E = G.afc_end(); I != E; ++I)
GetAnyCallees(*I, Callees);
}
-unsigned BUDataStructures::calculateGraphs(Function *F,
- std::vector<Function*> &Stack,
+unsigned BUDataStructures::calculateGraphs(const Function *F,
+ std::vector<const Function*> &Stack,
unsigned &NextID,
- hash_map<Function*, unsigned> &ValMap) {
+ hash_map<const Function*, unsigned> &ValMap) {
assert(!ValMap.count(F) && "Shouldn't revisit functions!");
unsigned Min = NextID++, MyID = Min;
ValMap[F] = Min;
@@ -240,18 +227,18 @@
DSGraph &Graph = getOrCreateGraph(F);
// Find all callee functions.
- std::vector<Function*> CalleeFunctions;
+ std::vector<const Function*> CalleeFunctions;
GetAnyAuxCallees(Graph, CalleeFunctions);
std::sort(CalleeFunctions.begin(), CalleeFunctions.end());
- std::vector<Function*>::iterator uid = std::unique(CalleeFunctions.begin(), CalleeFunctions.end());
+ std::vector<const Function*>::iterator uid = std::unique(CalleeFunctions.begin(), CalleeFunctions.end());
CalleeFunctions.resize(uid - CalleeFunctions.begin());
// The edges out of the current node are the call site targets...
for (unsigned i = 0, e = CalleeFunctions.size(); i != e; ++i) {
- Function *Callee = CalleeFunctions[i];
+ const Function *Callee = CalleeFunctions[i];
unsigned M;
// Have we visited the destination function yet?
- hash_map<Function*, unsigned>::iterator It = ValMap.find(Callee);
+ hash_map<const Function*, unsigned>::iterator It = ValMap.find(Callee);
if (It == ValMap.end()) // No, visit it now.
M = calculateGraphs(Callee, Stack, NextID, ValMap);
else // Yes, get it's number.
@@ -281,10 +268,10 @@
unsigned oldsize = CalleeFunctions.size();
GetAnyAuxCallees(Graph, CalleeFunctions);
std::sort(CalleeFunctions.begin(), CalleeFunctions.end());
- std::vector<Function*>::iterator uid = std::unique(CalleeFunctions.begin(), CalleeFunctions.end());
+ std::vector<const Function*>::iterator uid = std::unique(CalleeFunctions.begin(), CalleeFunctions.end());
CalleeFunctions.resize(uid - CalleeFunctions.begin());
- std::vector<Function*> ResolvedFuncs;
+ std::vector<const Function*> ResolvedFuncs;
GetAllAuxCallees(Graph, ResolvedFuncs);
if (ResolvedFuncs.size() || CalleeFunctions.size() > oldsize) {
DOUT << "Recalculating " << F->getName() << " due to new knowledge\n";
@@ -293,6 +280,8 @@
} else {
ValMap[F] = ~0U;
}
+ //propagate incomplete call nodes
+ inlineUnresolved(Graph);
return MyID;
} else {
@@ -301,7 +290,7 @@
std::vector<DSGraph*> SCCGraphs;
unsigned SCCSize = 1;
- Function *NF = Stack.back();
+ const Function *NF = Stack.back();
ValMap[NF] = ~0U;
DSGraph &SCCGraph = getDSGraph(*NF);
@@ -319,7 +308,7 @@
// Update the Function -> DSG map.
for (DSGraph::retnodes_iterator I = NFG.retnodes_begin(),
E = NFG.retnodes_end(); I != E; ++I)
- DSInfo[I->first] = &SCCGraph;
+ setDSGraph(*I->first, &SCCGraph);
SCCGraph.spliceFrom(NFG);
delete &NFG;
@@ -346,6 +335,8 @@
<< "DONE with SCC #: " << MyID << "\n";
// We never have to revisit "SCC" processed functions...
+ //propagate incomplete call nodes
+ inlineUnresolved(SCCGraph);
return MyID;
}
@@ -361,24 +352,6 @@
GG.getAuxFunctionCalls().push_front(RC.cloneCallSite(*ii));
}
-// releaseMemory - If the pass pipeline is done with this pass, we can release
-// our memory... here...
-//
-void BUDataStructures::releaseMyMemory() {
- for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
- E = DSInfo.end(); I != E; ++I) {
- I->second->getReturnNodes().erase(I->first);
- if (I->second->getReturnNodes().empty())
- delete I->second;
- }
-
- // Empty map so next time memory is released, data structures are not
- // re-deleted.
- DSInfo.clear();
- delete GlobalsGraph;
- GlobalsGraph = 0;
-}
-
void BUDataStructures::calculateGraph(DSGraph &Graph) {
// If this graph contains the main function, clone the globals graph into this
// graph before we inline callees and other fun stuff.
@@ -416,8 +389,7 @@
std::list<DSCallSite> &AuxCallsList = Graph.getAuxFunctionCalls();
TempFCs.swap(AuxCallsList);
- bool Printed = false;
- std::vector<Function*> CalledFuncs;
+ std::vector<const Function*> CalledFuncs;
while (!TempFCs.empty()) {
DSCallSite &CS = *TempFCs.begin();
@@ -447,9 +419,8 @@
Instruction *TheCall = CS.getCallSite().getInstruction();
if (CalledFuncs.size() == 1 && (isComplete || hasDSGraph(*CalledFuncs[0]))) {
- Function *Callee = CalledFuncs[0];
- ActualCallees.insert(std::make_pair(TheCall, Callee));
- if (isComplete) InlinedSomewhere.insert(Callee);
+ const Function *Callee = CalledFuncs[0];
+ callee_add(TheCall, Callee);
// Get the data structure graph for the called function.
GI = &getDSGraph(*Callee); // Graph to inline
@@ -463,20 +434,19 @@
(isComplete?0:DSGraph::DontCloneAuxCallNodes));
++NumBUInlines;
} else {
- if (!Printed)
- DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
+ DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
DEBUG(std::cerr << " calls " << CalledFuncs.size()
<< " fns from site: " << CS.getCallSite().getInstruction()
<< " " << *CS.getCallSite().getInstruction());
DEBUG(std::cerr << " Fns =");
unsigned NumPrinted = 0;
- for (std::vector<Function*>::iterator I = CalledFuncs.begin(),
+ for (std::vector<const Function*>::iterator I = CalledFuncs.begin(),
E = CalledFuncs.end(); I != E; ++I) {
if (NumPrinted++ < 8) DOUT << " " << (*I)->getName();
// Add the call edges to the call graph.
- ActualCallees.insert(std::make_pair(TheCall, *I));
+ callee_add(TheCall, *I);
}
DOUT << "\n";
@@ -496,7 +466,7 @@
IndCallGraphMap[CalledFuncs];
if (IndCallGraph.first == 0) {
- std::vector<Function*>::iterator I = CalledFuncs.begin(),
+ std::vector<const Function*>::iterator I = CalledFuncs.begin(),
E = CalledFuncs.end();
// Start with a copy of the first graph.
@@ -510,7 +480,6 @@
// Merge all of the other callees into this graph.
for (++I; I != E; ++I) {
- if (isComplete) InlinedSomewhere.insert(*I);
// If the graph already contains the nodes for the function, don't
// bother merging it in again.
if (!GI->containsFunction(*I)) {
@@ -576,66 +545,142 @@
//Graph.writeGraphToFile(cerr, "bu_" + F.getName());
}
-static const Function *getFnForValue(const Value *V) {
- if (const Instruction *I = dyn_cast<Instruction>(V))
- return I->getParent()->getParent();
- else if (const Argument *A = dyn_cast<Argument>(V))
- return A->getParent();
- else if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
- return BB->getParent();
- return 0;
-}
-
-/// deleteValue/copyValue - Interfaces to update the DSGraphs in the program.
-/// These correspond to the interfaces defined in the AliasAnalysis class.
-void BUDataStructures::deleteValue(Value *V) {
- if (const Function *F = getFnForValue(V)) { // Function local value?
- // If this is a function local value, just delete it from the scalar map!
- getDSGraph(*F).getScalarMap().eraseIfExists(V);
- return;
- }
-
- if (Function *F = dyn_cast<Function>(V)) {
- assert(getDSGraph(*F).getReturnNodes().size() == 1 &&
- "cannot handle scc's");
- delete DSInfo[F];
- DSInfo.erase(F);
- return;
- }
-
- assert(!isa<GlobalVariable>(V) && "Do not know how to delete GV's yet!");
-}
-
-void BUDataStructures::copyValue(Value *From, Value *To) {
- if (From == To) return;
- if (const Function *F = getFnForValue(From)) { // Function local value?
- // If this is a function local value, just delete it from the scalar map!
- getDSGraph(*F).getScalarMap().copyScalarIfExists(From, To);
- return;
- }
-
- if (Function *FromF = dyn_cast<Function>(From)) {
- Function *ToF = cast<Function>(To);
- assert(!DSInfo.count(ToF) && "New Function already exists!");
- DSGraph *NG = new DSGraph(getDSGraph(*FromF), GlobalECs);
- DSInfo[ToF] = NG;
- assert(NG->getReturnNodes().size() == 1 && "Cannot copy SCC's yet!");
-
- // Change the Function* is the returnnodes map to the ToF.
- DSNodeHandle Ret = NG->retnodes_begin()->second;
- NG->getReturnNodes().clear();
- NG->getReturnNodes()[ToF] = Ret;
- return;
- }
-
- if (const Function *F = getFnForValue(To)) {
- DSGraph &G = getDSGraph(*F);
- G.getScalarMap().copyScalarIfExists(From, To);
- return;
- }
-
- cerr << *From;
- cerr << *To;
- assert(0 && "Do not know how to copy this yet!");
- abort();
+void BUDataStructures::inlineUnresolved(DSGraph &Graph) {
+ std::list<DSCallSite> TempFCs;
+ std::list<DSCallSite> &AuxCallsList = Graph.getAuxFunctionCalls();
+ TempFCs.insert(TempFCs.begin(), AuxCallsList.begin(), AuxCallsList.end());
+
+ std::vector<const Function*> CalledFuncs;
+ while (!TempFCs.empty()) {
+ DSCallSite CS = *TempFCs.begin();
+ TempFCs.erase(TempFCs.begin());
+ CalledFuncs.clear();
+ GetAnyCallees(CS, CalledFuncs);
+ if (CalledFuncs.empty())
+ continue;
+
+ DSGraph *GI;
+ Instruction *TheCall = CS.getCallSite().getInstruction();
+ if (CalledFuncs.size() == 1 && hasDSGraph(*CalledFuncs[0])) {
+ const Function *Callee = CalledFuncs[0];
+ callee_add(TheCall, Callee);
+
+ // Get the data structure graph for the called function.
+ GI = &getDSGraph(*Callee); // Graph to inline
+ if (GI == &Graph) continue;
+ DOUT << " Inlining graph for " << Callee->getName()
+ << "[" << GI->getGraphSize() << "+"
+ << GI->getAuxFunctionCalls().size() << "] into '"
+ << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
+ << Graph.getAuxFunctionCalls().size() << "]\n";
+ Graph.mergeInGraph(CS, *Callee, *GI,
+ DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes);
+ ++NumBUInlines;
+ } else {
+ DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
+ DEBUG(std::cerr << " calls " << CalledFuncs.size()
+ << " fns from site: " << CS.getCallSite().getInstruction()
+ << " " << *CS.getCallSite().getInstruction());
+ DEBUG(std::cerr << " Fns =");
+ unsigned NumPrinted = 0;
+
+ for (std::vector<const Function*>::iterator I = CalledFuncs.begin(),
+ E = CalledFuncs.end(); I != E; ++I) {
+ if (NumPrinted++ < 8) DOUT << " " << (*I)->getName();
+
+ // Add the call edges to the call graph.
+ callee_add(TheCall, *I);
+ }
+ DOUT << "\n";
+
+ for (unsigned x = 0; x < CalledFuncs.size(); )
+ if (!hasDSGraph(*CalledFuncs[x]))
+ CalledFuncs.erase(CalledFuncs.begin() + x);
+ else
+ ++x;
+ if (!CalledFuncs.size())
+ continue;
+
+ // See if we already computed a graph for this set of callees.
+ std::sort(CalledFuncs.begin(), CalledFuncs.end());
+ std::pair<DSGraph*, std::vector<DSNodeHandle> > &IndCallGraph =
+ IndCallGraphMap[CalledFuncs];
+
+ if (IndCallGraph.first == &Graph) continue;
+
+ if (IndCallGraph.first == 0) {
+ std::vector<const Function*>::iterator I = CalledFuncs.begin(),
+ E = CalledFuncs.end();
+
+ // Start with a copy of the first graph.
+ GI = IndCallGraph.first = new DSGraph(getDSGraph(**I), GlobalECs);
+ GI->setGlobalsGraph(Graph.getGlobalsGraph());
+ std::vector<DSNodeHandle> &Args = IndCallGraph.second;
+
+ // Get the argument nodes for the first callee. The return value is
+ // the 0th index in the vector.
+ GI->getFunctionArgumentsForCall(*I, Args);
+
+ // Merge all of the other callees into this graph.
+ for (++I; I != E; ++I) {
+ // If the graph already contains the nodes for the function, don't
+ // bother merging it in again.
+ if (!GI->containsFunction(*I)) {
+ GI->cloneInto(getDSGraph(**I));
+ ++NumBUInlines;
+ }
+
+ std::vector<DSNodeHandle> NextArgs;
+ GI->getFunctionArgumentsForCall(*I, NextArgs);
+ unsigned i = 0, e = Args.size();
+ for (; i != e; ++i) {
+ if (i == NextArgs.size()) break;
+ Args[i].mergeWith(NextArgs[i]);
+ }
+ for (e = NextArgs.size(); i != e; ++i)
+ Args.push_back(NextArgs[i]);
+ }
+
+ // Clean up the final graph!
+ GI->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
+ } else {
+ DOUT << "***\n*** RECYCLED GRAPH ***\n***\n";
+ }
+
+ GI = IndCallGraph.first;
+
+ // Merge the unified graph into this graph now.
+ DOUT << " Inlining multi callee graph "
+ << "[" << GI->getGraphSize() << "+"
+ << GI->getAuxFunctionCalls().size() << "] into '"
+ << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
+ << Graph.getAuxFunctionCalls().size() << "]\n";
+
+ Graph.mergeInGraph(CS, IndCallGraph.second, *GI,
+ DSGraph::StripAllocaBit |
+ DSGraph::DontCloneCallNodes);
+ ++NumBUInlines;
+ }
+ }
+
+ // Recompute the Incomplete markers
+ Graph.maskIncompleteMarkers();
+ Graph.markIncompleteNodes(DSGraph::MarkFormalArgs);
+
+ // Delete dead nodes. Treat globals that are unreachable but that can
+ // reach live nodes as live.
+ Graph.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.
+ DSScalarMap &MainSM = Graph.getScalarMap();
+ ReachabilityCloner RC(*GlobalsGraph, Graph, DSGraph::StripAllocaBit);
+
+ // Clone everything reachable from globals in the function graph into the
+ // globals graph.
+ for (DSScalarMap::global_iterator I = MainSM.global_begin(),
+ E = MainSM.global_end(); I != E; ++I)
+ RC.getClonedNH(MainSM[*I]);
+
+ //Graph.writeGraphToFile(cerr, "bu_" + F.getName());
}
Modified: poolalloc/trunk/lib/DSA/CallTargets.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/CallTargets.cpp?rev=57319&r1=57318&r2=57319&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/CallTargets.cpp (original)
+++ poolalloc/trunk/lib/DSA/CallTargets.cpp Thu Oct 9 01:24:31 2008
@@ -78,7 +78,7 @@
void CallTargetFinder::print(std::ostream &O, const Module *M) const
{
O << "[* = incomplete] CS: func list\n";
- for (std::map<CallSite, std::vector<Function*> >::const_iterator ii =
+ for (std::map<CallSite, std::vector<const Function*> >::const_iterator ii =
IndMap.begin(),
ee = IndMap.end(); ii != ee; ++ii) {
if (!ii->first.getCalledFunction()) { //only print indirect
@@ -90,7 +90,7 @@
<< cs.getInstruction()->getName() << " ";
}
O << ii->first.getInstruction() << ":";
- for (std::vector<Function*>::const_iterator i = ii->second.begin(),
+ for (std::vector<const Function*>::const_iterator i = ii->second.begin(),
e = ii->second.end(); i != e; ++i) {
O << " " << (*i)->getName();
}
@@ -109,11 +109,11 @@
AU.addRequired<TDDataStructures>();
}
-std::vector<Function*>::iterator CallTargetFinder::begin(CallSite cs) {
+std::vector<const Function*>::iterator CallTargetFinder::begin(CallSite cs) {
return IndMap[cs].begin();
}
-std::vector<Function*>::iterator CallTargetFinder::end(CallSite cs) {
+std::vector<const Function*>::iterator CallTargetFinder::end(CallSite cs) {
return IndMap[cs].end();
}
Modified: poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp?rev=57319&r1=57318&r2=57319&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp (original)
+++ poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp Thu Oct 9 01:24:31 2008
@@ -13,7 +13,7 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "cbudatastructure"
+#define DEBUG_TYPE "dsa-cbu"
#include "dsa/DataStructure.h"
#include "llvm/Module.h"
#include "dsa/DSGraph.h"
@@ -25,7 +25,7 @@
namespace {
RegisterPass<CompleteBUDataStructures>
- X("cbudatastructure", "'Complete' Bottom-up Data Structure Analysis");
+ X("dsa-cbu", "'Complete' Bottom-up Data Structure Analysis");
STATISTIC (NumCBUInlines, "Number of graphs inlined");
}
@@ -35,13 +35,7 @@
// program.
//
bool CompleteBUDataStructures::runOnModule(Module &M) {
- BUDataStructures &BU = getAnalysis<BUDataStructures>();
- GlobalECs = BU.getGlobalECs();
- GlobalsGraph = new DSGraph(BU.getGlobalsGraph(), GlobalECs);
- GlobalsGraph->setPrintAuxCalls();
-
- // Our call graph is the same as the BU data structures call graph
- ActualCallees = BU.getActualCallees();
+ init(&getAnalysis<BUDataStructures>(), false, true);
std::vector<DSGraph*> Stack;
hash_map<DSGraph*, unsigned> ValMap;
@@ -50,18 +44,18 @@
Function *MainFunc = M.getFunction("main");
if (MainFunc) {
if (!MainFunc->isDeclaration())
- calculateSCCGraphs(getOrCreateGraph(*MainFunc), Stack, NextID, ValMap);
+ calculateSCCGraphs(getOrCreateGraph(MainFunc), Stack, NextID, ValMap);
} else {
DOUT << "CBU-DSA: No 'main' function found!\n";
}
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
- if (!I->isDeclaration() && !DSInfo.count(I)) {
+ if (!I->isDeclaration() && !hasDSGraph(*I)) {
if (MainFunc) {
DOUT << "*** CBU: Function unreachable from main: "
<< I->getName() << "\n";
}
- calculateSCCGraphs(getOrCreateGraph(*I), Stack, NextID, ValMap);
+ calculateSCCGraphs(getOrCreateGraph(I), Stack, NextID, ValMap);
}
GlobalsGraph->removeTriviallyDeadNodes();
@@ -71,7 +65,7 @@
// 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);
+ DSGraph &MainGraph = getOrCreateGraph(MainFunc);
const DSGraph &GG = *MainGraph.getGlobalsGraph();
ReachabilityCloner RC(MainGraph, GG,
DSGraph::DontCloneCallNodes |
@@ -91,27 +85,6 @@
return false;
}
-DSGraph &CompleteBUDataStructures::getOrCreateGraph(Function &F) {
- // Has the graph already been created?
- DSGraph *&Graph = DSInfo[&F];
- if (Graph) return *Graph;
-
- // Copy the BU graph...
- Graph = new DSGraph(getAnalysis<BUDataStructures>().getDSGraph(F), GlobalECs);
- Graph->setGlobalsGraph(GlobalsGraph);
- Graph->setPrintAuxCalls();
-
- // Make sure to update the DSInfo map for all of the functions currently in
- // this graph!
- for (DSGraph::retnodes_iterator I = Graph->retnodes_begin();
- I != Graph->retnodes_end(); ++I)
- DSInfo[I->first] = Graph;
-
- return *Graph;
-}
-
-
-
unsigned CompleteBUDataStructures::calculateSCCGraphs(DSGraph &FG,
std::vector<DSGraph*> &Stack,
unsigned &NextID,
@@ -127,11 +100,10 @@
Instruction *Call = CI->getCallSite().getInstruction();
// Loop over all of the actually called functions...
- callee_iterator I = callee_begin(Call), E = callee_end(Call);
- for (; I != E && I->first == Call; ++I) {
- assert(I->first == Call && "Bad callee construction!");
- if (!I->second->isDeclaration()) {
- DSGraph &Callee = getOrCreateGraph(*I->second);
+ 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);
@@ -159,7 +131,7 @@
// Update the DSInfo map and delete the old graph...
for (DSGraph::retnodes_iterator I = NG->retnodes_begin();
I != NG->retnodes_end(); ++I)
- DSInfo[I->first] = &FG;
+ setDSGraph(*I->first, &FG);
// Remove NG from the ValMap since the pointer may get recycled.
ValMap.erase(NG);
@@ -204,16 +176,15 @@
// Inline direct calls as well as indirect calls because the direct
// callee may have indirect callees and so may have changed.
//
- callee_iterator I = callee_begin(TheCall),E = callee_end(TheCall);
unsigned TNum = 0, Num = 0;
- DEBUG(Num = std::distance(I, E));
- for (; I != E; ++I, ++TNum) {
- assert(I->first == TheCall && "Bad callee construction!");
- Function *CalleeFunc = I->second;
+ 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);
+ DSGraph &GI = getOrCreateGraph(CalleeFunc);
++NumCBUInlines;
G.mergeInGraph(CS, *CalleeFunc, GI,
DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes |
Modified: poolalloc/trunk/lib/DSA/DataStructure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructure.cpp?rev=57319&r1=57318&r2=57319&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructure.cpp Thu Oct 9 01:24:31 2008
@@ -112,14 +112,14 @@
// DSScalarMap Implementation
//===----------------------------------------------------------------------===//
-DSNodeHandle &DSScalarMap::AddGlobal(GlobalValue *GV) {
+DSNodeHandle &DSScalarMap::AddGlobal(const GlobalValue *GV) {
assert(ValueMap.count(GV) == 0 && "GV already exists!");
// If the node doesn't exist, check to see if it's a global that is
// equated to another global in the program.
- EquivalenceClasses<GlobalValue*>::iterator ECI = GlobalECs.findValue(GV);
+ EquivalenceClasses<const GlobalValue*>::iterator ECI = GlobalECs.findValue(GV);
if (ECI != GlobalECs.end()) {
- GlobalValue *Leader = *GlobalECs.findLeader(ECI);
+ const GlobalValue *Leader = *GlobalECs.findLeader(ECI);
if (Leader != GV) {
GV = Leader;
iterator I = ValueMap.find(GV);
@@ -220,13 +220,13 @@
// addGlobal - Add an entry for a global value to the Globals list. This also
// marks the node with the 'G' flag if it does not already have it.
//
-void DSNode::addGlobal(GlobalValue *GV) {
+void DSNode::addGlobal(const GlobalValue *GV) {
// First, check to make sure this is the leader if the global is in an
// equivalence class.
GV = getParentGraph()->getScalarMap().getLeaderForGlobal(GV);
// Keep the list sorted.
- std::vector<GlobalValue*>::iterator I =
+ std::vector<const GlobalValue*>::iterator I =
std::lower_bound(Globals.begin(), Globals.end(), GV);
if (I == Globals.end() || *I != GV) {
@@ -237,8 +237,8 @@
// removeGlobal - Remove the specified global that is explicitly in the globals
// list.
-void DSNode::removeGlobal(GlobalValue *GV) {
- std::vector<GlobalValue*>::iterator I =
+void DSNode::removeGlobal(const GlobalValue *GV) {
+ std::vector<const GlobalValue*>::iterator I =
std::lower_bound(Globals.begin(), Globals.end(), GV);
assert(I != Globals.end() && *I == GV && "Global not in node!");
Globals.erase(I);
@@ -316,13 +316,13 @@
/// addFullGlobalsList - Compute the full set of global values that are
/// represented by this node. Unlike getGlobalsList(), this requires fair
/// amount of work to compute, so don't treat this method call as free.
-void DSNode::addFullGlobalsList(std::vector<GlobalValue*> &List) const {
+void DSNode::addFullGlobalsList(std::vector<const GlobalValue*> &List) const {
if (globals_begin() == globals_end()) return;
- EquivalenceClasses<GlobalValue*> &EC = getParentGraph()->getGlobalECs();
+ EquivalenceClasses<const GlobalValue*> &EC = getParentGraph()->getGlobalECs();
for (globals_iterator I = globals_begin(), E = globals_end(); I != E; ++I) {
- EquivalenceClasses<GlobalValue*>::iterator ECI = EC.findValue(*I);
+ EquivalenceClasses<const GlobalValue*>::iterator ECI = EC.findValue(*I);
if (ECI == EC.end())
List.push_back(*I);
else
@@ -332,20 +332,20 @@
/// addFullFunctionList - Identical to addFullGlobalsList, but only return the
/// functions in the full list.
-void DSNode::addFullFunctionList(std::vector<Function*> &List) const {
+void DSNode::addFullFunctionList(std::vector<const Function*> &List) const {
if (globals_begin() == globals_end()) return;
- EquivalenceClasses<GlobalValue*> &EC = getParentGraph()->getGlobalECs();
+ EquivalenceClasses<const GlobalValue*> &EC = getParentGraph()->getGlobalECs();
for (globals_iterator I = globals_begin(), E = globals_end(); I != E; ++I) {
- EquivalenceClasses<GlobalValue*>::iterator ECI = EC.findValue(*I);
+ EquivalenceClasses<const GlobalValue*>::iterator ECI = EC.findValue(*I);
if (ECI == EC.end()) {
- if (Function *F = dyn_cast<Function>(*I))
+ if (const Function *F = dyn_cast<Function>(*I))
List.push_back(F);
} else {
- for (EquivalenceClasses<GlobalValue*>::member_iterator MI =
+ for (EquivalenceClasses<const GlobalValue*>::member_iterator MI =
EC.member_begin(ECI), E = EC.member_end(); MI != E; ++MI)
- if (Function *F = dyn_cast<Function>(*MI))
+ if (const Function *F = dyn_cast<Function>(*MI))
List.push_back(F);
}
}
@@ -765,7 +765,7 @@
return false;
}
- Module *M = 0;
+ const Module *M = 0;
if (getParentGraph()->retnodes_begin() != getParentGraph()->retnodes_end())
M = getParentGraph()->retnodes_begin()->first->getParent();
@@ -802,51 +802,13 @@
}
-/// MergeSortedVectors - Efficiently merge a vector into another vector where
-/// duplicates are not allowed and both are sorted. This assumes that 'T's are
-/// efficiently copyable and have sane comparison semantics.
-///
-static void MergeSortedVectors(std::vector<GlobalValue*> &Dest,
- const std::vector<GlobalValue*> &Src) {
- // By far, the most common cases will be the simple ones. In these cases,
- // avoid having to allocate a temporary vector...
- //
- if (Src.empty()) { // Nothing to merge in...
- return;
- } else if (Dest.empty()) { // Just copy the result in...
- Dest = Src;
- } else if (Src.size() == 1) { // Insert a single element...
- const GlobalValue *V = Src[0];
- std::vector<GlobalValue*>::iterator I =
- std::lower_bound(Dest.begin(), Dest.end(), V);
- if (I == Dest.end() || *I != Src[0]) // If not already contained...
- Dest.insert(I, Src[0]);
- } else if (Dest.size() == 1) {
- GlobalValue *Tmp = Dest[0]; // Save value in temporary...
- Dest = Src; // Copy over list...
- std::vector<GlobalValue*>::iterator I =
- std::lower_bound(Dest.begin(), Dest.end(), Tmp);
- if (I == Dest.end() || *I != Tmp) // If not already contained...
- Dest.insert(I, Tmp);
-
- } else {
- // Make a copy to the side of Dest...
- std::vector<GlobalValue*> Old(Dest);
-
- // Make space for all of the type entries now...
- Dest.resize(Dest.size()+Src.size());
-
- // Merge the two sorted ranges together... into Dest.
- std::merge(Old.begin(), Old.end(), Src.begin(), Src.end(), Dest.begin());
-
- // Now erase any duplicate entries that may have accumulated into the
- // vectors (because they were in both of the input sets)
- Dest.erase(std::unique(Dest.begin(), Dest.end()), Dest.end());
- }
-}
-
-void DSNode::mergeGlobals(const std::vector<GlobalValue*> &RHS) {
- MergeSortedVectors(Globals, RHS);
+void DSNode::mergeGlobals(const std::vector<const GlobalValue*> &RHS) {
+ std::vector<const GlobalValue*> Temp;
+ std::back_insert_iterator< std::vector<const GlobalValue*> > back_it (Temp);
+ std::set_union(Globals.begin(), Globals.end(),
+ RHS.begin(), RHS.end(),
+ back_it);
+ Globals.swap(Temp);
}
// MergeNodes - Helper function for DSNode::mergeWith().
@@ -1002,7 +964,7 @@
CurNodeH.getNode()->mergeGlobals(N->Globals);
// Delete the globals from the old node...
- std::vector<GlobalValue*>().swap(N->Globals);
+ N->Globals.clear();
}
}
@@ -1081,7 +1043,7 @@
DSScalarMap &DestSM = Dest.getScalarMap();
for (DSNode::globals_iterator I = SN->globals_begin(),E = SN->globals_end();
I != E; ++I) {
- GlobalValue *GV = *I;
+ const GlobalValue *GV = *I;
DSScalarMap::iterator GI = DestSM.find(GV);
if (GI != DestSM.end() && !GI->second.isNull()) {
// We found one, use merge instead!
@@ -1137,7 +1099,7 @@
// map with the correct offset.
for (DSNode::globals_iterator I = SN->globals_begin(), E = SN->globals_end();
I != E; ++I) {
- GlobalValue *GV = *I;
+ const GlobalValue *GV = *I;
const DSNodeHandle &SrcGNH = Src.getNodeForValue(GV);
DSNodeHandle &DestGNH = NodeMap[SrcGNH.getNode()];
assert(DestGNH.getNode() == NH.getNode() &&"Global mapping inconsistent");
@@ -1226,7 +1188,7 @@
// into.
for (DSNode::globals_iterator I = SN->globals_begin(),
E = SN->globals_end(); I != E; ++I) {
- GlobalValue *GV = *I;
+ const GlobalValue *GV = *I;
const DSNodeHandle &SrcGNH = Src.getNodeForValue(GV);
DSNodeHandle &DestGNH = NodeMap[SrcGNH.getNode()];
assert(DestGNH.getNode()==NH.getNode() &&"Global mapping inconsistent");
@@ -1257,7 +1219,7 @@
// in the scalar map for them!
for (DSNode::globals_iterator I = SN->globals_begin(),
E = SN->globals_end(); I != E; ++I) {
- GlobalValue *GV = *I;
+ const GlobalValue *GV = *I;
const DSNodeHandle &SrcGNH = Src.getNodeForValue(GV);
DSNodeHandle &DestGNH = NodeMap[SrcGNH.getNode()];
assert(DestGNH.getNode()==NH.getNode() &&"Global mapping inconsistent");
@@ -1389,7 +1351,7 @@
//===----------------------------------------------------------------------===//
// Define here to avoid including iOther.h and BasicBlock.h in DSGraph.h
-Function &DSCallSite::getCaller() const {
+const Function &DSCallSite::getCaller() const {
return *Site.getInstruction()->getParent()->getParent();
}
@@ -1466,7 +1428,7 @@
}
-DSGraph::DSGraph(DSGraph &G, EquivalenceClasses<GlobalValue*> &ECs,
+DSGraph::DSGraph(DSGraph &G, EquivalenceClasses<const GlobalValue*> &ECs,
unsigned CloneFlags)
: GlobalsGraph(0), ScalarMap(ECs), TD(G.TD) {
PrintAuxCalls = false;
@@ -1671,10 +1633,10 @@
/// function arguments. The vector is filled in with the return value (or
/// null if it is not pointer compatible), followed by all of the
/// pointer-compatible arguments.
-void DSGraph::getFunctionArgumentsForCall(Function *F,
+void DSGraph::getFunctionArgumentsForCall(const Function *F,
std::vector<DSNodeHandle> &Args) const {
Args.push_back(getReturnNodeFor(*F));
- for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
+ for (Function::const_arg_iterator AI = F->arg_begin(), E = F->arg_end();
AI != E; ++AI)
if (isa<PointerType>(AI->getType())) {
Args.push_back(getNodeForValue(AI));
@@ -1840,7 +1802,7 @@
// through another global. Compute the set of node that can reach globals and
// aux call nodes to copy over, then do it.
std::vector<const DSCallSite*> AuxCallToCopy;
- std::vector<GlobalValue*> GlobalsToCopy;
+ std::vector<const GlobalValue*> GlobalsToCopy;
// NodesReachCopiedNodes - Memoize results for efficiency. Contains a
// true/false value for every visited node that reaches a copied node without
@@ -1887,7 +1849,7 @@
/// merges the nodes specified in the call site with the formal arguments in the
/// graph.
///
-void DSGraph::mergeInGraph(const DSCallSite &CS, Function &F,
+void DSGraph::mergeInGraph(const DSCallSite &CS, const Function &F,
const DSGraph &Graph, unsigned CloneFlags) {
// Set up argument bindings.
std::vector<DSNodeHandle> Args;
@@ -1899,10 +1861,10 @@
/// getCallSiteForArguments - Get the arguments and return value bindings for
/// the specified function in the current graph.
///
-DSCallSite DSGraph::getCallSiteForArguments(Function &F) const {
+DSCallSite DSGraph::getCallSiteForArguments(const Function &F) const {
std::vector<DSNodeHandle> Args;
- for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I)
+ for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I)
if (isa<PointerType>(I->getType()))
Args.push_back(getNodeForValue(I));
@@ -1982,8 +1944,8 @@
if (Flags & DSGraph::MarkFormalArgs)
for (ReturnNodesTy::iterator FI = ReturnNodes.begin(), E =ReturnNodes.end();
FI != E; ++FI) {
- Function &F = *FI->first;
- for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
+ const Function &F = *FI->first;
+ for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end();
I != E; ++I)
if (isa<PointerType>(I->getType()))
markIncompleteNode(getNodeForValue(I).getNode());
@@ -2013,7 +1975,7 @@
// Mark all global nodes as incomplete.
for (DSScalarMap::global_iterator I = ScalarMap.global_begin(),
E = ScalarMap.global_end(); I != E; ++I)
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
+ if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
if (!GV->hasInitializer() || // Always mark external globals incomp.
(!GV->isConstant() && (Flags & DSGraph::IgnoreGlobals) == 0))
markIncompleteNode(ScalarMap[GV].getNode());
@@ -2029,7 +1991,7 @@
}
static inline bool nodeContainsExternalFunction(const DSNode *N) {
- std::vector<Function*> Funcs;
+ std::vector<const Function*> Funcs;
N->addFullFunctionList(Funcs);
for (unsigned i = 0, e = Funcs.size(); i != e; ++i)
if (Funcs[i]->isDeclaration()) return true;
@@ -2246,7 +2208,7 @@
// scalar map, so we check those now.
//
if (Node.getNumReferrers() == Node.getGlobalsList().size()) {
- const std::vector<GlobalValue*> &Globals = Node.getGlobalsList();
+ const std::vector<const GlobalValue*> &Globals = Node.getGlobalsList();
// Loop through and make sure all of the globals are referring directly
// to the node...
@@ -2371,7 +2333,7 @@
// Alive - a set that holds all nodes found to be reachable/alive.
hash_set<const DSNode*> Alive;
- std::vector<std::pair<Value*, DSNode*> > GlobalNodes;
+ std::vector<std::pair<const Value*, DSNode*> > GlobalNodes;
// Copy and merge all information about globals to the GlobalsGraph if this is
// not a final pass (where unreachable globals are removed).
@@ -2507,7 +2469,7 @@
DEBUG(AssertGraphOK(); GlobalsGraph->AssertGraphOK());
}
-void DSGraph::AssertNodeContainsGlobal(const DSNode *N, GlobalValue *GV) const {
+void DSGraph::AssertNodeContainsGlobal(const DSNode *N, const GlobalValue *GV) const {
assert(std::find(N->globals_begin(),N->globals_end(), GV) !=
N->globals_end() && "Global value not in node!");
}
@@ -2543,7 +2505,7 @@
E = ScalarMap.end(); I != E; ++I) {
assert(!I->second.isNull() && "Null node in scalarmap!");
AssertNodeInGraph(I->second.getNode());
- if (GlobalValue *GV = dyn_cast<GlobalValue>(I->first)) {
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(I->first)) {
assert(I->second.getNode()->isGlobalNode() &&
"Global points to node, but node isn't global?");
AssertNodeContainsGlobal(I->second.getNode(), GV);
@@ -2557,8 +2519,8 @@
for (ReturnNodesTy::const_iterator RI = ReturnNodes.begin(),
E = ReturnNodes.end();
RI != E; ++RI) {
- Function &F = *RI->first;
- for (Function::arg_iterator AI = F.arg_begin(); AI != F.arg_end(); ++AI)
+ const Function &F = *RI->first;
+ for (Function::const_arg_iterator AI = F.arg_begin(); AI != F.arg_end(); ++AI)
if (isa<PointerType>(AI->getType()))
assert(!getNodeForValue(AI).isNull() &&
"Pointer argument must be in the scalar map!");
@@ -2759,7 +2721,7 @@
abort();
}
-DSGraph& DataStructures::getOrCreateGraph(Function* F) {
+DSGraph& DataStructures::getOrCreateGraph(const Function* F) {
assert(F && "No function");
DSGraph *&G = DSInfo[F];
if (!G) {
@@ -2789,11 +2751,11 @@
void DataStructures::formGlobalECs() {
// Grow the equivalence classes for the globals to include anything that we
// now know to be aliased.
- std::set<GlobalValue*> ECGlobals;
+ std::set<const GlobalValue*> ECGlobals;
buildGlobalECs(ECGlobals);
if (!ECGlobals.empty()) {
DOUT << "Eliminating " << ECGlobals.size() << " EC Globals!\n";
- for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
+ for (DSInfoTy::iterator I = DSInfo.begin(),
E = DSInfo.end(); I != E; ++I)
eliminateUsesOfECGlobals(*I->second, ECGlobals);
}
@@ -2804,9 +2766,9 @@
/// apart. Instead of maintaining this information in all of the graphs
/// throughout the entire program, store only a single global (the "leader") in
/// the graphs, and build equivalence classes for the rest of the globals.
-void DataStructures::buildGlobalECs(std::set<GlobalValue*> &ECGlobals) {
+void DataStructures::buildGlobalECs(std::set<const GlobalValue*> &ECGlobals) {
DSScalarMap &SM = GlobalsGraph->getScalarMap();
- EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();
+ EquivalenceClasses<const GlobalValue*> &GlobalECs = SM.getGlobalECs();
for (DSGraph::node_iterator I = GlobalsGraph->node_begin(),
E = GlobalsGraph->node_end();
I != E; ++I) {
@@ -2814,7 +2776,7 @@
// First, build up the equivalence set for this block of globals.
DSNode::globals_iterator i = I->globals_begin();
- GlobalValue *First = *i++;
+ const GlobalValue *First = *i++;
for( ; i != I->globals_end(); ++i) {
GlobalECs.unionSets(First, *i);
ECGlobals.insert(*i);
@@ -2837,14 +2799,14 @@
/// really just equivalent to some other globals, remove the globals from the
/// specified DSGraph (if present), and merge any nodes with their leader nodes.
void DataStructures::eliminateUsesOfECGlobals(DSGraph &G,
- const std::set<GlobalValue*> &ECGlobals) {
+ const std::set<const GlobalValue*> &ECGlobals) {
DSScalarMap &SM = G.getScalarMap();
- EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();
+ EquivalenceClasses<const GlobalValue*> &GlobalECs = SM.getGlobalECs();
bool MadeChange = false;
for (DSScalarMap::global_iterator GI = SM.global_begin(), E = SM.global_end();
GI != E; ) {
- GlobalValue *GV = *GI++;
+ const GlobalValue *GV = *GI++;
if (!ECGlobals.count(GV)) continue;
const DSNodeHandle &GVNH = SM[GV];
@@ -2852,7 +2814,7 @@
// Okay, this global is in some equivalence class. Start by finding the
// leader of the class.
- GlobalValue *Leader = GlobalECs.getLeaderValue(GV);
+ const GlobalValue *Leader = GlobalECs.getLeaderValue(GV);
// If the leader isn't already in the graph, insert it into the node
// corresponding to GV.
@@ -2877,3 +2839,37 @@
DEBUG(if(MadeChange) G.AssertGraphOK());
}
+
+void DataStructures::init(DataStructures* D, bool clone, bool printAuxCalls) {
+ assert (!GraphSource && "Already init");
+ GraphSource = D;
+ Clone = clone;
+ TD = D->TD;
+ ActualCallees = D->ActualCallees;
+ GlobalECs = D->getGlobalECs();
+ GlobalsGraph = new DSGraph(D->getGlobalsGraph(), GlobalECs);
+ if (printAuxCalls) GlobalsGraph->setPrintAuxCalls();
+}
+
+void DataStructures::init(TargetData* T) {
+ assert (!TD && "Already init");
+ GraphSource = 0;
+ Clone = false;
+ TD = T;
+ GlobalsGraph = new DSGraph(GlobalECs, *T);
+}
+
+void DataStructures::releaseMemory() {
+ for (DSInfoTy::iterator I = DSInfo.begin(), E = DSInfo.end(); I != E; ++I) {
+ I->second->getReturnNodes().erase(I->first);
+ if (I->second->getReturnNodes().empty())
+ delete I->second;
+ }
+
+ // Empty map so next time memory is released, data structures are not
+ // re-deleted.
+ DSInfo.clear();
+ ActualCallees.clear();
+ delete GlobalsGraph;
+ GlobalsGraph = 0;
+}
Modified: poolalloc/trunk/lib/DSA/DataStructureStats.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructureStats.cpp?rev=57319&r1=57318&r2=57319&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructureStats.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructureStats.cpp Thu Oct 9 01:24:31 2008
@@ -26,7 +26,7 @@
namespace {
STATISTIC (TotalNumCallees, "Total number of callee functions at all indirect call sites");
STATISTIC (NumIndirectCalls, "Total number of indirect call sites in the program");
- STATISTIC (NumPoolNodes, "Number of allocation nodes that could be pool allocated");
+ // STATISTIC (NumPoolNodes, "Number of allocation nodes that could be pool allocated");
// Typed/Untyped memory accesses: If DSA can infer that the types the loads
// and stores are accessing are correct (ie, the node has not been collapsed),
@@ -88,7 +88,7 @@
I != E; ++I)
if (isIndirectCallee(I->getCallSite().getCalledValue())) {
// This is an indirect function call
- std::vector<Function*> Callees;
+ std::vector<const Function*> Callees;
I->getCalleeNode()->addFullFunctionList(Callees);
if (Callees.size() > 0) {
Modified: poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp?rev=57319&r1=57318&r2=57319&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp (original)
+++ poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp Thu Oct 9 01:24:31 2008
@@ -29,7 +29,7 @@
using namespace llvm;
namespace {
- RegisterPass<EquivClassGraphs> X("eqdatastructure",
+ RegisterPass<EquivClassGraphs> X("dsa-eq",
"Equivalence-class Bottom-up Data Structure Analysis");
STATISTIC (NumEquivBUInlines,
"Number of graphs inlined");
@@ -39,7 +39,7 @@
char EquivClassGraphs::ID = 0;
-EquivClassGraphs::EquivClassGraphs() : ModulePass((intptr_t)&ID) {}
+EquivClassGraphs::EquivClassGraphs() : DataStructures((intptr_t)&ID) {}
#ifndef NDEBUG
template<typename GT>
@@ -58,12 +58,12 @@
// getSomeCalleeForCallSite - Return any one callee function at a call site.
//
-Function *EquivClassGraphs::getSomeCalleeForCallSite(const CallSite &CS) const{
+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*, Function *>::const_iterator I =
+ std::map<DSNode*, const Function *>::const_iterator I =
OneCalledFunction.find(calleeNode);
return (I == OneCalledFunction.end())? NULL : I->second;
}
@@ -72,14 +72,7 @@
// in the program.
//
bool EquivClassGraphs::runOnModule(Module &M) {
- CBU = &getAnalysis<CompleteBUDataStructures>();
- GlobalECs = CBU->getGlobalECs();
- DEBUG(CheckAllGraphs(&M, *CBU));
-
- GlobalsGraph = new DSGraph(CBU->getGlobalsGraph(), GlobalECs);
- GlobalsGraph->setPrintAuxCalls();
-
- ActualCallees = CBU->getActualCallees();
+ 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.
@@ -90,16 +83,16 @@
std::map<DSGraph*, unsigned> ValMap;
unsigned NextID = 1;
- Function *MainFunc = M.getFunction("main");
+ const Function *MainFunc = M.getFunction("main");
if (MainFunc && !MainFunc->isDeclaration()) {
- processSCC(getOrCreateGraph(*MainFunc), Stack, NextID, ValMap);
+ 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);
+ processSCC(getOrCreateGraph(I), Stack, NextID, ValMap);
DEBUG(CheckAllGraphs(&M, *this));
@@ -110,7 +103,7 @@
// 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);
+ DSGraph &MainGraph = getOrCreateGraph(MainFunc);
const DSGraph &GG = *MainGraph.getGlobalsGraph();
ReachabilityCloner RC(MainGraph, GG,
DSGraph::DontCloneCallNodes |
@@ -140,7 +133,7 @@
UI != E; ++UI)
// This only happens to direct uses by instructions.
if (Instruction *User = dyn_cast<Instruction>(*UI)) {
- DSGraph &DSG = getOrCreateGraph(*User->getParent()->getParent());
+ 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
@@ -159,46 +152,26 @@
// unify the N functions together in the FuncECs set.
//
void EquivClassGraphs::buildIndirectFunctionSets(Module &M) {
- const ActualCalleesTy& AC = CBU->getActualCallees();
-
// 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.
- Instruction *LastInst = 0;
- Function *FirstFunc = 0;
- for (ActualCalleesTy::const_iterator I=AC.begin(), E=AC.end(); I != E; ++I) {
- if (I->second->isDeclaration())
- continue; // Ignore functions we cannot modify
-
- CallSite CS = CallSite::get(I->first);
-
- if (CS.getCalledFunction()) { // Direct call:
- FuncECs.insert(I->second); // -- Make sure function has equiv class
- FirstFunc = I->second; // -- First callee at this site
- } else { // Else indirect call
- // DOUT << "CALLEE: " << I->second->getName()
- // << " from : " << I->first;
- if (I->first != LastInst) {
- // This is the first callee from this call site.
- LastInst = I->first;
- FirstFunc = I->second;
- // Instead of storing the lastInst For Indirection call Sites we store
- // the DSNode for the function ptr arguemnt
- Function *thisFunc = LastInst->getParent()->getParent();
- DSGraph &TFG = CBU->getDSGraph(*thisFunc);
- DSNode *calleeNode = TFG.getNodeForValue(CS.getCalledValue()).getNode();
- OneCalledFunction[calleeNode] = FirstFunc;
- FuncECs.insert(I->second);
+ 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 {
- // This is not the first possible callee from a particular call site.
- // Union the callee in with the other functions.
- FuncECs.unionSets(FirstFunc, I->second);
-#ifndef NDEBUG
- Function *thisFunc = LastInst->getParent()->getParent();
- DSGraph &TFG = CBU->getDSGraph(*thisFunc);
- DSNode *calleeNode = TFG.getNodeForValue(CS.getCalledValue()).getNode();
- assert(OneCalledFunction.count(calleeNode) > 0 && "Missed a call?");
-#endif
+ FuncECs.unionSets(*csi, F);
}
}
@@ -207,29 +180,29 @@
// 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 = CBU->getDSGraph(*I->second);
+ DSGraph& funcDSGraph = getOrCreateGraph(F);
for (DSGraph::retnodes_iterator RI = funcDSGraph.retnodes_begin(),
RE = funcDSGraph.retnodes_end(); RI != RE; ++RI)
- FuncECs.unionSets(FirstFunc, RI->first);
+ 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<Function*>::iterator EQSI = FuncECs.begin(), E =
+ for (EquivalenceClasses<const Function*>::iterator EQSI = FuncECs.begin(), E =
FuncECs.end(); EQSI != E; ++EQSI) {
if (!EQSI->isLeader()) continue;
- EquivalenceClasses<Function*>::member_iterator SI =
+ EquivalenceClasses<const Function*>::member_iterator SI =
FuncECs.member_begin(EQSI);
assert(SI != FuncECs.member_end() && "Empty equiv set??");
- EquivalenceClasses<Function*>::member_iterator SN = SI;
+ EquivalenceClasses<const Function*>::member_iterator SN = SI;
++SN;
if (SN == FuncECs.member_end())
continue; // Single function equivalence set, no merging to do.
- Function* LF = *SI;
+ const Function* LF = *SI;
#ifndef NDEBUG
DOUT <<" Equivalence set for leader " << LF->getName() <<" = ";
@@ -241,12 +214,12 @@
// 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);
+ DSGraph &MergedG = getOrCreateGraph(LF);
// Record the argument nodes for use in merging later below.
std::vector<DSNodeHandle> ArgNodes;
- for (Function::arg_iterator AI = LF->arg_begin(), E = LF->arg_end();
+ 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));
@@ -255,18 +228,16 @@
// 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(&CBU->getDSGraph(*LF));
+ GraphsMerged.insert(&getOrCreateGraph(LF));
for (++SI; SI != FuncECs.member_end(); ++SI) {
- Function *F = *SI;
- DSGraph &CBUGraph = CBU->getDSGraph(*F);
+ 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) {
- assert(DSInfo[I->first] == 0 && "Graph already exists for Fn!");
- DSInfo[I->first] = &MergedG;
- }
+ E = CBUGraph.retnodes_end(); I != E; ++I)
+ setDSGraph(*I->first, &MergedG);
// Clone this member of the equivalence class into MergedG.
MergedG.cloneInto(CBUGraph);
@@ -277,7 +248,7 @@
// 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::arg_iterator AI2 = F->arg_begin(), AI2end = F->arg_end();
+ 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()))
@@ -293,31 +264,6 @@
}
-DSGraph &EquivClassGraphs::getOrCreateGraph(Function &F) {
- // Has the graph already been created?
- DSGraph *&Graph = DSInfo[&F];
- if (Graph) return *Graph;
-
- DSGraph &CBUGraph = CBU->getDSGraph(F);
-
- // Copy the CBU graph...
- Graph = new DSGraph(CBUGraph, GlobalECs); // updates the map via reference
- Graph->setGlobalsGraph(&getGlobalsGraph());
- Graph->setPrintAuxCalls();
-
- // Make sure to update the DSInfo map for all functions in the graph!
- for (DSGraph::retnodes_iterator I = Graph->retnodes_begin();
- I != Graph->retnodes_end(); ++I)
- if (I->first != &F) {
- DSGraph *&FG = DSInfo[I->first];
- assert(FG == 0 && "Merging function in SCC twice?");
- FG = Graph;
- }
-
- return *Graph;
-}
-
-
unsigned EquivClassGraphs::
processSCC(DSGraph &FG, std::vector<DSGraph*> &Stack, unsigned &NextID,
std::map<DSGraph*, unsigned> &ValMap) {
@@ -339,9 +285,9 @@
// Loop over all of the actually called functions...
for (callee_iterator I = callee_begin(Call), E = callee_end(Call);
I != E; ++I)
- if (!I->second->isDeclaration()) {
+ if (!(*I)->isDeclaration()) {
// Process the callee as necessary.
- unsigned M = processSCC(getOrCreateGraph(*I->second),
+ unsigned M = processSCC(getOrCreateGraph(*I),
Stack, NextID, ValMap);
if (M < Min) Min = M;
}
@@ -364,7 +310,7 @@
// Update the DSInfo map and delete the old graph...
for (DSGraph::retnodes_iterator I = NG->retnodes_begin();
I != NG->retnodes_end(); ++I)
- DSInfo[I->first] = &FG;
+ setDSGraph(*I->first, &FG);
// Remove NG from the ValMap since the pointer may get recycled.
ValMap.erase(NG);
@@ -416,19 +362,19 @@
// 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->second->isDeclaration())
+ if (!(*I)->isDeclaration())
break;
// Now check if the graph has changed and if so, clone and inline it.
if (I != E) {
- Function *CalleeFunc = I->second;
+ 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);
+ CalleeGraph = &getOrCreateGraph(CalleeFunc);
if (CalleeGraph != &G) {
++NumFoldGraphInlines;
G.mergeInGraph(CS, *CalleeFunc, *CalleeGraph,
@@ -452,8 +398,8 @@
// same graph as the one inlined above.
if (CalleeGraph)
for (++I, ++TNum; I != E; ++I, ++TNum)
- if (!I->second->isDeclaration())
- assert(CalleeGraph == &getOrCreateGraph(*I->second) &&
+ if (!(*I)->isDeclaration())
+ assert(CalleeGraph == &getOrCreateGraph(*I) &&
"Callees at a call site have different graphs?");
#endif
}
Modified: poolalloc/trunk/lib/DSA/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=57319&r1=57318&r2=57319&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Local.cpp (original)
+++ poolalloc/trunk/lib/DSA/Local.cpp Thu Oct 9 01:24:31 2008
@@ -155,7 +155,7 @@
for (DSScalarMap::global_iterator I = g.getScalarMap().global_begin();
I != g.getScalarMap().global_end(); ++I)
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
+ if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
if (!GV->isDeclaration() && GV->isConstant())
RC.merge(g.getNodeForValue(GV), g.getGlobalsGraph()->getNodeForValue(GV));
}
@@ -765,10 +765,9 @@
char LocalDataStructures::ID;
bool LocalDataStructures::runOnModule(Module &M) {
- setTargetData(getAnalysis<TargetData>());
+ init(&getAnalysis<TargetData>());
// First step, build the globals graph.
- GlobalsGraph = new DSGraph(GlobalECs, getTargetData());
{
GraphBuilder GGB(*GlobalsGraph);
@@ -788,7 +787,7 @@
if (!I->isDeclaration()) {
DSGraph* G = new DSGraph(GlobalECs, getTargetData(), GlobalsGraph);
GraphBuilder GGB(*I, *G);
- DSInfo.insert(std::make_pair(I, G));
+ setDSGraph(*I, G);
}
GlobalsGraph->removeTriviallyDeadNodes();
@@ -803,21 +802,3 @@
return false;
}
-// releaseMemory - If the pass pipeline is done with this pass, we can release
-// our memory... here...
-//
-void LocalDataStructures::releaseMemory() {
- for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
- E = DSInfo.end(); I != E; ++I) {
- I->second->getReturnNodes().erase(I->first);
- if (I->second->getReturnNodes().empty())
- delete I->second;
- }
-
- // Empty map so next time memory is released, data structures are not
- // re-deleted.
- DSInfo.clear();
- delete GlobalsGraph;
- GlobalsGraph = 0;
-}
-
Modified: poolalloc/trunk/lib/DSA/Printer.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Printer.cpp?rev=57319&r1=57318&r2=57319&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Printer.cpp (original)
+++ poolalloc/trunk/lib/DSA/Printer.cpp Thu Oct 9 01:24:31 2008
@@ -43,7 +43,7 @@
static std::string getCaption(const DSNode *N, const DSGraph *G) {
std::stringstream OS;
- Module *M = 0;
+ const Module *M = 0;
if (!G) G = N->getParentGraph();
@@ -83,7 +83,7 @@
OS << "\n";
}
- EquivalenceClasses<GlobalValue*> *GlobalECs = 0;
+ EquivalenceClasses<const GlobalValue*> *GlobalECs = 0;
if (G) GlobalECs = &G->getGlobalECs();
for (unsigned i = 0, e = N->getGlobalsList().size(); i != e; ++i) {
@@ -91,7 +91,7 @@
// Figure out how many globals are equivalent to this one.
if (GlobalECs) {
- EquivalenceClasses<GlobalValue*>::iterator I =
+ EquivalenceClasses<const GlobalValue*>::iterator I =
GlobalECs->findValue(N->getGlobalsList()[i]);
if (I != GlobalECs->end()) {
unsigned NumMembers =
@@ -147,7 +147,7 @@
///
static void addCustomGraphFeatures(const DSGraph *G,
GraphWriter<const DSGraph*> &GW) {
- Module *CurMod = 0;
+ const Module *CurMod = 0;
if (G->retnodes_begin() != G->retnodes_end())
CurMod = G->retnodes_begin()->first->getParent();
else {
@@ -286,7 +286,7 @@
bool IsDuplicateGraph = false;
if (I->getName() == "main" || !OnlyPrintMain) {
- Function *SCCFn = Gr.retnodes_begin()->first;
+ const Function *SCCFn = Gr.retnodes_begin()->first;
if (&*I == SCCFn) {
Gr.writeGraphToFile(O, Prefix+I->getName());
} else {
@@ -296,7 +296,7 @@
<< "\n";
}
} else {
- Function *SCCFn = Gr.retnodes_begin()->first;
+ const Function *SCCFn = Gr.retnodes_begin()->first;
if (&*I == SCCFn) {
O << "Skipped Writing '" << Prefix+I->getName() << ".dot'... ["
<< Gr.getGraphSize() << "+" << NumCalls << "]\n";
Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/StdLibPass.cpp?rev=57319&r1=57318&r2=57319&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original)
+++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Thu Oct 9 01:24:31 2008
@@ -31,111 +31,175 @@
char StdLibDataStructures::ID;
+#define numOps 10
+
struct libAction {
- bool ret_read, ret_write, ret_heap;
- bool args_read, args_write, args_heap;
+ bool read[numOps];
+ bool write[numOps];
+ bool heap[numOps];
bool mergeAllArgs;
bool mergeWithRet;
bool collapse;
};
+#define NRET_NARGS {0,0,0,0,0,0,0,0,0,0}
+#define YRET_NARGS {1,0,0,0,0,0,0,0,0,0}
+#define NRET_YARGS {0,1,1,1,1,1,1,1,1,1}
+#define YRET_YARGS {1,1,1,1,1,1,1,1,1,1}
+#define NRET_NYARGS {0,0,1,1,1,1,1,1,1,1}
+#define YRET_NYARGS {1,0,1,1,1,1,1,1,1,1}
+#define NRET_YNARGS {0,1,0,0,0,0,0,0,0,0}
+#define YRET_YNARGS {1,1,0,0,0,0,0,0,0,0}
+
+
const struct {
const char* name;
libAction action;
} recFuncs[] = {
- {"calloc", {false, true, true, false, false, false, false, false, false}},
- {"malloc", {false, true, true, false, false, false, false, false, false}},
- {"valloc", {false, true, true, false, false, false, false, false, false}},
- {"memalign", {false, true, true, false, false, false, false, false, false}},
- {"strdup", {false, true, true, false, false, false, false, false, true}},
- {"wcsdup", {false, true, true, false, false, false, false, false, true}},
- {"free", {false, false, false, false, true, true, false, false, false}},
- {"realloc", {false, true, true, false, true, true, false, true, true}},
- {"atoi", {false, false, false, true, false, false, false, false, false}},
- {"atof", {false, false, false, true, false, false, false, false, false}},
- {"atol", {false, false, false, true, false, false, false, false, false}},
- {"atoll", {false, false, false, true, false, false, false, false, false}},
- {"remove", {false, false, false, true, false, false, false, false, false}},
- {"unlink", {false, false, false, true, false, false, false, false, false}},
- {"rename", {false, false, false, true, false, false, false, false, false}},
- {"memcmp", {false, false, false, true, false, false, false, false, false}},
- {"strcmp", {false, false, false, true, false, false, false, false, false}},
- {"strncmp", {false, false, false, true, false, false, false, false, false}},
- {"execl", {false, false, false, true, false, false, false, false, false}},
- {"execlp", {false, false, false, true, false, false, false, false, false}},
- {"execle", {false, false, false, true, false, false, false, false, false}},
- {"execv", {false, false, false, true, false, false, false, false, false}},
- {"execvp", {false, false, false, true, false, false, false, false, false}},
- {"chmod", {false, false, false, true, false, false, false, false, false}},
- {"puts", {false, false, false, true, false, false, false, false, false}},
- {"write", {false, false, false, true, false, false, false, false, false}},
- {"open", {false, false, false, true, false, false, false, false, false}},
- {"create", {false, false, false, true, false, false, false, false, false}},
- {"truncate", {false, false, false, true, false, false, false, false, false}},
- {"chdir", {false, false, false, true, false, false, false, false, false}},
- {"mkdir", {false, false, false, true, false, false, false, false, false}},
- {"rmdir", {false, false, false, true, false, false, false, false, false}},
- {"strlen", {false, false, false, true, false, false, false, false, false}},
- {"read", {false, false, false, false, true, false, false, false, false}},
- {"pipe", {false, false, false, false, true, false, false, false, false}},
- {"wait", {false, false, false, false, true, false, false, false, false}},
- {"time", {false, false, false, false, true, false, false, false, false}},
- {"getrusage",{false, false, false, false, true, false, false, false, false}},
- {"memchr", { true, false, false, true, false, false, false, true, true}},
- {"memrchr", { true, false, false, true, false, false, false, true, true}},
- {"rawmemchr",{ true, false, false, true, false, false, false, true, true}},
- {"memmove", {false, true, false, true, true, false, true, true, true}},
- {"bcopy", {false, false, false, true, true, false, true, false, true}},
- {"strcpy", {false, true, false, true, true, false, true, true, true}},
- {"strncpy", {false, true, false, true, true, false, true, true, true}},
- {"memccpy", {false, true, false, true, true, false, true, true, true}},
- {"wcscpy", {false, true, false, true, true, false, true, true, true}},
- {"wcsncpy", {false, true, false, true, true, false, true, true, true}},
- {"wmemccpy", {false, true, false, true, true, false, true, true, true}},
+ {"stat", {NRET_YNARGS, NRET_NYARGS, NRET_NARGS, false, false, false}},
+ {"fstat", {NRET_YNARGS, NRET_NYARGS, NRET_NARGS, false, false, false}},
+ {"lstat", {NRET_YNARGS, NRET_NYARGS, NRET_NARGS, false, false, false}},
+
+ //printf not strictly true, %n could cause a write
+ {"printf", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"fprintf", {NRET_YARGS, NRET_YNARGS, NRET_NARGS, false, false, false}},
+ {"sprintf", {NRET_YARGS, NRET_YNARGS, NRET_NARGS, false, false, false}},
+ {"snprintf", {NRET_YARGS, NRET_YNARGS, NRET_NARGS, false, false, false}},
+
+ {"calloc", {NRET_NARGS, YRET_NARGS, YRET_NARGS, false, false, false}},
+ {"malloc", {NRET_NARGS, YRET_NARGS, YRET_NARGS, false, false, false}},
+ {"valloc", {NRET_NARGS, YRET_NARGS, YRET_NARGS, false, false, false}},
+ {"memalign", {NRET_NARGS, YRET_NARGS, YRET_NARGS, false, false, false}},
+ {"realloc", {NRET_NARGS, YRET_NARGS, YRET_YNARGS, false, true, true}},
+ {"free", {NRET_NARGS, NRET_NARGS, NRET_YNARGS, false, false, false}},
+
+ {"strdup", {NRET_YARGS, YRET_NARGS, YRET_NARGS, false, true, false}},
+ {"wcsdup", {NRET_YARGS, YRET_NARGS, YRET_NARGS, false, true, false}},
+
+ {"atoi", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"atof", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"atol", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"atoll", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"atoq", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+
+ {"strcmp", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"wcscmp", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"strncmp", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"wcsncmp", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"strcasecmp", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"wcscasecmp", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"strncasecmp",{NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"wcsncasecmp",{NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"strlen", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+ {"wcslen", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+
+ {"memchr", {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+ {"wmemchr", {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+ {"memrchr", {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+ {"strchr", {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+ {"wcschr", {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+ {"strrchr", {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+ {"wcsrchr", {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+ {"strchrhul", {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+
+
+#if 0
+ {"remove", {false, false, false, true, false, false, false, false, false}},
+ {"unlink", {false, false, false, true, false, false, false, false, false}},
+ {"rename", {false, false, false, true, false, false, false, false, false}},
+ {"memcmp", {false, false, false, true, false, false, false, false, false}},
+ {"execl", {false, false, false, true, false, false, false, false, false}},
+ {"execlp", {false, false, false, true, false, false, false, false, false}},
+ {"execle", {false, false, false, true, false, false, false, false, false}},
+ {"execv", {false, false, false, true, false, false, false, false, false}},
+ {"execvp", {false, false, false, true, false, false, false, false, false}},
+ {"chmod", {false, false, false, true, false, false, false, false, false}},
+ {"puts", {false, false, false, true, false, false, false, false, false}},
+ {"write", {false, false, false, true, false, false, false, false, false}},
+ {"open", {false, false, false, true, false, false, false, false, false}},
+ {"create", {false, false, false, true, false, false, false, false, false}},
+ {"truncate", {false, false, false, true, false, false, false, false, false}},
+ {"chdir", {false, false, false, true, false, false, false, false, false}},
+ {"mkdir", {false, false, false, true, false, false, false, false, false}},
+ {"rmdir", {false, false, false, true, false, false, false, false, false}},
+ {"read", {false, false, false, false, true, false, false, false, false}},
+ {"pipe", {false, false, false, false, true, false, false, false, false}},
+ {"wait", {false, false, false, false, true, false, false, false, false}},
+ {"time", {false, false, false, false, true, false, false, false, false}},
+ {"getrusage", {false, false, false, false, true, false, false, false, false}},
+ {"memmove", {false, true, false, true, true, false, true, true, true}},
+ {"bcopy", {false, false, false, true, true, false, true, false, true}},
+ {"strcpy", {false, true, false, true, true, false, true, true, true}},
+ {"strncpy", {false, true, false, true, true, false, true, true, true}},
+ {"memccpy", {false, true, false, true, true, false, true, true, true}},
+ {"wcscpy", {false, true, false, true, true, false, true, true, true}},
+ {"wcsncpy", {false, true, false, true, true, false, true, true, true}},
+ {"wmemccpy", {false, true, false, true, true, false, true, true, true}},
+ {"fclose", {false, false, false, true, true, false, false, false, false}},
+ {"fopen", {false, true, true, true, false, false, false, false, false}},
+ {"getcwd", { true, true, true, true, true, true, false, true, true}},
+#endif
+ //C++ functions, as mangled on linux gcc 4.2
+ //operator new(unsigned long)
+ {"_Znwm", {NRET_NARGS, YRET_NARGS, YRET_NARGS, false, false, false}},
+ //operator new[](unsigned long)
+ {"_Znam", {NRET_NARGS, YRET_NARGS, YRET_NARGS, false, false, false}},
+ //operator delete(void*)
+ {"_ZdlPv", {NRET_NARGS, NRET_NARGS, NRET_YNARGS, false, false, false}},
+ //operator delete[](void*)
+ {"_ZdaPv", {NRET_NARGS, NRET_NARGS, NRET_YNARGS, false, false, false}},
+
};
-bool StdLibDataStructures::runOnModule(Module &M) {
- LocalDataStructures &LocalDSA = getAnalysis<LocalDataStructures>();
- setGraphSource(&LocalDSA);
- setTargetData(LocalDSA.getTargetData());
- setGraphClone(false);
- GlobalECs = LocalDSA.getGlobalECs();
+void StdLibDataStructures::eraseCallsTo(Function* F) {
+ for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
+ ii != ee; ++ii)
+ if (CallInst* CI = dyn_cast<CallInst>(ii))
+ if (CI->getOperand(0) == F) {
+ DSGraph& Graph = getDSGraph(*CI->getParent()->getParent());
+ //delete the call
+ DOUT << "Removing " << F->getName() << " from " << CI->getParent()->getParent()->getName() << "\n";
+ Graph.removeFunctionCalls(*F);
+ }
+}
- GlobalsGraph = new DSGraph(LocalDSA.getGlobalsGraph(), GlobalECs);
- GlobalsGraph->setPrintAuxCalls();
+bool StdLibDataStructures::runOnModule(Module &M) {
+ init(&getAnalysis<LocalDataStructures>(), false, true);
//Clone Module
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isDeclaration())
getOrCreateGraph(&*I);
+ //Functions we handle by summary
+
for (int x = 0; recFuncs[x].name; ++x)
if (Function* F = M.getFunction(recFuncs[x].name))
- if (F->isDeclaration())
+ if (F->isDeclaration()) {
for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
ii != ee; ++ii)
if (CallInst* CI = dyn_cast<CallInst>(ii))
if (CI->getOperand(0) == F) {
DSGraph& Graph = getDSGraph(*CI->getParent()->getParent());
- if (recFuncs[x].action.ret_read)
+ if (recFuncs[x].action.read[0])
Graph.getNodeForValue(CI).getNode()->setReadMarker();
- if (recFuncs[x].action.ret_write)
+ if (recFuncs[x].action.write[0])
Graph.getNodeForValue(CI).getNode()->setModifiedMarker();
- if (recFuncs[x].action.ret_heap)
+ if (recFuncs[x].action.heap[0])
Graph.getNodeForValue(CI).getNode()->setHeapMarker();
- if (recFuncs[x].action.args_read)
- for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+ for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+ if (recFuncs[x].action.read[y])
if (isa<PointerType>(CI->getOperand(y)->getType()))
if (DSNode * Node=Graph.getNodeForValue(CI->getOperand(y)).getNode())
Node->setReadMarker();
- if (recFuncs[x].action.args_write)
- for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+ for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+ if (recFuncs[x].action.write[y])
if (isa<PointerType>(CI->getOperand(y)->getType()))
if (DSNode * Node=Graph.getNodeForValue(CI->getOperand(y)).getNode())
Node->setModifiedMarker();
- if (recFuncs[x].action.args_heap)
- for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+ for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+ if (recFuncs[x].action.heap[y])
if (isa<PointerType>(CI->getOperand(y)->getType()))
if (DSNode * Node=Graph.getNodeForValue(CI->getOperand(y)).getNode())
Node->setHeapMarker();
@@ -156,32 +220,19 @@
for (unsigned y = 1; y < CI->getNumOperands(); ++y)
if (isa<PointerType>(CI->getOperand(y)->getType()))
if (DSNode * Node=Graph.getNodeForValue(CI->getOperand(y)).getNode())
- Node->foldNodeCompletely();
+ Node->foldNodeCompletely();
}
-
+ }
+ for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
+ ii != ee; ++ii)
+ if (CallInst* CI = dyn_cast<CallInst>(ii))
+ if (CI->getOperand(0) == F) {
+ DSGraph& Graph = getDSGraph(*CI->getParent()->getParent());
//delete the call
DOUT << "Removing " << F->getName() << " from " << CI->getParent()->getParent()->getName() << "\n";
Graph.removeFunctionCalls(*F);
}
+ }
return false;
}
-
-// releaseMemory - If the pass pipeline is done with this pass, we can release
-// our memory... here...
-//
-void StdLibDataStructures::releaseMemory() {
- for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
- E = DSInfo.end(); I != E; ++I) {
- I->second->getReturnNodes().erase(I->first);
- if (I->second->getReturnNodes().empty())
- delete I->second;
- }
-
- // Empty map so next time memory is released, data structures are not
- // re-deleted.
- DSInfo.clear();
- delete GlobalsGraph;
- GlobalsGraph = 0;
-}
-
Modified: poolalloc/trunk/lib/DSA/Steensgaard.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Steensgaard.cpp?rev=57319&r1=57318&r2=57319&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Steensgaard.cpp (original)
+++ poolalloc/trunk/lib/DSA/Steensgaard.cpp Thu Oct 9 01:24:31 2008
@@ -27,7 +27,7 @@
class Steens : public ModulePass, public AliasAnalysis {
DSGraph *ResultGraph;
- EquivalenceClasses<GlobalValue*> GlobalECs; // Always empty
+ EquivalenceClasses<const GlobalValue*> GlobalECs; // Always empty
public:
static char ID;
Steens() : ModulePass((intptr_t)&ID), ResultGraph(0) {}
@@ -73,7 +73,7 @@
virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2);
private:
- void ResolveFunctionCall(Function *F, const DSCallSite &Call,
+ void ResolveFunctionCall(const Function *F, const DSCallSite &Call,
DSNodeHandle &RetVal);
};
@@ -93,7 +93,7 @@
/// with the specified call site descriptor. This function links the arguments
/// and the return value for the call site context-insensitively.
///
-void Steens::ResolveFunctionCall(Function *F, const DSCallSite &Call,
+void Steens::ResolveFunctionCall(const Function *F, const DSCallSite &Call,
DSNodeHandle &RetVal) {
assert(ResultGraph != 0 && "Result graph not allocated!");
DSGraph::ScalarMapTy &ValMap = ResultGraph->getScalarMap();
@@ -104,7 +104,7 @@
// Loop over all pointer arguments, resolving them to their provided pointers
unsigned PtrArgIdx = 0;
- for (Function::arg_iterator AI = F->arg_begin(), AE = F->arg_end();
+ for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
AI != AE && PtrArgIdx < Call.getNumPtrArgs(); ++AI) {
DSGraph::ScalarMapTy::iterator I = ValMap.find(AI);
if (I != ValMap.end()) // If its a pointer argument...
@@ -150,7 +150,7 @@
DSCallSite &CurCall = *CI++;
// Loop over the called functions, eliminating as many as possible...
- std::vector<Function*> CallTargets;
+ std::vector<const Function*> CallTargets;
if (CurCall.isDirectCall())
CallTargets.push_back(CurCall.getCalleeFunc());
else
@@ -158,7 +158,7 @@
for (unsigned c = 0; c != CallTargets.size(); ) {
// If we can eliminate this function call, do so!
- Function *F = CallTargets[c];
+ const Function *F = CallTargets[c];
if (!F->isDeclaration()) {
ResolveFunctionCall(F, CurCall, ResultGraph->getReturnNodes()[F]);
CallTargets[c] = CallTargets.back();
Modified: poolalloc/trunk/lib/DSA/TopDownClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/TopDownClosure.cpp?rev=57319&r1=57318&r2=57319&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/TopDownClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/TopDownClosure.cpp Thu Oct 9 01:24:31 2008
@@ -48,7 +48,7 @@
for (unsigned i = 0, e = N->getNumLinks(); i != e; ++i) {
DSNodeHandle &NH = N->getLink(i*N->getPointerSize());
if (DSNode *NN = NH.getNode()) {
- std::vector<Function*> Functions;
+ std::vector<const Function*> Functions;
NN->addFullFunctionList(Functions);
ArgsRemainIncomplete.insert(Functions.begin(), Functions.end());
markReachableFunctionsExternallyAccessible(NN, Visited);
@@ -61,14 +61,7 @@
// program.
//
bool TDDataStructures::runOnModule(Module &M) {
- BUInfo = &getAnalysis<BUDataStructures>();
- setGraphSource(BUInfo);
- setTargetData(BUInfo->getTargetData());
- setGraphClone(true);
-
- GlobalECs = BUInfo->getGlobalECs();
- GlobalsGraph = new DSGraph(BUInfo->getGlobalsGraph(), GlobalECs);
- GlobalsGraph->setPrintAuxCalls();
+ init(&getAnalysis<BUDataStructures>(), true, true);
// Figure out which functions must not mark their arguments complete because
// they are accessible outside this compilation unit. Currently, these
@@ -144,7 +137,8 @@
}
-void TDDataStructures::ComputePostOrder(Function &F,hash_set<DSGraph*> &Visited,
+void TDDataStructures::ComputePostOrder(const Function &F,
+ hash_set<DSGraph*> &Visited,
std::vector<DSGraph*> &PostOrder) {
if (F.isDeclaration()) return;
DSGraph &G = getOrCreateGraph(&F);
@@ -154,39 +148,14 @@
// Recursively traverse all of the callee graphs.
for (DSGraph::fc_iterator CI = G.fc_begin(), CE = G.fc_end(); CI != CE; ++CI){
Instruction *CallI = CI->getCallSite().getInstruction();
- for (BUDataStructures::callee_iterator I = BUInfo->callee_begin(CallI),
- E = BUInfo->callee_end(CallI); I != E; ++I)
- ComputePostOrder(*I->second, Visited, PostOrder);
+ for (callee_iterator I = callee_begin(CallI),
+ E = callee_end(CallI); I != E; ++I)
+ ComputePostOrder(**I, Visited, PostOrder);
}
PostOrder.push_back(&G);
}
-
-
-
-
-// releaseMemory - If the pass pipeline is done with this pass, we can release
-// our memory... here...
-//
-// FIXME: This should be releaseMemory and will work fine, except that LoadVN
-// has no way to extend the lifetime of the pass, which screws up ds-aa.
-//
-void TDDataStructures::releaseMyMemory() {
- for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
- E = DSInfo.end(); I != E; ++I) {
- I->second->getReturnNodes().erase(I->first);
- if (I->second->getReturnNodes().empty())
- delete I->second;
- }
-
- // Empty map so next time memory is released, data structures are not
- // re-deleted.
- DSInfo.clear();
- delete GlobalsGraph;
- GlobalsGraph = 0;
-}
-
/// InlineCallersIntoGraph - Inline all of the callers of the specified DS graph
/// into it, then recompute completeness of nodes in the resultant graph.
void TDDataStructures::InlineCallersIntoGraph(DSGraph &DSG) {
@@ -235,7 +204,7 @@
// Inline all call sites from this caller graph.
do {
const DSCallSite &CS = *EdgesFromCaller.back().CS;
- Function &CF = *EdgesFromCaller.back().CalledFunction;
+ const Function &CF = *EdgesFromCaller.back().CalledFunction;
DOUT << " [TD] Inlining graph into Fn '" << CF.getName() << "' from ";
if (CallerGraph.getReturnNodes().empty())
DOUT << "SYNTHESIZED INDIRECT GRAPH";
@@ -300,21 +269,21 @@
Instruction *CallI = CI->getCallSite().getInstruction();
// For each function in the invoked function list at this call site...
- BUDataStructures::callee_iterator IPI =
- BUInfo->callee_begin(CallI), IPE = BUInfo->callee_end(CallI);
+ callee_iterator IPI =
+ callee_begin(CallI), IPE = callee_end(CallI);
// Skip over all calls to this graph (SCC calls).
- while (IPI != IPE && &getDSGraph(*IPI->second) == &DSG)
+ while (IPI != IPE && &getDSGraph(**IPI) == &DSG)
++IPI;
// All SCC calls?
if (IPI == IPE) continue;
- Function *FirstCallee = IPI->second;
+ const Function *FirstCallee = *IPI;
++IPI;
// Skip over more SCC calls.
- while (IPI != IPE && &getDSGraph(*IPI->second) == &DSG)
+ while (IPI != IPE && &getDSGraph(**IPI) == &DSG)
++IPI;
// If there is exactly one callee from this call site, remember the edge in
@@ -331,15 +300,14 @@
// this set of targets. If so, we don't want to do M*N inlining operations,
// so we build up a new, private, graph that represents the calls of all
// calls to this set of functions.
- std::vector<Function*> Callees;
- for (BUDataStructures::ActualCalleesTy::const_iterator I =
- BUInfo->callee_begin(CallI), E = BUInfo->callee_end(CallI);
+ std::vector<const Function*> Callees;
+ for (callee_iterator I = callee_begin(CallI), E = callee_end(CallI);
I != E; ++I)
- if (!I->second->isDeclaration())
- Callees.push_back(I->second);
+ if (!(*I)->isDeclaration())
+ Callees.push_back(*I);
std::sort(Callees.begin(), Callees.end());
- std::map<std::vector<Function*>, DSGraph*>::iterator IndCallRecI =
+ std::map<std::vector<const Function*>, DSGraph*>::iterator IndCallRecI =
IndCallMap.lower_bound(Callees);
DSGraph *IndCallGraph;
Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=57319&r1=57318&r2=57319&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Thu Oct 9 01:24:31 2008
@@ -393,6 +393,7 @@
OldFuncTy->isVarArg());
// Create the new function...
Function *New = Function::Create(FuncTy, Function::InternalLinkage, F.getName());
+ New->copyAttributesFrom(&F);
F.getParent()->getFunctionList().insert(&F, New);
CloneToOrigMap[New] = &F; // Remember original function.
Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp?rev=57319&r1=57318&r2=57319&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Thu Oct 9 01:24:31 2008
@@ -70,9 +70,15 @@
void visitMemAlignCall(CallSite CS);
void visitStrdupCall(CallSite CS);
void visitFreeInst(FreeInst &FI);
- void visitCallSite(CallSite CS);
- void visitCallInst(CallInst &CI) { visitCallSite(&CI); }
- void visitInvokeInst(InvokeInst &II) { visitCallSite(&II); }
+ void visitCallSite(CallSite &CS);
+ void visitCallInst(CallInst &CI) {
+ CallSite CS(&CI);
+ visitCallSite(CS);
+ }
+ void visitInvokeInst(InvokeInst &II) {
+ CallSite CS(&II);
+ visitCallSite(CS);
+ }
void visitLoadInst(LoadInst &I);
void visitStoreInst (StoreInst &I);
@@ -532,8 +538,8 @@
}
-void FuncTransform::visitCallSite(CallSite CS) {
- Function *CF = CS.getCalledFunction();
+void FuncTransform::visitCallSite(CallSite& CS) {
+ const Function *CF = CS.getCalledFunction();
Instruction *TheCall = CS.getInstruction();
// If the called function is casted from one function type to another, peer
@@ -614,11 +620,10 @@
if (!CF)
for (EquivClassGraphs::callee_iterator I = ECGraphs.callee_begin(OrigInst),
- E = ECGraphs.callee_end(OrigInst); I != E; ++I)
- if (I->second) {
- CF = I->second;
- break;
- }
+ E = ECGraphs.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.
@@ -627,11 +632,11 @@
if (!CF) {
DSGraph* dg = &ECGraphs.getDSGraph(*OrigInst->getParent()->getParent());
DSNode* d = dg->getNodeForValue(OrigInst->getOperand(0)).getNode();
- const std::vector<GlobalValue*> &g = d->getGlobalsList();
- for(std::vector<GlobalValue*>::const_iterator ii = g.begin(), ee = g.end();
+ 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< GlobalValue *> & EC = ECGraphs.getGlobalECs();
- for (EquivalenceClasses<GlobalValue *>::member_iterator MI = EC.findLeader(*ii);
+ EquivalenceClasses< const GlobalValue *> & EC = ECGraphs.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))) {
std::cerr << "\n***\nPA: *** WARNING (FuncTransform::visitCallSite): "
@@ -654,6 +659,7 @@
std::cerr << "\n***\nPA: *** WARNING (FuncTransform::visitCallSite): "
<< "Unknown callees for call-site in function "
<< CS.getCaller()->getName() << "\n***\n";
+ abort();
return;
}
@@ -665,8 +671,8 @@
EquivClassGraphs::callee_iterator I =
ECGraphs.callee_begin(OrigInst), E = ECGraphs.callee_end(OrigInst);
for (; I != E; ++I)
- if (!I->second->isDeclaration())
- assert(CalleeGraph == &ECGraphs.getDSGraph(*I->second) &&
+ if (!(*I)->isDeclaration())
+ assert(CalleeGraph == &ECGraphs.getDSGraph(**I) &&
"Callees at call site do not have a common graph!");
#endif
@@ -692,7 +698,7 @@
NewCallee = CastInst::createPointerCast(CS.getCalledValue(), PFTy, "tmp", TheCall);
}
- Function::arg_iterator FAI = CF->arg_begin(), E = CF->arg_end();
+ Function::const_arg_iterator FAI = CF->arg_begin(), E = CF->arg_end();
CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
for ( ; FAI != E && AI != AE; ++FAI, ++AI)
if (!isa<Constant>(*AI))
More information about the llvm-commits
mailing list