00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #define __STDC_LIMIT_MACROS
00042 #include <stdint.h>
00043 #if defined(BUILD_OS_DARWIN)
00044 #include <darwin_elf.h>
00045 #else
00046 #include <elf.h>
00047 #endif
00048
00049 #include "defs.h"
00050 #include "mempool.h"
00051 #include "config_ipa.h"
00052 #include "ipa_cg.h"
00053 #include "ipaa.h"
00054 #include "ipa_section_annot.h"
00055 #include "ipa_section_main.h"
00056 #include "ipa_section_prop.h"
00057 #include "ipa_reshape.h"
00058 #include "reshape.h"
00059 #include "ipa_cost.h"
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 static inline INT32
00071 Formal_position(const SUMMARY_FORMAL* formal_array,
00072 const SUMMARY_SYMBOL* formal_symbol)
00073 {
00074 Is_True(formal_symbol->Is_formal(), ("Expected a formal symbol"));
00075 return formal_array[formal_symbol->Get_findex()].Get_position();
00076 }
00077
00078
00079
00080
00081 static void
00082 Add_ivar_to_caller_linex(const IPA_NODE* caller,
00083 COEFF coeff,
00084 const IVAR* ivar,
00085 LINEX* linex)
00086 {
00087 IP_FILE_HDR& file_hdr = caller->File_Header();
00088 SECTION_FILE_ANNOT* caller_file_annot = IP_FILE_HDR_section_annot(file_hdr);
00089 INT32 idx = caller_file_annot->Find_ivar(caller, *ivar);
00090 if (idx == -1) {
00091 idx = caller_file_annot->Add_ivar(caller, *ivar);
00092 }
00093 linex->Set_term(LTKIND_IV, coeff, idx, 0);
00094 }
00095
00096
00097 static void
00098 Add_value_to_caller_linex(const IPA_NODE* caller,
00099 COEFF coeff,
00100 const SUMMARY_VALUE* value,
00101 LINEX* linex);
00102
00103
00104
00105
00106 static void
00107 Add_expr_to_caller_linex(const IPA_NODE* caller,
00108 COEFF coeff,
00109 const SUMMARY_EXPR* expr,
00110 LINEX* linex)
00111 {
00112 OPERATOR opr = OPCODE_operator(expr->Get_opcode());
00113
00114 if (expr->Has_const_operand()) {
00115
00116 if (expr->Is_expr_value(0)) {
00117 Is_True(opr == OPR_ADD || opr == OPR_SUB || opr == OPR_MPY,
00118 ("Add_expr_to_caller_linex: expected +, -, or *"));
00119 const SUMMARY_VALUE* value =
00120 IPA_get_value_array(caller) + expr->Get_node_index(expr->Get_kid());
00121 if (opr == OPR_ADD || opr == OPR_SUB) {
00122 linex->Set_term(LTKIND_CONST,
00123 (COEFF) expr->Get_const_value() * coeff,
00124 CONST_DESC, 0);
00125 }
00126 if (opr == OPR_SUB) {
00127 coeff = -coeff;
00128 }
00129 else if (opr == OPR_MPY) {
00130 coeff *= expr->Get_const_value();
00131 }
00132 Add_value_to_caller_linex(caller, coeff, value, linex);
00133 }
00134
00135 else {
00136 Is_True(expr->Is_expr_expr(0) && (opr == OPR_ADD || opr == OPR_SUB),
00137 ("Add_expr_to_caller_linex: expected const +|- expr"));
00138 const SUMMARY_EXPR* kid_expr =
00139 IPA_get_expr_array(caller) + expr->Get_node_index(expr->Get_kid());
00140 linex->Set_term(LTKIND_CONST,
00141 (COEFF) expr->Get_const_value() * coeff,
00142 CONST_DESC, 0);
00143 if (opr == OPR_SUB) {
00144 coeff = -coeff;
00145 }
00146 Add_expr_to_caller_linex(caller, coeff, kid_expr, linex);
00147 }
00148 }
00149 else {
00150 Is_True(opr == OPR_ADD || opr == OPR_SUB,
00151 ("Add_expr_to_caller_linex: expected + or -"));
00152
00153 for (INT i = 0; i < 2; ++i) {
00154 if (expr->Is_expr_value(i)) {
00155 const SUMMARY_VALUE* value =
00156 IPA_get_value_array(caller) + expr->Get_node_index(i);
00157 Add_value_to_caller_linex(caller, coeff, value, linex);
00158 }
00159 else if (expr->Is_expr_expr(i)) {
00160 const SUMMARY_EXPR* kid_expr =
00161 IPA_get_expr_array(caller) + expr->Get_node_index(i);
00162 Add_expr_to_caller_linex(caller, coeff, kid_expr, linex);
00163 }
00164 else {
00165 Is_True(0,
00166 ("Add_expr_to_caller_linex: kid %d must be value or expr", i));
00167 }
00168 if (opr == OPR_SUB) {
00169 coeff = -coeff;
00170 }
00171 }
00172 }
00173 }
00174
00175
00176
00177
00178 static void
00179 Add_value_to_caller_linex(const IPA_NODE* caller,
00180 COEFF coeff,
00181 const SUMMARY_VALUE* value,
00182 LINEX* linex)
00183 {
00184 IPA_CONST_TYPE value_kind = value->Get_const_type();
00185
00186 if (value_kind == VALUE_INT_CONST) {
00187 linex->Set_term(LTKIND_CONST,
00188 (COEFF) value->Get_int_const_value() * coeff,
00189 CONST_DESC, 0);
00190 }
00191 else if (value_kind == VALUE_CONST) {
00192 TCON_IDX tcon_idx = ST_tcon(ST_ptr(value->Get_const_st_idx()));
00193 linex->Set_term(LTKIND_CONST,
00194 (COEFF) Targ_To_Host(Tcon_Table[tcon_idx]) * coeff,
00195 CONST_DESC, 0);
00196 }
00197 else if (value_kind == VALUE_FORMAL) {
00198 const SUMMARY_FORMAL& formal =
00199 IPA_get_formal_array(caller)[value->Get_formal_index()];
00200 const SUMMARY_SYMBOL& symbol =
00201 IPA_get_symbol_array(caller)[formal.Get_symbol_index()];
00202
00203 IVAR ivar(formal.Get_position(), 0, symbol.Get_btype());
00204 Add_ivar_to_caller_linex(caller, coeff, &ivar, linex);
00205 }
00206 else if (value_kind == VALUE_GLOBAL) {
00207 const SUMMARY_SYMBOL& symbol =
00208 IPA_get_symbol_array(caller)[value->Get_global_index()];
00209 IVAR ivar(ST_ptr(symbol.St_idx()), 0, symbol.Get_btype());
00210 Add_ivar_to_caller_linex(caller, coeff, &ivar, linex);
00211 }
00212 else {
00213 Is_True(value_kind == VALUE_EXPR,
00214 ("Add_value_to_caller_linex: expected a linexable value"));
00215 SUMMARY_EXPR* expr = IPA_get_expr_array(caller) + value->Get_expr_index();
00216 Add_expr_to_caller_linex(caller, coeff, expr, linex);
00217 }
00218 }
00219
00220
00221
00222
00223 static void
00224 Add_actual_to_caller_linex(const IPA_NODE* caller,
00225 COEFF coeff,
00226 const SUMMARY_ACTUAL* actual,
00227 LINEX* linex)
00228 {
00229 if (actual->Get_symbol_index() != -1) {
00230
00231 IPAA_NODE_INFO* modref_info = caller->Mod_Ref_Info();
00232 const SUMMARY_SYMBOL& symbol =
00233 IPA_get_symbol_array(caller)[actual->Get_symbol_index()];
00234
00235 if (symbol.Is_formal()) {
00236
00237 UINT32 position = Formal_position(IPA_get_formal_array(caller), &symbol);
00238 if (!modref_info->Is_formal_dmod_elmt(position) &&
00239 !modref_info->Is_formal_imod_elmt(position)) {
00240 IVAR ivar(position, 0, symbol.Get_btype());
00241 Add_ivar_to_caller_linex(caller, coeff, &ivar, linex);
00242 return;
00243 }
00244 }
00245 else if (ST_IDX_level(symbol.St_idx()) == GLOBAL_SYMTAB) {
00246
00247 ST* st = ST_ptr(symbol.St_idx());
00248 while (ST_base(st) != st) {
00249 st = ST_base(st);
00250 }
00251 if (!modref_info->Is_def_elmt(ST_index(st))) {
00252 IVAR ivar(st, 0, symbol.Get_btype());
00253 Add_ivar_to_caller_linex(caller, coeff, &ivar, linex);
00254 return;
00255 }
00256 }
00257 }
00258
00259 Is_True(actual->Get_value_index() != -1,
00260 ("Add_actual_to_caller_linex: expected a linexable argument"));
00261
00262 const SUMMARY_VALUE* value =
00263 IPA_get_value_array(caller) + actual->Get_value_index();
00264 Add_value_to_caller_linex(caller, coeff, value, linex);
00265 }
00266
00267
00268
00269
00270 static void
00271 Map_term_to_caller(const IPA_NODE* caller,
00272 const IPA_NODE* callee,
00273 const SUMMARY_CALLSITE* call,
00274 TERM* term,
00275 LINEX* linex)
00276 {
00277 LTKIND term_kind = term->Get_type();
00278
00279 if (term_kind == LTKIND_CONST) {
00280 linex->Set_term(term);
00281 }
00282 else if (term_kind == LTKIND_IV) {
00283 INT32 size;
00284 const IVAR* ivar = IPA_get_ivar_array(callee, size) + term->Get_desc();
00285 if (ivar->Is_Formal()) {
00286 const SUMMARY_ACTUAL* actual = IPA_get_actual_array(caller)
00287 + call->Get_actual_index()
00288 + ivar->Formal_Position();
00289
00290 Add_actual_to_caller_linex(caller, term->Get_coeff(), actual, linex);
00291 }
00292 else {
00293
00294 Add_ivar_to_caller_linex(caller, term->Get_coeff(), ivar, linex);
00295 }
00296 }
00297
00298 Is_True(1, ("Map_term_to_caller: Unexpected term kind\n"));
00299 }
00300
00301
00302
00303
00304 static void
00305 Map_linex_to_caller(const IPA_NODE* caller,
00306 const IPA_NODE* callee,
00307 const SUMMARY_CALLSITE *callsite,
00308 LINEX* callee_linex,
00309 LINEX* caller_linex)
00310 {
00311 for (INT j = 0; j <= callee_linex->Num_terms(); ++j) {
00312 Map_term_to_caller(caller, callee, callsite,
00313 callee_linex->Get_term(j), caller_linex);
00314 }
00315 }
00316
00317
00318
00319
00320 static void
00321 Map_projected_node_to_caller(const IPA_NODE* caller,
00322 const IPA_NODE* callee,
00323 const SUMMARY_CALLSITE* callsite,
00324 PROJECTED_NODE* caller_pnode,
00325 PROJECTED_NODE* callee_pnode)
00326 {
00327 MEM_POOL* pool = caller_pnode->Mem_Pool();
00328
00329 caller_pnode->Set_flags(callee_pnode->Get_flags());
00330
00331
00332 if (!callee_pnode->Is_messy_ub()) {
00333 Map_linex_to_caller(caller, callee, callsite,
00334 callee_pnode->Get_upper_linex(),
00335 caller_pnode->Get_upper_linex());
00336 caller_pnode->Get_upper_linex()->Simplify();
00337 }
00338
00339
00340 if (!callee_pnode->Is_messy_lb()) {
00341 Map_linex_to_caller(caller, callee, callsite,
00342 callee_pnode->Get_lower_linex(),
00343 caller_pnode->Get_lower_linex());
00344 caller_pnode->Get_lower_linex()->Simplify();
00345 }
00346
00347
00348 if (!callee_pnode->Is_messy_step()) {
00349 Map_linex_to_caller(caller, callee, callsite,
00350 callee_pnode->Get_step_linex(),
00351 caller_pnode->Get_step_linex());
00352 caller_pnode->Get_step_linex()->Simplify();
00353 }
00354
00355
00356 if (callee_pnode->Get_segment_length_linex()) {
00357 LINEX* segment_length = CXX_NEW(LINEX(pool), pool);
00358 callee_pnode->Get_segment_length_linex()->Copy(segment_length);
00359 caller_pnode->Set_segment_length_linex(segment_length);
00360 }
00361
00362 if (callee_pnode->Get_segment_stride_linex()) {
00363 LINEX* segment_stride = CXX_NEW(LINEX(pool), pool);
00364 callee_pnode->Get_segment_stride_linex()->Copy(segment_stride);
00365 caller_pnode->Set_segment_stride_linex(segment_stride);
00366 }
00367 }
00368
00369
00370 static BOOL
00371 Is_caller_value_linexable(const IPA_NODE* caller,
00372 const SUMMARY_VALUE* value);
00373
00374
00375
00376
00377
00378 static BOOL
00379 Is_caller_expr_linexable(const IPA_NODE* caller,
00380 const SUMMARY_EXPR* expr)
00381 {
00382 if (expr->Is_expr_unknown()) {
00383 return FALSE;
00384 }
00385
00386 OPERATOR opr = OPCODE_operator(expr->Get_opcode());
00387
00388 if (expr->Has_const_operand()) {
00389
00390 if (expr->Is_expr_value(0) &&
00391 (opr == OPR_ADD || opr == OPR_SUB || opr == OPR_MPY)) {
00392 const SUMMARY_VALUE* value =
00393 IPA_get_value_array(caller) + expr->Get_node_index(expr->Get_kid());
00394 return Is_caller_value_linexable(caller, value);
00395 }
00396
00397 else if (expr->Is_expr_expr(0) && (opr == OPR_ADD || opr == OPR_SUB)) {
00398 const SUMMARY_EXPR* kid_expr =
00399 IPA_get_expr_array(caller) + expr->Get_node_index(expr->Get_kid());
00400 return Is_caller_expr_linexable(caller, kid_expr);
00401 }
00402 }
00403 else if (opr == OPR_ADD || opr == OPR_SUB) {
00404
00405 for (INT i = 0; i < 2; ++i) {
00406 if (expr->Is_expr_value(i)) {
00407 const SUMMARY_VALUE* value =
00408 IPA_get_value_array(caller) + expr->Get_node_index(i);
00409 if (!Is_caller_value_linexable(caller, value)) {
00410 return FALSE;
00411 }
00412 }
00413 else if (expr->Is_expr_expr(i)) {
00414 const SUMMARY_EXPR* kid_expr =
00415 IPA_get_expr_array(caller) + expr->Get_node_index(i);
00416 if (!Is_caller_expr_linexable(caller, kid_expr)) {
00417 return FALSE;
00418 }
00419 }
00420 else {
00421 return FALSE;
00422 }
00423 }
00424 return TRUE;
00425 }
00426
00427 return FALSE;
00428 }
00429
00430
00431
00432
00433
00434 static BOOL
00435 Is_caller_value_linexable(const IPA_NODE* caller,
00436 const SUMMARY_VALUE* value)
00437 {
00438 switch (value->Get_const_type()) {
00439
00440 case VALUE_INT_CONST:
00441 return TRUE;
00442
00443 case VALUE_CONST: {
00444 INT64 int_val;
00445 TCON_IDX tcon_idx = ST_tcon(ST_ptr(value->Get_const_st_idx()));
00446 return Targ_Is_Integral(Tcon_Table[tcon_idx], &int_val);
00447 }
00448
00449 case VALUE_FORMAL: {
00450 IPAA_NODE_INFO* caller_modref = caller->Mod_Ref_Info();
00451 INT32 caller_position =
00452 IPA_get_formal_array(caller)[value->Get_formal_index()].Get_position();
00453 return (!caller_modref->Is_formal_dmod_elmt(caller_position) &&
00454 !caller_modref->Is_formal_imod_elmt(caller_position));
00455 }
00456
00457 case VALUE_GLOBAL: {
00458 INT32 symbol_index = value->Get_global_index();
00459 if (symbol_index != -1) {
00460 IPAA_NODE_INFO* caller_modref = caller->Mod_Ref_Info();
00461 ST* st = ST_ptr(IPA_get_symbol_array(caller)[symbol_index].St_idx());
00462 while (ST_base(st) != st) {
00463 st = ST_base(st);
00464 }
00465 return !caller_modref->Is_def_elmt(ST_index(st));
00466 }
00467 }
00468
00469 case VALUE_EXPR: {
00470 SUMMARY_EXPR* expr = IPA_get_expr_array(caller)+value->Get_expr_index();
00471 return Is_caller_expr_linexable(caller, expr);
00472 }
00473 }
00474
00475 return FALSE;
00476 }
00477
00478
00479
00480
00481
00482
00483
00484
00485 static BOOL
00486 Is_callee_formal_mappable_to_caller(const IPA_NODE* caller,
00487 const SUMMARY_CALLSITE* call,
00488 UINT32 position)
00489 {
00490 if (position >= call->Get_param_count()) {
00491 return FALSE;
00492 }
00493
00494 const SUMMARY_ACTUAL& actual =
00495 IPA_get_actual_array(caller)[call->Get_actual_index() + position];
00496
00497 if (actual.Get_symbol_index() != -1) {
00498 IPAA_NODE_INFO* caller_modref = caller->Mod_Ref_Info();
00499 const SUMMARY_SYMBOL& caller_symbol =
00500 IPA_get_symbol_array(caller)[actual.Get_symbol_index()];
00501
00502 if (caller_symbol.Is_formal()) {
00503 INT32 caller_position =
00504 Formal_position(IPA_get_formal_array(caller), &caller_symbol);
00505 return (!caller_modref->Is_formal_dmod_elmt(caller_position) &&
00506 !caller_modref->Is_formal_imod_elmt(caller_position));
00507 }
00508
00509 else if (ST_IDX_level(caller_symbol.St_idx()) == GLOBAL_SYMTAB) {
00510 ST* st = ST_ptr(caller_symbol.St_idx());
00511 while (ST_base(st) != st) {
00512 st = ST_base(st);
00513 }
00514 return !caller_modref->Is_def_elmt(ST_index(st));
00515 }
00516 }
00517
00518 if (actual.Get_value_index() != -1) {
00519 const SUMMARY_VALUE* value =
00520 IPA_get_value_array(caller) + actual.Get_value_index();
00521 if (Is_caller_value_linexable(caller, value)) {
00522 return TRUE;
00523 }
00524 }
00525
00526 return FALSE;
00527 }
00528
00529
00530
00531
00532 static BOOL
00533 Is_term_mappable_to_caller(const IPA_NODE* caller,
00534 const IPA_NODE* callee,
00535 const SUMMARY_CALLSITE* call,
00536 const TERM* t)
00537 {
00538 switch (t->Get_type()) {
00539
00540 case LTKIND_CONST:
00541 return TRUE;
00542
00543 case LTKIND_IV:
00544 if (IPA_Enable_Simple_Alias) {
00545 INT32 size;
00546 const IVAR& ivar = IPA_get_ivar_array(callee, size)[t->Get_desc()];
00547 if (ivar.Is_Formal()) {
00548 UINT32 position = ivar.Formal_Position();
00549 return (ivar.Offset() == 0 &&
00550 Is_callee_formal_mappable_to_caller(caller, call, position));
00551 }
00552 else {
00553
00554 Is_True(ST_IDX_level(ivar.St_Idx()) == GLOBAL_SYMTAB,
00555 ("Map_term_to_caller: expected a global ST"));
00556 UINT32 modref_key = ST_IDX_index(ST_base_idx(ST_ptr(ivar.St_Idx())));
00557 return !caller->Mod_Ref_Info()->Is_def_elmt(modref_key);
00558 }
00559 }
00560 return FALSE;
00561
00562 default:
00563 return FALSE;
00564 }
00565 }
00566
00567
00568
00569
00570
00571 static BOOL
00572 Is_linex_mappable_to_caller(const IPA_NODE* caller,
00573 const IPA_NODE* callee,
00574 const SUMMARY_CALLSITE* callsite,
00575 LINEX* l)
00576 {
00577 for (INT j = 0; j <= l->Num_terms(); ++j) {
00578 if (!Is_term_mappable_to_caller(caller, callee, callsite, l->Get_term(j))){
00579 return FALSE;
00580 }
00581 }
00582 return TRUE;
00583 }
00584
00585
00586
00587
00588 static BOOL
00589 Is_region_mappable_to_caller(const IPA_NODE* caller,
00590 const IPA_NODE* callee,
00591 const SUMMARY_CALLSITE *callsite,
00592 PROJECTED_REGION *callee_region)
00593 {
00594 if (callee_region->Is_messy_region()) {
00595 return FALSE;
00596 }
00597
00598 for (INT i = 0; i < callee_region->Get_num_dims(); ++i) {
00599
00600 PROJECTED_NODE* p1 = callee_region->Get_projected_node(i);
00601 Is_True(p1, ("Is_projected_region_mappable_to_caller: p1 is NULL\n"));
00602
00603
00604 if (!p1->Is_messy_ub()) {
00605 if (LINEX* ub = p1->Get_upper_linex()) {
00606 if (!Is_linex_mappable_to_caller(caller, callee, callsite, ub)) {
00607 return FALSE;
00608 }
00609 }
00610 }
00611
00612
00613 if (!p1->Is_messy_lb()) {
00614 if (LINEX *lb = p1->Get_lower_linex()) {
00615 if (!Is_linex_mappable_to_caller(caller, callee, callsite, lb)) {
00616 return FALSE;
00617 }
00618 }
00619 }
00620
00621
00622 if (!p1->Is_messy_step()) {
00623 if (LINEX *step = p1->Get_step_linex()) {
00624 if (!Is_linex_mappable_to_caller(caller, callee, callsite, step)) {
00625 return FALSE;
00626 }
00627 }
00628 }
00629 }
00630
00631 return TRUE;
00632 }
00633
00634
00635
00636
00637
00638
00639
00640 extern void
00641 Map_callee_region_to_caller(const IPA_NODE* caller,
00642 const IPA_NODE* callee,
00643 const SUMMARY_CALLSITE* callsite,
00644 PROJECTED_REGION* caller_region,
00645 PROJECTED_REGION* callee_region)
00646 {
00647 if (Is_region_mappable_to_caller(caller, callee, callsite, callee_region)) {
00648
00649 Is_True(callee_region->Get_num_dims() == caller_region->Get_num_dims(),
00650 ("Dim size mismatch in Map_callee_region_to_caller\n"));
00651
00652 for (INT i = 0; i < callee_region->Get_num_dims(); ++i) {
00653 Map_projected_node_to_caller(caller, callee, callsite,
00654 caller_region->Get_projected_node(i),
00655 callee_region->Get_projected_node(i));
00656 }
00657 }
00658 else {
00659 caller_region->Set_messy_region();
00660 }
00661 }
00662
00663
00664
00665
00666
00667
00668 static BOOL
00669 Same_Shape (const IPA_NODE* caller_node,
00670 const IPA_NODE* callee_node,
00671 const SUMMARY_CALLSITE* callsite,
00672 PROJECTED_REGION* caller_shape,
00673 PROJECTED_REGION* callee_shape,
00674 TYPE_ID caller_mtype,
00675 TYPE_ID callee_mtype,
00676 MEM_POOL* mem_pool)
00677 {
00678 if (!caller_shape && !callee_shape) {
00679 return TRUE;
00680 }
00681
00682 if (!caller_shape || !callee_shape || !callsite ||
00683 caller_shape->Get_num_dims() != callee_shape->Get_num_dims() ||
00684 caller_mtype != callee_mtype) {
00685 return FALSE;
00686 }
00687
00688 PROJECTED_REGION callee_shape_in_caller(callee_shape->Get_type(),
00689 callee_shape->Get_depth(),
00690 callee_shape->Get_num_dims(),
00691 mem_pool);
00692
00693 Map_callee_region_to_caller(caller_node, callee_node, callsite,
00694 &callee_shape_in_caller, callee_shape);
00695
00696 return caller_shape->Equivalent(&callee_shape_in_caller);
00697 }
00698
00699
00700
00701
00702 static PROJECTED_REGION*
00703 Get_actual_passed_region(const IPA_NODE* caller,
00704 const SUMMARY_ACTUAL& actual)
00705 {
00706 INT ra_idx = actual.Get_index();
00707 Is_True(ra_idx != -1, ("Expecting a valid region array index\n"));
00708
00709 INT pr_idx = IPA_get_region_array(caller)[ra_idx].Get_idx();
00710 Is_True(pr_idx != -1, ("Expecting a valid projected region index\n"));
00711
00712 return IPA_get_proj_region_array(caller) + pr_idx;
00713 }
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 static BOOL
00725 Union_sections(const IPA_NODE* caller,
00726 const IPA_NODE* callee,
00727 const SUMMARY_CALLSITE* callsite,
00728 STATE* caller_annot,
00729 STATE* callee_annot,
00730 BOOL is_mod,
00731 PROJECTED_REGION* caller_shape = NULL,
00732 PROJECTED_REGION* callee_shape = NULL,
00733 TYPE_ID caller_mtype = MTYPE_UNKNOWN,
00734 TYPE_ID callee_mtype = MTYPE_UNKNOWN,
00735 PROJECTED_REGION* callsite_region = NULL)
00736 {
00737 PROJECTED_REGION* caller_region;
00738 PROJECTED_REGION* callee_region;
00739
00740 if (is_mod) {
00741 caller_region = caller_annot->Get_projected_mod_region();
00742 callee_region = callee_annot->Get_projected_mod_region();
00743 }
00744 else {
00745 caller_region = caller_annot->Get_projected_ref_region();
00746 callee_region = callee_annot->Get_projected_ref_region();
00747 }
00748
00749
00750 if (!callee_region || (caller_region && caller_region->Is_messy_region())) {
00751 return FALSE;
00752 }
00753
00754 MEM_POOL* mem_pool = caller->Section_Annot()->Mem_Pool();
00755 BOOL created_caller_region = FALSE;
00756
00757
00758 if (!caller_region) {
00759 created_caller_region = TRUE;
00760 caller_region = CXX_NEW(PROJECTED_REGION(callee_region->Get_type(),
00761 callee_region->Get_depth(),
00762 callee_region->Get_num_dims(),
00763 mem_pool), mem_pool);
00764 if (is_mod) {
00765 caller_annot->Set_projected_mod_region(caller_region);
00766 }
00767 else {
00768 caller_annot->Set_projected_ref_region(caller_region);
00769 }
00770 }
00771
00772
00773 if (callee_region->Is_messy_region()) {
00774 caller_region->Set_messy_region();
00775 return TRUE;
00776 }
00777
00778 BOOL reshape_trace = Get_Trace(TP_IPA, IPA_TRACE_RESHAPE);
00779
00780 RESHAPE reshape(caller_shape, callee_shape, callee_region,
00781 callsite_region, mem_pool, reshape_trace);
00782
00783 BOOL same_shape = Same_Shape(caller, callee, callsite,
00784 caller_shape, callee_shape,
00785 caller_mtype, callee_mtype, mem_pool);
00786
00787
00788 if (same_shape && callsite_region) {
00789 reshape.Set_callee_proj_reshaped_region(callee_region);
00790 if (!reshape.Reshapeable_Passed_Section(reshape_trace)) {
00791 caller_region->Set_messy_region();
00792 return TRUE;
00793 }
00794 }
00795
00796
00797 if (!same_shape && caller_shape) {
00798 callee_region = reshape.Reshape_Callee_To_Caller(reshape_trace);
00799 if (callsite_region && !callee_region->Is_messy_region()) {
00800 if (!reshape.Reshapeable_Passed_Section(reshape_trace)) {
00801 callee_region->Set_messy_region();
00802 }
00803 }
00804 }
00805
00806 if (callee_region->Is_messy_region()) {
00807 caller_region->Set_messy_region();
00808 return TRUE;
00809 }
00810
00811 PROJECTED_REGION* new_caller_region =
00812 (created_caller_region &&
00813 caller_region->Get_num_dims() == callee_region->Get_num_dims()) ?
00814 caller_region :
00815 CXX_NEW(PROJECTED_REGION(callee_region->Get_type(),
00816 callee_region->Get_depth(),
00817 callee_region->Get_num_dims(),
00818 mem_pool), mem_pool);
00819
00820
00821 Map_callee_region_to_caller(caller, callee, callsite,
00822 new_caller_region, callee_region);
00823
00824
00825 if (callsite_region) {
00826 reshape.Reshape_Passed_Section(new_caller_region, reshape_trace);
00827 }
00828
00829 BOOL change = TRUE;
00830 if (!created_caller_region) {
00831 change = caller_region->May_Union(*new_caller_region, Trace_IPA_Sections);
00832 }
00833 else {
00834 if (is_mod) {
00835 caller_annot->Set_projected_mod_region(new_caller_region);
00836 }
00837 else {
00838 caller_annot->Set_projected_ref_region(new_caller_region);
00839 }
00840 }
00841
00842 return change;
00843 }
00844
00845
00846
00847
00848
00849
00850 static
00851 BOOL Set_Caller_Annot_Messy(STATE* caller_annot,
00852 STATE* callee_annot,
00853 BOOL make_messy_region,
00854 MEM_POOL* pool)
00855 {
00856 BOOL change = FALSE;
00857
00858 PROJECTED_REGION* pr_callee_mod
00859 = callee_annot != NULL ? callee_annot->Get_projected_mod_region() : NULL;
00860 if (pr_callee_mod || make_messy_region) {
00861 PROJECTED_REGION* pr_caller_mod= caller_annot->Get_projected_mod_region();
00862 if (!pr_caller_mod) {
00863 if (pr_callee_mod) {
00864 pr_caller_mod = CXX_NEW(PROJECTED_REGION(MESSY_REGION,
00865 pr_callee_mod->Get_depth(), pr_callee_mod->Get_num_dims(), pool),
00866 pool);
00867 } else {
00868 pr_caller_mod = CXX_NEW(PROJECTED_REGION(MESSY_REGION, 0, 0, pool),
00869 pool);
00870 }
00871 caller_annot->Set_projected_mod_region(pr_caller_mod);
00872 change = TRUE;
00873 } else if (!pr_caller_mod->Is_messy_region()) {
00874 pr_caller_mod->Set_messy_region();
00875 change = TRUE;
00876 }
00877 }
00878
00879 PROJECTED_REGION* pr_callee_ref
00880 = callee_annot != NULL ? callee_annot->Get_projected_ref_region() : NULL;
00881 if (pr_callee_ref || make_messy_region) {
00882 PROJECTED_REGION* pr_caller_ref= caller_annot->Get_projected_ref_region();
00883 if (!pr_caller_ref) {
00884 if (pr_callee_ref) {
00885 pr_caller_ref = CXX_NEW(PROJECTED_REGION(MESSY_REGION,
00886 pr_callee_ref->Get_depth(), pr_callee_ref->Get_num_dims(), pool),
00887 pool);
00888 } else {
00889 pr_caller_ref = CXX_NEW(PROJECTED_REGION(MESSY_REGION, 0, 0, pool),
00890 pool);
00891 }
00892 caller_annot->Set_projected_ref_region(pr_caller_ref);
00893 change = TRUE;
00894 } else if (!pr_caller_ref->Is_messy_region()) {
00895 pr_caller_ref->Set_messy_region();
00896 change = TRUE;
00897 }
00898 }
00899
00900 return change;
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910 static BOOL
00911 Set_Caller_Actual_Messy(const IPA_NODE* caller,
00912 IPA_NODE_SECTION_INFO* caller_info,
00913 IPA_NODE_SECTION_INFO* callee_info,
00914 const SUMMARY_FORMAL* caller_formals,
00915 const SUMMARY_SYMBOL* caller_symbols,
00916 const SUMMARY_ACTUAL* actuals,
00917 INT i)
00918 {
00919 INT symbol_index = actuals[i].Get_symbol_index();
00920 if (symbol_index == -1) {
00921
00922 return FALSE;
00923 }
00924
00925 STATE* callee_formal = NULL;
00926 BOOL make_messy_region = FALSE;
00927 if (i >= 0 && i < callee_info->Get_formal_count()) {
00928 callee_formal = callee_info->Get_formal(i);
00929 } else {
00930 make_messy_region = TRUE;
00931 }
00932
00933 const SUMMARY_SYMBOL* symbol = caller_symbols + symbol_index;
00934
00935 if (symbol->Is_formal() &&
00936 ST_IDX_level(symbol->St_idx()) == caller->Lexical_Level()) {
00937 INT formal_pos = Formal_position(caller_formals, symbol);
00938 return Set_Caller_Annot_Messy(caller_info->Get_formal(formal_pos),
00939 callee_formal, make_messy_region,
00940 caller_info->Mem_Pool());
00941 }
00942
00943 else if (ST_IDX_level(symbol->St_idx()) == GLOBAL_SYMTAB &&
00944 ST_class(symbol->St_idx()) == CLASS_VAR &&
00945 TY_kind(ST_type(symbol->St_idx())) == KIND_ARRAY) {
00946
00947
00948 if (ST_is_equivalenced(ST_ptr(symbol->St_idx()))) {
00949 return caller_info->Set_Global_Array_List_To_Messy(symbol);
00950 }
00951
00952 GLOBAL_ARRAY_INFO* gai = caller_info->Find_Global_Array_Info(symbol);
00953 if (!gai) {
00954 gai = caller_info->Add_Global_Array_Info(symbol);
00955 }
00956 return Set_Caller_Annot_Messy(gai->Get_state(),
00957 callee_formal, make_messy_region,
00958 caller_info->Mem_Pool());
00959 }
00960
00961 return FALSE;
00962 }
00963
00964
00965
00966
00967
00968
00969
00970 static BOOL
00971 Merge_global_sections(IPA_NODE *caller,
00972 IPA_NODE *callee,
00973 SUMMARY_CALLSITE *call)
00974 {
00975 BOOL change = FALSE;
00976 IPA_NODE_SECTION_INFO* caller_info = caller->Section_Annot();
00977 IPA_NODE_SECTION_INFO* callee_info = callee->Section_Annot();
00978
00979 GLOBAL_ARRAY_TABLE* caller_tbl = caller_info->Global_Array_Table();
00980 GLOBAL_ARRAY_TABLE* callee_tbl = callee_info->Global_Array_Table();
00981
00982 MEM_POOL* pool = caller_info->Mem_Pool();
00983
00984
00985 ST_IDX st;
00986 GLOBAL_ARRAY_LIST* callee_list;
00987 GLOBAL_ARRAY_TABLE_ITER callee_tbl_iter(callee_tbl);
00988 while (callee_tbl_iter.Step (&st, &callee_list)) {
00989 GLOBAL_ARRAY_LIST* caller_list = caller_tbl->Find(st);
00990
00991 if (!caller_list) {
00992 caller_list = CXX_NEW(GLOBAL_ARRAY_LIST(st), pool);
00993 caller_tbl->Enter(st, caller_list);
00994 }
00995 change |= caller_list->Merge(caller, callee, call, callee_list, pool);
00996 }
00997 return change;
00998 }
00999
01000
01001
01002
01003
01004 static PROJECTED_REGION*
01005 Global_shape_region(SUMMARY_SYMBOL* symbol, MEM_POOL* pool)
01006 {
01007 TY_IDX ty_idx = ST_type(symbol->St_idx());
01008 INT num_dims = TY_AR_ndims(ty_idx);
01009
01010 PROJECTED_REGION* p =
01011 CXX_NEW(PROJECTED_REGION(NON_MESSY_REGION, 0, num_dims, pool), pool);
01012
01013
01014 for (INT i = 0; i < num_dims; ++i) {
01015 PROJECTED_NODE* node = p->Get_projected_node (i);
01016 node->Set_constant_linexs (TY_AR_ubnd_val(ty_idx,i) -
01017 TY_AR_lbnd_val(ty_idx,i),
01018 0,
01019 1,
01020 0,
01021 0);
01022 }
01023 return p;
01024 }
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051 BOOL
01052 Merge_Section(IPA_NODE* caller)
01053 {
01054 if (caller->Summary_Proc()->Has_incomplete_array_info()) {
01055 return FALSE;
01056 }
01057
01058
01059 if (!caller->Icall_List().empty() || !caller->Ocall_List().empty()) {
01060 caller->Summary_Proc()->Set_has_incomplete_array_info();
01061 return TRUE;
01062 }
01063
01064 BOOL change = FALSE;
01065 IPA_NODE_SECTION_INFO* caller_info = caller->Section_Annot();
01066 SUMMARY_FORMAL* caller_formals = IPA_get_formal_array(caller);
01067 SUMMARY_SYMBOL* caller_symbols = IPA_get_symbol_array(caller);
01068
01069 change = Merge_Execution_Cost(caller, &IPA_array_prop_pool);
01070
01071
01072 IPA_SUCC_ITER edge_iter(IPA_Call_Graph, caller);
01073 for (edge_iter.First(); !edge_iter.Is_Empty(); edge_iter.Next()) {
01074
01075 IPA_EDGE* e = edge_iter.Current_Edge();
01076 if (!e) {
01077 continue;
01078 }
01079
01080 IPA_NODE* callee = IPA_Call_Graph->Callee(e);
01081 IPA_NODE_SECTION_INFO* callee_info = callee->Section_Annot();
01082 SUMMARY_FORMAL* callee_formals = IPA_get_formal_array (callee);
01083 Init_IPA_Print_Arrays(callee);
01084
01085
01086 if (callee->Summary_Proc()->Has_incomplete_array_info()) {
01087 caller->Summary_Proc()->Set_has_incomplete_array_info();
01088 return TRUE;
01089 }
01090
01091 SUMMARY_CALLSITE* call = e->Summary_Callsite();
01092 SUMMARY_ACTUAL* actuals = IPA_get_actual_array(caller)
01093 + call->Get_actual_index();
01094
01095
01096 INT formal_count = callee->Summary_Proc()->Get_formal_count();
01097 INT actual_count = e->Num_Actuals();
01098 if (formal_count != actual_count) {
01099 for (INT i = 0; i < actual_count; i++)
01100 change = Set_Caller_Actual_Messy(caller,
01101 caller_info, callee_info,
01102 caller_formals, caller_symbols,
01103 actuals, i);
01104 continue;
01105 }
01106
01107 for (INT i = 0; i < actual_count; ++i) {
01108 if ((!IPA_Enable_Reshape &&
01109 Try_Reshape_Callee_Formal(caller,callee,call,i,&IPA_array_prop_pool))
01110 ||
01111 (IPA_Enable_Reshape &&
01112 Mismatched_Types(caller, callee, call, i, &IPA_array_prop_pool))) {
01113 change = Set_Caller_Actual_Messy(caller,
01114 caller_info, callee_info,
01115 caller_formals, caller_symbols,
01116 actuals, i);
01117 continue;
01118 }
01119
01120 INT actual_symbol_index = actuals[i].Get_symbol_index();
01121
01122 if (actual_symbol_index != -1) {
01123
01124 STATE* caller_annot;
01125 PROJECTED_REGION* caller_shape;
01126 STATE* callee_annot = callee_info->Get_formal(i);
01127 PROJECTED_REGION* callee_shape = callee_annot->
01128 Get_projected_dcl_region();
01129 PROJECTED_REGION* passed_region = NULL;
01130
01131 INT32 callee_f_idx = callee->Summary_Proc()->Get_formal_index() + i;
01132 TYPE_ID callee_mtype = callee_formals[callee_f_idx].Get_machine_type();
01133
01134 SUMMARY_SYMBOL* symbol = caller_symbols + actual_symbol_index;
01135
01136 if (symbol->Is_formal() &&
01137 ST_IDX_level(symbol->St_idx()) == caller->Lexical_Level()) {
01138 INT caller_mtype =
01139 caller_formals[symbol->Get_findex()].Get_machine_type();
01140 INT formal_pos = Formal_position(caller_formals, symbol);
01141
01142 caller_annot = caller_info->Get_formal(formal_pos);
01143 caller_shape = caller_annot->Get_projected_dcl_region();
01144
01145 if (actuals[i].Get_pass_type() == PASS_ARRAY_SECTION) {
01146 passed_region = Get_actual_passed_region(caller, actuals[i]);
01147 passed_region = Projected_Region_To_Memory(caller,
01148 passed_region,
01149 &IPA_array_prop_pool);
01150 }
01151
01152 change |= Union_sections(caller, callee, call,
01153 caller_annot, callee_annot, TRUE,
01154 caller_shape, callee_shape,
01155 caller_mtype, callee_mtype, passed_region);
01156
01157 change |= Union_sections(caller, callee, call,
01158 caller_annot, callee_annot, FALSE,
01159 caller_shape, callee_shape,
01160 caller_mtype, callee_mtype, passed_region);
01161 }
01162
01163 else if (ST_IDX_level(symbol->St_idx()) == GLOBAL_SYMTAB) {
01164
01165 if (ST_class(symbol->St_idx()) == CLASS_FUNC
01166 || ST_class(symbol->St_idx()) == CLASS_BLOCK) {
01167 change = Set_Caller_Actual_Messy(caller,
01168 caller_info, callee_info,
01169 caller_formals, caller_symbols,
01170 actuals, i);
01171 continue;
01172 }
01173
01174 TY_IDX ty_idx = ST_type(symbol->St_idx());
01175 if (TY_kind(ty_idx) != KIND_ARRAY) {
01176
01177 continue;
01178 }
01179
01180 BOOL is_messy = FALSE;
01181 caller_info->Global_Array_Region(symbol, &is_messy, NULL, TRUE);
01182 caller_info->Global_Array_Region(symbol, &is_messy, NULL, FALSE);
01183 if (is_messy) {
01184 continue;
01185 }
01186
01187 if (actuals[i].Get_pass_type() == PASS_ARRAY_SECTION) {
01188 passed_region = Get_actual_passed_region(caller, actuals[i]);
01189 passed_region = Projected_Region_To_Memory(caller,
01190 passed_region,
01191 &IPA_array_prop_pool);
01192 }
01193
01194 caller_annot = caller_info->Find_Global_Array_Sections(symbol);
01195 caller_shape = Global_shape_region(symbol, &IPA_array_prop_pool);
01196
01197 INT caller_mtype = TY_mtype(TY_etype(ty_idx));
01198
01199 change |= Union_sections(caller, callee, call,
01200 caller_annot, callee_annot, TRUE,
01201 caller_shape, callee_shape,
01202 caller_mtype, callee_mtype, passed_region);
01203
01204 change |= Union_sections(caller, callee, call,
01205 caller_annot, callee_annot, FALSE,
01206 caller_shape, callee_shape,
01207 caller_mtype, callee_mtype, passed_region);
01208 }
01209 }
01210 }
01211
01212
01213 change |= Merge_global_sections(caller, callee, call);
01214 }
01215
01216 return change;
01217 }
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228 GLOBAL_ARRAY_INFO*
01229 GLOBAL_ARRAY_LIST::Find_Global_Array_Info(ST_IDX st_idx)
01230 {
01231 Is_True(ST_IDX_level(st_idx) == GLOBAL_SYMTAB,
01232 ("Find_Global_Array_Info: Symbol is NOT global!\n"));
01233
01234 GLOBAL_ARRAY_LIST_ITER iter(this);
01235 for (iter.First(); !iter.Is_Empty(); iter.Next()) {
01236
01237 GLOBAL_ARRAY_INFO* current_section = iter.Cur();
01238 ST_IDX current_st_idx = current_section->St_Idx();
01239
01240 if (st_idx == current_st_idx ||
01241 (ST_type(st_idx) == ST_type(current_st_idx) &&
01242 ST_ofst(ST_ptr(st_idx)) == ST_ofst(ST_ptr(current_st_idx)))) {
01243 return current_section;
01244 }
01245 }
01246
01247 return NULL;
01248 }
01249
01250
01251
01252
01253 BOOL
01254 GLOBAL_ARRAY_LIST::Merge(const IPA_NODE* caller,
01255 const IPA_NODE* callee,
01256 const SUMMARY_CALLSITE* call,
01257 GLOBAL_ARRAY_LIST* callee_list,
01258 MEM_POOL* m)
01259 {
01260 if (callee_list->Is_messy()) {
01261 if (Is_messy()) {
01262 return FALSE;
01263 }
01264 Set_is_messy();
01265 return TRUE;
01266 }
01267
01268 BOOL change = FALSE;
01269
01270
01271 GLOBAL_ARRAY_LIST_ITER iter(callee_list);
01272 for (iter.First(); !iter.Is_Empty(); iter.Next()) {
01273
01274 GLOBAL_ARRAY_INFO* callee_info = iter.Cur();
01275 ST_IDX st_idx = callee_info->St_Idx();
01276 GLOBAL_ARRAY_INFO* caller_info = Find_Global_Array_Info(st_idx);
01277 if (!caller_info) {
01278 caller_info = Append(st_idx, m);
01279 }
01280
01281 STATE* caller_state = caller_info->Get_state();
01282 STATE* callee_state = callee_info->Get_state();
01283
01284
01285
01286 change |= Union_sections(caller, callee, call,
01287 caller_state, callee_state, TRUE);
01288 change |= Union_sections(caller, callee, call,
01289 caller_state, callee_state, FALSE);
01290 }
01291
01292 return change;
01293 }
01294
01295
01296
01297
01298 void
01299 GLOBAL_ARRAY_LIST::Print(FILE* fp)
01300 {
01301 GLOBAL_ARRAY_LIST_ITER iter(this);
01302 for (iter.First(); !iter.Is_Empty(); iter.Next()) {
01303 iter.Cur()->Print(fp);
01304 }
01305 }
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318 PROJECTED_REGION*
01319 IPA_NODE_SECTION_INFO::Global_Array_Region(const SUMMARY_SYMBOL* s,
01320 BOOL* is_messy,
01321 PROJECTED_REGION* region,
01322 BOOL is_mod)
01323 {
01324 ST_IDX st_idx = s->St_idx();
01325
01326 GLOBAL_ARRAY_LIST* list = Find_Global_Array_List(s);
01327 if (!list) {
01328 list = Add_Global_Array_List(s);
01329 if (ST_is_equivalenced(ST_ptr(s->St_idx()))) {
01330 list->Set_is_messy();
01331 }
01332 }
01333
01334 if (!list->Is_messy()) {
01335 *is_messy = FALSE;
01336 GLOBAL_ARRAY_INFO* global_array_info = Find_Global_Array_Info(s);
01337 if (!global_array_info) {
01338 global_array_info = Add_Global_Array_Info(s);
01339 }
01340 if (is_mod) {
01341 if (region && !global_array_info->Get_projected_mod_region()) {
01342 global_array_info->Set_projected_mod_region(region);
01343 }
01344 return global_array_info->Get_projected_mod_region();
01345 }
01346 else {
01347 if (region && !global_array_info->Get_projected_ref_region()) {
01348 global_array_info->Set_projected_ref_region(region);
01349 }
01350 return global_array_info->Get_projected_ref_region();
01351 }
01352 }
01353 else {
01354 *is_messy = TRUE;
01355 return 0;
01356 }
01357 }
01358
01359
01360
01361
01362 BOOL
01363 IPA_NODE_SECTION_INFO::Set_Global_Array_List_To_Messy(const SUMMARY_SYMBOL* s)
01364 {
01365 GLOBAL_ARRAY_LIST* list = Find_Global_Array_List(s);
01366 if (!list) {
01367 list = Add_Global_Array_List(s);
01368 }
01369 if (list->Is_messy()) {
01370 return FALSE;
01371 }
01372 list->Set_is_messy();
01373 return TRUE;
01374 }
01375
01376
01377
01378
01379 void
01380 IPA_NODE_SECTION_INFO::Print(FILE *fp)
01381 {
01382 fprintf(fp,"---------start printing section information-------\n");
01383 if (STATE_ARRAY* state = Get_formals()) {
01384 for (INT i = 0; i < state->Elements(); ++i) {
01385 fprintf(fp, "formal %d : ", i);
01386 (*state)[i].Print(fp);
01387 }
01388 }
01389 fprintf(fp,"------end printing section information-------\n");
01390 }
01391
01392
01393
01394
01395 void
01396 IPA_NODE_SECTION_INFO::Print_Global_Sections (FILE* fp)
01397 {
01398 GLOBAL_ARRAY_TABLE_ITER tbl_iter(Global_Array_Table());
01399
01400 GLOBAL_ARRAY_LIST* list;
01401 ST_IDX st_idx;
01402
01403 while (tbl_iter.Step(&st_idx, &list)) {
01404 fprintf(fp, "Common block = %s\n", ST_name(st_idx));
01405 GLOBAL_ARRAY_LIST_ITER iter(list);
01406 for (iter.First(); !iter.Is_Empty(); iter.Next()) {
01407 iter.Cur()->Print(fp);
01408 }
01409 }
01410 }
01411
01412
01413
01414
01415 INT
01416 IPA_NODE_SECTION_INFO::Get_formal_euse_count()
01417 {
01418 INT count = 0;
01419 if (STATE_ARRAY* formals_state = Get_formals()) {
01420 for (INT i = 0; i < formals_state->Elements(); ++i) {
01421 if ((*formals_state)[i].Is_euse()) {
01422 ++count;
01423 }
01424 }
01425 }
01426 return count;
01427 }
01428
01429
01430
01431
01432 INT
01433 IPA_NODE_SECTION_INFO::Get_formal_kill_count()
01434 {
01435 INT count = 0;
01436 if (STATE_ARRAY* formals_state = Get_formals()) {
01437 for (INT i = 0; i < formals_state->Elements(); ++i) {
01438 if ((*formals_state)[i].Is_must_kill()) {
01439 ++count;
01440 }
01441 }
01442 }
01443 return count;
01444 }
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454 void
01455 GLOBAL_ARRAY_INFO::Print(FILE* fp)
01456 {
01457 const ST& st = St_Table[St_Idx()];
01458 st.Print(fp, FALSE);
01459 Ty_Table[ST_type(st)].Print(fp);
01460
01461 if (PROJECTED_REGION* mod = Get_projected_mod_region()) {
01462 fprintf(fp, "mod region\n");
01463 mod->Print(fp);
01464 }
01465
01466 if (PROJECTED_REGION* ref = Get_projected_ref_region()) {
01467 fprintf(fp, "ref region\n");
01468 ref->Print(fp);
01469 }
01470 }
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480 INT32
01481 SECTION_FILE_ANNOT::Find_ivar(const IPA_NODE* node, const IVAR& ivar)
01482 {
01483 INT32 ivar_size;
01484 const IVAR* ivar_array = IPA_get_ivar_array(node, ivar_size);
01485 for (INT32 i = 0; i < ivar_size; i++) {
01486 if (ivar_array[i] == ivar) {
01487 return i;
01488 }
01489 }
01490 return -1;
01491 }
01492
01493
01494
01495
01496 INT32
01497 SECTION_FILE_ANNOT::Add_ivar(const IPA_NODE* node, const IVAR& ivar)
01498 {
01499 if (!_iv_grow) {
01500
01501 _iv_grow = CXX_NEW(IVAR_ARRAY(Mem_Pool()), Mem_Pool());
01502 INT32 ivar_size;
01503 IPA_get_ivar_file_array(node->File_Header(), ivar_size);
01504 for (INT32 i = 0; i < ivar_size; ++i) {
01505 _iv_grow->AddElement(_iv_base[i]);
01506 }
01507 }
01508
01509 _iv_grow->AddElement(ivar);
01510 return _iv_grow->Lastidx();
01511 }
01512
01513
01514
01515
01516 void
01517 STATE::Print(FILE *fp)
01518 {
01519 if (Is_must_kill()) fprintf(fp, " must kill, ");
01520 if (Is_may_kill()) fprintf(fp, " may kill, ");
01521 if (Is_euse()) fprintf(fp, " euse, ");
01522 if (Is_use()) fprintf(fp, " use, ");
01523 if (Is_must_reduc())fprintf(fp, " must reduc, ");
01524 if (Is_may_reduc()) fprintf(fp, " may reduc, ");
01525 if (Is_scalar()) fprintf(fp, "is scalar, ");
01526
01527 if (PROJECTED_REGION* mod = Get_projected_mod_region()) mod->Print_file(fp);
01528 fprintf(fp, "\n");
01529 if (PROJECTED_REGION* ref = Get_projected_ref_region()) ref->Print_file(fp);
01530 fprintf(fp, "\n");
01531 if (PROJECTED_REGION* dcl = Get_projected_dcl_region()) dcl->Print_file(fp);
01532 fprintf(fp, "\n");
01533 }