Added a first-class representation for each call site that can be

used in the DS graphs.  Essentially, what was vector<DSNodeHandle>
before is now a DSCallSite with the same vector, plus pointers to the
CallInst and the caller Function.  The special-purpose class
BUDataStructure::CallSite is no longer needed.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4228 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Vikram S. Adve 2002-10-20 18:07:37 +00:00
parent 726bafda65
commit 42fd169310
6 changed files with 77 additions and 61 deletions

View File

@ -56,7 +56,7 @@ bool BUDataStructures::run(Module &M) {
// ResolveArguments - Resolve the formal and actual arguments for a function
// call.
//
static void ResolveArguments(std::vector<DSNodeHandle> &Call, Function &F,
static void ResolveArguments(DSCallSite &Call, Function &F,
map<Value*, DSNodeHandle> &ValueMap) {
// Resolve all of the function arguments...
Function::aiterator AI = F.abegin();
@ -87,7 +87,7 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
#endif
// Start resolving calls...
std::vector<std::vector<DSNodeHandle> > &FCs = Graph->getFunctionCalls();
std::vector<DSCallSite> &FCs = Graph->getFunctionCalls();
DEBUG(std::cerr << " [BU] Inlining: " << F.getName() << "\n");
@ -97,14 +97,14 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
for (unsigned i = 0; i != FCs.size(); ++i) {
// Copy the call, because inlining graphs may invalidate the FCs vector.
std::vector<DSNodeHandle> Call = FCs[i];
DSCallSite Call = FCs[i];
// If the function list is complete...
if ((Call[1].getNode()->NodeType & DSNode::Incomplete) == 0) {
if ((Call.getCalleeNode().getNode()->NodeType & DSNode::Incomplete)==0) {
// Start inlining all of the functions we can... some may not be
// inlinable if they are external...
//
std::vector<GlobalValue*> Callees(Call[1].getNode()->getGlobals());
std::vector<GlobalValue*> Callees(Call.getCalleeNode().getNode()->getGlobals());
// Loop over the functions, inlining whatever we can...
for (unsigned c = 0; c != Callees.size(); ++c) {
@ -112,7 +112,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
Function &FI = cast<Function>(*Callees[c]);
// Record that this is a call site of FI.
CallSites[&FI].push_back(CallSite(F, Call));
assert(&Call.getCaller() == &F && "Invalid caller in DSCallSite?");
CallSites[&FI].push_back(DSCallSite(Call));
if (&FI == &F) {
// Self recursion... simply link up the formal arguments with the
@ -120,8 +121,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
DEBUG(std::cerr << "\t[BU] Self Inlining: " << F.getName() << "\n");
if (Call[0].getNode()) // Handle the return value if present...
Graph->getRetNode().mergeWith(Call[0]);
if (Call.getReturnValueNode().getNode()) // Handle the return value if present...
Graph->getRetNode().mergeWith(Call.getReturnValueNode());
// Resolve the arguments in the call to the actual values...
ResolveArguments(Call, F, Graph->getValueMap());
@ -159,8 +160,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
// Resolve the arguments in the call to the actual values...
ResolveArguments(Call, FI, OldValMap);
if (Call[0].getNode()) // Handle the return value if present
RetVal.mergeWith(Call[0]);
if (Call.getReturnValueNode().getNode()) // Handle the return value if present
RetVal.mergeWith(Call.getReturnValueNode());
// Erase the entry in the Callees vector
Callees.erase(Callees.begin()+c--);
@ -178,7 +179,7 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
// Erase the call if it is resolvable...
FCs.erase(FCs.begin()+i--); // Don't skip a the next call...
Inlined = true;
} else if (Callees.size() != Call[1].getNode()->getGlobals().size()) {
} else if (Callees.size() != Call.getCalleeNode().getNode()->getGlobals().size()) {
// Was able to inline SOME, but not all of the functions. Construct a
// new global node here.
//

View File

@ -351,6 +351,21 @@ void DSNode::mergeWith(const DSNodeHandle &NH, unsigned Offset) {
}
}
template<typename _CopierFunction>
DSCallSite::DSCallSite(const DSCallSite& FromCall,
_CopierFunction nodeCopier)
: std::vector<DSNodeHandle>(),
caller(&FromCall.getCaller()),
callInst(&FromCall.getCallInst()) {
reserve(FromCall.size());
for (unsigned j = 0, ej = FromCall.size(); j != ej; ++j)
push_back((&nodeCopier == (_CopierFunction*) 0)? DSNodeHandle(FromCall[j])
: nodeCopier(&FromCall[j]));
}
//===----------------------------------------------------------------------===//
// DSGraph Implementation
//===----------------------------------------------------------------------===//
@ -378,23 +393,22 @@ DSGraph::~DSGraph() {
// dump - Allow inspection of graph in a debugger.
void DSGraph::dump() const { print(std::cerr); }
// Helper function used to clone a function list.
//
static void CopyFunctionCallsList(const vector<vector<DSNodeHandle> >&fromCalls,
vector<vector<DSNodeHandle> > &toCalls,
std::map<const DSNode*, DSNode*> &NodeMap) {
DSNodeHandle copyHelper(const DSNodeHandle* fromNode,
std::map<const DSNode*, DSNode*> *NodeMap) {
return DSNodeHandle((*NodeMap)[fromNode->getNode()], fromNode->getOffset());
}
// Helper function used to clone a function list.
//
static void CopyFunctionCallsList(const vector<DSCallSite>& fromCalls,
vector<DSCallSite> &toCalls,
std::map<const DSNode*, DSNode*> &NodeMap) {
unsigned FC = toCalls.size(); // FirstCall
toCalls.reserve(FC+fromCalls.size());
for (unsigned i = 0, ei = fromCalls.size(); i != ei; ++i) {
toCalls.push_back(vector<DSNodeHandle>());
const vector<DSNodeHandle> &CurCall = fromCalls[i];
toCalls.back().reserve(CurCall.size());
for (unsigned j = 0, ej = fromCalls[i].size(); j != ej; ++j)
toCalls[FC+i].push_back(DSNodeHandle(NodeMap[CurCall[j].getNode()],
CurCall[j].getOffset()));
}
for (unsigned i = 0, ei = fromCalls.size(); i != ei; ++i)
toCalls.push_back(DSCallSite(fromCalls[i],
std::bind2nd(std::ptr_fun(&copyHelper), &NodeMap)));
}
/// remapLinks - Change all of the Links in the current node according to the
@ -404,6 +418,7 @@ void DSNode::remapLinks(std::map<const DSNode*, DSNode*> &OldNodeMap) {
Links[i].setNode(OldNodeMap[Links[i].getNode()]);
}
// cloneInto - Clone the specified DSGraph into the current graph, returning the
// Return node of the graph. The translated ValueMap for the old function is
// filled into the OldValMap member. If StripLocals is set to true, Scalar and
@ -532,9 +547,9 @@ void DSGraph::markIncompleteNodes(bool markFormalArgs) {
// Mark stuff passed into functions calls as being incomplete...
for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
vector<DSNodeHandle> &Args = FunctionCalls[i];
DSCallSite &Args = FunctionCalls[i];
// Then the return value is certainly incomplete!
markIncompleteNode(Args[0].getNode());
markIncompleteNode(Args.getReturnValueNode().getNode());
// The call does not make the function argument incomplete...
@ -590,7 +605,7 @@ bool DSGraph::isNodeDead(DSNode *N) {
return false;
}
static void removeIdenticalCalls(vector<vector<DSNodeHandle> > &Calls,
static void removeIdenticalCalls(vector<DSCallSite> &Calls,
const std::string &where) {
// Remove trivially identical function calls
unsigned NumFns = Calls.size();
@ -665,7 +680,7 @@ static bool checkGlobalAlive(DSNode *N, std::set<DSNode*> &Alive,
// the simple iterative loop in the first few lines below suffice.
//
static void markGlobalsIteration(std::set<DSNode*>& GlobalNodes,
vector<vector<DSNodeHandle> > &Calls,
vector<DSCallSite> &Calls,
std::set<DSNode*> &Alive,
bool FilterCalls) {
@ -723,7 +738,7 @@ static void markGlobalsAlive(DSGraph &G, std::set<DSNode*> &Alive,
GlobalNodes.insert(G.getNodes()[i]);
// Add all call nodes to the same set
vector<vector<DSNodeHandle> > &Calls = G.getFunctionCalls();
vector<DSCallSite> &Calls = G.getFunctionCalls();
if (FilterCalls) {
for (unsigned i = 0, e = Calls.size(); i != e; ++i)
for (unsigned j = 0, e = Calls[i].size(); j != e; ++j)
@ -963,15 +978,15 @@ void GlobalDSGraph::cloneGlobals(DSGraph& Graph, bool CloneCalls) {
//
void GlobalDSGraph::cloneCalls(DSGraph& Graph) {
std::map<const DSNode*, DSNode*> NodeCache;
vector<vector<DSNodeHandle> >& FromCalls =Graph.FunctionCalls;
vector<DSCallSite >& FromCalls =Graph.FunctionCalls;
FunctionCalls.reserve(FunctionCalls.size() + FromCalls.size());
for (int i = 0, ei = FromCalls.size(); i < ei; ++i) {
FunctionCalls.push_back(vector<DSNodeHandle>());
FunctionCalls.back().reserve(FromCalls[i].size());
DSCallSite& callCopy = FunctionCalls.back();
callCopy.reserve(FromCalls[i].size());
for (unsigned j = 0, ej = FromCalls[i].size(); j != ej; ++j)
FunctionCalls.back().push_back
callCopy.push_back
((FromCalls[i][j] && (FromCalls[i][j]->NodeType & ExternalTypeBits))
? cloneNodeInto(FromCalls[i][j], NodeCache, true)
: 0);

View File

@ -61,12 +61,12 @@ namespace {
vector<DSNode*> &Nodes;
DSNodeHandle &RetNode; // Node that gets returned...
map<Value*, DSNodeHandle> &ValueMap;
vector<vector<DSNodeHandle> > &FunctionCalls;
vector<DSCallSite> &FunctionCalls;
public:
GraphBuilder(DSGraph &g, vector<DSNode*> &nodes, DSNodeHandle &retNode,
map<Value*, DSNodeHandle> &vm,
vector<vector<DSNodeHandle> > &fc)
vector<DSCallSite> &fc)
: G(g), Nodes(nodes), RetNode(retNode), ValueMap(vm), FunctionCalls(fc) {
// Create scalar nodes for all pointer arguments...
@ -356,8 +356,8 @@ void GraphBuilder::visitReturnInst(ReturnInst &RI) {
void GraphBuilder::visitCallInst(CallInst &CI) {
// Add a new function call entry...
FunctionCalls.push_back(vector<DSNodeHandle>());
vector<DSNodeHandle> &Args = FunctionCalls.back();
FunctionCalls.push_back(DSCallSite(G.getFunction(), CI));
DSCallSite &Args = FunctionCalls.back();
// Set up the return value...
if (isPointerType(CI.getType()))

View File

@ -105,9 +105,9 @@ struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
}
// Output all of the call nodes...
const std::vector<std::vector<DSNodeHandle> > &FCs = G->getFunctionCalls();
const std::vector<DSCallSite> &FCs = G->getFunctionCalls();
for (unsigned i = 0, e = FCs.size(); i != e; ++i) {
const std::vector<DSNodeHandle> &Call = FCs[i];
const DSCallSite &Call = FCs[i];
GW.emitSimpleNode(&Call, "shape=record", "call", Call.size());
for (unsigned j = 0, e = Call.size(); j != e; ++j)

View File

@ -63,7 +63,7 @@ namespace {
}
private:
void ResolveFunctionCall(Function *F, const std::vector<DSNodeHandle> &Call,
void ResolveFunctionCall(Function *F, const DSCallSite &Call,
DSNodeHandle &RetVal);
};
@ -81,14 +81,14 @@ namespace {
/// and the return value for the call site context-insensitively.
///
void Steens::ResolveFunctionCall(Function *F,
const std::vector<DSNodeHandle> &Call,
const DSCallSite &Call,
DSNodeHandle &RetVal) {
assert(ResultGraph != 0 && "Result graph not allocated!");
std::map<Value*, DSNodeHandle> &ValMap = ResultGraph->getValueMap();
// Handle the return value of the function... which is Call[0]
if (Call[0].getNode() && RetVal.getNode())
RetVal.mergeWith(Call[0]);
// Handle the return value of the function...
if (Call.getReturnValueNode().getNode() && RetVal.getNode())
RetVal.mergeWith(Call.getReturnValueNode());
// Loop over all pointer arguments, resolving them to their provided pointers
unsigned ArgIdx = 2; // Skip retval and function to call...
@ -154,13 +154,13 @@ bool Steens::run(Module &M) {
// Now that we have all of the graphs inlined, we can go about eliminating
// call nodes...
//
std::vector<std::vector<DSNodeHandle> > &Calls =
std::vector<DSCallSite> &Calls =
ResultGraph->getFunctionCalls();
for (unsigned i = 0; i != Calls.size(); ) {
std::vector<DSNodeHandle> &CurCall = Calls[i];
DSCallSite &CurCall = Calls[i];
// Loop over the called functions, eliminating as many as possible...
std::vector<GlobalValue*> CallTargets = CurCall[1].getNode()->getGlobals();
std::vector<GlobalValue*> CallTargets = CurCall.getCalleeNode().getNode()->getGlobals();
for (unsigned c = 0; c != CallTargets.size(); ) {
// If we can eliminate this function call, do so!
bool Eliminated = false;

View File

@ -48,24 +48,24 @@ bool TDDataStructures::run(Module &M) {
/// local to the specified graph.
///
void TDDataStructures::ResolveCallSite(DSGraph &Graph,
const BUDataStructures::CallSite &CallSite) {
const DSCallSite &CallSite) {
// Resolve all of the function formal arguments...
Function &F = Graph.getFunction();
Function::aiterator AI = F.abegin();
for (unsigned i = 2, e = CallSite.Context.size(); i != e; ++i, ++AI) {
for (unsigned i = 2, e = CallSite.size(); i != e; ++i, ++AI) {
// Advance the argument iterator to the first pointer argument...
while (!DataStructureAnalysis::isPointerType(AI->getType())) ++AI;
// TD ...Merge the formal arg scalar with the actual arg node
DSNodeHandle &NodeForFormal = Graph.getNodeForValue(AI);
if (NodeForFormal.getNode())
NodeForFormal.mergeWith(CallSite.Context[i]);
NodeForFormal.mergeWith(CallSite[i]);
}
// Merge returned node in the caller with the "return" node in callee
if (CallSite.Context[0].getNode() && Graph.getRetNode().getNode())
Graph.getRetNode().mergeWith(CallSite.Context[0]);
if (CallSite.getReturnValueNode().getNode() && Graph.getRetNode().getNode())
Graph.getRetNode().mergeWith(CallSite.getReturnValueNode());
}
DSGraph &TDDataStructures::calculateGraph(Function &F) {
@ -79,7 +79,7 @@ DSGraph &TDDataStructures::calculateGraph(Function &F) {
DSGraph &BUGraph = BU.getDSGraph(F);
Graph = new DSGraph(BUGraph);
const vector<BUDataStructures::CallSite> *CallSitesP = BU.getCallSites(F);
const vector<DSCallSite> *CallSitesP = BU.getCallSites(F);
if (CallSitesP == 0) {
DEBUG(std::cerr << " [TD] No callers for: " << F.getName() << "\n");
return *Graph; // If no call sites, the graph is the same as the BU graph!
@ -89,10 +89,10 @@ DSGraph &TDDataStructures::calculateGraph(Function &F) {
// graph.
//
DEBUG(std::cerr << " [TD] Inlining callers for: " << F.getName() << "\n");
const vector<BUDataStructures::CallSite> &CallSites = *CallSitesP;
const vector<DSCallSite> &CallSites = *CallSitesP;
for (unsigned c = 0, ce = CallSites.size(); c != ce; ++c) {
const BUDataStructures::CallSite &CallSite = CallSites[c]; // Copy
Function &Caller = *CallSite.Caller;
const DSCallSite &CallSite = CallSites[c]; // Copy
Function &Caller = CallSite.getCaller();
assert(!Caller.isExternal() && "Externals function cannot 'call'!");
DEBUG(std::cerr << "\t [TD] Inlining caller #" << c << " '"
@ -128,10 +128,10 @@ DSGraph &TDDataStructures::calculateGraph(Function &F) {
// Make a temporary copy of the call site, and transform the argument node
// pointers.
BUDataStructures::CallSite TmpCallSite = CallSite;
for (unsigned i = 0, e = CallSite.Context.size(); i != e; ++i) {
const DSNode *OldNode = TmpCallSite.Context[i].getNode();
TmpCallSite.Context[i].setNode(OldNodeMap[OldNode]);
DSCallSite TmpCallSite = CallSite;
for (unsigned i = 0, e = CallSite.size(); i != e; ++i) {
const DSNode *OldNode = TmpCallSite[i].getNode();
TmpCallSite[i].setNode(OldNodeMap[OldNode]);
}
ResolveCallSite(*Graph, CallSite);