blob: dd0b52a4383470a0a1ade2d11cbce888480a7c5c [file] [log] [blame]
Chris Lattnerc68c31b2002-07-10 22:38:08 +00001//===- DataStructure.cpp - Implement the core data structure analysis -----===//
Chris Lattnerbb2a28f2002-03-26 22:39:06 +00002//
Chris Lattnerc68c31b2002-07-10 22:38:08 +00003// This file implements the core data structure functionality.
Chris Lattnerbb2a28f2002-03-26 22:39:06 +00004//
5//===----------------------------------------------------------------------===//
6
7#include "llvm/Analysis/DataStructure.h"
8#include "llvm/Module.h"
Chris Lattnerc68c31b2002-07-10 22:38:08 +00009#include "llvm/DerivedTypes.h"
Chris Lattnerbb2a28f2002-03-26 22:39:06 +000010#include <algorithm>
Chris Lattnerc68c31b2002-07-10 22:38:08 +000011#include "Support/STLExtras.h"
12
13AnalysisID LocalDataStructures::ID(AnalysisID::create<LocalDataStructures>());
Chris Lattnerbb2a28f2002-03-26 22:39:06 +000014
15//===----------------------------------------------------------------------===//
Chris Lattnerc68c31b2002-07-10 22:38:08 +000016// DSNode Implementation
17//===----------------------------------------------------------------------===//
Chris Lattnerbb2a28f2002-03-26 22:39:06 +000018
Chris Lattnerc68c31b2002-07-10 22:38:08 +000019DSNode::DSNode(enum NodeTy NT, const Type *T) : Ty(T), NodeType(NT) {
20 // If this node has any fields, allocate them now, but leave them null.
21 switch (T->getPrimitiveID()) {
22 case Type::PointerTyID: Links.resize(1); break;
23 case Type::ArrayTyID: Links.resize(1); break;
24 case Type::StructTyID:
25 Links.resize(cast<StructType>(T)->getNumContainedTypes());
26 break;
27 default: break;
28 }
29}
30
31void DSNode::removeReferrer(DSNodeHandle *H) {
32 // Search backwards, because we depopulate the list from the back for
33 // efficiency (because it's a vector).
34 std::vector<DSNodeHandle*>::reverse_iterator I =
35 std::find(Referrers.rbegin(), Referrers.rend(), H);
36 assert(I != Referrers.rend() && "Referrer not pointing to node!");
37 Referrers.erase(I.base()-1);
38}
39
Chris Lattnerf9ae4c52002-07-11 20:32:22 +000040// addGlobal - Add an entry for a global value to the Globals list. This also
41// marks the node with the 'G' flag if it does not already have it.
42//
43void DSNode::addGlobal(GlobalValue *GV) {
44 assert(GV->getType()->getElementType() == Ty);
45 Globals.push_back(GV);
46 NodeType |= GlobalNode;
47}
48
49
Chris Lattnerc68c31b2002-07-10 22:38:08 +000050// addEdgeTo - Add an edge from the current node to the specified node. This
51// can cause merging of nodes in the graph.
52//
53void DSNode::addEdgeTo(unsigned LinkNo, DSNode *N) {
54 assert(LinkNo < Links.size() && "LinkNo out of range!");
55 if (N == 0 || Links[LinkNo] == N) return; // Nothing to do
56 if (Links[LinkNo] == 0) { // No merging to perform
57 Links[LinkNo] = N;
58 return;
59 }
60
61 // Merge the two nodes...
62 Links[LinkNo]->mergeWith(N);
63}
64
65
66// mergeWith - Merge this node into the specified node, moving all links to and
67// from the argument node into the current node. The specified node may be a
68// null pointer (in which case, nothing happens).
69//
70void DSNode::mergeWith(DSNode *N) {
71 if (N == 0 || N == this) return; // Noop
72 assert(N->Ty == Ty && N->Links.size() == Links.size() &&
73 "Cannot merge nodes of two different types!");
74
75 // Remove all edges pointing at N, causing them to point to 'this' instead.
76 while (!N->Referrers.empty())
77 *N->Referrers.back() = this;
78
79 // Make all of the outgoing links of N now be outgoing links of this. This
80 // can cause recursive merging!
81 //
82 for (unsigned i = 0, e = Links.size(); i != e; ++i) {
83 addEdgeTo(i, N->Links[i]);
84 N->Links[i] = 0; // Reduce unneccesary edges in graph. N is dead
85 }
86
Chris Lattnerf9ae4c52002-07-11 20:32:22 +000087 // Merge the node types
Chris Lattnerc68c31b2002-07-10 22:38:08 +000088 NodeType |= N->NodeType;
89 N->NodeType = 0; // N is now a dead node.
Chris Lattnerf9ae4c52002-07-11 20:32:22 +000090
91 // Merge the globals list...
92 Globals.insert(Globals.end(), N->Globals.begin(), N->Globals.end());
93 N->Globals.clear();
Chris Lattnerc68c31b2002-07-10 22:38:08 +000094}
95
96//===----------------------------------------------------------------------===//
97// DSGraph Implementation
98//===----------------------------------------------------------------------===//
99
100DSGraph::~DSGraph() {
101 FunctionCalls.clear();
102 ValueMap.clear();
103 RetNode = 0;
104
105#ifndef NDEBUG
106 // Drop all intra-node references, so that assertions don't fail...
107 std::for_each(Nodes.begin(), Nodes.end(),
108 std::mem_fun(&DSNode::dropAllReferences));
109#endif
110
111 // Delete all of the nodes themselves...
112 std::for_each(Nodes.begin(), Nodes.end(), deleter<DSNode>);
113}
114
115//===----------------------------------------------------------------------===//
116// LocalDataStructures Implementation
117//===----------------------------------------------------------------------===//
Chris Lattnerbb2a28f2002-03-26 22:39:06 +0000118
119// releaseMemory - If the pass pipeline is done with this pass, we can release
120// our memory... here...
Chris Lattnerc68c31b2002-07-10 22:38:08 +0000121//
122void LocalDataStructures::releaseMemory() {
123 for (std::map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
124 E = DSInfo.end(); I != E; ++I)
125 delete I->second;
Chris Lattnerbb2a28f2002-03-26 22:39:06 +0000126
127 // Empty map so next time memory is released, data structures are not
128 // re-deleted.
129 DSInfo.clear();
130}
131
Chris Lattnerc68c31b2002-07-10 22:38:08 +0000132bool LocalDataStructures::run(Module &M) {
133 // Calculate all of the graphs...
134 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
Chris Lattner18961502002-06-25 16:12:52 +0000135 if (!I->isExternal()) {
Chris Lattnerc68c31b2002-07-10 22:38:08 +0000136 std::map<Function*, DSGraph*>::iterator DI = DSInfo.find(I);
137 if (DI == DSInfo.end() || DI->second == 0)
138 DSInfo.insert(std::make_pair(&*I, new DSGraph(*I)));
Chris Lattnerbb2a28f2002-03-26 22:39:06 +0000139 }
Chris Lattnerc68c31b2002-07-10 22:38:08 +0000140
141 return false;
Chris Lattnerbb2a28f2002-03-26 22:39:06 +0000142}