aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/DataStructure
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/DataStructure')
-rw-r--r--lib/Analysis/DataStructure/BottomUpClosure.cpp24
-rw-r--r--lib/Analysis/DataStructure/DataStructure.cpp64
-rw-r--r--lib/Analysis/DataStructure/Local.cpp188
-rw-r--r--lib/Analysis/DataStructure/Printer.cpp27
4 files changed, 133 insertions, 170 deletions
diff --git a/lib/Analysis/DataStructure/BottomUpClosure.cpp b/lib/Analysis/DataStructure/BottomUpClosure.cpp
index defd80e308..08c86c5e12 100644
--- a/lib/Analysis/DataStructure/BottomUpClosure.cpp
+++ b/lib/Analysis/DataStructure/BottomUpClosure.cpp
@@ -16,8 +16,7 @@ using std::map;
static RegisterAnalysis<BUDataStructures>
X("budatastructure", "Bottom-up Data Structure Analysis Closure");
-// TODO: FIXME
-namespace DataStructureAnalysis {
+namespace DataStructureAnalysis { // TODO: FIXME: Eliminate
// isPointerType - Return true if this first class type is big enough to hold
// a pointer.
//
@@ -60,14 +59,12 @@ static void ResolveArguments(DSCallSite &Call, Function &F,
map<Value*, DSNodeHandle> &ValueMap) {
// Resolve all of the function arguments...
Function::aiterator AI = F.abegin();
- for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i) {
+ for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i, ++AI) {
// Advance the argument iterator to the first pointer argument...
while (!isPointerType(AI->getType())) ++AI;
// Add the link from the argument scalar to the provided value
- DSNodeHandle &NN = ValueMap[AI];
- NN.addEdgeTo(Call.getPtrArg(i));
- ++AI;
+ ValueMap[AI].mergeWith(Call.getPtrArg(i));
}
}
@@ -118,8 +115,7 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
DEBUG(std::cerr << "\t[BU] Self Inlining: " << F.getName() << "\n");
// Handle the return value if present...
- if (Call.getRetVal().getNode())
- Graph->getRetNode().mergeWith(Call.getRetVal());
+ Graph->getRetNode().mergeWith(Call.getRetVal());
// Resolve the arguments in the call to the actual values...
ResolveArguments(Call, F, Graph->getValueMap());
@@ -143,11 +139,12 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
// Record that the original DSCallSite was a call site of FI.
// This may or may not have been known when the DSCallSite was
// originally created.
+#if 1 /// FIXME: Reenable
std::vector<DSCallSite> &CallSitesForFunc = CallSites[&FI];
CallSitesForFunc.push_back(Call);
CallSitesForFunc.back().setResolvingCaller(&F);
CallSitesForFunc.back().setCallee(0);
-
+#endif
// Clone the callee's graph into the current graph, keeping
// track of where scalars in the old graph _used_ to point,
// and of the new nodes matching nodes of the old graph.
@@ -163,8 +160,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
// Resolve the arguments in the call to the actual values...
ResolveArguments(Call, FI, OldValMap);
- if (Call.getRetVal().getNode())// Handle the return value if present
- RetVal.mergeWith(Call.getRetVal());
+ // Handle the return value if present...
+ RetVal.mergeWith(Call.getRetVal());
// Erase the entry in the Callees vector
Callees.erase(Callees.begin()+c--);
@@ -172,9 +169,10 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
} else if (FI.getName() == "printf" || FI.getName() == "sscanf" ||
FI.getName() == "fprintf" || FI.getName() == "open" ||
FI.getName() == "sprintf") {
- // FIXME: These special cases should go away when we can define
- // functions that take a variable number of arguments.
+ // FIXME: These special cases (eg printf) should go away when we can
+ // define functions that take a variable number of arguments.
+ // FIXME: at the very least, this should update mod/ref info
// Erase the entry in the globals vector
Callees.erase(Callees.begin()+c--);
}
diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp
index 44ecd01ab7..2aadc000f6 100644
--- a/lib/Analysis/DataStructure/DataStructure.cpp
+++ b/lib/Analysis/DataStructure/DataStructure.cpp
@@ -16,8 +16,7 @@
using std::vector;
-// TODO: FIXME
-namespace DataStructureAnalysis {
+namespace DataStructureAnalysis { // TODO: FIXME
// isPointerType - Return true if this first class type is big enough to hold
// a pointer.
//
@@ -538,14 +537,15 @@ void DSNode::remapLinks(std::map<const DSNode*, DSNode*> &OldNodeMap) {
// 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
-// Alloca markers are removed from the graph, as the graph is being cloned into
-// a calling function's graph.
+// filled into the OldValMap member. If StripAllocas is set to true, Alloca
+// markers are removed from the graph, as the graph is being cloned into a
+// calling function's graph.
//
DSNodeHandle DSGraph::cloneInto(const DSGraph &G,
std::map<Value*, DSNodeHandle> &OldValMap,
std::map<const DSNode*, DSNode*> &OldNodeMap,
- bool StripScalars, bool StripAllocas) {
+ bool StripScalars, // FIXME: Kill StripScalars
+ bool StripAllocas) {
assert(OldNodeMap.empty() && "Returned OldNodeMap should be empty!");
unsigned FN = Nodes.size(); // First new node...
@@ -564,8 +564,7 @@ DSNodeHandle DSGraph::cloneInto(const DSGraph &G,
Nodes[i]->remapLinks(OldNodeMap);
// Remove local markers as specified
- unsigned char StripBits = (StripScalars ? DSNode::ScalarNode : 0) |
- (StripAllocas ? DSNode::AllocaNode : 0);
+ unsigned char StripBits = StripAllocas ? DSNode::AllocaNode : 0;
if (StripBits)
for (unsigned i = FN, e = Nodes.size(); i != e; ++i)
Nodes[i]->NodeType &= ~StripBits;
@@ -574,7 +573,8 @@ DSNodeHandle DSGraph::cloneInto(const DSGraph &G,
for (std::map<Value*, DSNodeHandle>::const_iterator I = G.ValueMap.begin(),
E = G.ValueMap.end(); I != E; ++I) {
DSNodeHandle &H = OldValMap[I->first];
- H = DSNodeHandle(OldNodeMap[I->second.getNode()], I->second.getOffset());
+ H.setNode(OldNodeMap[I->second.getNode()]);
+ H.setOffset(I->second.getOffset());
if (isa<GlobalValue>(I->first)) { // Is this a global?
std::map<Value*, DSNodeHandle>::iterator GVI = ValueMap.find(I->first);
@@ -655,11 +655,8 @@ void DSGraph::markIncompleteNodes(bool markFormalArgs) {
// Mark any incoming arguments as incomplete...
if (markFormalArgs && Func)
for (Function::aiterator I = Func->abegin(), E = Func->aend(); I != E; ++I)
- if (isPointerType(I->getType()) && ValueMap.find(I) != ValueMap.end()) {
- DSNodeHandle &INH = ValueMap[I];
- if (INH.getNode() && INH.hasLink(0))
- markIncompleteNode(ValueMap[I].getLink(0)->getNode());
- }
+ if (isPointerType(I->getType()) && ValueMap.find(I) != ValueMap.end())
+ markIncompleteNode(ValueMap[I].getNode());
// Mark stuff passed into functions calls as being incomplete...
for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
@@ -667,17 +664,16 @@ void DSGraph::markIncompleteNodes(bool markFormalArgs) {
// Then the return value is certainly incomplete!
markIncompleteNode(Call.getRetVal().getNode());
- // The call does not make the function argument incomplete...
-
- // All arguments to the function call are incomplete though!
+ // All objects pointed to by function arguments are incomplete though!
for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i)
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 nodes as incomplete...
for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
if (Nodes[i]->NodeType & DSNode::GlobalNode) {
DSNode *N = Nodes[i];
+ // FIXME: Make more efficient by looking over Links directly
for (unsigned i = 0, e = N->getSize(); i != e; ++i)
if (DSNodeHandle *DSNH = N->getLink(i))
markIncompleteNode(DSNH->getNode());
@@ -706,9 +702,7 @@ bool DSGraph::isNodeDead(DSNode *N) {
return true;
// Is it a function node or some other trivially unused global?
- if (N->NodeType != 0 &&
- (N->NodeType & ~DSNode::GlobalNode) == 0 &&
- N->getSize() == 0 &&
+ if ((N->NodeType & ~DSNode::GlobalNode) == 0 && N->getSize() == 0 &&
N->getReferrers().size() == N->getGlobals().size()) {
// Remove the globals from the ValueMap, so that the referrer count will go
@@ -758,6 +752,7 @@ static void markAlive(DSNode *N, std::set<DSNode*> &Alive) {
if (N == 0) return;
Alive.insert(N);
+ // FIXME: Make more efficient by looking over Links directly
for (unsigned i = 0, e = N->getSize(); i != e; ++i)
if (DSNodeHandle *DSNH = N->getLink(i))
if (!Alive.count(DSNH->getNode()))
@@ -887,7 +882,7 @@ static void markGlobalsAlive(DSGraph &G, std::set<DSNode*> &Alive,
markGlobalsIteration(GlobalNodes, Calls, Alive, FilterCalls);
// Free up references to dead globals from the ValueMap
- std::set<DSNode*>::iterator I=GlobalNodes.begin(), E=GlobalNodes.end();
+ std::set<DSNode*>::iterator I = GlobalNodes.begin(), E = GlobalNodes.end();
for( ; I != E; ++I)
if (Alive.count(*I) == 0)
removeRefsToGlobal(*I, G.getValueMap());
@@ -931,20 +926,21 @@ void DSGraph::removeDeadNodes(bool KeepAllGlobals, bool KeepCalls) {
markAlive(FunctionCalls[i].getCallee().getNode(), Alive);
}
+ // Mark all nodes reachable by scalar nodes as alive...
+ for (std::map<Value*, DSNodeHandle>::iterator I = ValueMap.begin(),
+ E = ValueMap.end(); I != E; ++I)
+ markAlive(I->second.getNode(), Alive);
+
#if 0
- for (unsigned i = 0, e = OrigFunctionCalls.size(); i != e; ++i)
- for (unsigned j = 0, e = OrigFunctionCalls[i].size(); j != e; ++j)
- markAlive(OrigFunctionCalls[i][j].getNode(), Alive);
+ // Marge all nodes reachable by global nodes, as alive. Isn't this covered by
+ // the ValueMap?
+ //
+ if (KeepAllGlobals)
+ for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
+ if (Nodes[i]->NodeType & DSNode::GlobalNode)
+ markAlive(Nodes[i], Alive);
#endif
- // Mark all nodes reachable by scalar nodes (and global nodes, if
- // keeping them was specified) as alive...
- unsigned char keepBits = DSNode::ScalarNode |
- (KeepAllGlobals ? DSNode::GlobalNode : 0);
- for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
- if (Nodes[i]->NodeType & keepBits)
- markAlive(Nodes[i], Alive);
-
// The return value is alive as well...
markAlive(RetNode.getNode(), Alive);
@@ -952,7 +948,7 @@ void DSGraph::removeDeadNodes(bool KeepAllGlobals, bool KeepCalls) {
// This also marks all nodes reachable from such nodes as alive.
// Of course, if KeepAllGlobals is specified, they would be live already.
if (!KeepAllGlobals)
- markGlobalsAlive(*this, Alive, ! KeepCalls);
+ markGlobalsAlive(*this, Alive, !KeepCalls);
// Loop over all unreachable nodes, dropping their references...
vector<DSNode*> DeadNodes;
diff --git a/lib/Analysis/DataStructure/Local.cpp b/lib/Analysis/DataStructure/Local.cpp
index dddd54ad49..456eb2f333 100644
--- a/lib/Analysis/DataStructure/Local.cpp
+++ b/lib/Analysis/DataStructure/Local.cpp
@@ -61,7 +61,6 @@ namespace {
vector<DSNode*> &Nodes;
DSNodeHandle &RetNode; // Node that gets returned...
map<Value*, DSNodeHandle> &ValueMap;
- map<GlobalValue*, DSNodeHandle> GlobalScalarValueMap;
vector<DSCallSite> &FunctionCalls;
public:
@@ -107,23 +106,21 @@ namespace {
/// createNode - Create a new DSNode, ensuring that it is properly added to
/// the graph.
///
- DSNode *createNode(DSNode::NodeTy NodeType, const Type *Ty);
-
- /// getValueNode - Return a DSNode that corresponds the the specified LLVM
- /// value. This either returns the already existing node, or creates a new
- /// one and adds it to the graph, if none exists.
- ///
- DSNodeHandle &getValueNode(Value &V);
+ DSNode *createNode(DSNode::NodeTy NodeType, const Type *Ty = 0) {
+ DSNode *N = new DSNode(NodeType, Ty); // Create the node
+ Nodes.push_back(N); // Add node to nodes list
+ return N;
+ }
- /// getValueDest - Return the DSNode that the actual value points to. This
- /// is the same thing as: getLink(getValueNode(V))
+ /// setDestTo - Set the ValueMap entry for the specified value to point to
+ /// the specified destination. If the Value already points to a node, make
+ /// sure to merge the two destinations together.
///
- DSNodeHandle &getValueDest(Value &V);
+ void setDestTo(Value &V, const DSNodeHandle &NH);
- /// getGlobalNode - Just like getValueNode, except the global node itself is
- /// returned, not a scalar node pointing to a global.
+ /// getValueDest - Return the DSNode that the actual value points to.
///
- DSNodeHandle &getGlobalNode(GlobalValue &V);
+ DSNodeHandle getValueDest(Value &V);
/// getLink - This method is used to return the specified link in the
/// specified node if one exists. If a link does not already exist (it's
@@ -148,78 +145,34 @@ DSGraph::DSGraph(Function &F) : Func(&F) {
//
-// createNode - Create a new DSNode, ensuring that it is properly added to the
-// graph.
-//
-DSNode *GraphBuilder::createNode(DSNode::NodeTy NodeType, const Type *Ty) {
- DSNode *N = new DSNode(NodeType, Ty);
- Nodes.push_back(N);
- return N;
-}
+/// getValueDest - Return the DSNode that the actual value points to.
+///
+DSNodeHandle GraphBuilder::getValueDest(Value &V) {
+ if (Constant *C = dyn_cast<Constant>(&V)) {
+ // FIXME: Return null NH for constants like 10 or null
+ // FIXME: Handle constant exprs here.
+ return 0; // Constant doesn't point to anything.
+ }
-// getGlobalNode - Just like getValueNode, except the global node itself is
-// returned, not a scalar node pointing to a global.
-//
-DSNodeHandle &GraphBuilder::getGlobalNode(GlobalValue &V) {
DSNodeHandle &NH = ValueMap[&V];
- if (NH.getNode()) return NH; // Already have a node? Just return it...
-
- // Create a new global node for this global variable...
- DSNode *G = createNode(DSNode::GlobalNode, V.getType()->getElementType());
- G->addGlobal(&V);
-
- // If this node has outgoing edges, make sure to recycle the same node for
- // each use. For functions and other global variables, this is unneccesary,
- // so avoid excessive merging by cloning these nodes on demand.
- //
- NH.setNode(G);
- return NH;
-}
-
-
-// getValueNode - Return a DSNode that corresponds the the specified LLVM value.
-// This either returns the already existing node, or creates a new one and adds
-// it to the graph, if none exists.
-//
-DSNodeHandle &GraphBuilder::getValueNode(Value &V) {
- assert(isPointerType(V.getType()) && "Should only use pointer scalars!");
+ if (NH.getNode())
+ return NH; // Already have a node? Just return it...
+ // Otherwise we need to create a new node to point to...
+ DSNode *N;
if (GlobalValue *GV = dyn_cast<GlobalValue>(&V)) {
- // The GlobalScalarValueMap keeps track of the scalar nodes that point to
- // global values... The ValueMap contains pointers to the global memory
- // object itself, not the scalar constant that points to the memory.
- //
- DSNodeHandle &NH = GlobalScalarValueMap[GV];
- if (NH.getNode()) return NH;
-
- // If this is a global value, create the global pointed to.
- DSNode *N = createNode(DSNode::ScalarNode, V.getType());
- NH.setOffset(0);
- NH.setNode(N);
-
- N->addEdgeTo(0, getGlobalNode(*GV));
- return NH;
-
+ // Create a new global node for this global variable...
+ N = createNode(DSNode::GlobalNode, GV->getType()->getElementType());
+ N->addGlobal(GV);
} else {
- DSNodeHandle &NH = ValueMap[&V];
- if (NH.getNode())
- return NH; // Already have a node? Just return it...
-
- // Otherwise we need to create a new scalar node...
- DSNode *N = createNode(DSNode::ScalarNode, V.getType());
-
- NH.setOffset(0);
- NH.setNode(N);
- return NH;
+ // Otherwise just create a shadow node
+ N = createNode(DSNode::ShadowNode);
}
-}
-/// getValueDest - Return the DSNode that the actual value points to. This is
-/// the same thing as: getLink(getValueNode(V), 0)
-///
-DSNodeHandle &GraphBuilder::getValueDest(Value &V) {
- return getLink(getValueNode(V));
+ NH.setNode(N); // Remember that we are pointing to it...
+ NH.setOffset(0);
+ return NH;
}
@@ -235,12 +188,25 @@ DSNodeHandle &GraphBuilder::getLink(const DSNodeHandle &node, unsigned LinkNo) {
if (Link) return *Link;
// If the link hasn't been created yet, make and return a new shadow node
- DSNode *N = createNode(DSNode::ShadowNode, 0);
+ DSNode *N = createNode(DSNode::ShadowNode);
Node.setLink(LinkNo, N);
return *Node.getLink(LinkNo);
}
+/// setDestTo - Set the ValueMap entry for the specified value to point to the
+/// specified destination. If the Value already points to a node, make sure to
+/// merge the two destinations together.
+///
+void GraphBuilder::setDestTo(Value &V, const DSNodeHandle &NH) {
+ DSNodeHandle &AINH = ValueMap[&V];
+ if (AINH.getNode() == 0) // Not pointing to anything yet?
+ AINH = NH; // Just point directly to NH
+ else
+ AINH.mergeWith(NH);
+}
+
+
//===----------------------------------------------------------------------===//
// Specific instruction type handler implementations...
//
@@ -249,10 +215,7 @@ DSNodeHandle &GraphBuilder::getLink(const DSNodeHandle &node, unsigned LinkNo) {
/// object, pointing the scalar to it.
///
void GraphBuilder::handleAlloc(AllocationInst &AI, DSNode::NodeTy NodeType) {
- DSNode *New = createNode(NodeType, 0);
-
- // Make the scalar point to the new node...
- getValueNode(AI).addEdgeTo(New);
+ setDestTo(AI, createNode(NodeType));
}
// PHINode - Make the scalar for the PHI node point to all of the things the
@@ -261,14 +224,14 @@ void GraphBuilder::handleAlloc(AllocationInst &AI, DSNode::NodeTy NodeType) {
void GraphBuilder::visitPHINode(PHINode &PN) {
if (!isPointerType(PN.getType())) return; // Only pointer PHIs
- DSNodeHandle &ScalarDest = getValueDest(PN);
+ DSNodeHandle &PNDest = ValueMap[&PN];
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
- if (!isa<ConstantPointerNull>(PN.getIncomingValue(i)))
- ScalarDest.mergeWith(getValueDest(*PN.getIncomingValue(i)));
+ PNDest.mergeWith(getValueDest(*PN.getIncomingValue(i)));
}
void GraphBuilder::visitGetElementPtrInst(GetElementPtrInst &GEP) {
DSNodeHandle Value = getValueDest(*GEP.getOperand(0));
+ if (Value.getNode() == 0) return;
unsigned Offset = 0;
const PointerType *PTy = cast<PointerType>(GEP.getOperand(0)->getType());
@@ -278,7 +241,7 @@ void GraphBuilder::visitGetElementPtrInst(GetElementPtrInst &GEP) {
// If the node had to be folded... exit quickly
if (TopTypeRec.Ty == Type::VoidTy) {
- getValueNode(GEP).addEdgeTo(Value); // GEP result points to folded node
+ setDestTo(GEP, Value); // GEP result points to folded node
return;
}
@@ -297,7 +260,7 @@ void GraphBuilder::visitGetElementPtrInst(GetElementPtrInst &GEP) {
if (Value.getOffset()) {
// Value is now the pointer we want to GEP to be...
Value.getNode()->foldNodeCompletely();
- getValueNode(GEP).addEdgeTo(Value); // GEP result points to folded node
+ setDestTo(GEP, Value); // GEP result points to folded node
return;
} else {
// This is a pointer to the first byte of the node. Make sure that we
@@ -346,56 +309,51 @@ void GraphBuilder::visitGetElementPtrInst(GetElementPtrInst &GEP) {
Value.setOffset(Value.getOffset()+Offset);
// Value is now the pointer we want to GEP to be...
- getValueNode(GEP).addEdgeTo(Value);
+ setDestTo(GEP, Value);
}
void GraphBuilder::visitLoadInst(LoadInst &LI) {
- DSNodeHandle &Ptr = getValueDest(*LI.getOperand(0));
+ DSNodeHandle Ptr = getValueDest(*LI.getOperand(0));
+ if (Ptr.getNode() == 0) return;
+
+ // Make that the node is read from...
Ptr.getNode()->NodeType |= DSNode::Read;
// Ensure a typerecord exists...
Ptr.getNode()->getTypeRec(LI.getType(), Ptr.getOffset());
-
+
if (isPointerType(LI.getType()))
- getValueNode(LI).addEdgeTo(getLink(Ptr));
+ setDestTo(LI, getLink(Ptr));
}
void GraphBuilder::visitStoreInst(StoreInst &SI) {
- DSNodeHandle &Dest = getValueDest(*SI.getOperand(1));
- Dest.getNode()->NodeType |= DSNode::Modified;
const Type *StoredTy = SI.getOperand(0)->getType();
+ DSNodeHandle Dest = getValueDest(*SI.getOperand(1));
+ if (Dest.getNode() == 0) return;
+
+ // Make that the node is written to...
+ Dest.getNode()->NodeType |= DSNode::Modified;
// Ensure a typerecord exists...
Dest.getNode()->getTypeRec(StoredTy, Dest.getOffset());
// Avoid adding edges from null, or processing non-"pointer" stores
- if (isPointerType(StoredTy) &&
- !isa<ConstantPointerNull>(SI.getOperand(0))) {
+ if (isPointerType(StoredTy))
Dest.addEdgeTo(getValueDest(*SI.getOperand(0)));
- }
}
void GraphBuilder::visitReturnInst(ReturnInst &RI) {
- if (RI.getNumOperands() && isPointerType(RI.getOperand(0)->getType()) &&
- !isa<ConstantPointerNull>(RI.getOperand(0))) {
- DSNodeHandle &Value = getValueDest(*RI.getOperand(0));
- Value.mergeWith(RetNode);
- RetNode = Value;
- }
+ if (RI.getNumOperands() && isPointerType(RI.getOperand(0)->getType()))
+ RetNode.mergeWith(getValueDest(*RI.getOperand(0)));
}
void GraphBuilder::visitCallInst(CallInst &CI) {
// Set up the return value...
DSNodeHandle RetVal;
if (isPointerType(CI.getType()))
- RetVal = getLink(getValueNode(CI));
+ RetVal = getValueDest(CI);
- DSNodeHandle Callee;
- // Special case for a direct call, avoid creating spurious scalar node...
- if (GlobalValue *GV = dyn_cast<GlobalValue>(CI.getOperand(0)))
- Callee = getGlobalNode(*GV);
- else
- Callee = getLink(getValueNode(*CI.getOperand(0)));
+ DSNodeHandle Callee = getValueDest(*CI.getOperand(0));
std::vector<DSNodeHandle> Args;
Args.reserve(CI.getNumOperands()-1);
@@ -403,7 +361,7 @@ void GraphBuilder::visitCallInst(CallInst &CI) {
// Calculate the arguments vector...
for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i)
if (isPointerType(CI.getOperand(i)->getType()))
- Args.push_back(getLink(getValueNode(*CI.getOperand(i))));
+ Args.push_back(getValueDest(*CI.getOperand(i)));
// Add a new function call entry...
FunctionCalls.push_back(DSCallSite(CI, RetVal, Callee, Args));
@@ -411,8 +369,12 @@ void GraphBuilder::visitCallInst(CallInst &CI) {
/// Handle casts...
void GraphBuilder::visitCastInst(CastInst &CI) {
- if (isPointerType(CI.getType()) && isPointerType(CI.getOperand(0)->getType()))
- getValueNode(CI).addEdgeTo(getLink(getValueNode(*CI.getOperand(0))));
+ if (isPointerType(CI.getType())) {
+ if (isPointerType(CI.getOperand(0)->getType()))
+ setDestTo(CI, getValueDest(*CI.getOperand(0)));
+ else
+ ; // FIXME: "Other" node
+ }
}
diff --git a/lib/Analysis/DataStructure/Printer.cpp b/lib/Analysis/DataStructure/Printer.cpp
index 35f491dd5c..fd6006c2a5 100644
--- a/lib/Analysis/DataStructure/Printer.cpp
+++ b/lib/Analysis/DataStructure/Printer.cpp
@@ -36,7 +36,6 @@ static string getCaption(const DSNode *N, const DSGraph *G) {
OS << "\n";
}
- if (N->NodeType & DSNode::ScalarNode) OS << "S";
if (N->NodeType & DSNode::AllocaNode) OS << "A";
if (N->NodeType & DSNode::NewNode ) OS << "N";
if (N->NodeType & DSNode::GlobalNode) OS << "G";
@@ -49,15 +48,6 @@ static string getCaption(const DSNode *N, const DSGraph *G) {
OS << "\n";
}
- if ((N->NodeType & DSNode::ScalarNode) && G) {
- const std::map<Value*, DSNodeHandle> &VM = G->getValueMap();
- for (std::map<Value*, DSNodeHandle>::const_iterator I = VM.begin(),
- E = VM.end(); I != E; ++I)
- if (I->second.getNode() == N) {
- WriteAsOperand(OS, I->first, false, true, M);
- OS << "\n";
- }
- }
return OS.str();
}
@@ -94,6 +84,23 @@ struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
///
static void addCustomGraphFeatures(const DSGraph *G,
GraphWriter<const DSGraph*> &GW) {
+ // Add scalar nodes to the graph...
+ const std::map<Value*, DSNodeHandle> &VM = G->getValueMap();
+ for (std::map<Value*, DSNodeHandle>::const_iterator I = VM.begin();
+ I != VM.end(); ++I)
+ if (!isa<GlobalValue>(I->first)) {
+ std::stringstream OS;
+ WriteAsOperand(OS, I->first, false, true, G->getFunction().getParent());
+ GW.emitSimpleNode(I->first, "plaintext=circle", OS.str());
+
+ // Add edge from return node to real destination
+ int EdgeDest = I->second.getOffset();
+ if (EdgeDest == 0) EdgeDest = -1;
+ GW.emitEdge(I->first, -1, I->second.getNode(),
+ EdgeDest, "arrowtail=tee,color=gray63");
+ }
+
+
// Output the returned value pointer...
if (G->getRetNode().getNode() != 0) {
// Output the return node...