Polaris: IPCPProcData.cc Source File

IPCPProcData.cc

Go to the documentation of this file.
00001 ///
00002 ///
00003 ///
00004 /// \file IPCPProcData.cc
00005 ///
00006 #include "../Collection/Iterator.h"
00007 #include "../Collection/KeyIterator.h"
00008 #include "../Collection/RefSet.h"
00009 #include "../Statement/Statement.h"
00010 #include "../Symbol/Symbol.h"
00011 #include "../Symbol/VariableSymbol.h"
00012 #include "../Directive/AssertMayMod.h"
00013 #include "../utilities/expression_util.h"
00014 #include "../CommonBlock.h"
00015 #include "../ProgramUnit.h"
00016 #include "../Range/range_dict_util.h"
00017 
00018 #include "InterProcConstProp.h"
00019 #include "IPCPProcData.h"
00020 #include "JumpFunction.h"
00021 #include "constant.h"
00022 
00023 /// Template instantiations:
00024 
00025 template class TypedBaseMap<String, IPCPCallData>;
00026 template class ProtoDatabase<String, IPCPCallData>;
00027 template class Database<String, IPCPCallData>;
00028 template ostream & operator << (ostream &,
00029                 const Database<String, IPCPCallData> &);
00030 template class KeyIterator<String, IPCPCallData>;
00031 
00032 template class TypedCollection<IPCPConstants>;
00033 template class List<IPCPConstants>;
00034 template ostream & operator << (ostream &, const List<IPCPConstants> &);
00035 template class Assign<IPCPConstants>;
00036 template class Iterator<IPCPConstants>;
00037 template class Mutator<IPCPConstants>;
00038 
00039 
00040 ///  Constructors
00041 
00042 IPCPCallData::IPCPCallData(IPCPProcData *called_pgm_data)
00043 {
00044   _called_pgm_data = called_pgm_data;
00045   _jump_function = 0;
00046 }
00047 
00048 IPCPCallData::IPCPCallData(const IPCPCallData &other)
00049 {
00050   _called_pgm_data = other._called_pgm_data;
00051 
00052   if (other._jump_function)
00053     _jump_function = new JumpFunction(*other._jump_function);
00054   else
00055     _jump_function = 0;
00056 }
00057 
00058 
00059 ///  Destructor
00060 
00061 IPCPCallData::~IPCPCallData()
00062 {
00063   jump_function(0);
00064 }
00065 
00066 
00067 ///  jump_function
00068 
00069 void
00070 IPCPCallData::jump_function(JumpFunction *jump_func)
00071 {
00072   if (_jump_function)
00073     delete _jump_function;
00074 
00075   _jump_function = jump_func;
00076 }
00077 
00078 
00079 ///  add_constant_set
00080 
00081 void
00082 IPCPCallData::add_constant_set(IPCPConstants *constants,
00083                    const List<Expression> &param_values)
00084 {
00085   if (_called_pgm_data)
00086     _called_pgm_data->add_constant_set(constants, param_values);
00087   else
00088     delete constants;
00089 }
00090 
00091 
00092 /// compute_rtoporder
00093 
00094 void
00095 IPCPCallData::compute_rtoporder(int &max_visited_elems)
00096 {
00097   if (_called_pgm_data)
00098     _called_pgm_data->compute_rtoporder(max_visited_elems);
00099 }
00100     
00101 
00102 ///  listable_clone
00103 
00104 Listable *
00105 IPCPCallData::listable_clone() const
00106 {
00107   return new IPCPCallData(*this);
00108 }
00109 
00110 
00111 ///  print
00112 
00113 void
00114 IPCPCallData::print(ostream &o) const
00115 {
00116   o << "[";
00117   o << "_called_pgm_data=";
00118 
00119   if (_called_pgm_data)
00120     _called_pgm_data->entry().print_debug(o, 0);
00121   else
00122     o << "NULL";
00123 
00124   o << ", _jump_function=";
00125 
00126   if (_jump_function)
00127     o << *_jump_function;
00128   else
00129     o << "NULL";
00130 
00131   o << "]";
00132 }
00133 
00134 
00135 ///  structures_OK
00136 
00137 int
00138 IPCPCallData::structures_OK() const
00139 {
00140   return _called_pgm_data->structures_OK();
00141 }
00142 
00143 
00144 ///  proc_name
00145 ///    Return the name of the subroutine or function called by the given
00146 ///    statement.
00147 
00148 static const char *
00149 _proc_name(const Statement &call_stmt)
00150 {
00151   if (call_stmt.stmt_class() == CALL_STMT)
00152     return call_stmt.routine_guarded().symbol().name_ref();
00153   else if (call_stmt.stmt_class() == ASSIGNMENT_STMT
00154        && call_stmt.rhs().op() == FUNCTION_CALL_OP) 
00155     return call_stmt.rhs().function().symbol().name_ref();
00156   else
00157     return 0;
00158 }
00159 
00160 
00161 ///  call_arg_list
00162 ///    Return a reference to the argument list of the given call site.
00163 
00164 static const List<Expression> &
00165 _call_arg_list(const Statement &call_site)
00166 {
00167   const List<Expression> *args = NULL;
00168 
00169   if (call_site.stmt_class() == CALL_STMT)
00170     args = &call_site.parameters_guarded().arg_list();
00171   else if (call_site.stmt_class() == ASSIGNMENT_STMT
00172        && call_site.rhs().op() == FUNCTION_CALL_OP)
00173     args = &call_site.rhs().parameters_guarded().arg_list();
00174   else
00175     p_abort("_call_arg_list(): Given statement is not a call statement or function call.");
00176 
00177   return *args;
00178 }
00179 
00180 
00181 ///  mark_external_func_calls
00182 ///    Mark all function calls in the given expression as executed 
00183 ///    externally.
00184 
00185 void
00186 IPCPProcData::_mark_external_func_calls(const Expression &expr)
00187 {
00188   if (expr.op() == ID_OP && expr.symbol().sym_class() == FUNCTION_CLASS) {
00189     IPCPProcData *called_proc_data
00190       = _ipcp_ref->_get_proc_data_ref(expr.symbol().name_ref());
00191 
00192     if (called_proc_data)
00193       called_proc_data->called_externally();
00194   }
00195   else {
00196     Iterator<Expression> arg_iter = expr.arg_list();
00197 
00198     for ( ; arg_iter.valid(); ++arg_iter)
00199       _mark_external_func_calls(arg_iter.current());
00200   }
00201 }
00202 
00203 
00204 ///  init_call_sites
00205 ///    Create a IPCPCallData object for each call site.
00206 
00207 void
00208 IPCPProcData::_init_call_sites()
00209 {
00210   Iterator<Statement> stmt_iter = _pgm_ref->stmts().iterator();
00211 
00212   for ( ; stmt_iter.valid(); ++stmt_iter) {
00213     Statement &stmt = stmt_iter.current();
00214     const char *proc_name = _proc_name(stmt);
00215 
00216     if (proc_name) {
00217       IPCPProcData *called_proc_data = _ipcp_ref->_get_proc_data_ref(proc_name);
00218       _call_data.ins(stmt.tag(), new IPCPCallData(called_proc_data));
00219 
00220       if (called_proc_data
00221       && _call_arg_list(stmt).entries() != called_proc_data->param_list().entries()) {
00222 
00223     cout << "Error: The number of actual parameters of call to "
00224          << proc_name << " on line " << stmt.line() << endl;
00225     cout << "       does not agree with the number of formal parameters for that routine.\n";
00226     p_abort("Aborting.");
00227       }
00228     }
00229     else if (contains_func_call(stmt)) {
00230       Iterator<Expression> expr_iter = stmt.iterate_expressions();
00231 
00232       for ( ; expr_iter.valid(); ++expr_iter)
00233     _mark_external_func_calls(expr_iter.current());
00234     }
00235   }
00236 }
00237 
00238 
00239 /// convert_local_to_global
00240 ///   Convert the given local variable into a global variable.
00241 
00242 const Symbol &
00243 IPCPProcData::_convert_local_to_global(const Symbol &local_var,
00244                        const char *global_namespace)
00245 {
00246   Symbol *global_var = _local_to_global_vars.find_ref(local_var);
00247 
00248   if (! global_var) {
00249     String global_name = global_namespace;
00250     global_name += ":";
00251     global_name += local_var.name_ref();
00252 
00253     global_var = _ipcp_ref->_global_vars.find_ref(global_name);
00254 
00255     if (! global_var) {
00256       global_var = new VariableSymbol(global_name, local_var.type(),
00257                       NOT_FORMAL, NOT_SAVED);
00258 
00259       /// ...  VariableSymbol constructor erases dimensioning info in type,
00260       /// ...  so set its type again to put the dimensioning info back in.
00261       global_var->type(local_var.type());
00262 
00263       global_var = &_ipcp_ref->_global_vars.ins(global_var);
00264     }
00265 
00266     _local_to_global_vars.ins(local_var, *global_var);
00267     _global_to_local_vars.ins(*global_var, local_var);
00268   }
00269 
00270   return *global_var;
00271 }
00272 
00273 
00274 /// init_params
00275 ///   Initialize the param_list and return_var fields.
00276 
00277 void
00278 IPCPProcData::_init_params()
00279 {
00280   p_assert(_entry->routine_guarded().op() == ID_OP,
00281        "Routine name for an entry statement is not a variable.");
00282   const char *entry_name = _entry->routine_guarded().symbol().name_ref();
00283   Iterator<Expression> param_iter = _entry->parameters_guarded().arg_list();
00284 
00285   for ( ; param_iter.valid(); ++param_iter) {
00286     p_assert(param_iter.current().op() == ID_OP,
00287          "An entry statement has a parameter that is not a variable.");
00288     const Symbol &global_var
00289       = _convert_local_to_global(param_iter.current().symbol(),
00290                  entry_name);
00291     _param_list.ins_last(CASTAWAY(Symbol &) global_var);
00292   }
00293 
00294   if (_entry->routine_guarded().symbol().sym_class() == FUNCTION_CLASS) {
00295     const Symbol &global_var
00296       = _convert_local_to_global(_entry->routine_guarded().symbol(),
00297                  entry_name);
00298     _return_var = &global_var;
00299   } 
00300   else
00301     _return_var = 0;
00302 }
00303 
00304 
00305 /// add_params_to_set
00306 ///   Add my entry's parameters to the given set of variables.
00307 
00308 void
00309 IPCPProcData::_add_params_to_set(RefSet<Symbol> &vars) const
00310 {
00311   Iterator<Symbol> param_iter = _param_list;
00312     
00313   for ( ; param_iter.valid(); ++param_iter)
00314     vars.ins(param_iter.current());
00315 
00316   if (_return_var)
00317     vars.ins(* CASTAWAY(Symbol *) _return_var);
00318 }
00319 
00320 
00321 ///  init_usable_global_vars
00322 ///    Initialize the set of global variables used by this routine and
00323 ///    all called subsroutines.
00324 
00325 void
00326 IPCPProcData::_init_usable_global_vars()
00327 {
00328 /// Collect the useable global variables for called subroutines.
00329 
00330   KeyIterator<String, IPCPCallData> call_iter = _call_data;
00331 
00332   for ( ; call_iter.valid(); ++call_iter) {
00333     const IPCPProcData *call_data = call_iter.current_data().data_ref();
00334 
00335     if (call_data) {
00336       Iterator<Symbol> var_iter = call_data->usable_global_vars();
00337 
00338       for ( ; var_iter.valid(); ++var_iter)
00339     if (! call_data->param_list().member(var_iter.current())
00340         && &var_iter.current() != call_data->return_var())
00341 
00342       _usable_global_vars.ins(var_iter.current());
00343     }
00344   }
00345 
00346 /// Add my common variables to the set.
00347 
00348   DictionaryIter<Symbol> common_iter = _pgm_ref->symtab().iterator();
00349 
00350   for ( ; common_iter.valid(); ++common_iter) {
00351     const Symbol &var = common_iter.current();
00352 
00353     if (var.sym_class() == VARIABLE_CLASS && var.common_ref()) {
00354       const Symbol &global_var = _convert_local_to_global(var, var.common_ref()->name_ref());
00355       _usable_global_vars.ins(CASTAWAY(Symbol &) global_var);
00356     }
00357   }
00358 
00359 /// Add my parameters to the set.
00360 
00361   _add_params_to_set(_usable_global_vars);
00362 }
00363 
00364 
00365 /// add_refs_to_globals -
00366 ///   Add the given set of references to the given variable set.
00367 
00368 void
00369 IPCPProcData::_add_refs_to_globals(const RefSet<Expression> &refs)
00370 {
00371   Iterator<Expression> iter = refs;
00372     
00373   for ( ; iter.valid(); ++iter) {
00374     const Symbol *var = iter.current().base_variable_ref();
00375 
00376     if (var
00377     && var->sym_class() == VARIABLE_CLASS 
00378     && var->common_ref()) {
00379 
00380       const Symbol &global_var = _convert_local_to_global(*var, var->common_ref()->name_ref());
00381       _used_global_vars.ins(CASTAWAY(Symbol &) global_var);
00382     }
00383   }
00384 }
00385 
00386 
00387 ///  init_used_global_vars
00388 ///    Initialize the set of global variables used by this routine and
00389 ///    all called subsroutines.
00390 
00391 void
00392 IPCPProcData::_init_used_global_vars()
00393 {
00394 /// Collect the used global variables for called subroutines.
00395 
00396   KeyIterator<String, IPCPCallData> call_iter = _call_data;
00397 
00398   for ( ; call_iter.valid(); ++call_iter) {
00399     const IPCPProcData *call_data = call_iter.current_data().data_ref();
00400 
00401     if (call_data) {
00402       Iterator<Symbol> var_iter = call_data->used_global_vars();
00403 
00404       for ( ; var_iter.valid(); ++var_iter)
00405     if (! call_data->param_list().member(var_iter.current())
00406         && &var_iter.current() != call_data->return_var())
00407 
00408       _used_global_vars.ins(var_iter.current());
00409     }
00410   }
00411 
00412 /// Add my common variables to the set.
00413 
00414   Iterator<Statement> stmt_iter = _pgm_ref->stmts().iterator();
00415 
00416   for ( ; stmt_iter.valid(); ++stmt_iter) {
00417     const Statement &stmt = stmt_iter.current();
00418 
00419     _add_refs_to_globals(stmt.in_refs());
00420     _add_refs_to_globals(stmt.out_refs());
00421   }
00422 
00423 /// Add my parameters to the set.
00424 
00425   _add_params_to_set(_used_global_vars);
00426 }
00427 
00428 
00429 /// add_refs -
00430 ///   Add the given set of references to the given variable set.
00431 
00432 static void
00433 _add_refs(RefSet<Symbol> &vars, const RefSet<Expression> &refs)
00434 {
00435   Iterator<Expression> iter = refs;
00436     
00437   for ( ; iter.valid(); ++iter)
00438     if (iter.current().base_variable_ref())
00439       vars.ins(*iter.current().base_variable_ref());
00440 }
00441 
00442 
00443 ///  local_vars
00444 
00445 RefSet<Symbol> *
00446 IPCPProcData::local_vars(const RefSet<Symbol> &vars) const
00447 {
00448   RefSet<Symbol> *local_ugvs = new RefSet<Symbol>;
00449   Iterator<Symbol> global_iter = vars;
00450 
00451   for ( ; global_iter.valid(); ++global_iter) {
00452     const Symbol *local_var = _global_to_local_vars.find_ref(global_iter.current());
00453 
00454     if (local_var)
00455       local_ugvs->ins(*local_var);
00456     else
00457       local_ugvs->ins(global_iter.current());
00458   }
00459 
00460   return local_ugvs;
00461 }
00462 
00463 
00464 ///  add_vars_to_set
00465 ///    Add the variables in the given expression to the given set.
00466 
00467 static void
00468 _add_vars_to_set(RefSet<Symbol> &var_set, const Expression &expr)
00469 {
00470   if (expr.op() == ID_OP && expr.symbol().sym_class() == VARIABLE_CLASS)
00471     var_set.ins(expr.symbol());
00472   else {
00473     Iterator<Expression> iter = expr.arg_list();
00474 
00475     for ( ; iter.valid(); ++iter)
00476       _add_vars_to_set(var_set, iter.current());
00477   }
00478 }
00479 
00480 
00481 ///  candidates
00482 ///    Return the set of variables that are candidates for constant propagation.
00483 
00484 RefSet<Symbol> *
00485 IPCPProcData::_candidates() const
00486 {
00487 /// Copy usable_global_vars into candidates, converting global names to
00488 /// local names.
00489 
00490   RefSet<Symbol> *candidates = local_vars(usable_global_vars());
00491 
00492 /// Add used local variables to candidates.
00493 
00494   Iterator<Statement> stmt_iter = _pgm_ref->stmts().iterator();
00495 
00496   for ( ; stmt_iter.valid(); ++stmt_iter) {
00497     const Statement &stmt = stmt_iter.current();
00498 
00499     if (stmt.stmt_class() == CALL_STMT
00500     || contains_func_call(stmt)
00501     || (stmt.stmt_class() == ASSIGNMENT_STMT
00502         && stmt.lhs().op() == ID_OP
00503         && _ipcp_ref->_is_substitutable(stmt.lhs().symbol()))) {
00504 
00505       if (stmt.stmt_class() == ASSIGNMENT_STMT)
00506     candidates->ins(stmt.lhs().symbol());
00507 
00508       Iterator<Expression> ref_iter = stmt.in_refs();
00509         
00510       for ( ; ref_iter.valid(); ++ref_iter) {
00511     Symbol *var = ref_iter.current().base_variable_ref();
00512 
00513     if (var && _ipcp_ref->_is_substitutable(*var))
00514       candidates->ins(*var);
00515       }
00516     }
00517   }
00518 
00519 /// Add all variables used in my sets of constants in my candidates.
00520 
00521   Iterator<IPCPConstants> const_set_iter = _consts_sets;
00522 
00523   for ( ; const_set_iter.valid(); ++const_set_iter) {
00524     KeyIterator<Symbol, Expression> const_iter
00525       = const_set_iter.current().constants();
00526     
00527     for ( ; const_iter.valid(); ++const_iter)
00528       _add_vars_to_set(*candidates, const_iter.current_data());
00529   }
00530     
00531   return candidates;
00532 }
00533     
00534 
00535 
00536 ///  Constructors
00537 
00538 IPCPProcData::IPCPProcData(ProgramUnit &pgm, InterProcConstProp &ipcp,
00539                            const Statement &entry, int debug GIV(0))
00540 {
00541   if (debug > 0) {
00542     cout << "!  Computing side effects for ";
00543     entry.print_debug(cout, 0);
00544     cout << endl;
00545   }
00546     
00547   _pgm_ref = &pgm;
00548   _ipcp_ref = &ipcp;
00549   _entry = &entry;
00550   _return_jump_function = 0;
00551   _rtoporder = -1;
00552   _called_externally = False;
00553   _init_call_sites();
00554   _init_params();
00555   _init_used_global_vars();
00556   _init_usable_global_vars();
00557 }
00558 
00559 IPCPProcData::IPCPProcData(ProgramUnit &cloned_proc,
00560                            const Statement &clone_entry,
00561                IPCPProcData &orig_proc_data)
00562 {
00563   _pgm_ref = &cloned_proc;
00564   _ipcp_ref = orig_proc_data._ipcp_ref;
00565   _entry = &clone_entry;
00566   _rtoporder = -1;
00567   _called_externally = False;
00568   _call_data = orig_proc_data._call_data;
00569   _used_global_vars = orig_proc_data._used_global_vars;
00570   _usable_global_vars = orig_proc_data._usable_global_vars;
00571   _param_list = orig_proc_data._param_list;
00572   _return_var = orig_proc_data._return_var;
00573 
00574   if (orig_proc_data._return_jump_function)
00575     _return_jump_function = new ReturnJumpFunction(*orig_proc_data._return_jump_function);
00576   else
00577     _return_jump_function = 0;
00578 
00579 /// Initialize local_to_global_vars and global_to_local_vars.
00580 
00581   KeyIterator<Symbol,Symbol> ltog_iter = orig_proc_data._local_to_global_vars;
00582 
00583   for ( ; ltog_iter.valid(); ++ltog_iter) {
00584     const Symbol &global_var = ltog_iter.current_data();
00585     const Symbol *local_var;
00586 
00587     if (&global_var == _return_var)
00588       local_var = &_entry->routine_guarded().symbol();
00589     else
00590       local_var = &_pgm_ref->symtab()[ltog_iter.current_key().name_ref()];
00591 
00592     _local_to_global_vars.ins(*local_var, global_var);
00593     _global_to_local_vars.ins(global_var, *local_var);
00594   }
00595 }
00596 
00597 
00598 ///  Destructor
00599 
00600 IPCPProcData::~IPCPProcData()
00601 {
00602   if (_return_jump_function)
00603     delete _return_jump_function;
00604 }
00605 
00606 
00607 ///  contains_local_vars
00608 ///    Return true if the expression contains a variable not in
00609 ///    used_global_vars.
00610 
00611 Boolean
00612 IPCPProcData::_contains_local_vars(const Expression &expr) const
00613 {
00614   if (expr.op() == ID_OP) {
00615     return (expr.symbol().sym_class() == VARIABLE_CLASS
00616         && ! _usable_global_vars.member(expr.symbol()));
00617   }
00618   else {
00619     Iterator<Expression> arg_iter = expr.arg_list();
00620 
00621     for ( ; arg_iter.valid(); ++arg_iter)
00622       if (_contains_local_vars(arg_iter.current()))
00623     return True;
00624   }
00625 
00626   return False;
00627 }
00628 
00629 Boolean
00630 IPCPProcData::_contains_local_vars(const Expression &expr,
00631                    const RefList<Symbol> &caller_formals) const
00632 {
00633   if (expr.op() == ID_OP) {
00634     return (expr.symbol().sym_class() == VARIABLE_CLASS
00635         && ! _usable_global_vars.member(expr.symbol())
00636         && ! caller_formals.member(expr.symbol()));
00637   }
00638   else {
00639     Iterator<Expression> arg_iter = expr.arg_list();
00640 
00641     for ( ; arg_iter.valid(); ++arg_iter)
00642       if (_contains_local_vars(arg_iter.current(), caller_formals))
00643     return True;
00644   }
00645 
00646   return False;
00647 }
00648 
00649 
00650 ///  filter_out_local_vars
00651 ///    Filter out all local symbols from the given map.
00652 
00653 void
00654 IPCPProcData::_filter_out_local_vars(Map<Symbol, Expression> &var_mods) const
00655 {
00656   RefSet<Symbol> *mod_vars = modified_vars(var_mods);
00657   Iterator<Symbol> mod_var_iter = *mod_vars;
00658     
00659   for ( ; mod_var_iter.valid(); ++mod_var_iter) {
00660     Symbol &var = mod_var_iter.current();
00661 
00662     if (! _usable_global_vars.member(var))
00663       var_mods.del(var);
00664     else if (_contains_local_vars(var_mods[var]))
00665       var_mods.ins(var, omega());
00666   }
00667 
00668   delete mod_vars;
00669 }
00670 
00671 void
00672 IPCPProcData::_filter_out_local_vars(Map<Symbol, Expression> &var_mods,
00673                      const RefList<Symbol> &caller_formals) const
00674 {
00675   RefSet<Symbol> *mod_vars = modified_vars(var_mods);
00676   Iterator<Symbol> mod_var_iter = *mod_vars;
00677     
00678   for ( ; mod_var_iter.valid(); ++mod_var_iter) {
00679     Symbol &var = mod_var_iter.current();
00680 
00681     if (! _usable_global_vars.member(var))
00682       var_mods.del(var);
00683     else if (_contains_local_vars(var_mods[var], caller_formals))
00684       var_mods.ins(var, omega());
00685   }
00686 
00687   delete mod_vars;
00688 }
00689 
00690 
00691 ///  _filter_out_entering_consts.
00692 ///   Filter out any constants in new_consts that are not in old_const_mods.
00693 ///   This can occur when a constant in new_consts originated from an
00694 ///   entering interprocedural constant for the procedure.
00695 
00696 
00697 static void 
00698 _filter_out_entering_consts(Map<Symbol,Expression> &new_consts,
00699                 const Map<Symbol, Expression> &old_const_mods)
00700 {
00701   RefSet<Symbol> *mod_vars = modified_vars(new_consts);
00702   Iterator<Symbol> mod_var_iter = *mod_vars;
00703 
00704   for ( ; mod_var_iter.valid(); ++mod_var_iter) {
00705     Symbol &var = mod_var_iter.current();
00706 
00707     if (! old_const_mods.member(var))
00708       new_consts.del(var);
00709   }
00710 
00711   delete mod_vars;
00712 }
00713 
00714 
00715 ///  create_return_jump_function
00716 
00717 void
00718 IPCPProcData::create_return_jump_function(Map<Symbol, Expression> *old_const_mods,
00719                       Map<Symbol, Expression> *new_consts)
00720 {
00721   _filter_out_entering_consts(*new_consts, *old_const_mods);
00722   _rename_locals_to_globals(*old_const_mods);
00723   _filter_out_local_vars(*old_const_mods);
00724   _rename_locals_to_globals(*new_consts);
00725   _filter_out_local_vars(*new_consts);
00726 
00727   if (_return_jump_function)
00728     delete _return_jump_function;
00729 
00730   _return_jump_function = new ReturnJumpFunction(_param_list,
00731                          _usable_global_vars,
00732                          old_const_mods, new_consts);
00733 }
00734 
00735 
00736 ///  call_data
00737 
00738 const IPCPCallData *
00739 IPCPProcData::call_data(const Statement &call_site) const
00740 {
00741   return _call_data.find_ref(call_site.tag());
00742 }
00743 
00744 
00745 ///  create_jump_function
00746 
00747 void
00748 IPCPProcData::create_jump_function(const Statement &call_site,
00749                    Map<Symbol, Expression> *old_const_mods,
00750                    Map<Symbol, Expression> *new_consts,
00751                    List<Expression> *actuals)
00752 {
00753   _filter_out_entering_consts(*new_consts, *old_const_mods);
00754   IPCPCallData *cdata = _call_data.find_ref(call_site.tag());
00755 
00756   if (cdata && cdata->data_ref()) {
00757     _rename_locals_to_globals(*old_const_mods);
00758     _rename_locals_to_globals(*new_consts);
00759 
00760     /// ...  Add the parameter values to the jump function.
00761 
00762     p_assert(cdata->data_ref()->param_list().entries() == actuals->entries(),
00763          "IPCPProcData::create_jump_function(): The number of given actuals does not equal the number of formals.");
00764 
00765     Iterator<Symbol> formal_iter = cdata->data_ref()->param_list();
00766     Mutator<Expression> actual_iter = *actuals;
00767 
00768     for ( ; formal_iter.valid(); ++formal_iter, ++actual_iter) {
00769       const Symbol &formal = formal_iter.current();
00770       Expression *actual_expr = actual_iter.grab();
00771 
00772       if (formal.type() == actual_expr->type()
00773       && (_ipcp_ref->_is_substitutable(formal)
00774           || actual_expr->base_variable_ref())) {
00775 
00776     _rename_locals_to_globals(*actual_expr);
00777     new_consts->ins(formal, actual_expr);
00778       }
00779       else {
00780     delete actual_expr;
00781     new_consts->ins(formal, omega());
00782       }
00783     }
00784 
00785     cdata->data_ref()->_filter_out_local_vars(*old_const_mods, _param_list);
00786     cdata->data_ref()->_filter_out_local_vars(*new_consts, _param_list);
00787 
00788     RefSet<Symbol> *new_const_mods = modified_vars(*new_consts);
00789     Iterator<Symbol> new_const_iter = *new_const_mods;
00790 
00791     for ( ; new_const_iter.valid(); ++new_const_iter) {
00792       Symbol &var = new_const_iter.current();
00793 
00794       if ((*new_consts)[var].op() == OMEGA_OP)
00795     if (old_const_mods->member(var))
00796       new_consts->del(var);
00797     else
00798       old_const_mods->ins(var, new_consts->grab(var));
00799     }
00800 
00801     delete new_const_mods;
00802     cdata->jump_function(new JumpFunction(_param_list,
00803                       cdata->data_ref()->usable_global_vars(),
00804                       old_const_mods, new_consts));
00805   }
00806 
00807   delete actuals;
00808 }
00809 
00810 
00811 /// rename_locals_to_globals
00812 ///   Rename all local variables in the given expression to their global
00813 ///   names.
00814 
00815 void
00816 IPCPProcData::_rename_locals_to_globals(Expression &expr) const
00817 {
00818   if (expr.op() == ID_OP) {
00819     if (expr.symbol().sym_class() == VARIABLE_CLASS) {
00820       const Symbol *global_var = _local_to_global_vars.find_ref(expr.symbol());
00821 
00822       if (global_var)
00823     expr.symbol(*global_var);
00824     }
00825   }
00826   else {
00827     Iterator<Expression> iter = expr.arg_list();
00828 
00829     for ( ; iter.valid(); ++iter)
00830       _rename_locals_to_globals(iter.current());
00831   }
00832 }
00833        
00834 void
00835 IPCPProcData::_rename_locals_to_globals(Map<Symbol,Expression> &var_mods) const
00836 {
00837   RefSet<Symbol> *mod_vars = modified_vars(var_mods);
00838   Iterator<Symbol> mod_var_iter = *mod_vars;
00839     
00840   for ( ; mod_var_iter.valid(); ++mod_var_iter) {
00841     Symbol &local_var = mod_var_iter.current();
00842     const Symbol *global_var = _local_to_global_vars.find_ref(local_var);
00843 
00844     if (! global_var)
00845       global_var = &local_var;
00846 
00847     Expression *global_mod_expr = var_mods.grab(local_var);
00848     _rename_locals_to_globals(*global_mod_expr);
00849     var_mods.ins(*global_var, global_mod_expr);
00850   }
00851 
00852   delete mod_vars;
00853 }
00854 
00855 void
00856 IPCPProcData::_rename_locals_to_globals(List<Expression> &expr_list) const
00857 {
00858   Iterator<Expression> iter = expr_list;
00859     
00860   for ( ; iter.valid(); ++iter)
00861     _rename_locals_to_globals(iter.current());
00862 }
00863 
00864 
00865 /// _rename_globals_to_locals
00866 ///   Rename all global variables in the given expression to their local
00867 ///   names.
00868 
00869 void
00870 IPCPProcData::_rename_globals_to_locals(Expression &expr) const
00871 {
00872   if (expr.op() == ID_OP) {
00873     if (expr.symbol().sym_class() == VARIABLE_CLASS) {
00874       const Symbol *local_var = _global_to_local_vars.find_ref(expr.symbol());
00875 
00876       if (local_var)
00877     expr.symbol(*local_var);
00878     }
00879   }
00880   else {
00881     Iterator<Expression> iter = expr.arg_list();
00882 
00883     for ( ; iter.valid(); ++iter)
00884       _rename_globals_to_locals(iter.current());
00885   }
00886 }
00887 
00888 void
00889 IPCPProcData::_rename_globals_to_locals(Map<Symbol,Expression> &var_mods) const
00890 {
00891   RefSet<Symbol> *mod_vars = modified_vars(var_mods);
00892   Iterator<Symbol> mod_var_iter = *mod_vars;
00893     
00894   for ( ; mod_var_iter.valid(); ++mod_var_iter) {
00895     Symbol &global_var = mod_var_iter.current();
00896     const Symbol *local_var = _global_to_local_vars.find_ref(global_var);
00897 
00898     if (! local_var)
00899       local_var = &global_var;
00900 
00901     Expression *local_mod_expr = var_mods.grab(global_var);
00902     _rename_globals_to_locals(*local_mod_expr);
00903     var_mods.ins(*local_var, local_mod_expr);
00904   }
00905 
00906   delete mod_vars;
00907 }
00908 
00909 
00910 /// local_old_const_mods
00911 
00912 Map<Symbol,Expression> *
00913 IPCPProcData::local_old_const_mods(const Statement &call_site,
00914                    const ReturnJumpFunction &jump_function) const
00915 {
00916   List<Expression> global_arg_list(_call_arg_list(call_site));
00917   _rename_locals_to_globals(global_arg_list);
00918   Map<Symbol, Expression> *var_mods = jump_function.const_mods(global_arg_list);
00919   _rename_globals_to_locals(*var_mods);
00920 
00921   return var_mods;
00922 }
00923     
00924 
00925 /// local_new_consts
00926 
00927 Map<Symbol,Expression> *
00928 IPCPProcData::local_new_consts(const Statement &call_site,
00929                    const ReturnJumpFunction &jump_function) const
00930 {
00931   List<Expression> global_arg_list(_call_arg_list(call_site));
00932   _rename_locals_to_globals(global_arg_list);
00933   Map<Symbol, Expression> *var_mods = jump_function.new_consts(global_arg_list);
00934   _rename_globals_to_locals(*var_mods);
00935 
00936   return var_mods;
00937 }
00938     
00939 
00940 /// add_constant_set
00941 
00942 void
00943 IPCPProcData::add_constant_set(IPCPConstants *constants,
00944                    const List<Expression> &param_values)
00945 {
00946   constants->filter_out_vars_not_in_set(_used_global_vars,
00947                     _usable_global_vars);
00948 
00949 /// If such a set of constants already exists in my sets of constants,
00950 /// return without updating.
00951 
00952   Iterator<IPCPConstants> consts_iter = _consts_sets;
00953 
00954   for ( ; consts_iter.valid(); ++consts_iter)
00955     if (*constants == consts_iter.current()) {
00956       consts_iter.current().merge_invocation_sites(constants);
00957       return;
00958     }
00959 
00960 /// The given constant set differs from my other constant sets,
00961 /// so add it to my constant sets.
00962 
00963   constants->proc_data_ref = this;
00964 
00965   if (constants->constants().entries() == 0) {
00966     /// ...  Always make the empty constant set be first, so that when cloning
00967     /// ...  occurs, the original program would receive the empty constant set.
00968 
00969     _consts_sets.ins_first(constants);
00970   }
00971   else
00972     _consts_sets.ins_last(constants);
00973 
00974 /// Update the constant sets of my call sites.
00975 
00976   KeyIterator<String, IPCPCallData> call_iter = _call_data;
00977 
00978   for ( ; call_iter.valid(); ++call_iter) {
00979     IPCPCallData &call_data = call_iter.current_data();
00980 
00981     if (call_data.data_ref() && call_data.jump_function_valid()) {
00982       const Statement *call_site = _pgm_ref->stmts().find_ref(call_iter.current_key());
00983       p_assert(call_site, "Couldn't find the call statement for one of the object's call sites.");
00984       List<Expression> global_arg_list(param_values);
00985       _rename_locals_to_globals(global_arg_list);
00986       IPCPConstants *call_constants
00987     = call_data.jump_function().constants(*constants,
00988                           global_arg_list);
00989       call_constants->add_invocation_site(
00990                       new CallSite(constants, call_site->tag()));
00991                            
00992       call_data.add_constant_set(call_constants, _call_arg_list(*call_site));
00993     }
00994   }
00995 }
00996 
00997 
00998 /// update_call_site
00999 ///   Update my call site with the given tag to the given IPCPProcData object.
01000 ///   Also rename the call itself to call the procedure owned by the
01001 ///   given IPCPProcData object.
01002 
01003 void
01004 IPCPProcData::_update_call_site(const char *call_site_tag,
01005                 IPCPProcData &new_call_proc_data)
01006 {
01007   IPCPCallData *call_data = _call_data.find_ref(call_site_tag);
01008   p_assert(call_data,
01009        "IPCPConstants::_update_call_site(): Couldn't find the given call site.");
01010   call_data->data_ref(&new_call_proc_data);
01011   Statement *call_site = _pgm_ref->stmts().find_ref(call_site_tag);
01012   const Symbol &entry_var = new_call_proc_data.entry().routine_guarded().symbol();
01013   Symbol *call_site_symbol = _pgm_ref->symtab().find_ref(entry_var.name_ref());
01014 
01015   if (! call_site_symbol) {
01016     call_site_symbol = entry_var.clone();
01017     call_site_symbol->external(IS_EXTERNAL);
01018     _pgm_ref->symtab().ins(call_site_symbol);
01019   }
01020 
01021   if (call_site->stmt_class() == CALL_STMT)
01022     call_site->routine_guarded().symbol(*call_site_symbol);
01023   else if (call_site->stmt_class() == ASSIGNMENT_STMT
01024        && call_site->rhs().op() == FUNCTION_CALL_OP) {
01025     /// ...  Make my call site symbol's type be the old call site symbol's
01026     /// ...  type.  This is needed to handle the CHARACTER*(*)
01027     /// ...  --> CHARACTER*(80) problem in some program units.
01028 
01029     call_site_symbol->type(call_site->rhs().function().symbol().type());
01030     call_site->rhs().function().symbol(*call_site_symbol);
01031   }
01032   else
01033     p_abort("Internal error: Given call site does not make a subroutine call.");
01034 }
01035 
01036 
01037 /// transfer_const_set
01038 
01039 void
01040 IPCPProcData::transfer_const_set(IPCPConstants &consts, IPCPProcData &other)
01041 {
01042   IPCPConstants *consts_obj = other._consts_sets.grab(consts);
01043     
01044   _consts_sets.ins_last(consts_obj);
01045   consts.proc_data_ref = this;
01046 
01047 /// Rename all calls to the original program unit with the given
01048 /// constant set to calls to the cloned program unit.
01049 
01050   Iterator<CallSite> caller_iter = consts.invocation_sites();
01051 
01052   for ( ; caller_iter.valid(); ++caller_iter) {
01053     CallSite &call_site = caller_iter.current();
01054     p_assert(call_site.caller_consts_ref(),
01055          "Internal error: main program unit was cloned.");
01056     call_site.caller_consts_ref()->proc_data_ref->_update_call_site(call_site.call_tag(),
01057                                     *this);
01058   }
01059 }
01060 
01061 
01062 /// local_consts
01063 ///   Return the constants stored in IPCPConstants, where all
01064 ///   variable references in the constant map are locally defined
01065 ///   variables.
01066 
01067 Map<Symbol,Expression> *
01068 IPCPProcData::_local_consts(const IPCPConstants &consts) const
01069 {
01070 /// Filter out global variables not used in my program unit.
01071 
01072   RefSet<Symbol> locally_used_global_vars;
01073   RefSet<Symbol> locally_usable_global_vars;
01074 
01075   KeyIterator<Symbol,Symbol> global_iter = _global_to_local_vars;
01076     
01077   for ( ; global_iter.valid(); ++global_iter) {
01078     Symbol &global_var = global_iter.current_key();
01079     locally_usable_global_vars.ins(global_var);
01080 
01081     if (_used_global_vars.member(global_var))
01082       locally_used_global_vars.ins(global_var);
01083   }
01084 
01085   IPCPConstants my_consts(consts);
01086   my_consts.filter_out_vars_not_in_set(locally_used_global_vars,
01087                        locally_usable_global_vars);
01088   Map<Symbol,Expression> *lconsts
01089     = new Map<Symbol,Expression>(my_consts.constants());
01090   _rename_globals_to_locals(*lconsts);
01091 
01092   return lconsts;
01093 }
01094 
01095 
01096 /// add_consts_to_pgm
01097 
01098 void
01099 IPCPProcData::add_consts_to_pgm(const IPCPConstants &consts)
01100 {
01101   Map<Symbol,Expression> *const_map = _local_consts(consts);
01102   KeyIterator<Symbol, Expression> const_iter = *const_map;
01103 
01104   for ( ; const_iter.valid(); ++const_iter)
01105     if (! const_iter.current_key().is_array()) {
01106       /// ...  silvius: do not do that as it messes up read-only common vars
01107 ///       Statement *const_stmt
01108 ///     = new AssignmentStmt(_pgm_ref->stmts().new_tag(),
01109 ///                  id(const_iter.current_key()),
01110 ///                  const_iter.current_data().clone());
01111 ///       _pgm_ref->stmts().ins_after(const_stmt, (Statement *) _entry);
01112     }
01113 
01114   delete const_map;
01115 }
01116 
01117 void
01118 IPCPProcData::add_consts_to_pgm()
01119 {
01120   p_assert(_consts_sets.entries() <= 1,
01121        "IPCPProcData::add_consts_to_pgm():  There are multiple number of sets of constants.");
01122 
01123   if (_consts_sets.entries() == 1)
01124     add_consts_to_pgm(_consts_sets[0]);
01125 }
01126 
01127 
01128 ///  propagate_constants
01129 
01130 void
01131 IPCPProcData::build_jump_functions(int debug GIV(0))
01132 {
01133   RefSet<Symbol> *use_candidates = _candidates();
01134   RefSet<Symbol> *def_candidates = new RefSet<Symbol>(*use_candidates);
01135 
01136   Mutator<Symbol> cand_iter = *def_candidates;
01137 
01138   for ( ; cand_iter.valid(); ++cand_iter)
01139     if (! _ipcp_ref->_is_substitutable(cand_iter.current()))
01140       cand_iter.del();
01141 
01142   KeyIterator<String,IPCPCallData> call_iter = _call_data;
01143 
01144   for ( ; call_iter.valid(); ++call_iter)
01145     call_iter.current_data().jump_function(0);
01146 
01147   Map<Symbol,Expression> *entering_constants;
01148 
01149   if (_consts_sets.entries() == 1)
01150     entering_constants = _local_consts(_consts_sets[0]);
01151   else
01152     entering_constants = new Map<Symbol, Expression>;
01153       
01154   _ipcp_build_jump_functions(*_pgm_ref, *this, *def_candidates,
01155                  *use_candidates, *entering_constants, debug);
01156   delete entering_constants;
01157   delete def_candidates;
01158   delete use_candidates;
01159 }
01160 
01161 
01162 ///  expr_del_global_substituted
01163 ///     Delete or substitute all global variables in the given expression.
01164 
01165 Expression *
01166 IPCPProcData::_expr_del_global_substituted(Expression *expr)
01167 {
01168   if (expr)
01169     if (expr->op() == ID_OP) {
01170       expr->substituted(_expr_del_global_substituted(expr->grab_substituted()));
01171 
01172       if (_usable_global_vars.member(expr->symbol())) {
01173     Expression *new_expr = expr->grab_substituted();
01174     delete expr;
01175     return new_expr;
01176       }
01177     }
01178     else {
01179       Mutator<Expression> arg_iter = expr->arg_list();
01180 
01181       for ( ; arg_iter.valid(); ++arg_iter) {
01182     Assign<Expression> eas(arg_iter.assign());
01183     Expression *new_arg = _expr_del_global_substituted(arg_iter.pull());
01184     if (new_arg)
01185       eas = new_arg;
01186     else {
01187       delete expr;
01188       delete new_arg;
01189       return 0;
01190     }
01191       }
01192     }
01193 
01194   return expr;
01195 }
01196 
01197 
01198 ///  del_global_substituted
01199 ///     Delete or substitute all global variables in my program unit.
01200 
01201 void
01202 IPCPProcData::_del_global_substituted()
01203 {
01204   Iterator<Statement> stmt_iter = _pgm_ref->stmts().iterator();
01205 
01206   for ( ; stmt_iter.valid(); ++stmt_iter) {
01207     Mutator<Expression> expr_iter = stmt_iter.current().iterate_expressions();
01208 
01209     for ( ; expr_iter.valid(); ++expr_iter) {
01210       Assign<Expression> eas(expr_iter.assign());
01211       Expression *new_expr = _expr_del_global_substituted(expr_iter.pull());
01212       p_assert(new_expr, "Internal error in IPCPProcData::_del_global_substituted()");
01213       eas = new_expr;
01214     }
01215   }
01216 }
01217     
01218 
01219 
01220 ///  propagate_constants
01221 
01222 void
01223 IPCPProcData::propagate_constants(PC_UNREACH_BOOL remove_unreachable,
01224                   int debug GIV(0))
01225 {
01226   RefSet<Symbol> *use_candidates = _candidates();
01227   RefSet<Symbol> *def_candidates = new RefSet<Symbol>(*use_candidates);
01228     
01229   Mutator<Symbol> cand_iter = *def_candidates;
01230 
01231   for ( ; cand_iter.valid(); ++cand_iter)
01232     if (! _ipcp_ref->_is_substitutable(cand_iter.current()))
01233       cand_iter.del();
01234     
01235   Map<Symbol,Expression> *entering_constants;
01236 
01237   if (_consts_sets.entries() == 1)
01238     entering_constants = _local_consts(_consts_sets[0]);
01239   else
01240     entering_constants = new Map<Symbol, Expression>;
01241       
01242   _ipcp_propagate_constants(*_pgm_ref, *this, *def_candidates,
01243                 *use_candidates, remove_unreachable,
01244                 *entering_constants, debug);
01245   delete entering_constants;
01246   delete def_candidates;
01247   delete use_candidates;
01248 
01249   _del_global_substituted();
01250 }
01251 
01252 
01253 ///  add_maymods
01254 
01255 void
01256 IPCPProcData::add_maymods()
01257 {
01258   KeyIterator<String, IPCPCallData> call_iter = _call_data;
01259 
01260   for ( ; call_iter.valid(); ++call_iter) {
01261     const IPCPProcData *call_data = call_iter.current_data().data_ref();
01262     const Statement *call_site = _pgm_ref->stmts().find_ref(call_iter.current_key());
01263 
01264     if (call_data && call_site) {
01265       /// ...  Delete any old MAYMOD assertions.
01266 
01267       Mutator<Assertion> asrt_iter = call_site->assertions();
01268 
01269       for ( ; asrt_iter.valid(); ++asrt_iter)
01270     if (asrt_iter.current().type() == AS_MAYMOD)
01271       asrt_iter.del();
01272 
01273       /// ...  Compute the set of possibly modified variables for this call
01274       /// ...  site.
01275 
01276       Map<Symbol, Expression> *var_modifications
01277     = local_old_const_mods(*call_site,
01278                    call_data->return_jump_function());
01279 
01280       RefList<Symbol> maymods;
01281       KeyIterator<Symbol, Expression> mod_iter = *var_modifications;
01282 
01283       for ( ; mod_iter.valid(); ++mod_iter) {
01284     Symbol &var = mod_iter.current_key();
01285 
01286     if (_pgm_ref->symtab().find_ref(var.name_ref()) == &var)
01287       maymods.ins_last(var);
01288       }
01289 
01290       delete var_modifications;
01291       sort_sym_list(maymods);
01292 
01293       /// ...  Create a MAYMOD assertion with these variables.
01294 
01295       AssertMayMod *assert = new AssertMayMod();
01296       Mutator<Symbol> mod_var_iter = maymods;
01297 
01298       for ( ; mod_var_iter.valid(); ++mod_var_iter)
01299     assert->arg_list_guarded().ins_last(id(mod_var_iter.current()));
01300 
01301       call_site->assertions().ins_last(assert);
01302     }
01303   }
01304 }
01305 
01306 
01307 ///  expand_all_substituted
01308 
01309 //GUOBIN HE BEGIN
01310 Boolean
01311 constant_value(const Expression &expr)
01312 {
01313   if(expr.arg_list().entries()==0)
01314     return (expr.op() == INTEGER_CONSTANT_OP
01315            || expr.op() == LOGICAL_CONSTANT_OP);
01316   else if(expr.op() == INTRINSIC_CALL_OP)
01317     return constant_value(expr.parameters_guarded());
01318   else {
01319     Iterator<Expression> iter = expr.arg_list();
01320 
01321     for(; iter.valid(); ++iter)
01322       if(! constant_value(iter.current()))
01323         return false;
01324   }
01325 
01326   return true;
01327 }
01328 //GUOBIN HE END
01329 
01330 void
01331 IPCPProcData::expand_all_substituted()
01332 {
01333   //expand_substituted(*_pgm_ref, 0, 0);
01334   expand_substituted(*_pgm_ref, 0, constant_value);
01335 }
01336 
01337 
01338 ///  make_consts_sets_old
01339 
01340 void
01341 IPCPProcData::make_consts_sets_old()
01342 {
01343   _old_consts_sets.clear();
01344 
01345   while (_consts_sets.entries())
01346     _old_consts_sets.ins_first(_consts_sets.grab(0));
01347 }
01348 
01349 
01350 ///  have_consts_sets_changed
01351 
01352 Boolean
01353 IPCPProcData::have_consts_sets_changed() const
01354 {
01355   if (_consts_sets.entries() != _old_consts_sets.entries())
01356     return True;
01357 
01358   Iterator<IPCPConstants> new_consts_iter = _consts_sets;
01359 
01360   for ( ; new_consts_iter.valid(); ++new_consts_iter) {
01361     const IPCPConstants &new_consts = new_consts_iter.current();
01362     Boolean is_consts_in_set = False;
01363     Iterator<IPCPConstants> old_consts_iter = _old_consts_sets;
01364     
01365     for ( ; old_consts_iter.valid() && ! is_consts_in_set; ++old_consts_iter)
01366       if (new_consts == old_consts_iter.current())
01367     is_consts_in_set = True;
01368 
01369     if (! is_consts_in_set)
01370       return True;
01371   }
01372 
01373   return False;
01374 }
01375 
01376 
01377 ///  listable_clone
01378 
01379 Listable *
01380 IPCPProcData::listable_clone() const
01381 {
01382   return new IPCPProcData(*this);
01383 }
01384 
01385 
01386 /// _print_var_map
01387 ///   Print a mapping from variables to variables;
01388 
01389 static void
01390 _print_var_map(ostream &o, const RefMap<Symbol,Symbol> &var_map)
01391 {
01392   o << "{";
01393   KeyIterator<Symbol,Symbol> iter = var_map;
01394 
01395   if (iter.valid()) {
01396     o << iter.current_key().name_ref() << "="
01397       << iter.current_data().name_ref();
01398     ++iter;
01399 
01400     for ( ; iter.valid(); ++iter)
01401       o << ", " << iter.current_key().name_ref() << "="
01402     << iter.current_data().name_ref();
01403   }
01404 
01405   o << "}";
01406 }
01407 
01408 
01409 /// init_rtoporder
01410 
01411 void
01412 IPCPProcData::init_rtoporder()
01413 {
01414   _rtoporder = -1;
01415 }
01416 
01417 
01418 /// compute_rtoporder
01419 
01420 void
01421 IPCPProcData::compute_rtoporder(int &max_visited_elems)
01422 {
01423   if (_rtoporder < 0) {
01424     KeyIterator<String, IPCPCallData> call_iter = _call_data;
01425     
01426     for ( ; call_iter.valid(); ++call_iter)
01427       call_iter.current_data().compute_rtoporder(max_visited_elems);
01428     
01429     _rtoporder = max_visited_elems;
01430     ++max_visited_elems;
01431   }
01432 }
01433     
01434 
01435 /// _print_var_set
01436 ///   Print a mapping from variables to variables;
01437 
01438 static void
01439 _print_var_set(ostream &o, const RefSet<Symbol> &var_map)
01440 {
01441   o << "{";
01442   Iterator<Symbol> iter = var_map;
01443 
01444   if (iter.valid()) {
01445     o << iter.current().name_ref();
01446     ++iter;
01447 
01448     for ( ; iter.valid(); ++iter)
01449       o << ", " << iter.current().name_ref();
01450   }
01451 
01452   o << "}";
01453 }
01454 
01455 
01456 ///  print
01457 
01458 void
01459 IPCPProcData::print(ostream &o, Boolean pretty_print) const
01460 {
01461   o << "[";
01462   o << "pgm=" << _pgm_ref->routine_name_ref();
01463   o << ", ipcp=" << _ipcp_ref;
01464   o << ", entry=";
01465   _entry->print_debug(o, 0);
01466   o << ", ";
01467   o << ", rtoporder=" << _rtoporder;
01468   o << ", ";
01469   if (pretty_print) o << "\n ";
01470   o << "used_global_vars={";
01471   _print_var_set(o, _used_global_vars);
01472   o << "}, ";
01473   if (pretty_print) o << "\n ";
01474   o << "usable_global_vars={";
01475   _print_var_set(o, _usable_global_vars);
01476   o << "}, ";
01477   if (pretty_print) o << "\n ";
01478   o << "local_to_global_vars=";
01479   _print_var_map(o, _local_to_global_vars);
01480   o << ", ";
01481   if (pretty_print) o << "\n ";
01482   o << "global_to_local_vars=";
01483   _print_var_map(o, _global_to_local_vars);
01484   o << ", ";
01485   if (pretty_print) o << "\n ";
01486   o << "param_list={";
01487   Iterator<Symbol> param_iter = _param_list;
01488 
01489   if (param_iter.valid()) {
01490     o << param_iter.current().name_ref();
01491     ++param_iter;
01492 
01493     for ( ; param_iter.valid(); ++param_iter)
01494       o << ", " << param_iter.current().name_ref();
01495   }
01496 
01497   o << "}, ";
01498   if (pretty_print) o << "\n ";
01499   o << "return_var=";
01500 
01501   if (_return_var)
01502     o << _return_var->name_ref();
01503   else
01504     o << "NULL";
01505 
01506   o << ", ";
01507   if (pretty_print) o << "\n ";
01508   o << "return_jump_function=";
01509 
01510   if (_return_jump_function)
01511     o << *_return_jump_function;
01512   else
01513     o << "NULL";
01514 
01515   o << ", ";
01516   if (pretty_print) o << "\n ";
01517   o << "consts_sets=" << _consts_sets;
01518   o << ", ";
01519   if (pretty_print) o << "\n ";
01520   o << "_call_data={";
01521 
01522   KeyIterator<String,IPCPCallData> call_iter = _call_data;
01523 
01524   if (call_iter.valid()) {
01525     if (pretty_print) o << "\n  ";
01526     o << call_iter.current_key() << ": " << call_iter.current_data();
01527     ++call_iter;
01528 
01529     for ( ; call_iter.valid(); ++call_iter) {
01530       o << ", ";
01531       if (pretty_print) o << "\n  ";
01532       o << call_iter.current_key() << ": " << call_iter.current_data();
01533     }
01534   }
01535 
01536   o << "}";
01537   o << "]";
01538   if (pretty_print) o << "\n";
01539 }
01540 
01541 void
01542 IPCPProcData::print(ostream &o) const
01543 {
01544   print(o, False);
01545 }
01546 
01547 
01548 ///  structures_OK
01549 
01550 int
01551 IPCPProcData::structures_OK() const
01552 {
01553   return (_call_data.structures_OK()
01554       && _used_global_vars.structures_OK()
01555       && _local_to_global_vars.structures_OK()
01556       && _global_to_local_vars.structures_OK()
01557       && _param_list.structures_OK()
01558       && (! _return_jump_function
01559           || _return_jump_function->structures_OK()));
01560 }
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:57 2005