Polaris: TranslateObject.cc Source File

TranslateObject.cc

Go to the documentation of this file.
00001 ///
00002 ///
00003 #ifdef POLARIS_GNU_PRAGMAS
00004 #pragma implementation
00005 #endif
00006 ///
00007 #include <stdio.h>
00008 #include <strstream.h>
00009 
00010 #include "TranslateObject.h"
00011 
00012 #include "Expression/expr_funcs.h"
00013 #include "Expression/LambdaCallExpr.h"
00014 #include "Info.h"
00015 #include "ProgramUnit.h"
00016 #include "Symbol/VariableSymbol.h"
00017 #include "StmtList.h"
00018 
00019 template class TypedBaseMap<Symbol,TranslateObject::SymRefElem>;
00020 template class ProtoMap<Symbol,TranslateObject::SymRefElem>;
00021 template class Map<Symbol,TranslateObject::SymRefElem>;
00022 template ostream & operator << (ostream &, const Map<Symbol,TranslateObject::SymRefElem> &);
00023 template class KeyIterator<Symbol,TranslateObject::SymRefElem>;
00024 
00025 Listable *
00026 TranslateObject::SymRefElem::listable_clone() const
00027 {
00028     return new SymRefElem(*this);
00029 }
00030 
00031 void 
00032 TranslateObject::SymRefElem::print(ostream & o) const
00033 {
00034 
00035   o << '<';
00036 
00037   if (_symref.valid())
00038     _symref->print(o);
00039 
00040   if (_privat == PRIVATE)
00041       o << ", Private";
00042     else
00043       o << ", Non-Private";
00044 
00045   if (_precalc == CAND_PRECALC_VAR)
00046     o << ", Candidate-Precalc>";
00047   else
00048     o << ", Not-Precalc>";
00049 
00050 }
00051   
00052 /// Copy translate object
00053 
00054 TranslateObject::TranslateObject(const TranslateObject & map)
00055     : _pgm_main(map._pgm_main),
00056       _permanent_changes(map._permanent_changes),
00057       _debug_flag(map._debug_flag),
00058       _private_vars(map._private_vars),
00059       _precalc_vars(map._precalc_vars),
00060       _test_exprs(map._test_exprs)
00061 {
00062     #ifdef CLASS_INSTANCE_REGISTRY
00063     register_instance(TRANSLATE_OBJECT, sizeof(TranslateObject), this);
00064     #endif
00065 
00066   p_assert(_pgm_ref != &_pgm_main,
00067        "Invalid attempt to clone TranslateObject");
00068 
00069   _pgm_ref = new ProgramUnit(*map._pgm_ref);
00070   _pgm_owned = true;
00071 
00072 /// Translate local program symbols in symbol, array, substring and
00073 /// constant maps: main program symbols (including SymRefElems)
00074 /// and expressions do not need to be translated
00075     
00076   for (DictionaryIter<Symbol> symbol_iter = _pgm_ref->symtab().iterator();
00077        symbol_iter.valid(); ++symbol_iter) {
00078 
00079     if ((symbol_iter.current().sym_class() != VARIABLE_CLASS) ||
00080     (!symbol_iter.current().formal())) {
00081 
00082       Symbol         *current_symbol_ptr = &symbol_iter.current();
00083 
00084       Symbol & current_symbol = *current_symbol_ptr;
00085 
00086 
00087       const char     *current_tag = current_symbol.name_ref();
00088 
00089       Symbol         *map_symbol_ptr =
00090     map._pgm_ref->symtab().find_ref(current_tag);
00091 
00092       p_assert(map_symbol_ptr,
00093            "Invalid symbol found in map in TranslateObject constructor");
00094 
00095       const SymRefElem  *symbol_data_ref
00096     = map._symbol_map.find_ref(*map_symbol_ptr);
00097 
00098       if (symbol_data_ref) {
00099     _symbol_map.ins(current_symbol,symbol_data_ref->clone());
00100 
00101     const Expression      *array_data_ref =
00102       map._array_map.find_ref(*map_symbol_ptr);
00103 
00104     if (array_data_ref) {
00105       _array_map.ins(current_symbol, array_data_ref->clone());
00106     }
00107 
00108     const Expression *substring_data_ref =
00109       map._substring_map.find_ref(*map_symbol_ptr);
00110 
00111     if (substring_data_ref) {
00112       _substring_map.ins(current_symbol, substring_data_ref->clone());
00113     }
00114 
00115     const Expression *alternate_data_ref =
00116       map._alternate_map.find_ref(*map_symbol_ptr);
00117 
00118     if (alternate_data_ref) {
00119       _alternate_map.ins(current_symbol, alternate_data_ref->clone());
00120     }
00121     continue;
00122       }
00123 
00124       const Expression     *constant_data_ref =
00125     map._constant_map.find_ref(*map_symbol_ptr);
00126 
00127       if (constant_data_ref) 
00128     _constant_map.ins(current_symbol, *constant_data_ref);
00129     }
00130   }
00131 
00132 /// Translate format map
00133 
00134   for (KeyIterator<int,Format> format_iter = _pgm_ref->formats();
00135        format_iter.valid(); ++format_iter) {
00136     Format & current_format = format_iter.current_data();
00137     int current_value = current_format.value();
00138     const Format         *map_format_ptr 
00139       = map._pgm_ref->formats().find_ref(current_value);
00140     
00141     p_assert(map_format_ptr,
00142          "Invalid format found in map in TranslateObject constructor");
00143     
00144     const Format         *main_format_ptr 
00145       = map._format_map.find_ref(*map_format_ptr);
00146 
00147     p_assert(main_format_ptr,
00148          "Valid format not found in map in TranslateObject constructor");
00149       
00150     _format_map.ins(current_format, CASTAWAY (Format &) *main_format_ptr);
00151   }
00152 }
00153 
00154 /// Copy translate object
00155 
00156 TranslateObject::TranslateObject(const TranslateObject & map, const ProgramUnit & new_main_pgm)
00157     : _pgm_main(CASTAWAY(ProgramUnit &) new_main_pgm),
00158       _pgm_owned(false),
00159       _permanent_changes(false),
00160       _debug_flag(map._debug_flag),
00161       _private_vars(0),
00162       _precalc_vars(0)
00163 {
00164     #ifdef CLASS_INSTANCE_REGISTRY
00165     register_instance(TRANSLATE_OBJECT, sizeof(TranslateObject), this);
00166     #endif
00167 
00168   p_assert((map._pgm_ref == &map._pgm_main) &&
00169        !map._array_map.entries() &&
00170        !map._constant_map.entries() &&
00171        !map._substring_map.entries() &&
00172        !map._alternate_map.entries() &&
00173        !map._test_exprs.entries() &&
00174        !map._begin_comment_list.entries() &&
00175        !map._end_comment_list.entries() &&
00176        !map._format_map.entries(),
00177        "Invalid attempt to clone TranslateObject");
00178 
00179   _pgm_ref = &_pgm_main;
00180 
00181 /// Translate main program symbol references (including SymRefElems) in _symbol_map
00182 /// to refer to new_main_pgm
00183 
00184   for (KeyIterator<Symbol,SymRefElem> symbol_iter = map._symbol_map;
00185        symbol_iter.valid(); ++symbol_iter) {
00186     const Symbol & curr_key_sym = symbol_iter.current_key();
00187     Symbol * new_key_sym = 
00188       CASTAWAY(Symbol *) new_main_pgm.symtab().find_ref(curr_key_sym.name_ref());
00189     p_assert(new_key_sym,
00190          "Invalid symbol found in TranslateObject to be cloned");
00191     const RefElement<Symbol> & curr_data_sym = symbol_iter.current_data().symref();
00192     if (curr_data_sym.valid()) {
00193       Symbol * new_data_sym =
00194     CASTAWAY(Symbol *) new_main_pgm.symtab().find_ref(curr_data_sym->name_ref());
00195       p_assert(new_data_sym,
00196            "Invalid symbol found in TranslateObject to be cloned");
00197       _symbol_map.ins(*new_key_sym, new SymRefElem(*new_data_sym));
00198     }
00199     else /// ...  Must be a pseudo function symbol (e.g., BETA)
00200       _symbol_map.ins(*new_key_sym, new SymRefElem());
00201   }
00202 }
00203 
00204 
00205 TranslateObject::~TranslateObject()
00206 {
00207     #ifdef CLASS_INSTANCE_REGISTRY
00208     unregister_instance(TRANSLATE_OBJECT, this);
00209     #endif
00210 
00211 ///    if (_pgm_owned)
00212 ///        delete _pgm_ref;  /// ...  Removed this since it was causing a p_assert about attempting
00213                         /// ...  to delete a live object.  Apparently the cloned ProgramUnit gets
00214                             /// ...  put in the Program (or on some kind of ProgramUnit list).
00215 }
00216 
00217 Listable *
00218 TranslateObject::listable_clone() const
00219 
00220 {
00221     return new TranslateObject(*this);
00222 }
00223 
00224 void 
00225 TranslateObject::print(ostream & o) const
00226 {
00227   if (&_pgm_main != _pgm_ref) {
00228     o << "Inlined program:\n\n";
00229     o << *_pgm_ref;
00230   }
00231 
00232   o << "\nSymbol map:\n\n";
00233   o << _symbol_map;
00234 
00235   o << "\nArray map:\n\n";
00236   o << _array_map;
00237 
00238   o << "\nConstant map:\n\n";
00239   o << _constant_map << "\n";
00240 
00241   o << "\nFormat map:\n\n";
00242   o << _format_map;
00243 
00244   o << "\nSubstring map:\n\n";
00245   o << _substring_map;
00246 
00247   o << "\nAlternate expression map:\n\n";
00248   o << _alternate_map;
00249 
00250   o << "\nSubscript test expressions:\n\n";
00251   o << _test_exprs;
00252 }
00253 
00254 /// Return an initial subscript for the variable pointed to by
00255 /// src_name_ptr.
00256 
00257 Expression      *
00258 initial_array_ref(Symbol * src_name_ptr)
00259 {
00260   p_assert(src_name_ptr->sym_class() == VARIABLE_CLASS,
00261        "Illegal symbol passed to src_name_ptr");
00262 
00263   Expression *returned_ref = comma();
00264 
00265 /// Add a clone of lower bound (or 1 if not defined) for each dimension
00266 
00267   for (Iterator<ArrayBounds> array_iter = src_name_ptr->dim();
00268        array_iter.valid(); ++array_iter) {
00269     Expression     *lb = array_iter.current().lower_ref();
00270 
00271     if (lb)
00272       lb = lb->clone();
00273     else
00274       lb = constant(1);
00275     
00276     returned_ref->arg_list().ins_last(lb);
00277   }
00278   
00279   return returned_ref;
00280 }
00281 
00282 VariableSymbol *
00283 TranslateObject::translate_symbol ( const Symbol & in_symbol ) const
00284 {
00285     VariableSymbol * symbol_ptr = 0;
00286 
00287     const SymRefElem *symbol_ref
00288     = _symbol_map.find_ref(in_symbol);
00289 
00290     if (symbol_ref)
00291     symbol_ptr = (VariableSymbol *) &(*symbol_ref->symref());
00292 
00293     return symbol_ptr;
00294 }
00295 
00296 /// Find all array references in this expression specified by _array_map
00297 /// and replace them with LAMBDA_CALL expressions to the caller's array.
00298 ///
00299 /// Find all substring references in this expression specified by 
00300 /// _substring_map and replace them with appropriate substring expressions.
00301 ///
00302 /// Find all symbol references in this expression specified by _symbol_map
00303 /// or _constant_map and replace them.
00304 ///
00305 /// Find all format references in this expression specified by _format_map
00306 /// and replace them.
00307 ///
00308 /// If an alternate expression exists in _alternate_map for references in
00309 /// this expression, attempt to use it instead of the equivalent expression.
00310 
00311 Expression     *
00312 TranslateObject::_translate_symbol_refs_expr(Expression * expr,
00313                          REF_TYPE ref,
00314                          bool & expr_flag,
00315                          const Map<Symbol, Expression> *formal_to_actual) const
00316 {
00317 /// Initially, return original expression
00318   Expression     *e = expr;
00319 
00320 /// Nothing transformed here so far
00321   bool            repl_flag = false;
00322 
00323 /// Check by type of operator
00324   switch (expr->op()) {
00325 
00326   case SUBSTRING_OP:
00327     {
00328       List<Expression> & substr_list = expr->arg_list();
00329     
00330       /// ...  Translate bound expression
00331 
00332       bool local_expr_flag = false;
00333 
00334       Assign<Expression> bound_as(substr_list.assign(1));
00335       bound_as = _translate_symbol_refs_expr(substr_list.pull(1),
00336                          IN_REF_EXPR, local_expr_flag,
00337                          formal_to_actual);
00338       repl_flag |= local_expr_flag;
00339 
00340       if ((_debug_flag > 19) && (local_expr_flag))
00341     cerr << "Replacement of substring bound detected.\n";
00342 
00343       /// ...  Translate string expression
00344 
00345       local_expr_flag = false;
00346 
00347       Assign<Expression> string_as(substr_list.assign(0));
00348       string_as = _translate_symbol_refs_expr(substr_list.pull(0),
00349                           IN_REF_EXPR, local_expr_flag,
00350                           formal_to_actual);
00351       repl_flag |= local_expr_flag;
00352 
00353       if ((_debug_flag > 19) && (local_expr_flag))
00354     cerr << "Replacement of substring string detected.\n";
00355 
00356       /// ...  If string expression is also a substring, fix up expression
00357 
00358       if (substr_list[0].op()==SUBSTRING_OP) {
00359 
00360     /// ...  Grab subexpressions
00361 
00362     Expression * string_ptr = substr_list.grab(0);
00363     Expression * bound_ptr = substr_list.grab(1);
00364 
00365     /// ...  Delete empty top-level expression
00366 
00367     delete expr;
00368 
00369     /// ...  Make string expression top-level expression
00370 
00371     e = string_ptr;
00372 
00373     /// ...  Point at old bound expressions
00374 
00375     List<Expression> & old_bound_list = bound_ptr->arg_list();
00376     int old_bound_entries = old_bound_list.entries();
00377 
00378     /// ...  Adjust new bound expressions accordingly
00379 
00380     List<Expression> & new_bound_list = e->bound().arg_list();
00381 
00382     Expression * le = old_bound_list.grab(0);
00383 
00384     if (le->op() == OMEGA_OP)
00385       delete le;
00386     else {
00387       Assign<Expression> new_bound_as(new_bound_list.assign(0));
00388       new_bound_as = sub(add(le,new_bound_list.pull(0)),
00389                  constant(1));
00390     }
00391 
00392     if (old_bound_entries > 1) {
00393  
00394       Expression * ue = old_bound_list.grab(0);
00395       if (ue->op() != OMEGA_OP) {
00396         new_bound_list.del(1);
00397         new_bound_list.ins_last(sub(add(ue,le->clone()),
00398                     constant(1)));
00399       }
00400       else
00401         delete ue;
00402     }
00403 
00404     /// ...  Delete empty old bound expression
00405 
00406     delete bound_ptr;
00407       }
00408 
00409       break;
00410     }
00411 
00412   case ARRAY_REF_OP:
00413     {
00414       bool local_expr_flag = false;
00415 
00416       /// ...  Take subscript out of original expression
00417 
00418       Expression * subs_e = expr->grab_right();
00419 
00420       /// ...  Check subscript for substitution
00421 
00422       subs_e = _translate_symbol_refs_expr(subs_e, IN_REF_EXPR,
00423                        local_expr_flag,
00424                        formal_to_actual);
00425       if ((_debug_flag > 19) && (local_expr_flag))
00426     cerr << "Replacement of array subscript detected.\n";
00427 
00428       /// ...  If something replaced, remember for later
00429 
00430       repl_flag |= local_expr_flag;
00431 
00432       /// ...  Point at base variable
00433       VariableSymbol *name_ptr 
00434     = (VariableSymbol *) expr->base_variable_ref();
00435 
00436       /// ...  Look up base variable in symbol, array and substring maps
00437 
00438       const VariableSymbol *symbol_ptr = translate_symbol( *name_ptr );
00439 
00440 ///      const SymRefElem *symbol_ref
00441 //  = _symbol_map.find_ref(*name_ptr);
00442 ///      if (symbol_ref)
00443 //  symbol_ptr = (VariableSymbol *) &(*symbol_ref->symref());
00444 
00445       const Expression *array_ptr = _array_map.find_ref(*name_ptr);
00446 
00447       const Expression *substr_ptr =
00448     _substring_map.find_ref(*name_ptr);
00449 
00450       /// ...  Eventually, add support for alternate expressions here
00451       /// ...  (when equivalence variable does not have to be identical
00452       /// ...  any longer)
00453 
00454       if (array_ptr) {
00455     p_assert(symbol_ptr, "Array map entry but no symbol map "
00456          "entry in _translate_symbol_refs_expr");
00457 
00458     /// ...  We will replace array reference
00459     repl_flag = true;
00460 
00461     /// ...  Delete original expression
00462 
00463     delete expr;
00464 
00465     /// ...  Define new array reference 
00466     Expression     *ref_e 
00467       = array_reference(id(*symbol_ptr), array_ptr->clone());
00468 
00469     /// ...  Absorb ref_e and subs_e as subexpressions of ex
00470     /// ...  Define lambda call expression
00471     Expression *ex
00472       = new LambdaCallExpr(ref_e->type(), ref_e,
00473                    subs_e);
00474 
00475     /// ...  If substring, add it around array reference
00476 
00477     if (substr_ptr)
00478       ex = substring(ex, substr_ptr->clone());
00479 
00480     if (_debug_flag > 19)
00481       cerr << "Replacement of array reference to " << *name_ptr
00482            << " detected with pattern " << *ex << "\n";
00483 
00484     /// ...  Replace whole original expression
00485 
00486     e = ex;
00487       }
00488       else if (symbol_ptr) {
00489 
00490     /// ...  We will replace array reference
00491     repl_flag = true;
00492 
00493     /// ...  If not translating an in-out-expr, look up base variable
00494     /// ...  in alternate map
00495 
00496     const Expression * alternate_ptr = 0;
00497     if (ref != IN_OUT_REF_EXPR)
00498       alternate_ptr = _alternate_map.find_ref(*name_ptr);
00499 
00500     /// ...  If translating an array reference with a single constant
00501     /// ...  subscript and an available alternate expression, translate using
00502     /// ...  the alternate expression with an appropriate intrinsic
00503     /// ...  function around it (eventually, do more general translation)
00504 
00505     Expression & subs_ref = subs_e->arg_list()[0];
00506 
00507     if (alternate_ptr &&
00508         (subs_ref.op() == INTEGER_CONSTANT_OP)) {
00509 
00510       // Copy subscript value
00511 
00512       int subs_val = subs_ref.value();
00513 
00514       // Delete subscript and original expression
00515 
00516       delete subs_e;
00517       delete expr;
00518 
00519       static String real_str("REAL");
00520       static String aimag_str("AIMAG");
00521       static Type func_type(REAL_TYPE, 0);
00522       Expression * func_id_ptr = NULL;
00523       
00524       switch (subs_val) {
00525       case 1: {
00526         /// ...  Create call to "REAL" function
00527         const Symbol * func_ptr = 
00528           _pgm_main.symtab().find_ref(real_str);
00529         if (func_ptr)
00530           func_id_ptr = id(*func_ptr);
00531         else
00532           func_id_ptr = new_intrinsic(real_str, func_type, _pgm_main);
00533         break;
00534       }
00535       case 2: {
00536         /// ...  Create call to "AIMAG" function
00537         const Symbol * func_ptr = 
00538           _pgm_main.symtab().find_ref(aimag_str);
00539         if (func_ptr)
00540           func_id_ptr = id(*func_ptr);
00541         else
00542           func_id_ptr = new_intrinsic(aimag_str, func_type, _pgm_main);
00543         break;
00544       }
00545       default:
00546         p_abort("Invalid subscript encountered in alternate "
00547             "array in _translate_symbol_refs_expr");
00548       }
00549 
00550       e = intrinsic_call(func_id_ptr,comma(alternate_ptr->clone()));
00551 
00552       if (_debug_flag > 19)
00553         cerr << "Replacement of array reference to " << *name_ptr
00554          << " with alternate reference " << *e
00555          << " detected.\n";
00556 
00557     }
00558     else {
00559 
00560       // Put subscript back into original expression
00561     
00562       expr->right(subs_e);
00563 
00564       // Modify original expression in place
00565       expr->array().symbol(*symbol_ptr);
00566 
00567       // If substring, add it around array reference
00568 
00569       if (substr_ptr) {
00570         e = substring(expr, substr_ptr->clone());
00571         if (_debug_flag > 19)
00572           cerr << "Replacement of array reference to " << *name_ptr
00573            << " with substring reference " << *e
00574            << " detected.\n";
00575 
00576       }
00577       else if (_debug_flag > 19)
00578         cerr << "Replacement of array reference to " << *name_ptr
00579          << " with identical reference to " << *symbol_ptr 
00580          << " detected.\n";
00581     }
00582 
00583       }
00584       else {
00585     /// ...  Put subscript back into original expression
00586     expr->right(subs_e);
00587       }
00588       break;
00589     }
00590 
00591   case ID_OP:
00592     {
00593       switch (expr->symbol().sym_class()) {
00594       case VARIABLE_CLASS:{
00595     /// ...  Point at variable
00596     VariableSymbol *name_ptr 
00597       = (VariableSymbol *) & expr->symbol();
00598     /// ...  Look up variable in symbol, array and substring maps
00599     VariableSymbol *symbol_ptr = translate_symbol (*name_ptr);
00600 //  if (! symbol_ptr) {
00601 //      symbol_ptr = new VariableSymbol(*name_ptr);
00602 //      symbol_ptr->relink_dptrs(_pgm_main);
00603 //  }
00604 
00605 //  const SymRefElem *symbol_ref
00606 //    = _symbol_map.find_ref(*name_ptr);
00607 //  if (symbol_ref)
00608 //    symbol_ptr = (VariableSymbol *) &(*symbol_ref->symref());
00609 
00610     const Expression *array_ptr =
00611       _array_map.find_ref(*name_ptr);
00612     const Expression *substr_ptr =
00613       _substring_map.find_ref(*name_ptr);
00614             
00615     if (array_ptr) {
00616       p_assert(symbol_ptr, "Array map entry but no symbol "
00617            "map entry in _translate_symbol_refs_expr");
00618 
00619       if (_debug_flag > 19)
00620         cerr << "Replacement of scalar reference to " 
00621          << *name_ptr
00622          << " with array reference to " << *symbol_ptr
00623          << " with pattern:\n";
00624 
00625       // We will replace ID expression
00626       repl_flag = true;
00627 
00628       // Define new array reference
00629       Expression     *ref_e 
00630         = array_reference(id(*symbol_ptr), 
00631                   array_ptr->clone());
00632 
00633       if (name_ptr->is_array()) {
00634         /// ...  Absorb ref_e as subexpression of ex
00635         /// ...  Define lambda call expression
00636 
00637         Expression *ex 
00638           = new LambdaCallExpr(expr->type(), ref_e,
00639                    initial_array_ref(name_ptr));
00640 
00641         /// ...  If substring, add it around array reference
00642 
00643         if (substr_ptr)
00644           ex = substring(ex, substr_ptr->clone());
00645 
00646         if (_debug_flag > 19)
00647           cerr << *ex << "\n";
00648 
00649         /// ...  Replace whole original expression
00650         delete expr;
00651 
00652         e = ex;
00653       }
00654       else {
00655         /// ...  Replace whole original expression
00656         delete expr;
00657 
00658         /// ...  If substring, add it around array reference
00659 
00660         if (substr_ptr)
00661           ref_e = substring(ref_e, substr_ptr->clone());
00662 
00663         if (_debug_flag > 19)
00664           cerr << *ref_e << "\n";
00665 
00666         e = ref_e;
00667 
00668       }
00669     }
00670     else if (symbol_ptr) {
00671 
00672       // We will replace ID expression
00673       repl_flag = true;
00674 
00675       // Modify original expression in place
00676       expr->symbol(*symbol_ptr);
00677 
00678       // If substring, add it around ID expression
00679 
00680       if (substr_ptr) {
00681         e = substring(expr, substr_ptr->clone());
00682         if (_debug_flag > 19)
00683           cerr << "Replacement of scalar reference to " 
00684            << *name_ptr
00685            << " with substring reference " 
00686            << *e << " detected.\n";
00687       }
00688       else if (_debug_flag > 19)
00689         cerr << "Replacement of scalar reference to " 
00690          << *name_ptr
00691          << " with identical reference to " 
00692          << *symbol_ptr << " detected.\n";
00693 
00694     }
00695     else {
00696         /// ...  Check constant map
00697         const Expression *constant_ptr 
00698         = _constant_map.find_ref(*name_ptr);
00699       
00700         const Expression *actual_ptr = 0;
00701         if (formal_to_actual)
00702         actual_ptr = formal_to_actual->find_ref(*name_ptr);
00703 
00704         if (constant_ptr) {
00705         
00706         /// ...  We will replace ID expression
00707         repl_flag = true;
00708 
00709         /// ...  Replace whole original expression
00710 
00711         delete expr;
00712 
00713         if (_debug_flag > 19)
00714             cerr << "Replacement of scalar reference to " 
00715             << *name_ptr << " with constant " 
00716                 << *constant_ptr << " detected.\n";
00717 
00718         e = constant_ptr->clone();
00719         } else if (actual_ptr) {
00720 
00721         /// ...  We will replace ID expression
00722         repl_flag = true;
00723 
00724         /// ...  Replace whole original expression
00725 
00726         delete expr;
00727 
00728         if (_debug_flag > 19)
00729             cerr << "Replacement of scalar reference to " 
00730             << *name_ptr << " with actual arg " 
00731                 << *actual_ptr << " detected.\n";
00732 
00733         e = actual_ptr->clone();
00734         }
00735     }
00736     break;
00737     }
00738 
00739       case PROGRAM_CLASS:
00740       case FUNCTION_CLASS:
00741       case SUBROUTINE_CLASS:
00742       case SYMBOLIC_CONSTANT_CLASS:
00743       case BLOCK_DATA_CLASS:
00744       case NAMELIST_CLASS:
00745       {
00746           VariableSymbol * symbol_ptr = translate_symbol( expr->symbol() );
00747 //    const SymRefElem    *symbol_ref
00748 //      = _symbol_map.find_ref(expr->symbol());
00749 
00750       if (symbol_ptr) {
00751 
00752         if (_debug_flag > 19)
00753           cerr << "Replacement of symbol reference to " 
00754            << expr->symbol() << " with reference to " 
00755            << *symbol_ptr << " detected.\n";
00756 
00757         /// ...  We will replace ID expression
00758         repl_flag = true;
00759 
00760         /// ...  Modify original expression in place
00761         expr->symbol(*symbol_ptr);
00762       }
00763       break;
00764     }
00765 
00766       default:
00767     p_abort("Invalid symbol encountered in _translate_symbol_refs_expr");
00768       }
00769       break;
00770     }
00771 
00772   case FORMAT_OP:
00773     {
00774       /// ...  Point at format
00775       Format & current_format = expr->format();
00776 
00777       /// ...  Look up format in format map
00778       Format         *new_format_ptr 
00779     = CASTAWAY(Format *) _format_map.find_ref(current_format);
00780 
00781       /// ...  If format is mapped, modify old format in place
00782       if (new_format_ptr) {
00783 
00784     if (_debug_flag > 19)
00785       cerr << "Replacement of format reference " << current_format
00786            << " with identical reference to " << *new_format_ptr
00787            << " detected.\n";
00788 
00789     expr->format(*new_format_ptr);
00790       }
00791       break;
00792     }
00793 
00794   case INTRINSIC_CALL_OP:
00795   case FUNCTION_CALL_OP:
00796     {
00797       /// ...  Handle the LEN intrinsic function with a character argument
00798 
00799       if (expr->op() == INTRINSIC_CALL_OP &&
00800       (strcmp(expr->intrinsic().symbol().tag_ref(),"LEN") == 0) &&
00801       expr->parameters_valid() &&
00802       (expr->parameters_guarded().arg_list()[0].type().data_type()
00803        == CHARACTER_TYPE)) {
00804 
00805     /// ...  Assert that function should have exactly one argument
00806 
00807     List<Expression> & parm_list = expr->parameters_guarded().arg_list();
00808     p_assert((parm_list.entries()==1),
00809          "Invalid number of arguments to LEN function");
00810 
00811     /// ...  Translate argument
00812 
00813     bool local_expr_flag = false;
00814 
00815     Assign<Expression> parm_as(parm_list.assign(0));
00816     parm_as = _translate_symbol_refs_expr(parm_list.pull(0),
00817                           IN_REF_EXPR, local_expr_flag,
00818                           formal_to_actual);
00819     repl_flag |= local_expr_flag;
00820 
00821     /// ...  Check if translated argument is a substring expression
00822 
00823     if (parm_list[0].op() == SUBSTRING_OP) {
00824 
00825       // Build length expression
00826 
00827       List<Expression> & bound_list = parm_list[0].bound().arg_list();
00828       int bound_entries = bound_list.entries();
00829 
00830       // Check if the size of the base variable is known, or, if not,
00831       // that there is an explicit upper bound
00832 
00833       int base_len = parm_list[0].base_variable_ref()->type().size();
00834 
00835       if (base_len ||
00836           ((bound_entries == 2) &&
00837            (bound_list[1].op()!=OMEGA_OP))) {
00838          
00839         /// ...  Substring length can be determined at compile time, so fix
00840         /// ...  up expression
00841 
00842         Expression * le = bound_list.grab(0);
00843 
00844         if (le->op() == OMEGA_OP) {
00845           delete le;
00846           le = constant(1);
00847         }
00848  
00849         Expression * ue;
00850 
00851         if (bound_entries > 1) {
00852           ue = bound_list.grab(0);
00853           if (ue->op()==OMEGA_OP) {
00854         delete ue;
00855         ue = constant(base_len);
00856           }
00857         }
00858         else
00859           ue = constant(base_len);
00860 
00861         /// ...  Delete top-level expression
00862 
00863         delete expr;
00864 
00865         /// ...  Replace expression with calculated expression
00866 
00867         e = add(sub(ue,le),constant(1));
00868 
00869         /// ...  Expression was replaced
00870 
00871         repl_flag = true;
00872 
00873       }
00874     }
00875 
00876     break;
00877       }
00878 
00879       /// ...  If this is an IN_OUT_REF_EXPR, translate argument of pseudo
00880       /// ...  function in place
00881 
00882       else if ((ref == IN_OUT_REF_EXPR) &&
00883            is_pseudo_function(*expr)) {
00884     
00885     /// ...  Indicate that expression was modified
00886     repl_flag = true;
00887 
00888     /// ...  Pull out the subexpression to be translated
00889     Expression     *expr_t 
00890       = expr->parameters_guarded().arg_list().grab(1);
00891 
00892     /// ...  Delete top-level expression
00893     delete expr;
00894 
00895     /// ...  Return translated subexpression
00896     bool local_expr_flag = false;
00897     e = _translate_symbol_refs_expr(expr_t,
00898                     IN_OUT_REF_EXPR, local_expr_flag,
00899                     formal_to_actual);
00900     break;
00901       }
00902 
00903       /// ...  Traverse expressions and replace any which are relevant
00904       /// ...  (but do not use an alternate expression to translate any
00905       /// ...  actual parameter expressions: however, their subexpressions
00906       /// ...  can be translated using an alternate expression)
00907       
00908       for (Mutator<Expression> expr_mutr = expr->arg_list();
00909        expr_mutr.valid(); ++expr_mutr) {
00910     bool local_expr_flag = false;
00911 
00912     Assign<Expression> expr_as(expr_mutr.assign());
00913     expr_as = _translate_symbol_refs_expr(expr_mutr.pull(),
00914                           IN_OUT_REF_EXPR,
00915                           local_expr_flag,
00916                           formal_to_actual);
00917 
00918     repl_flag |= local_expr_flag;
00919       }
00920 
00921       break;
00922     }
00923 
00924   default:
00925     {
00926       /// ...  Traverse expressions and replace any which are relevant
00927       for (Mutator<Expression> expr_mutr = expr->arg_list();
00928        expr_mutr.valid(); ++expr_mutr) {
00929     bool local_expr_flag = false;
00930 
00931     Assign<Expression> expr_as(expr_mutr.assign());
00932     expr_as = _translate_symbol_refs_expr(expr_mutr.pull(),
00933                           IN_REF_EXPR, local_expr_flag,
00934                           formal_to_actual);
00935     repl_flag |= local_expr_flag;
00936       }
00937     }
00938   }
00939 
00940 /// Set final expr_flag
00941   expr_flag |= repl_flag;
00942 
00943   return e;
00944 }
00945 
00946 /// Translate symbol references for GSA within the range of an Expression
00947 /// mutator using the symbol map, returning a count of the number of
00948 /// modifications
00949 
00950 int
00951 TranslateObject::_translate_GSA_symbol_refs_mutr(Mutator<Expression> expr_mutr,
00952                          REF_TYPE ref) const
00953 {
00954   int modify_counter = 0;
00955 
00956   for (; expr_mutr.valid(); ++expr_mutr) {
00957 
00958     /// ...  Remove expression from arg list
00959 
00960     Assign<Expression> ex_as(expr_mutr.assign());
00961     Expression * ex = expr_mutr.pull();
00962 
00963     /// ...  Substitute expression only once
00964 
00965     bool local_expr_flag = false;
00966     ex = _translate_symbol_refs_expr(ex, ref, local_expr_flag);
00967 
00968     /// ...  If this expression was replaced, signal that it was modified
00969 
00970     if (local_expr_flag)
00971       ++modify_counter;
00972 
00973     /// ...  Put expression back into arg list
00974 
00975     ex_as = ex;
00976 
00977   }
00978   return modify_counter;
00979 }
00980 
00981 /// Translate symbol references for GSA within a statement's expression
00982 /// list using the symbol map
00983 
00984 void 
00985 TranslateObject::_translate_GSA_symbol_refs_stmt(Statement & s) const
00986 {
00987 /// Iterate over all statement expressions
00988   bool modify_flag = false;
00989 
00990 /// Iterate over any expressions in an assertion
00991 /// (note: do not keep track of assertion modifications,
00992 /// because they do not require any cleanup processing)
00993 
00994   for (Iterator<Assertion> assert_iter = s.assertions();
00995        assert_iter.valid(); ++assert_iter) {
00996 
00997     Assertion & current_assert = assert_iter.current();
00998     /// ...    AssertionType current_type = current_assert.type();
00999 
01000     if (current_assert.arg_list_valid())
01001       _translate_GSA_symbol_refs_mutr(Mutator<Expression>(current_assert.arg_list_guarded()),
01002                       IN_REF_EXPR);
01003 
01004   }
01005 
01006 /// Iterate over any s_control expressions in an I/O statement
01007 /// (keep track of modifications)
01008 
01009   if (s.s_control_valid()) {
01010     for (Iterator<s_control_type> s_iter = s.s_control_guarded();
01011      s_iter.valid(); ++s_iter) {
01012       if (_translate_GSA_symbol_refs_mutr(Mutator<Expression>(s_iter.current().expr),
01013                       IN_REF_EXPR))
01014     modify_flag = true;
01015     }
01016   }
01017 
01018 /// Iterate over in, out, and in out ref expressions
01019 /// (keep track of modifications)
01020 
01021   if (s.iterate_in_exprs_valid() &&
01022       _translate_GSA_symbol_refs_mutr(s.iterate_in_exprs_guarded(),
01023                       IN_REF_EXPR)) {
01024       modify_flag = true;
01025   }
01026 
01027   if (s.iterate_out_exprs_valid() &&
01028       _translate_GSA_symbol_refs_mutr(s.iterate_out_exprs_guarded(),
01029                       OUT_REF_EXPR)) {
01030       modify_flag = true;
01031   }
01032 
01033   if (s.iterate_in_out_exprs_valid() &&
01034       _translate_GSA_symbol_refs_mutr(s.iterate_in_out_exprs_guarded(),
01035                       IN_OUT_REF_EXPR)) {
01036       modify_flag = true;
01037   }
01038 
01039   if (s.access_table_exists())
01040       s.access_table().translate_GSA_symbols( (TranslateObject *)this );
01041   
01042 /// If body of statement was modified, rebuild references
01043 
01044   if (modify_flag)
01045       s.build_refs();
01046 }
01047 
01048 /// Check to see if an assignment statement is an identity assignment
01049 
01050 bool
01051 TranslateObject::_is_identity_assignment(const Statement &s) const
01052 {
01053   const Expression & lhs_expr = s.lhs();
01054   const Expression & rhs_expr = s.rhs();
01055 
01056 /// See if assignment is one variable to another
01057 
01058   if (lhs_expr.op()!=ID_OP ||
01059       rhs_expr.op()!=ID_OP)
01060     return false;
01061     
01062 /// See if symbol on left side is to be translated
01063 
01064   const Symbol & lhs_sym = s.lhs().symbol();
01065   const VariableSymbol * lhs_symbol = translate_symbol( lhs_sym );
01066 
01067 ///  const SymRefElem * lhs_data_ref
01068 ///    = _symbol_map.find_ref(lhs_sym);
01069 ///  if (!lhs_data_ref)
01070   if (lhs_symbol == 0)
01071       return false;
01072 
01073 /// See if symbol on right hand side is to be translated
01074 
01075   const Symbol & rhs_sym = s.rhs().symbol();
01076   
01077   const VariableSymbol * rhs_symbol = translate_symbol( rhs_sym );
01078 ///  const SymRefElem * rhs_data_ref
01079 ///    = _symbol_map.find_ref(rhs_sym);
01080 ///  if (!rhs_data_ref)
01081   if (rhs_symbol == 0)
01082       return false;
01083 
01084 /// See if each symbol translates to the same base symbol
01085 
01086   return (lhs_symbol == rhs_symbol);
01087 }
01088 
01089 /// Translate contained GSA symbol references using the symbol map
01090 /// and remove all GSA symbols from the program
01091 
01092 void 
01093 TranslateObject::translate_GSA_symbol_refs()
01094 {
01095   if (_symbol_map.entries()) {
01096 
01097     /// ...  Create set of statements to delete for GSA translation
01098 
01099     RefSet<Statement> gsa_set;
01100 
01101     /// ...  Translate each statement
01102 
01103     for (Iterator<Statement> stmt_iter = _pgm_ref->stmts().iterator();
01104      stmt_iter.valid(); ++stmt_iter) {
01105       Statement & s = stmt_iter.current();
01106       switch (s.stmt_class()) {
01107       case ASSIGNMENT_STMT: {
01108     Expression & rhs = s.rhs();
01109     if (is_pseudo_function(rhs)) {
01110       if (rhs.op() == ALPHA_OP) {
01111         /// ...  Pull out the subexpression to be translated
01112             Expression     *rhs_t 
01113           = rhs.parameters_guarded().arg_list().grab(1);
01114         /// ...  Replace RHS by this subexpression
01115         s.rhs(rhs_t);
01116         /// ...  Fall through to translation code, relying on it
01117         /// ...  to rebuild statement references (which it should)
01118       }
01119       // Do not translate, and mark for later deletion
01120       else {
01121         gsa_set.ins(s);
01122         break;
01123       }
01124     }
01125     /// ...  Mark identity assignment for later deletion
01126     else if (_is_identity_assignment(s)) {
01127       gsa_set.ins(s);
01128       break;
01129     }
01130       }
01131       default:
01132     _translate_GSA_symbol_refs_stmt(s);
01133       }
01134     }
01135 
01136     /// ...  Delete any pseudo-assignment statements
01137 
01138     _pgm_ref->stmts().del(gsa_set);
01139 
01140     /// ...  Now, go through symbol map and delete all the GSA symbols, because
01141     /// ...  they are no longer in use
01142 
01143     for (KeyIterator<Symbol,SymRefElem> key_iter = _symbol_map;
01144      key_iter.valid(); ++key_iter) {
01145     if ((key_iter.current_key().sym_class() == VARIABLE_CLASS) &&
01146         ((VariableSymbol &)(key_iter.current_key())).is_gsa_symbol()) {
01147         _pgm_ref->symtab().del(key_iter.current_key().name_ref());
01148     }
01149     }
01150 
01151     /// ...  Clear out symbol map now, because it is full of invalid data
01152     _symbol_map.clear();
01153   }
01154 }
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:06:15 2005