C-Breeze
C Compiler Infrastructure

[ Project home page]
Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

test.cc

Go to the documentation of this file.
00001 // $Id: test.cc,v 1.11 2003/08/07 23:14:33 pnav Exp $
00002 // ----------------------------------------------------------------------
00003 //
00004 //  C-Breeze
00005 //  C Compiler Framework
00006 // 
00007 //  Copyright (c) 2000 University of Texas at Austin
00008 // 
00009 //  Samuel Z. Guyer
00010 //  Daniel A. Jimenez
00011 //  Calvin Lin
00012 // 
00013 //  Permission is hereby granted, free of charge, to any person
00014 //  obtaining a copy of this software and associated documentation
00015 //  files (the "Software"), to deal in the Software without
00016 //  restriction, including without limitation the rights to use, copy,
00017 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00018 //  of the Software, and to permit persons to whom the Software is
00019 //  furnished to do so, subject to the following conditions:
00020 //  
00021 //  The above copyright notice and this permission notice shall be
00022 //  included in all copies or substantial portions of the Software.
00023 //  
00024 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00028 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00029 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00030 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00031 //  THE SOFTWARE.
00032 //
00033 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00034 //  Computer Science for inspiring parts of the C-Breeze design.
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 // Make sure its a tree
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     // Defaults:
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       // Dismantle
00217 
00218       Dismantle::dismantle(u, DEFAULT_DISMANTLER_FLAGS | INDEX_IS_PRIMITIVE);
00219       //Dismantle::dismantle(u, DEFAULT_DISMANTLER_FLAGS );
00220 
00221       // Build CFG
00222 
00223       cfg_changer cfgc;
00224       u->change (cfgc);
00225 
00226       // Remove unreachable code
00227 
00228       Unreachable::remove(u);
00229 
00230       // Fixup indentifiers
00231 
00232       id_lookup_walker::fixup(u, false);
00233       // semcheck_walker::check(u, false);
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       // -- Find the main function
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               // memoryAccess::Verbose = true;
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                 // memoryBlock::stats();
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                 // constantAnalysis::watch = new string("globalCrc");
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               if (_stats) {
00345                 Location::stats();
00346                 memoryBlock::stats();
00347                 memoryAccess::stats();
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 bool operator<(const constant & one, const constant & two)
00422 {
00423   // -- CASE 1: Non value is the smallest element
00424 
00425   if (one.no_val() && two.no_val())
00426     return false;
00427 
00428   if (one.no_val())
00429     return true;
00430 
00431   if (two.no_val())
00432     return false;
00433 
00434   // -- CASE 2: Strings
00435 
00436   if (one.is_str() &&
00437       two.is_str())
00438     return (strcmp(one.Str(),two.Str()) < 0);
00439 
00440   // -- CASE 3: Pointers
00441 
00442   if (one.is_ptr() &&
00443       two.is_ptr())
00444     return one.Ptr() < two.Ptr();
00445 
00446   // -- CASE 4: Regular numeric types
00447 
00448   if (one.basic() == two.basic()) {
00449     constant result = constant::eval(Operators::table['<'], one, two);
00450     return result.Boolean();
00451   }
00452   else {
00453 
00454     // -- CASE 5: Two different basic types: Always return false?
00455 
00456     return one.basic() < two.basic();
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 

Generated on August 27, 2003
Back to the C-Breeze home page