Eliminate the cfg namespace, moving LoopInfo, Dominators, Interval* classes
[oota-llvm.git] / lib / Analysis / DataStructure / DataStructure.cpp
1 //===- DataStructure.cpp - Analysis for data structure identification -------=//
2 //
3 // Implement the LLVM data structure analysis library.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "llvm/Analysis/DataStructure.h"
8 #include "llvm/Module.h"
9 #include "llvm/Function.h"
10 #include <fstream>
11 #include <algorithm>
12
13 //===----------------------------------------------------------------------===//
14 // DataStructure Class Implementation
15 //
16
17 AnalysisID DataStructure::ID(AnalysisID::create<DataStructure>());
18
19 // releaseMemory - If the pass pipeline is done with this pass, we can release
20 // our memory... here...
21 void DataStructure::releaseMemory() {
22   for (InfoMap::iterator I = DSInfo.begin(), E = DSInfo.end(); I != E; ++I) {
23     delete I->second.first;
24     delete I->second.second;
25   }
26
27   // Empty map so next time memory is released, data structures are not
28   // re-deleted.
29   DSInfo.clear();
30 }
31
32 // FIXME REMOVE
33 #include <sys/time.h>
34 #include "Support/CommandLine.h"
35
36 cl::Flag   Time("t", "Print analysis time...");
37
38
39 // print - Print out the analysis results...
40 void DataStructure::print(std::ostream &O, Module *M) const {
41   if (Time) {
42     timeval TV1, TV2;
43     gettimeofday(&TV1, 0);
44     for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
45       if (!(*I)->isExternal()) {
46         getDSGraph(*I);
47         getClosedDSGraph(*I);
48       }
49     gettimeofday(&TV2, 0);
50     cerr << "Analysis took "
51          << (TV2.tv_sec-TV1.tv_sec)*1000000+(TV2.tv_usec-TV1.tv_usec)
52          << " microseconds.\n";
53   }
54
55   for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
56     if (!(*I)->isExternal()) {
57
58       string Filename = "ds." + (*I)->getName() + ".dot";
59       O << "Writing '" << Filename << "'...";
60       ofstream F(Filename.c_str());
61       if (F.good()) {
62         F << "digraph DataStructures {\n"
63           << "\tnode [shape=Mrecord];\n"
64           << "\tedge [arrowtail=\"dot\"];\n"
65           << "\tsize=\"10,7.5\";\n"
66           << "\trotate=\"90\";\n";
67
68         getDSGraph(*I).printFunction(F, "Local");
69         getClosedDSGraph(*I).printFunction(F, "Closed");
70
71         F << "}\n";
72       } else {
73         O << "  error opening file for writing!\n";
74       }
75
76       if (Time) 
77         O << " [" << getDSGraph(*I).getGraphSize() << ", "
78           << getClosedDSGraph(*I).getGraphSize() << "]\n";
79       else
80         O << "\n";
81     }
82 }
83
84
85 //===----------------------------------------------------------------------===//
86 // PointerVal Class Implementation
87 //
88
89 void PointerVal::print(std::ostream &O) const {
90   if (Node) {
91     O << "  Node: " << Node->getCaption() << "[" << Index << "]\n";
92   } else {
93     O << "  NULL NODE\n";
94   }
95 }
96
97 //===----------------------------------------------------------------------===//
98 // PointerValSet Class Implementation
99 //
100
101 void PointerValSet::addRefs() {
102   for (unsigned i = 0, e = Vals.size(); i != e; ++i)
103     Vals[i].Node->addReferrer(this);
104 }
105
106 void PointerValSet::dropRefs() {
107   for (unsigned i = 0, e = Vals.size(); i != e; ++i)
108     Vals[i].Node->removeReferrer(this);
109 }
110
111 const PointerValSet &PointerValSet::operator=(const PointerValSet &PVS) {
112   dropRefs();
113   Vals.clear();
114   Vals = PVS.Vals;
115   addRefs();
116   return *this;
117 }
118
119 // operator< - Allow insertion into a map...
120 bool PointerValSet::operator<(const PointerValSet &PVS) const {
121   if (Vals.size() < PVS.Vals.size()) return true;
122   if (Vals.size() > PVS.Vals.size()) return false;
123   if (Vals.size() == 1) return Vals[0] < PVS.Vals[0];  // Most common case
124
125   vector<PointerVal> S1(Vals), S2(PVS.Vals);
126   sort(S1.begin(), S1.end());
127   sort(S2.begin(), S2.end());
128   return S1 < S2;
129 }
130
131 bool PointerValSet::operator==(const PointerValSet &PVS) const {
132   if (Vals.size() != PVS.Vals.size()) return false;
133   if (Vals.size() == 1) return Vals[0] == PVS.Vals[0];  // Most common case...
134
135   vector<PointerVal> S1(Vals), S2(PVS.Vals);
136   sort(S1.begin(), S1.end());
137   sort(S2.begin(), S2.end());
138   return S1 == S2;
139 }
140
141
142 bool PointerValSet::add(const PointerVal &PV, Value *Pointer) {
143   if (std::find(Vals.begin(), Vals.end(), PV) != Vals.end())
144     return false;
145   Vals.push_back(PV);
146   if (Pointer) PV.Node->addPointer(Pointer);
147   PV.Node->addReferrer(this);
148   return true;
149 }
150
151 // removePointerTo - Remove a single pointer val that points to the specified
152 // node...
153 void PointerValSet::removePointerTo(DSNode *Node) {
154   vector<PointerVal>::iterator I = std::find(Vals.begin(), Vals.end(), Node);
155   assert(I != Vals.end() && "Couldn't remove nonexistent edge!");
156   Vals.erase(I);
157   Node->removeReferrer(this);
158 }
159
160
161 void PointerValSet::print(std::ostream &O) const {
162   for (unsigned i = 0, e = Vals.size(); i != e; ++i)
163     Vals[i].print(O);
164 }
165