program_util.ccGo to the documentation of this file.00001
00002
00003 #include <stdio.h>
00004 #include <strstream.h>
00005
00006 #include "../CommonBlock.h"
00007 #include "../Equivalence.h"
00008 #include "../Program.h"
00009 #include "../ProgramTag.h"
00010 #include "../ProgramUnit.h"
00011 #include "../Collection/RefSet.h"
00012 #include "../Collection/RefList.h"
00013 #include "../Expression/Expression.h"
00014 #include "../Statement/EntryStmt.h"
00015 #include "../Symbol/BlockDataSymbol.h"
00016 #include "../Symbol/Symbol.h"
00017 #include "../Symbol/VariableSymbol.h"
00018 #include "symbol_util.h"
00019 #include "program_util.h"
00020
00021
00022
00023
00024 void
00025 mark_data_variables(Expression & expr,
00026 RefSet<Symbol> & var_set,
00027 RefSet<Symbol> & overflow_set,
00028 RefSet<Symbol> & match_set,
00029 Boolean & found_vars)
00030 {
00031 for (Iterator<Expression> expr_iter = expr.arg_list();
00032 expr_iter.valid(); ++expr_iter) {
00033
00034
00035
00036
00037 Expression & current_expr = expr_iter.current();
00038
00039 switch (current_expr.op()) {
00040 case ID_OP: {
00041 Symbol & current_symbol = current_expr.symbol();
00042 var_set.ins(current_symbol);
00043 if (match_set.member(current_symbol))
00044 found_vars = True;
00045 break;
00046 }
00047 case ARRAY_REF_OP: {
00048 Symbol & current_symbol = *current_expr.base_variable_ref();
00049 var_set.ins(current_symbol);
00050 if (match_set.member(current_symbol))
00051 found_vars = True;
00052 break;
00053 }
00054 case DO_OP:
00055 overflow_set.ins(current_expr.iterator().index_id().symbol());
00056 mark_data_variables(current_expr.iolist(), var_set,
00057 overflow_set, match_set, found_vars);
00058 default: break;
00059 }
00060 }
00061 }
00062
00063
00064
00065 void
00066 move_saved_vars(ProgramUnit & pgm,
00067 Program & p)
00068 {
00069
00070
00071
00072
00073 static int saved_tag = 0;
00074
00075
00076
00077 RefSet<Symbol> saved_vars;
00078 RefSet<Symbol> saved_init_vars;
00079
00080 RefList<Equivalence> equivs_encountered;
00081
00082 for (DictionaryIter<Symbol> symbol_iter = pgm.symtab().iterator();
00083 symbol_iter.valid(); ++symbol_iter) {
00084 Symbol & sym = symbol_iter.current();
00085 if ((sym.sym_class() == VARIABLE_CLASS) &&
00086 (sym.saved())) {
00087 Equivalence *equiv_class = sym.equivalence_ref();
00088 if (equiv_class) {
00089 if (!equivs_encountered.member(*equiv_class)) {
00090
00091
00092
00093 ArrayDims *dims = new ArrayDims;
00094
00095 int size = equiv_class->size();
00096
00097 ArrayBounds *bound =
00098 new ArrayBounds(constant(1),
00099 constant(size % 4 == 0 ? size/4 : (size/4)+1));
00100 dims->ins_last(bound);
00101 VariableSymbol *new_sym =
00102 new VariableSymbol("EQUIV",
00103 LOGICAL_TYPE,
00104 NOT_FORMAL,
00105 IS_SAVED,
00106 NOT_GLOBAL,
00107 dims);
00108
00109
00110 pgm.symtab().rename_and_ins(new_sym);
00111
00112
00113
00114
00115
00116
00117 equiv_class->ins(*new_sym,0);
00118
00119
00120
00121 saved_vars.ins(*new_sym);
00122 if (sym.initial_value())
00123 saved_init_vars.ins(sym);
00124
00125
00126
00127
00128 equivs_encountered.ins_last(*equiv_class);
00129 }
00130 else {
00131 if (sym.initial_value())
00132 saved_init_vars.ins(sym);
00133 }
00134 } else {
00135 saved_vars.ins(sym);
00136 if (sym.initial_value())
00137 saved_init_vars.ins(sym);
00138 }
00139 }
00140 }
00141
00142 if (saved_vars.any_valid()) {
00143
00144
00145
00146 ostrstream * str_ref = new ostrstream;
00147 (*str_ref) << ++saved_tag << '\000';
00148 char * tag_data = str_ref->str();
00149 String string_tag(tag_data);
00150 delete [] tag_data;
00151 delete str_ref;
00152 CommonBlock * saved_cb;
00153 {
00154 String common_tag = "/CB" + string_tag + "/";
00155 saved_cb = new CommonBlock(common_tag);
00156 }
00157 saved_cb->saved(1);
00158
00159
00160
00161 pgm.common_blocks().ins(saved_cb);
00162
00163
00164
00165
00166 ProgramUnit * saved_pu = 0;
00167
00168 if (saved_init_vars.any_valid()) {
00169
00170
00171
00172 ProgramTag block_tag;
00173 saved_pu = new ProgramUnit(block_tag, BLOCK_DATA_PU_TYPE);
00174 BlockDataSymbol * entry_symbol_ptr;
00175 {
00176 String entry_tag = "BD" + string_tag;
00177 entry_symbol_ptr = new BlockDataSymbol(entry_tag);
00178 }
00179 Symbol & entry_symbol =
00180 saved_pu->symtab().ins(entry_symbol_ptr);
00181 EntryStmt * entry_stmt =
00182 new EntryStmt(saved_pu->stmts().new_tag(),
00183 id(entry_symbol), comma());
00184 saved_pu->stmts().ins_after(entry_stmt,
00185 saved_pu->stmts().first_ref());
00186
00187
00188
00189 Type int_type = make_type(INTEGER_TYPE);
00190 RefSet<Symbol> match_set(saved_init_vars);
00191
00192 for (Mutator<Data> data_mutr = pgm.data();
00193 data_mutr.valid(); ++data_mutr) {
00194
00195 RefSet<Symbol> local_set;
00196 RefSet<Symbol> local_overflow_set;
00197 Boolean found_vars = False;
00198
00199 mark_data_variables(data_mutr.current().variable_list(),
00200 local_set, local_overflow_set,
00201 match_set, found_vars);
00202
00203 if (found_vars) {
00204
00205
00206
00207
00208
00209
00210 for (Mutator<Symbol> set_mutr = local_set;
00211 set_mutr.valid(); ++set_mutr) {
00212 Symbol & current_symbol = set_mutr.current();
00213 set_mutr.del();
00214
00215
00216
00217
00218 if (!current_symbol.saved()) {
00219 saved_vars.ins(current_symbol);
00220 saved_init_vars.ins(current_symbol);
00221 }
00222 match_set.del(current_symbol);
00223 }
00224
00225
00226
00227
00228
00229
00230
00231 for (Mutator<Symbol> overflow_mutr = local_overflow_set;
00232 overflow_mutr.valid(); ++overflow_mutr) {
00233 Symbol & current_symbol = overflow_mutr.current();
00234 overflow_mutr.del();
00235 const char * current_name = current_symbol.name_ref();
00236 if (!saved_pu->symtab().find_ref(current_name)) {
00237 VariableSymbol *var_sym =
00238 new VariableSymbol(current_name, int_type,
00239 NOT_FORMAL, NOT_SAVED);
00240 saved_pu->symtab().ins(var_sym);
00241 }
00242 }
00243
00244
00245
00246 saved_pu->data().ins_last(data_mutr.grab());
00247
00248
00249 if (!match_set.any_valid())
00250 break;
00251 }
00252 }
00253 }
00254
00255
00256
00257 for (Iterator<Symbol> saved_iter = saved_vars;
00258 saved_iter.valid(); ++saved_iter) {
00259
00260 VariableSymbol & current_symbol =
00261 (VariableSymbol &)saved_iter.current();
00262
00263
00264
00265 current_symbol.saved(NOT_SAVED);
00266 current_symbol.initial_value(NOT_INITIALIZED);
00267
00268
00269
00270
00271
00272
00273 int current_size = current_symbol.type().size();
00274
00275 int maxdiv;
00276
00277 if ((current_size % 8) == 0)
00278 maxdiv = 8;
00279 else if ((current_size % 4) == 0)
00280 maxdiv = 4;
00281 else if ((current_size % 2) == 0)
00282 maxdiv = 2;
00283 else
00284 maxdiv = 1;
00285
00286 int cb_index = 0;
00287
00288 if (maxdiv != 1) {
00289 for (Iterator<Symbol> pos_iter = saved_cb->iterator();
00290 pos_iter.valid(); ++pos_iter) {
00291 VariableSymbol & pos_symbol =
00292 (VariableSymbol &) pos_iter.current();
00293 int pos_size = pos_symbol.type().size();
00294
00295 if ((((maxdiv == 2) && ((pos_size % 2) == 0)) ||
00296 ((maxdiv == 4) && ((pos_size % 4) == 0)) ||
00297 ((pos_size % 8) == 0)) &&
00298 (strcmp(current_symbol.name_ref(),
00299 pos_symbol.name_ref()) > 0))
00300 ++cb_index;
00301 else
00302 break;
00303 }
00304 }
00305 else
00306 cb_index = saved_cb->entries();
00307
00308
00309
00310 current_symbol.common(*saved_cb, cb_index);
00311
00312
00313
00314
00315
00316 if (saved_pu) {
00317 saved_pu->symtab().ins(current_symbol.clone_all());
00318
00319
00320
00321
00322
00323 if (current_symbol.is_array()) {
00324
00325 RefSet<Symbol> symb_const;
00326 collect_symb_const(symb_const, current_symbol.dim());
00327 for (Iterator<Symbol> siter = symb_const;
00328 siter.valid();
00329 ++siter) {
00330 Symbol & constant = siter.current();
00331 if (!saved_pu->symtab().find_ref(constant.name_ref()))
00332 saved_pu->symtab().ins(constant.clone_all());
00333 }
00334 }
00335 }
00336
00337 }
00338 if (saved_pu) {
00339
00340 for (Iterator<Equivalence> eqiter = equivs_encountered;
00341 eqiter.valid();
00342 ++eqiter) {
00343 Equivalence & eq = eqiter.current();
00344 saved_pu->equivalences().ins((Equivalence *)(eq.definition_clone()));
00345
00346 for (Iterator<EquivalenceMember> eqmiter = eq.iterator();
00347 eqmiter.valid();
00348 ++eqmiter) {
00349 Symbol & eqsym = eqmiter.current().symbol();
00350 if (!saved_pu->symtab().find_ref(eqsym.name_ref()))
00351 saved_pu->symtab().ins(eqsym.clone_all());
00352 }
00353 }
00354
00355
00356
00357
00358 CommonBlock * saved_cb_clone =
00359 new CommonBlock(*saved_cb);
00360
00361 saved_pu->common_blocks().ins(saved_cb_clone);
00362
00363
00364
00365 saved_cb_clone->relink_dptrs(*saved_pu);
00366
00367
00368
00369 saved_pu->symtab().relink_ptrs(*saved_pu);
00370
00371
00372
00373 saved_pu->data().relink_ptrs(*saved_pu);
00374
00375
00376
00377 saved_pu->equivalences().relink_ptrs(*saved_pu);
00378
00379
00380
00381 p.absorb(saved_pu);
00382 }
00383 }
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393 Symbol &
00394 rename_variable_to_match(ProgramUnit & current_pgm,
00395 Symbol & current_symbol,
00396 ProgramUnit & new_pgm,
00397 Symbol * new_symbol_ptr)
00398 {
00399
00400 new_pgm.symtab().rename_and_ins(new_symbol_ptr);
00401
00402 Symbol *check_ptr =
00403 current_pgm.symtab().find_ref(new_symbol_ptr->name_ref());
00404
00405 if (check_ptr != ¤t_symbol) {
00406
00407 current_pgm.symtab().grab(current_symbol.name_ref());
00408
00409 if (check_ptr)
00410 check_ptr = current_pgm.symtab().grab(check_ptr->name_ref());
00411
00412 current_symbol.name(new_symbol_ptr->name_ref());
00413 current_pgm.symtab().ins(¤t_symbol);
00414
00415 if (check_ptr) {
00416
00417
00418
00419
00420
00421
00422
00423
00424 current_pgm.symtab().rename_and_ins(check_ptr);
00425 }
00426 }
00427
00428 return *new_symbol_ptr;
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438 Equivalence &
00439 rename_equivalence_to_match(ProgramUnit & current_pgm,
00440 Equivalence & current_equiv,
00441 ProgramUnit & new_pgm,
00442 Equivalence * new_equiv_ptr)
00443 {
00444
00445 new_pgm.equivalences().rename_and_ins(new_equiv_ptr);
00446
00447 Equivalence *check_ptr =
00448 current_pgm.equivalences().find_ref(new_equiv_ptr->name_ref());
00449
00450 if (check_ptr != ¤t_equiv) {
00451
00452 current_pgm.equivalences().grab(current_equiv.name_ref());
00453
00454 if (check_ptr)
00455 check_ptr = current_pgm.equivalences().grab(check_ptr->name_ref());
00456
00457 current_equiv.rename(new_equiv_ptr->name_ref());
00458 current_pgm.equivalences().ins(¤t_equiv);
00459
00460 if (check_ptr) {
00461
00462
00463
00464
00465
00466
00467
00468
00469 current_pgm.equivalences().rename_and_ins(check_ptr);
00470 }
00471 }
00472
00473 return *new_equiv_ptr;
00474 }
00475
00476
00477 RefSet<Symbol> *
00478 interface_vars( ProgramUnit & pgm )
00479 {
00480
00481
00482 RefSet<Symbol> * iface_vars = new RefSet<Symbol>;
00483
00484 for (Iterator<Statement> entry_iter = pgm.stmts().iterate_entry_points();
00485 entry_iter.valid();
00486 ++entry_iter) {
00487
00488 EntryStmt & entry_stmt = (EntryStmt &) entry_iter.current();
00489
00490 if (entry_stmt.parameters_valid()) {
00491 for (Iterator<Expression> param_iter = entry_stmt.parameters_guarded().arg_list();
00492 param_iter.valid();
00493 ++param_iter) {
00494
00495 Symbol * formal = param_iter.current().base_variable_ref();
00496
00497 iface_vars->ins( *formal );
00498 }
00499 }
00500 }
00501
00502 for (DictionaryIter<Symbol> sym_iter = pgm.symtab().iterator();
00503 sym_iter.valid();
00504 ++sym_iter) {
00505
00506 Symbol & sym = sym_iter.current();
00507
00508 if (sym.common_ref()) {
00509 iface_vars->ins( sym );
00510 }
00511 }
00512
00513 return iface_vars;
00514 }
00515
00516
00517
00518
00519
00520 void
00521 rename_all_occurences(ProgramUnit &pgm, Symbol &var)
00522 {
00523 Symbol *new_var = var.clone();
00524 new_var = & pgm.symtab().rename_and_ins(new_var);
00525
00526 for(Iterator<Statement> siter = pgm.stmts(); siter.valid(); ++siter)
00527 for(Mutator<Expression> eiter = siter.current().iterate_expressions();
00528 eiter.valid(); ++eiter)
00529 substitute_var(eiter.current(), var, *new_var);
00530
00531 pgm.symtab().del(var.name_ref());
00532 }
|