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  

optimize.cc

Go to the documentation of this file.
00001 // $Id: optimize.cc,v 1.7 2003/08/07 23:14:19 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 // optimize.cc
00039 //
00040 // An optimization phase including dead code elimination,
00041 // constant propagation, constant folding and control flow
00042 // simplification.  Soon to come: copy propagation.
00043 //
00044 
00045 #include <stdio.h>
00046 #include "c_breeze.h"
00047 #include "scope_walker.h"
00048 #include "name_mangle_walker.h"
00049 #include "goto_label_walker.h"
00050 #include "dismantle.h"
00051 #include "gc_walker.h"
00052 #include "cfg.h"
00053 #include "bits.h"
00054 #include "reaching_genkill.h"
00055 #include "reaching.h"
00056 #include "constprop.h"
00057 #include "optimize.h"
00058 #include "defuse.h"
00059 #include "live.h"
00060 #include "dead.h"
00061 #include "localcopyprop.h"
00062 
00063 Node * CFS_Changer::at_proc (procNode *p, Order) {
00064         // after all ifs have been checked,
00065         // flatten (to remove unreachable code)
00066         // and put it back into a smaller control flow
00067         // graph
00068         if (changed) {
00069                 UsedLabelWalker uw;
00070                 p->walk (uw);
00071                 FlattenDismantleChanger fc (uw.labels(), DEFAULT_DISMANTLER_FLAGS);
00072                 p->change (fc);
00073                 UsedLabelWalker uw1;
00074                 p->walk (uw1);
00075                 FlattenDismantleChanger fc1 (uw1.labels(), DEFAULT_DISMANTLER_FLAGS);
00076                 p->change (fc1);
00077                 cfg_changer cfgc;
00078                 p->change (cfgc);
00079         }
00080 
00081         return p;
00082 }
00083 
00084 Node * CFS_Changer::at_if (ifNode *i, Order) {
00085         if (i->expr() && i->expr()->typ() == Const) {
00086                 constNode *c = (constNode *) i->expr();
00087 
00088                 if (c->value().Boolean()) {
00089 
00090                         // if the constant is true, just return the
00091                         // stmt; it's always executed.
00092 
00093                         changed = true;
00094                         return i->stmt();
00095                 } else {
00096 
00097                         // otherwise, return an empty stmt; 
00098                         // i->stmt() is never executed
00099 
00100                         changed = true;
00101                         return new exprstmtNode (NULL);
00102                 }
00103         }
00104         return i;
00105 }
00106 
00107 class CastRemover : public Changer {
00108 public:
00109         CastRemover (void) : Changer (Preorder, Subtree, false) { }
00110 
00111         Node * at_cast (castNode *c, Order) {
00112           if (c->is_implicit())
00113             return c->expr();
00114           else
00115             return c;
00116         }
00117 
00118 #ifdef FOO
00119         Node * at_binary (binaryNode *b, Order) {
00120                 if (b->op()->id() == '=') {
00121                         if (b->left()->typ() == Const) {
00122                                 return b->left();
00123                         }
00124                 }
00125                 return b;
00126         }
00127 #endif
00128 };
00129 
00130 Node * Optimizer::at_proc (procNode *p, Order) {
00131         fprintf (stderr, "%s: ", p->decl()->name().c_str());
00132         fflush (stderr);
00133         reachingDefinitionsWalker rdw;
00134         constantPropChanger cpc;
00135         constantFoldingChanger cfc;
00136         udChainRemover udr;
00137         livenessRemover lr;
00138         CFS_Changer cfsc;
00139         livenessWalker lw;
00140         deadCodeEliminationChanger dcc;
00141         unusedVariableCleanupChanger cc;
00142         LocalCopyPropChanger lcpc;
00143         CastRemover cr;
00144 
00145         int i = 0;
00146 
00147         // initially do constant folding; maybe the
00148         // program has constant folding opportunities
00149         // we can quickly exploit and maybe do fewer iterations
00150         // of the expensive stuff
00151 
00152         p->change (cfc);
00153         p->change (cr);
00154         do {
00155                 cpc.changed = false;
00156                 cfc.changed = false;
00157 
00158                 // get ud-chain information for each use
00159 
00160                 p->walk (rdw);
00161 
00162                 // do constant propagation with ud-chain info
00163 
00164                 fprintf (stderr, "C"); fflush (stdout);
00165                 p->change (cpc);
00166 
00167                 // do constant folding
00168 
00169                 fprintf (stderr, "F"); fflush (stdout);
00170                 p->change (cfc);
00171                 p->change (cr);
00172 
00173                 // do control flow simplification
00174 
00175                 fprintf (stderr, "S"); fflush (stdout);
00176                 p->change (cfsc);
00177 
00178                 // local copy propagation
00179                 // something's wrong with local
00180                 // copyprop, I think.  
00181                 // it's causing MPG123 to crash.
00182                 fprintf (stderr, "P"); fflush (stdout);
00183                 p->change (lcpc);
00184 
00185                 // get liveness information for each basic block
00186 
00187                 fprintf (stderr, "L"); fflush (stdout);
00188                 p->walk (lw);
00189 
00190                 // remove dead code
00191 
00192                 fprintf (stderr, "D"); fflush (stdout);
00193                 p->change (dcc);
00194                 fprintf (stderr, "U"); fflush (stdout);
00195                 p->change (cc);
00196                 fprintf (stderr, "."); fflush (stdout);
00197 
00198                 // don't blow away ud-chains or liveness info
00199                 // on last iteration; someone else might want them.
00200 
00201 #define MAX_ITER 4
00202                 i++;
00203 
00204 // I don't know why, but sometimes this doesn't converge, so we
00205 // have to say arbitrarily "there will be no more than MAX_ITER iterations."
00206 
00207                 if ((i < MAX_ITER) && 
00208                         (cpc.changed || cfc.changed || cfsc.changed)) {
00209                         p->walk (udr);
00210                         p->walk (lr);
00211                 }
00212 
00213 // why don't we care whether dead code elimination changed something?
00214 // because dead code couldn't generate any liveness (obviously) or
00215 // any reaching definitions, and we don't care about any constants
00216 // contained in dead code, so we couldn't improve anything if all we
00217 // did was eliminate dead code.
00218 
00219         } while ((i < MAX_ITER) && 
00220                 (cpc.changed || cfc.changed || cfsc.changed));
00221         fprintf (stderr, "\n");
00222         return p;
00223 }
00224 
00225 Node * Optimizer::at_unit (unitNode *u, Order) {
00226         cfg_changer::generate_cfg (u);
00227         return u;
00228 }

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