Polaris: DeadCodeElimWS.cc Source File

DeadCodeElimWS.cc

Go to the documentation of this file.
00001 ///
00002 ///
00003 /// \file DeadCodeElimWS.cc
00004 ///
00005 #include "../Collection/Iterator.h"
00006 #include "../Statement/Statement.h"
00007 #include "../Directive/Assertion.h"
00008 #include "../utilities/equivalence_util.h"
00009 
00010 #include "DeadCodeElimWS.h"
00011 
00012 
00013 /// refs_to_set
00014 ///   Convert a collection of Expression references (e.g. in_refs or out_refs)
00015 ///   into a set of symbol tags.
00016 
00017 static void
00018 _refs_to_set(IntSet &set, const RefSet<Expression> &refs,
00019          const Map<Symbol,IntElem> &candidates,
00020          Boolean only_id_exprs)
00021 {
00022     for (Iterator<Expression> iter = refs; iter.valid(); ++iter) {
00023     const Symbol *symbol = iter.current().base_variable_ref();
00024 
00025     if (symbol && (! only_id_exprs || iter.current().op() == ID_OP)) {
00026         const IntElem *elem = candidates.find_ref(*symbol);
00027 
00028         if (elem)
00029         set.ins(elem->value());
00030 
00031         if (! only_id_exprs) {
00032         /// ...  Also place any aliased variables in the set.
00033         
00034         RefSet<Symbol> *aliases = equiv_aliases(*symbol);
00035         
00036         if (aliases) {
00037             Iterator<Symbol> alias_iter = *aliases;
00038             
00039             for ( ; alias_iter.valid(); ++alias_iter) {
00040             const IntElem *alias_elem
00041                 = candidates.find_ref(alias_iter.current());
00042             
00043             if (alias_elem)
00044                 set.ins(alias_elem->value());
00045             }
00046             
00047             delete aliases;
00048         }
00049         }
00050     }
00051     }
00052 }
00053 
00054 
00055 /// assert_refs_to_set
00056 ///   Convert a collection of Expression references from private or induction
00057 ///   assertions into a set of symbol tags.
00058 
00059 static void
00060 _assert_refs_to_set(IntSet &set, Iterator<Expression> iter,
00061             const Map<Symbol,IntElem> &candidates)
00062 {
00063     for (; iter.valid(); ++iter) {
00064     Expression & expr = iter.current();
00065     switch (expr.op()) {
00066     case ID_OP: {
00067         const Symbol &symbol = expr.symbol();
00068         const IntElem *elem = candidates.find_ref(symbol);
00069         if (elem)
00070         set.ins(elem->value());
00071         break;
00072     }
00073     default:
00074         _assert_refs_to_set(set, expr.arg_list(),
00075                 candidates);
00076     }
00077     }
00078 }
00079 
00080 
00081 /// Constructors
00082 ///   Build a new DeadCodeElimWS object.
00083 
00084 DeadCodeElimWS::DeadCodeElimWS(unsigned long pass_tag, const Statement &stmt,
00085                    const Map<Symbol,IntElem> &candidates)
00086 : WorkSpace(pass_tag),
00087   use_set(candidates.entries()), kill_set(candidates.entries()),
00088   in_live_vars(candidates.entries()), out_live_vars(candidates.entries())
00089 {
00090     _refs_to_set(use_set, stmt.in_refs(), candidates, False);
00091 
00092     if (stmt.stmt_class() != READ_STMT) {
00093     _refs_to_set(kill_set, stmt.out_refs(), candidates, True);
00094     kill_set -= use_set;
00095     }
00096 
00097     _is_eliminatable = False;
00098     _lhs_tag = -1;
00099     _private_kill_set = 0;
00100 
00101     if (stmt.stmt_class() == ASSIGNMENT_STMT) {
00102     const Symbol *lhs_var = stmt.lhs().base_variable_ref();
00103     p_assert(lhs_var,
00104          "LHS of assignment statement is not an IDExpr or ArrayRefExpr");
00105 
00106     const IntElem *tag_elem = candidates.find_ref(*lhs_var);
00107     
00108     if (tag_elem) {
00109         _lhs_tag = candidates[*lhs_var].value();
00110 
00111         if (stmt.rhs().is_side_effect_free())
00112         _is_eliminatable = True;
00113     }
00114     }
00115 
00116     for (Iterator<Assertion> dirs = stmt.assertions(); dirs.valid(); ++dirs) {
00117         const Assertion & ass = dirs.current();
00118     switch (ass.type()) {
00119       // TODO: When a LOCAL assertion is added, check that instead
00120       // (and ignore PRIVATE assertions)
00121     case AS_PRIVATE:
00122       if (stmt.stmt_class()==BLOCK_ENTRY_STMT)
00123         _assert_refs_to_set(kill_set, ass.arg_list_guarded(), candidates);
00124       break;
00125     case AS_INDUCTION: {
00126       // Get an iterator for the overall induction expression
00127       Iterator<Expression> ass_iter1(ass.arg_list_guarded());
00128       // Get an iterator for each individual induction expression
00129       Iterator<Expression> ass_iter2(ass_iter1.current().arg_list());
00130       /* Skip over the first induction expression, an IDExpr for the
00131          former induction variable, when computing uses because it
00132          has been substituted out */
00133       ++ass_iter2;
00134       _assert_refs_to_set(use_set, ass_iter2, candidates);
00135       break;
00136     }
00137     default:
00138       continue;
00139     }
00140     }
00141     _num_visits = 0;
00142     _visited = False;
00143     _toporder = -1;
00144 }
00145 
00146 DeadCodeElimWS::DeadCodeElimWS(const DeadCodeElimWS &other)
00147 : WorkSpace(other), use_set(other.use_set), kill_set(other.kill_set),
00148   in_live_vars(other.in_live_vars), out_live_vars(other.out_live_vars)
00149 {
00150     _is_eliminatable = other._is_eliminatable;
00151     _lhs_tag = other._lhs_tag;
00152 
00153     if (other._private_kill_set)
00154     _private_kill_set = new IntSet(*other._private_kill_set);
00155     else
00156     _private_kill_set = 0;
00157 
00158     _num_visits = other._num_visits;
00159     _visited = other._visited;
00160     _toporder = other._toporder;
00161 }
00162 
00163 DeadCodeElimWS::~DeadCodeElimWS()
00164 {
00165     private_kill_set(0);
00166 }
00167 
00168 
00169 /// update_out_live_vars
00170 
00171 Boolean
00172 DeadCodeElimWS::update_out_live_vars()
00173 {
00174     Boolean changed = False;
00175 
00176     if (! is_dead_code()) {
00177     IntSet new_out_live_vars(in_live_vars);
00178     new_out_live_vars -= kill_set;
00179     new_out_live_vars |= use_set;
00180 
00181     if (new_out_live_vars != out_live_vars) {
00182         out_live_vars = new_out_live_vars;
00183         changed = True;
00184     }
00185     }
00186     else if (out_live_vars != in_live_vars) {
00187     out_live_vars = in_live_vars;
00188     changed = True;
00189     }
00190 
00191     return changed;
00192 }
00193 
00194 
00195 /// pretty_print_set
00196 ///   Print out a IntSet using symbol names rather than their integer tags.
00197 
00198 static void
00199 _pretty_print_set(ostream &o, const IntSet &set,
00200           const Array<Symbol *> &tag_to_candidate)
00201 {
00202     int sym_tag = set.first();
00203 
00204     if (sym_tag != -1) {
00205     o << tag_to_candidate[sym_tag]->name_ref();
00206 
00207     while ((sym_tag = set.next(sym_tag)) != -1)
00208         o << ", " << tag_to_candidate[sym_tag]->name_ref();
00209     }
00210 }
00211 
00212 
00213 /// pretty_print
00214 ///   Print out all of my fields in a nice, readable format
00215 
00216 void
00217 DeadCodeElimWS::pretty_print(ostream &o,
00218                  const Array<Symbol *> &tag_to_candidate) const
00219 {
00220     o << "  is_eliminatable = " << _is_eliminatable;
00221     o << ",  lhs_tag = " << _lhs_tag << endl;
00222     o << "  num_visits = " << _num_visits;
00223     o << ",  toporder = " << _toporder << endl;
00224 
00225     o << "  use = {";
00226     _pretty_print_set(o, use_set, tag_to_candidate);
00227     o << "}\n";
00228 
00229     o << "  kill = {";
00230     _pretty_print_set(o, kill_set, tag_to_candidate);
00231     o << "}\n";
00232 
00233     if (_private_kill_set) {
00234     o << "  priv_kill = {";
00235     _pretty_print_set(o, *_private_kill_set, tag_to_candidate);
00236     o << "}\n";
00237     }
00238 
00239     o << "  in_live_vars = {";
00240     _pretty_print_set(o, in_live_vars, tag_to_candidate);
00241     o << "}\n";
00242 
00243     o << "  out_live_vars = {";
00244     _pretty_print_set(o, out_live_vars, tag_to_candidate);
00245     o << "}\n";
00246 }
00247 
00248 
00249 /// print
00250 ///   Print out all of my fields in a rather terse and unreadable format
00251 
00252 void
00253 DeadCodeElimWS::print(ostream &o) const
00254 {
00255     o << "DeadCodeElimWS:{";
00256     o << "is_elim=" << _is_eliminatable << ", ";
00257     o << "lhs_tag=" << _lhs_tag << ", ";
00258     o << "num_visits=" << _num_visits << ", ";
00259     o << "toporder=" << _toporder << ", ";
00260     o << "use=" << use_set << ", ";
00261     o << "kill=" << kill_set << ", ";
00262     o << "priv_kill=";
00263 
00264     if (_private_kill_set)
00265     o << *_private_kill_set;
00266     else
00267     o << "NULL";
00268 
00269     o << ", ";
00270     o << "in_live_vars=" << in_live_vars << ", ";
00271     o << "out_live_vars=" << out_live_vars;
00272     o << "}";
00273 }
00274 
00275 
00276 /// listable_clone
00277 ///   Return a copy of myself.
00278 
00279 Listable *
00280 DeadCodeElimWS::listable_clone() const
00281 {
00282     return new DeadCodeElimWS(*this);
00283 }
00284 
00285 
00286 /// structures_OK
00287 ///   Return true if all of my structures are OK.
00288 
00289 int
00290 DeadCodeElimWS::structures_OK() const
00291 {
00292     return (use_set.structures_OK()
00293         && kill_set.structures_OK()
00294         && in_live_vars.structures_OK()
00295         && out_live_vars.structures_OK());
00296 }
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:44 2005