- Make DSCallSite not inherit from std::vector. Renamed methods slightly.

Make copy ctor have two versions to avoid dealing with conditional template
    argument.  DSCallSite ctor now takes all arguments instead of taking one
    and being populated later.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4240 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2002-10-21 02:08:03 +00:00
parent 0c8d73b74c
commit 0969c50cb8
8 changed files with 209 additions and 100 deletions

View File

@ -47,6 +47,7 @@ public:
bool operator<(const DSNodeHandle &H) const { // Allow sorting bool operator<(const DSNodeHandle &H) const { // Allow sorting
return N < H.N || (N == H.N && Offset < H.Offset); return N < H.N || (N == H.N && Offset < H.Offset);
} }
bool operator>(const DSNodeHandle &H) const { return H < *this; }
bool operator==(const DSNodeHandle &H) const { // Allow comparison bool operator==(const DSNodeHandle &H) const { // Allow comparison
return N == H.N && Offset == H.Offset; return N == H.N && Offset == H.Offset;
} }
@ -361,28 +362,66 @@ inline void DSNodeHandle::mergeWith(const DSNodeHandle &Node) {
/// the DSNode handle for the callee function (or function pointer), and /// the DSNode handle for the callee function (or function pointer), and
/// the DSNode handles for the function arguments. /// the DSNode handles for the function arguments.
/// ///
class DSCallSite: public std::vector<DSNodeHandle> { class DSCallSite {
CallInst* callInst; CallInst *Inst; // Actual call site
DSCallSite(); // do not implement DSNodeHandle RetVal; // Returned value
DSNodeHandle Callee; // The function node called
std::vector<DSNodeHandle> CallArgs; // The pointer arguments
DSCallSite(); // DO NOT IMPLEMENT
public: public:
DSCallSite(CallInst& _callInst) : callInst(&_callInst) { } /// Note - This ctor destroys the argument vector passed in. On exit, the
/// argument vector is empty.
///
DSCallSite(CallInst &inst, const DSNodeHandle &rv, const DSNodeHandle &callee,
std::vector<DSNodeHandle> &Args)
: Inst(&inst), RetVal(rv), Callee(callee) {
Args.swap(CallArgs);
}
// Copy constructor with helper for cloning nodes. The helper should be a /// Copy constructor with helper for cloning nodes. The helper should be a
// model of unary_function<const DSNodeHandle*, DSNodeHandle>, i.e., it /// model of unary_function<const DSNodeHandle*, DSNodeHandle>, i.e., it
// should take a pointer to DSNodeHandle and return a fresh DSNodeHandle. /// should take a pointer to DSNodeHandle and return a fresh DSNodeHandle.
// If no helper is specified, this defaults to a simple copy constructor. /// If no helper is specified, this defaults to a simple copy constructor.
template<typename _CopierFunction> ///
DSCallSite(const DSCallSite& FromCall, template<typename CopyFunctor>
_CopierFunction nodeCopier = *(_CopierFunction*) 0); DSCallSite(const DSCallSite &FromCall, CopyFunctor nodeCopier);
DSCallSite(const DSCallSite &DSCS)
: Inst(DSCS.Inst), RetVal(DSCS.RetVal),
Callee(DSCS.Callee), CallArgs(DSCS.CallArgs) {}
Function& getCaller() const; // Accessor functions...
CallInst& getCallInst() const { return *callInst; } Function &getCaller() const;
DSNodeHandle getReturnValueNode() const { return (*this)[0]; } CallInst &getCallInst() const { return *Inst; }
DSNodeHandle getCalleeNode() const { return (*this)[1]; } DSNodeHandle &getRetVal() { return RetVal; }
unsigned getNumPtrArgs() const { return (size() - 2); } DSNodeHandle &getCallee() { return Callee; }
DSNodeHandle getPtrArgNode(unsigned i) const { assert(i < getNumPtrArgs()); const DSNodeHandle &getRetVal() const { return RetVal; }
return (*this)[i+2]; } const DSNodeHandle &getCallee() const { return Callee; }
unsigned getNumPtrArgs() const { return CallArgs.size(); }
DSNodeHandle &getPtrArg(unsigned i) {
assert(i < CallArgs.size() && "Argument to getPtrArgNode is out of range!");
return CallArgs[i];
}
const DSNodeHandle &getPtrArg(unsigned i) const {
assert(i < CallArgs.size() && "Argument to getPtrArgNode is out of range!");
return CallArgs[i];
}
bool operator<(const DSCallSite &CS) const {
if (Inst < CS.Inst) return true;
if (Inst > CS.Inst) return false;
if (RetVal < CS.RetVal) return true;
if (RetVal > CS.RetVal) return false;
if (Callee < CS.Callee) return true;
if (Callee > CS.Callee) return false;
return CallArgs < CS.CallArgs;
}
bool operator==(const DSCallSite &CS) const {
return Inst == CS.Inst && RetVal == CS.RetVal && Callee == CS.Callee &&
CallArgs == CS.CallArgs;
}
}; };

View File

@ -47,6 +47,7 @@ public:
bool operator<(const DSNodeHandle &H) const { // Allow sorting bool operator<(const DSNodeHandle &H) const { // Allow sorting
return N < H.N || (N == H.N && Offset < H.Offset); return N < H.N || (N == H.N && Offset < H.Offset);
} }
bool operator>(const DSNodeHandle &H) const { return H < *this; }
bool operator==(const DSNodeHandle &H) const { // Allow comparison bool operator==(const DSNodeHandle &H) const { // Allow comparison
return N == H.N && Offset == H.Offset; return N == H.N && Offset == H.Offset;
} }
@ -361,28 +362,66 @@ inline void DSNodeHandle::mergeWith(const DSNodeHandle &Node) {
/// the DSNode handle for the callee function (or function pointer), and /// the DSNode handle for the callee function (or function pointer), and
/// the DSNode handles for the function arguments. /// the DSNode handles for the function arguments.
/// ///
class DSCallSite: public std::vector<DSNodeHandle> { class DSCallSite {
CallInst* callInst; CallInst *Inst; // Actual call site
DSCallSite(); // do not implement DSNodeHandle RetVal; // Returned value
DSNodeHandle Callee; // The function node called
std::vector<DSNodeHandle> CallArgs; // The pointer arguments
DSCallSite(); // DO NOT IMPLEMENT
public: public:
DSCallSite(CallInst& _callInst) : callInst(&_callInst) { } /// Note - This ctor destroys the argument vector passed in. On exit, the
/// argument vector is empty.
///
DSCallSite(CallInst &inst, const DSNodeHandle &rv, const DSNodeHandle &callee,
std::vector<DSNodeHandle> &Args)
: Inst(&inst), RetVal(rv), Callee(callee) {
Args.swap(CallArgs);
}
// Copy constructor with helper for cloning nodes. The helper should be a /// Copy constructor with helper for cloning nodes. The helper should be a
// model of unary_function<const DSNodeHandle*, DSNodeHandle>, i.e., it /// model of unary_function<const DSNodeHandle*, DSNodeHandle>, i.e., it
// should take a pointer to DSNodeHandle and return a fresh DSNodeHandle. /// should take a pointer to DSNodeHandle and return a fresh DSNodeHandle.
// If no helper is specified, this defaults to a simple copy constructor. /// If no helper is specified, this defaults to a simple copy constructor.
template<typename _CopierFunction> ///
DSCallSite(const DSCallSite& FromCall, template<typename CopyFunctor>
_CopierFunction nodeCopier = *(_CopierFunction*) 0); DSCallSite(const DSCallSite &FromCall, CopyFunctor nodeCopier);
DSCallSite(const DSCallSite &DSCS)
: Inst(DSCS.Inst), RetVal(DSCS.RetVal),
Callee(DSCS.Callee), CallArgs(DSCS.CallArgs) {}
Function& getCaller() const; // Accessor functions...
CallInst& getCallInst() const { return *callInst; } Function &getCaller() const;
DSNodeHandle getReturnValueNode() const { return (*this)[0]; } CallInst &getCallInst() const { return *Inst; }
DSNodeHandle getCalleeNode() const { return (*this)[1]; } DSNodeHandle &getRetVal() { return RetVal; }
unsigned getNumPtrArgs() const { return (size() - 2); } DSNodeHandle &getCallee() { return Callee; }
DSNodeHandle getPtrArgNode(unsigned i) const { assert(i < getNumPtrArgs()); const DSNodeHandle &getRetVal() const { return RetVal; }
return (*this)[i+2]; } const DSNodeHandle &getCallee() const { return Callee; }
unsigned getNumPtrArgs() const { return CallArgs.size(); }
DSNodeHandle &getPtrArg(unsigned i) {
assert(i < CallArgs.size() && "Argument to getPtrArgNode is out of range!");
return CallArgs[i];
}
const DSNodeHandle &getPtrArg(unsigned i) const {
assert(i < CallArgs.size() && "Argument to getPtrArgNode is out of range!");
return CallArgs[i];
}
bool operator<(const DSCallSite &CS) const {
if (Inst < CS.Inst) return true;
if (Inst > CS.Inst) return false;
if (RetVal < CS.RetVal) return true;
if (RetVal > CS.RetVal) return false;
if (Callee < CS.Callee) return true;
if (Callee > CS.Callee) return false;
return CallArgs < CS.CallArgs;
}
bool operator==(const DSCallSite &CS) const {
return Inst == CS.Inst && RetVal == CS.RetVal && Callee == CS.Callee &&
CallArgs == CS.CallArgs;
}
}; };

View File

@ -66,7 +66,7 @@ static void ResolveArguments(DSCallSite &Call, Function &F,
// Add the link from the argument scalar to the provided value // Add the link from the argument scalar to the provided value
DSNodeHandle &NN = ValueMap[AI]; DSNodeHandle &NN = ValueMap[AI];
NN.addEdgeTo(Call.getPtrArgNode(i)); NN.addEdgeTo(Call.getPtrArg(i));
++AI; ++AI;
} }
} }
@ -100,12 +100,12 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
DSCallSite Call = FCs[i]; DSCallSite Call = FCs[i];
// If the function list is complete... // If the function list is complete...
if ((Call.getCalleeNode().getNode()->NodeType & DSNode::Incomplete)==0) { if ((Call.getCallee().getNode()->NodeType & DSNode::Incomplete)==0) {
// Start inlining all of the functions we can... some may not be // Start inlining all of the functions we can... some may not be
// inlinable if they are external... // inlinable if they are external...
// //
std::vector<GlobalValue*> Callees = std::vector<GlobalValue*> Callees =
Call.getCalleeNode().getNode()->getGlobals(); Call.getCallee().getNode()->getGlobals();
// Loop over the functions, inlining whatever we can... // Loop over the functions, inlining whatever we can...
for (unsigned c = 0; c != Callees.size(); ++c) { for (unsigned c = 0; c != Callees.size(); ++c) {
@ -118,8 +118,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
DEBUG(std::cerr << "\t[BU] Self Inlining: " << F.getName() << "\n"); DEBUG(std::cerr << "\t[BU] Self Inlining: " << F.getName() << "\n");
// Handle the return value if present... // Handle the return value if present...
if (Call.getReturnValueNode().getNode()) if (Call.getRetVal().getNode())
Graph->getRetNode().mergeWith(Call.getReturnValueNode()); Graph->getRetNode().mergeWith(Call.getRetVal());
// Resolve the arguments in the call to the actual values... // Resolve the arguments in the call to the actual values...
ResolveArguments(Call, F, Graph->getValueMap()); ResolveArguments(Call, F, Graph->getValueMap());
@ -162,8 +162,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
// Resolve the arguments in the call to the actual values... // Resolve the arguments in the call to the actual values...
ResolveArguments(Call, FI, OldValMap); ResolveArguments(Call, FI, OldValMap);
if (Call.getReturnValueNode().getNode()) // Handle the return value if present if (Call.getRetVal().getNode())// Handle the return value if present
RetVal.mergeWith(Call.getReturnValueNode()); RetVal.mergeWith(Call.getRetVal());
// Erase the entry in the Callees vector // Erase the entry in the Callees vector
Callees.erase(Callees.begin()+c--); Callees.erase(Callees.begin()+c--);
@ -181,7 +181,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
// Erase the call if it is resolvable... // Erase the call if it is resolvable...
FCs.erase(FCs.begin()+i--); // Don't skip a the next call... FCs.erase(FCs.begin()+i--); // Don't skip a the next call...
Inlined = true; Inlined = true;
} else if (Callees.size() != Call.getCalleeNode().getNode()->getGlobals().size()) { } else if (Callees.size() !=
Call.getCallee().getNode()->getGlobals().size()) {
// Was able to inline SOME, but not all of the functions. Construct a // Was able to inline SOME, but not all of the functions. Construct a
// new global node here. // new global node here.
// //

View File

@ -358,17 +358,19 @@ void DSNode::mergeWith(const DSNodeHandle &NH, unsigned Offset) {
// Define here to avoid including iOther.h and BasicBlock.h in DSGraph.h // Define here to avoid including iOther.h and BasicBlock.h in DSGraph.h
Function &DSCallSite::getCaller() const { Function &DSCallSite::getCaller() const {
return *callInst->getParent()->getParent(); return *Inst->getParent()->getParent();
} }
template <typename CopyFunctor> template <typename CopyFunctor>
DSCallSite::DSCallSite(const DSCallSite &FromCall, CopyFunctor nodeCopier) DSCallSite::DSCallSite(const DSCallSite &FromCall, CopyFunctor nodeCopier)
: callInst(&FromCall.getCallInst()) { : Inst(FromCall.Inst) {
reserve(FromCall.size()); RetVal = nodeCopier(&RetVal);
for (unsigned j = 0, ej = FromCall.size(); j != ej; ++j) Callee = nodeCopier(&Callee);
push_back(&nodeCopier == 0 ? DSNodeHandle(FromCall[j])
: nodeCopier(&FromCall[j])); CallArgs.reserve(FromCall.CallArgs.size());
for (unsigned j = 0, ej = FromCall.CallArgs.size(); j != ej; ++j)
CallArgs.push_back(nodeCopier(&FromCall.CallArgs[j]));
} }
@ -555,13 +557,13 @@ void DSGraph::markIncompleteNodes(bool markFormalArgs) {
for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) { for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
DSCallSite &Call = FunctionCalls[i]; DSCallSite &Call = FunctionCalls[i];
// Then the return value is certainly incomplete! // Then the return value is certainly incomplete!
markIncompleteNode(Call.getReturnValueNode().getNode()); markIncompleteNode(Call.getRetVal().getNode());
// The call does not make the function argument incomplete... // The call does not make the function argument incomplete...
// All arguments to the function call are incomplete though! // All arguments to the function call are incomplete though!
for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i) for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i)
markIncompleteNode(Call.getPtrArgNode(i).getNode()); markIncompleteNode(Call.getPtrArg(i).getNode());
} }
// Mark all of the nodes pointed to by global or cast nodes as incomplete... // Mark all of the nodes pointed to by global or cast nodes as incomplete...
@ -693,7 +695,7 @@ static void markGlobalsIteration(std::set<DSNode*>& GlobalNodes,
// Iterate, marking globals or cast nodes alive until no new live nodes // Iterate, marking globals or cast nodes alive until no new live nodes
// are added to Alive // are added to Alive
std::set<DSNode*> Visiting; // Used to identify cycles std::set<DSNode*> Visiting; // Used to identify cycles
std::set<DSNode*>::iterator I=GlobalNodes.begin(), E=GlobalNodes.end(); std::set<DSNode*>::iterator I = GlobalNodes.begin(), E = GlobalNodes.end();
for (size_t liveCount = 0; liveCount < Alive.size(); ) { for (size_t liveCount = 0; liveCount < Alive.size(); ) {
liveCount = Alive.size(); liveCount = Alive.size();
for ( ; I != E; ++I) for ( ; I != E; ++I)
@ -708,24 +710,39 @@ static void markGlobalsIteration(std::set<DSNode*>& GlobalNodes,
// Since all call nodes must be live if any one is live, we have to mark // Since all call nodes must be live if any one is live, we have to mark
// all nodes of the call as live and continue the iteration (via recursion). // all nodes of the call as live and continue the iteration (via recursion).
if (FilterCalls) { if (FilterCalls) {
bool recurse = false; bool Recurse = false;
for (int i = 0, ei = Calls.size(); i < ei; ++i) { for (unsigned i = 0, ei = Calls.size(); i < ei; ++i) {
bool CallIsDead = true, CallHasDeadArg = false; bool CallIsDead = true, CallHasDeadArg = false;
for (unsigned j = 0, ej = Calls[i].size(); j != ej; ++j) { DSCallSite &CS = Calls[i];
bool argIsDead = Calls[i][j].getNode() == 0 || for (unsigned j = 0, ej = CS.getNumPtrArgs(); j != ej; ++j)
Alive.count(Calls[i][j].getNode()) == 0; if (DSNode *N = CS.getPtrArg(j).getNode()) {
CallHasDeadArg |= (Calls[i][j].getNode() != 0 && argIsDead); bool ArgIsDead = !Alive.count(N);
CallIsDead &= argIsDead; CallHasDeadArg |= ArgIsDead;
CallIsDead &= ArgIsDead;
}
if (DSNode *N = CS.getRetVal().getNode()) {
bool RetIsDead = !Alive.count(N);
CallHasDeadArg |= RetIsDead;
CallIsDead &= RetIsDead;
} }
DSNode *N = CS.getCallee().getNode();
bool FnIsDead = !Alive.count(N);
CallHasDeadArg |= FnIsDead;
CallIsDead &= FnIsDead;
if (!CallIsDead && CallHasDeadArg) { if (!CallIsDead && CallHasDeadArg) {
// Some node in this call is live and another is dead. // Some node in this call is live and another is dead.
// Mark all nodes of call as live and iterate once more. // Mark all nodes of call as live and iterate once more.
recurse = true; Recurse = true;
for (unsigned j = 0, ej = Calls[i].size(); j != ej; ++j) for (unsigned j = 0, ej = CS.getNumPtrArgs(); j != ej; ++j)
markAlive(Calls[i][j].getNode(), Alive); markAlive(CS.getPtrArg(j).getNode(), Alive);
markAlive(CS.getRetVal().getNode(), Alive);
markAlive(CS.getCallee().getNode(), Alive);
} }
} }
if (recurse) if (Recurse)
markGlobalsIteration(GlobalNodes, Calls, Alive, FilterCalls); markGlobalsIteration(GlobalNodes, Calls, Alive, FilterCalls);
} }
} }
@ -746,10 +763,15 @@ static void markGlobalsAlive(DSGraph &G, std::set<DSNode*> &Alive,
// Add all call nodes to the same set // Add all call nodes to the same set
vector<DSCallSite> &Calls = G.getFunctionCalls(); vector<DSCallSite> &Calls = G.getFunctionCalls();
if (FilterCalls) { if (FilterCalls) {
for (unsigned i = 0, e = Calls.size(); i != e; ++i) for (unsigned i = 0, e = Calls.size(); i != e; ++i) {
for (unsigned j = 0, e = Calls[i].size(); j != e; ++j) for (unsigned j = 0, e = Calls[i].getNumPtrArgs(); j != e; ++j)
if (Calls[i][j].getNode()) if (DSNode *N = Calls[i].getPtrArg(j).getNode())
GlobalNodes.insert(Calls[i][j].getNode()); GlobalNodes.insert(N);
if (DSNode *N = Calls[i].getRetVal().getNode())
GlobalNodes.insert(N);
if (DSNode *N = Calls[i].getCallee().getNode())
GlobalNodes.insert(N);
}
} }
// Iterate and recurse until no new live node are discovered. // Iterate and recurse until no new live node are discovered.
@ -766,8 +788,9 @@ static void markGlobalsAlive(DSGraph &G, std::set<DSNode*> &Alive,
if (FilterCalls) if (FilterCalls)
for (int ei = Calls.size(), i = ei-1; i >= 0; --i) { for (int ei = Calls.size(), i = ei-1; i >= 0; --i) {
bool CallIsDead = true; bool CallIsDead = true;
for (unsigned j = 0, ej = Calls[i].size(); CallIsDead && j != ej; ++j) for (unsigned j = 0, ej = Calls[i].getNumPtrArgs();
CallIsDead = Alive.count(Calls[i][j].getNode()) == 0; CallIsDead && j != ej; ++j)
CallIsDead = Alive.count(Calls[i].getPtrArg(j).getNode()) == 0;
if (CallIsDead) if (CallIsDead)
Calls.erase(Calls.begin() + i); // remove the call entirely Calls.erase(Calls.begin() + i); // remove the call entirely
} }
@ -793,9 +816,12 @@ void DSGraph::removeDeadNodes(bool KeepAllGlobals, bool KeepCalls) {
// If KeepCalls, mark all nodes reachable by call nodes as alive... // If KeepCalls, mark all nodes reachable by call nodes as alive...
if (KeepCalls) if (KeepCalls)
for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
for (unsigned j = 0, e = FunctionCalls[i].size(); j != e; ++j) for (unsigned j = 0, e = FunctionCalls[i].getNumPtrArgs(); j != e; ++j)
markAlive(FunctionCalls[i][j].getNode(), Alive); markAlive(FunctionCalls[i].getPtrArg(j).getNode(), Alive);
markAlive(FunctionCalls[i].getRetVal().getNode(), Alive);
markAlive(FunctionCalls[i].getCallee().getNode(), Alive);
}
#if 0 #if 0
for (unsigned i = 0, e = OrigFunctionCalls.size(); i != e; ++i) for (unsigned i = 0, e = OrigFunctionCalls.size(); i != e; ++i)
@ -817,7 +843,7 @@ void DSGraph::removeDeadNodes(bool KeepAllGlobals, bool KeepCalls) {
// Mark all globals or cast nodes that can reach a live node as alive. // Mark all globals or cast nodes that can reach a live node as alive.
// This also marks all nodes reachable from such nodes as alive. // This also marks all nodes reachable from such nodes as alive.
// Of course, if KeepAllGlobals is specified, they would be live already. // Of course, if KeepAllGlobals is specified, they would be live already.
if (! KeepAllGlobals) if (!KeepAllGlobals)
markGlobalsAlive(*this, Alive, ! KeepCalls); markGlobalsAlive(*this, Alive, ! KeepCalls);
// Loop over all unreachable nodes, dropping their references... // Loop over all unreachable nodes, dropping their references...

View File

@ -257,6 +257,7 @@ DSNodeHandle &GraphBuilder::getLink(const DSNodeHandle &node,
/// object, pointing the scalar to it. /// object, pointing the scalar to it.
/// ///
void GraphBuilder::handleAlloc(AllocationInst &AI, DSNode::NodeTy NodeType) { void GraphBuilder::handleAlloc(AllocationInst &AI, DSNode::NodeTy NodeType) {
//DSNode *New = createNode(NodeType, Type::VoidTy);
DSNode *New = createNode(NodeType, AI.getAllocatedType()); DSNode *New = createNode(NodeType, AI.getAllocatedType());
// Make the scalar point to the new node... // Make the scalar point to the new node...
@ -354,28 +355,30 @@ void GraphBuilder::visitReturnInst(ReturnInst &RI) {
} }
void GraphBuilder::visitCallInst(CallInst &CI) { void GraphBuilder::visitCallInst(CallInst &CI) {
// Add a new function call entry...
FunctionCalls.push_back(CI);
DSCallSite &Args = FunctionCalls.back();
// Set up the return value... // Set up the return value...
DSNodeHandle RetVal;
if (isPointerType(CI.getType())) if (isPointerType(CI.getType()))
Args.push_back(getLink(getValueNode(CI), 0, CI.getType())); RetVal = getLink(getValueNode(CI), 0, CI.getType());
else
Args.push_back(DSNodeHandle());
unsigned Start = 0; DSNodeHandle Callee;
// Special case for a direct call, avoid creating spurious scalar node... // Special case for a direct call, avoid creating spurious scalar node...
if (GlobalValue *GV = dyn_cast<GlobalValue>(CI.getOperand(0))) { if (GlobalValue *GV = dyn_cast<GlobalValue>(CI.getOperand(0)))
Args.push_back(getGlobalNode(*GV)); Callee = getGlobalNode(*GV);
Start = 1; else
} Callee = getLink(getValueNode(*CI.getOperand(0)), 0,
CI.getOperand(0)->getType());
// Pass the arguments in... std::vector<DSNodeHandle> Args;
for (unsigned i = Start, e = CI.getNumOperands(); i != e; ++i) Args.reserve(CI.getNumOperands()-1);
// Calculate the arguments vector...
for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i)
if (isPointerType(CI.getOperand(i)->getType())) if (isPointerType(CI.getOperand(i)->getType()))
Args.push_back(getLink(getValueNode(*CI.getOperand(i)), 0, Args.push_back(getLink(getValueNode(*CI.getOperand(i)), 0,
CI.getOperand(i)->getType())); CI.getOperand(i)->getType()));
// Add a new function call entry...
FunctionCalls.push_back(DSCallSite(CI, RetVal, Callee, Args));
} }
/// Handle casts... /// Handle casts...

View File

@ -110,13 +110,13 @@ struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
const std::vector<DSCallSite> &FCs = G->getFunctionCalls(); const std::vector<DSCallSite> &FCs = G->getFunctionCalls();
for (unsigned i = 0, e = FCs.size(); i != e; ++i) { for (unsigned i = 0, e = FCs.size(); i != e; ++i) {
const DSCallSite &Call = FCs[i]; const DSCallSite &Call = FCs[i];
GW.emitSimpleNode(&Call, "shape=record", "call", Call.size()); GW.emitSimpleNode(&Call, "shape=record", "call", Call.getNumPtrArgs()+2);
for (unsigned j = 0, e = Call.size(); j != e; ++j) for (unsigned j = 0, e = Call.getNumPtrArgs(); j != e; ++j)
if (Call[j].getNode()) { if (DSNode *N = Call.getPtrArg(j).getNode()) {
int EdgeDest = Call[j].getOffset(); int EdgeDest = Call.getPtrArg(j).getOffset();
if (EdgeDest == 0) EdgeDest = -1; if (EdgeDest == 0) EdgeDest = -1;
GW.emitEdge(&Call, j, Call[j].getNode(), EdgeDest, "color=gray63"); GW.emitEdge(&Call, j+2, N, EdgeDest, "color=gray63");
} }
} }
} }

View File

@ -87,15 +87,15 @@ void Steens::ResolveFunctionCall(Function *F,
std::map<Value*, DSNodeHandle> &ValMap = ResultGraph->getValueMap(); std::map<Value*, DSNodeHandle> &ValMap = ResultGraph->getValueMap();
// Handle the return value of the function... // Handle the return value of the function...
if (Call.getReturnValueNode().getNode() && RetVal.getNode()) if (Call.getRetVal().getNode() && RetVal.getNode())
RetVal.mergeWith(Call.getReturnValueNode()); RetVal.mergeWith(Call.getRetVal());
// Loop over all pointer arguments, resolving them to their provided pointers // Loop over all pointer arguments, resolving them to their provided pointers
unsigned PtrArgIdx = 0; unsigned PtrArgIdx = 0;
for (Function::aiterator AI = F->abegin(), AE = F->aend(); AI != AE; ++AI) { for (Function::aiterator AI = F->abegin(), AE = F->aend(); AI != AE; ++AI) {
std::map<Value*, DSNodeHandle>::iterator I = ValMap.find(AI); std::map<Value*, DSNodeHandle>::iterator I = ValMap.find(AI);
if (I != ValMap.end()) // If its a pointer argument... if (I != ValMap.end()) // If its a pointer argument...
I->second.addEdgeTo(Call.getPtrArgNode(PtrArgIdx++)); I->second.addEdgeTo(Call.getPtrArg(PtrArgIdx++));
} }
assert(PtrArgIdx == Call.getNumPtrArgs() && "Argument resolution mismatch!"); assert(PtrArgIdx == Call.getNumPtrArgs() && "Argument resolution mismatch!");
@ -160,7 +160,8 @@ bool Steens::run(Module &M) {
DSCallSite &CurCall = Calls[i]; DSCallSite &CurCall = Calls[i];
// Loop over the called functions, eliminating as many as possible... // Loop over the called functions, eliminating as many as possible...
std::vector<GlobalValue*> CallTargets = CurCall.getCalleeNode().getNode()->getGlobals(); std::vector<GlobalValue*> CallTargets =
CurCall.getCallee().getNode()->getGlobals();
for (unsigned c = 0; c != CallTargets.size(); ) { for (unsigned c = 0; c != CallTargets.size(); ) {
// If we can eliminate this function call, do so! // If we can eliminate this function call, do so!
bool Eliminated = false; bool Eliminated = false;

View File

@ -60,12 +60,12 @@ void TDDataStructures::ResolveCallSite(DSGraph &Graph,
// TD ...Merge the formal arg scalar with the actual arg node // TD ...Merge the formal arg scalar with the actual arg node
DSNodeHandle &NodeForFormal = Graph.getNodeForValue(AI); DSNodeHandle &NodeForFormal = Graph.getNodeForValue(AI);
if (NodeForFormal.getNode()) if (NodeForFormal.getNode())
NodeForFormal.mergeWith(CallSite.getPtrArgNode(i)); NodeForFormal.mergeWith(CallSite.getPtrArg(i));
} }
// Merge returned node in the caller with the "return" node in callee // Merge returned node in the caller with the "return" node in callee
if (CallSite.getReturnValueNode().getNode() && Graph.getRetNode().getNode()) if (CallSite.getRetVal().getNode() && Graph.getRetNode().getNode())
Graph.getRetNode().mergeWith(CallSite.getReturnValueNode()); Graph.getRetNode().mergeWith(CallSite.getRetVal());
} }