Many changes
[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
33 // print - Print out the analysis results...
34 void DataStructure::print(std::ostream &O, Module *M) const {
35   for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
36     if (!(*I)->isExternal()) {
37
38       string Filename = "ds." + (*I)->getName() + ".dot";
39       O << "Writing '" << Filename << "'...\n";
40       ofstream F(Filename.c_str());
41       if (F.good()) {
42         F << "digraph DataStructures {\n"
43           << "\tnode [shape=Mrecord];\n"
44           << "\tedge [arrowtail=\"dot\"];\n"
45           << "\tsize=\"10,7.5\";\n"
46           << "\trotate=\"90\";\n";
47
48         getDSGraph(*I).printFunction(F, "Local");
49         getClosedDSGraph(*I).printFunction(F, "Closed");
50
51         F << "}\n";
52       } else {
53         O << "  error opening file for writing!\n";
54       }
55     }
56 }
57
58
59 //===----------------------------------------------------------------------===//
60 // PointerVal Class Implementation
61 //
62
63 void PointerVal::print(std::ostream &O) const {
64   if (Node) {
65     O << "  Node: " << Node->getCaption() << "[" << Index << "]\n";
66   } else {
67     O << "  NULL NODE\n";
68   }
69 }
70
71 //===----------------------------------------------------------------------===//
72 // PointerValSet Class Implementation
73 //
74
75 void PointerValSet::addRefs() {
76   for (unsigned i = 0, e = Vals.size(); i != e; ++i)
77     Vals[i].Node->addReferrer(this);
78 }
79
80 void PointerValSet::dropRefs() {
81   for (unsigned i = 0, e = Vals.size(); i != e; ++i)
82     Vals[i].Node->removeReferrer(this);
83 }
84
85 const PointerValSet &PointerValSet::operator=(const PointerValSet &PVS) {
86   dropRefs();
87   Vals.clear();
88   Vals = PVS.Vals;
89   addRefs();
90   return *this;
91 }
92
93 // operator< - Allow insertion into a map...
94 bool PointerValSet::operator<(const PointerValSet &PVS) const {
95   if (Vals.size() < PVS.Vals.size()) return true;
96   if (Vals.size() > PVS.Vals.size()) return false;
97   if (Vals.size() == 1) return Vals[0] < PVS.Vals[0];  // Most common case
98
99   vector<PointerVal> S1(Vals), S2(PVS.Vals);
100   sort(S1.begin(), S1.end());
101   sort(S2.begin(), S2.end());
102   return S1 < S2;
103 }
104
105 bool PointerValSet::operator==(const PointerValSet &PVS) const {
106   if (Vals.size() != PVS.Vals.size()) return false;
107   if (Vals.size() == 1) return Vals[0] == PVS.Vals[0];  // Most common case...
108
109   vector<PointerVal> S1(Vals), S2(PVS.Vals);
110   sort(S1.begin(), S1.end());
111   sort(S2.begin(), S2.end());
112   return S1 == S2;
113 }
114
115
116 bool PointerValSet::add(const PointerVal &PV, Value *Pointer) {
117   if (std::find(Vals.begin(), Vals.end(), PV) != Vals.end())
118     return false;
119   Vals.push_back(PV);
120   if (Pointer) PV.Node->addPointer(Pointer);
121   PV.Node->addReferrer(this);
122   return true;
123 }
124
125 // removePointerTo - Remove a single pointer val that points to the specified
126 // node...
127 void PointerValSet::removePointerTo(DSNode *Node) {
128   vector<PointerVal>::iterator I = std::find(Vals.begin(), Vals.end(), Node);
129   assert(I != Vals.end() && "Couldn't remove nonexistent edge!");
130   Vals.erase(I);
131   Node->removeReferrer(this);
132 }
133
134
135 void PointerValSet::print(std::ostream &O) const {
136   for (unsigned i = 0, e = Vals.size(); i != e; ++i)
137     Vals[i].print(O);
138 }
139