DSNodeHandle Callee; // The function node called
std::vector<DSNodeHandle> CallArgs; // The pointer arguments
+ static DSNode *mapLookup(const DSNode *Node,
+ const std::map<const DSNode*, DSNode*> &NodeMap) {
+ if (Node == 0) return 0;
+ std::map<const DSNode*, DSNode*>::const_iterator I = NodeMap.find(Node);
+ assert(I != NodeMap.end() && "Not not in mapping!");
+ return I->second;
+ }
+
DSCallSite(); // DO NOT IMPLEMENT
public:
- /// Note - This ctor destroys the argument vector passed in. On exit, the
- /// argument vector is empty.
+ /// Constructor. 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)
Args.swap(CallArgs);
}
- /// Copy constructor with helper for cloning nodes. The helper should be a
- /// model of unary_function<const DSNodeHandle*, DSNodeHandle>, i.e., it
- /// should take a pointer to DSNodeHandle and return a fresh DSNodeHandle.
- /// If no helper is specified, this defaults to a simple copy constructor.
- ///
- template<typename CopyFunctor>
- DSCallSite(const DSCallSite &FromCall, CopyFunctor nodeCopier);
- DSCallSite(const DSCallSite &DSCS)
+ DSCallSite(const DSCallSite &DSCS) // Simple copy ctor
: Inst(DSCS.Inst), RetVal(DSCS.RetVal),
Callee(DSCS.Callee), CallArgs(DSCS.CallArgs) {}
+ /// Mapping copy constructor - This constructor takes a preexisting call site
+ /// to copy plus a map that specifies how the links should be transformed.
+ /// This is useful when moving a call site from one graph to another.
+ ///
+ DSCallSite(const DSCallSite &FromCall,
+ const std::map<const DSNode*, DSNode*> &NodeMap) {
+ Inst = FromCall.Inst;
+ RetVal.setOffset(FromCall.RetVal.getOffset());
+ RetVal.setNode(mapLookup(FromCall.RetVal.getNode(), NodeMap));
+ Callee.setOffset(FromCall.Callee.getOffset());
+ Callee.setNode(mapLookup(FromCall.Callee.getNode(), NodeMap));
+ CallArgs.reserve(FromCall.CallArgs.size());
+
+ for (unsigned i = 0, e = FromCall.CallArgs.size(); i != e; ++i) {
+ const DSNodeHandle &OldNH = FromCall.CallArgs[i];
+ CallArgs.push_back(DSNodeHandle(mapLookup(OldNH.getNode(), NodeMap),
+ OldNH.getOffset()));
+ }
+ }
+
// Accessor functions...
Function &getCaller() const;
CallInst &getCallInst() const { return *Inst; }
DSNodeHandle Callee; // The function node called
std::vector<DSNodeHandle> CallArgs; // The pointer arguments
+ static DSNode *mapLookup(const DSNode *Node,
+ const std::map<const DSNode*, DSNode*> &NodeMap) {
+ if (Node == 0) return 0;
+ std::map<const DSNode*, DSNode*>::const_iterator I = NodeMap.find(Node);
+ assert(I != NodeMap.end() && "Not not in mapping!");
+ return I->second;
+ }
+
DSCallSite(); // DO NOT IMPLEMENT
public:
- /// Note - This ctor destroys the argument vector passed in. On exit, the
- /// argument vector is empty.
+ /// Constructor. 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)
Args.swap(CallArgs);
}
- /// Copy constructor with helper for cloning nodes. The helper should be a
- /// model of unary_function<const DSNodeHandle*, DSNodeHandle>, i.e., it
- /// should take a pointer to DSNodeHandle and return a fresh DSNodeHandle.
- /// If no helper is specified, this defaults to a simple copy constructor.
- ///
- template<typename CopyFunctor>
- DSCallSite(const DSCallSite &FromCall, CopyFunctor nodeCopier);
- DSCallSite(const DSCallSite &DSCS)
+ DSCallSite(const DSCallSite &DSCS) // Simple copy ctor
: Inst(DSCS.Inst), RetVal(DSCS.RetVal),
Callee(DSCS.Callee), CallArgs(DSCS.CallArgs) {}
+ /// Mapping copy constructor - This constructor takes a preexisting call site
+ /// to copy plus a map that specifies how the links should be transformed.
+ /// This is useful when moving a call site from one graph to another.
+ ///
+ DSCallSite(const DSCallSite &FromCall,
+ const std::map<const DSNode*, DSNode*> &NodeMap) {
+ Inst = FromCall.Inst;
+ RetVal.setOffset(FromCall.RetVal.getOffset());
+ RetVal.setNode(mapLookup(FromCall.RetVal.getNode(), NodeMap));
+ Callee.setOffset(FromCall.Callee.getOffset());
+ Callee.setNode(mapLookup(FromCall.Callee.getNode(), NodeMap));
+ CallArgs.reserve(FromCall.CallArgs.size());
+
+ for (unsigned i = 0, e = FromCall.CallArgs.size(); i != e; ++i) {
+ const DSNodeHandle &OldNH = FromCall.CallArgs[i];
+ CallArgs.push_back(DSNodeHandle(mapLookup(OldNH.getNode(), NodeMap),
+ OldNH.getOffset()));
+ }
+ }
+
// Accessor functions...
Function &getCaller() const;
CallInst &getCallInst() const { return *Inst; }
return *Inst->getParent()->getParent();
}
-template <typename CopyFunctor>
-DSCallSite::DSCallSite(const DSCallSite &FromCall, CopyFunctor nodeCopier)
- : Inst(FromCall.Inst) {
-
- RetVal = nodeCopier(&FromCall.RetVal);
- Callee = nodeCopier(&FromCall.Callee);
-
- CallArgs.reserve(FromCall.CallArgs.size());
- for (unsigned j = 0, ej = FromCall.CallArgs.size(); j != ej; ++j)
- CallArgs.push_back(nodeCopier(&FromCall.CallArgs[j]));
-}
-
//===----------------------------------------------------------------------===//
// DSGraph Implementation
void DSGraph::dump() const { print(std::cerr); }
-static 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,
unsigned FC = toCalls.size(); // FirstCall
toCalls.reserve(FC+fromCalls.size());
for (unsigned i = 0, ei = fromCalls.size(); i != ei; ++i)
- toCalls.push_back(DSCallSite(fromCalls[i],
- std::bind2nd(std::ptr_fun(©Helper), &NodeMap)));
+ toCalls.push_back(DSCallSite(fromCalls[i], NodeMap));
}
/// remapLinks - Change all of the Links in the current node according to the
// TD ...Merge the formal arg scalar with the actual arg node
DSNodeHandle &NodeForFormal = Graph.getNodeForValue(AI);
- if (NodeForFormal.getNode())
- NodeForFormal.mergeWith(CallSite.getPtrArg(i));
+ assert(NodeForFormal.getNode() && "Pointer argument has no dest node!");
+ NodeForFormal.mergeWith(CallSite.getPtrArg(i));
}
// Merge returned node in the caller with the "return" node in callee
}
-static DSNodeHandle copyHelper(const DSNodeHandle* fromNode,
- std::map<const DSNode*, DSNode*> *NodeMap) {
- return DSNodeHandle((*NodeMap)[fromNode->getNode()], fromNode->getOffset());
-}
-
-
DSGraph &TDDataStructures::calculateGraph(Function &F) {
// Make sure this graph has not already been calculated, or that we don't get
// into an infinite loop with mutually recursive functions.
DEBUG(std::cerr << "\t [TD] Inlining caller #" << c << " '"
<< Caller.getName() << "' into callee: " << F.getName() << "\n");
- if (&Caller == &F) {
- // Self-recursive call: this can happen after a cycle of calls is inlined.
- ResolveCallSite(*Graph, CallSite);
- } else {
- // Recursively compute the graph for the Caller. That should
- // be fully resolved except if there is mutual recursion...
+ if (&Caller != &F) {
+ // Recursively compute the graph for the Caller. It should be fully
+ // resolved except if there is mutual recursion...
//
DSGraph &CG = calculateGraph(Caller); // Graph to inline
// Make a temporary copy of the call site, and transform the argument node
// pointers.
- DSCallSite TmpCallSite(CallSite, std::bind2nd(std::ptr_fun(©Helper),
- &OldNodeMap));
- ResolveCallSite(*Graph, CallSite);
+ //
}
+ ResolveCallSite(*Graph, CallSite);
}
// Recompute the Incomplete markers and eliminate unreachable nodes.