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 #ifndef cxx_ipa_cg_INCLUDED
00042 #define cxx_ipa_cg_INCLUDED
00043
00044 #include <vector>
00045
00046 #ifndef mempool_allocator_INCLUDED
00047 #include <mempool_allocator.h>
00048 #endif
00049
00050 #ifndef pu_info_INCLUDED
00051 #include "pu_info.h"
00052 #endif
00053
00054 #ifndef ip_graph_INCLUDED
00055 #include "ip_graph.h"
00056 #endif
00057
00058 #ifndef cxx_ip_graph_trav_INCLUDED
00059 #include "ip_graph_trav.h"
00060 #endif
00061
00062 #ifndef xstats_INCLUDED
00063 #include "xstats.h"
00064 #endif
00065
00066 #ifndef ipl_summary_INCLUDED
00067 #include "ipl_summary.h"
00068 #endif
00069
00070 #ifndef ip_call_INCLUDED
00071 #include "ip_call.h"
00072 #endif // ip_call_INCLUDED
00073
00074 #ifndef dwarf_DST_mem_INCLUDED
00075 #include "dwarf_DST_mem.h"
00076 #endif // dwarf_DST_mem_INCLUDED
00077
00078 #ifndef ipc_file_INCLUDED
00079 #include "ipc_file.h"
00080 #endif
00081
00082 #ifndef ip_bwrite_INCLUDED
00083 #include "ipc_bwrite.h"
00084 #endif
00085
00086 #ifndef cxx_ipa_cprop_INCLUDED
00087 #include "ipa_cprop.h"
00088 #endif
00089
00090 #ifndef cxx_ipa_summary_INCLUDED
00091 #include "ipa_summary.h"
00092 #endif
00093
00094 #ifndef ipc_pu_size_INCLUDED
00095 #include "ipc_pu_size.h"
00096 #endif
00097
00098 #ifndef fb_whirl_INCLUDED
00099 #include "fb_whirl.h"
00100 #endif
00101
00102
00103 class CALLEE_STATE;
00104 class IPAA_NODE_INFO;
00105 class IPA_NODE_SECTION_INFO;
00106 class IPA_CALL_GRAPH;
00107 class IPL_SUMMARY_PTRS;
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 class IPA_ICALL_NODE
00131 {
00132 private:
00133 SUMMARY_CALLSITE *_c;
00134 SUMMARY_VALUE _v;
00135
00136 public:
00137
00138 IPA_ICALL_NODE ( SUMMARY_CALLSITE *cs )
00139 {
00140 _c = cs;
00141 _v.Init ();
00142 }
00143
00144 void Set_Callsite ( SUMMARY_CALLSITE *cs ) { _c = cs; }
00145 SUMMARY_CALLSITE* Callsite() const { return _c; }
00146
00147 void Set_Value ( SUMMARY_VALUE &value ) { _v = value; }
00148 SUMMARY_VALUE& Value () { return _v; }
00149 };
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 typedef vector<IPA_ICALL_NODE*> IPA_ICALL_LIST;
00160
00161 #ifdef _LIGHTWEIGHT_INLINER
00162 typedef vector<char*> INLINED_BODY_LIST;
00163 #endif // _LIGHTWEIGHT_INLINER
00164
00165 typedef UINT32 IPA_NODE_INDEX;
00166
00167 typedef UINT32 IPA_EDGE_INDEX;
00168
00169
00170 class IPA_NODE
00171 {
00172 private:
00173
00174 static const mUINT32 _clone = 0x1;
00175 static const mUINT32 _visited = 0x2;
00176 static const mUINT32 _mempool_init = 0x4;
00177 static const mUINT32 _deletable = 0x8;
00178 static const mUINT32 _dont_delete = 0x10;
00179 static const mUINT32 _processed = 0x20;
00180 static const mUINT32 _recursive_in_edge = 0x40;
00181 static const mUINT32 _feedback = 0x80;
00182 static const mUINT32 _constants = 0x100;
00183 static const mUINT32 _clone_candidate = 0x200;
00184 static const mUINT32 _padding = 0x400;
00185 static const mUINT32 _non_local = 0x800;
00186 static const mUINT32 _no_aggressive_cprop = 0x1000;
00187 static const mUINT32 _split_commons = 0x2000;
00188 static const mUINT32 _internal_part = 0x4000;
00189 static const mUINT32 _use_kill = 0x8000;
00190 static const mUINT32 _incoming_back_edge = 0x10000;
00191 static const mUINT32 _quasi_clone = 0x20000;
00192 static const mUINT32 _preoptimized = 0x40000;
00193 static const mUINT32 _has_aliased_formal = 0x80000;
00194 #ifdef KEY
00195 static const mUINT32 _builtin = 0x100000;
00196 static const mUINT32 _pu_write_complete = 0x200000;
00197 static const mUINT32 _recursive = 0x400000;
00198 static const mUINT32 _merged = 0x800000;
00199 static const mUINT32 _can_throw = 0x1000000;
00200 static const mUINT32 _ehinfo_updated = 0x2000000;
00201 static const mUINT32 _pending_icalls = 0x4000000;
00202 #endif
00203
00204
00205 mINT32 _file_index;
00206 mINT32 _proc_info_index;
00207 mINT32 _summary_proc_index;
00208 NODE_INDEX _vertex_index;
00209 IPA_NODE_INDEX _array_index;
00210
00211
00212
00213 ST *_func_st;
00214 SCOPE *_scope_tab;
00215 IPO_SYMTAB *_cloned_symtab;
00216 CALLEE_STATE *_callee_state;
00217
00218 PU_SIZE _pu_size;
00219 #if defined(TARG_SL)
00220 mINT32 _emit_id;
00221 #endif // TARG_SL
00222
00223 #ifdef KEY
00224 struct pu_info *_builtin_pu_info;
00225 mUINT32 _sizeof_eh_spec;
00226 mINT32 _file_id;
00227 #endif
00228
00229 IPAA_NODE_INFO* _mod_ref_info;
00230 VALUE_DYN_ARRAY* _cprop_annot;
00231 GLOBAL_ANNOT* _global_annot;
00232 IPA_NODE_SECTION_INFO* _array_annot;
00233 FEEDBACK* _feedback_info;
00234
00235 MEM_POOL _mem_pool;
00236 WN_MAP _parent_map;
00237
00238 IPA_ICALL_LIST _icall_list;
00239 IPA_ICALL_LIST _ocall_list;
00240
00241
00242
00243 UINT16 _total_succ;
00244 mUINT32 _max_region_id;
00245
00246 mUINT32 _flags;
00247 INT32 _partition_num;
00248 #ifdef _LIGHTWEIGHT_INLINER
00249 INLINED_BODY_LIST _inlined_list;
00250
00251 #endif // _LIGHTWEIGHT_INLINER
00252 public:
00253
00254
00255 IPA_NODE (ST* st,
00256 INT32 file_idx,
00257 INT32 p_idx,
00258 INT32 summary_idx,
00259 NODE_INDEX index,
00260 IPA_NODE_INDEX array_index) :
00261 _proc_info_index (p_idx),
00262 _file_index (file_idx),
00263 _summary_proc_index (summary_idx),
00264 _vertex_index (index),
00265 _array_index (array_index),
00266 _func_st (st),
00267 _scope_tab (NULL),
00268 _cloned_symtab (NULL),
00269 _callee_state (NULL),
00270 _mod_ref_info (NULL),
00271 _cprop_annot (NULL),
00272 _array_annot (NULL),
00273 _global_annot (NULL),
00274 _feedback_info (NULL),
00275 _parent_map (0),
00276 _icall_list (),
00277 _ocall_list (),
00278 _max_region_id (0),
00279 #ifdef _LIGHTWEIGHT_INLINER
00280 _inlined_list (),
00281 #endif
00282 _flags (0),
00283 _partition_num(0)
00284 #ifdef KEY
00285 ,_builtin_pu_info (NULL)
00286 ,_sizeof_eh_spec (0)
00287 ,_file_id (-1)
00288 #endif
00289 {
00290 #ifdef KEY
00291
00292
00293 if (_file_index == -1) {
00294 _total_succ = 0;
00295 Is_True ((_flags & _mempool_init) == 0,
00296 ("Uninitialized IPA NODE mempool"));
00297 Is_True(st != 0, ("IPA NODE must have valid st"));
00298 return;
00299 }
00300 #endif
00301
00302 SUMMARY_PROCEDURE* summary_proc = this->Summary_Proc();
00303 _pu_size.Set_PU_Size (summary_proc->Get_bb_count (),
00304 summary_proc->Get_stmt_count (),
00305 summary_proc->Get_call_count ());
00306 _total_succ = summary_proc->Get_callsite_count();
00307
00308 Is_True ((_flags & _mempool_init) == 0,
00309 ("Uninitialized IPA NODE mempool"));
00310 Is_True(st != 0, ("IPA NODE must have valid st"));
00311 Is_True(p_idx >= 0 && p_idx < IP_FILE_HDR_num_procs(File_Header()),
00312 ("Bad proc index, should be in range 0 <= idx < %d",
00313 IP_FILE_HDR_num_procs(File_Header())));
00314 }
00315
00316
00317
00318 void Set_File_Index ( INT32 i ) { _file_index = i; }
00319 INT32 File_Index () const { return _file_index; }
00320 void Set_Partition_Num(INT32 num) { _partition_num = num; }
00321 INT32 Get_Partition_Num(void) { return _partition_num; }
00322 void Set_Proc_Info_Index ( INT32 i ) { _proc_info_index = i; }
00323 INT32 Proc_Info_Index () const
00324 {
00325 Is_True(_proc_info_index >= 0 &&
00326 _proc_info_index < IP_FILE_HDR_num_procs(File_Header()),
00327 ("Proc idx %d should be in range 0 <= idx < %u (input file %s)",
00328 _proc_info_index,
00329 IP_FILE_HDR_num_procs(File_Header()),
00330 Input_File_Name()));
00331 return _proc_info_index;
00332 }
00333
00334 void Set_Summary_Proc_Index (INT32 i) { _summary_proc_index = i;}
00335 INT32 Summary_Proc_Index () const { return _summary_proc_index; }
00336
00337 NODE_INDEX Node_Index () const { return _vertex_index; }
00338
00339 IPA_NODE_INDEX Array_Index () const { return _array_index; }
00340
00341 void Set_Func_ST (ST* st) { _func_st = st; }
00342 ST *Func_ST () const { return _func_st; }
00343
00344 void Set_Scope (SCOPE* scope_tab) { _scope_tab = scope_tab; }
00345 SCOPE* Scope_Table () { return _scope_tab; }
00346 SCOPE* Scope ();
00347
00348 void Set_Cloned_Symtab (IPO_SYMTAB *symtab) { _cloned_symtab = symtab; }
00349 void Clear_Cloned_Symtab ();
00350 IPO_SYMTAB* Cloned_Symtab () { return _cloned_symtab; }
00351
00352 void Set_PU_Size (const PU_SIZE& sze) { _pu_size = sze;};
00353 const PU_SIZE& PU_Size () const { return _pu_size;};
00354 void UpdateSize (IPA_NODE* callee, IPA_EDGE* edge);
00355
00356 void Set_Callee_State (CALLEE_STATE* ste) { _callee_state = ste; }
00357 CALLEE_STATE *Callee_State () const { return _callee_state; }
00358
00359 void Set_Mod_Ref_Info (IPAA_NODE_INFO* info) { _mod_ref_info = info; }
00360 IPAA_NODE_INFO* Mod_Ref_Info () const { return _mod_ref_info; }
00361
00362 void Set_Cprop_Annot (VALUE_DYN_ARRAY* annot) { _cprop_annot = annot; }
00363 VALUE_DYN_ARRAY* Cprop_Annot() const { return _cprop_annot; }
00364
00365 void Set_Global_Annot (GLOBAL_ANNOT* annot) { _global_annot = annot; }
00366 GLOBAL_ANNOT* Global_Annot () const { return _global_annot; }
00367
00368 void Set_Feedback_Info (FEEDBACK* fb) { _feedback_info = fb; }
00369 FEEDBACK* Feedback_Info () const { return _feedback_info; }
00370
00371 void Set_Section_Annot (IPA_NODE_SECTION_INFO* annot)
00372 {
00373 _array_annot = annot;
00374 }
00375 IPA_NODE_SECTION_INFO* Section_Annot () const { return _array_annot;};
00376
00377 MEM_POOL* Mem_Pool () const { return (MEM_POOL*)(&_mem_pool); }
00378
00379 void Set_Parent_Map(WN_MAP map) { _parent_map = map; }
00380 WN_MAP Parent_Map(void) const { return _parent_map; }
00381
00382 IPA_ICALL_LIST& Icall_List () { return _icall_list; }
00383
00384 IPA_ICALL_LIST& Ocall_List () { return _ocall_list; }
00385
00386 void Set_Total_Succ (INT32 i) { _total_succ = i; }
00387 void Incr_Total_Succ () { _total_succ++; }
00388 UINT16 Total_Succ () const { return _total_succ; }
00389
00390 void Set_Max_Region_Id (mUINT32 i) { _max_region_id = i; }
00391 mUINT32 Max_Region_Id () const { return _max_region_id; }
00392
00393
00394 void Set_Flags (UINT32 flags) { _flags |= flags; }
00395 void Clear_Flags (UINT32 flags) { _flags &= ~flags; }
00396 UINT32 Flags () const { return _flags; }
00397
00398 #ifdef _LIGHTWEIGHT_INLINER
00399 INLINED_BODY_LIST& Inlined_list () { return _inlined_list; }
00400 #endif // _LIGHTWEIGHT_INLINER
00401
00402
00403 void Set_Clone () { _flags |= _clone; }
00404 BOOL Is_Clone () const { return _flags & _clone; }
00405
00406
00407 void Set_Visited () { _flags |= _visited; }
00408 void Clear_Visited () { _flags &= ~_visited; }
00409 BOOL Is_Visited () const { return _flags & _visited; }
00410
00411
00412 void Set_Mempool_Initialized () { _flags |= _mempool_init; }
00413 void Clear_Mempool_Initialized () { _flags &= ~_mempool_init; }
00414 BOOL Is_Mempool_Initialized () const { return _flags & _mempool_init; }
00415
00416
00417 void Set_Deletable ()
00418 {
00419 if ((_flags & _dont_delete) == 0)
00420 _flags |= _deletable;
00421 }
00422 void Clear_Deletable ()
00423 {
00424 _flags &= ~_deletable;
00425 }
00426 BOOL Is_Deletable () const
00427 {
00428 return ((_flags & _deletable) && !(_flags & _dont_delete));
00429 }
00430
00431
00432 void Set_Undeletable ()
00433 {
00434 _flags = (_flags & ~_deletable) | _dont_delete;
00435 }
00436 BOOL Is_Undeletable () const
00437 {
00438 return Summary_Proc()->Is_no_delete () || (_flags & _dont_delete);
00439 }
00440
00441
00442 void Set_Processed () { _flags |= _processed;}
00443 BOOL Is_Processed () const { return _flags & _processed;}
00444
00445
00446 void Set_Recursive_In_Edge () { _flags |= _recursive_in_edge; }
00447 BOOL Has_Recursive_In_Edge () const
00448 {
00449 return ( _flags & _recursive_in_edge);
00450 }
00451
00452
00453 void Set_Feedback () { _flags |= _feedback; }
00454 BOOL Has_Feedback () const { return _flags & _feedback; }
00455
00456
00457 void Set_Propagated_Const () { _flags |= _constants; }
00458 void Clear_Propagated_Const () { _flags &= ~_constants; }
00459 BOOL Has_Propagated_Const () { return _flags & _constants; }
00460
00461
00462 void Set_Clone_Candidate () { _flags |= _clone_candidate; }
00463 void Clear_Clone_Candidate () { _flags &= ~_clone_candidate; }
00464 BOOL Is_Clone_Candidate () const { return _flags & _clone_candidate; }
00465
00466
00467 void Set_Needs_Padding () { _flags |= _padding; }
00468 BOOL Needs_Padding () const { return _flags & _padding; }
00469
00470
00471 void Set_Non_Local () { _flags |= _non_local; }
00472 BOOL Is_Non_Local () const { return _flags & _non_local; }
00473
00474
00475 void Set_No_Aggr_Cprop () { _flags |= _no_aggressive_cprop; }
00476 BOOL Has_No_Aggr_Cprop () const { return _flags & _no_aggressive_cprop; }
00477
00478
00479 void Set_Split_Commons () { _flags |= _split_commons; }
00480 void Clear_Split_Commons () { _flags &= ~_split_commons; }
00481 BOOL Needs_Split_Commons () const { return _flags & _split_commons; }
00482
00483
00484 void Set_Use_Kill () { _flags |= _use_kill;};
00485 BOOL Has_Use_Kill () const { return _flags & _use_kill;};
00486
00487
00488 void Set_Incoming_Back_Edge () { _flags |= _incoming_back_edge; }
00489 BOOL Has_Incoming_Back_Edge () const { return _flags & _incoming_back_edge; }
00490
00491
00492 void Set_Quasi_Clone () { _flags |= _quasi_clone; }
00493 void Clear_Quasi_Clone () { _flags &= ~_quasi_clone; }
00494 BOOL Is_Quasi_Clone () const { return _flags & _quasi_clone; }
00495
00496
00497 void Set_Preoptimized () { _flags |= _preoptimized; }
00498 BOOL Is_Preoptimized () const { return _flags & _preoptimized; }
00499
00500 #ifdef KEY
00501
00502 void Set_Builtin () { _flags |= _builtin; }
00503 BOOL Is_Builtin () const { return _flags & _builtin; }
00504
00505
00506 void Set_PU_Write_Complete () { _flags |= _pu_write_complete; }
00507 BOOL Is_PU_Write_Complete () const { return _flags & _pu_write_complete; }
00508
00509
00510 void Set_EH_spec_size (mUINT32 s) { _sizeof_eh_spec = s; }
00511 mUINT32 EH_spec_size () const { return _sizeof_eh_spec; }
00512
00513
00514 void Set_Recursive () { _flags |= _recursive; }
00515 BOOL Is_Recursive () { return _flags & _recursive; }
00516
00517 void Set_Merged () { _flags |= _merged; }
00518 BOOL Is_Merged () { return _flags & _merged; }
00519
00520 void Set_PU_Can_Throw () { _flags |= _can_throw; }
00521 BOOL PU_Can_Throw () { return _flags & _can_throw; }
00522
00523 void Set_EHinfo_Updated () { _flags |= _ehinfo_updated; }
00524 BOOL EHinfo_Updated () { return _flags & _ehinfo_updated; }
00525
00526 void Set_File_Id (mINT32 f) { _file_id = f; }
00527 mINT32 File_Id () const { return _file_id; }
00528
00529 void Set_Pending_Icalls () { _flags |= _pending_icalls; }
00530 BOOL Has_Pending_Icalls () const { return _flags & _pending_icalls; }
00531
00532 static mINT32 next_file_id;
00533 #endif
00534
00535
00536
00537
00538
00539
00540
00541 void Set_Aliased_Formal () { _flags |= _has_aliased_formal; }
00542 BOOL Has_Aliased_Formal () const { return _flags & _has_aliased_formal; }
00543
00544
00545 SUMMARY_PROCEDURE* Summary_Proc () const
00546 {
00547 return IPA_get_procedure_array(this) + _summary_proc_index;
00548 }
00549
00550 SUMMARY_SYMBOL* Summary_Symbol () const
00551 {
00552 return IPA_get_symbol_array(this) + Summary_Proc()->Get_symbol_index();
00553 }
00554
00555
00556 void Clear_Has_Pstatics () { Summary_Proc()->Reset_has_pstatics(); }
00557 BOOL Has_Pstatics () { return Summary_Proc()->Has_pstatic(); }
00558
00559 BOOL Has_Direct_Mod_Ref()
00560 {
00561 return (Summary_Proc() ? Summary_Proc()->Is_direct_mod_ref() : TRUE);
00562 }
00563
00564 mUINT16 Num_Formals () const { return Summary_Proc()->Get_formal_count();};
00565
00566
00567 PU& Get_PU () const
00568 {
00569 Is_True(_func_st != 0, ("IPA_NODE: null ST pointer"));
00570 Is_True(ST_pu(_func_st) > 0 && ST_pu(_func_st) < Pu_Table.size(),
00571 ("PU index %d should be in range 0 < idx < %d",
00572 ST_pu(_func_st), Pu_Table.size()));
00573 return Pu_Table[ST_pu(_func_st)];
00574 }
00575
00576
00577 void Set_Must_Inline_Attrib () { Set_PU_must_inline (Get_PU ()); }
00578 void Clear_Must_Inline_Attrib () { Clear_PU_must_inline (Get_PU ()); }
00579 BOOL Has_Must_Inline_Attrib () const { return PU_must_inline (Get_PU ()); }
00580
00581 void Set_Noinline_Attrib () { Set_PU_no_inline (Get_PU ()); }
00582 void Clear_Noinline_Attrib () { Clear_PU_no_inline (Get_PU ()); }
00583 BOOL Has_Noinline_Attrib () const { return PU_no_inline (Get_PU ()); }
00584
00585 void Set_Inline_Attrib () { Set_PU_is_inline_function (Get_PU ()); }
00586 void Clear_Inline_Attrib () { Clear_PU_is_inline_function (Get_PU ()); }
00587 BOOL Has_Inline_Attrib () const { return PU_is_inline_function (Get_PU ()); }
00588
00589 BOOL Is_Nested_PU () const { return PU_is_nested_func(Get_PU()); }
00590
00591 BOOL Has_Varargs () const
00592 {
00593 return TY_is_varargs (Ty_Table[PU_prototype (Get_PU ())]);
00594 }
00595
00596 BOOL Is_Lang_F77() const { return PU_f77_lang (Get_PU()); }
00597 BOOL Is_Lang_F90() const { return PU_f90_lang (Get_PU()); }
00598 #ifdef KEY
00599 BOOL Is_Lang_CXX() const { return PU_cxx_lang (Get_PU()); }
00600 #endif
00601
00602
00603 UINT32 Weight (void) const { return _pu_size.Weight (); }
00604
00605 SYMTAB_IDX Lexical_Level(void) const { return PU_lexical_level(Get_PU()); }
00606
00607 IP_FILE_HDR& File_Header(void) const
00608 {
00609 Is_True(_file_index >= 0 && _file_index < IP_File_header.size(),
00610 ("IPA_NODE: file index %d should be in range 0 <= idx < %d",
00611 _file_index, IP_File_header.size()));
00612 return IP_File_header[_file_index];
00613 }
00614
00615 FILE_INFO& File_Info(void) const
00616 {
00617 return IP_FILE_HDR_file_info(File_Header());
00618 }
00619
00620 DST_TYPE File_Dst(void) const
00621 {
00622 return IP_FILE_HDR_dst(File_Header());
00623 }
00624
00625 const char *Input_File_Name () const
00626 {
00627 return IP_FILE_HDR_file_name (File_Header());
00628 }
00629 const char *Output_File_Name () const
00630 {
00631 DevWarn("IPA_NODE::Output_File_Name is not yet implemented");
00632 return "Unknown_Output_File.I";
00633 }
00634
00635 char *Name (void) const
00636 {
00637 Is_True (_func_st != 0, ("IPA_NODE: null st"));
00638 return ST_name(_func_st);
00639 }
00640
00641 struct pu_info *PU_Info(void) const
00642 {
00643 Is_True(_func_st != 0, ("IPA NODE must have valid st"));
00644 #if 0
00645 Is_True(&St_Table[PU_Info_proc_sym(IP_FILE_HDR_proc_info(
00646 File_Header())[Proc_Info_Index()].info)]
00647 == _func_st,
00648 ("IPA_NODE: file/proc indices [%d:%d] inconsistent with st",
00649 _file_index, _proc_info_index));
00650 #endif
00651
00652 #ifdef KEY
00653 if (this->Is_Builtin())
00654 return _builtin_pu_info;
00655 #endif
00656
00657 return IP_FILE_HDR_proc_info (File_Header())[Proc_Info_Index()].info;
00658 }
00659
00660 #ifdef KEY
00661 void Set_Builtin_PU_Info (struct pu_info *p) { _builtin_pu_info = p; }
00662
00663 struct pu_info *Builtin_PU_Info() { return _builtin_pu_info; }
00664 #endif
00665
00666 WN_MAP_TAB* Map_Table() const
00667 {
00668 return (PU_Info_maptab(PU_Info()));
00669 }
00670
00671 DST_IDX Dst_Index() const
00672 {
00673 return (PU_Info_pu_dst(PU_Info()));
00674 }
00675
00676
00677
00678 BOOL Is_Externally_Callable ();
00679
00680 void Read_PU (BOOL = TRUE);
00681
00682 WN* Whirl_Tree (BOOL = TRUE);
00683
00684 void Set_Whirl_Tree (WN *wn);
00685
00686 void Write_PU ();
00687
00688 void Un_Read_PU ();
00689
00690 void Set_Global_Tables(IPA_CALL_GRAPH*)
00691 {
00692 DevWarn("Use IPA_NODE_CONTEXT instead of IPA_NODE::Set_Global_Tables");
00693 }
00694
00695
00696 BOOL Should_Be_Skipped () const
00697 {
00698 static BOOL reported = FALSE;
00699 if (!reported) {
00700 reported = TRUE;
00701 DevWarn("IPA_NODE::Skip is not yet implemented");
00702 }
00703 return FALSE;
00704 }
00705
00706
00707 void Cleanup_State(IPA_CALL_GRAPH*)
00708 {
00709 DevWarn("IPA_NODE::Cleanup_State is not yet implemented");
00710 }
00711
00712 void Print (FILE* fp) const
00713 {
00714 fprintf (fp, "%s\n", Name());
00715 }
00716
00717 void Trace () const
00718 {
00719 Print (TFile);
00720 }
00721
00722 BOOL Has_frequency() const { return Summary_Proc()->Has_PU_freq(); };
00723
00724
00725 SUMMARY_FEEDBACK *Get_feedback () const {
00726 #if (defined(_STANDALONE_INLINER) || defined(_LIGHTWEIGHT_INLINER))
00727 return NULL;
00728 #else
00729 #ifdef KEY
00730
00731
00732
00733
00734 if( Summary_Proc()->Is_Never_Invoked() ){
00735 return NULL;
00736 }
00737 #endif
00738 return IPA_get_feedback_array (this) + Summary_Proc()->Get_feedback_index ();
00739 #endif
00740 }
00741
00742 FB_FREQ Get_frequency() {
00743 SUMMARY_FEEDBACK* fb = Get_feedback();
00744 return (fb? fb->Get_frequency_count (): FB_FREQ_UNKNOWN);
00745 };
00746
00747
00748 UINT16 Get_wn_count () {
00749 SUMMARY_FEEDBACK* fb = Get_feedback();
00750 return (fb? fb->Get_wn_count(): 0);
00751 };
00752
00753 FB_FREQ Get_cycle_count_2 () {
00754 SUMMARY_FEEDBACK* fb = Get_feedback();
00755 return (fb? fb->Get_cycle_count_2(): FB_FREQ_UNKNOWN);
00756 };
00757
00758 FB_FREQ Get_cycle_count () {
00759 SUMMARY_FEEDBACK* fb = Get_feedback();
00760 return (fb? fb->Get_cycle_count (): FB_FREQ_UNKNOWN);
00761 };
00762
00763 #ifdef KEY
00764 UINT64 Get_func_runtime_addr () {
00765 SUMMARY_FEEDBACK * fb = Get_feedback();
00766 return (fb ? fb->Get_func_runtime_addr () : 0);
00767 }
00768 #endif
00769
00770 #ifdef _LIGHTWEIGHT_INLINER
00771 void Add_to_inlined_list (char *body) {
00772 _inlined_list.push_back(body);
00773 }
00774
00775 void Free_inlined_list();
00776
00777 #endif // _LIGHTWEIGHT_INLINER
00778
00779 #if defined(TARG_SL)
00780 void Set_Emit_Id(mINT32 i) { _emit_id = i; }
00781 mINT32 Emit_Id() const { return _emit_id; }
00782 #endif // TARG_SL
00783
00784 };
00785
00786 #ifdef KEY
00787 #include <ext/hash_map>
00788 #include <functional>
00789 struct option_cmp : public std::binary_function<char *, char *, bool>
00790 {
00791 bool operator() (char * s1, char * s2)
00792 {
00793 return (strcmp (s1, s2) < 0);
00794 }
00795 };
00796
00797 struct hashfn
00798 {
00799 size_t operator()(const IPA_NODE* n) const {
00800 return reinterpret_cast<size_t>(n);
00801 }
00802 };
00803
00804 struct eqnode
00805 {
00806 bool operator()(const IPA_NODE* n1, const IPA_NODE* n2) const
00807 {
00808 return n1 == n2;
00809 }
00810 };
00811 extern vector<IPA_NODE *> emit_order;
00812
00813 class Nodes_To_Edge
00814 {
00815 NODE_INDEX caller_id, callee_id;
00816 IPA_EDGE * e;
00817 public:
00818 Nodes_To_Edge (NODE_INDEX from, NODE_INDEX to, IPA_EDGE * edge=0) :
00819 caller_id (from), callee_id (to), e (edge) {}
00820 IPA_EDGE * Edge (void) const { return e; }
00821 NODE_INDEX Caller (void) const { return caller_id; }
00822 NODE_INDEX Callee (void) const { return callee_id; }
00823 bool operator== (const Nodes_To_Edge * o)
00824 {
00825 return (caller_id == o->caller_id && callee_id == o->callee_id);
00826 }
00827 };
00828 #endif
00829
00830 class IPA_EDGE
00831 {
00832 private:
00833
00834 static const mUINT32 _processed = 0x01;
00835 static const mUINT32 _constants = 0x02;
00836 static const mUINT32 _deletable = 0x04;
00837 static const mUINT32 _recursive = 0x08;
00838 static const mUINT32 _inline = 0x10;
00839 static const mUINT32 _must_inline = 0x20;
00840 static const mUINT32 _no_inline = 0x40;
00841
00842 EDGE_INDEX _edge_index;
00843 IPA_EDGE_INDEX _array_index;
00844 SUMMARY_CALLSITE *_c;
00845 WN *_w;
00846 #ifdef KEY
00847 WN *_eh_wn;
00848 LABEL_IDX try_label;
00849 WN *_mp_wn;
00850 #endif
00851
00852 VALUE_DYN_ARRAY *_cprop_annot;
00853
00854 mUINT32 _flags;
00855 mUINT32 _readonly_actuals;
00856 mUINT32 _pass_not_saved_actuals;
00857 UINT32 _reason_ID; float _reason_data;
00858
00859 public:
00860
00861 IPA_EDGE (SUMMARY_CALLSITE *c,
00862 EDGE_INDEX index,
00863 IPA_EDGE_INDEX array_index) :
00864 _edge_index(index),
00865 _array_index (array_index),
00866 _c(c),
00867 _w(0),
00868 #ifdef KEY
00869 _eh_wn(0),
00870 try_label(0),
00871 _mp_wn(0),
00872 #endif
00873 _cprop_annot(0),
00874 _flags(0),
00875 _readonly_actuals(0),
00876 _pass_not_saved_actuals(0),
00877 _reason_ID(0),
00878 _reason_data(0.0)
00879 {}
00880
00881
00882 UINT32 reason_id() {return _reason_ID;}
00883 float reason_data() {return _reason_data;}
00884 void Set_reason_id(UINT32 i) { _reason_ID = i;}
00885 void Set_reason_data(float i) { _reason_data = i;}
00886
00887 void Set_Edge_Index (EDGE_INDEX i) { _edge_index = i; }
00888 EDGE_INDEX Edge_Index () const { return _edge_index; }
00889
00890 IPA_EDGE_INDEX Array_Index () const { return _array_index; }
00891
00892 SUMMARY_CALLSITE* Summary_Callsite () const { return _c; }
00893
00894 void Set_Whirl_Node (WN* w) { _w = w; }
00895 WN* Whirl_Node () const { return _w; }
00896
00897 #ifdef KEY
00898 void Set_EH_Whirl_Node (WN* w) { _eh_wn = w; }
00899 WN* EH_Whirl_Node () const { return _eh_wn; }
00900
00901
00902 void Set_Try_Label (LABEL_IDX l) { try_label = l; }
00903 LABEL_IDX Try_Label () const { return try_label; }
00904
00905 void Set_MP_Whirl_Node (WN * w) { _mp_wn = w; }
00906 WN * MP_Whirl_Node () const { return _mp_wn; }
00907 #endif
00908
00909 void Set_Cprop_Annot (VALUE_DYN_ARRAY* annot) { _cprop_annot = annot; }
00910 VALUE_DYN_ARRAY* Cprop_Annot () const { return _cprop_annot; }
00911
00912
00913 void Set_Processed () { _flags |= _processed; }
00914 BOOL Is_Processed () const { return _flags & _processed; }
00915
00916 void Set_Propagated_Const () { _flags |= _constants; }
00917 BOOL Has_Propagated_Const () const { return _flags & _constants; }
00918
00919 void Set_Deletable () { _flags |= _deletable; }
00920 BOOL Is_Deletable () const { return _flags & _deletable; }
00921
00922 void Set_Recursive () { _flags |= _recursive; }
00923 BOOL Is_Recursive () const { return _flags & _recursive;}
00924
00925 void Set_Must_Inline_Attrib () { _flags |= _must_inline; }
00926 BOOL Has_Must_Inline_Attrib () const { return _flags & _must_inline; }
00927
00928 void Set_Inline_Attrib () { _flags |= _inline; }
00929 BOOL Has_Inline_Attrib () const { return _flags & _inline; }
00930
00931 void Set_Noinline_Attrib () { _flags |= _no_inline; }
00932 BOOL Has_Noinline_Attrib () const { return _flags & _no_inline; }
00933
00934 void Clear_All_Inline_Attrib () { _flags &= ~(_inline|_must_inline); }
00935
00936
00937
00938
00939
00940
00941 void Set_Param_Readonly (INT32 pos) { _readonly_actuals |= (1 << pos); }
00942 void Clear_Param_Readonly (INT32 pos) { _readonly_actuals &= ~(1 << pos); }
00943 BOOL Is_Param_Readonly (INT32 pos) const
00944 {
00945 return _readonly_actuals & (1 << pos);
00946 }
00947 BOOL Has_Readonly_Param () const { return _readonly_actuals != 0; }
00948
00949
00950 void Set_Param_Pass_Not_Saved (INT32 pos)
00951 {
00952 _pass_not_saved_actuals |= (1 << pos);
00953 }
00954 void Clear_Param_Pass_Not_Saved (INT32 pos)
00955 {
00956 _pass_not_saved_actuals &= ~(1 << pos);
00957 }
00958 BOOL Is_Param_Pass_Not_Saved (INT32 pos) const
00959 {
00960 return _pass_not_saved_actuals & (1 << pos);
00961 }
00962 BOOL Has_Pass_Not_Saved_Param () const
00963 {
00964 return _pass_not_saved_actuals != 0;
00965 }
00966
00967 static INT Max_Num_Readonly_Actuals() { return sizeof(mUINT32) * 8; }
00968
00969
00970 UINT16 Callsite_Id () const { return _c->Get_callsite_id(); }
00971
00972
00973 UINT16 Num_Actuals () const { return _c->Get_param_count(); }
00974
00975 void Print (const FILE *f,
00976 const IPA_CALL_GRAPH *cg,
00977 BOOL invert = FALSE ) const;
00978
00979 void Trace ( const IPA_CALL_GRAPH *cg, BOOL invert = FALSE ) const;
00980
00981
00982 IPA_EDGE* Copy (MEM_POOL*)
00983 {
00984 DevWarn("IPA_EDGE::Copy is not yet implemented");
00985 return 0;
00986 }
00987
00988
00989 BOOL Has_frequency () const {
00990 return Summary_Callsite() ? Summary_Callsite()->Has_callsite_freq() : FALSE;
00991 }
00992
00993 FB_FREQ Get_frequency ( void ) {
00994 return Summary_Callsite() ? Summary_Callsite()->Get_frequency_count() : FB_FREQ_UNKNOWN;
00995 }
00996
00997 #ifdef KEY
00998 void Set_frequency ( FB_FREQ freq ) {
00999 if (Summary_Callsite())
01000 Summary_Callsite()->Set_frequency_count (freq) ;
01001 }
01002 #endif
01003
01004 };
01005
01006
01007 typedef GRAPH_TEMPLATE<IPA_NODE*, IPA_EDGE*> IPA_GRAPH;
01008 typedef DYN_ARRAY<IPA_NODE*> IPA_CLONE_ARRAY;
01009
01010
01011 class IPA_CALL_GRAPH
01012 {
01013 typedef SEGMENTED_ARRAY<IPA_NODE> IPA_NODE_ARRAY;
01014 typedef SEGMENTED_ARRAY<IPA_EDGE> IPA_EDGE_ARRAY;
01015
01016 typedef HASH_TABLE<IPA_NODE*, IPA_CLONE_ARRAY*> IPA_NODE_TO_IPA_CLONES_MAP;
01017 typedef HASH_TABLE<IPA_NODE*, IPA_NODE*> IPA_CLONE_TO_IPA_NODE_MAP;
01018 typedef HASH_TABLE<const IPA_NODE*, IPL_SUMMARY_PTRS*> IPA_NODE_TO_IPL_SUMMARY_MAP;
01019
01020 private:
01021 MEM_POOL* _pool;
01022 IPA_GRAPH* _graph;
01023 IPA_NODE_ARRAY* _nodes;
01024 IPA_EDGE_ARRAY* _edges;
01025 IPA_CLONE_TO_IPA_NODE_MAP* _clone_to_orig_node_map;
01026 IPA_NODE_TO_IPA_CLONES_MAP* _orig_node_to_clones_map;
01027 IPA_NODE_TO_IPL_SUMMARY_MAP* _preopt_node_to_new_summary_map;
01028
01029 public:
01030 IPA_CALL_GRAPH (MEM_POOL* pool)
01031 {
01032 _pool = pool;
01033 _graph = CXX_NEW (IPA_GRAPH(pool), pool);
01034 _nodes = CXX_NEW (IPA_NODE_ARRAY, pool);
01035 _edges = CXX_NEW (IPA_EDGE_ARRAY, pool);
01036 _clone_to_orig_node_map = NULL;
01037 _orig_node_to_clones_map = NULL;
01038 _preopt_node_to_new_summary_map = NULL;
01039 }
01040
01041 IPA_GRAPH* Graph () const { return _graph; }
01042
01043 UINT Edge_Size () const { return _edges->Size (); }
01044 UINT Node_Size () const { return _nodes->Size (); }
01045
01046 IPA_NODE* Node (IPA_NODE_INDEX idx) { return &(_nodes->Entry (idx)); }
01047 IPA_EDGE* Edge (IPA_EDGE_INDEX idx) { return &(_edges->Entry (idx)); }
01048
01049 void Set_Root (NODE_INDEX root) { GRAPH_root(_graph) = root; }
01050 NODE_INDEX Root () const { return GRAPH_root(_graph); }
01051
01052
01053 IPA_NODE* Add_New_Node (ST* st,
01054 INT32 file_index,
01055 INT32 proc_info_index,
01056 INT32 summary_proc_index)
01057 {
01058
01059 UINT32 index;
01060 IPA_NODE* node = &(_nodes->New_entry(index));
01061
01062
01063 new (node) IPA_NODE (st,
01064 file_index,
01065 proc_info_index,
01066 summary_proc_index,
01067 _graph->Add_Node(node),
01068 index);
01069 return node;
01070 }
01071
01072
01073 IPA_EDGE* Add_New_Edge (SUMMARY_CALLSITE* callsite,
01074 NODE_INDEX caller_index,
01075 NODE_INDEX callee_index)
01076 {
01077
01078 UINT32 index;
01079 IPA_EDGE* edge = &(_edges->New_entry(index));
01080
01081
01082 new (edge) IPA_EDGE (callsite,
01083 _graph->Add_Edge (caller_index, callee_index, edge),
01084 index);
01085 return edge;
01086 }
01087
01088
01089
01090 void Add_Edge (IPA_NODE* caller, IPA_NODE* callee, IPA_EDGE* edge)
01091 {
01092 EDGE_INDEX edge_index =
01093 _graph->Add_Edge (caller->Node_Index(), callee->Node_Index(), edge);
01094 if (edge) {
01095 edge->Set_Edge_Index (edge_index);
01096 }
01097 caller->Incr_Total_Succ();
01098 }
01099
01100 IPA_NODE* Caller (EDGE_INDEX edge_idx) const
01101 {
01102 return _graph->Node_User(EDGE_from(&GRAPH_e_i(_graph, edge_idx)));
01103 }
01104 IPA_NODE* Caller (const IPA_EDGE* edge) const
01105 {
01106 return Caller(edge->Edge_Index());
01107 }
01108
01109 IPA_NODE* Callee (EDGE_INDEX edge_idx) const
01110 {
01111 return _graph->Node_User(EDGE_to(&GRAPH_e_i(_graph, edge_idx)));
01112 }
01113 IPA_NODE* Callee (const IPA_EDGE* edge) const
01114 {
01115 return Callee(edge->Edge_Index());
01116 }
01117
01118 INT32 Num_Out_Edges (const IPA_NODE* n) const
01119 {
01120 return NODE_fcnt(&GRAPH_v_i(_graph, n->Node_Index()));
01121 }
01122 INT32 Num_In_Edges (const IPA_NODE* n) const
01123 {
01124 return NODE_tcnt(&GRAPH_v_i(_graph, n->Node_Index()));
01125 }
01126
01127 INT32 Node_Depth (IPA_NODE* node) const
01128 {
01129 return NODE_level(&GRAPH_v_i(_graph, node->Node_Index()));
01130 }
01131
01132 #ifdef KEY
01133 void Merge_Nodes (NODE_INDEX, NODE_INDEX);
01134 #endif
01135
01136
01137 INT32 Num_Calls (IPA_NODE* caller, IPA_NODE* callee) const;
01138
01139
01140 void Print (FILE*);
01141
01142
01143 void Print (FILE*, TRAVERSAL_ORDER);
01144
01145
01146 void Print_vobose (FILE*);
01147 void Print_vobose (FILE*, TRAVERSAL_ORDER);
01148
01149
01150
01151 void Map_Callsites(IPA_NODE* caller);
01152
01153
01154 IPA_NODE* Create_Clone (IPA_NODE* node);
01155
01156
01157
01158 IPA_NODE* Create_Quasi_Clone (IPA_EDGE* call_edge);
01159
01160
01161 void Quasi_To_Real_Clone (IPA_NODE* clone);
01162
01163
01164 void Remove_Quasi_Clone (IPA_NODE* clone);
01165
01166
01167 IPA_NODE* Clone_Origin (IPA_NODE* clone) const
01168 {
01169 Is_True(_clone_to_orig_node_map,
01170 ("IPA_CALL_GRAPH::Clone_Origin: _clone_to_orig_node_map is NULL"));
01171 return _clone_to_orig_node_map->Find (clone);
01172 }
01173
01174
01175 IPA_CLONE_ARRAY* Clone_Array (IPA_NODE* node) const
01176 {
01177 return (_orig_node_to_clones_map ?
01178 _orig_node_to_clones_map->Find(node) : NULL);
01179 }
01180
01181
01182 void Update_Node_After_Preopt (IPA_NODE*,
01183 WN*,
01184 SUMMARY_CALLSITE*,
01185 IPL_SUMMARY_PTRS*);
01186
01187
01188 IPL_SUMMARY_PTRS* New_Summary_Ptrs (const IPA_NODE* node) const
01189 {
01190 Is_True (_preopt_node_to_new_summary_map,
01191 ("IPA_CALL_GRAPH::New_Summary_Ptrs: _preopt_node_to_new_summary_map is NULL"));
01192 Is_True (node->Is_Preoptimized(),
01193 ("IPA_CALL_GRAPH::New_Summary_Ptrs: node is not preoptimized"));
01194 return _preopt_node_to_new_summary_map->Find(node);
01195 }
01196
01197 };
01198
01199
01200 extern IPA_CALL_GRAPH *IPA_Call_Graph;
01201 extern BOOL IPA_Call_Graph_Built;
01202
01203 extern void IPA_Process_File (IP_FILE_HDR& hdr);
01204 extern void Build_Call_Graph ();
01205 #ifdef KEY
01206 extern IPA_CALL_GRAPH *IPA_Graph_Undirected;
01207 extern void IPA_Convert_Icalls( IPA_CALL_GRAPH* );
01208 #endif
01209
01210
01211 extern UINT32 Orig_Prog_WN_Count;
01212 extern UINT32 Prog_WN_Count;
01213 extern UINT32 Total_Dead_Function_WN_Count;
01214 extern FB_FREQ Total_cycle_count_2;
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232 template <class EDGE>
01233 class AUX_IPA_EDGE
01234 {
01235 private:
01236 EDGE* data;
01237 MEM_POOL* pool;
01238 UINT edge_size;
01239
01240 public:
01241
01242 AUX_IPA_EDGE (const IPA_CALL_GRAPH* cg, MEM_POOL* m = Malloc_Mem_Pool) :
01243 pool (m), edge_size (cg->Edge_Size()) {
01244 UINT size = sizeof(EDGE) * edge_size;
01245 data = (EDGE*) MEM_POOL_Alloc (pool, size);
01246 BZERO (data, size);
01247 }
01248
01249 ~AUX_IPA_EDGE () { MEM_POOL_FREE (pool, data); }
01250
01251 EDGE& operator[] (const IPA_EDGE* edge) {
01252 Is_True (edge->Array_Index () < edge_size, ("Subscript out of bound"));
01253 return data[edge->Array_Index ()];
01254 }
01255 const EDGE& operator[] (const IPA_EDGE* edge) const {
01256 Is_True (edge->Array_Index () < edge_size, ("Subscript out of bound"));
01257 return data[edge->Array_Index ()];
01258 }
01259
01260 EDGE& operator[] (UINT32 n_idx) {
01261 Is_True (n_idx < edge_size, ("Subscript out of bound"));
01262 return data[n_idx];
01263 }
01264 const EDGE& operator[] (UINT32 n_idx) const {
01265 Is_True (n_idx < edge_size, ("Subscript out of bound"));
01266 return data[n_idx];
01267 }
01268 };
01269
01270
01271 template <class NODE>
01272 class AUX_IPA_NODE
01273 {
01274 private:
01275 NODE* data;
01276 MEM_POOL* pool;
01277 UINT node_size;
01278
01279 public:
01280
01281 AUX_IPA_NODE (const IPA_CALL_GRAPH* cg, MEM_POOL* m = Malloc_Mem_Pool) :
01282 pool (m), node_size (cg->Node_Size()) {
01283 UINT size = sizeof(NODE) * node_size;
01284 data = (NODE*) MEM_POOL_Alloc (pool, size);
01285 BZERO (data, size);
01286 }
01287
01288 ~AUX_IPA_NODE () { MEM_POOL_FREE (pool, data); }
01289
01290
01291
01292 NODE& operator[] (const IPA_NODE* node) {
01293 #if defined(_LIGHTWEIGHT_INLINER) || !defined(_STANDALONE_INLINER)
01294 if (node->Array_Index () >= node_size) {
01295 UINT size = sizeof(NODE) * node_size;
01296 node_size *= 2;
01297 data = (NODE*) MEM_POOL_Realloc (pool, data, size, size*2);
01298 BZERO (((char *)data)+size, size);
01299 }
01300 #else // _LIGHTWEIGHT_INLINER || !_STANDALONE_INLINER
01301 Is_True (node->Array_Index () < node_size, ("Subscript out of bound"));
01302 #endif // _LIGHTWEIGHT_INLINER || !_STANDALONE_INLINER
01303 return data[node->Array_Index ()];
01304 }
01305 const NODE& operator[] (const IPA_NODE* node) const {
01306 #if defined(_LIGHTWEIGHT_INLINER) || !defined(_STANDALONE_INLINER)
01307 if (node->Array_Index () >= node_size) {
01308 UINT size = sizeof(NODE) * node_size;
01309 node_size *= 2;
01310 data = (NODE*) MEM_POOL_Realloc (pool, data, size, size*2);
01311 BZERO (data+size, size);
01312 }
01313 #else // _LIGHTWEIGHT_INLINER || !_STANDALONE_INLINER
01314 Is_True (node->Array_Index () < node_size, ("Subscript out of bound"));
01315 #endif // _LIGHTWEIGHT_INLINER || !_STANDALONE_INLINER
01316 return data[node->Array_Index ()];
01317 }
01318
01319 NODE& operator[] (UINT32 n_idx) {
01320 #if defined(_LIGHTWEIGHT_INLINER) || !defined(_STANDALONE_INLINER)
01321 if (n_idx >= node_size) {
01322 UINT size = sizeof(NODE) * node_size;
01323 node_size *= 2;
01324 data = (NODE*) MEM_POOL_Realloc (pool, data, size, size*2);
01325 BZERO (data+size, size);
01326 }
01327 #else // _LIGHTWEIGHT_INLINER || !_STANDALONE_INLINER
01328 Is_True (n_idx < node_size, ("Subscript out of bound"));
01329 #endif // _LIGHTWEIGHT_INLINER || !_STANDALONE_INLINER
01330 return data[n_idx];
01331 }
01332 const NODE& operator[] (UINT32 n_idx) const {
01333 #if defined(_LIGHTWEIGHT_INLINER) || !defined(_STANDALONE_INLINER)
01334 if (n_idx >= node_size) {
01335 UINT size = sizeof(NODE) * node_size;
01336 node_size *= 2;
01337 data = (NODE*) MEM_POOL_Realloc (pool, data, size, size*2);
01338 BZERO (data+size, size);
01339 }
01340 #else // _LIGHTWEIGHT_INLINER || !_STANDALONE_INLINER
01341 Is_True (n_idx < node_size, ("Subscript out of bound"));
01342 #endif // _LIGHTWEIGHT_INLINER || !_STANDALONE_INLINER
01343 return data[n_idx];
01344 }
01345 };
01346
01347
01348
01349
01350
01351
01352
01353
01354 extern UINT32 Total_Dead_Function_Weight;
01355 extern UINT32 Orig_Prog_Weight;
01356
01357 extern FB_FREQ Total_call_freq;
01358 extern FB_FREQ Total_cycle_count;
01359
01360 extern INT Total_Must_Inlined;
01361 extern INT Total_Must_Not_Inlined;
01362
01363
01364
01365 IPA_NODE* Get_Node_From_PU(PU_Info*);
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381 class IPA_NODE_ITER
01382 {
01383 private:
01384 IPA_GRAPH* _graph;
01385 TRAVERSAL_ORDER _order;
01386 ORDERED_NODE_ITER _node_iter;
01387
01388 public:
01389
01390 IPA_NODE_ITER (TRAVERSAL_ORDER order, MEM_POOL* pool) :
01391 _graph (IPA_Call_Graph->Graph()),
01392 _order (order),
01393 _node_iter (_graph, _order, pool)
01394 {}
01395
01396 IPA_NODE_ITER (IPA_CALL_GRAPH* cg,
01397 TRAVERSAL_ORDER order,
01398 MEM_POOL* pool = Malloc_Mem_Pool) :
01399 _graph (cg->Graph()),
01400 _order (order),
01401 _node_iter (_graph, _order, pool)
01402 {}
01403
01404 void First () { _node_iter.Reset (); }
01405 void Next () { ++_node_iter; }
01406
01407 BOOL Is_Empty () const { return _node_iter.Is_Empty (); }
01408
01409 IPA_NODE* Current (void) const
01410 {
01411 return _graph->Node_User (_node_iter.Current ());
01412 }
01413
01414 void Print (FILE *fp) { _node_iter.Print (fp); }
01415
01416 };
01417
01418
01419
01420
01421
01422 class IPA_SUCC_ITER
01423 {
01424 private:
01425 IPA_GRAPH* _graph;
01426 NODE_INDEX _node_idx;
01427 NODE_ITER _node_iter;
01428
01429 public:
01430
01431 IPA_SUCC_ITER (NODE_INDEX n) :
01432 _graph (IPA_Call_Graph->Graph()),
01433 _node_idx (INVALID_NODE_INDEX),
01434 _node_iter (_graph, n)
01435 {}
01436
01437 IPA_SUCC_ITER (const IPA_NODE* n) :
01438 _graph (IPA_Call_Graph->Graph()),
01439 _node_idx (INVALID_NODE_INDEX),
01440 _node_iter (_graph, n->Node_Index())
01441 {}
01442
01443 IPA_SUCC_ITER (IPA_CALL_GRAPH* cg, IPA_NODE* n) :
01444 _graph (cg->Graph()),
01445 _node_idx (INVALID_NODE_INDEX),
01446 _node_iter (_graph, n->Node_Index())
01447 {}
01448
01449 void First () { _node_idx = _node_iter.First_Succ(); }
01450 void Next () { _node_idx = _node_iter.Next_Succ(); }
01451
01452 BOOL Is_Empty () const { return (_node_idx == INVALID_NODE_INDEX); }
01453
01454 EDGE_INDEX Current_Edge_Index () const
01455 {
01456 return _node_iter.Current_Edge_Index();
01457 }
01458
01459 IPA_EDGE* Current_Edge () const
01460 {
01461 return _graph->Edge_User(Current_Edge_Index());
01462 }
01463
01464 void Set_Current_Edge (IPA_EDGE *e)
01465 {
01466 _graph->Set_Edge_User(Current_Edge_Index(), e);
01467 }
01468
01469 };
01470
01471
01472
01473
01474
01475 class IPA_PRED_ITER
01476 {
01477 IPA_GRAPH* _graph;
01478 NODE_INDEX _node_idx;
01479 NODE_ITER _node_iter;
01480
01481 public:
01482
01483
01484 IPA_PRED_ITER (NODE_INDEX n) :
01485 _graph (IPA_Call_Graph->Graph()),
01486 _node_idx (INVALID_NODE_INDEX),
01487 _node_iter (_graph, n)
01488 {}
01489
01490 IPA_PRED_ITER (const IPA_NODE* n) :
01491 _graph (IPA_Call_Graph->Graph()),
01492 _node_idx (INVALID_NODE_INDEX),
01493 _node_iter (_graph, n->Node_Index())
01494 {}
01495
01496 IPA_PRED_ITER (IPA_CALL_GRAPH* cg, IPA_NODE* n) :
01497 _graph (cg->Graph()),
01498 _node_idx (INVALID_NODE_INDEX),
01499 _node_iter (_graph, n->Node_Index())
01500 {}
01501
01502 void First () { _node_idx = _node_iter.First_Pred(); }
01503 void Next () { _node_idx = _node_iter.Next_Pred(); }
01504
01505 BOOL Is_Empty () const { return (_node_idx == INVALID_NODE_INDEX); }
01506
01507 EDGE_INDEX Current_Edge_Index () const
01508 {
01509 return _node_iter.Current_Edge_Index();
01510 }
01511
01512 IPA_EDGE* Current_Edge () const
01513 {
01514 return _graph->Edge_User(Current_Edge_Index());
01515 }
01516
01517 void Set_Current_Edge (IPA_EDGE *e)
01518 {
01519 _graph->Set_Edge_User(Current_Edge_Index(), e);
01520 }
01521
01522 };
01523
01524 extern UINT32 Eliminate_Dead_Func (BOOL update_modref_count = TRUE);
01525 extern IPA_NODE* Main_Entry (IPA_NODE* ipan_alt);
01526 extern void IPA_update_summary_st_idx (const IP_FILE_HDR& hdr);
01527 extern char* IPA_Node_Name(IPA_NODE* node);
01528
01529 #if defined(KEY) && !defined(_STANDALONE_INLINER) && !defined(_LIGHTWEIGHT_INLINER)
01530 extern void Mark_PUs_With_File_Id (PU_Info *, UINT);
01531 extern BOOL Opt_Options_Inconsistent;
01532 #endif // KEY && !_STANDALONE_INLINER && !_LIGHTWEIGHT_INLINER
01533
01534 #ifdef _LIGHTWEIGHT_INLINER
01535 extern BOOL Is_Node_Inlinable_In_Call_Graph(ST_IDX idx);
01536
01537 extern IPA_NODE* Add_One_Node (IP_FILE_HDR& s, INT32 file_idx, INT i, NODE_INDEX& index);
01538 extern void Add_Edges_For_Node (IP_FILE_HDR& s, INT i, SUMMARY_PROCEDURE* proc_array, SUMMARY_SYMBOL* symbol_array);
01539 extern BOOL Pred_Is_Root(const IPA_NODE* node);
01540 #endif // _LIGHTWEIGHT_INLINER
01541
01542 #endif // cxx_ipa_cg_INCLUDED