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 #define __STDC_LIMIT_MACROS
00041 #include <stdint.h>
00042 #if defined(BUILD_OS_DARWIN)
00043 #include <darwin_elf.h>
00044 #else
00045 #include <elf.h>
00046 #endif
00047 #include <sys/elf_whirl.h>
00048 #include <errno.h>
00049 #include <sys/types.h>
00050
00051 #include "defs.h"
00052 #include "wn.h"
00053 #include "pu_info.h"
00054 #include "erglob.h"
00055 #include "dwarf_DST.h"
00056 #include "ir_bread.h"
00057 #include "xstats.h"
00058
00059 #include "ipc_file.h"
00060 #include "ipa_summary.h"
00061 #include "ipc_bread.h"
00062 #include "ipc_symtab_merge.h"
00063 #include "ipl_summary.h"
00064
00065 BOOL IPA_Has_Feedback = FALSE;
00066
00067
00068
00069
00070
00071 static const int ERROR_VALUE = -1;
00072
00073
00074
00075 void IP_READ_remap_pu_infos(PU_Info* base, const IPC_GLOBAL_IDX_MAP* idx_map)
00076 {
00077 for ( ; base != NULL ; base = PU_Info_next(base)) {
00078
00079
00080 PU_Info_proc_sym(base) = idx_map->st[PU_Info_proc_sym(base)];
00081
00082 if (PU_Info_child(base) != NULL)
00083 IP_READ_remap_pu_infos(PU_Info_child(base), idx_map);
00084 }
00085 }
00086
00087
00088
00089
00090
00091
00092
00093 INT
00094 IPA_process_PUs (IP_FILE_HDR &s, const SUMMARY_PROCEDURE *proc_array,
00095 PU_Info *pu_tree, INT proc_idx)
00096 {
00097 for (PU_Info *pu = pu_tree; pu; pu = PU_Info_next(pu)) {
00098 IP_PROC_INFO *proci = IP_FILE_HDR_proc_info(s) + proc_idx;
00099
00100
00101
00102 while (proc_array[proc_idx].Is_alt_entry()) {
00103 Set_IP_PROC_INFO_pu_info (*proci, NULL);
00104 Set_IP_PROC_INFO_state (*proci, IPA_ORIG);
00105 ++proc_idx;
00106 ++proci;
00107 }
00108
00109 Set_IP_PROC_INFO_pu_info (*proci, pu);
00110 Set_IP_PROC_INFO_state (*proci, IPA_ORIG);
00111
00112 ++proc_idx;
00113
00114 if (PU_Info_child(pu)) {
00115 proc_idx = IPA_process_PUs (s, proc_array, PU_Info_child(pu),
00116 proc_idx);
00117 Set_IP_FILE_HDR_has_nested_pu(s);
00118 }
00119 }
00120 return proc_idx;
00121 }
00122
00123
00124
00125
00126
00127 void
00128 IP_READ_pu_infos (IP_FILE_HDR& s)
00129 {
00130 if (IP_FILE_HDR_pu_list(s) == NULL) {
00131 void *fhandle = (void *)IP_FILE_HDR_input_map_addr(s);
00132
00133 Temporary_Error_Phase ephase("Reading WHIRL file");
00134
00135
00136 IP_READ_file_info(s);
00137
00138
00139 PU_Info* pu_tree = WN_get_PU_Infos(fhandle, NULL);
00140 if (pu_tree == (PU_Info *)-1) {
00141 ErrMsg ( EC_IR_Scn_Read, "PU headers", IP_FILE_HDR_file_name(s));
00142 }
00143
00144 IP_READ_remap_pu_infos(pu_tree, IP_FILE_HDR_idx_maps(s));
00145
00146 Set_IP_FILE_HDR_pu_list(s, pu_tree);
00147
00148
00149
00150 if (IP_FILE_HDR_summary (s) == 0) {
00151 char *base = (char*)
00152 WN_get_section_base (IP_FILE_HDR_input_map_addr (s),
00153 WT_IPA_SUMMARY);
00154 Set_IP_FILE_HDR_summary(s, base);
00155 Set_IP_FILE_HDR_file_header (s, IPA_get_file_header (base));
00156 }
00157
00158 SUMMARY_FILE_HEADER *file_header = IP_FILE_HDR_file_header (s);
00159 UINT vv=file_header->Get_version_number();
00160 UINT vv2=IPA_SUMMARY_REVISION;
00161
00162 if (file_header &&
00163 file_header->Get_version_number() != IPA_SUMMARY_REVISION) {
00164 ErrMsg(EC_IR_Revision, "summary info", IP_FILE_HDR_file_name(s));
00165 }
00166
00167
00168
00169 INT32 count;
00170 SUMMARY_PROCEDURE *proc_array = IPA_get_procedure_file_array(s, count);
00171
00172 Set_IP_FILE_HDR_num_procs (s, count);
00173
00174 INT size_proc = 0;
00175 if (count != 0) {
00176
00177 size_proc = count < 32 ? count + 8 : count + count / 4;
00178 }
00179
00180 Set_IP_FILE_HDR_proc_info (s, (IP_PROC_INFO*)
00181 MEM_POOL_Alloc (Malloc_Mem_Pool,
00182 (sizeof(IP_PROC_INFO)*size_proc)));
00183
00184 Set_IP_FILE_HDR_max_size (s, size_proc);
00185
00186 if (count != 0) {
00187 INT proc_idx = IPA_process_PUs (s, proc_array,
00188 IP_FILE_HDR_pu_list(s), 0);
00189 while ((proc_idx < count) && proc_array[proc_idx].Is_alt_entry()) {
00190 IP_PROC_INFO &proci = IP_FILE_HDR_proc_info(s)[proc_idx];
00191 Set_IP_PROC_INFO_pu_info (proci, NULL);
00192 Set_IP_PROC_INFO_state (proci, IPA_ORIG);
00193 ++proc_idx;
00194 }
00195 FmtAssert((proc_idx == count),
00196 ("procedure headers do not match summary information"));
00197 }
00198 }
00199 }
00200
00201 namespace {
00202
00203
00204
00205
00206 const IPC_GLOBAL_IDX_MAP* dst_idx_map;
00207
00208 void remap_ST_index(DST_ASSOC_INFO& idx) {
00209 if (DST_ASSOC_INFO_st_level(idx) == GLOBAL_SYMTAB) {
00210 const ST_IDX new_idx = dst_idx_map->st[DST_ASSOC_INFO_st_idx(idx)];
00211 DST_ASSOC_INFO_st_idx(idx) = new_idx;
00212 }
00213 }
00214
00215 INT32 remap_dst_entry(INT32 , DST_DW_tag tag, DST_flag flag,
00216 DST_ATTR_IDX attr, DST_INFO_IDX info_idx)
00217 {
00218 Is_True(!DST_IS_NULL(attr) && !DST_IS_NULL(info_idx),
00219 ("remap_dst_entry: invalid DST index"));
00220 Is_True(DST_ARE_EQUAL(DST_INFO_attributes(DST_INFO_IDX_TO_PTR(info_idx)), attr),
00221 ("remap_dst_entry: DST_ATTR doesn't match DST_INFO"));
00222 Is_True(DST_INFO_tag(DST_INFO_IDX_TO_PTR(info_idx)) == tag,
00223 ("remap_dst_entry: tag doesn't match DST_INFO"));
00224 Is_True(DST_INFO_flag(DST_INFO_IDX_TO_PTR(info_idx)) == flag,
00225 ("remap_dst_entry: flag doesn't match DST_INFO"));
00226
00227 switch(tag) {
00228 case DW_TAG_subprogram:
00229 {
00230 DST_subprogram* sub = DST_ATTR_IDX_TO_PTR(attr, DST_subprogram);
00231 if (DST_IS_memdef(flag)) {
00232 remap_ST_index(DST_SUBPROGRAM_memdef_st(sub));
00233 }
00234 else if (DST_IS_declaration(flag)) {
00235
00236 }
00237 else {
00238 remap_ST_index(DST_SUBPROGRAM_def_st(sub));
00239 }
00240 }
00241 break;
00242
00243 case DW_TAG_entry_point:
00244 {
00245 DST_entry_point* entry = DST_ATTR_IDX_TO_PTR(attr, DST_entry_point);
00246 remap_ST_index(DST_ENTRY_POINT_st(entry));
00247 }
00248 break;
00249
00250 case DW_TAG_common_block:
00251 {
00252 DST_common_block* block = DST_ATTR_IDX_TO_PTR(attr, DST_common_block);
00253 remap_ST_index(DST_COMMON_BLOCK_st(block));
00254 }
00255 break;
00256
00257 case DW_TAG_variable:
00258 {
00259 DST_variable* var = DST_ATTR_IDX_TO_PTR(attr, DST_variable);
00260
00261 if (DST_IS_declaration(flag)) {
00262
00263 }
00264 else if (DST_IS_const(flag)) {
00265
00266 }
00267 else if (DST_IS_comm(flag)) {
00268 remap_ST_index(DST_VARIABLE_comm_st(var));
00269 }
00270 else if (DST_IS_memdef(flag)) {
00271 remap_ST_index(DST_VARIABLE_memdef_st(var));
00272 }
00273 else {
00274 remap_ST_index(DST_VARIABLE_def_st(var));
00275 }
00276 }
00277 break;
00278
00279 case DW_TAG_formal_parameter:
00280 {
00281 DST_formal_parameter* param =
00282 DST_ATTR_IDX_TO_PTR(attr, DST_formal_parameter);
00283 remap_ST_index(DST_FORMAL_PARAMETER_st(param));
00284 }
00285 break;
00286
00287
00288
00289
00290
00291 default:
00292 break;
00293 }
00294
00295 return 0;
00296 }
00297
00298
00299
00300 void remap_dst(const IP_FILE_HDR& s) {
00301 dst_idx_map = IP_FILE_HDR_idx_maps(s);
00302 Is_True(dst_idx_map != 0,
00303 ("Index map not initialized for file header %s",
00304 IP_FILE_HDR_file_name(s)));
00305
00306 Is_True(Current_DST == IP_FILE_HDR_dst(s),
00307 ("File header %s: DST mismatch", IP_FILE_HDR_file_name(s)));
00308
00309 DST_IDX compile_unit = DST_get_compile_unit();
00310 Is_True(!DST_IS_NULL(compile_unit),
00311 ("File header %s: DST has no DST_COMPILE_UNIT entry",
00312 IP_FILE_HDR_file_name(s)));
00313
00314 DST_preorder_visit(compile_unit,
00315 0 ,
00316 remap_dst_entry);
00317 }
00318
00319 }
00320
00321 void
00322 IP_READ_file_info (IP_FILE_HDR& s)
00323 {
00324
00325
00326
00327
00328 void *fhandle = IP_FILE_HDR_input_map_addr(s);
00329 const char* file_name = IP_FILE_HDR_file_name(s);
00330
00331 Temporary_Error_Phase ephase("Reading WHIRL file");
00332
00333 if (IP_FILE_HDR_dst(s)) {
00334 Current_DST = IP_FILE_HDR_dst(s);
00335 }
00336 else {
00337 Current_DST = 0;
00338 if (WN_get_dst(fhandle) == -1) {
00339 ErrMsg ( EC_IR_Scn_Read, "dst", IP_FILE_HDR_file_name(s));
00340 }
00341 Set_IP_FILE_HDR_dst(s, Current_DST);
00342 remap_dst(s);
00343 }
00344 }
00345
00346
00347 template <class T>
00348 inline T* convert_offset(T* p, char* base) {
00349 return reinterpret_cast<T*>(base + reinterpret_cast<INTPTR>(p));
00350 }
00351
00352 #ifdef KEY
00353
00354
00355
00356
00357
00358
00359 static void
00360 Count_WN (WN * wn, INT32& bbs, INT32& stmts, INT32& calls)
00361 {
00362 OPERATOR opr = WN_operator (wn);
00363 TYPE_ID rtype = WN_rtype (wn);
00364
00365
00366 if (OPERATOR_is_non_scf(opr)) {
00367 switch (opr) {
00368 case OPR_LABEL:
00369 if (WN_Label_Is_Not_Used (wn))
00370 return;
00371 else break;
00372 case OPR_RETURN:
00373 case OPR_RETURN_VAL:
00374 return;
00375 }
00376 ++bbs;
00377 } else if (OPERATOR_is_stmt(opr)) {
00378 if (OPERATOR_is_call(opr)) {
00379 ++bbs;
00380 ++calls;
00381 } else if (opr == OPR_IO) {
00382
00383
00384 ++bbs;
00385 ++calls;
00386 } else if (! OPERATOR_is_not_executable(opr)) {
00387 ++stmts;
00388 if (MTYPE_is_complex(rtype) && OPERATOR_is_store(opr)) {
00389 ++stmts;
00390 }
00391 }
00392 } else if (OPERATOR_is_scf(opr)) {
00393 if (opr != OPR_BLOCK && opr != OPR_FUNC_ENTRY) {
00394
00395 ++bbs;
00396 }
00397
00398
00399 } else if ((rtype == MTYPE_FQ || rtype == MTYPE_CQ) &&
00400 OPERATOR_is_expression(opr) &&
00401 !OPERATOR_is_load(opr) &&
00402 !OPERATOR_is_leaf(opr) ) {
00403
00404 ++bbs;
00405 ++calls;
00406 } else if (opr == OPR_CAND || opr == OPR_CIOR) {
00407
00408
00409
00410 ++bbs;
00411 }
00412 }
00413 #endif // KEY
00414
00415
00416
00417
00418
00419 INT
00420 IP_READ_fix_tree (WN *node, char *base, Elf64_Word size,
00421 const IPC_GLOBAL_IDX_MAP* idx_map)
00422 {
00423 OPCODE opcode = (OPCODE) WN_opcode (node);
00424 WN *wn;
00425
00426 if (OPCODE_has_sym(opcode) || OPCODE_has_label(opcode)) {
00427 const ST_IDX idx = WN_st_idx(node);
00428 if (ST_IDX_level(idx) == GLOBAL_SYMTAB)
00429 WN_st_idx(node) = idx_map->st[idx];
00430 }
00431 #ifdef KEY
00432 if (OPCODE_operator(opcode) == OPR_PRAGMA &&
00433 WN_pragma(node) == WN_PRAGMA_THREADPRIVATE) {
00434 const ST_IDX idx = WN_pragma_arg2(node);
00435 if (ST_IDX_level(idx) == GLOBAL_SYMTAB) {
00436 #pragma frequency_hint frequent
00437 WN_pragma_arg2(node) = idx_map->st[idx];
00438 }
00439 }
00440 #endif
00441 if (OPCODE_has_1ty(opcode)) {
00442 WN_set_ty(node, idx_map->ty[WN_ty(node)]);
00443 }
00444 else if (OPCODE_has_2ty(opcode)) {
00445 WN_set_ty(node, idx_map->ty[WN_ty(node)]);
00446 WN_set_load_addr_ty(node, idx_map->ty[WN_load_addr_ty(node)]);
00447 }
00448 else if (OPCODE_operator(opcode) == OPR_PRAGMA &&
00449 WN_pragma(node) == WN_PRAGMA_TYPE_OF_RESHAPED_ARRAY) {
00450 WN_pragma_arg1(node) = idx_map->ty[WN_pragma_arg1(node)];
00451 }
00452
00453
00454
00455 #ifndef CFE
00456 if (opcode == OPC_REGION)
00457 Set_Max_Region_Id (WN_region_id(node));
00458 #endif
00459
00460 #if defined(BACK_END)
00461 if (opcode == OPC_ALTENTRY)
00462 Set_PU_has_altentry (Get_Current_PU ());
00463
00464
00465 #ifdef KEY
00466 Count_WN (node, PU_WN_BB_Cnt, PU_WN_Stmt_Cnt, PU_WN_Call_Cnt);
00467 #else
00468 Count_WN_Opcode (opcode, &PU_WN_BB_Cnt, &PU_WN_Stmt_Cnt);
00469 #endif // KEY
00470 #endif
00471
00472 if (opcode == OPC_BLOCK) {
00473 wn = WN_first(node);
00474 if (wn == (WN *) -1) {
00475 WN_first(node) = NULL;
00476 WN_last(node) = NULL;
00477 } else {
00478 wn = convert_offset(wn, base);
00479 WN_first(node) = wn;
00480 WN_last(node) = convert_offset(WN_last(node), base);
00481
00482 do {
00483 if (IP_READ_fix_tree (wn, base, size, idx_map) == ERROR_VALUE)
00484 return ERROR_VALUE;
00485 wn = WN_next(wn);
00486 } while (wn);
00487 }
00488 }
00489 else if (!OPCODE_is_leaf(opcode)) {
00490 const INT cnt = WN_kid_count(node);
00491 WN** wn_ptr = &WN_kid(node, 0);
00492 for (INT i = 0; i < cnt; i++, wn_ptr++) {
00493 wn = *wn_ptr;
00494 if (wn == (WN *) -1) {
00495 *wn_ptr = NULL;
00496 }
00497 else {
00498 wn = convert_offset(wn, base);
00499 *wn_ptr = wn;
00500 if (IP_READ_fix_tree (wn, base, size, idx_map) == ERROR_VALUE)
00501 return ERROR_VALUE;
00502 }
00503 }
00504 }
00505
00506 if (OPCODE_has_next_prev(opcode)) {
00507 wn = WN_prev(node);
00508 if (wn == (WN *) -1) {
00509 WN_prev(node) = NULL;
00510 } else {
00511 wn = convert_offset(wn, base);
00512 WN_prev(node) = wn;
00513 }
00514 wn = WN_next(node);
00515 if (wn == (WN *) -1) {
00516 WN_next(node) = NULL;
00517 } else {
00518 wn = convert_offset(wn, base);
00519 WN_next(node) = wn;
00520 }
00521 }
00522
00523
00524 if (WN_map_id(node) != -1) {
00525 register OPERATOR_MAPCAT category = OPCODE_mapcat(opcode);
00526 register INT32 map_id = WN_map_id(node);
00527 register INT32 *last_id_ptr;
00528
00529 last_id_ptr = &WN_MAP_TAB_Last_ID(Current_Map_Tab, category);
00530 if (map_id > *last_id_ptr) {
00531 *last_id_ptr = map_id;
00532 }
00533 }
00534
00535 return 0;
00536 }
00537
00538 WN *
00539 IP_READ_get_tree (void *handle, PU_Info *pu,
00540 const IPC_GLOBAL_IDX_MAP* idx_map)
00541 {
00542 Subsect_State st = PU_Info_state(pu, WT_TREE);
00543 if (st == Subsect_InMem)
00544 return PU_Info_tree_ptr(pu);
00545 if (st != Subsect_Exists)
00546 return reinterpret_cast<WN*>(ERROR_VALUE);
00547
00548 Elf64_Word offset = PU_Info_subsect_offset(pu, WT_TREE);
00549 Elf64_Word size = PU_Info_subsect_size(pu, WT_TREE);
00550
00551 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, WT_PU_SECTION);
00552 if (shdr.offset == 0)
00553 return reinterpret_cast<WN*>(ERROR_VALUE);
00554
00555 if (offset + size > shdr.size) {
00556 errno = EINVAL;
00557 return reinterpret_cast<WN*>(ERROR_VALUE);
00558 }
00559
00560 char* section_base = (char *) handle + shdr.offset;
00561 char* tree_base = section_base + offset;
00562
00563
00564 Elf64_Word first_node = *(Elf64_Word *)tree_base;
00565 WN* wn = (WN *) (tree_base + first_node);
00566
00567 #ifndef CFE
00568 Set_Max_Region_Id(0);
00569 #endif
00570
00571
00572
00573 Current_Map_Tab = PU_Info_maptab(pu);
00574 if (IP_READ_fix_tree (wn, tree_base, size, idx_map) == ERROR_VALUE)
00575 return reinterpret_cast<WN*>(ERROR_VALUE);
00576
00577 WN_next(wn) = NULL;
00578 WN_prev(wn) = NULL;
00579
00580 Set_PU_Info_tree_ptr(pu, wn);
00581 Set_PU_Info_state(pu, WT_TREE, Subsect_InMem);
00582
00583 return wn;
00584 }
00585
00586 namespace {
00587
00588
00589
00590
00591
00592
00593
00594 struct fix_st_entry {
00595 const SYMSTR_IDX_MAP& str_map;
00596 const ST_IDX_MAP& st_map;
00597 const TY_IDX_MAP& ty_map;
00598 const TCON_IDX_MAP& tcon_map;
00599 IPA_NODE* node;
00600
00601 fix_st_entry(IPA_NODE* n, const IPC_GLOBAL_IDX_MAP* idx_map)
00602 : str_map(idx_map->sym_str),
00603 st_map(idx_map->st),
00604 ty_map(idx_map->ty),
00605 tcon_map(idx_map->tcon),
00606 node (n)
00607 {}
00608
00609 void operator()(UINT32, ST* st) const {
00610 const ST_CLASS sym_class = ST_sym_class(*st);
00611
00612 if (sym_class == CLASS_CONST)
00613 Set_ST_tcon(*st, tcon_map[ST_tcon(*st)]);
00614 else
00615 Set_ST_name_idx(*st, str_map[ST_name_idx(*st)]);
00616
00617 if (sym_class != CLASS_FUNC &&
00618 sym_class != CLASS_BLOCK &&
00619 sym_class != CLASS_NAME)
00620 Set_ST_type(*st, ty_map[ST_type(*st)]);
00621
00622 const ST_IDX base = ST_base_idx(*st);
00623 if (base != ST_st_idx(*st)) {
00624 if (ST_IDX_level(base) == GLOBAL_SYMTAB) {
00625 const ST& mapped_base = St_Table[st_map[base]];
00626 Set_ST_base_idx(*st, ST_st_idx (mapped_base));
00627 Set_ST_storage_class (*st, ST_storage_class (mapped_base));
00628 if (ST_is_initialized (mapped_base)) {
00629 Set_ST_is_initialized (st);
00630 if (ST_init_value_zero (mapped_base))
00631 Set_ST_init_value_zero (st);
00632 }
00633 if (ST_is_not_used (mapped_base))
00634 Set_ST_is_not_used (st);
00635 if (ST_is_const_var (mapped_base))
00636 Set_ST_is_const_var (st);
00637 } else {
00638 const ST& base_st = St_Table[base];
00639 if (ST_sclass (base_st) == SCLASS_FORMAL ||
00640 ST_sclass (base_st) == SCLASS_FORMAL_REF)
00641 if (node)
00642 node->Set_Aliased_Formal ();
00643 }
00644 }
00645
00646 if (base != ST_st_idx(*st) && ST_IDX_level(base) == GLOBAL_SYMTAB)
00647 Set_ST_base_idx(*st, st_map[base]);
00648 }
00649 };
00650
00651
00652
00653
00654 struct fix_label_entry {
00655 const SYMSTR_IDX_MAP& str_map;
00656
00657 fix_label_entry(const IPC_GLOBAL_IDX_MAP* idx_map)
00658 : str_map(idx_map->sym_str)
00659 {}
00660
00661 void operator()(UINT32, LABEL* lbl) const {
00662 Set_LABEL_name_idx(*lbl, str_map[LABEL_name_idx(*lbl)]);
00663 }
00664 };
00665
00666
00667
00668
00669 struct fix_preg_entry {
00670 const SYMSTR_IDX_MAP& str_map;
00671
00672 fix_preg_entry(const IPC_GLOBAL_IDX_MAP* idx_map)
00673 : str_map(idx_map->sym_str)
00674 {}
00675
00676 void operator()(UINT32, PREG* preg) const {
00677 Set_PREG_name_idx(*preg, str_map[PREG_name_idx(*preg)]);
00678 }
00679 };
00680
00681
00682
00683 struct fix_inito_entry {
00684 const ST_IDX_MAP& st_map;
00685 const INITV_IDX_MAP initv_map;
00686
00687 fix_inito_entry(const IPC_GLOBAL_IDX_MAP* idx_map)
00688 : st_map(idx_map->st),
00689 initv_map(idx_map->initv)
00690 {}
00691
00692 void operator()(UINT32, INITO* inito) const {
00693 if (ST_IDX_level(INITO_st_idx(*inito)) == GLOBAL_SYMTAB)
00694 Set_INITO_st_idx(*inito, st_map[INITO_st_idx(*inito)]);
00695
00696 Set_INITO_val(*inito, initv_map[INITO_val(*inito)]);
00697 }
00698 };
00699
00700 void fix_local_st_tab(IPA_NODE* node,
00701 SYMTAB_IDX level,
00702 const IPC_GLOBAL_IDX_MAP* idx_map) {
00703 For_all(St_Table, level, fix_st_entry(node, idx_map));
00704 }
00705
00706 void fix_local_label_tab(const IPC_GLOBAL_IDX_MAP* idx_map) {
00707 For_all(Label_Table, fix_label_entry(idx_map));
00708 }
00709
00710 void fix_local_preg_tab(const IPC_GLOBAL_IDX_MAP* idx_map) {
00711 For_all(Preg_Table, fix_preg_entry(idx_map));
00712 }
00713
00714 void fix_local_inito_tab(SYMTAB_IDX level,
00715 const IPC_GLOBAL_IDX_MAP* idx_map) {
00716 For_all(Inito_Table, level, fix_inito_entry(idx_map));
00717 }
00718
00719 }
00720
00721 void
00722 IP_READ_pu (IPA_NODE* node, IP_FILE_HDR& s, INT p_index, MEM_POOL *pool)
00723 {
00724 Temporary_Error_Phase ephase( "Reading WHIRL file" );
00725 IP_PROC_INFO& proci = IP_FILE_HDR_proc_info(s)[p_index];
00726
00727
00728 if (IP_PROC_INFO_state(proci) == IPA_ORIG) {
00729 PU_Info* const pu = IP_PROC_INFO_pu_info(proci);
00730
00731 FmtAssert((pu != 0), ("IP_READ_pu called for alternate entry point"));
00732
00733 void* fhandle = IP_FILE_HDR_input_map_addr(s);
00734
00735
00736
00737 IP_READ_file_info (s);
00738
00739 Set_IP_PROC_INFO_state(proci, IPA_MODIFIED);
00740
00741
00742 Current_Map_Tab = PU_Info_maptab(pu);
00743 if (!Current_Map_Tab) {
00744 Current_Map_Tab = WN_MAP_TAB_Create(pool);
00745 PU_Info_maptab(pu) = Current_Map_Tab;
00746 }
00747
00748
00749 Initialize_PU_Stats();
00750
00751 CURRENT_SYMTAB = PU_lexical_level (&St_Table[PU_Info_proc_sym (pu)]);
00752 Is_True(CURRENT_SYMTAB >= 2,
00753 ("Incorrect lexical level %d for pu %s",
00754 CURRENT_SYMTAB,
00755 ST_name(St_Table[PU_Info_proc_sym(pu)])));
00756
00757 #if Is_True_On
00758 for (UINT i = GLOBAL_SYMTAB; i < CURRENT_SYMTAB; ++i) {
00759 Is_True(Scope_tab[i].st_tab != NULL,
00760 ("Parent PU's symtab must be set up"));
00761 }
00762 #endif
00763
00764 New_Scope (CURRENT_SYMTAB, pool, FALSE);
00765 if (WN_get_symtab (fhandle, pu) == -1)
00766 ErrMsg ( EC_IR_Scn_Read, "local symtab", IP_FILE_HDR_file_name(s));
00767
00768 Scope_tab[CURRENT_SYMTAB].st = WN_get_proc_sym (pu);
00769 if (Scope_tab[CURRENT_SYMTAB].st == reinterpret_cast<ST *>(-1))
00770 ErrMsg ( EC_IR_Scn_Read, "proc ST", IP_FILE_HDR_file_name(s));
00771 else
00772 Current_pu = &Pu_Table[ST_pu (Scope_tab[CURRENT_SYMTAB].st)];
00773
00774 if (IP_READ_get_tree (fhandle, pu, IP_FILE_HDR_idx_maps(s)) == (WN*) -1) {
00775 ErrMsg ( EC_IR_Scn_Read, "tree", IP_FILE_HDR_file_name(s));
00776 }
00777
00778
00779
00780
00781
00782 fix_local_st_tab(node, CURRENT_SYMTAB, IP_FILE_HDR_idx_maps(s));
00783 fix_local_label_tab(IP_FILE_HDR_idx_maps(s));
00784 fix_local_preg_tab(IP_FILE_HDR_idx_maps(s));
00785 fix_local_inito_tab(CURRENT_SYMTAB, IP_FILE_HDR_idx_maps(s));
00786
00787 #ifdef BACK_END
00788 if (WN_get_depgraph (fhandle, pu) == (void *) -1) {
00789 ErrMsg ( EC_IR_Scn_Read, "dependence graph", IP_FILE_HDR_file_name(s));
00790 }
00791 #endif
00792
00793 #if defined(BACK_END) || defined(BUILD_WHIRL2C) || defined(BUILD_WHIRL2F)
00794 if (WN_get_prefetch (fhandle, pu) == -1) {
00795 ErrMsg ( EC_IR_Scn_Read, "prefetch map", IP_FILE_HDR_file_name(s));
00796 }
00797 #endif
00798
00799 if (WN_get_feedback (fhandle, pu, pool) == -1)
00800 ErrMsg ( EC_IR_Scn_Read, "feedback info", IP_FILE_HDR_file_name(s));
00801
00802 if (PU_Info_state (pu, WT_FEEDBACK) == Subsect_InMem) {
00803 const Pu_Hdr* pu_hdr = (const Pu_Hdr*)
00804 PU_Info_feedback_ptr (pu);
00805 #ifdef KEY
00806 Cur_PU_Feedback = CXX_NEW (FEEDBACK (PU_Info_tree_ptr (pu),
00807 pool,
00808 pu_hdr->pu_num_inv_entries,
00809 pu_hdr->pu_num_br_entries,
00810 pu_hdr->pu_num_loop_entries,
00811 pu_hdr->pu_num_scircuit_entries,
00812 pu_hdr->pu_num_call_entries,
00813 pu_hdr->pu_num_icall_entries,
00814 pu_hdr->pu_num_switch_entries,
00815 pu_hdr->pu_num_value_entries,
00816 pu_hdr->pu_num_value_fp_bin_entries,
00817 pu_hdr->runtime_fun_address),
00818 pool);
00819 #else
00820 Cur_PU_Feedback = CXX_NEW (FEEDBACK (PU_Info_tree_ptr (pu),
00821 pool,
00822 pu_hdr->pu_num_inv_entries,
00823 pu_hdr->pu_num_br_entries,
00824 pu_hdr->pu_num_loop_entries,
00825 pu_hdr->pu_num_scircuit_entries,
00826 pu_hdr->pu_num_call_entries,
00827 pu_hdr->pu_num_icall_entries,
00828 pu_hdr->pu_num_switch_entries),
00829 pool);
00830 #endif
00831 Read_Feedback_Info (Cur_PU_Feedback, PU_Info_tree_ptr (pu), *pu_hdr);
00832
00833 IPA_Has_Feedback = TRUE;
00834 node->Set_Feedback_Info (Cur_PU_Feedback);
00835 } else {
00836 Cur_PU_Feedback = NULL;
00837 }
00838 }
00839 }