00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "c_breeze.h"
00041 #include "precision.h"
00042
00043 precisionAnalyzer::precisionAnalyzer()
00044 : analysisProblem(Forward),
00045 _pointer_targets(),
00046 _derefs(0)
00047 {}
00048
00053 void precisionAnalyzer::at_field_access(stmtLocation * current,
00054 operandNode *operand,
00055 pointerValue & operand_value,
00056 pointerValue & result)
00057 {
00058 record(current, operand_value, result);
00059 }
00060
00061
00062
00067 void precisionAnalyzer::at_dereference(stmtLocation * current,
00068 operandNode *operand,
00069 pointerValue & operand_value,
00070 pointerValue & result)
00071 {
00072 record(current, operand_value, result);
00073 }
00074
00079 void precisionAnalyzer::at_index(stmtLocation * current,
00080 operandNode *operand,
00081 pointerValue & left,
00082 pointerValue & right,
00083 pointerValue & result)
00084 {
00085 record(current, left, result);
00086 }
00087
00092 void precisionAnalyzer::report(ostream & out)
00093 {
00094 long int total_targets = 0;
00095 long int total_size = 0;
00096 long int def_targets = 0;
00097 long int def_size = 0;
00098 long int use_targets = 0;
00099 long int use_size = 0;
00100
00101 typedef map< stmtNode *, int > stmt_size_map;
00102 typedef stmt_size_map::iterator stmt_size_map_p;
00103
00104 stmt_size_map statements;
00105
00106 for (pointer_targets_map_p p = _pointer_targets.begin();
00107 p != _pointer_targets.end();
00108 ++p)
00109 {
00110 stmt_pointer_pair spp = (*p).first;
00111 memoryblock_set & targets = (*p).second;
00112 stmtLocation * loc = spp.first;
00113 memoryBlock * ptr = spp.second;
00114
00115 total_targets += targets.size();
00116 total_size++;
00117
00118
00119
00120
00121 stmtNode * stmt = loc->stmt();
00122 stmt_size_map_p found = statements.find(stmt);
00123 int max = 0;
00124
00125 if (found != statements.end())
00126 max = statements[stmt];
00127
00128 if ((int)targets.size() > max)
00129 statements[stmt] = max;
00130
00131 out << "------------------------------------------------------------" << endl;
00132 out << ptr->name() << " " << * loc << " " << targets.size() << endl;
00133
00134 output_context oc(out);
00135 stmt->output(oc, 0);
00136 out << endl << endl;
00137
00138
00139
00140 bool is_def = false;
00141
00142 for (memoryblock_set_p q = targets.begin();
00143 q != targets.end();
00144 q++)
00145 {
00146 memoryBlock * target = (*q);
00147 out << " --> " << target->name() << endl;
00148 if (target->find_def_at(loc) != 0)
00149 is_def = true;
00150 }
00151
00152 if (is_def) {
00153 def_targets += targets.size();
00154 def_size++;
00155 }
00156 else {
00157 use_targets += targets.size();
00158 use_size++;
00159 }
00160
00161
00162 }
00163
00164 double t = (double) total_targets;
00165 double s = (double) total_size;
00166
00167 if (total_size != 0)
00168 out << "Average points-to size: " << (t/s)
00169 << " = (" << t << "/" << s << ")" << endl;
00170 else
00171 out << "No dereferences" << endl;
00172
00173 t = (double) def_targets;
00174 s = (double) def_size;
00175
00176 if (def_size != 0)
00177 out << "Average points-to size at a definition: " << (t/s)
00178 << " = (" << t << "/" << s << ")" << endl;
00179 else
00180 out << "No dereferences at definitions" << endl;
00181
00182 t = (double) use_targets;
00183 s = (double) use_size;
00184
00185 if (use_size != 0)
00186 out << "Average points-to size at a use: " << (t/s)
00187 << " = (" << t << "/" << s << ")" << endl;
00188 else
00189 out << "No dereferences at uses" << endl;
00190
00191 long int stmt_targets = 0;
00192 long int stmt_size = 0;
00193
00194 for (stmt_size_map_p p = statements.begin();
00195 p != statements.end();
00196 ++p)
00197 {
00198 stmt_targets += (*p).second;
00199 stmt_size++;
00200 }
00201
00202 t = (double) stmt_targets;
00203 s = (double) stmt_size;
00204
00205 if (stmt_size != 0)
00206 out << "Average points-to size at each statement: " << (t/s)
00207 << " = (" << t << "/" << s << ")" << endl;
00208 else
00209 out << "No dereferences at statements" << endl;
00210
00211 out << "Total deref cout: " << _derefs << endl;
00212 }
00213
00214 void precisionAnalyzer::record(stmtLocation * current,
00215 pointerValue & operand,
00216 pointerValue & result)
00217 {
00218 memoryblock_set & pointers = operand.blocks;
00219 memoryblock_set & targets = result.blocks;
00220
00221 _derefs++;
00222
00223
00224
00225 if ( ! operand.is_address) {
00226
00227 if (pointerOptions::Verbose) {
00228 if (pointers.empty()) {
00229 cout << "------------------------------------------------------------" << endl;
00230 cout << "WARNING: No pointer operand at " << * current << endl;
00231 stmtNode * stmt = current->stmt();
00232 output_context oc(cout);
00233 stmt->output(oc, 0);
00234 cout << endl << endl;
00235 }
00236 }
00237
00238 for (memoryblock_set_p p = pointers.begin();
00239 p != pointers.end();
00240 ++p)
00241 {
00242 memoryBlock * pointer = *p;
00243
00244
00245
00246 stmt_pointer_pair spp(current, pointer);
00247
00248
00249
00250 memoryblock_set & target_set = _pointer_targets[spp];
00251
00252
00253
00254 target_set.insert(targets.begin(), targets.end());
00255
00256
00257 }
00258 }
00259 }
00260