stmt_util.ccGo 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
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
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
00142
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
00179
00180
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;
00193
00194
00195
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;
00221 }
00222
00223 if (!found) return True;
00224 }
00225
00226 return False;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
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
|