Polaris: stmt_util.cc Source File

stmt_util.cc

Go to the documentation of this file.
00001 ///
00002 #include "expression_util.h"
00003 #include "stmt_util.h"
00004 
00005 #include "../Expression/CommaExpr.h"
00006 #include "../Expression/DoExpr.h"
00007 #include "../Expression/EqualExpr.h"
00008 #include "../InlineObject.h"
00009 #include "../Program.h"
00010 #include "../ProgramUnit.h"
00011 #include "../Statement/Statement.h"
00012 #include "../Symbol/Symbol.h"
00013 #include "../SymbolAccess.h"
00014 #include "../Range/AIRangeDict.h"
00015 #include "../Range/RangeAccessor.h"
00016 #include "../Range/Relation.h"
00017 #include "../Statement/AssignmentStmt.h"
00018 #include "../Statement/ComputedGotoStmt.h"
00019 #include "../Statement/EntryStmt.h"
00020 #include "../Symbol/VariableSymbol.h"
00021 #include "../Symbol/FunctionSymbol.h"
00022 #include "../Traverser.h"
00023 #include "../Collection/Iterator.h"
00024 #include "../Collection/Mutator.h"
00025 #include "../Collection/RefMap.h"
00026 #include "../Collection/RefDatabase.h"
00027 #include "../Collection/RefSet.h"
00028 #include "../Collection/Map.h"
00029 #include "../utilities/switches_util.h"
00030 #include "../utilities/invariant_util.h"
00031 
00032 static Boolean
00033 is_array_ref (const Expression & expr)
00034 {
00035     switch (expr.op()) 
00036     {
00037     case ARRAY_REF_OP:
00038         return True;
00039     default:
00040         return False;
00041     }
00042 }
00043 
00044 void 
00045 remove_elseif_stmts( ProgramUnit &pgm )
00046 {
00047     for (Iterator<Statement> iter = pgm.stmts().stmts_of_type( ELSEIF_STMT ); 
00048                              iter.valid(); ++iter) {
00049         pgm.stmts().split_elseif( iter.current() );
00050     }
00051 }
00052 
00053 ///
00054 /// Change the following code:
00055 ///  ASSIGN 100 TO X
00056 ///  ASSIGN 200 TO X
00057 ///  GOTO X   
00058 ///
00059 /// Into the following code:
00060 ///  ASSIGN 100 TO X
00061 ///  XAGT = 1
00062 ///  ASSIGN 200 TO X
00063 ///  XAGT = 2
00064 ///  GOTO (100,200) XAGT
00065 ///
00066 ///
00067 
00068 typedef RefList<Statement>  Targets;
00069 
00070 template class TypedBaseMap<Symbol,Targets>;
00071 template class ProtoMap<Symbol,Targets>;
00072 template class Map<Symbol,Targets>;
00073 template class KeyIterator<Symbol,Targets>;
00074 
00075 void 
00076 remove_assigned_goto_stmts( ProgramUnit &pgm )
00077 {
00078     RefMap<Symbol,Symbol> assign_map;
00079     Map<Symbol,Targets>   target_map;
00080 
00081     Iterator<Statement> iter = pgm.stmts().stmts_of_type( ASSIGN_STMT ); 
00082 
00083     for ( ; iter.valid(); ++iter) {
00084         Statement & s = iter.current();
00085         Symbol  & sym = s.lhs().symbol();
00086 
00087         if (s.atype() == EXECUTABLE_ASSIGN) {
00088             if (assign_map.find_ref( sym ) == 0) {
00089                 String new_name = sym.name_ref();
00090 
00091                 new_name += "AGOTO";
00092 
00093                 Symbol *new_sym = new VariableSymbol(new_name, 
00094                                      make_type(INTEGER_TYPE),
00095                                                       NOT_FORMAL, NOT_SAVED );
00096                 pgm.symtab().rename_and_ins( new_sym );
00097 
00098                 assign_map.ins( sym, *new_sym );
00099                 target_map.ins( sym, new Targets );
00100             }
00101 
00102             Targets & T = target_map[sym];
00103 
00104             T.ins_last( *s.target_ref() );
00105 
00106             Expression *lhs = id( assign_map[sym] );
00107             Expression *rhs = constant( T.entries() );
00108 
00109             Statement *st = new AssignmentStmt(pgm.stmts().new_tag(),
00110                                lhs, rhs );
00111             pgm.stmts().ins_after( st, &s );
00112         }
00113     }
00114 
00115     iter = pgm.stmts().stmts_of_type( ASSIGNED_GOTO_STMT ); 
00116 
00117     for ( ; iter.valid(); ++iter) {
00118         Statement & s = iter.current();
00119         Symbol  & sym = s.expr().symbol();
00120 
00121         Expression *rhs = id( assign_map[sym] );
00122 
00123         Statement *st = new ComputedGotoStmt(pgm.stmts().new_tag(),
00124                              rhs, target_map[sym] );
00125         pgm.stmts().ins_after( st, &s );
00126         pgm.stmts().del( s );
00127     }
00128 }
00129 
00130 void
00131 precalc_stmt( ProgramUnit &pgm, Statement &s,  
00132               enum PRECALC_COND cond )
00133 {
00134     for (Mutator<Expression> muter = s.iterate_expressions();
00135      muter.valid(); ++muter) {
00136     Assign<Expression> muter_as(muter.assign());
00137     muter_as = get_precalc( muter.pull(), pgm, s, cond );
00138     }
00139 }
00140 
00141 /// Procedure passed to sub-list iterator to check Assertion
00142 /// against a single Assertion type.
00143 
00144 int
00145 check_assertion_type(void *as, void *assert_type)
00146 {
00147     return (((Assertion *) as)->type() == *((AssertionType *) assert_type));
00148 }
00149 
00150 Iterator<Assertion>
00151 assertions_of_type(Statement &s, AssertionType type)
00152 {
00153     AssertionType      *holdtype = new AssertionType;
00154 
00155     *holdtype = type;
00156 
00157     Iterator<Assertion> iter(s.assertions(),
00158                  (cond_proc) check_assertion_type, holdtype);
00159     
00160     return iter;
00161 }
00162 
00163 Boolean
00164 is_func (const Expression &expr)
00165 {
00166     if (expr.op() == FUNCTION_CALL_OP) {
00167     return True;
00168     } else {
00169     return False;
00170     }
00171 }
00172 
00173 Boolean
00174 contains_side_effect_call (Statement &s)
00175 {
00176     List<Symbol> *funcs = new List<Symbol>;
00177 
00178     /// ...  Look through all the expressions in the statement and 
00179     /// ...  make a list of all the FunctionSymbols representing 
00180     /// ...  routines being called.
00181 
00182     for (Mutator<Expression> mu_expr = s.iterate_expressions();
00183      mu_expr.valid();
00184      ++mu_expr) {
00185 
00186     Traverser tr (mu_expr.current(), is_func);
00187     for ( ; tr.valid(); ++tr) {
00188         funcs->ins_last(tr.current().function().symbol().clone());
00189     }
00190     }
00191 
00192     if (funcs->entries() == 0) return False;  /// ...  There are no func calls at all
00193 
00194     /// ...  For each function called, check it against the list of 
00195     /// ...  side-effect-free symbols from the assertions
00196 
00197     List<Symbol> *clean_funcs = new List<Symbol>;
00198 
00199     Iterator<Assertion> as_iter 
00200     = assertions_of_type(s, AS_SIDE_EFFECT_FREE);
00201 
00202     for ( ; as_iter.valid(); ++as_iter) {
00203     for (Iterator<Expression> expr_iter = 
00204          as_iter.current().arg_list_guarded();
00205          expr_iter.valid();
00206          ++expr_iter) {
00207         clean_funcs->ins_last(expr_iter.current().symbol().clone());
00208     }
00209     }
00210 
00211     for (Iterator<Symbol> symiter = funcs;
00212      symiter.valid();
00213      ++symiter) {
00214 
00215     Boolean found = False;
00216     for (Iterator<Symbol> clean_iter = clean_funcs; 
00217          clean_iter.valid(); 
00218          ++clean_iter) {
00219         if (strcmp(clean_iter.current().name_ref(), symiter.current().name_ref()) == 0)
00220         found = True;  /// ...  Found - this function won't cause a side-effect
00221     }
00222 
00223     if (!found) return True;
00224     }
00225 
00226     return False;
00227 }
00228 
00229 
00230     
00231 
00232 ///  range_stmt
00233 /// 
00234 /// The statement which should be used to best reflect the
00235 /// range environment of this statement,
00236 /// which is the ENDDO statement of the current loop, 
00237 /// or the statement itself.
00238 
00239 Statement *
00240 range_stmt (Statement & stmt) 
00241 {
00242     if (stmt.stmt_class() == DO_STMT) {
00243     return stmt.follow_ref();
00244     } else {
00245     Statement * outer_loop = stmt.outer_ref();
00246     if (outer_loop) {
00247         return outer_loop->follow_ref();
00248     } else {
00249         return &stmt;
00250     }
00251     }
00252 }    
00253 
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:06:12 2005