00001
00002
00003
00004
00005
00006
00007
00008 #ifdef POLARIS_GNU_PRAGMAS
00009 #pragma implementation
00010 #endif
00011
00012 #include "InlineObject.h"
00013
00014 #include <stdio.h>
00015 #include <strstream.h>
00016
00017 #include "AbstractAccess.h"
00018 #include "Collection/KeySet.h"
00019 #include "CommonBlock.h"
00020 #include "Directive/AssertComment.h"
00021 #include "Directive/AssertPrivate.h"
00022 #include "Directive/AssertRelation.h"
00023
00024 #include "Directive/AssertRecursiveInline.h"
00025 #include "Directive/Assertion.h"
00026 #include "Equivalence.h"
00027 #include "Expression/expr_funcs.h"
00028 #include "Expression/ArgNumberExpr.h"
00029 #include "Expression/IntConstExpr.h"
00030 #include "Expression/LambdaCallExpr.h"
00031 #include "Expression/LogicalConstExpr.h"
00032 #include "FormatDB.h"
00033 #include "Info.h"
00034 #include "IntElem.h"
00035 #include "LabelDB.h"
00036 #include "ProgramUnit.h"
00037 #include "Statement/AssignmentStmt.h"
00038 #include "Statement/GotoStmt.h"
00039 #include "Statement/LabelStmt.h"
00040 #include "StmtList.h"
00041 #include "Symbol/FunctionSymbol.h"
00042 #include "Symbol/VariableSymbol.h"
00043 #include "TranslateObject.h"
00044 #include "Wildcard/AnyOfType.h"
00045 #include "Wildcard/WildcardOr.h"
00046 #include "utilities/StmtInfo.h"
00047 #include "utilities/access_util.h"
00048 #include "utilities/entry_util.h"
00049 #include "utilities/intrinsic_util.h"
00050 #include "utilities/lambda_util.h"
00051 #include "utilities/precalc_util.h"
00052 #include "utilities/program_util.h"
00053 #include "utilities/removegotos_util.h"
00054 #include "utilities/stmt_util.h"
00055 #include "utilities/string_util.h"
00056 #include "utilities/switches_util.h"
00057 #include "utilities/symbol_util.h"
00058
00059 #include "Constant/constant.h"
00060 #include "Deadcode/deadcode.h"
00061
00062 template class TypedBaseMap<ProgramUnit,InlineObject>;
00063 template class ProtoMap<ProgramUnit,InlineObject>;
00064 template class Map<ProgramUnit,InlineObject>;
00065 template ostream & operator << (ostream &,
00066 const Map<ProgramUnit,InlineObject> &);
00067 template class KeyIterator<ProgramUnit,InlineObject>;
00068
00069 template class Assign<InlineWorkSpace>;
00070 template class Element<InlineWorkSpace>;
00071 template ostream & operator << (ostream &,
00072 const Element<InlineWorkSpace> &);
00073 template class RefElement<InlineWorkSpace>;
00074 template ostream & operator << (ostream &,
00075 const RefElement<InlineWorkSpace> &);
00076
00077 void
00078 InlineWorkSpace::print(ostream & o) const
00079 {
00080 if (_count_active) {
00081 o << "(<" <<
00082 _exec_lines_input << ", " << _exec_lines_output << ">, <" <<
00083 _total_lines_input << ", " << _total_lines_output << ">)";
00084 }
00085 else
00086 o << "(<false>)";
00087 }
00088
00089 struct VariableSizes {
00090 int size;
00091 int elem_size;
00092
00093 inline VariableSizes(VariableSymbol & var);
00094 inline void remap(VariableSymbol & var);
00095 };
00096
00097 inline
00098 VariableSizes::VariableSizes(VariableSymbol & var)
00099 {
00100 size = var.size();
00101 elem_size = var.type().size();
00102 }
00103
00104 inline void
00105 VariableSizes::remap(VariableSymbol & var)
00106 {
00107 size = var.size();
00108 elem_size = var.type().size();
00109 }
00110
00111 enum CONFORM_TYPE {
00112 IDENTICAL,
00113 TRANSFORMABLE_CONSTANT,
00114 TRANSFORMABLE_ARRAY,
00115 TRANSFORMABLE_SUBSTRING,
00116 TRANSFORMABLE_SUBSTRING_ARRAY,
00117 NON_CONFORMABLE
00118 };
00119
00120 void
00121 InlineObject::print(ostream & o) const
00122 {
00123 TranslateObject::print(o);
00124
00125 if (_ws_ref.valid()) {
00126 o << "\nInline workspace:\n\n";
00127 o << *_ws_ref;
00128 }
00129 }
00130
00131
00132
00133
00134 void
00135 InlineObject::_remap_and_move_formats()
00136 {
00137
00138
00139
00140 for (KeyIterator<int,Format> db_iter = _pgm_ref->formats();
00141 db_iter.valid(); ++db_iter) {
00142 Format & current_format = db_iter.current_data();
00143 int format_label = current_format.value();
00144
00145
00146
00147
00148 while (1) {
00149
00150 int label_save = format_label;
00151 format_label = _pgm_main.stmts().new_label(label_save);
00152 if (format_label == label_save)
00153 break;
00154 label_save = format_label;
00155 format_label = _pgm_ref->stmts().new_label(label_save);
00156 if (format_label == label_save)
00157 break;
00158 }
00159
00160
00161
00162 if (format_label != current_format.value())
00163 _pgm_ref->formats().relabel(current_format.value(),format_label);
00164
00165
00166
00167 Format * cloned_format = (Format *) current_format.listable_clone();
00168 _pgm_main.formats().ins(cloned_format);
00169
00170
00171
00172 _format_map.ins(current_format, *cloned_format);
00173 }
00174 }
00175
00176
00177
00178 void
00179 InlineObject::_precalc_adjustable_array_bounds()
00180 {
00181 StmtInfo arg_map;
00182
00183 arg_map.program_ref = _pgm_ref;
00184
00185
00186
00187 for (Iterator<Statement> entry_iter
00188 = _pgm_ref->stmts().iterate_entry_points();
00189 entry_iter.valid(); ++entry_iter) {
00190
00191
00192 Statement *c = &entry_iter.current();
00193
00194
00195
00196 if ((c->stmt_class() == FLOW_ENTRY_STMT) || (!c->parameters_valid()))
00197 continue;
00198
00199
00200
00201 arg_map.stmt_ref = c->next_ref();
00202
00203 {
00204
00205
00206
00207
00208
00209 for (Iterator<Expression> parm_iter
00210 = c->parameters_guarded().arg_list();
00211 parm_iter.valid(); ++parm_iter) {
00212 p_assert(parm_iter.current().op() == ID_OP,
00213 "Bad entry parmlist in precalc_adjustable_array_bounds");
00214
00215 Symbol & parm_symbol = parm_iter.current().symbol();
00216
00217 if (parm_symbol.sym_class() == VARIABLE_CLASS) {
00218
00219 for (Iterator<ArrayBounds> bound_iter = parm_symbol.dim();
00220 bound_iter.valid();
00221 ++bound_iter) {
00222 ArrayBounds & current_bound = bound_iter.current();
00223
00224 if (current_bound.lower_exists()) {
00225 Expression & lb = current_bound.lower_guarded();
00226
00227 if (lb.op() != INTEGER_CONSTANT_OP) {
00228 Assign<Expression> lb_as (
00229 current_bound.arg_list().assign(lb));
00230 lb_as = get_precalc(current_bound.arg_list().pull(lb),
00231 *arg_map.program_ref,
00232 *arg_map.stmt_ref,
00233 PRECALC_ALWAYS, "PC");
00234 }
00235 }
00236
00237 if (current_bound.upper_exists()) {
00238 Expression & ub = current_bound.upper_guarded();
00239
00240 if (ub.op() != INTEGER_CONSTANT_OP) {
00241 Assign<Expression> ub_as (
00242 current_bound.arg_list().assign(ub));
00243 ub_as = get_precalc(current_bound.arg_list().pull(ub),
00244 *arg_map.program_ref,
00245 *arg_map.stmt_ref,
00246 PRECALC_ALWAYS, "PC");
00247 }
00248 }
00249 }
00250 }
00251 }
00252 }
00253 }
00254 }
00255
00256
00257
00258
00259 void
00260 InlineObject::_expand_IO_array_names()
00261
00262 {
00263
00264
00265 for (Iterator<Statement> IO_iter
00266 = _pgm_ref->stmts().stmts_of_type(READ_STMT, WRITE_STMT, PRINT_STMT);
00267 IO_iter.valid(); ++IO_iter) {
00268 Statement & s = IO_iter.current();
00269
00270
00271
00272 if (s.io_list_valid()) {
00273 for (Mutator<Expression> expr_mutr = s.io_list_guarded().arg_list();
00274 expr_mutr.valid(); ++expr_mutr) {
00275 Expression & expr = expr_mutr.current();
00276 IntConstExpr cstone(1);
00277
00278 if (expr.op() != ID_OP)
00279 continue;
00280
00281 Symbol & sym = expr.symbol();
00282
00283 if (sym.sym_class() != VARIABLE_CLASS)
00284 continue;
00285
00286 if (sym.is_array()) {
00287
00288 ArrayDims & dim = sym.dim();
00289
00290
00291
00292 Type int_type = make_type(INTEGER_TYPE);
00293 Expression *array_expr
00294 = array_reference(expr.clone(), comma());
00295 Expression *current_expr = array_expr;
00296
00297 for (Iterator<ArrayBounds> bound_iter = dim;
00298 bound_iter.valid();
00299 ++bound_iter) {
00300 ArrayBounds & current_bound = bound_iter.current();
00301 Expression * bound_lb = current_bound.lower_ref();
00302
00303 if (!bound_lb)
00304 bound_lb = &cstone;
00305
00306 Expression *bound_ub = current_bound.upper_ref();
00307
00308 if (!bound_ub)
00309 bound_ub = &cstone;
00310
00311 Expression *var_comma_expr
00312 = comma(bound_lb->clone(), bound_ub->clone());
00313
00314
00315
00316 Symbol *var_sym
00317 = new VariableSymbol("PV", int_type,
00318 NOT_FORMAL, NOT_SAVED);
00319
00320
00321
00322 _pgm_ref->symtab().rename_and_ins(var_sym);
00323
00324
00325
00326
00327 array_expr->subscript().arg_list().ins_last(id(*var_sym));
00328
00329
00330
00331 Expression *var_eq_expr
00332 = equal(id(*var_sym), var_comma_expr);
00333
00334
00335
00336 current_expr
00337 = do_expression(comma(current_expr), var_eq_expr);
00338
00339 }
00340
00341
00342
00343 expr_mutr.modify(current_expr);
00344
00345 }
00346 }
00347 }
00348 }
00349 }
00350
00351
00352
00353
00354
00355 void
00356 InlineObject::_remap_variable_symbol(Symbol & current_symbol,
00357 RefList<Symbol>&rename_list)
00358 {
00359
00360
00361
00362 const char *sym_name = current_symbol.name_ref();
00363
00364 if ((int) _pgm_main.symtab().find_ref(sym_name) ||
00365 (int) lookup_intrinsic(sym_name)) {
00366 rename_list.ins_last(current_symbol);
00367 }
00368 else {
00369
00370
00371
00372 Symbol *new_symbol_ptr
00373 = current_symbol.clone();
00374
00375 _pgm_main.symtab().ins(new_symbol_ptr);
00376
00377
00378
00379
00380 PRIVAT_TYPE priv_type = NOT_PRIVATE;
00381
00382 if(current_symbol.saved()==NOT_SAVED) {
00383 priv_type = PRIVATE;
00384 _private_vars++;
00385 }
00386
00387
00388
00389
00390 PRECALC_TYPE prec_type = NOT_PRECALC_VAR;
00391
00392 const Type & current_type = current_symbol.type();
00393
00394 if ((current_type.data_type() == INTEGER_TYPE) &&
00395 (current_type.is_scalar()) &&
00396 (strncmp(current_symbol.name_ref(),"PC",2) == 0)) {
00397 prec_type = CAND_PRECALC_VAR;
00398 _precalc_vars++;
00399 }
00400
00401 _symbol_map.ins(current_symbol,
00402 new SymRefElem(*new_symbol_ptr, priv_type,
00403 prec_type));
00404
00405
00406 }
00407 }
00408
00409
00410
00411
00412 void
00413 InlineObject::_remap_unvalued_symbol(Symbol & current_symbol)
00414 {
00415 Symbol * new_symbol_ptr = NULL;
00416
00417
00418
00419 Symbol *main_symbol_ptr
00420 = _pgm_main.symtab().grab(current_symbol.name_ref());
00421
00422 if (!main_symbol_ptr) {
00423
00424
00425
00426
00427 new_symbol_ptr = current_symbol.clone();
00428 _pgm_main.symtab().ins(new_symbol_ptr);
00429 }
00430 else {
00431
00432
00433
00434 switch (main_symbol_ptr->sym_class()) {
00435
00436 case VARIABLE_CLASS:
00437 case SYMBOLIC_CONSTANT_CLASS:
00438
00439 {
00440
00441
00442
00443
00444
00445 new_symbol_ptr = current_symbol.clone();
00446 _pgm_main.symtab().ins(new_symbol_ptr);
00447
00448
00449
00450
00451 _pgm_main.symtab().rename_and_ins(main_symbol_ptr);
00452 break;
00453 }
00454
00455 case FUNCTION_CLASS:
00456 case SUBROUTINE_CLASS:
00457 case PROGRAM_CLASS:
00458 case BLOCK_DATA_CLASS:
00459 case NAMELIST_CLASS:
00460
00461 {
00462
00463
00464
00465
00466
00467
00468 new_symbol_ptr = main_symbol_ptr;
00469
00470
00471
00472 _pgm_main.symtab().ins(main_symbol_ptr);
00473
00474 break;
00475 }
00476 default: break;
00477 }
00478 }
00479
00480
00481
00482 _symbol_map.ins(current_symbol,
00483 new SymRefElem(*new_symbol_ptr));
00484
00485 }
00486
00487
00488
00489
00490
00491 void
00492 InlineObject::_remap_variable_symbols(RefList<Symbol>&rename_list)
00493 {
00494 for (Iterator<Symbol> rename_iter = rename_list;
00495 rename_iter.valid(); ++rename_iter) {
00496
00497
00498
00499
00500 Symbol & current_symbol = rename_iter.current();
00501 Symbol * new_symbol_ptr = current_symbol.clone();
00502
00503 _pgm_main.symtab().rename_and_ins(new_symbol_ptr);
00504
00505
00506
00507
00508 PRIVAT_TYPE priv_type = NOT_PRIVATE;
00509
00510 if(current_symbol.saved()==NOT_SAVED) {
00511 priv_type = PRIVATE;
00512 _private_vars++;
00513 }
00514
00515
00516
00517
00518 PRECALC_TYPE prec_type = NOT_PRECALC_VAR;
00519
00520 const Type & current_type = current_symbol.type();
00521
00522 if ((current_type.data_type() == INTEGER_TYPE) &&
00523 (current_type.is_scalar()) &&
00524 (strncmp(current_symbol.name_ref(),"PC",2) == 0)) {
00525 prec_type = CAND_PRECALC_VAR;
00526 _precalc_vars++;
00527 }
00528
00529 _symbol_map.ins(current_symbol,
00530 new SymRefElem(*new_symbol_ptr, priv_type,
00531 prec_type));
00532
00533 }
00534 }
00535
00536 void
00537 InlineObject::_remap_local_variables()
00538 {
00539
00540 RefList<Symbol> rename_list;
00541 RefList<Symbol> symbolic_list;
00542
00543 for (DictionaryIter<Symbol> sym_iter = _pgm_ref->symtab().iterator();
00544 sym_iter.valid(); ++sym_iter) {
00545 Symbol & current_symbol = sym_iter.current();
00546
00547 switch (current_symbol.sym_class()) {
00548 case VARIABLE_CLASS:
00549 {
00550 if ((!current_symbol.formal()) &&
00551 (!current_symbol.equivalence_ref()) &&
00552 (!current_symbol.common_ref()))
00553 _remap_variable_symbol(current_symbol, rename_list);
00554 break;
00555 }
00556
00557 case FUNCTION_CLASS:
00558 case SUBROUTINE_CLASS:
00559 case PROGRAM_CLASS:
00560 case BLOCK_DATA_CLASS:
00561 case NAMELIST_CLASS:
00562 {
00563 _remap_unvalued_symbol(current_symbol);
00564 break;
00565 }
00566
00567 case SYMBOLIC_CONSTANT_CLASS:
00568 {
00569 Symbol & main_symbol =
00570 rename_variable_to_match(*_pgm_ref, current_symbol,
00571 _pgm_main, current_symbol.clone());
00572 _symbol_map.ins(current_symbol,
00573 new SymRefElem(main_symbol));
00574 symbolic_list.ins_last(main_symbol);
00575 break;
00576 }
00577
00578 default: break;
00579 }
00580 }
00581
00582
00583
00584 if(rename_list.entries())
00585 _remap_variable_symbols(rename_list);
00586
00587
00588
00589
00590 for(Iterator<Symbol> symbolic_iter = symbolic_list;
00591 symbolic_iter.valid(); ++ symbolic_iter) {
00592 symbolic_iter.current().relink_dptrs(_pgm_main);
00593 }
00594 }
00595
00596
00597
00598
00599 void
00600 InlineObject::_rename_branch_targets()
00601 {
00602
00603 StmtList & stmts = _pgm_ref->stmts();
00604 StmtList & main_stmts = _pgm_main.stmts();
00605
00606
00607
00608 int label_number = stmts.labels().first_ref();
00609
00610 while (label_number) {
00611
00612
00613
00614
00615 int old_label_number = label_number;
00616
00617 while (1) {
00618
00619 int label_save = label_number;
00620 label_number = main_stmts.new_label(label_save);
00621 if (label_number == label_save)
00622 break;
00623 label_save = label_number;
00624 label_number = stmts.new_label(label_save);
00625 if (label_number == label_save)
00626 break;
00627 }
00628
00629
00630
00631 if (label_number != old_label_number)
00632 stmts.relabel(old_label_number,label_number);
00633
00634
00635
00636
00637 label_number = stmts.labels().successor_ref(old_label_number);
00638
00639 }
00640
00641 }
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 static CONFORM_TYPE
00664 conformable_test(VariableSymbol * name_ptr, Expression & main_expr,
00665 bool equivalent_var_generated)
00666 {
00667 Symbol *main_name_ptr = 0;
00668 Expression *main_subs_ptr = 0;
00669 Expression *main_bound_ptr = 0;
00670
00671
00672
00673 switch (main_expr.op()) {
00674 case INTEGER_CONSTANT_OP:
00675 case REAL_CONSTANT_OP:
00676 case LOGICAL_CONSTANT_OP:
00677
00678 if (main_expr.type() == name_ptr->type())
00679 return TRANSFORMABLE_CONSTANT;
00680 else
00681 return NON_CONFORMABLE;
00682
00683 case ID_OP:
00684 {
00685 main_name_ptr = main_expr.base_variable_ref();
00686
00687 if (main_name_ptr->sym_class() == SYMBOLIC_CONSTANT_CLASS) {
00688 if (main_name_ptr->type() == name_ptr->type())
00689 return IDENTICAL;
00690 else
00691 return NON_CONFORMABLE;
00692 }
00693 break;
00694 }
00695
00696 case ARRAY_REF_OP:
00697 {
00698 main_name_ptr = main_expr.base_variable_ref();
00699 main_subs_ptr = &main_expr.subscript();
00700 break;
00701 }
00702
00703 case SUBSTRING_OP:
00704 {
00705 main_bound_ptr = &main_expr.bound();
00706 Expression & main_string_expr = main_expr.string();
00707 main_name_ptr = main_string_expr.base_variable_ref();
00708 if (main_string_expr.op()==ARRAY_REF_OP)
00709 main_subs_ptr = &main_string_expr.subscript();
00710 break;
00711 }
00712
00713 default:
00714 p_abort("Illegal expression detected in conformable_test");
00715 }
00716
00717
00718
00719
00720
00721 bool transformable = ((!name_ptr->common_ref()) ||
00722 (!name_ptr->equivalence_ref()) ||
00723 equivalent_var_generated);
00724
00725 const Type & name_type = name_ptr->type();
00726 const Type & main_name_type = main_name_ptr->type();
00727
00728
00729
00730
00731 if ((name_type.data_type() == CHARACTER_TYPE) && (name_type.size() == 0)) {
00732 if (main_name_type.data_type() == CHARACTER_TYPE) {
00733 if (!main_bound_ptr)
00734 return IDENTICAL;
00735 else
00736 return TRANSFORMABLE_SUBSTRING;
00737 }
00738 else
00739 return NON_CONFORMABLE;
00740 }
00741
00742
00743
00744 if ((name_type.data_type() != main_name_type.data_type()) ||
00745 (name_type.size() != main_name_type.size()))
00746 return NON_CONFORMABLE;
00747
00748
00749
00750
00751
00752
00753
00754 ArrayDims & name_dim = name_ptr->dim();
00755 int name_dims = name_dim.entries();
00756
00757 ArrayDims & main_name_dim = main_name_ptr->dim();
00758 int main_name_dims = main_name_dim.entries();
00759
00760
00761
00762 if ((name_dims == 0) && (main_name_dims == 0)) {
00763 if (!main_bound_ptr)
00764 return IDENTICAL;
00765 else
00766 return TRANSFORMABLE_SUBSTRING;
00767 }
00768
00769
00770
00771 CONFORM_TYPE conformable;
00772
00773 if (!main_bound_ptr)
00774 conformable = IDENTICAL;
00775 else
00776 conformable = TRANSFORMABLE_SUBSTRING;
00777
00778
00779
00780 if ((name_dims != 0) && (main_name_dims != 0)) {
00781
00782
00783 if (name_dims == main_name_dims) {
00784
00785
00786 IntConstExpr cstone(1);
00787
00788 Iterator<ArrayBounds> name_iter = name_dim;
00789 Iterator<ArrayBounds> main_name_iter = main_name_dim;
00790
00791 List<Expression> dummy_list;
00792 List<Expression> *main_subs_listptr = &dummy_list;
00793
00794 if (main_subs_ptr)
00795 main_subs_listptr = &main_subs_ptr->arg_list();
00796
00797 Iterator<Expression> main_subs_iter(*main_subs_listptr);
00798
00799 for (int i = 0; i<name_dims; ++i) {
00800 Expression *name_lb = name_iter.current().lower_ref();
00801
00802 if (!name_lb)
00803 name_lb = &cstone;
00804
00805 Expression *name_ub = name_iter.current().upper_ref();
00806
00807 if (!name_ub)
00808 name_ub = &cstone;
00809
00810 Expression *main_name_lb = main_name_iter.current().lower_ref();
00811
00812 if (!main_name_lb)
00813 main_name_lb = &cstone;
00814
00815 Expression *main_name_ub = main_name_iter.current().upper_ref();
00816
00817 if (!main_name_ub)
00818 main_name_ub = &cstone;
00819
00820 Expression *main_name_offptr;
00821
00822
00823
00824 if (main_subs_ptr) {
00825 main_name_offptr =
00826 simplify(sub(main_subs_iter.current().clone(),
00827 main_name_lb->clone()));
00828
00829
00830
00831
00832 if ((i != name_dims - 1) &&
00833 ((main_name_offptr->op() != INTEGER_CONSTANT_OP) ||
00834 (main_name_offptr->value() != 0))) {
00835 delete main_name_offptr;
00836 return NON_CONFORMABLE;
00837 }
00838
00839 delete main_name_offptr;
00840 main_name_offptr = main_subs_iter.current().clone();
00841 }
00842 else {
00843
00844 main_name_offptr = main_name_lb->clone();
00845 }
00846
00847 Expression *offset
00848 = simplify(sub(sub(main_name_ub->clone(),
00849 main_name_offptr->clone()),
00850 sub(name_ub->clone(), name_lb->clone())));
00851
00852 if ((offset->op() != INTEGER_CONSTANT_OP) ||
00853 (offset->value() != 0)) {
00854 delete main_name_offptr;
00855 delete offset;
00856
00857 if (transformable &&
00858 (i == main_name_dims - 1)) {
00859 if (!main_bound_ptr)
00860 return TRANSFORMABLE_ARRAY;
00861 else
00862 return TRANSFORMABLE_SUBSTRING_ARRAY;
00863 }
00864 else
00865 return NON_CONFORMABLE;
00866 }
00867
00868 delete offset;
00869
00870
00871
00872 offset = simplify(sub(main_name_offptr, name_lb->clone()));
00873
00874 if ((offset->op() != INTEGER_CONSTANT_OP) ||
00875 (offset->value() != 0)) {
00876 if (!main_bound_ptr)
00877 conformable = TRANSFORMABLE_ARRAY;
00878 else
00879 conformable = TRANSFORMABLE_SUBSTRING_ARRAY;
00880 }
00881
00882 delete offset;
00883
00884
00885
00886 ++name_iter;
00887 ++main_name_iter;
00888
00889 if (main_subs_ptr)
00890 ++main_subs_iter;
00891 }
00892 if (transformable)
00893 return conformable;
00894 else
00895 return NON_CONFORMABLE;
00896 }
00897 else {
00898
00899 if (transformable &&
00900 (main_name_dims == 1)) {
00901 if (!main_bound_ptr)
00902 return TRANSFORMABLE_ARRAY;
00903 else
00904 return TRANSFORMABLE_SUBSTRING_ARRAY;
00905 }
00906 }
00907 }
00908 else {
00909
00910 if (transformable &&
00911 (name_dims == 0)) {
00912 if (!main_bound_ptr)
00913 return TRANSFORMABLE_ARRAY;
00914 else
00915 return TRANSFORMABLE_SUBSTRING_ARRAY;
00916 }
00917 }
00918
00919 return NON_CONFORMABLE;
00920 }
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930 Expression *
00931 InlineObject::_linearize_array_ref(VariableSymbol * src_name_ptr,
00932 Expression * src_subs_ptr,
00933 VariableSymbol * tgt_name_ptr)
00934 {
00935
00936
00937
00938 ArrayDims & src_dim = src_name_ptr->dim();
00939 int src_dims = src_dim.entries();
00940
00941 ArrayDims & tgt_dim = tgt_name_ptr->dim();
00942
00943
00944 List<Expression> & src_subs_list = src_subs_ptr->arg_list();
00945
00946
00947
00948 Expression *src_exl;
00949 Expression *src_exu;
00950 Expression *tgt_exl;
00951 Expression *offset;
00952
00953 if (src_dims>1) {
00954 src_exl = src_dim[src_dims - 1].lower_ref();
00955
00956 if (src_exl)
00957 src_exl = src_exl->clone();
00958 else
00959 src_exl = constant(1);
00960
00961
00962
00963 offset = sub(src_subs_list[src_dims - 1].clone(), src_exl);
00964
00965 for (int i = src_dims - 2; i>0; --i) {
00966 src_exl = src_dim[i].lower_ref();
00967
00968 if (src_exl)
00969 src_exl = src_exl->clone();
00970 else
00971 src_exl = constant(1);
00972
00973 src_exu = src_dim[i].upper_ref();
00974
00975 if (src_exu)
00976 src_exu = src_exu->clone();
00977 else
00978 src_exu = constant(1);
00979
00980
00981
00982 offset = add(mul(add(sub(src_exu, src_exl), constant(1)),
00983 offset),
00984 sub(src_subs_list[i].clone(), src_exl->clone()));
00985 }
00986 }
00987 else {
00988 offset = constant(0);
00989 }
00990
00991 src_exl = src_dim[0].lower_ref();
00992
00993 if (src_exl)
00994 src_exl = src_exl->clone();
00995 else
00996 src_exl = constant(1);
00997
00998 src_exu = src_dim[0].upper_ref();
00999
01000 if (src_exu)
01001 src_exu = src_exu->clone();
01002 else
01003 src_exu = constant(1);
01004
01005
01006
01007 offset = add(mul(add(sub(src_exu, src_exl), constant(1)),
01008 offset),
01009 sub(src_subs_list[0].clone(), src_exl->clone()));
01010
01011
01012
01013 int src_name_size = src_name_ptr->type().size();
01014 int tgt_name_size = tgt_name_ptr->type().size();
01015
01016 Expression * test_expr;
01017
01018 if (tgt_name_size > src_name_size) {
01019
01020 p_assert(!(tgt_name_size % src_name_size),
01021 "Non-conformable sizes encountered in _linearize_array_ref");
01022
01023
01024
01025 Expression * divisor = constant(tgt_name_size / src_name_size);
01026
01027
01028
01029 Symbol *mod_sym = _pgm_main.symtab().find_ref("MOD");
01030
01031 if (! mod_sym) {
01032 mod_sym = new FunctionSymbol("MOD", make_type(INTEGER_TYPE),
01033 NOT_EXTERNAL, IS_INTRINSIC, NOT_FORMAL);
01034 _pgm_main.symtab().ins(mod_sym);
01035 }
01036
01037 test_expr = intrinsic_call(id(*mod_sym),
01038 comma(offset->clone(), divisor->clone()));
01039 test_expr->type(offset->type());
01040
01041 test_expr = eq(test_expr,constant(0));
01042
01043
01044
01045 offset = div(offset, divisor);
01046
01047 }
01048
01049 else {
01050
01051 if (src_name_size > tgt_name_size) {
01052
01053 p_assert(!(src_name_size % tgt_name_size),
01054 "Non-conformable sizes encountered in _linearize_array_ref");
01055
01056
01057
01058 offset = mul(offset, constant(src_name_size / tgt_name_size));
01059
01060 }
01061 test_expr = new LogicalConstExpr(".TRUE.");
01062 }
01063
01064
01065 tgt_exl = tgt_dim[0].lower_ref();
01066
01067 if (tgt_exl)
01068 tgt_exl = tgt_exl->clone();
01069 else
01070 tgt_exl = constant(1);
01071
01072
01073
01074 offset = add(offset, tgt_exl);
01075
01076
01077
01078 return comma(offset,test_expr);
01079 }
01080
01081
01082
01083
01084
01085 static Expression *
01086 unlinearize_array_ref(VariableSymbol * src_name_ptr, int src_offset)
01087 {
01088 int lb_size_array[7];
01089 int src_size_array[7];
01090 int i = 0;
01091 int src_size = 1;
01092 Iterator<ArrayBounds> array_iter(src_name_ptr->dim());
01093
01094 for ( ; array_iter.valid(); ++array_iter, ++i) {
01095 int ub_size;
01096
01097 Expression *lb = array_iter.current().lower_ref();
01098
01099 if (lb)
01100 lb_size_array[i] = lb->value();
01101 else
01102 lb_size_array[i] = 1;
01103
01104 Expression *ub = array_iter.current().upper_ref();
01105
01106 if (ub)
01107 ub_size = ub->value();
01108 else
01109 ub_size = 1;
01110
01111 src_size = src_size * (ub_size - lb_size_array[i] + 1);
01112 src_size_array[i] = src_size;
01113 }
01114
01115
01116
01117 Expression *returned_ref = comma();
01118
01119 i = src_name_ptr->dim().entries() - 1;
01120
01121 for ( ; i > 0; --array_iter, --i ) {
01122 int off_value = lb_size_array[i] + (src_offset / src_size_array[i]);
01123
01124 returned_ref->arg_list().ins_first(constant(off_value));
01125 src_offset = src_offset % src_size_array[i];
01126 }
01127
01128 returned_ref->arg_list().ins_first(constant(lb_size_array[0] + src_offset));
01129
01130 return returned_ref;
01131 }
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142 Expression *
01143 InlineObject::_gen_equivalent_var(VariableSymbol * name_ptr,
01144 Expression & main_expr)
01145 {
01146 p_assert((main_expr.base_variable_ref() &&
01147 (main_expr.base_variable_ref()->sym_class() == VARIABLE_CLASS)),
01148 "Non-conformable non-variable in _gen_equivalent_var");
01149
01150 VariableSymbol *main_name_ptr
01151 = (VariableSymbol *) main_expr.base_variable_ref();
01152
01153 Expression *main_subs_ptr = 0;
01154
01155 if (main_expr.op() == ARRAY_REF_OP)
01156 main_subs_ptr = &main_expr.subscript();
01157
01158
01159
01160 VariableSizes variable_sizes(*name_ptr);
01161
01162 VariableSizes main_variable_sizes(*main_name_ptr);
01163
01164 int main_name_base;
01165
01166 VariableSymbol *equiv_name_ptr = 0;
01167
01168
01169
01170 Equivalence *main_equiv_ptr = main_name_ptr->equivalence_ref();
01171
01172 if (main_equiv_ptr) {
01173
01174
01175
01176 main_name_base = main_equiv_ptr->find_ref(*main_name_ptr)->byte_base();
01177
01178 for (Iterator<EquivalenceMember> equiv_iter =
01179 main_equiv_ptr->iterator();equiv_iter.valid(); ++equiv_iter) {
01180 equiv_name_ptr =
01181 (VariableSymbol *) & equiv_iter.current().symbol();
01182
01183 int equiv_name_base = equiv_iter.current().byte_base();
01184
01185 if ((equiv_name_base == main_name_base) &&
01186 (equiv_name_ptr->type().data_type()==
01187 name_ptr->type().data_type())) {
01188
01189 VariableSizes equiv_variable_sizes(*equiv_name_ptr);
01190
01191 if ((main_variable_sizes.size == equiv_variable_sizes.size)
01192 && (variable_sizes.elem_size == equiv_variable_sizes.elem_size)
01193 && ((!name_ptr->is_array()) ||
01194 (equiv_name_ptr->dim().entries() == 1))) {
01195
01196
01197
01198
01199
01200
01201 if ((!name_ptr->common_ref()) || (!name_ptr->equivalence_ref())) {
01202
01203
01204
01205
01206 if (main_subs_ptr) {
01207
01208 Expression *linearized_ref =
01209 simplify(_linearize_array_ref(main_name_ptr, main_subs_ptr,
01210 equiv_name_ptr ));
01211 Expression * test_expr =
01212 linearized_ref->arg_list().grab(1);
01213
01214 return comma(array_reference(id(*equiv_name_ptr),
01215 linearized_ref),
01216 test_expr);
01217 }
01218 else
01219 return comma(id(*equiv_name_ptr),
01220 new LogicalConstExpr(".TRUE."));
01221 }
01222
01223
01224
01225
01226 else
01227 break;
01228
01229 }
01230 else
01231 equiv_name_ptr = 0;
01232 }
01233 else
01234 equiv_name_ptr = 0;
01235
01236 }
01237 }
01238
01239 else {
01240
01241
01242 char label_buff[10];
01243 int equiv_count = _pgm_main.equivalences().entries();
01244
01245 sprintf(label_buff, "EQ%u", equiv_count+1);
01246
01247 main_equiv_ptr = new Equivalence(label_buff);
01248
01249
01250 _pgm_main.equivalences().rename_and_ins(main_equiv_ptr);
01251
01252
01253 main_name_base = 0;
01254 main_equiv_ptr->ins(*main_name_ptr, main_name_base);
01255
01256
01257
01258
01259 if (name_ptr->common_ref() && name_ptr->equivalence_ref() &&
01260 (main_name_ptr->type().data_type()==
01261 name_ptr->type().data_type()) &&
01262 (variable_sizes.elem_size == main_variable_sizes.elem_size) &&
01263 ((!name_ptr->is_array()) ||
01264 (main_name_ptr->dim().entries() == 1)))
01265 equiv_name_ptr = main_name_ptr;
01266
01267 }
01268
01269
01270
01271 if (!equiv_name_ptr) {
01272
01273
01274
01275 Expression *upper_bound;
01276 ArrayBounds *new_bounds;
01277
01278 if ((variable_sizes.size != 0) ||
01279 (main_variable_sizes.size != 0)) {
01280 if (variable_sizes.size<main_variable_sizes.size)
01281 upper_bound
01282 = constant(main_variable_sizes.size / variable_sizes.elem_size);
01283 else
01284 upper_bound =
01285 constant(variable_sizes.size / variable_sizes.elem_size);
01286 new_bounds = new ArrayBounds(constant(1), upper_bound);
01287 }
01288 else
01289 new_bounds = new ArrayBounds();
01290
01291 equiv_name_ptr
01292 = new VariableSymbol(main_name_ptr->name_ref(), name_ptr->type(),
01293 main_name_ptr->formal(), main_name_ptr->saved(),
01294 new_bounds);
01295
01296
01297
01298 _pgm_main.symtab().rename_and_ins(equiv_name_ptr);
01299 main_equiv_ptr->ins(*equiv_name_ptr, main_name_base);
01300
01301 }
01302
01303
01304
01305
01306 if ((!name_ptr->common_ref()) || (!name_ptr->equivalence_ref())) {
01307
01308
01309
01310
01311 if (main_subs_ptr) {
01312
01313 Expression *linearized_ref =
01314 simplify(_linearize_array_ref(main_name_ptr, main_subs_ptr,
01315 equiv_name_ptr ));
01316 Expression * test_expr =
01317 linearized_ref->arg_list().grab(1);
01318
01319 return comma(array_reference(id(*equiv_name_ptr),
01320 linearized_ref),
01321 test_expr);
01322 }
01323 else
01324 return comma(id(*equiv_name_ptr),
01325 new LogicalConstExpr(".TRUE."));
01326 }
01327
01328
01329
01330 Symbol & main_equiv_name =
01331 rename_variable_to_match(*_pgm_ref, *name_ptr,
01332 _pgm_main, name_ptr->clone());
01333
01334
01335
01336 main_equiv_name.formal(main_name_ptr->formal());
01337 main_equiv_name.saved(main_name_ptr->saved());
01338
01339
01340
01341 if(!main_subs_ptr)
01342 main_equiv_ptr->ins(main_equiv_name, main_name_base);
01343 else {
01344
01345 Expression *linearized_ref
01346 = simplify(_linearize_array_ref(main_name_ptr, main_subs_ptr,
01347 equiv_name_ptr));
01348 int array_offset = linearized_ref->arg_list()[0].value();
01349 delete linearized_ref;
01350 ArrayBounds & old_bound = equiv_name_ptr->dim()[0];
01351 if (old_bound.lower_exists())
01352 array_offset = array_offset - old_bound.lower_guarded().value();
01353 else
01354 --array_offset;
01355
01356 main_equiv_ptr->ins(main_equiv_name,
01357 main_name_base +
01358 array_offset * variable_sizes.elem_size);
01359
01360 }
01361
01362
01363
01364 return comma(id(main_equiv_name),
01365 new LogicalConstExpr(".TRUE."));
01366 }
01367
01368
01369
01370 bool
01371 alternate_expr_valid(VariableSymbol * name_ptr,
01372 Expression & main_expr)
01373 {
01374 bool return_value = false;
01375
01376 if (main_expr.op()==ID_OP) {
01377 Symbol & main_name = main_expr.symbol();
01378 if (main_name.is_scalar()) {
01379 ArrayDims & name_dims = name_ptr->dim();
01380 if ((name_dims.entries()==1)) {
01381 ArrayBounds & name_bnds = name_dims[0];
01382 Expression * lower_bnd_ref = 0;
01383 if (name_bnds.lower_exists())
01384 lower_bnd_ref = &name_bnds.lower_guarded();
01385 if ((!lower_bnd_ref ||
01386 ((lower_bnd_ref->op()==INTEGER_CONSTANT_OP) &&
01387 (lower_bnd_ref->value() == 1))) &&
01388 name_bnds.upper_exists()) {
01389 Expression & upper_bnd = name_bnds.upper_guarded();
01390 if ((upper_bnd.op()==INTEGER_CONSTANT_OP) &&
01391 (upper_bnd.value() == 2))
01392 return_value = true;
01393 }
01394 }
01395 }
01396 }
01397 return return_value;
01398 }
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409 static Expression *
01410 gen_alternate_expr(VariableSymbol * name_ptr,
01411 Expression & main_expr)
01412 {
01413 if (alternate_expr_valid(name_ptr, main_expr))
01414 return id(main_expr.symbol());
01415 else
01416 return NULL;
01417 }
01418
01419
01420
01421 static void
01422 fix_alternate_expr(Statement & s,
01423 ProgramUnit & pgm)
01424 {
01425 static String real_str("REAL");
01426 static String aimag_str("AIMAG");
01427 static String cmplx_str("CMPLX");
01428 static Type real_type(REAL_TYPE, 0);
01429 static Type cmplx_type(COMPLEX_TYPE, 0);
01430
01431 Expression * intrinsic_parm_expr = NULL;
01432 const char * symbol_name =
01433 s.lhs().intrinsic().symbol().tag_ref();
01434
01435
01436
01437
01438 Mutator<Expression> out_mutr = s.iterate_out_exprs_guarded();
01439 Expression * rhs_alternate_expr = out_mutr.current().grab_right();
01440 Expression * lhs_alternate_expr = rhs_alternate_expr->arg_list()[0].clone();
01441
01442
01443
01444 out_mutr.modify(lhs_alternate_expr);
01445
01446
01447
01448 Mutator<Expression> in_mutr = s.iterate_in_exprs_guarded();
01449 Assign<Expression> in_as(in_mutr.assign());
01450 Expression * rhs_expr = in_mutr.pull();
01451
01452 if (aimag_str==symbol_name) {
01453
01454 Symbol * opposite_ptr =
01455 pgm.symtab().find_ref(real_str);
01456 Expression * opposite_id_expr;
01457 if (opposite_ptr)
01458 opposite_id_expr = id(*opposite_ptr);
01459 else
01460 opposite_id_expr = new_intrinsic(real_str, real_type, pgm);
01461 intrinsic_parm_expr = comma(intrinsic_call(opposite_id_expr,
01462 rhs_alternate_expr),
01463 rhs_expr);
01464 }
01465 else if (real_str==symbol_name) {
01466
01467 Symbol * opposite_ptr =
01468 pgm.symtab().find_ref(aimag_str);
01469 Expression * opposite_id_expr;
01470 if (opposite_ptr)
01471 opposite_id_expr = id(*opposite_ptr);
01472 else
01473 opposite_id_expr = new_intrinsic(aimag_str, real_type, pgm);
01474 intrinsic_parm_expr = comma(rhs_expr,
01475 intrinsic_call(opposite_id_expr,
01476 rhs_alternate_expr));
01477 }
01478 else
01479 p_abort("Invalid intrinsic function encountered in fix_alternate_expr");
01480
01481 Expression * intrinsic_id_expr;
01482
01483
01484 Symbol * intrinsic_ptr =
01485 pgm.symtab().find_ref(cmplx_str);
01486 if (intrinsic_ptr)
01487 intrinsic_id_expr = id(*intrinsic_ptr);
01488 else
01489 intrinsic_id_expr = new_intrinsic(cmplx_str, cmplx_type, pgm);
01490
01491
01492
01493 in_as = intrinsic_call(intrinsic_id_expr, intrinsic_parm_expr);
01494
01495
01496 }
01497
01498
01499
01500 Expression *
01501 InlineObject::make_conformable(VariableSymbol * name_ptr,
01502 Expression & main_expr)
01503 {
01504 Expression *main_expr_ptr = &main_expr;
01505 Expression *test_expr = 0;
01506 bool non_conformable_flag = false;
01507 Expression *debug_output = 0;
01508
01509 if (_debug_flag) {
01510 debug_output = comma();
01511 debug_output->arg_list().ins_first(id(*name_ptr));
01512 }
01513
01514
01515 CONFORM_TYPE conformable = conformable_test(name_ptr, main_expr,
01516 non_conformable_flag);
01517
01518 if (conformable == NON_CONFORMABLE) {
01519
01520 Expression * equivalent_pair =
01521 main_expr_ptr = _gen_equivalent_var(name_ptr, main_expr);
01522
01523
01524
01525
01526 if ((main_expr.type().data_type() == COMPLEX_TYPE) &&
01527 (name_ptr->type().data_type() == REAL_TYPE)) {
01528 Expression * alt_expr = gen_alternate_expr(name_ptr,main_expr);
01529 if (alt_expr)
01530 _alternate_map.ins(*name_ptr,alt_expr);
01531 }
01532
01533 non_conformable_flag = true;
01534 main_expr_ptr = equivalent_pair->arg_list().grab(0);
01535 test_expr = equivalent_pair->arg_list().grab(0);
01536 delete equivalent_pair;
01537 conformable = conformable_test(name_ptr, *main_expr_ptr,
01538 non_conformable_flag);
01539 p_assert(conformable != NON_CONFORMABLE,
01540 "Call to _gen_equivalent_var failed in make_conformable");
01541 }
01542
01543
01544
01545 if (conformable != TRANSFORMABLE_CONSTANT) {
01546 Symbol & base_symbol = *main_expr_ptr->base_variable_ref();
01547 _symbol_map.ins(*name_ptr, new SymRefElem(base_symbol));
01548 if (_debug_flag)
01549 debug_output->arg_list().ins_last(id(base_symbol));
01550 }
01551
01552
01553
01554
01555
01556
01557
01558 Expression *main_subs_ptr = NULL;
01559 Expression *main_array_ptr = main_expr_ptr;
01560
01561 switch (conformable) {
01562 case TRANSFORMABLE_CONSTANT:
01563 {
01564
01565 _constant_map.ins(*name_ptr, *main_expr_ptr);
01566 if (_debug_flag)
01567 debug_output->arg_list().ins_last(main_expr_ptr->clone());
01568 break;
01569 }
01570
01571 case TRANSFORMABLE_SUBSTRING:
01572 {
01573
01574 _substring_map.ins(*name_ptr, main_expr_ptr->bound().clone());
01575 break;
01576 }
01577
01578 case TRANSFORMABLE_SUBSTRING_ARRAY:
01579 {
01580
01581
01582 _substring_map.ins(*name_ptr, main_expr_ptr->bound().clone());
01583
01584
01585
01586 main_array_ptr = & main_expr_ptr->string();
01587
01588
01589
01590 }
01591
01592 case TRANSFORMABLE_ARRAY:
01593 {
01594
01595 VariableSymbol *main_name_ptr
01596 = (VariableSymbol *) main_array_ptr->base_variable_ref();
01597
01598 if (main_array_ptr->op() == ARRAY_REF_OP)
01599 main_subs_ptr = &main_array_ptr->subscript();
01600
01601
01602 ArrayDims & name_dim = name_ptr->dim();
01603 int name_dims = name_dim.entries();
01604
01605 ArrayDims & main_name_dim = main_name_ptr->dim();
01606 int main_name_dims = main_name_dim.entries();
01607
01608 Expression *lambda_ref = comma();
01609
01610 if ((main_name_dims>0) && (name_dims == main_name_dims)) {
01611 Iterator<ArrayBounds> name_iter = name_dim;
01612 Iterator<ArrayBounds> main_name_iter = main_name_dim;
01613
01614 List<Expression> dummy_list;
01615 List<Expression> *main_subs_listptr = &dummy_list;
01616
01617 if (main_subs_ptr)
01618 main_subs_listptr = &main_subs_ptr->arg_list();
01619
01620 Iterator<Expression> main_subs_iter(*main_subs_listptr);
01621
01622 for (int i = 1; i <= name_dims; ++i) {
01623 Expression *name_lb = name_iter.current().lower_ref();
01624
01625 if (name_lb)
01626 name_lb = name_lb->clone();
01627 else
01628 name_lb = constant(1);
01629
01630 Expression *main_name_lb
01631 = main_name_iter.current().lower_ref();
01632
01633 if (main_name_lb)
01634 main_name_lb = main_name_lb->clone();
01635 else
01636 main_name_lb = constant(1);
01637
01638
01639
01640
01641 Expression *main_name_offptr = sub(main_name_lb, name_lb);
01642
01643
01644
01645
01646 if (main_subs_ptr) {
01647 main_name_offptr
01648 = add(main_name_offptr,
01649 sub(main_subs_iter.current().clone(),
01650 main_name_lb->clone()));
01651 ++main_subs_iter;
01652 }
01653
01654 Type main_type = make_type(INTEGER_TYPE);
01655
01656 main_name_offptr
01657 = add(main_name_offptr,
01658 new ArgNumberExpr(main_type, i));
01659
01660
01661
01662 lambda_ref->arg_list().ins_last(main_name_offptr);
01663
01664
01665
01666 ++name_iter;
01667 ++main_name_iter;
01668 }
01669
01670
01671 _array_map.ins(*name_ptr, lambda_ref);
01672 if (_debug_flag)
01673 debug_output->arg_list().ins_last(lambda_ref->clone());
01674 }
01675 else if ((main_name_dims == 1) && (name_dims>0)) {
01676
01677
01678
01679 Expression *subscript_ref = comma();
01680
01681 Type int_type = make_type(INTEGER_TYPE);
01682
01683 for (int i = 1; i <= name_dims; ++i) {
01684 Expression *arg_number_ptr
01685 = new ArgNumberExpr(int_type, i);
01686
01687
01688 subscript_ref->arg_list().ins_last(arg_number_ptr);
01689 }
01690
01691
01692
01693 Expression *linearize_pair =
01694 _linearize_array_ref(name_ptr, subscript_ref,
01695 main_name_ptr);
01696
01697 Expression *offset = linearize_pair->arg_list().grab(0);
01698
01699 delete linearize_pair;
01700
01701
01702
01703 if (main_subs_ptr) {
01704 Expression *main_name_lb
01705 = main_name_ptr->dim()[0].lower_ref();
01706
01707 if (main_name_lb)
01708 main_name_lb = main_name_lb->clone();
01709 else
01710 main_name_lb = constant(1);
01711
01712
01713 offset = add(offset,
01714 sub(main_subs_ptr->arg_list()[0].clone(),
01715 main_name_lb));
01716 }
01717
01718
01719 lambda_ref->arg_list().ins_last(offset);
01720
01721
01722 _array_map.ins(*name_ptr, lambda_ref);
01723 if (_debug_flag)
01724 debug_output->arg_list().ins_last(lambda_ref->clone());
01725 }
01726 else if (name_dims == 0) {
01727 if (main_subs_ptr)
01728 lambda_ref = main_subs_ptr->clone();
01729 else
01730 lambda_ref = initial_array_ref(main_name_ptr);
01731
01732
01733 _array_map.ins(*name_ptr, lambda_ref);
01734 if (_debug_flag)
01735 debug_output->arg_list().ins_last(lambda_ref->clone());
01736 }
01737 }
01738 default: break;
01739 }
01740
01741
01742
01743 if (non_conformable_flag) {
01744
01745 if (test_expr->op()!=LOGICAL_CONSTANT_OP) {
01746
01747
01748
01749 _test_exprs.ins_last(test_expr);
01750
01751 }
01752
01753 else {
01754
01755
01756
01757
01758 p_assert(strcmp(test_expr->data_ref(),".TRUE.") == 0,
01759 "Illegal subscript alignment detected in make_conformable");
01760 delete test_expr;
01761
01762 }
01763
01764
01765
01766 delete main_expr_ptr;
01767 }
01768
01769 return debug_output;
01770 }
01771
01772
01773
01774 void
01775 InlineObject::_remap_common_blocks()
01776 {
01777
01778 for (DictionaryIter<CommonBlock> common_iter = _pgm_ref->common_blocks();
01779 common_iter.valid(); ++common_iter) {
01780
01781 CommonBlock &common_local = common_iter.current();
01782 const char *common_main_tag
01783 = common_local.name_ref();
01784 CommonBlock *common_main_ptr
01785 = _pgm_main.common_blocks().find_ref(common_main_tag);
01786
01787 if (!common_main_ptr) {
01788
01789 RefList<Symbol> common_relink_list;
01790
01791
01792
01793
01794 for (Iterator<Symbol> common_block_iter
01795 = common_local.iterator();
01796 common_block_iter.valid();
01797 ++common_block_iter) {
01798 VariableSymbol & current_symbol =
01799 (VariableSymbol &) common_block_iter.current();
01800
01801
01802 Symbol & main_symbol =
01803 rename_variable_to_match(*_pgm_ref, current_symbol,
01804 _pgm_main, current_symbol.clone_all());
01805
01806
01807 _symbol_map.ins(current_symbol,
01808 new SymRefElem(main_symbol));
01809
01810
01811
01812 if (!current_symbol.equivalence_ref())
01813 common_relink_list.ins_last(main_symbol);
01814 }
01815
01816
01817
01818
01819 common_main_ptr = new CommonBlock(common_local);
01820 if (common_local.saved() &&
01821 (_pgm_main.pu_class()==PROGRAM_PU_TYPE))
01822 common_main_ptr->saved(0);
01823 _pgm_main.common_blocks().ins(common_main_ptr);
01824
01825
01826
01827 common_main_ptr->relink_dptrs(_pgm_main);
01828
01829
01830
01831 for (Iterator<Symbol> relink_iter = common_relink_list;
01832 relink_iter.valid(); ++relink_iter)
01833 relink_iter.current().relink_dptrs(_pgm_main);
01834
01835 }
01836 else {
01837 map_existing_common_block(common_local, common_main_ptr);
01838 }
01839 }
01840 }
01841
01842
01843
01844
01845
01846
01847
01848 void
01849 InlineObject::map_existing_common_block(CommonBlock & common_local,
01850 CommonBlock * common_main_ptr)
01851 {
01852
01853
01854
01855
01856
01857
01858 if (common_local.saved() &&
01859 (_pgm_main.pu_class()!=PROGRAM_PU_TYPE))
01860 common_main_ptr->saved(1);
01861
01862
01863 int common_offset = 0;
01864 int common_main_offset = 0;
01865
01866 Iterator<Symbol> common_main_block_iter
01867 = common_main_ptr->iterator();
01868 VariableSymbol *name_ptr;
01869 VariableSymbol *main_name_ptr
01870 = (VariableSymbol *) & common_main_block_iter.current();
01871 VariableSizes common_main_variable_sizes(*main_name_ptr);
01872
01873 for (Iterator<Symbol> common_block_iter
01874 = common_local.iterator();
01875 common_block_iter.valid();
01876 ++common_block_iter) {
01877
01878 name_ptr = (VariableSymbol *) & common_block_iter.current();
01879
01880 VariableSizes common_variable_sizes(*name_ptr);
01881
01882
01883
01884
01885 while (common_main_block_iter.valid() &&
01886 ((common_main_offset>common_offset) ||
01887 (common_main_offset + common_main_variable_sizes.size <=
01888 common_offset))) {
01889 common_main_offset += common_main_variable_sizes.size;
01890
01891 ++common_main_block_iter;
01892
01893 if (common_main_block_iter.valid()) {
01894 main_name_ptr
01895 = (VariableSymbol *)
01896 &common_main_block_iter.current();
01897 common_main_variable_sizes.remap(*main_name_ptr);
01898 }
01899 }
01900
01901
01902
01903 if (!common_main_block_iter.valid())
01904 break;
01905
01906 int var_offset = common_offset - common_main_offset;
01907 Expression *main_expr_ptr;
01908 Expression *main_id_ptr = id(*main_name_ptr);
01909
01910 if (var_offset) {
01911 if ((var_offset % common_main_variable_sizes.elem_size)
01912 == 0) {
01913
01914
01915 Expression *main_subs_ptr
01916 = unlinearize_array_ref(main_name_ptr,
01917 var_offset / common_main_variable_sizes.elem_size);
01918
01919
01920
01921
01922 main_expr_ptr
01923 = array_reference(main_id_ptr, main_subs_ptr);
01924 }
01925 else {
01926
01927
01928
01929
01930
01931 Expression *equivalent_pair =
01932 _gen_equivalent_var(name_ptr,*main_id_ptr);
01933 Expression *main_equiv_ptr =
01934 equivalent_pair->arg_list().grab(0);
01935 delete equivalent_pair;
01936
01937
01938 VariableSymbol *equiv_name_ptr =
01939 (VariableSymbol *) main_equiv_ptr->base_variable_ref();
01940
01941
01942 delete main_id_ptr;
01943
01944
01945 Expression *main_subs_ptr
01946 = unlinearize_array_ref(equiv_name_ptr,
01947 var_offset / common_variable_sizes.elem_size);
01948
01949
01950
01951
01952 main_expr_ptr
01953 = array_reference(main_equiv_ptr, main_subs_ptr);
01954
01955 }
01956 }
01957 else {
01958 main_expr_ptr = main_id_ptr;
01959 }
01960
01961
01962 Expression * debug_output =
01963 make_conformable(name_ptr, *main_expr_ptr);
01964
01965 if (debug_output)
01966 delete debug_output;
01967
01968
01969 delete main_expr_ptr;
01970
01971
01972 common_offset += common_variable_sizes.size;
01973 }
01974 }
01975
01976
01977
01978 void
01979 InlineObject::_remap_equivalences()
01980 {
01981
01982
01983 for (DictionaryIter<Equivalence> equiv_iter = _pgm_ref->equivalences();
01984 equiv_iter.valid(); ++equiv_iter) {
01985 Equivalence & current_equiv = equiv_iter.current();
01986
01987 Equivalence * pre_main_equiv_ptr = 0;
01988 int pre_main_equiv_bb = 0;
01989 int common_bb = 0;
01990 PRIVAT_TYPE priv_type = PRIVATE;
01991
01992
01993
01994 for (Iterator<EquivalenceMember> scan_iter = current_equiv.iterator();
01995 scan_iter.valid(); ++scan_iter) {
01996 EquivalenceMember & scan_em = scan_iter.current();
01997 Symbol & scan_symbol = scan_em.symbol();
01998 if(scan_symbol.saved()!=NOT_SAVED) {
01999 priv_type = NOT_PRIVATE;
02000 break;
02001 }
02002 else if(scan_symbol.common_ref()) {
02003 priv_type = NOT_PRIVATE;
02004 SymRefElem * main_symbol_ref =
02005 _symbol_map.find_ref(scan_symbol);
02006 Symbol * main_symbol_ptr = _pgm_main.symtab().find_ref(scan_symbol.name_ref());
02007 p_assert(main_symbol_ptr &&
02008 main_symbol_ref &&
02009 (&(*main_symbol_ref->symref()) == main_symbol_ptr),
02010 "Invalid common symbol in _remap_equivalences");
02011
02012
02013
02014
02015
02016
02017 if (!main_symbol_ptr->equivalence_ref()) {
02018 char label_buff[10];
02019 int equiv_count = _pgm_main.equivalences().entries();
02020 sprintf(label_buff, "EQ%u", equiv_count+1);
02021 Equivalence * main_equiv_ptr = new Equivalence(label_buff);
02022 _pgm_main.equivalences().rename_and_ins(main_equiv_ptr);
02023 main_equiv_ptr->ins(*main_symbol_ptr, 0);
02024 }
02025
02026
02027
02028
02029 if (main_symbol_ptr->equivalence_ref() != ¤t_equiv) {
02030 pre_main_equiv_ptr = main_symbol_ptr->equivalence_ref();
02031 common_bb = scan_em.byte_base();
02032 EquivalenceMember * em_ptr =
02033 pre_main_equiv_ptr->find_ref(*main_symbol_ptr);
02034 p_assert(em_ptr,
02035 "Invalid equivalence in _remap_equivalences");
02036 pre_main_equiv_bb = em_ptr->byte_base();
02037 }
02038 break;
02039 }
02040 }
02041
02042 if (priv_type == PRIVATE)
02043 _private_vars += current_equiv.entries();
02044
02045 if (pre_main_equiv_ptr) {
02046
02047
02048
02049
02050 for (Iterator<EquivalenceMember> eb_iter = current_equiv.iterator();
02051 eb_iter.valid(); ++eb_iter) {
02052 EquivalenceMember & current_em = eb_iter.current();
02053 Symbol & current_symbol = current_em.symbol();
02054 if (!current_symbol.common_ref()) {
02055 int em_bb = current_em.byte_base();
02056 current_equiv.del(current_symbol);
02057 Symbol & main_symbol =
02058 rename_variable_to_match(*_pgm_ref, current_symbol,
02059 _pgm_main, current_symbol.clone());
02060 _symbol_map.ins(current_symbol,
02061 new SymRefElem(main_symbol, priv_type));
02062
02063
02064 pre_main_equiv_ptr->ins(main_symbol,
02065 em_bb - common_bb + pre_main_equiv_bb);
02066 }
02067 }
02068 }
02069
02070 else {
02071
02072
02073
02074
02075 for (Iterator<EquivalenceMember> eb_iter = current_equiv.iterator();
02076 eb_iter.valid(); ++eb_iter) {
02077 EquivalenceMember & current_em = eb_iter.current();
02078 VariableSymbol & current_symbol = (VariableSymbol &) current_em.symbol();
02079
02080 if (!current_symbol.common_ref()) {
02081
02082 Symbol & main_symbol =
02083 rename_variable_to_match(*_pgm_ref, current_symbol,
02084 _pgm_main, current_symbol.clone_all());
02085
02086
02087 _symbol_map.ins(current_symbol,
02088 new SymRefElem(main_symbol, priv_type));
02089 }
02090 }
02091
02092
02093
02094
02095 Equivalence & equiv_main =
02096 rename_equivalence_to_match(*_pgm_ref, current_equiv,
02097 _pgm_main, new Equivalence(current_equiv));
02098
02099
02100
02101 equiv_main.relink_dptrs(_pgm_main);
02102
02103
02104
02105 for (Iterator<EquivalenceMember> relink_iter = equiv_main.iterator();
02106 relink_iter.valid(); ++relink_iter)
02107 relink_iter.current().symbol().relink_dptrs(_pgm_main);
02108
02109 }
02110
02111 }
02112 }
02113
02114
02115
02116
02117
02118 void
02119 InlineObject::_remap_and_move_data()
02120 {
02121
02122
02123 for (Iterator<Data> data_iter = _pgm_ref->data();
02124 data_iter.valid(); ++data_iter) {
02125
02126 Data *current_data = data_iter.current().clone();
02127
02128
02129
02130 Expression & var_list =
02131 CASTAWAY(Expression &) current_data->variable_list();
02132
02133 for (Mutator<Expression> expr_mutr = var_list.arg_list();
02134 expr_mutr.valid(); ++expr_mutr) {
02135 bool local_expr_flag = false;
02136 Assign<Expression> expr_as(expr_mutr.assign());
02137 expr_as = _translate_symbol_refs_expr(expr_mutr.pull(),
02138 IN_REF_EXPR,
02139 local_expr_flag);
02140 }
02141
02142
02143
02144 _pgm_main.data().ins_last(current_data);
02145
02146 }
02147 }
02148
02149
02150
02151
02152 Statement &
02153 InlineObject::_remap_arg_uses(Statement & s)
02154 {
02155
02156 Symbol *entry_name_ptr = 0;
02157
02158 List<Expression> *actual_ptr = 0;
02159 int actual_entries = 0;
02160 List<Expression> *formal_ptr = 0;
02161 int formal_entries = 0;
02162
02163 ostrstream *str_ref;
02164 char *data;
02165
02166 if (s.stmt_class() == CALL_STMT) {
02167
02168
02169
02170 if (s.parameters_valid())
02171 actual_ptr = &s.parameters_guarded().arg_list();
02172
02173 entry_name_ptr =
02174 _pgm_ref->symtab().find_ref(s.routine_guarded().symbol().name_ref());
02175 }
02176 else {
02177
02178
02179
02180
02181
02182 if (s.rhs().parameters_valid())
02183 actual_ptr = &s.rhs().parameters_guarded().arg_list();
02184 entry_name_ptr =
02185 _pgm_ref->symtab().find_ref(s.rhs().function().symbol().name_ref());
02186
02187
02188 _symbol_map.ins(*entry_name_ptr,
02189 new SymRefElem(s.lhs().symbol()));
02190 }
02191
02192
02193
02194
02195 if (_debug_flag) {
02196 str_ref = new ostrstream;
02197 StringElem * comment_line;
02198 const char * rout_tag = entry_name_ptr->tag_ref();
02199 (*str_ref) << " Beginning of call to routine " << rout_tag << '\000';
02200 data = str_ref->str();
02201 comment_line = new StringElem(data);
02202 delete [] data;
02203 delete str_ref;
02204 _begin_comment_list.ins_first(comment_line);
02205 str_ref = new ostrstream;
02206 (*str_ref) << " End of call to routine " << rout_tag << '\000';
02207 data = str_ref->str();
02208 comment_line = new StringElem(data);
02209 delete [] data;
02210 delete str_ref;
02211 _end_comment_list.ins_first(comment_line);
02212 }
02213
02214
02215 Statement *entry_point_ptr = NULL;
02216
02217 for (Iterator<Statement> entry_iter
02218 = _pgm_ref->stmts().iterate_entry_points();
02219 entry_iter.valid(); ++entry_iter) {
02220
02221 Statement *c = &entry_iter.current();
02222
02223 if ((c->stmt_class() != FLOW_ENTRY_STMT) &&
02224 (entry_name_ptr == &c->routine_guarded().symbol())) {
02225 entry_point_ptr = c;
02226 break;
02227 }
02228 }
02229
02230 p_assert(entry_point_ptr, "Entry point not found by _remap_arg_uses");
02231
02232
02233
02234 if (actual_ptr)
02235 actual_entries = actual_ptr->entries();
02236
02237 if (entry_point_ptr->parameters_valid()) {
02238 formal_ptr = &entry_point_ptr->parameters_guarded().arg_list();
02239 formal_entries = formal_ptr->entries();
02240 }
02241
02242
02243
02244 p_assert(actual_entries==formal_entries,
02245 "Different number of parameters in _remap_arg_uses");
02246
02247 if (actual_entries) {
02248
02249 Iterator<Expression> actual_iter = *actual_ptr;
02250 Iterator<Expression> formal_iter = *formal_ptr;
02251
02252 while (actual_iter.valid() && formal_iter.valid()) {
02253
02254 VariableSymbol *name_ptr
02255 = (VariableSymbol *) formal_iter.current().base_variable_ref();
02256 Expression & main_expr
02257 = actual_iter.current();
02258
02259
02260 Expression * debug_output =
02261 make_conformable(name_ptr, main_expr);
02262
02263
02264
02265 if (_debug_flag) {
02266 Iterator<Expression> debug_iter = debug_output->arg_list();
02267 str_ref = new ostrstream;
02268 (*str_ref) << " Dummy parm "
02269 << debug_iter.current(); ++debug_iter;
02270 (*str_ref) << " replaced by actual parm "
02271 << debug_iter.current(); ++debug_iter;
02272 if (debug_iter.valid()) {
02273 (*str_ref) << " (with lambda subexpression " << debug_iter.current()
02274 << ')';
02275 }
02276 (*str_ref) << '\000';
02277 data = str_ref->str();
02278 StringElem *comment_line = new StringElem(data);
02279 delete [] data;
02280 delete str_ref;
02281 _begin_comment_list.ins_last(comment_line);
02282 delete debug_output;
02283 }
02284
02285
02286
02287 ++actual_iter;
02288 ++formal_iter;
02289 }
02290 }
02291
02292 return *entry_point_ptr;
02293 }
02294
02295
02296
02297
02298
02299 void
02300 InlineObject::remap_arg_names(Statement & s)
02301 {
02302
02303 Symbol *entry_name_ptr = 0;
02304
02305 List<Expression> *actual_ptr = 0;
02306 int actual_entries = 0;
02307 List<Expression> *formal_ptr = 0;
02308 int formal_entries = 0;
02309
02310
02311
02312
02313 int narrays = 0;
02314 int nreshaped = 0;
02315
02316 if (s.stmt_class() == CALL_STMT) {
02317
02318
02319
02320 if (s.parameters_valid())
02321 actual_ptr = &s.parameters_guarded().arg_list();
02322
02323 entry_name_ptr =
02324 _pgm_ref->symtab().find_ref(s.routine_guarded().symbol().name_ref());
02325 }
02326 else {
02327
02328
02329
02330
02331
02332 if (s.rhs().parameters_valid())
02333 actual_ptr = &s.rhs().parameters_guarded().arg_list();
02334 entry_name_ptr =
02335 _pgm_ref->symtab().find_ref(s.rhs().function().symbol().name_ref());
02336
02337
02338
02339
02340 }
02341
02342
02343 Statement *entry_point_ptr = NULL;
02344
02345 for (Iterator<Statement> entry_iter
02346 = _pgm_ref->stmts().iterate_entry_points();
02347 entry_iter.valid(); ++entry_iter) {
02348
02349 Statement *c = &entry_iter.current();
02350
02351 if ((c->stmt_class() != FLOW_ENTRY_STMT) &&
02352 (entry_name_ptr == &c->routine_guarded().symbol())) {
02353 entry_point_ptr = c;
02354 break;
02355 }
02356 }
02357
02358 p_assert(entry_point_ptr, "Entry point not found by _remap_arg_uses");
02359
02360
02361
02362 if (actual_ptr)
02363 actual_entries = actual_ptr->entries();
02364
02365 if (entry_point_ptr->parameters_valid()) {
02366 formal_ptr = &entry_point_ptr->parameters_guarded().arg_list();
02367 formal_entries = formal_ptr->entries();
02368 }
02369
02370
02371
02372 p_assert(actual_entries==formal_entries,
02373 "Different number of parameters in _remap_arg_uses");
02374
02375 if (actual_entries) {
02376
02377
02378 Iterator<Expression> actual_iter = *actual_ptr;
02379 Iterator<Expression> formal_iter = *formal_ptr;
02380
02381
02382
02383 while (actual_iter.valid() && formal_iter.valid()) {
02384
02385 VariableSymbol *formal_symbol
02386 = (VariableSymbol *) formal_iter.current().base_variable_ref();
02387 Expression & current_expr
02388 = actual_iter.current();
02389
02390
02391
02392 Expression * actual_expr=0;
02393 AbstractAccess * aa;
02394
02395 if ((current_expr.op() == FUNCTION_CALL_OP) &&
02396 (strcmp(current_expr.arg_list()[0].symbol().name_ref(), "<BETA>") == 0)) {
02397
02398
02399
02400 if (current_expr.arg_list()[1].arg_list()[0].op() == ALPHA_OP) {
02401
02402 actual_expr = current_expr.arg_list()[1].arg_list()[0].arg_list()[1].arg_list()[0].clone();
02403 aa = compute_abstract_access(*actual_expr,
02404 &s,
02405 AR_READWRITE);
02406 } else {
02407 p_abort("Unexpected form of BETA function");
02408 }
02409 } else {
02410 actual_expr = current_expr.clone();
02411 aa = compute_abstract_access( *actual_expr, &s, AR_READWRITE );
02412 }
02413
02414 _insert_arg_mapping(*formal_symbol, actual_expr, aa);
02415
02416
02417
02418
02419
02420 if ((actual_expr->op() == ARRAY_REF_OP) ||
02421 (actual_expr->op() == ID_OP)) {
02422
02423 _symbol_map.ins(*formal_symbol,
02424 new SymRefElem(*(actual_expr->base_variable_ref())));
02425 }
02426
02427
02428
02429 ++actual_iter;
02430 ++formal_iter;
02431 }
02432
02433
02434
02435 if (_ar_reshape) {
02436 actual_iter.reset();
02437 formal_iter.reset();
02438 while (actual_iter.valid() && formal_iter.valid()) {
02439
02440 VariableSymbol *formal_symbol
02441 = (VariableSymbol *) formal_iter.current().base_variable_ref();
02442 Expression & current_expr
02443 = actual_iter.current();
02444 VariableSymbol *actual_symbol
02445 = (VariableSymbol *) current_expr.base_variable_ref();
02446
02447
02448
02449 if (_ar_reshape && actual_symbol &&
02450 formal_symbol->is_array() && actual_symbol->is_array()) {
02451
02452 narrays++;
02453
02454 for (int i=0; i<formal_symbol->dim().entries()-1; i++) {
02455
02456 if (i>actual_symbol->dim().entries()-1) {
02457 nreshaped++;
02458 if (_ar_reshape == 2) {
02459 ostrstream str1;
02460 ostrstream str2;
02461 str1 << convert_case(formal_symbol->name_ref());
02462 str2 << convert_case(actual_symbol->name_ref());
02463 formal_symbol->dim().print(str1);
02464 actual_symbol->dim().print(str2);
02465 str1 << '\000';
02466 str2 << '\000';
02467 char *data1 = str1.str();
02468 char *data2 = str2.str();
02469 cout << "RESHAPING: " << data2 << " to " << data1 << endl;
02470 }
02471 break;
02472 }
02473
02474 ArrayBounds & actual_bounds = actual_symbol->dim()[i];
02475 ArrayBounds & formal_bounds = formal_symbol->dim()[i];
02476
02477 Expression * act_lo;
02478 Expression * form_lo;
02479 Expression * act_num_elems;
02480 Expression * form_num_elems;
02481
02482 if (!(actual_bounds.lower_exists())) {
02483 act_lo = constant(1);
02484 } else {
02485 act_lo = actual_bounds.lower_guarded().clone();
02486 }
02487
02488 if (!actual_bounds.upper_exists()) {
02489 nreshaped++;
02490 ostrstream str1;
02491 ostrstream str2;
02492 str1 << convert_case(formal_symbol->name_ref());
02493 str2 << convert_case(actual_symbol->name_ref());
02494 formal_symbol->dim().print(str1);
02495 actual_symbol->dim().print(str2);
02496 str1 << '\000';
02497 str2 << '\000';
02498 char *data1 = str1.str();
02499 char *data2 = str2.str();
02500 cout << "RESHAPING: " << data2 << " to " << data1 << endl;
02501 delete act_lo;
02502 break;
02503 }
02504
02505 act_num_elems = simplify(add(sub(actual_bounds.upper_guarded().clone(),
02506 act_lo),
02507 constant(1)));
02508
02509 if (!(formal_bounds.lower_exists())) {
02510 form_lo = constant(1);
02511 } else {
02512 form_lo = formal_bounds.lower_guarded().clone();
02513 }
02514
02515 Expression * upper_expr;
02516
02517
02518
02519
02520 Expression & upper = formal_bounds.upper_guarded();
02521
02522 if ((upper.op() == ID_OP) && (upper.symbol().formal())) {
02523 upper_expr = actual_arg(upper.symbol())->clone();
02524 } else {
02525 upper_expr = formal_bounds.upper_guarded().clone();
02526 }
02527
02528 form_num_elems = simplify(add(sub(upper_expr, form_lo),
02529 constant(1)));
02530
02531 Expression * diff = simplify(sub(form_num_elems,act_num_elems));
02532
02533 if (!is_integer_zero(*diff)) {
02534 nreshaped++;
02535 ostrstream str1;
02536 ostrstream str2;
02537 str1 << convert_case(formal_symbol->name_ref());
02538 str2 << convert_case(actual_symbol->name_ref());
02539 formal_symbol->dim().print(str1);
02540 actual_symbol->dim().print(str2);
02541 str1 << '\000';
02542 str2 << '\000';
02543 char *data1 = str1.str();
02544 char *data2 = str2.str();
02545 cout << "RESHAPING: " << data2 << " to " << data1 << endl;
02546 delete diff;
02547 break;
02548 } else {
02549 delete diff;
02550 }
02551 }
02552 }
02553
02554
02555
02556 ++actual_iter;
02557 ++formal_iter;
02558 }
02559 }
02560 }
02561 if (_ar_reshape) {
02562 cout << "CALL: " << actual_entries << " params " << narrays << " arrays " << nreshaped << " reshaped" << endl;
02563 }
02564 }
02565
02566
02567
02568
02569
02570 static Expression *
02571 remap_args_precalc_expr(StmtInfo & arg_map,
02572 Expression * expr)
02573 {
02574
02575 switch (expr->op()) {
02576
02577 case INTEGER_CONSTANT_OP:
02578 case REAL_CONSTANT_OP:
02579 case LOGICAL_CONSTANT_OP:
02580 case ID_OP:
02581 break;
02582
02583 case ARRAY_REF_OP:
02584 {
02585
02586 for (Mutator<Expression> subs_mutr = expr->subscript().arg_list();
02587 subs_mutr.valid(); ++subs_mutr) {
02588 Expression & current_subs = subs_mutr.current();
02589
02590 if (current_subs.op() != INTEGER_CONSTANT_OP) {
02591 Assign<Expression> subs_as(subs_mutr.assign());
02592 subs_as = get_precalc(subs_mutr.pull(),
02593 *arg_map.program_ref,
02594 *arg_map.stmt_ref,
02595 PRECALC_ALWAYS, "PC");
02596 }
02597 }
02598 break;
02599 }
02600
02601
02602 case SUBSTRING_OP:
02603 {
02604
02605
02606
02607 List<Expression> & bound_list = expr->bound().arg_list();
02608 int bound_entries = bound_list.entries();
02609
02610
02611
02612 int base_len = expr->string().base_variable_ref()->type().size();
02613
02614 switch (bound_list[0].op()) {
02615
02616 case INTEGER_CONSTANT_OP:
02617 break;
02618 case OMEGA_OP:
02619 {
02620 bound_list.del(0);
02621 bound_list.ins_first(constant(1));
02622 break;
02623 }
02624 default: {
02625 Assign<Expression> bound_as(bound_list.assign(0));
02626 bound_as = get_precalc(bound_list.pull(0),
02627 *arg_map.program_ref,
02628 *arg_map.stmt_ref,
02629 PRECALC_ALWAYS, "PC");
02630 }
02631 }
02632
02633 if (bound_entries==2)
02634 switch (bound_list[1].op()) {
02635
02636 case INTEGER_CONSTANT_OP:
02637 break;
02638 case OMEGA_OP:
02639 {
02640 bound_list.del(1);
02641 bound_list.ins_last(constant(base_len));
02642 break;
02643 }
02644 default: {
02645 Assign<Expression> bound_as(bound_list.assign(1));
02646 bound_as = get_precalc(bound_list.pull(1),
02647 *arg_map.program_ref,
02648 *arg_map.stmt_ref,
02649 PRECALC_ALWAYS, "PC");
02650 }
02651 }
02652
02653 else
02654
02655
02656
02657
02658 bound_list.ins_last(constant(base_len));
02659
02660
02661
02662 expr->left(remap_args_precalc_expr(arg_map,expr->grab_left()));
02663 break;
02664 }
02665
02666 default:
02667 expr = get_precalc(expr,
02668 *arg_map.program_ref,
02669 *arg_map.stmt_ref,
02670 PRECALC_ALWAYS, "PC");
02671 }
02672
02673 return expr;
02674
02675 }
02676
02677
02678
02679
02680 static Statement *
02681 remap_args_precalc(ProgramUnit & pgm_main,
02682 Statement & s)
02683 {
02684 Statement *prev_stmt_ref = s.prev_ref();
02685 Expression *arglist_ptr = 0;
02686
02687
02688
02689 switch (s.stmt_class()) {
02690 case CALL_STMT:
02691 {
02692 if (s.parameters_valid())
02693 arglist_ptr = &s.parameters_guarded();
02694 else
02695 return &s;
02696 break;
02697 }
02698
02699 case ASSIGNMENT_STMT:
02700 {
02701 if ((s.rhs().op() == FUNCTION_CALL_OP) &&
02702 (s.rhs().parameters_valid()))
02703 arglist_ptr = &(s.rhs().parameters_guarded());
02704 else
02705 return &s;
02706 break;
02707 }
02708
02709 default:
02710 return &s;
02711 }
02712
02713
02714 StmtInfo arg_map;
02715
02716 arg_map.program_ref = &pgm_main;
02717 arg_map.stmt_ref = &s;
02718
02719
02720 for (Mutator<Expression> arg_mutr = arglist_ptr->arg_list();
02721 arg_mutr.valid(); ++arg_mutr) {
02722 Assign<Expression> expr_as(arg_mutr.assign());
02723 expr_as = remap_args_precalc_expr(arg_map, arg_mutr.pull());
02724 }
02725
02726
02727
02728 s.build_refs();
02729
02730 if (prev_stmt_ref)
02731 return prev_stmt_ref->next_ref();
02732 else
02733 return pgm_main.stmts().first_ref();
02734 }
02735
02736
02737
02738 static Expression *
02739 precalc_func_call(Expression * e, ExtraInfo & extra_info)
02740 {
02741 StmtInfo & arg_map = *((Info<StmtInfo * >&) extra_info).data();
02742
02743 return get_precalc(e->clone(), *arg_map.program_ref, *arg_map.stmt_ref,
02744 PRECALC_ALWAYS, "PC");
02745 }
02746
02747
02748
02749
02750
02751
02752
02753 static Expression *
02754 precalc_non_do_expr(Expression * e, ExtraInfo & extra_info)
02755 {
02756 static AnyOfType func_call_pattern(FUNCTION_CALL_OP);
02757
02758 if (e->op() == FUNCTION_CALL_OP)
02759 return replace(e, func_call_pattern, precalc_func_call,
02760 extra_info, NON_RECURSIVE_REPLACE,
02761 POSTORDER_REPLACE);
02762 else
02763 return e;
02764
02765 }
02766
02767
02768
02769 static Statement &
02770 clean_statement(ProgramUnit & pgm,
02771 Statement & s)
02772 {
02773
02774 static AnyOfType func_call_pattern(FUNCTION_CALL_OP);
02775 static StmtInfo arg_map;
02776
02777 Statement *prev_stmt_ref = s.prev_ref();
02778 STMT_TYPE stype = s.stmt_class();
02779
02780 arg_map.program_ref = &pgm;
02781 arg_map.stmt_ref = &s;
02782
02783 switch (stype) {
02784
02785 case ASSIGNMENT_STMT: {
02786
02787
02788
02789
02790 if (s.lhs().op() == ID_OP) {
02791 for (Mutator<Expression> expr_mutr = s.rhs().arg_list();
02792 expr_mutr.valid(); ++expr_mutr) {
02793 Info<StmtInfo *> inf(&arg_map);
02794 Assign<Expression> expr_as(expr_mutr.assign());
02795 expr_as = replace(expr_mutr.pull(),
02796 func_call_pattern,
02797 precalc_func_call, inf,
02798 NON_RECURSIVE_REPLACE,
02799 POSTORDER_REPLACE);
02800 }
02801 }
02802
02803
02804 else {
02805 for (Mutator<Expression> expr_mutr = s.iterate_expressions();
02806 expr_mutr.valid(); ++expr_mutr) {
02807 Info<StmtInfo *> inf(&arg_map);
02808 Assign<Expression> expr_as(expr_mutr.assign());
02809 expr_as = replace(expr_mutr.pull(),
02810 func_call_pattern,
02811 precalc_func_call, inf,
02812 NON_RECURSIVE_REPLACE,
02813 POSTORDER_REPLACE);
02814 }
02815 }
02816 break;
02817 }
02818
02819 case READ_STMT:
02820 case WRITE_STMT:
02821 case PRINT_STMT: {
02822
02823
02824
02825
02826 static WildcardOr * full_pattern =
02827 new WildcardOr(new AnyOfType(FUNCTION_CALL_OP),
02828 new AnyOfType(DO_OP));
02829
02830 for (Mutator<Expression> expr_mutr = s.iterate_expressions();
02831 expr_mutr.valid(); ++expr_mutr) {
02832 Info<StmtInfo *> inf(&arg_map);
02833
02834 Assign<Expression> expr_as(expr_mutr.assign());
02835 expr_as = replace(expr_mutr.pull(),
02836 *full_pattern,
02837 precalc_non_do_expr, inf,
02838 NON_RECURSIVE_REPLACE,
02839 PREORDER_REPLACE);
02840 }
02841 break;
02842 }
02843
02844 default: {
02845
02846
02847
02848 for (Mutator<Expression> expr_mutr = s.iterate_expressions();
02849 expr_mutr.valid(); ++expr_mutr) {
02850 Info<StmtInfo *> inf(&arg_map);
02851 Assign<Expression> expr_as(expr_mutr.assign());
02852 expr_as = replace(expr_mutr.pull(),
02853 func_call_pattern,
02854 precalc_func_call, inf,
02855 NON_RECURSIVE_REPLACE,
02856 POSTORDER_REPLACE);
02857 }
02858 }
02859 }
02860
02861
02862 Statement *first_stmt_ref;
02863
02864 if (prev_stmt_ref)
02865 first_stmt_ref = prev_stmt_ref->next_ref();
02866 else
02867 first_stmt_ref = &s;
02868
02869 RefSet<Statement> processed_stmts;
02870
02871
02872
02873 do {
02874 processed_stmts.ins(*first_stmt_ref);
02875 first_stmt_ref = remap_args_precalc(pgm, *first_stmt_ref);
02876 }
02877 while (!processed_stmts.member(*first_stmt_ref));
02878
02879
02880
02881 if (first_stmt_ref != &s) {
02882
02883
02884
02885 Statement * stmt_ref = first_stmt_ref->next_ref();
02886
02887 while (stmt_ref != &s) {
02888
02889 while (!processed_stmts.member(*stmt_ref)) {
02890 processed_stmts.ins(*stmt_ref);
02891 stmt_ref = remap_args_precalc(pgm, *stmt_ref);
02892 }
02893 stmt_ref = stmt_ref->next_ref();
02894 }
02895
02896
02897
02898 if (!processed_stmts.member(s))
02899 s.build_refs();
02900
02901 }
02902
02903
02904
02905 return *first_stmt_ref;
02906 }
02907
02908
02909
02910 static void
02911 clean_variables(ProgramUnit & pgm)
02912 {
02913 List<StringElem> rename_list;
02914
02915 for (DictionaryIter<Symbol> sym_iter = pgm.symtab().iterator();
02916 sym_iter.valid(); ++ sym_iter) {
02917
02918 Symbol & current_symbol = sym_iter.current();
02919
02920 switch (current_symbol.sym_class()) {
02921
02922 case VARIABLE_CLASS:
02923 case SYMBOLIC_CONSTANT_CLASS: {
02924
02925 const char *current_tag = current_symbol.name_ref();
02926 if(lookup_intrinsic(current_tag))
02927 rename_list.ins_last(new StringElem(current_tag));
02928 }
02929 default: break;
02930 }
02931 }
02932
02933 for (Iterator<StringElem> rename_iter = rename_list;
02934 rename_iter.valid(); ++rename_iter) {
02935
02936 Symbol * symbol_ptr = pgm.symtab().grab(rename_iter.current());
02937 pgm.symtab().rename_and_ins(symbol_ptr);
02938 }
02939 }
02940
02941
02942
02943 int
02944 count_stmt(Statement & stmt,
02945 int stmt_counter)
02946 {
02947 switch (stmt.stmt_class()) {
02948 case UNDEFINED_STMT:
02949 case IMPLIED_GOTO_STMT:
02950 case FLOW_ENTRY_STMT:
02951 case FLOW_EXIT_STMT:
02952 case BLOCK_ENTRY_STMT:
02953 case BLOCK_EXIT_STMT:
02954 case ENTRY_STMT:
02955 case LABEL_STMT:
02956 case ALLOCATE_STMT:
02957 case DEALLOCATE_STMT:
02958 case NULLIFY_STMT:
02959 case DIRECTIVE_STMT:
02960 case STMT_PTR:
02961 return stmt_counter;
02962 default: break;
02963 }
02964 return ++stmt_counter;
02965 }
02966
02967
02968
02969 static int
02970 count_stmts(Iterator<Statement> stmt_iter)
02971 {
02972 int executable_stmts = 0;
02973 for (; stmt_iter.valid(); ++stmt_iter)
02974 executable_stmts = count_stmt(stmt_iter.current(), executable_stmts);
02975 return executable_stmts;
02976 }
02977
02978
02979
02980
02981 void
02982 clean_program(ProgramUnit & pgm, Element<InlineWorkSpace> & ws_ref)
02983 {
02984 clean_variables(pgm);
02985 int executable_stmts = 0;
02986 for (Iterator<Statement> stmt_iter = pgm.stmts().iterator();
02987 stmt_iter.valid(); ++stmt_iter) {
02988 Statement & current_stmt = stmt_iter.current();
02989 if (ws_ref->count_active())
02990 executable_stmts = count_stmt(current_stmt, executable_stmts);
02991 Statement & first_precalc_stmt =
02992 clean_statement(pgm, current_stmt);
02993
02994 if (&first_precalc_stmt != ¤t_stmt) {
02995
02996
02997
02998
02999 RefList<Assertion> assertlist;
03000
03001 for (Iterator<Assertion> assert_iter = current_stmt.assertions();
03002 assert_iter.valid(); ++ assert_iter) {
03003 Assertion & current_assert = assert_iter.current();
03004 AssertionType current_type = current_assert.type();
03005
03006 if ((current_type == AS_INLINE) ||
03007 (current_type == AS_RECURSIVEINLINE) ||
03008 (current_type == AS_NOINLINE) ||
03009 (current_type == AS_SIDE_EFFECT_FREE)) {
03010 assertlist.ins_last(current_assert);
03011 break;
03012 }
03013 }
03014
03015 int entries = assertlist.entries();
03016
03017 if (entries > 0 || ws_ref->count_active()) {
03018
03019
03020
03021 for (Iterator<Statement> prop_iter =
03022 pgm.stmts().iterator(first_precalc_stmt,
03023 *current_stmt.prev_ref());
03024 prop_iter.valid(); ++prop_iter) {
03025 Statement & prop_stmt = prop_iter.current();
03026
03027 if (ws_ref->count_active())
03028 executable_stmts = count_stmt(prop_stmt, executable_stmts);
03029
03030
03031 if (entries > 0) {
03032 for (Iterator<Assertion> assertion_iter = assertlist;
03033 assertion_iter.valid();
03034 ++assertion_iter) {
03035 if ((prop_stmt.stmt_class()==ASSIGNMENT_STMT) &&
03036 (prop_stmt.rhs().op()==FUNCTION_CALL_OP))
03037 prop_stmt.assertions().ins_last(assertion_iter.current().clone());
03038 }
03039 }
03040 }
03041
03042
03043
03044 if (entries > 0) {
03045
03046 for (Iterator<Assertion> assert_iter = assertlist;
03047 assert_iter.valid();
03048 ++assert_iter) {
03049
03050
03051
03052 if ((assert_iter.current().type() == AS_INLINE) ||
03053 (assert_iter.current().type() == AS_RECURSIVEINLINE) ||
03054 (assert_iter.current().type() == AS_NOINLINE)) {
03055 STMT_TYPE stype = current_stmt.stmt_class();
03056
03057 if (stype == CALL_STMT)
03058 continue;
03059 if ((stype != ASSIGNMENT_STMT) ||
03060 current_stmt.rhs().op() != FUNCTION_CALL_OP)
03061 current_stmt.assertions().del(assert_iter.current());
03062 } else {
03063 current_stmt.assertions().del(assert_iter.current());
03064 }
03065 }
03066 }
03067 }
03068 }
03069 }
03070
03071
03072 if (ws_ref->count_active()) {
03073 int total_stmts = pgm.stmts().entries();
03074 pgm.work_stack().push(new InlineWorkSpace(*ws_ref,
03075 executable_stmts,
03076 total_stmts));
03077 const char * routine_name_ref = pgm.routine_name_ref();
03078 const char * null_name_ref = "NULL";
03079 cout << "Routine " << (routine_name_ref ? routine_name_ref : null_name_ref)
03080 << ": <" << executable_stmts << ", " << total_stmts << ">\n";
03081 int exec_routine_count =
03082 InlineWorkSpace::exec_routine_count() + 1;
03083 InlineWorkSpace::exec_routine_count(exec_routine_count);
03084 int total_routine_count =
03085 InlineWorkSpace::total_routine_count() + 1;
03086 InlineWorkSpace::total_routine_count(total_routine_count);
03087 int exec_line_count =
03088 InlineWorkSpace::exec_line_count() + executable_stmts;
03089 InlineWorkSpace::exec_line_count(exec_line_count);
03090 int total_line_count =
03091 InlineWorkSpace::total_line_count() + total_stmts;
03092 InlineWorkSpace::total_line_count(total_line_count);
03093 }
03094 }
03095
03096
03097
03098 void
03099 cleanup_program(ProgramUnit & pgm)
03100 {
03101
03102 static String dc_debug_switch("dead_debug");
03103
03104
03105
03106 RefSet<Symbol> candidate_set;
03107
03108 for (DictionaryIter<Symbol> symbol_iter = pgm.symtab().iterator();
03109 symbol_iter.valid(); ++symbol_iter) {
03110
03111 Symbol & current_symbol = symbol_iter.current();
03112 const Type & current_type = current_symbol.type();
03113
03114 if ((current_type.data_type() == INTEGER_TYPE) &&
03115 (current_type.is_scalar()) &&
03116 (strncmp(current_symbol.name_ref(),"PC",2) == 0))
03117 candidate_set.ins(current_symbol);
03118 }
03119
03120 if (candidate_set.entries()) {
03121
03122
03123
03124 propagate_constants(pgm, candidate_set, REMOVE_UNREACH_CODE);
03125
03126
03127
03128 expand_small_substituted(pgm);
03129
03130
03131
03132 clear_substituted(pgm);
03133
03134 }
03135
03136
03137
03138 eliminate_dead_code(pgm, DONT_DEADCODE_ARRAYS,
03139 switch_value(dc_debug_switch));
03140
03141 }
03142
03143
03144
03145
03146 static Expression *
03147 simplify_subs_exprs(Expression * expr)
03148
03149 {
03150
03151 switch (expr->op()) {
03152
03153 case ARRAY_REF_OP:
03154 case SUBSTRING_OP:
03155
03156
03157
03158 return simplify(expr);
03159
03160 default:
03161
03162
03163 for (Mutator<Expression> expr_mutr = expr->arg_list();
03164 expr_mutr.valid(); ++expr_mutr) {
03165 Assign<Expression> expr_as(expr_mutr.assign());
03166 expr_as = simplify_subs_exprs(expr_mutr.pull());
03167 }
03168 }
03169 return expr;
03170 }
03171
03172
03173
03174
03175
03176 int
03177 InlineObject::_translate_symbol_refs_mutr(Mutator<Expression> expr_mutr,
03178 LambdaInfo & lambda,
03179 REF_TYPE ref)
03180 {
03181 int modify_counter = 0;
03182
03183 for (; expr_mutr.valid(); ++expr_mutr) {
03184
03185 int local_modify_counter = 0;
03186
03187
03188
03189 Assign<Expression> ex_as(expr_mutr.assign());
03190 Expression * ex = expr_mutr.pull();
03191
03192
03193
03194 local_modify_counter = remap_expr( &ex, lambda, ref );
03195
03196
03197
03198
03199 if (local_modify_counter) {
03200 modify_counter += local_modify_counter;
03201 ex = simplify_subs_exprs(ex);
03202 }
03203
03204
03205
03206 ex_as = ex;
03207 }
03208
03209 return modify_counter;
03210 }
03211
03212
03213
03214
03215 int
03216 InlineObject::remap_expr( Expression ** ex, LambdaInfo & lambda, REF_TYPE ref ) const
03217 {
03218 int local_modify_counter = 0;
03219
03220 while (1) {
03221
03222 bool local_expr_flag = false;
03223
03224 *ex = _translate_symbol_refs_expr(*ex, ref, local_expr_flag,
03225 &(this->_formal_to_actual));
03226
03227
03228
03229
03230 if (local_expr_flag) {
03231 ++local_modify_counter;
03232 *ex = remove_lambda_calls(*ex, lambda);
03233 }
03234 else
03235 break;
03236 }
03237 return local_modify_counter;
03238 }
03239
03240
03241
03242
03243
03244
03245
03246 void
03247 InlineObject::_translate_symbol_refs_entry(LambdaInfo & lambda)
03248 {
03249 Statement & s = *lambda.stmt_ref;
03250
03251
03252
03253
03254
03255
03256 for (Iterator<Assertion> assert_iter = s.assertions();
03257 assert_iter.valid(); ++assert_iter) {
03258
03259 Assertion & current_assert = assert_iter.current();
03260
03261
03262 if (current_assert.arg_list_valid()) {
03263 _translate_symbol_refs_mutr(Mutator<Expression>(current_assert.arg_list_guarded()),
03264 lambda, IN_REF_EXPR);
03265 }
03266 }
03267
03268
03269
03270 if (s.parameters_valid()) {
03271 bool modify_flag = false;
03272 for (Iterator<Expression> expr_iter = s.parameters_guarded().arg_list();
03273 expr_iter.valid(); ++expr_iter) {
03274 Expression & expr = expr_iter.current();
03275 p_assert(expr.op() == ID_OP,
03276 "Invalid parameter encountered in _translate_symbol_refs_entry_");
03277 SymRefElem *symbol_ref
03278 = _symbol_map.find_ref(expr.symbol());
03279 if (symbol_ref) {
03280
03281 modify_flag = true;
03282 expr.symbol(*symbol_ref->symref());
03283 }
03284 }
03285 if (modify_flag)
03286 s.build_refs();
03287 }
03288 return;
03289 }
03290
03291
03292
03293
03294 void
03295 InlineObject::_translate_symbol_refs_stmt(LambdaInfo & lambda,
03296 TRANS_CLEANUP_TYPE cleanup)
03297 {
03298 Statement & s = *lambda.stmt_ref;
03299 Statement * prev_stmt_ref = s.prev_ref();
03300
03301
03302 bool modify_flag = false;
03303
03304
03305
03306
03307
03308 for (Iterator<Assertion> assert_iter = s.assertions();
03309 assert_iter.valid(); ++assert_iter) {
03310
03311 Assertion & current_assert = assert_iter.current();
03312
03313
03314 if (current_assert.arg_list_valid()) {
03315 _translate_symbol_refs_mutr(Mutator<Expression>(current_assert.arg_list_guarded()),
03316 lambda, IN_REF_EXPR);
03317 }
03318 }
03319
03320
03321
03322
03323 if (s.s_control_valid()) {
03324 for (Iterator<s_control_type> s_iter = s.s_control_guarded();
03325 s_iter.valid(); ++s_iter) {
03326 if (_translate_symbol_refs_mutr(Mutator<Expression>(s_iter.current().expr),
03327 lambda, IN_REF_EXPR))
03328 modify_flag = true;
03329 }
03330 }
03331
03332
03333
03334
03335 if (s.iterate_in_exprs_valid() &&
03336 _translate_symbol_refs_mutr(s.iterate_in_exprs_guarded(),lambda,
03337 IN_REF_EXPR))
03338 modify_flag = true;
03339
03340 if (s.iterate_out_exprs_valid()) {
03341
03342 Mutator<Expression> out_mutr = s.iterate_out_exprs_guarded();
03343 if (_translate_symbol_refs_mutr(out_mutr,lambda,OUT_REF_EXPR)) {
03344 modify_flag = true;
03345 if ((s.stmt_class()==ASSIGNMENT_STMT) &&
03346 (s.lhs().op()==INTRINSIC_CALL_OP))
03347 fix_alternate_expr(s, _pgm_main);
03348 }
03349 }
03350
03351 if (s.iterate_in_out_exprs_valid() &&
03352 _translate_symbol_refs_mutr(s.iterate_in_out_exprs_guarded(),lambda,
03353 IN_OUT_REF_EXPR))
03354 modify_flag = true;
03355
03356
03357
03358 if (!modify_flag)
03359 return;
03360
03361
03362
03363
03364 if (cleanup != CLEANUP_NEEDED) {
03365 s.build_refs();
03366 return;
03367 }
03368
03369
03370
03371
03372 Statement *first_stmt_ref;
03373
03374
03375
03376
03377 p_assert(prev_stmt_ref, "Replacement done for first statement in StmtList");
03378
03379 if (prev_stmt_ref != s.prev_ref()) {
03380 Statement *clean_stmt = prev_stmt_ref->next_ref();
03381
03382
03383
03384
03385
03386 first_stmt_ref = &clean_statement(*_pgm_ref, *clean_stmt);
03387
03388
03389
03390
03391 for (Iterator<Statement> precalc_stmt_iter
03392 = _pgm_ref->stmts().iterator(*clean_stmt->next_ref(), s);
03393 precalc_stmt_iter.valid();
03394 ++precalc_stmt_iter) {
03395 clean_statement(*_pgm_ref, precalc_stmt_iter.current());
03396 }
03397 }
03398 else {
03399
03400
03401 first_stmt_ref = &clean_statement(*_pgm_ref, s);
03402 }
03403
03404
03405 s.build_refs();
03406
03407
03408 if (first_stmt_ref == &s)
03409 return;
03410
03411
03412
03413
03414 RefList<Symbol> rename_list;
03415
03416 for (Iterator<Statement> precalc_stmt_iter
03417 = _pgm_ref->stmts().iterator(*first_stmt_ref, *s.prev_ref());
03418 precalc_stmt_iter.valid();
03419 ++precalc_stmt_iter) {
03420 Statement & precalc_stmt
03421 = precalc_stmt_iter.current();
03422
03423 p_assert(precalc_stmt.stmt_class() == ASSIGNMENT_STMT,
03424 "Non-assignment statement encountered "
03425 "in translate_symbol_refs_stmt");
03426
03427 _remap_variable_symbol(precalc_stmt.lhs().symbol(), rename_list);
03428 }
03429
03430
03431 _remap_variable_symbols(rename_list);
03432
03433
03434 LambdaInfo our_lambda(_pgm_ref, 0, INLINE_CALL);
03435
03436 for (Iterator<Statement> trans_stmt_iter
03437 = _pgm_ref->stmts().iterator(*first_stmt_ref, *s.prev_ref());
03438 trans_stmt_iter.valid(); ++trans_stmt_iter) {
03439 our_lambda.stmt_ref = &trans_stmt_iter.current();
03440 _translate_symbol_refs_stmt(our_lambda, cleanup);
03441 }
03442
03443
03444
03445
03446
03447
03448
03449 our_lambda.stmt_ref = &s;
03450
03451 _translate_symbol_refs_stmt(our_lambda, NO_CLEANUP_NEEDED);
03452 }
03453
03454
03455
03456
03457 void
03458 InlineObject::translate_symbol_refs(TRANS_CLEANUP_TYPE cleanup)
03459 {
03460 static LambdaInfo lambda(0, 0, INLINE_CALL);
03461
03462 lambda.program_ref = _pgm_ref;
03463
03464
03465
03466 if ((!_symbol_map.entries()) && (!_constant_map.entries()) &&
03467 (!_format_map.entries()))
03468 return;
03469
03470
03471
03472 for (Iterator<Statement> stmt_iter = _pgm_ref->stmts().iterator();
03473 stmt_iter.valid(); ++stmt_iter) {
03474 Statement & s = stmt_iter.current();
03475 if ((s.stmt_class()!=ENTRY_STMT)) {
03476 lambda.stmt_ref = &s;
03477 _translate_symbol_refs_stmt(lambda, cleanup);
03478 }
03479 else if (cleanup == NO_CLEANUP_NEEDED) {
03480 lambda.stmt_ref = &s;
03481 _translate_symbol_refs_entry(lambda);
03482 }
03483 }
03484 }
03485
03486
03487
03488
03489
03490
03491
03492
03493 Statement &
03494 InlineObject::_remap_merge_stmts(Statement & entry_statement, Statement & s,
03495 bool recursive)
03496 {
03497
03498
03499
03500 Statement &flow_entry = _pgm_ref->stmts().first();
03501 Statement &flow_exit = _pgm_ref->stmts().last();
03502 cout<<"The flow exit statement is "<<endl; flow_exit.print(cout); cout<<endl;
03503
03504
03505
03506 RefSet<Statement> entry_refset = flow_entry.succ();
03507
03508
03509
03510
03511 if (flow_entry.next_ref() != &entry_statement) {
03512
03513 Statement * next_stmt_ref = entry_statement.next_ref();
03514
03515
03516
03517 switch (next_stmt_ref->stmt_class()) {
03518
03519 case LABEL_STMT:
03520 break;
03521 case GOTO_STMT:
03522 {
03523 next_stmt_ref = next_stmt_ref->target_ref();
03524 break;
03525 }
03526 default:
03527 p_abort("Irregular entry point encountered in _remap_merge_stmts");
03528
03529 }
03530
03531
03532
03533 Statement * goto_stmt = new GotoStmt(_pgm_ref->stmts().new_tag(),
03534 next_stmt_ref);
03535 _pgm_ref->stmts().ins_after(goto_stmt, &flow_entry);
03536
03537 }
03538
03539
03540
03541 _pgm_ref->stmts().del(entry_refset);
03542
03543
03544
03545 Statement & routine_exit_stmt = *flow_exit.prev_ref();
03546 cout<<"The routine exit statement is "<<endl; routine_exit_stmt.print(cout); cout<<endl;
03547 switch (routine_exit_stmt.stmt_class()) {
03548 case STOP_STMT:
03549 break;
03550 case RETURN_STMT: {
03551 _pgm_ref->stmts().del(routine_exit_stmt);
03552 break;
03553 }
03554 default:
03555 p_abort("Irregular exit point encountered in _remap_merge_stmts");
03556 }
03557
03558
03559
03560 remove_unreachable_code(*_pgm_ref);
03561 remove_trivial_gotos(*_pgm_ref);
03562
03563 RefSet<Symbol> candidate_set;
03564
03565
03566
03567
03568 if (_precalc_vars) {
03569
03570 for (KeyIterator<Symbol,SymRefElem> precalc_iter = _symbol_map;
03571 precalc_iter.valid(); ++precalc_iter) {
03572
03573 SymRefElem & current_ref = precalc_iter.current_data();
03574
03575 if (current_ref.precalc()==CAND_PRECALC_VAR) {
03576
03577 Symbol & precalc_symbol = *current_ref.symref();
03578 candidate_set.ins(precalc_symbol);
03579 }
03580 }
03581 }
03582
03583
03584
03585 Statement * flow_exit_prev = flow_exit.prev_ref();
03586 if (flow_exit_prev == &flow_entry)
03587 flow_exit_prev = 0;
03588
03589 _pgm_ref->stmts().ins_BLOCK_after(&flow_entry,
03590 flow_exit_prev);
03591
03592 Statement * block_entry_stmt = flow_entry.next_ref();
03593 Statement * block_exit_stmt = flow_exit.prev_ref();
03594
03595
03596
03597
03598 block_exit_stmt->work_stack().push(new InlineWorkSpace(*_ws_ref));
03599
03600
03601
03602
03603 Assertion * private_assert_ref = 0;
03604
03605 for (Mutator<Assertion> assert_mutr = s.assertions();
03606 assert_mutr.valid(); ++assert_mutr) {
03607 Assertion * assert_ref = assert_mutr.grab();
03608 if(assert_ref->type()==AS_PRIVATE)
03609 private_assert_ref = assert_ref;
03610 block_entry_stmt->assertions().ins_last(assert_ref);
03611 }
03612
03613
03614
03615
03616 if (_private_vars) {
03617
03618 if (!private_assert_ref) {
03619 private_assert_ref = new AssertPrivate;
03620 block_entry_stmt->assertions().ins_last(private_assert_ref);
03621 }
03622
03623 List<Expression> & private_list = private_assert_ref->arg_list_guarded();
03624
03625
03626
03627 for (KeyIterator<Symbol,SymRefElem> private_iter = _symbol_map;
03628 private_iter.valid(); ++private_iter) {
03629
03630 SymRefElem & current_ref = private_iter.current_data();
03631
03632 if (current_ref.privat()==PRIVATE) {
03633
03634 Symbol & private_symbol = *current_ref.symref();
03635
03636 if(private_symbol.is_array()) {
03637
03638
03639
03640
03641 Expression * private_subscript = comma();
03642 List<Expression> & private_arg_list =
03643 private_subscript->arg_list();
03644
03645 for (Iterator<ArrayBounds>private_bound_iter = private_symbol.dim();
03646 private_bound_iter.valid(); ++private_bound_iter) {
03647 ArrayBounds & private_bound = private_bound_iter.current();
03648 Expression * lower_ptr;
03649 if(private_bound.lower_exists())
03650 lower_ptr = private_bound.lower_guarded().clone();
03651 else
03652 lower_ptr = constant(1);
03653 Expression * upper_ptr;
03654 if(private_bound.upper_exists())
03655 upper_ptr = private_bound.upper_guarded().clone();
03656 else
03657 upper_ptr = constant(1);
03658 private_arg_list.ins_last(colon(lower_ptr, upper_ptr, NULL));
03659 }
03660 private_list.ins_last(array_reference(id(private_symbol),
03661 private_subscript));
03662 }
03663 else
03664 private_list.ins_last(id(private_symbol));
03665 }
03666 }
03667 }
03668
03669
03670
03671
03672 if (_test_exprs.entries()) {
03673 AssertRelation * test_exprs_ref = new AssertRelation;
03674 List<Expression> & expr_args = test_exprs_ref->arg_list_guarded();
03675 for (Mutator<Expression> test_mutr = _test_exprs;
03676 test_mutr.valid(); ++test_mutr)
03677 expr_args.ins_last(test_mutr.grab());
03678 block_entry_stmt->assertions().ins_last(test_exprs_ref);
03679 }
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692
03693
03694
03695
03696
03697
03698
03699
03700 if (_debug_flag) {
03701
03702 AssertComment * begin_comment_ref = new AssertComment;
03703 List<StringElem> & begin_args =
03704 begin_comment_ref->string_arg_list_guarded();
03705 for (Mutator<StringElem> begin_mutr = _begin_comment_list;
03706 begin_mutr.valid(); ++begin_mutr)
03707 begin_args.ins_last(begin_mutr.grab());
03708 block_entry_stmt->assertions().ins_last(begin_comment_ref);
03709
03710 AssertComment * end_comment_ref = new AssertComment;
03711 List<StringElem> & end_args =
03712 end_comment_ref->string_arg_list_guarded();
03713 for (Mutator<StringElem> end_mutr = _end_comment_list;
03714 end_mutr.valid(); ++end_mutr)
03715 end_args.ins_last(end_mutr.grab());
03716 block_exit_stmt->assertions().ins_last(end_comment_ref);
03717
03718 }
03719
03720
03721
03722 Statement * caller_next_ref = s.next_ref();
03723
03724
03725
03726
03727 Statement * precalc_ref = s.prev_ref();
03728
03729 Statement * first_precalc_ref = 0;
03730
03731 while (precalc_ref &&
03732 (precalc_ref->stmt_class() == ASSIGNMENT_STMT) &&
03733 (precalc_ref->lhs().op()==ID_OP) &&
03734 (strncmp(precalc_ref->lhs().symbol().name_ref(),"PC",2) == 0)) {
03735
03736 first_precalc_ref = precalc_ref;
03737
03738 Symbol & precalc_symbol = precalc_ref->lhs().symbol();
03739
03740 const Type & precalc_type = precalc_symbol.type();
03741
03742
03743
03744 if ((precalc_type.data_type() == INTEGER_TYPE) &&
03745 (precalc_type.is_scalar()))
03746 candidate_set.ins(precalc_symbol);
03747
03748 precalc_ref = precalc_ref->prev_ref();
03749 }
03750
03751
03752
03753
03754 if (first_precalc_ref) {
03755 Statement & first_precalc_stmt = *first_precalc_ref;
03756
03757 Statement & last_precalc_stmt = *s.prev_ref();
03758 StmtList & main_stmts = _pgm_main.stmts();
03759 List<Statement> * precalc_block =
03760 main_stmts.grab(first_precalc_stmt, last_precalc_stmt, DONT_RELABEL);
03761 _pgm_ref->stmts().ins_after(precalc_block, &flow_entry);
03762 }
03763
03764 if (candidate_set.entries()) {
03765
03766
03767
03768 propagate_constants(*_pgm_ref, candidate_set, REMOVE_UNREACH_CODE);
03769
03770
03771
03772 expand_small_substituted(*_pgm_ref);
03773
03774
03775
03776 clear_substituted(*_pgm_ref);
03777
03778 }
03779
03780
03781
03782 Statement *first_stmt_ref = flow_entry.next_ref();
03783
03784
03785
03786 List<Statement> *grabbed_block =
03787 _pgm_ref->stmts().grab(*first_stmt_ref,
03788 *flow_exit.prev_ref(),
03789 DONT_RELABEL);
03790
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805 _pgm_main.stmts().del(s);
03806
03807
03808 _pgm_main.stmts().ins_before(grabbed_block, caller_next_ref);
03809
03810
03811
03812
03813
03814 if (recursive) {
03815 Iterator<Statement> stmt_iter(_pgm_main.stmts(),
03816 block_entry_stmt,
03817 block_exit_stmt);
03818
03819 for (; stmt_iter.valid(); ++stmt_iter) {
03820 Statement & s_here = stmt_iter.current();
03821 STMT_TYPE stype = s_here.stmt_class();
03822
03823 switch (stype) {
03824
03825
03826 case ASSIGNMENT_STMT:
03827 case CALL_STMT:
03828 if ((stype != ASSIGNMENT_STMT) ||
03829 (s_here.rhs().op() == FUNCTION_CALL_OP)) {
03830 bool assert_noinline = false;
03831 bool no_assertions = true;
03832 for (Iterator<Assertion> assert_iter = s_here.assertions();
03833 assert_iter.valid(); ++assert_iter) {
03834
03835 AssertionType current_type = assert_iter.current().type();
03836 if (current_type==AS_NOINLINE) {
03837 no_assertions = false;
03838 assert_noinline = true;
03839 }
03840 else if ((current_type == AS_INLINE) ||
03841 (current_type == AS_RECURSIVEINLINE)) {
03842 no_assertions = false;
03843 }
03844 }
03845 if (!assert_noinline) {
03846 Assertion * s_here_assert = new AssertRecursiveInline;
03847
03848 s_here.assertions().ins_last(s_here_assert);
03849 }
03850 }
03851 break;
03852 default: break;
03853 }
03854 }
03855 }
03856
03857
03858
03859 return *first_stmt_ref;
03860 }
03861
03862
03863
03864
03865
03866
03867 Statement &
03868 InlineObject::inline_expand(Statement & s, bool recursive)
03869 {
03870
03871 static String debug_switch("inline_debug");
03872 _debug_flag = switch_value(debug_switch);
03873
03874 if (_debug_flag > 9) {
03875 int i = 0;
03876 cerr << "Inliner called to substitute the following statement:\n ";
03877 s.write(cerr, i);
03878 cerr.flush();
03879 }
03880
03881
03882 if (!_permanent_changes) {
03883 float_entry_points(*_pgm_ref);
03884 sink_return_points(*_pgm_ref);
03885 _remap_local_variables();
03886 _precalc_adjustable_array_bounds();
03887 prepare_routines_for_arg_mapping();
03888 _remap_local_variables();
03889 _remap_and_move_formats();
03890
03891 _permanent_changes = true;
03892 }
03893
03894
03895 InlineObject proto_work(*this);
03896
03897
03898 proto_work._rename_branch_targets();
03899
03900
03901 Statement & entry_statement = proto_work._remap_arg_uses(s);
03902
03903
03904 proto_work.translate_symbol_refs(CLEANUP_NEEDED);
03905
03906
03907
03908 Statement & t = proto_work._remap_merge_stmts(entry_statement, s, recursive);
03909
03910
03911 substitute_parameters(_pgm_main, IGNORE_REALS);
03912
03913
03914 return t;
03915 }
03916
03917 void
03918 InlineObject::prepare_routines_for_arg_mapping()
03919 {
03920 substitute_parameters(*_pgm_ref, IGNORE_REALS);
03921
03922 _expand_IO_array_names();
03923 _remap_common_blocks();
03924 _remap_equivalences();
03925 _remap_and_move_data();
03926 }
03927
03928 void
03929 InlineObject::_insert_arg_mapping( Symbol & formal, Expression * actual,
03930 AbstractAccess * aa)
03931 {
03932 _formal_to_actual.ins(formal, actual);
03933 if (aa) {
03934 _formal_to_access_region.ins(formal, aa);
03935 }
03936 }
03937
03938 const Expression *
03939 InlineObject::actual_arg(const Symbol & formal) const
03940 {
03941 return _formal_to_actual.find_ref(formal);
03942 }
03943
03944 const AbstractAccess *
03945 InlineObject::access_region( const Symbol & formal) const
03946 {
03947 return _formal_to_access_region.find_ref(formal);
03948 }