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 #include "c_breeze.h"
00039
00040 #include <bitset>
00041
00042 #include "semcheck.h"
00043 #include "scope_walker.h"
00044 #include "id_lookup_walker.h"
00045 #include "callgraph_walker.h"
00046 #include "ref_clone_changer.h"
00047 #include "ssa.h"
00048 #include "pointers.h"
00049 #include "unreachable.h"
00050 #include "dismantle.h"
00051 #include "cfg.h"
00052 #include "callgraph.h"
00053 #include "dfpreds.h"
00054
00055 #include "constants.h"
00056 #include "liveness.h"
00057
00058 #include <sys/time.h>
00059 #include <unistd.h>
00060
00061
00062
00063
00064
00065 typedef set< Node * > node_set;
00066 typedef node_set::iterator node_set_p;
00067
00068 class TreeFixer : public Changer
00069 {
00070 public:
00071
00072 static void fix(Node * node)
00073 {
00074 TreeFixer tf;
00075 node->change(tf);
00076 }
00077
00078 private:
00079
00080 node_set _nodes;
00081
00082 TreeFixer()
00083 : Changer(Preorder, Subtree, false),
00084 _nodes()
00085 {}
00086
00087 public:
00088
00089 Node * at_decl(declNode * the_node, Order ord)
00090 {
00091 node_set_p f = _nodes.find(the_node);
00092 if (f == _nodes.end()) {
00093 _nodes.insert(the_node);
00094 return the_node;
00095 }
00096 else {
00097 return ref_clone_changer::clone(the_node, false);
00098 }
00099 }
00100 };
00101
00102 class count_walker : public Walker
00103 {
00104 private:
00105
00106 int _id_count;
00107 int _const_count;
00108
00109 public:
00110
00111 count_walker()
00112 : Walker(Preorder, Subtree),
00113 _id_count(0),
00114 _const_count(0)
00115 {}
00116
00117 virtual void at_id(idNode * the_id, Order ord)
00118 {
00119 _id_count++;
00120 }
00121
00122 virtual void at_const(constNode * the_const, Order ord)
00123 {
00124 _const_count++;
00125 }
00126
00127 int final_id_count() const { return _id_count; }
00128 int final_const_count() const { return _const_count; }
00129 };
00130
00131 class pointers_phase : public Phase
00132 {
00133 private:
00134
00135 bool _debug;
00136 bool _defs_uses;
00137 bool _constants;
00138 bool _simplify;
00139 bool _deadcode;
00140 bool _stats;
00141 bool _callgraph;
00142 int _threshold;
00143 bool _use_mult;
00144
00145 public:
00146
00147 void get_flags (str_list_p & arg) {
00148
00149
00150
00151 _debug = false;
00152 _defs_uses = false;
00153 _constants = false;
00154 _simplify = false;
00155 _deadcode = false;
00156 _stats = false;
00157 _callgraph = false;
00158 _threshold = -1;
00159 _use_mult = true;
00160
00161 bool done = false;
00162
00163 do {
00164
00165 string & flag = (*arg);
00166
00167 if (flag == "debug")
00168 _debug = true;
00169 else
00170 if (flag == "defsuses")
00171 _defs_uses = true;
00172 else
00173 if (flag == "constants")
00174 _constants = true;
00175 else
00176 if (flag == "simplify")
00177 _simplify = true;
00178 else
00179 if (flag == "deadcode")
00180 _deadcode = true;
00181 else
00182 if (flag == "stats")
00183 _stats = true;
00184 else
00185 if (flag == "callgraph")
00186 _stats = true;
00187 else
00188 if (flag == "mult")
00189 _use_mult = true;
00190 else
00191 if (flag == "nomult")
00192 _use_mult = false;
00193 else
00194 if (flag == "cs") {
00195 ++arg;
00196 _threshold = atoi((*arg).c_str());
00197 }
00198 else
00199 done = true;
00200
00201 if ( ! done )
00202 ++arg;
00203 } while ( ! done );
00204 }
00205
00206 void run()
00207 {
00208
00209 cout << " *** Start Fixup *** " << endl;
00210
00211 for (unit_list_p up = CBZ::Program.begin();
00212 up != CBZ::Program.end();
00213 ++up) {
00214 unitNode * u = (*up);
00215
00216
00217
00218 Dismantle::dismantle(u, DEFAULT_DISMANTLER_FLAGS | INDEX_IS_PRIMITIVE);
00219
00220
00221
00222
00223 cfg_changer cfgc;
00224 u->change (cfgc);
00225
00226
00227
00228 Unreachable::remove(u);
00229
00230
00231
00232 id_lookup_walker::fixup(u, false);
00233
00234 TreeFixer::fix(u);
00235 }
00236
00237 for (unit_list_p up = CBZ::Program.begin();
00238 up != CBZ::Program.end();
00239 ++up) {
00240 unitNode * u = (*up);
00241 procNode * main_proc = 0;
00242
00243
00244
00245 for (def_list_p dp = u->defs().begin();
00246 dp != u->defs().end();
00247 ++dp) {
00248 defNode * dn = (*dp);
00249 if (dn->typ() == Proc) {
00250 procNode * pr = (procNode *) dn;
00251 if (pr->decl()->name() == "main") {
00252
00253 if (_callgraph) {
00254 Linker l;
00255 callGraph cg(pr, l);
00256 cg.show_all_contexts();
00257 }
00258 else {
00259 Pointers * pointers = new Pointers(pr, u, _debug);
00260
00261 struct timeval before;
00262 struct timeval after;
00263
00264 if (_use_mult) {
00265 pointers->turn_on_multiplicity();
00266 cout << "Multiplicity on" << endl;
00267 }
00268 else {
00269 pointers->turn_off_multiplicity();
00270 cout << "Multiplicity off" << endl;
00271 }
00272
00273 cout << "*** Starting pointer analysis ***" << endl;
00274
00275 if (_threshold >= 0) {
00276 cout << " Context-sensitivity at " << _threshold << endl;
00277 pointers->set_context_sensitivity_threshold(_threshold);
00278 }
00279
00280
00281
00282 gettimeofday(&before,0);
00283
00284 pointers->analyze();
00285
00286 gettimeofday(&after, 0);
00287
00288 if (_defs_uses)
00289 pointers->uses_and_defs();
00290
00291 cout << "Time: " << after.tv_sec - before.tv_sec << endl;
00292 cout << "Calls to dominates: " << Location::dom_calls << endl;
00293
00294 if (_stats) {
00295 Location::stats();
00296
00297 pointers->stats(cout);
00298 memoryAccess::stats();
00299 }
00300
00301 if (_constants) {
00302 int ids_before;
00303 int ids_after;
00304 int consts_before;
00305 int consts_after;
00306
00307 count_walker before;
00308 count_walker after;
00309
00310 u->walk(before);
00311 ids_before = before.final_id_count();
00312 consts_before = before.final_const_count();
00313
00314 constantAnalyzer constants(_debug);
00315
00316
00317 pointers->analyze(&constants);
00318 constantsChanger::optimize(u, &constants, _simplify);
00319
00320 u->walk(after);
00321 ids_after = after.final_id_count();
00322 consts_after = after.final_const_count();
00323
00324 if (_stats) {
00325 cout << "Constant propagation results:" << endl;
00326 cout << " IDs: before = " << ids_before << " after = " <<
00327 ids_after << " diff = " << ids_after - ids_before << endl;
00328 cout << " Consts: before = " << consts_before << " after = " <<
00329 consts_after << " diff = " << consts_after - consts_before << endl;
00330 }
00331
00332 pointers->analyze();
00333 }
00334
00335 if (_deadcode) {
00336 livenessAnalyzer liveness(_debug);
00337 pointers->analyze(&liveness);
00338 deadcodeChanger::optimize(u, &liveness);
00339 }
00340
00341 delete pointers;
00342
00343
00344
00345
00346
00347
00348
00349
00350 }
00351 }
00352 }
00353 }
00354
00355 }
00356 }
00357 };
00358
00359 Phases make_pointers_phase ("pointers", new pointers_phase());
00360
00361
00362
00363 class ssa_phase : public Phase
00364 {
00365 public:
00366
00367 void run()
00368 {
00369 for (unit_list_p up = CBZ::Program.begin();
00370 up != CBZ::Program.end();
00371 ++up) {
00372 unitNode * u = (*up);
00373 TreeFixer::fix(u);
00374 for (def_list_p dp = u->defs().begin();
00375 dp != u->defs().end();
00376 ++dp) {
00377 defNode * dn = (*dp);
00378 if (dn->typ() == Proc) {
00379 procNode * pr = (procNode *) dn;
00380 SSA ssa(pr);
00381 }
00382 }
00383 }
00384 }
00385 };
00386
00387 Phases make_ssa_phase("ssa", new ssa_phase());
00388
00389
00390
00391 class dfpreds_phase : public Phase
00392 {
00393 public:
00394
00395 void run()
00396 {
00397 for (unit_list_p up = CBZ::Program.begin();
00398 up != CBZ::Program.end();
00399 ++up) {
00400 unitNode * u = (*up);
00401 TreeFixer::fix(u);
00402 for (def_list_p dp = u->defs().begin();
00403 dp != u->defs().end();
00404 ++dp) {
00405 defNode * dn = (*dp);
00406 if (dn->typ() == Proc) {
00407 procNode * pr = (procNode *) dn;
00408 DFPreds dfpreds(pr);
00409 }
00410 }
00411 }
00412 }
00413 };
00414
00415 Phases make_dfpreds_phase("dfpreds", new dfpreds_phase());
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 class const_phase : public Phase
00462 {
00463 public:
00464
00465 typedef set< constant > constant_set;
00466 typedef constant_set::iterator constant_set_p;
00467
00468
00469
00470 void run()
00471 {
00472 constant_set temp;
00473
00474 temp.insert(constant(1));
00475 temp.insert(constant(2));
00476 temp.insert(constant(3));
00477
00478 constant_set_p p;
00479
00480 p = temp.find(constant(2));
00481 if (p == temp.end())
00482 cout << "Not found (unexpected)" << endl;
00483 else
00484 cout << "Found (expected)" << endl;
00485
00486 p = temp.find(constant(4));
00487 if (p == temp.end())
00488 cout << "Not found (expected)" << endl;
00489 else
00490 cout << "Found (unexpected)" << endl;
00491
00492 p = temp.find(constant(2.0));
00493 if (p == temp.end())
00494 cout << "Not found (expected)" << endl;
00495 else
00496 cout << "Found (unexpected)" << endl;
00497
00498 temp.insert(constant(2.0));
00499
00500 p = temp.find(constant(2.0));
00501 if (p == temp.end())
00502 cout << "Not found (unexpected)" << endl;
00503 else
00504 cout << "Found (expected)" << endl;
00505
00506 constant nv;
00507
00508 nv.set_no_val();
00509
00510 temp.insert(nv);
00511
00512 constant nv2;
00513
00514 nv2.set_no_val();
00515
00516 p = temp.find(nv2);
00517 if (p == temp.end())
00518 cout << "Not found (unexpected)" << endl;
00519 else
00520 cout << "Found (expected)" << endl;
00521
00522 temp.insert(nv);
00523
00524 cout << "Size = " << temp.size() << endl;
00525
00526 }
00527 };
00528
00529 Phases make_const_phase("const", new const_phase());
00530