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
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 #define __STDC_LIMIT_MACROS
00079 #include <stdint.h>
00080 #if defined(BUILD_OS_DARWIN)
00081 #include <darwin_elf.h>
00082 #else
00083 #include <elf.h>
00084 #endif
00085 #include <cmplrs/host.h>
00086
00087 #include "assert.h"
00088 #define USE_STANDARD_TYPES // override unwanted defines in defs.h
00089 #include "defs.h"
00090 #include "cxx_memory.h"
00091 #include "cxx_hash.h"
00092 #include "erglob.h"
00093 #include "glob.h"
00094 #include "mempool.h"
00095 #include "tracing.h"
00096
00097 #include "strtab.h"
00098 #include "stab.h"
00099 #include "wn.h"
00100 #include "const.h"
00101 #include "pu_info.h"
00102
00103 #include "irbdata.h"
00104 #include "dwarf_DST_mem.h"
00105
00106 #include "ipc_defs.h"
00107 #include "ipc_weak.h"
00108 #include "ipc_file.h"
00109
00110 #include "ipl_summary.h"
00111 #include "ipa_cg.h"
00112 #include "ipa_option.h"
00113 #include "ipa_solver.h"
00114 #include "ipa_summary.h"
00115 #include "ipaa.h"
00116 #include "opt_ipaa_io.h"
00117 #include "opt_ipaa_summary.h"
00118 #include "ipc_symtab_merge.h"
00119
00120
00121 extern "C" void add_to_tmp_file_list ( char *pathname );
00122
00123
00124 MEM_POOL *IPAA_Pool = NULL;
00125
00126
00127 INT Mext_Size = 0;
00128
00129
00130
00131
00132 BOOL Trace_IPAA = FALSE;
00133 BOOL Trace_Detail = FALSE;
00134 BOOL Trace_Stats = FALSE;
00135 BOOL Trace_Iterator = FALSE;
00136 BOOL Log_IPAA = FALSE;
00137
00138
00139
00140 IPAA_OBJECT_REF_SET *icall_eref;
00141 IPAA_OBJECT_REF_SET *icall_def;
00142 IPAA_OBJECT_REF_SET *icall_kill;
00143
00144
00145
00146
00147
00148
00149
00150
00151 static inline UINT32
00152 Get_Merged_Sym_ID ( SUMMARY_SYMBOL *sym )
00153 {
00154 return ST_IDX_index(sym->St_idx());
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 void
00168 IPAA_OBJECT_REF_SET::Print ( FILE *f ) const
00169 {
00170 fprintf ( f, "ORS:f%3d: d", _fcount );
00171 _dformals.Print ( f, _fcount );
00172 fprintf ( f, ": i" );
00173 _iformals.Print ( f, _fcount );
00174 fprintf ( f, "\n\t\t" );
00175 }
00176
00177
00178
00179 void
00180 IPAA_OBJECT_REF_SET::Trace ( void ) const
00181 {
00182 Print ( TFile );
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 class IPAA_FORMAL_MAP
00201 {
00202 public:
00203
00204
00205
00206 typedef INT32 MAP_ELMT;
00207 static const MAP_ELMT MAP_NONE = -1;
00208
00209 private:
00210
00211 mBOOL _junk;
00212 mINT16 _count;
00213 union {
00214 MAP_ELMT _single;
00215 MAP_ELMT *_mvec;
00216 };
00217
00218 void Expand ( INT32 min_size = 0 );
00219
00220 public:
00221
00222
00223 IPAA_FORMAL_MAP ( void );
00224 ~IPAA_FORMAL_MAP ( void ) {}
00225
00226
00227 void Print ( FILE * ) const;
00228 void Trace ( void ) const;
00229
00230
00231 BOOL Is_empty () const { return _junk && _count == 0; }
00232 INT32 Get_size () const { return _count + (_junk == TRUE); }
00233
00234
00235 BOOL Get_junk () const { return _junk; }
00236 void Set_junk () { _junk = TRUE; }
00237
00238
00239 BOOL Is_elmt ( INT32 elmt ) const;
00240 BOOL Add_elmt ( INT32 elmt );
00241
00242
00243 MAP_ELMT Get_elmt ( INT32 index ) const {
00244 return ( _count == 1 ) ? _single : _mvec[index];
00245 }
00246
00247
00248 BOOL Union_2 ( const IPAA_FORMAL_MAP *set );
00249 };
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 void
00262 IPAA_FORMAL_MAP::Expand ( INT32 min_size )
00263 {
00264 MAP_ELMT *data;
00265 INT32 i;
00266
00267
00268 if ( min_size == 0 ) {
00269 if ( _count == 0 ) {
00270 min_size = 2;
00271 } else {
00272 min_size = _count*2;
00273 }
00274 } else {
00275 if ( min_size <= _count ) {
00276 return;
00277 }
00278 if ( (min_size & (min_size-1)) != 0 ) {
00279 while ( (min_size & (min_size-1)) != 0 ) {
00280 min_size &= (min_size-1);
00281 }
00282 min_size += min_size;
00283 }
00284 }
00285
00286
00287 if ( _count <= 1 ) {
00288 data = (MAP_ELMT *) MEM_POOL_Alloc
00289 ( IPAA_Pool, sizeof(MAP_ELMT) * min_size );
00290 if ( data == NULL ) {
00291 ErrMsg ( EC_No_Mem, "Expand (new)" );
00292 }
00293 if ( _count == 1 ) {
00294 data[0] = _single;
00295 }
00296
00297 } else {
00298 data = (MAP_ELMT *) MEM_POOL_Realloc
00299 ( IPAA_Pool, _mvec,
00300 sizeof(MAP_ELMT) * _count,
00301 sizeof(MAP_ELMT) * min_size );
00302 if ( data == NULL ) {
00303 ErrMsg ( EC_No_Mem, "Expand (enlarge)" );
00304 }
00305 }
00306
00307
00308 for ( i = _count; i < min_size; i++ ) {
00309 data[i] = MAP_NONE;
00310 }
00311 _mvec = data;
00312 _count = min_size;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 IPAA_FORMAL_MAP::IPAA_FORMAL_MAP ()
00324 {
00325
00326 _junk = FALSE;
00327 _count = 0;
00328 _mvec = NULL;
00329 }
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 void
00341 IPAA_FORMAL_MAP::Print ( FILE *f ) const
00342 {
00343 INT16 i;
00344
00345 if ( this == NULL ) {
00346 fprintf ( f, "<NULL>\n" );
00347 return;
00348 }
00349 fprintf ( f, "%s[%d] ", _junk ? "arbitrary + " : "", _count );
00350 if ( _count == 0 ) {
00351 fprintf ( f, "EMPTY\n" );
00352 } else if ( _count == 1 ) {
00353 fprintf ( f, "%d\n", _single );
00354 } else {
00355 for ( i = 0; i < _count; i++ ) {
00356 if ( _mvec[i] != MAP_NONE ) {
00357 fprintf ( f, "%d ", _mvec[i] );
00358 }
00359 }
00360 fprintf ( f, "\n" );
00361 }
00362 }
00363
00364
00365
00366 void
00367 IPAA_FORMAL_MAP::Trace ( void ) const
00368 {
00369 Print ( TFile );
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 BOOL
00381 IPAA_FORMAL_MAP::Is_elmt ( INT32 elmt ) const
00382 {
00383 INT16 i;
00384
00385 if ( _count == 0 ) return FALSE;
00386 if ( _count == 1 ) return ( _single == elmt );
00387 for ( i = 0; i < _count; i++ ) {
00388 if ( _mvec[i] == elmt ) return TRUE;
00389 if ( _mvec[i] == MAP_NONE ) return FALSE;
00390 if ( _mvec[i] > elmt ) return FALSE;
00391 }
00392 return FALSE;
00393 }
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 BOOL
00405 IPAA_FORMAL_MAP::Add_elmt ( INT32 elmt )
00406 {
00407 INT16 i;
00408 INT32 old;
00409 BOOL added = FALSE;
00410
00411 if ( _count == 0 ) {
00412 _count = 1;
00413 _single = elmt;
00414 added = TRUE;
00415 } else if ( _count == 1 ) {
00416 if ( _single != elmt ) {
00417 old = _single;
00418 Expand ( 4 );
00419 if ( old < elmt ) {
00420 _mvec[0] = old;
00421 _mvec[1] = elmt;
00422 } else {
00423 _mvec[0] = elmt;
00424 _mvec[1] = old;
00425 }
00426 added = TRUE;
00427 }
00428 } else {
00429 for ( i = 0; i < _count; i++ ) {
00430 if ( _mvec[i] == elmt ) return FALSE;
00431 if ( _mvec[i] == MAP_NONE ) {
00432 _mvec[i] = elmt;
00433 added = TRUE;
00434 goto trace_and_exit;
00435 }
00436 if ( _mvec[i] > elmt ) {
00437 INT16 k = _count;
00438 if ( _mvec[_count-1] != MAP_NONE ) {
00439 Expand ();
00440 while ( _mvec[--k] == MAP_NONE ) {};
00441 while ( k >= i ) {
00442 _mvec[k+1] = _mvec[k];
00443 k--;
00444 }
00445 _mvec[i] = elmt;
00446 added = TRUE;
00447 goto trace_and_exit;
00448 }
00449 }
00450 }
00451
00452
00453 Expand ();
00454 _mvec[i] = elmt;
00455 added = TRUE;
00456 }
00457
00458 trace_and_exit:
00459 if ( Trace_Detail ) {
00460 fprintf ( TFile, "<ipaa> Add element %d to formals:", elmt );
00461 Trace ();
00462 }
00463
00464 return added;
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 BOOL
00477 IPAA_FORMAL_MAP::Union_2 ( const IPAA_FORMAL_MAP *map )
00478 {
00479 INT16 i, t, m, cnt;
00480 BOOL changed;
00481 MAP_ELMT valt, valm;
00482
00483
00484 if ( map->_count == 0 ) {
00485 return FALSE;
00486 } else if ( map->_count == 1 ) {
00487 return Add_elmt ( map->_single );
00488 } else if ( map->_mvec[1] == MAP_NONE ) {
00489
00490 return Add_elmt ( map->_mvec[0] );
00491 }
00492
00493
00494 if ( this->_count == 0 ) {
00495 Expand ( map->_count );
00496 bcopy ( _mvec, map->_mvec, map->_count * sizeof(MAP_ELMT) );
00497 return TRUE;
00498 } else if ( this->_count <= 1 || this->_mvec[1] == MAP_NONE ) {
00499 valt = ( this->_count <= 1 ) ? this->_single : this->_mvec[0];
00500 Expand ( map->_count );
00501 bcopy ( _mvec, map->_mvec, map->_count * sizeof(MAP_ELMT) );
00502 (void) Add_elmt ( valt );
00503 return TRUE;
00504 }
00505
00506
00507
00508 for ( cnt = _count; cnt > 0; cnt-- ) {
00509 if ( this->_mvec[cnt-1] != MAP_NONE ) break;
00510 }
00511 if ( cnt + map->_count > this->_count ) {
00512
00513 Expand ( cnt + map->_count );
00514 }
00515
00516
00517 changed = FALSE;
00518 t = cnt-1;
00519 valt = this->_mvec[t];
00520 for ( m = map->_count-1; m>=0; m-- ) {
00521 if ( (valm = map->_mvec[m]) != MAP_NONE ) break;
00522 }
00523 for ( i = this->_count-1; i>=0; i-- ) {
00524 if ( valt >= valm ) {
00525 this->_mvec[i] = valt;
00526 if ( valt == valm ) {
00527 m--;
00528 valm = (m>=0) ? map->_mvec[m] : -1;
00529 }
00530 t--;
00531 valt = (t>=0) ? this->_mvec[t] : -1;
00532 } else {
00533 this->_mvec[i] = valm;
00534 changed = TRUE;
00535 m--;
00536 valm = (m>=0) ? map->_mvec[m] : -1;
00537 }
00538 if ( m < 0 && t < 0 ) break;
00539 }
00540
00541
00542 if ( i > 0 ) {
00543 for ( t = 0; i < this->_count; t++, i++ ) {
00544 this->_mvec[t] = this->_mvec[i];
00545 }
00546 for ( ; t < this->_count; t++ ) {
00547 this->_mvec[t] = MAP_NONE;
00548 }
00549 }
00550
00551 return changed;
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 void
00566 IPAA_NODE_INFO::Print ( FILE *f, const char *pfx ) const
00567 {
00568 INT16 fid;
00569
00570 if ( pfx != NULL ) {
00571 sprintf ( Modref_Buf,
00572 "<ipaa> NODE_INFO: %s (iter%d : pu%d) -- "
00573 "changed iter %d%s%s%s%s%s%s\n",
00574 pfx, _fcount, _changed_iter, _pu_info,
00575 Has_back_edge() ? ", BE" : "",
00576 Depends_on_back_edge() ? ", DBE" : "",
00577 Has_indirect_edge() ? ", IE" : "",
00578 Passes_formals_by_value() ? ", FVAL" : "",
00579 Passes_globals_by_reference() ? ", GREF" : "",
00580 Has_unknown_call_effects() ? ", UNK" : "" );
00581 fprintf (f, "%s", Modref_Buf);
00582 if ( IPA_Trace_Mod_Ref ) {
00583 Ipa_tlog("MOD_REF", 0, "%s", Modref_Buf);
00584 }
00585 }
00586 fprintf ( f, "<ipaa>\tEREF #\t" );
00587 if ( IPA_Trace_Mod_Ref )
00588 Ipa_tlog("MOD_REF", 0, "%s", "<ipaa> EREF #");
00589 _eref->Print ( f );
00590 fprintf ( f, "<ipaa>\tDEF #\t" );
00591 if ( IPA_Trace_Mod_Ref )
00592 Ipa_tlog("MOD_REF", 0, "%s", "<ipaa> DEF #");
00593 _def->Print ( f );
00594 fprintf ( f, "<ipaa>\tKILL #\t" );
00595 if ( IPA_Trace_Mod_Ref )
00596 Ipa_tlog("MOD_REF", 0, "%s", "<ipaa> KILL #");
00597 _kill->Print ( f );
00598 if ( _fmap != NULL ) {
00599 for ( fid = 0; fid < _fcount; fid++ ) {
00600 fprintf ( f, "<ipaa>\tFMAP %d #\t", fid );
00601 if ( IPA_Trace_Mod_Ref )
00602 Ipa_tlog("MOD_REF", 0, "<ipaa> FMAP %d # ", fid);
00603 Get_fmap(fid)->Print ( f );
00604 }
00605 }
00606 }
00607
00608
00609
00610 void
00611 IPAA_NODE_INFO::Trace ( const char *pfx ) const
00612 {
00613 Print ( TFile, pfx );
00614 }
00615
00616
00617
00618 void
00619 IPAA_NODE_INFO::New_eref_set ( INT32 fsize )
00620 {
00621 _eref = CXX_NEW ( IPAA_OBJECT_REF_SET ( fsize ), Malloc_Mem_Pool );
00622 }
00623
00624
00625
00626 void
00627 IPAA_NODE_INFO::New_def_set ( INT32 fsize )
00628 {
00629 _def = CXX_NEW ( IPAA_OBJECT_REF_SET ( fsize ), Malloc_Mem_Pool );
00630 }
00631
00632
00633
00634 void
00635 IPAA_NODE_INFO::New_kill_set ( INT32 fsize )
00636 {
00637 _kill = CXX_NEW ( IPAA_OBJECT_REF_SET ( fsize ), Malloc_Mem_Pool );
00638 }
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650 BOOL
00651 IPAA_NODE_INFO::Is_actual_in_map ( INT16 f, UINT32 glob ) const
00652 {
00653
00654 if ( Get_fmap() == NULL
00655 || f >= Get_fcount()
00656 || Get_fmap(f) == NULL )
00657 {
00658 return FALSE;
00659 }
00660
00661
00662 return Get_fmap(f)->Is_elmt ( glob );
00663 }
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679 IPAA_FORMAL_MAP *
00680 Force_Map ( IPAA_NODE_INFO &info, INT16 f )
00681 {
00682 IPAA_FORMAL_MAP **mapvec;
00683 IPAA_FORMAL_MAP *map;
00684
00685
00686
00687
00688 if ( f >= info.Get_fcount() ) return NULL;
00689
00690
00691 if ( info.Get_fmap() == NULL ) {
00692 mapvec = (IPAA_FORMAL_MAP **) MEM_POOL_Alloc
00693 ( IPAA_Pool, sizeof(IPAA_FORMAL_MAP *) * info.Get_fcount() );
00694 if ( mapvec == NULL ) {
00695 ErrMsg ( EC_No_Mem, "Force_Map: map vector" );
00696 }
00697 bzero ( mapvec, sizeof(IPAA_FORMAL_MAP *) * info.Get_fcount() );
00698 info.Set_fmap ( mapvec );
00699 }
00700 if ( info.Get_fmap(f) == NULL ) {
00701 map = (IPAA_FORMAL_MAP *)
00702 CXX_NEW ( IPAA_FORMAL_MAP (), IPAA_Pool );
00703 if ( map == NULL ) {
00704 ErrMsg ( EC_No_Mem, "Force_Map: map" );
00705 }
00706 bzero ( map, sizeof(IPAA_FORMAL_MAP) );
00707 info.Set_fmap ( f, map );
00708 }
00709
00710
00711 return info.Get_fmap(f);
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729 static BOOL
00730 Add_Actual_To_Map ( IPAA_NODE_INFO &info, INT16 f, UINT32 glob )
00731 {
00732 IPAA_FORMAL_MAP *tmap;
00733
00734
00735 if ( ( tmap = Force_Map ( info, f ) ) != NULL ) {
00736
00737 return tmap->Add_elmt ( glob );
00738 }
00739
00740
00741 return FALSE;
00742 }
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 static BOOL
00757 Add_Map_To_Map (
00758 IPAA_NODE_INFO &info,
00759 INT16 f,
00760 IPAA_FORMAL_MAP &smap )
00761 {
00762 IPAA_FORMAL_MAP *tmap;
00763
00764
00765 if ( ( tmap = Force_Map ( info, f ) ) != NULL
00766 && &smap != NULL
00767 && tmap != &smap )
00768 {
00769
00770 return tmap->Union_2 ( &smap );
00771 }
00772
00773
00774 return FALSE;
00775 }
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786 IPAA_NODE_INFO *
00787 Force_IPAA_Info ( IPA_NODE &pu )
00788 {
00789 IPAA_NODE_INFO *pu_info = pu.Mod_Ref_Info();
00790
00791 if ( pu_info == NULL ) {
00792 INT16 fcnt = pu.Summary_Proc()->Get_formal_count();
00793 pu.Set_Mod_Ref_Info( CXX_NEW ( IPAA_NODE_INFO(fcnt), IPAA_Pool ) );
00794 pu_info = pu.Mod_Ref_Info();
00795 }
00796 return pu_info;
00797 }
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812 typedef enum {
00813 ACTUAL_KIND_NONE = 0,
00814 ACTUAL_KIND_GLOBAL,
00815 ACTUAL_KIND_FORMAL,
00816 ACTUAL_KIND_LOCAL,
00817 ACTUAL_KIND_PSTATIC,
00818 ACTUAL_KIND_FSTATIC,
00819 } ACTUAL_KIND;
00820
00821 class IPAA_STEP
00822 {
00823 private:
00824
00825 IPA_CALL_GRAPH *_cg;
00826 IPA_NODE *_nd;
00827 IPAA_NODE_INFO *_info;
00828 mINT32 _fix;
00829 mINT16 _fsize;
00830 SUMMARY_SYMBOL* symbols;
00831 SUMMARY_GLOBAL* globals;
00832 SUMMARY_ACTUAL *actuals;
00833 SUMMARY_FORMAL* formals;
00834
00835 public:
00836
00837
00838 IPAA_STEP ( IPA_CALL_GRAPH &graph, IPA_NODE &cg_node );
00839 ~IPAA_STEP ( void ) {}
00840
00841
00842 SUMMARY_ACTUAL* Get_actuals (void) const { return actuals; }
00843
00844
00845 void Init_Summary_Pointers ( void );
00846
00847
00848 void Print ( FILE * ) const;
00849 void Trace ( void ) const;
00850
00851
00852 UINT32 Get_merged_global_id ( SUMMARY_GLOBAL *gs );
00853
00854
00855 BOOL Initialize_Ref_Info ();
00856
00857
00858 ACTUAL_KIND Get_actual_info (
00859 const SUMMARY_ACTUAL &actual,
00860 SUMMARY_SYMBOL * &sym,
00861 ST_IDX &merged_id,
00862 INT32 &formal_num ) const;
00863
00864
00865 void Finalize_Ref_Info ();
00866 };
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876 void
00877 IPAA_STEP::Init_Summary_Pointers ( void )
00878 {
00879 Ipl_Summary_Symbol = symbols;
00880 }
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891 IPAA_STEP::IPAA_STEP ( IPA_CALL_GRAPH &callgraph, IPA_NODE &cg_node )
00892 {
00893 bzero ( this, sizeof(IPAA_STEP) );
00894 this->_cg = &callgraph;
00895 this->_nd = &cg_node;
00896 _fsize = cg_node.Summary_Proc()->Get_formal_count();
00897
00898
00899 this->_info = Force_IPAA_Info ( *_nd );
00900
00901
00902 if ( this->_info->Get_eref_set() == NULL ) {
00903 this->_info->New_eref_set ( _fsize );
00904 }
00905 if ( this->_info->Get_def_set() == NULL ) {
00906 this->_info->New_def_set ( _fsize );
00907 }
00908 if ( this->_info->Get_kill_set() == NULL ) {
00909 this->_info->New_kill_set ( _fsize );
00910 }
00911
00912
00913 actuals = IPA_get_actual_array(this->_nd);
00914 symbols = IPA_get_symbol_array(this->_nd);
00915 globals = IPA_get_global_array(this->_nd);
00916 formals = IPA_get_formal_array(this->_nd);
00917
00918
00919 Init_Summary_Pointers ();
00920 }
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930 void
00931 IPAA_STEP::Print ( FILE *f ) const
00932 {
00933 _info->Print ( f, _nd->Name() );
00934 }
00935
00936
00937
00938 void
00939 IPAA_STEP::Trace ( void ) const
00940 {
00941 Print ( TFile );
00942 }
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 UINT32
00953 IPAA_STEP::Get_merged_global_id ( SUMMARY_GLOBAL *gs )
00954 {
00955 INT32 sym_id = gs->Get_symbol_index();
00956 return ( sym_id < 0 ) ? 0 : Get_Merged_Sym_ID ( &(this->symbols)[sym_id] );
00957 }
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969 BOOL
00970 IPAA_STEP::Initialize_Ref_Info ()
00971 {
00972 SUMMARY_PROCEDURE *p = _nd->Summary_Proc();
00973 INT gix = p->Get_global_index();
00974 INT gcount = p->Get_global_count();
00975 INT fix = p->Get_formal_index();
00976 INT j;
00977 BOOL global_change = FALSE;
00978
00979
00980 if ( _info->Is_initialized() ) return global_change;
00981
00982
00983 for ( j=0; j<gcount; j++, gix++ ) {
00984 SUMMARY_GLOBAL* global = &(this->globals)[gix];
00985 UINT32 gid = 0;
00986
00987 if ( Trace_Detail ) {
00988 fprintf ( TFile, "<ipaa>\tiri: " );
00989 global->Trace();
00990 fprintf ( TFile, "<ipaa>\t\t" );
00991 Ipl_Summary_Symbol[global->Get_symbol_index()].Trace ();
00992 }
00993
00994 if ( global->Is_modref() ) {
00995
00996 gid = this->Get_merged_global_id ( global );
00997 if ( gid <= 0 ) continue;
00998 }
00999
01000 if ( global->Is_ref() ) {
01001 (_info->Get_eref_set())->Add_elmt ( gid );
01002 }
01003 if ( global->Is_dmod() ) {
01004 (_info->Get_def_set())->Add_elmt ( gid );
01005 }
01006 if ( global->Is_dkill() ) {
01007 (_info->Get_kill_set())->Add_elmt ( gid );
01008 }
01009 }
01010
01011
01012 const SUMMARY_SYMBOL* func_sym = _nd->Summary_Symbol ();
01013 if (func_sym->Is_addr_saved() || func_sym->Is_addr_passed ()) {
01014 icall_eref->Union_2 (_info->Get_eref_set ());
01015 icall_def->Union_2 (_info->Get_def_set ());
01016 icall_kill->Union_2 (_info->Get_kill_set ());
01017 global_change = TRUE;
01018 }
01019
01020
01021 for ( j = 0; j<_fsize; j++ ) {
01022 INT16 position = formals[fix+j].Get_position();
01023 SUMMARY_SYMBOL *sym;
01024 sym = &Ipl_Summary_Symbol[formals[fix+j].Get_symbol_index()];
01025
01026 if ( Trace_Detail ) {
01027 fprintf ( TFile, "<ipaa>\tiri: " );
01028 formals[fix+j].Trace();
01029 }
01030 if ( IPA_Trace_Mod_Ref ) {
01031 fprintf ( TFile, "<ipaa>\tiri: " );
01032 formals[fix+j].Trace();
01033 }
01034
01035 if ( sym->Is_imod() ) {
01036 (_info->Get_def_set())->Add_indirect_formal_elmt ( position );
01037 }
01038 if ( sym->Is_dmod() ) {
01039 (_info->Get_def_set())->Add_direct_formal_elmt ( position );
01040 }
01041 if ( sym->Is_iref() ) {
01042 (_info->Get_eref_set())->Add_indirect_formal_elmt ( position );
01043 }
01044 if ( sym->Is_dref() ) {
01045 (_info->Get_eref_set())->Add_direct_formal_elmt ( position );
01046 }
01047 if ( sym->Is_ikill() ) {
01048 (_info->Get_kill_set())->Add_indirect_formal_elmt ( position );
01049 }
01050 if ( sym->Is_dkill() ) {
01051 (_info->Get_kill_set())->Add_direct_formal_elmt ( position );
01052 }
01053 }
01054
01055
01056 _info->Set_initialized();
01057
01058
01059 if ( Trace_IPAA ) {
01060 fprintf ( TFile, "<ipaa> Initialize_Ref_Info:\n" );
01061 this->Trace();
01062 fflush ( TFile );
01063 }
01064 if ( IPA_Trace_Mod_Ref ) {
01065 Ipa_tlog("MOD_REF", 0, "%s", "<ipaa> Initialize_Ref_Info:");
01066 this->Trace();
01067 }
01068
01069 return global_change;
01070 }
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083 ACTUAL_KIND
01084 IPAA_STEP::Get_actual_info (const SUMMARY_ACTUAL &actual,
01085 SUMMARY_SYMBOL * &sym,
01086 UINT32 &merged_idx,
01087 INT32 &formal_num ) const
01088 {
01089 INT32 formid;
01090
01091 if (actual.Get_symbol_index () == -1)
01092 return ACTUAL_KIND_NONE;
01093
01094 sym = symbols + actual.Get_symbol_index ();
01095
01096 if (sym->Is_global ()) {
01097 merged_idx = Get_Merged_Sym_ID ( sym );
01098 if ( Trace_Detail ) {
01099 fprintf ( TFile, "<ipaa>\tgai: Global %d\n", merged_idx );
01100 }
01101 return ACTUAL_KIND_GLOBAL;
01102 }
01103 else if (sym->Is_formal()) {
01104 formid = sym->Get_findex ();
01105 SUMMARY_FORMAL *formal = formals + formid;
01106 formal_num = formal->Get_position ();
01107 const SUMMARY_PROCEDURE *proc = _nd->Summary_Proc();
01108 if (proc->Is_alt_entry () || proc->Has_alt_entry ()) {
01109
01110
01111 if (proc->Get_formal_index () + formal_num != formid)
01112 return ACTUAL_KIND_LOCAL;
01113 }
01114 if ( Trace_Detail ) {
01115 fprintf ( TFile, "<ipaa>\tgai: Formal %d\n", formal_num );
01116 }
01117 return ACTUAL_KIND_FORMAL;
01118 } else if (sym->Is_static ())
01119
01120 return ACTUAL_KIND_FSTATIC;
01121
01122
01123 else if (sym->Is_common()) {
01124
01125 merged_idx = ST_IDX_index(ST_base_idx(St_Table[sym->St_idx()]));
01126 Is_True (merged_idx,
01127 ("Invalid global symbol idx in IPAA_STEP::Get_actual_info"));
01128 if ( Trace_Detail ) {
01129 fprintf ( TFile, "<ipaa>\tgai: Global %d\n", merged_idx );
01130 }
01131 return ACTUAL_KIND_GLOBAL;
01132 } else if (sym->Is_local())
01133 return ACTUAL_KIND_LOCAL;
01134
01135 return ACTUAL_KIND_NONE;
01136 }
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152 void
01153 IPAA_STEP::Finalize_Ref_Info ()
01154 {
01155 if ( Trace_IPAA ) {
01156 fprintf ( TFile, "<ipaa> Finalize_Ref_Info:\n" );
01157 this->Trace();
01158 }
01159 if ( IPA_Trace_Mod_Ref ) {
01160 Ipa_tlog("MOD_REF", 0, "%s", "<ipaa> Finalize_Ref_Info:");
01161 this->Trace();
01162 }
01163 }
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179 class IPAA_DF_SOLVER : public DFBASE
01180 {
01181 public:
01182
01183
01184
01185
01186 typedef IPAA_NODE_INFO IN_T;
01187 typedef void OUT_T;
01188
01189 typedef enum {
01190 PHASE_INIT,
01191 PHASE_DIRECT,
01192 PHASE_FORMALS,
01193 } PHASE;
01194
01195 private:
01196
01197 IN_T **_in;
01198 OUT_T **_out;
01199
01200
01201 mINT16 _iteration;
01202 PHASE _phase;
01203 IPAA_STEP *_step;
01204
01205
01206 mINT32 _next_seq_id;
01207 mINT16 _direct_iters;
01208 mINT16 _formal_iters;
01209 mINT32 _direct_nodes;
01210 mINT32 _direct_edges;
01211 mINT32 _direct_recur;
01212 mINT32 _direct_changed;
01213 mINT32 _formal_nodes;
01214 mINT32 _formal_edges;
01215
01216 public:
01217
01218
01219 IPAA_DF_SOLVER (IPA_CALL_GRAPH &cg, DF_DIRECTION df, MEM_POOL *m, PHASE
01220 phase );
01221
01222
01223 ~IPAA_DF_SOLVER (void);
01224
01225
01226
01227
01228 IN_T **Get_in (void) const { return _in; }
01229 OUT_T **Get_out (void) const { return _out; }
01230 void Set_in ( IN_T **in ) { _in = in; }
01231 void Set_out ( OUT_T **out ) { _out = out; }
01232 IN_T *Get_in_elmt(NODE_INDEX i) const { return _in[i]; }
01233 OUT_T *Get_out_elmt(NODE_INDEX i) const { return _out[i]; }
01234 void Set_in_elmt ( NODE_INDEX i, IN_T *in ) { _in[i] = in; };
01235 void Set_out_elmt ( NODE_INDEX i, OUT_T *out ) { _out[i] = out; };
01236
01237 INT16 Get_iteration (void) const { return _iteration; }
01238 void Set_iteration ( INT16 i ) { _iteration = i; }
01239 void Inc_iteration (void) { ++_iteration; }
01240 PHASE Get_phase (void) const { return _phase; }
01241 void Set_phase ( PHASE phase ) { _phase = phase; }
01242
01243
01244 IPAA_STEP *Get_step (void) const { return _step; }
01245 void Set_step ( IPAA_STEP *step ) { _step = step; }
01246 SUMMARY_ACTUAL *Get_actuals (void) const { return _step->Get_actuals(); }
01247
01248
01249 INT32 Get_next_seq_id (void) const { return _next_seq_id; }
01250 INT32 Inc_next_seq_id (void) { return ++_next_seq_id; }
01251 INT16 Get_direct_iters (void) const { return _direct_iters; }
01252 INT16 Inc_direct_iters (void) { return ++_direct_iters; }
01253 void Set_direct_iters ( INT16 cnt ){ _direct_iters = cnt; }
01254 INT16 Get_formal_iters (void) const { return _formal_iters; }
01255 INT16 Inc_formal_iters (void) { return ++_formal_iters; }
01256 void Set_formal_iters ( INT16 cnt ) { _formal_iters = cnt; }
01257 INT32 Get_direct_nodes (void) const { return _direct_nodes; }
01258 INT32 Inc_direct_nodes (void) { return ++_direct_nodes; }
01259 INT32 Get_formal_nodes (void) const { return _formal_nodes; }
01260 INT32 Inc_formal_nodes (void) { return ++_formal_nodes; }
01261 INT32 Get_direct_edges (void) const { return _direct_edges; }
01262 INT32 Inc_direct_edges (void) { return ++_direct_edges; }
01263 INT32 Get_formal_edges (void) const { return _formal_edges; }
01264 INT32 Inc_formal_edges (void) { return ++_formal_edges; }
01265 INT32 Get_direct_changed (void) const{ return _direct_changed; }
01266 INT32 Inc_direct_changed (void) { return ++_direct_changed; }
01267
01268
01269
01270
01271 void Report_graph_statistics ( PHASE phase ) const;
01272
01273
01274
01275
01276
01277 void Initialize_node ( void * ) const {};
01278
01279
01280
01281
01282
01283 void Initialize_annotations (void) {
01284 Initialize_Annotation ( this, this->_in, this->_out );
01285 };
01286
01287
01288 void Map_worst_case_actual_attributes (const IPA_NODE &caller,
01289 IPAA_NODE_INFO &caller_info,
01290 const SUMMARY_ACTUAL &actual );
01291
01292
01293 BOOL Map_formal_attributes (const IPA_NODE &caller,
01294 IPAA_NODE_INFO &caller_info,
01295 IPAA_NODE_INFO &callee_info,
01296 INT16 formal_num,
01297 const SUMMARY_ACTUAL &actual);
01298
01299
01300 void Accumulate_ref_info (const IPA_NODE &caller, IPA_NODE &callee,
01301 IPA_EDGE &edge );
01302
01303
01304 void Accumulate_indirect_actual_refs (const IPA_NODE &caller,
01305 SUMMARY_CALLSITE &call );
01306
01307 BOOL Check_and_accumulate_ref_info (const IPA_NODE &caller,
01308 const IPA_NODE &callee,
01309 IPA_EDGE &edge );
01310
01311
01312 BOOL Map_actual (const IPA_NODE &caller, IPAA_NODE_INFO &caller_info,
01313 IPA_EDGE &edge,
01314 const IPA_NODE &callee, IPAA_NODE_INFO &callee_info,
01315 INT16 formal_num, const SUMMARY_ACTUAL &actual);
01316
01317
01318 void Map_actuals (const IPA_NODE &caller, const IPA_NODE &callee,
01319 IPA_EDGE &edge );
01320
01321
01322
01323
01324
01325 void Meet_direct_iter_1 ( IPA_NODE &caller );
01326 void Meet_direct_iter_n ( IPA_NODE &caller );
01327 void Meet_formals_iter_1 ( IPA_NODE &caller );
01328 void Meet_formals_iter_n ( IPA_NODE &caller );
01329 IN_T *Meet ( IN_T *in, void *vertex_user );
01330
01331
01332
01333
01334
01335 OUT_T *Trans ( IN_T *, OUT_T *, void * ) const { return NULL; }
01336
01337
01338
01339
01340
01341
01342
01343 void Solver_core (void) {
01344 Inc_iteration ();
01345 Iterative_Solver_Core ( this );
01346 }
01347
01348
01349
01350
01351 void Solver (void) {
01352 Iterative_Dataflow_Solver ( this, Depth_First_Ordering );
01353 }
01354
01355
01356 void Init_IO () {}
01357 void Post_process_IO ( const void * ) {}
01358
01359
01360
01361 void Extract_solution (void) {
01362 if ( Trace_Stats ) {
01363 Extract_Solution ( this );
01364 }
01365 }
01366 };
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377 IPAA_DF_SOLVER::IPAA_DF_SOLVER (
01378 IPA_CALL_GRAPH &cg,
01379 DF_DIRECTION direction,
01380 MEM_POOL *mpool,
01381 PHASE phase )
01382 : DFBASE ( cg, direction, mpool, NULL )
01383 {
01384
01385 _in = NULL;
01386 _out = NULL;
01387 _iteration = 0;
01388 _phase = phase;
01389 _next_seq_id = 0;
01390 _direct_iters = 0;
01391 _formal_iters = 0;
01392 _direct_nodes = 0;
01393 _formal_nodes = 0;
01394 _direct_edges = 0;
01395 _formal_edges = 0;
01396 _direct_changed = 0;
01397 }
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410 IPAA_DF_SOLVER::~IPAA_DF_SOLVER ()
01411 {
01412 if ( _in != NULL ) {
01413 MEM_POOL_FREE ( Get_mempool(), _in );
01414 _in = NULL;
01415 }
01416 if ( _out != NULL ) {
01417 MEM_POOL_FREE ( Get_mempool(), _out );
01418 _out = NULL;
01419 }
01420 }
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430 void
01431 IPAA_DF_SOLVER::Report_graph_statistics ( PHASE phase ) const
01432 {
01433 if ( ! Trace_Stats ) return;
01434
01435 if ( phase == PHASE_DIRECT ) {
01436 fprintf ( TFile,
01437 "<ipaa> DIRECT phase: %2d iterations, "
01438 "%3d nodes, %3d edges (%3d changed)\n",
01439 Get_direct_iters(), Get_direct_nodes(),
01440 Get_direct_edges(), Get_direct_changed()
01441 );
01442 } else {
01443 fprintf ( TFile,
01444 "<ipaa> FORMAL phase: %2d iterations, "
01445 "%3d nodes, %3d edges\n",
01446 Get_formal_iters(), Get_formal_nodes(),
01447 Get_formal_edges()
01448 );
01449 }
01450 }
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464 void
01465 IPAA_DF_SOLVER::Map_worst_case_actual_attributes (
01466 const IPA_NODE &caller,
01467 IPAA_NODE_INFO &caller_info,
01468 const SUMMARY_ACTUAL &actual )
01469 {
01470 IPA_PASS_TYPE pass = actual.Get_pass_type();
01471 SUMMARY_SYMBOL * sym;
01472 UINT32 merged_idx = 0;
01473 INT32 caller_formal = 0;
01474
01475 switch ( pass ) {
01476
01477
01478 case PASS_LDID:
01479
01480
01481
01482 switch (Get_step()->Get_actual_info (actual, sym, merged_idx,
01483 caller_formal)) {
01484
01485 case ACTUAL_KIND_GLOBAL:
01486
01487 caller_info.Add_eref_elmt ( merged_idx );
01488 break;
01489
01490 case ACTUAL_KIND_FORMAL:
01491
01492 caller_info.Add_formal_iref_elmt ( caller_formal );
01493 caller_info.Add_formal_dref_elmt ( caller_formal );
01494 caller_info.Add_formal_imod_elmt ( caller_formal );
01495 break;
01496
01497 }
01498 break;
01499
01500 case PASS_LDA:
01501
01502 switch (Get_step()->Get_actual_info (actual, sym, merged_idx,
01503 caller_formal)) {
01504 case ACTUAL_KIND_GLOBAL: {
01505 ST_IDX merged_st_idx = make_ST_IDX( merged_idx, GLOBAL_SYMTAB );
01506 caller_info.Add_eref_elmt ( merged_idx );
01507 caller_info.Add_def_elmt ( merged_idx );
01508 if (IPA_Enable_Addressing &&
01509 ! (ST_addr_saved (&St_Table[merged_st_idx]) ||
01510 ST_addr_passed (&St_Table[merged_st_idx])) ) {
01511 Set_ST_addr_saved (&St_Table[merged_st_idx]);
01512
01513 }
01514 }
01515 break;
01516
01517 case ACTUAL_KIND_FORMAL:
01518 caller_info.Add_formal_dref_elmt ( caller_formal );
01519 caller_info.Add_formal_dmod_elmt ( caller_formal );
01520 caller_info.Add_formal_iref_elmt ( caller_formal );
01521 caller_info.Add_formal_imod_elmt ( caller_formal );
01522 if (IPA_Enable_Addressing && ! sym->Is_addr_saved() ) {
01523 sym -> Set_addr_saved ();
01524 caller_info . Set_local_addr_taken_mods ();
01525
01526
01527
01528 SUMMARY_PROCEDURE *summary_proc = caller.Summary_Proc();
01529 if ( summary_proc != NULL ) {
01530 summary_proc->Set_has_addr_taken_reset();
01531 }
01532 }
01533 break;
01534
01535 case ACTUAL_KIND_LOCAL:
01536 if (IPA_Enable_Addressing && ! sym->Is_addr_saved() ) {
01537 sym -> Set_addr_saved ();
01538 caller_info . Set_local_addr_taken_mods ();
01539
01540
01541
01542 SUMMARY_PROCEDURE *summary_proc = caller.Summary_Proc();
01543 if ( summary_proc != NULL ) {
01544 summary_proc->Set_has_addr_taken_reset();
01545 }
01546 }
01547 break;
01548 }
01549
01550 break;
01551 }
01552 }
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574 BOOL
01575 IPAA_DF_SOLVER::Map_formal_attributes (const IPA_NODE &caller,
01576 IPAA_NODE_INFO &caller_info,
01577 IPAA_NODE_INFO &callee_info,
01578 INT16 formal_num,
01579 const SUMMARY_ACTUAL &actual )
01580 {
01581 SUMMARY_SYMBOL * sym;
01582 UINT32 merged_idx = 0;
01583 INT32 caller_formal = 0;
01584 BOOL ref, mod;
01585 BOOL changed = FALSE;
01586
01587 if ( formal_num >= callee_info.Get_fcount() && Get_iteration() == 1 ) {
01588
01589
01590 Map_worst_case_actual_attributes ( caller, caller_info, actual );
01591
01592
01593
01594
01595 return FALSE;
01596 }
01597
01598 switch ( actual.Get_pass_type() ) {
01599
01600
01601 case PASS_LDID:
01602
01603
01604 switch ( Get_step()->Get_actual_info (actual, sym, merged_idx,
01605 caller_formal)) {
01606
01607 case ACTUAL_KIND_GLOBAL:
01608
01609 if (! caller_info.Is_eref_elmt ( merged_idx ) &&
01610 (callee_info.Is_formal_iref_elmt ( formal_num ) ||
01611 callee_info.Is_formal_dref_elmt ( formal_num ) ||
01612 callee_info.Is_formal_imod_elmt ( formal_num ) ) ) {
01613 caller_info.Add_eref_elmt ( merged_idx );
01614 changed = TRUE;
01615 }
01616 break;
01617
01618 case ACTUAL_KIND_FORMAL:
01619
01620
01621 caller_info.Set_passes_formals_by_value();
01622
01623
01624 if (!caller_info.Is_formal_iref_elmt ( caller_formal ) &&
01625 callee_info.Is_formal_iref_elmt ( formal_num ) ) {
01626 caller_info.Add_formal_iref_elmt ( caller_formal );
01627 changed = TRUE;
01628 }
01629
01630 if (!caller_info.Is_formal_dref_elmt ( caller_formal ) &&
01631 callee_info.Is_formal_dref_elmt ( formal_num ) ) {
01632 caller_info.Add_formal_dref_elmt ( caller_formal );
01633 changed = TRUE;
01634 }
01635
01636 if (!caller_info.Is_formal_imod_elmt ( caller_formal ) &&
01637 callee_info.Is_formal_imod_elmt ( formal_num ) ) {
01638 caller_info.Add_formal_imod_elmt ( caller_formal );
01639 changed = TRUE;
01640 }
01641
01642 break;
01643
01644 }
01645 break;
01646
01647 case PASS_LDA:
01648
01649
01650 ACTUAL_KIND akind = Get_step()->Get_actual_info (actual, sym,
01651 merged_idx,
01652 caller_formal );
01653
01654 if ( akind == ACTUAL_KIND_NONE )
01655 break;
01656
01657
01658 ref = callee_info.Is_formal_iref_elmt ( formal_num )
01659 | callee_info.Is_formal_dref_elmt ( formal_num );
01660 #ifdef KEY // bug 8316
01661
01662 mod = callee_info.Is_formal_imod_elmt ( formal_num )
01663 | callee_info.Is_formal_dmod_elmt ( formal_num );
01664 #else
01665 mod = callee_info.Is_formal_imod_elmt ( formal_num );
01666 #endif
01667
01668
01669 switch (akind) {
01670 case ACTUAL_KIND_GLOBAL:
01671
01672
01673 caller_info.Set_passes_globals_by_reference();
01674
01675
01676 #if _RECORD_GLOBAL_REF_VIA_FORMAL_
01677 if ( ref && ! callee_info.Is_eref_elmt ( merged_idx ) ) {
01678 callee_info.Add_eref_elmt ( merged_idx );
01679 changed = TRUE;
01680 }
01681 #endif
01682
01683 if ( mod && ! callee_info.Is_def_elmt ( merged_idx ) ) {
01684 callee_info.Add_def_elmt ( merged_idx );
01685 changed = TRUE;
01686 }
01687
01688 ref |= callee_info.Is_eref_elmt (merged_idx);
01689 mod |= callee_info.Is_def_elmt (merged_idx);
01690
01691 if ( ref && ! caller_info.Is_eref_elmt ( merged_idx ) ) {
01692 caller_info.Add_eref_elmt ( merged_idx );
01693 changed = TRUE;
01694 }
01695 if ( mod && ! caller_info.Is_def_elmt ( merged_idx ) ) {
01696 caller_info.Add_def_elmt ( merged_idx );
01697 changed = TRUE;
01698 }
01699
01700 break;
01701
01702 case ACTUAL_KIND_FORMAL:
01703 if ( ref && ! caller_info.Is_formal_dref_elmt ( caller_formal ) ) {
01704 caller_info.Add_formal_dref_elmt ( caller_formal );
01705 changed = TRUE;
01706 }
01707 if ( mod && ! caller_info.Is_formal_dmod_elmt ( caller_formal ) ) {
01708 caller_info.Add_formal_dmod_elmt ( caller_formal );
01709 changed = TRUE;
01710 }
01711 break;
01712
01713 case ACTUAL_KIND_LOCAL:
01714 if (ref && !sym->Is_dref()) {
01715 sym->Set_dref ();
01716 changed = TRUE;
01717 }
01718 if (mod && !sym->Is_dmod()) {
01719 sym->Set_dmod ();
01720 changed = TRUE;
01721 }
01722 break;
01723
01724 case ACTUAL_KIND_PSTATIC:
01725 case ACTUAL_KIND_FSTATIC:
01726
01727
01728 mod = ref = TRUE;
01729 break;
01730 }
01731
01732 break;
01733 }
01734
01735
01736
01737 return changed;
01738 }
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790 void
01791 IPAA_DF_SOLVER::Accumulate_ref_info (const IPA_NODE &caller,
01792 IPA_NODE &callee, IPA_EDGE &edge )
01793 {
01794 IPAA_NODE_INFO *callee_info = callee.Mod_Ref_Info();
01795 IPAA_NODE_INFO *caller_info = caller.Mod_Ref_Info();
01796 SUMMARY_CALLSITE *call;
01797 INT32 acount;
01798
01799
01800 if ( Trace_IPAA ) {
01801 fprintf ( TFile, "<ipaa> ari: edge " );
01802 edge.Trace ( Get_callgraph(), TRUE );
01803 fflush ( TFile );
01804 }
01805
01806
01807
01808
01809
01810
01811
01812 if ( callee_info == NULL || ! callee_info->Is_initialized() ) {
01813 IPAA_STEP istep ( *Get_callgraph(), callee );
01814
01815
01816 if (istep.Initialize_Ref_Info ())
01817 Set_changed ();
01818 }
01819
01820
01821 if ( &caller != &callee ) {
01822 (caller_info->Get_eref_set())->Union_2 ( callee_info->Get_eref_set() );
01823 (caller_info->Get_def_set() )->Union_2 ( callee_info->Get_def_set() );
01824
01825 const SUMMARY_SYMBOL* func_sym = caller.Summary_Symbol ();
01826
01827 if (func_sym->Is_addr_saved() || func_sym->Is_addr_passed ()) {
01828 if (Get_changed ())
01829 icall_eref->Union_2 (caller_info->Get_eref_set ());
01830 else if (icall_eref->Union_2_diff (caller_info->Get_eref_set ()))
01831 Set_changed ();
01832
01833 if (Get_changed ())
01834 icall_def->Union_2 (caller_info->Get_def_set ());
01835 else if (icall_def->Union_2_diff (caller_info->Get_def_set ()))
01836 Set_changed ();
01837 }
01838 } else if ( Trace_IPAA | Trace_Detail ) {
01839 fprintf ( TFile, "<ipaa> ari: self-call edge\n" );
01840 fflush ( TFile );
01841 }
01842
01843
01844 call = edge.Summary_Callsite();
01845 acount = call->Get_param_count();
01846 if ( acount > 0 ) {
01847
01848 INT32 aix;
01849 INT32 j;
01850
01851
01852 for ( j=0, aix = call->Get_actual_index(); j < acount; ++j, ++aix) {
01853 const SUMMARY_ACTUAL &actual = Get_actuals()[aix];
01854
01855
01856 if ( Trace_Detail ) {
01857 fprintf ( TFile, "<ipaa> ari: " );
01858 actual.Trace ( aix );
01859 }
01860 if ( IPA_Trace_Mod_Ref ) {
01861 Ipa_tlog("MOD_REF", 0, "%s <ipaa> ari: ", caller.Name());
01862 actual.Trace ( aix );
01863 }
01864
01865 (void) Map_formal_attributes ( caller, *caller_info,
01866 *callee_info, j, actual);
01867 }
01868 }
01869 }
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880 void
01881 IPAA_DF_SOLVER::Accumulate_indirect_actual_refs (const IPA_NODE &caller,
01882 SUMMARY_CALLSITE &call)
01883 {
01884 IPAA_NODE_INFO *caller_info = caller.Mod_Ref_Info();
01885 INT32 acount;
01886
01887
01888 if ( Trace_IPAA ) {
01889 fprintf ( TFile, "<ipaa> aiar: edge " );
01890 call.Trace ();
01891 fflush ( TFile );
01892 }
01893
01894
01895 acount = call.Get_param_count();
01896 if ( acount > 0 ) {
01897
01898 INT32 aix;
01899 INT32 j;
01900
01901
01902 for ( j=0, aix = call.Get_actual_index(); j < acount; ++j, ++aix) {
01903 SUMMARY_ACTUAL* actual = &(Get_actuals())[aix];
01904
01905
01906 if ( Trace_Detail ) {
01907 fprintf ( TFile, "<ipaa> aiar: " );
01908 actual->Trace ( aix );
01909 }
01910
01911 Map_worst_case_actual_attributes ( caller, *caller_info, *actual );
01912 }
01913 }
01914 }
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926 BOOL
01927 IPAA_DF_SOLVER::Check_and_accumulate_ref_info (const IPA_NODE &caller,
01928 const IPA_NODE &callee,
01929 IPA_EDGE &edge)
01930 {
01931 IPAA_NODE_INFO *callee_info = callee.Mod_Ref_Info();
01932 IPAA_NODE_INFO *caller_info = caller.Mod_Ref_Info();
01933 SUMMARY_CALLSITE *call;
01934 INT32 acount;
01935 BOOL changed = FALSE;
01936
01937
01938 if ( Trace_IPAA ) {
01939 fprintf ( TFile, "<ipaa> cari: edge " );
01940 edge.Trace ( Get_callgraph(), TRUE );
01941 fflush ( TFile );
01942 }
01943
01944
01945
01946
01947 changed |= (caller_info->Get_eref_set())->Union_2_diff
01948 ( callee_info->Get_eref_set() );
01949 changed |= (caller_info->Get_def_set() )->Union_2_diff
01950 ( callee_info->Get_def_set() );
01951
01952 if (changed) {
01953 const SUMMARY_SYMBOL* func_sym = caller.Summary_Symbol ();
01954 if (func_sym->Is_addr_saved () || func_sym->Is_addr_passed ()) {
01955 if (Get_changed ())
01956 icall_eref->Union_2 (caller_info->Get_eref_set ());
01957 else if (icall_eref->Union_2_diff (caller_info->Get_eref_set ()))
01958 Set_changed ();
01959
01960 if (Get_changed ())
01961 icall_def->Union_2 (caller_info->Get_def_set ());
01962 else if (icall_def->Union_2_diff (caller_info->Get_def_set ()))
01963 Set_changed ();
01964 }
01965 }
01966
01967
01968 call = edge.Summary_Callsite();
01969 acount = call->Get_param_count();
01970 for (INT j = 0, aix = call->Get_actual_index (); j < acount; ++j, ++aix) {
01971
01972
01973 const SUMMARY_ACTUAL &actual = Get_actuals()[aix];
01974
01975
01976 if ( Trace_Detail ) {
01977 fprintf ( TFile, "<ipaa> ari: " );
01978 actual.Trace ( aix );
01979 }
01980
01981 changed |= Map_formal_attributes (caller, *caller_info,
01982 *callee_info, j, actual);
01983 }
01984
01985 if ( Trace_Detail ) {
01986 fprintf ( TFile, "<ipaa> cari: edge changed " );
01987 edge.Trace ( Get_callgraph(), TRUE );
01988 }
01989 return changed;
01990 }
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025 void
02026 IPAA_DF_SOLVER::Meet_direct_iter_1 ( IPA_NODE &caller )
02027 {
02028 INT16 self_calls = 0;
02029
02030
02031
02032 IPA_CALL_GRAPH *cg = Get_callgraph();
02033 IPAA_STEP istep ( *cg, caller );
02034 Set_step ( &istep );
02035
02036
02037
02038 if (istep.Initialize_Ref_Info ())
02039 Set_changed ();
02040
02041
02042
02043
02044 IPAA_NODE_INFO *info = caller.Mod_Ref_Info();
02045 info->Set_visited();
02046 if ( info->Get_seq_id() == 0 ) {
02047 info->Set_seq_id ( Inc_next_seq_id() );
02048 }
02049 (void) Inc_direct_nodes();
02050
02051
02052 info->Set_changed_iter(1);
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063 IPA_PRED_ITER edge_iter ( cg, &caller );
02064 for ( edge_iter.First(); !edge_iter.Is_Empty(); edge_iter.Next() ) {
02065 IPA_EDGE* edge = edge_iter.Current_Edge();
02066
02067 if (edge == NULL)
02068 continue;
02069
02070
02071
02072
02073
02074 (void) Inc_direct_edges();
02075
02076
02077 IPA_NODE *callee = Get_callee(edge);
02078 IPAA_NODE_INFO *callee_info = Force_IPAA_Info ( *callee );
02079
02080
02081 if ( ! callee_info->Is_visited() ) {
02082
02083
02084
02085 edge->Set_Recursive ();
02086 info->Set_has_back_edge ();
02087 callee->Set_Incoming_Back_Edge ();
02088
02089
02090
02091 Set_changed ();
02092
02093 if ( Trace_IPAA ) {
02094 fprintf ( TFile, "<ipaa> Meet_direct_iter_1: unvisited edge " );
02095 edge->Trace ( Get_callgraph(), TRUE );
02096 fflush ( TFile );
02097 }
02098
02099
02100 } else if ( &caller == callee ) {
02101
02102
02103
02104 edge->Set_Recursive ();
02105 info->Set_has_back_edge ();
02106 info->Set_depends_on_back_edge ();
02107 callee->Set_Incoming_Back_Edge ();
02108 Accumulate_ref_info ( caller, *callee, *edge );
02109
02110
02111
02112
02113
02114 if ( info->Passes_formals_by_value() ) {
02115 ++self_calls;
02116 }
02117
02118
02119 } else {
02120
02121
02122 if ( callee_info->Depends_on_back_edge() ) {
02123 info->Set_depends_on_back_edge();
02124 }
02125 Accumulate_ref_info ( caller, *callee, *edge );
02126 }
02127
02128
02129 if ( callee_info->Has_unknown_call_effects() ) {
02130 info->Set_has_unknown_call_effects();
02131 }
02132
02133 }
02134
02135
02136
02137
02138
02139
02140
02141
02142 if (! caller.Icall_List().empty ()) {
02143 IPA_ICALL_LIST& icall_list = caller.Icall_List();
02144 for (IPA_ICALL_LIST::iterator icall_iter = icall_list.begin ();
02145 icall_iter != icall_list.end (); ++icall_iter) {
02146 SUMMARY_CALLSITE *c = (*icall_iter)->Callsite();
02147 (void) Inc_direct_edges();
02148
02149 if ( c != NULL ) {
02150 Accumulate_indirect_actual_refs ( caller, *c );
02151 }
02152
02153 info->Set_has_indirect_edge();
02154 info->Set_has_unknown_call_effects();
02155 }
02156
02157 info->Get_eref_set ()->Union_2 (icall_eref);
02158 info->Get_def_set ()->Union_2 (icall_def);
02159 info->Get_kill_set ()->Union_2 (icall_kill);
02160 }
02161
02162
02163
02164
02165
02166 if (! caller.Ocall_List ().empty () ) {
02167 IPA_ICALL_LIST& ocall_list = caller.Ocall_List ();
02168 for (IPA_ICALL_LIST::iterator ocall_iter = ocall_list.begin ();
02169 ocall_iter != ocall_list.end (); ++ocall_iter) {
02170
02171 SUMMARY_CALLSITE *c = (*ocall_iter)->Callsite();
02172 (void) Inc_direct_edges();
02173
02174 if ( c != NULL ) {
02175 Accumulate_indirect_actual_refs ( caller, *c );
02176 }
02177
02178 info->Set_has_unknown_call_effects();
02179 }
02180
02181 info->Get_eref_set ()->Union_2 (icall_eref);
02182 info->Get_def_set ()->Union_2 (icall_def);
02183 info->Get_kill_set ()->Union_2 (icall_kill);
02184 }
02185
02186
02187
02188
02189 BOOL changed = TRUE;
02190 while ( self_calls-- > 0 && changed ) {
02191 changed = FALSE;
02192 IPA_PRED_ITER edge_iter ( cg, &caller );
02193
02194 for ( edge_iter.First(); !edge_iter.Is_Empty(); edge_iter.Next() ) {
02195 IPA_EDGE* edge = edge_iter.Current_Edge();
02196
02197 if ( edge != NULL ) {
02198 IPA_NODE *callee = Get_callee(edge);
02199
02200 if ( &caller == callee ) {
02201
02202 (void) Inc_direct_edges();
02203 (void) Inc_direct_changed();
02204 changed |= Check_and_accumulate_ref_info (caller,
02205 *callee,
02206 *edge );
02207 }
02208 }
02209 }
02210 }
02211
02212
02213
02214
02215
02216 istep.Finalize_Ref_Info ();
02217
02218 Set_step ( NULL );
02219 }
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237 void
02238 IPAA_DF_SOLVER::Meet_direct_iter_n ( IPA_NODE &caller )
02239 {
02240 IPAA_NODE_INFO *info = caller.Mod_Ref_Info();
02241 if (! caller.Mod_Ref_Info ()->Depends_on_back_edge () &&
02242 caller.Icall_List().empty () &&
02243 caller.Ocall_List ().empty ())
02244 return;
02245 (void) Inc_direct_nodes ();
02246
02247
02248 IPA_CALL_GRAPH *cg = Get_callgraph();
02249 IPAA_STEP istep ( *cg, caller );
02250 Set_step ( &istep );
02251
02252
02253
02254
02255
02256
02257 IPA_PRED_ITER edge_iter ( cg, &caller );
02258 INT16 iteration = Get_iteration();
02259
02260 for ( edge_iter.First();
02261 !edge_iter.Is_Empty();
02262 edge_iter.Next() )
02263 {
02264 IPA_EDGE* edge = edge_iter.Current_Edge();
02265
02266 if ( edge != NULL ) {
02267 IPA_NODE *callee = Get_callee(edge);
02268 IPAA_NODE_INFO *callee_info = callee -> Mod_Ref_Info();
02269 (void) Inc_direct_edges ();
02270
02271
02272 INT16 changed_iteration = callee_info->Get_changed_iter()
02273 + ( edge->Is_Recursive() ? 1 : 0 );
02274
02275
02276 if ( changed_iteration == iteration ) {
02277
02278
02279 if ( Check_and_accumulate_ref_info ( caller, *callee, *edge ) )
02280 {
02281 callee_info->Set_changed_iter ( iteration );
02282 Set_changed ();
02283 (void) Inc_direct_changed ();
02284 }
02285 }
02286 }
02287 }
02288
02289
02290
02291 if (! caller.Icall_List().empty ()) {
02292 info->Get_eref_set ()->Union_2 (icall_eref);
02293 info->Get_def_set ()->Union_2 (icall_def);
02294 info->Get_kill_set ()->Union_2 (icall_kill);
02295 }
02296
02297 if (! caller.Ocall_List ().empty () ) {
02298 info->Get_eref_set ()->Union_2 (icall_eref);
02299 info->Get_def_set ()->Union_2 (icall_def);
02300 info->Get_kill_set ()->Union_2 (icall_kill);
02301 }
02302
02303
02304
02305 Set_step ( NULL );
02306 }
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320 static void
02321 Check_Passed_Global (const IPAA_NODE_INFO &callee_info,
02322 INT16 formal_num,
02323 UINT32 merged_idx )
02324 {
02325 if (callee_info.Is_formal_dref_elmt ( formal_num ) ||
02326 callee_info.Get_fcount() <= formal_num ||
02327 callee_info.Is_eref_elmt (merged_idx) ||
02328 callee_info.Is_def_elmt (merged_idx) ||
02329 callee_info.Is_kill_elmt (merged_idx)) {
02330
02331
02332
02333
02334
02335
02336 ST_IDX merged_st_idx = make_ST_IDX( merged_idx, GLOBAL_SYMTAB );
02337 Set_ST_addr_saved (&St_Table[merged_st_idx]);
02338 }
02339 }
02340
02341
02342
02343 static void
02344 Check_Passed_Local (
02345 const IPA_NODE &caller,
02346 IPAA_NODE_INFO &callee_info,
02347 INT16 formal_num,
02348 SUMMARY_SYMBOL *sym )
02349 {
02350 if ( callee_info . Get_fcount() <= formal_num
02351 || callee_info . Is_formal_dref_elmt ( formal_num ) )
02352 {
02353
02354
02355
02356 sym -> Set_addr_saved ();
02357 callee_info . Set_local_addr_taken_mods ();
02358
02359
02360
02361 SUMMARY_PROCEDURE *summary_proc = caller.Summary_Proc();
02362 if ( summary_proc != NULL ) {
02363 summary_proc->Set_has_addr_taken_reset();
02364 }
02365 }
02366 }
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396 BOOL
02397 IPAA_DF_SOLVER::Map_actual (const IPA_NODE &caller,
02398 IPAA_NODE_INFO &caller_info,
02399 IPA_EDGE &edge,
02400 const IPA_NODE &callee,
02401 IPAA_NODE_INFO &callee_info,
02402 INT16 formal_num,
02403 const SUMMARY_ACTUAL &actual)
02404 {
02405 IPA_PASS_TYPE pass = actual.Get_pass_type();
02406 SUMMARY_SYMBOL * sym = 0;
02407 INT32 caller_formal = 0;
02408 BOOL changed = FALSE;
02409 ACTUAL_KIND akind;
02410 BOOL mod;
02411 UINT32 merged_idx;
02412
02413 switch ( pass ) {
02414
02415
02416 case PASS_LDID:
02417
02418 akind = Get_step()->Get_actual_info
02419 ( actual, sym, merged_idx, caller_formal );
02420
02421 if ( akind == ACTUAL_KIND_FORMAL ) {
02422
02423 changed |=
02424 Add_Map_To_Map ( callee_info, formal_num,
02425 *caller_info.Get_fmap(caller_formal) );
02426 }
02427 break;
02428
02429
02430 case PASS_LDA:
02431
02432 if ( Get_iteration() > 1 ) break;
02433
02434 akind = Get_step()->Get_actual_info
02435 ( actual, sym, merged_idx, caller_formal );
02436
02437 mod = callee_info.Is_formal_imod_elmt (formal_num);
02438
02439 switch ( akind ) {
02440
02441 case ACTUAL_KIND_GLOBAL:
02442
02443 if ( Add_Actual_To_Map ( callee_info, formal_num, merged_idx ) ) {
02444 ST_IDX merged_st_idx = make_ST_IDX( merged_idx, GLOBAL_SYMTAB );
02445 changed = TRUE;
02446 if (IPA_Enable_Addressing &&
02447 ! (ST_addr_saved (&St_Table[merged_st_idx]) ||
02448 ST_addr_passed (&St_Table[merged_st_idx]) ) )
02449 Check_Passed_Global (callee_info, formal_num, merged_idx );
02450 }
02451
02452 mod |= callee_info.Is_def_elmt (merged_idx);
02453
02454 break;
02455
02456 case ACTUAL_KIND_FORMAL:
02457 case ACTUAL_KIND_LOCAL:
02458
02459 if (IPA_Enable_Addressing && ! sym -> Is_addr_saved() ) {
02460 Check_Passed_Local (caller, callee_info, formal_num, sym );
02461 }
02462 break;
02463
02464 case ACTUAL_KIND_PSTATIC:
02465 case ACTUAL_KIND_FSTATIC:
02466
02467
02468 mod = TRUE;
02469 break;
02470 }
02471
02472
02473 if (!IPA_Enable_Readonly_Ref || caller.Is_Lang_F77() ||
02474 caller.Is_Lang_F90())
02475 break;
02476
02477 if (sym && sym->Is_addr_saved ()) {
02478 edge.Clear_Param_Readonly(formal_num);
02479 edge.Clear_Param_Pass_Not_Saved(formal_num);
02480 break;
02481 }
02482
02483 if (mod)
02484 edge.Clear_Param_Readonly(formal_num);
02485 else
02486 edge.Set_Param_Readonly(formal_num);
02487 if (callee_info.Is_formal_dref_elmt (formal_num))
02488 edge.Clear_Param_Pass_Not_Saved(formal_num);
02489 else
02490 edge.Set_Param_Pass_Not_Saved (formal_num);
02491
02492 break;
02493 }
02494
02495 return changed;
02496 }
02497
02498
02499
02500
02501
02502 static void
02503 Verify_duplicated_actuals (IPA_EDGE &edge, const SUMMARY_ACTUAL *actual,
02504 INT actual_count)
02505 {
02506 for (INT i = 0; i < actual_count; ++i) {
02507 if (actual[i].Get_pass_type () != PASS_LDA)
02508 continue;
02509 for (INT j = i + 1; j < actual_count; ++j) {
02510 if (actual[j].Get_pass_type () != PASS_LDA)
02511 continue;
02512 if (actual[j].Get_symbol_index () != actual[i].Get_symbol_index ())
02513 continue;
02514 if (edge.Is_Param_Readonly(i) != edge.Is_Param_Readonly(j)) {
02515 edge.Clear_Param_Readonly(i);
02516 edge.Clear_Param_Readonly(j);
02517 }
02518 if (edge.Is_Param_Pass_Not_Saved(i) !=
02519 edge.Is_Param_Pass_Not_Saved(j)) {
02520 edge.Clear_Param_Pass_Not_Saved(i);
02521 edge.Clear_Param_Pass_Not_Saved(j);
02522 }
02523 }
02524 }
02525
02526 }
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545 void
02546 IPAA_DF_SOLVER::Map_actuals (const IPA_NODE &caller,
02547 const IPA_NODE &callee,
02548 IPA_EDGE &edge )
02549 {
02550 SUMMARY_CALLSITE *call = edge.Summary_Callsite();
02551 INT32 acount;
02552
02553
02554 if ( Trace_IPAA ) {
02555 fprintf ( TFile, "<ipaa> mapa: edge " );
02556 edge.Trace ( Get_callgraph() );
02557 fflush ( TFile );
02558 }
02559
02560
02561 acount = call->Get_param_count();
02562 SUMMARY_ACTUAL *actual = Get_actuals() + call->Get_actual_index();
02563
02564
02565 for (INT j=0; j < acount; ++j) {
02566 IPAA_NODE_INFO *callee_info = callee.Mod_Ref_Info();
02567 IPAA_NODE_INFO *caller_info = caller.Mod_Ref_Info();
02568
02569
02570 if ( Trace_Detail ) {
02571 fprintf ( TFile, "<ipaa> mapa: " );
02572 actual[j].Trace (call->Get_actual_index() + j);
02573 }
02574
02575 if ( Map_actual (caller, *caller_info, edge, callee, *callee_info,
02576 j, actual[j])) {
02577
02578
02579
02580
02581
02582 if ( callee_info->Passes_formals_by_value() ) {
02583 INT16 iteration = Get_iteration();
02584
02585
02586
02587 if ( edge.Is_Recursive() ) {
02588 callee_info->Set_changed_iter ( iteration+1 );
02589 Set_changed();
02590
02591
02592 } else {
02593 callee_info->Set_changed_iter ( iteration );
02594 }
02595 }
02596 }
02597 }
02598
02599 Verify_duplicated_actuals (edge, actual, acount);
02600 }
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616 void
02617 IPAA_DF_SOLVER::Meet_formals_iter_1 ( IPA_NODE &caller )
02618 {
02619
02620 IPA_CALL_GRAPH *cg = Get_callgraph();
02621 IPAA_NODE_INFO *info = caller.Mod_Ref_Info();
02622 IPAA_STEP istep ( *cg, caller );
02623 Set_step ( &istep );
02624 (void) Inc_formal_nodes ();
02625
02626
02627 info->Set_changed_iter ( 0 );
02628
02629
02630
02631 IPA_SUCC_ITER edge_iter ( cg, &caller );
02632 for ( edge_iter.First();
02633 !edge_iter.Is_Empty();
02634 edge_iter.Next() )
02635 {
02636 IPA_EDGE* edge = edge_iter.Current_Edge();
02637
02638
02639 if ( edge != NULL ) {
02640 Map_actuals ( caller, *Get_callee(edge), *edge );
02641 (void) Inc_formal_edges ();
02642 }
02643 }
02644
02645
02646
02647
02648 if ( Trace_IPAA ) {
02649 fprintf ( TFile, "<ipaa> Meet_formals_iter_1:\n" );
02650 istep.Trace();
02651 fflush ( TFile );
02652 }
02653
02654 Set_step ( NULL );
02655 }
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666 void
02667 IPAA_DF_SOLVER::Meet_formals_iter_n ( IPA_NODE &caller )
02668 {
02669 INT16 iteration = Get_iteration();
02670 IPAA_NODE_INFO *caller_info = caller.Mod_Ref_Info();
02671
02672
02673
02674 if ( caller_info->Get_changed_iter() < iteration ) return;
02675
02676
02677
02678
02679
02680
02681
02682 (void) Inc_formal_nodes ();
02683 IPA_CALL_GRAPH *cg = Get_callgraph();
02684 IPAA_STEP istep ( *cg, caller );
02685 Set_step ( &istep );
02686
02687
02688
02689 IPA_SUCC_ITER edge_iter ( cg, &caller );
02690
02691 for ( edge_iter.First();
02692 !edge_iter.Is_Empty();
02693 edge_iter.Next() )
02694 {
02695 IPA_EDGE* edge = edge_iter.Current_Edge();
02696
02697 if ( edge != NULL ) {
02698
02699 Map_actuals ( caller, *Get_callee(edge), *edge );
02700 (void) Inc_formal_edges ();
02701 }
02702 }
02703
02704
02705
02706
02707 if ( Trace_IPAA ) {
02708 fprintf ( TFile, "<ipaa> Meet_formals_iter_%d:\n", iteration );
02709 istep.Trace();
02710 fflush ( TFile );
02711 }
02712
02713 Set_step ( NULL );
02714 }
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761 IPAA_DF_SOLVER::IN_T *
02762 IPAA_DF_SOLVER::Meet ( IN_T *, void *vertex_user )
02763 {
02764 IPA_NODE *caller = (IPA_NODE *)vertex_user;
02765
02766
02767 if ( Trace_Iterator ) {
02768 DFN *iter = this->Get_iter();
02769 INT32 i;
02770
02771 fprintf ( TFile, "\n%sAnalyze_Direct_Refs: tracing iterator\n%s",
02772 DBar, DBar );
02773
02774 for ( i=DFN_first(iter); i< DFN_end(iter); ++i ) {
02775 INT vindex = DFN_v_list_i(iter,i);
02776 IPA_NODE *vertex = (IPA_NODE *)
02777 NODE_user ( &GRAPH_v_i (Get_callgraph()->Graph(), vindex) );
02778
02779 fprintf ( TFile, "Node %5d: ", vindex );
02780 if ( vertex != NULL ) {
02781 vertex->Trace ();
02782 } else {
02783 fprintf ( TFile, "NULL\n" );
02784 }
02785 }
02786
02787 fprintf ( TFile, "%s\n", DBar );
02788 fflush ( TFile );
02789
02790 Trace_Iterator = FALSE;
02791 }
02792
02793
02794 if ( Trace_IPAA ) {
02795 if ( caller == NULL ) {
02796 fprintf ( TFile, "<ipaa> Meet: NULL vertex\n" );
02797 } else {
02798 fprintf ( TFile, "<ipaa> Meet: " );
02799 caller->Print ( TFile );
02800 }
02801 fflush ( TFile );
02802 }
02803
02804
02805 if ( caller == NULL ) {
02806 return NULL;
02807 }
02808
02809 if ( Get_phase() == PHASE_DIRECT ) {
02810
02811 if ( Get_iteration() == 1 ) {
02812
02813
02814
02815
02816
02817 Meet_direct_iter_1 ( *caller );
02818
02819 } else {
02820
02821
02822 if ( Get_iteration() != Get_direct_iters() ) {
02823 Report_graph_statistics ( PHASE_DIRECT );
02824 Set_direct_iters ( Get_iteration() );
02825 }
02826
02827
02828
02829
02830
02831
02832
02833
02834 Meet_direct_iter_n ( *caller );
02835 }
02836
02837 } else if ( Get_phase() == PHASE_FORMALS ) {
02838
02839 if ( Get_iteration() == 1 ) {
02840
02841
02842
02843
02844
02845 Meet_formals_iter_1 ( *caller );
02846
02847 } else {
02848
02849
02850 if ( Get_iteration() != Get_formal_iters() ) {
02851 Report_graph_statistics ( PHASE_FORMALS );
02852 Set_formal_iters ( Get_iteration() );
02853 }
02854
02855
02856
02857
02858
02859
02860
02861
02862 Meet_formals_iter_n ( *caller );
02863 }
02864
02865 } else {
02866 ErrMsg ( EC_Unimplemented, "Meet -- unexpected phase" );
02867 }
02868
02869
02870 return caller->Mod_Ref_Info();
02871 }
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889 static void
02890 Analyze_Direct_Refs ( IPA_CALL_GRAPH &cg )
02891 {
02892 IPAA_DF_SOLVER solver ( cg, BACKWARD, IPAA_Pool,
02893 IPAA_DF_SOLVER::PHASE_DIRECT );
02894
02895
02896 solver.Solver ();
02897
02898
02899 solver.Report_graph_statistics ( IPAA_DF_SOLVER::PHASE_DIRECT );
02900
02901
02902 }
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913 static void
02914 Analyze_Indirect_Refs ( IPA_CALL_GRAPH &cg )
02915 {
02916 IPAA_DF_SOLVER solver ( cg, FORWARD, IPAA_Pool,
02917 IPAA_DF_SOLVER::PHASE_FORMALS );
02918
02919 solver.Solver ();
02920
02921
02922 solver.Report_graph_statistics ( IPAA_DF_SOLVER::PHASE_FORMALS );
02923
02924
02925 solver.Extract_solution ();
02926
02927
02928 }
02929
02930
02931
02932
02933
02934
02935
02936 IPAA::IPAA ( MEM_POOL *mem )
02937 {
02938 _m = mem;
02939 }
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953 void
02954 IPAA::Do_Simple_IPAA ( IPA_CALL_GRAPH &cg )
02955 {
02956
02957 Trace_IPAA = Get_Trace ( TP_IPA, IPA_TRACE_IPAA );
02958 Trace_Detail = Get_Trace ( TP_IPA, IPA_TRACE_DETAIL );
02959 Trace_Stats = Get_Trace ( TP_IPA, IPA_TRACE_STATS );
02960 Trace_Iterator = Get_Trace ( TP_IPA, IPA_TRACE_ITERATOR );
02961 IPA_Trace_Mod_Ref = Get_Trace ( TP_IPA, IPA_TRACE_MODREF );
02962 if ( Trace_IPAA ) {
02963 Trace_Callgraph ( cg, FORWARD, "before IPAA" );
02964 }
02965
02966
02967 IPAA_Pool = this->Get_IPAA_Mem_Pool();
02968 if ( IPAA_Pool == NULL ) {
02969 IPAA_Pool = Malloc_Mem_Pool;
02970 this->Set_IPAA_Mem_Pool ( IPAA_Pool );
02971 }
02972 MEM_POOL_Push ( MEM_local_pool_ptr );
02973
02974
02975 Mext_Size = ST_Table_Size(GLOBAL_SYMTAB);
02976
02977
02978 icall_eref = CXX_NEW (IPAA_OBJECT_REF_SET (0), Malloc_Mem_Pool);
02979 icall_def = CXX_NEW (IPAA_OBJECT_REF_SET (0), Malloc_Mem_Pool);
02980 icall_kill = CXX_NEW (IPAA_OBJECT_REF_SET (0), Malloc_Mem_Pool);
02981
02982
02983
02984 if ( Trace_IPAA ) {
02985 fprintf ( TFile, "\n%s%sIPAA: Analyze Direct References\n%s%s\n",
02986 DBar, DBar, DBar, DBar );
02987 fflush ( TFile );
02988 }
02989 Analyze_Direct_Refs ( cg );
02990
02991
02992
02993
02994 if ( Trace_IPAA ) {
02995 fprintf ( TFile,
02996 "\n%s%sIPAA: Analyze Formal Points-To Mapping\n%s%s\n",
02997 DBar, DBar, DBar, DBar );
02998 fflush ( TFile );
02999 }
03000 Analyze_Indirect_Refs ( cg );
03001
03002
03003 IPAA_Pool = NULL;
03004 MEM_POOL_Pop ( MEM_local_pool_ptr );
03005 }
03006
03007 #ifdef _OBSOLETE
03008
03009
03010
03011
03012
03013
03014
03015
03016 MEM_POOL IPAA_Emit_Pool;
03017
03018
03019
03020
03021 MEM_POOL *IPAA_Callsite_Pool;
03022
03023
03024
03025 typedef class USER_HASH_TABLE < char*, INT32, String_Hash, String_Equal >
03026 STRING_HASH_TABLE;
03027 STRING_HASH_TABLE *String_Hash_Table;
03028 String_Hash Hash_Func;
03029
03030
03031
03032
03033 static INT32 *Name_Table = NULL;
03034
03035
03036
03037
03038 static SYMREF_IX *Symref_Table = NULL;
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055 INT32
03056 IPAA::Emit_name ( const char *name )
03057 {
03058 INT32 index = String_Hash_Table->Find ( (char *)name );
03059
03060 if ( index == 0 ) {
03061 if ( Trace_IPAA_Summary ) {
03062 fprintf ( TFile,
03063 "<ipaa> Emit_Name 0x%08lx hash 0x%04x (%2d) %s\n",
03064 name, Hash_Func(name), Hash_Func(name)%75,
03065 (char *)name );
03066 fflush ( TFile );
03067 }
03068 index = _summary->Add_string ( (char *)name );
03069 String_Hash_Table->Enter ( (char *)name, index );
03070 if ( Trace_IPAA_Summary ) {
03071 String_Hash_Table->Print ( TFile );
03072 }
03073 }
03074
03075 return index;
03076 }
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093 INT32
03094 IPAA::Emit_global_name ( INT32 merged_id )
03095 {
03096 if ( Name_Table == NULL ) {
03097 Name_Table = TYPE_MEM_POOL_ALLOC_N ( INT32, &IPAA_Emit_Pool,
03098 ST_Table_Size(GLOBAL_SYMTAB) );
03099 }
03100
03101 if ( Name_Table[merged_id] == NULL ) {
03102 ST_IDX st_idx = make_ST_IDX( merged_id, GLOBAL_SYMTAB );
03103 Name_Table[merged_id] = Emit_name ( ST_name(St_Table[st_idx]) );
03104 }
03105
03106 return Name_Table[merged_id];
03107 }
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122 INT32
03123 IPAA::Emit_pu_name ( const char *name )
03124 {
03125
03126 IPAA_SYMBOL_REF sref ( SREF_NAME, 0, Emit_name ( name ) );
03127
03128
03129 return _summary->Add_symref ( sref );
03130 }
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145 SYMREF_IX
03146 IPAA::Emit_global ( INT32 merged_id, BOOL reuse_ok )
03147 {
03148 IPAA_SYMBOL_REF sref ( SREF_GLOBAL, 0,
03149 Emit_global_name ( merged_id ) );
03150
03151
03152 if ( Symref_Table == NULL ) {
03153 Symref_Table = TYPE_MEM_POOL_ALLOC_N ( SYMREF_IX,
03154 &IPAA_Emit_Pool,
03155 ST_Table_Size(GLOBAL_SYMTAB) );
03156 }
03157
03158 if ( reuse_ok && Symref_Table[merged_id] != 0 ) {
03159 return Symref_Table[merged_id];
03160 } else {
03161 return Symref_Table[merged_id] = _summary->Add_symref ( sref );
03162 }
03163 }
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174 void
03175 IPAA::Emit_IPAA_node ( const IPA_NODE &node )
03176 {
03177 IPAA_NODE_INFO *info = node.Mod_Ref_Info();
03178 INT32 i, count;
03179
03180
03181 if ( Trace_IPAA_Summary ) {
03182 fprintf ( TFile, "<ipaa> ### Emit_IPAA_node ( %s in %s ) ###\n",
03183 node.Name(), node.Input_File_Name() );
03184 if ( info == NULL ) {
03185 fprintf ( TFile,
03186 "<ipaa> ### No IPAA information available ###\n" );
03187 }
03188 }
03189
03190
03191
03192 if ( info == NULL ) return;
03193
03194 INT32 fcount = info->Get_fcount();
03195
03196
03197 INT32 filename_ix = Emit_name ( node . Input_File_Name() );
03198
03199
03200 SYMREF_IX pu = Emit_pu_name ( node . Name() );
03201
03202
03203
03204
03205 SET_IX formal_mapping = 0;
03206 SET_IX formal_modref = 0;
03207
03208 if ( fcount > 0 ) {
03209
03210
03211
03212 IPAA_SET *formal_sets = (IPAA_SET *)
03213 CXX_NEW_ARRAY ( IPAA_SET, fcount, MEM_local_pool_ptr );
03214 IPAA_FORMAL_MAP **maps = info->Get_fmap();
03215
03216 for ( i = 0; i < fcount; i++ ) {
03217 IPAA_FORMAL_MAP *map = maps ? maps[i] : NULL;
03218 IPAA_SET *set = formal_sets + i;
03219
03220 set->Set_kind ( SET_SYMREF );
03221 set->Set_index ( 0 );
03222 set->Set_size ( 0 );
03223 if ( (map != NULL) && ( count = map->Get_size() ) > 0 ) {
03224 SYMREF_IX first = 0, last;
03225 INT32 j = 0;
03226
03227 if ( map->Get_junk() ) {
03228
03229
03230
03231 if ( count-- == 0 ) {
03232
03233
03234
03235
03236 first = SYMREF_IX_UNKNOWN;
03237 } else {
03238 IPAA_SYMBOL_REF sref ( SREF_UNKNOWN, 0, 0 );
03239 first = _summary->Add_symref ( sref );
03240 }
03241 }
03242
03243 for ( j = 0; j < count; j++ ) {
03244 IPAA_FORMAL_MAP::MAP_ELMT melmt = map->Get_elmt ( j );
03245
03246 if ( melmt != IPAA_FORMAL_MAP::MAP_NONE ) {
03247 last = Emit_global ( (INT32) melmt, FALSE );
03248 if ( first == 0 ) first = last;
03249 }
03250 }
03251
03252 set->Set_index ( first );
03253 set->Set_size ( map->Get_size() );
03254 }
03255 }
03256
03257
03258 IPAA_SET formal_maps ( formal_sets, fcount );
03259 formal_mapping = _summary->Add_set ( formal_maps );
03260
03261
03262 REFBITS *masks = TYPE_MEM_POOL_ALLOC_N ( REFBITS,
03263 MEM_local_pool_ptr,
03264 fcount );
03265 for ( i = 0; i < fcount; i++ ) {
03266 if ( info-> Is_formal_dref_elmt ( i ) ) masks[i] |= MODREF_DREF;
03267 if ( info-> Is_formal_iref_elmt ( i ) ) masks[i] |= MODREF_IREF;
03268 if ( info-> Is_formal_dmod_elmt ( i ) ) masks[i] |= MODREF_DMOD;
03269 if ( info-> Is_formal_imod_elmt ( i ) ) masks[i] |= MODREF_IMOD;
03270 if ( info-> Is_formal_dkill_elmt( i ) ) masks[i] |= MODREF_DKILL;
03271 if ( info-> Is_formal_ikill_elmt( i ) ) masks[i] |= MODREF_IKILL;
03272 }
03273 IPAA_SET formal_modrefs ( masks, fcount );
03274 formal_modref = _summary->Add_set ( formal_modrefs );
03275 }
03276
03277
03278
03279 SPARSE_ITER eref ( info->Get_eref_set() -> _data );
03280 SPARSE_ITER def ( info-> Get_def_set() -> _data );
03281 SPARSE_ITER kill ( info->Get_kill_set() -> _data );
03282 REFBITS refbits;
03283 INT32 elmt;
03284 SBV_ELEMENT eref_elmt = eref.Element();
03285 SBV_ELEMENT def_elmt = def.Element();
03286 BOOL eref_valid = (eref_elmt != SBV_Invalid );
03287 BOOL def_valid = ( def_elmt != SBV_Invalid );
03288 MODREF_IX first_global = 0;
03289 INT32 num_globals = 0;
03290
03291 while ( eref_valid || def_valid ) {
03292 refbits = 0;
03293 if ( eref_valid
03294 && ( !def_valid || eref_elmt <= def_elmt ) )
03295 {
03296
03297 elmt = eref_elmt;
03298
03299 refbits = MODREF_DREF;
03300 if ( eref_valid = eref.Advance() ) {
03301 eref_elmt = eref.Element();
03302 }
03303 if ( def_elmt == elmt ) {
03304 refbits |= MODREF_DMOD;
03305 if ( def_valid = def.Advance() ) {
03306 def_elmt = def.Element();
03307 }
03308 if ( kill.Element() == elmt ) {
03309 refbits |= MODREF_DKILL;
03310 (void) kill.Advance();
03311 }
03312 }
03313 } else {
03314
03315 elmt = def_elmt;
03316
03317 refbits = MODREF_DMOD;
03318 if ( def_valid = def.Advance() ) {
03319 def_elmt = def.Element();
03320 }
03321 if ( kill.Element() == elmt ) {
03322 refbits |= MODREF_DKILL;
03323 (void) kill.Advance();
03324 }
03325 }
03326
03327
03328 IPAA_MODREF modref ( refbits, Emit_global ( elmt, TRUE ) );
03329 MODREF_IX mix = _summary->Add_modref ( modref );
03330 if ( first_global == 0 ) first_global = mix;
03331 ++ num_globals;
03332 }
03333
03334
03335 SET_IX globals = 0;
03336 if ( num_globals > 0 ) {
03337 IPAA_SET global_set ( SET_MODREF, first_global, num_globals );
03338 globals = _summary->Add_set ( global_set );
03339 }
03340
03341
03342 IPAA_PU_INFO pu_info ( pu, formal_mapping, formal_modref, globals );
03343 info -> Set_pu_info ( _summary->Add_pu_info ( pu_info ) );
03344 }
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355 void
03356 IPAA::Emit_IPAA_callsites ( IPA_NODE &node )
03357 {
03358 IPAA_NODE_INFO *info = node.Mod_Ref_Info();
03359
03360
03361 if ( Trace_IPAA_Summary ) {
03362 fprintf ( TFile, "<ipaa> ### Emit_IPAA_callsites ( %s in %s ) ###\n",
03363 node.Name(), node.Input_File_Name() );
03364 if ( info == NULL ) {
03365 fprintf ( TFile,
03366 "<ipaa> ### No IPAA information available ###\n" );
03367 }
03368 }
03369
03370
03371
03372 if ( info == NULL ) return;
03373
03374
03375 IPAA_CALLSITES *callsites =
03376 CXX_NEW ( IPAA_CALLSITES ( info->Get_pu_info(),
03377 node . Total_Succ(),
03378 IPAA_Callsite_Pool ),
03379 IPAA_Callsite_Pool );
03380
03381
03382 IPA_SUCC_ITER edge_iter ( Get_cg(), &node );
03383 for ( edge_iter.First();
03384 ! edge_iter.Is_Empty();
03385 edge_iter.Next() )
03386 {
03387 IPA_EDGE *e = edge_iter.Current_Edge();
03388
03389 if ( e != NULL ) {
03390 if ( Trace_IPAA_Summary ) {
03391 fprintf ( TFile, "<ipaa>\tedge: " );
03392 e->Trace ( Get_cg() );
03393 }
03394
03395 INT32 map_id = e -> Summary_Callsite() -> Get_map_id();
03396 IPAA_NODE_INFO *callee_info = Get_cg() -> Callee ( e )
03397 -> Mod_Ref_Info ();
03398
03399
03400
03401
03402 if ( callee_info != NULL ) {
03403 INT32 callee = callee_info -> Get_pu_info();
03404 (void ) callsites -> Add_callsite ( map_id, callee );
03405 }
03406 }
03407 }
03408
03409
03410 PU_Info *pu = node . PU_Info();
03411 Set_PU_Info_callsites_ptr ( pu, callsites );
03412 Set_PU_Info_state ( pu, WT_CALLSITES, Subsect_InMem );
03413
03414 if ( Trace_IPAA_Summary ) {
03415 callsites -> Trace ( node.Name() );
03416 }
03417
03418 return;
03419 }
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430 void
03431 IPAA::Emit_Simple_IPAA ( IPA_CALL_GRAPH &cg )
03432 {
03433 NODE_INDEX i;
03434
03435
03436 Trace_IPAA = Get_Trace ( TP_IPA, IPA_TRACE_IPAA );
03437 Trace_IPAA_Summary = Get_Trace ( TP_IPA, IPA_TRACE_IPAA_SUMMARY );
03438 if ( Trace_IPAA || Trace_IPAA_Summary ) {
03439 Trace_Callgraph ( cg, FORWARD, "emitting IPAA summary" );
03440 }
03441 _cg = &cg;
03442
03443
03444 MEM_POOL_Initialize ( &IPAA_Emit_Pool, "IPAA summary pool", TRUE );
03445 MEM_POOL_Push ( &IPAA_Emit_Pool );
03446 IPAA_Pool = &IPAA_Emit_Pool;
03447
03448
03449 MEM_POOL_Push ( MEM_local_pool_ptr );
03450
03451
03452 _summary = CXX_NEW ( IPAA_SUMMARY ( &IPAA_Emit_Pool ),
03453 &IPAA_Emit_Pool );
03454 if ( _summary == NULL ) {
03455 ErrMsg ( EC_No_Mem, "IPAA::Emit_Simple_IPAA : summary" );
03456 }
03457
03458
03459 String_Hash_Table = CXX_NEW ( STRING_HASH_TABLE ( ST_Table_Size(GLOBAL_SYMTAB),
03460 &IPAA_Emit_Pool ),
03461 &IPAA_Emit_Pool );
03462
03463
03464
03465 DFN *dfn = Depth_First_Ordering ( cg.Graph(), &IPAA_Emit_Pool );
03466 for ( i = DFN_first(dfn); i < DFN_end(dfn); ++i ) {
03467 NODE_INDEX ix = DFN_v_list_i(dfn,i);
03468 IPA_NODE *node = cg.Graph()->Node_User(ix);
03469 if ( node != NULL ) {
03470 Emit_IPAA_node ( *node );
03471 }
03472 }
03473
03474
03475 IPAA_Callsite_Pool = (MEM_POOL *) malloc ( sizeof(MEM_POOL) );
03476 if ( IPAA_Callsite_Pool == NULL ) {
03477 ErrMsg ( EC_No_Mem, "IPAA::Emit_Simple_IPAA : Callsites" );
03478 }
03479 MEM_POOL_Initialize ( IPAA_Callsite_Pool, "IPAA callsite pool", FALSE );
03480 MEM_POOL_Push ( IPAA_Callsite_Pool );
03481
03482
03483
03484
03485
03486 for ( i = DFN_first(dfn); i < DFN_end(dfn); ++i ) {
03487 NODE_INDEX ix = DFN_v_list_i(dfn,i);
03488 IPA_NODE *node = cg.Graph()->Node_User(ix);
03489 if ( node != NULL ) {
03490 Emit_IPAA_callsites ( *node );
03491 }
03492 }
03493
03494
03495 extern char *tmpdir __attribute__((weak));
03496 char *Ipa_Path_Name = (char *) malloc
03497 ( strlen(tmpdir) + strlen(Ipa_File_Name) + 2 );
03498 (void) sprintf ( Ipa_Path_Name, "%s/%s", tmpdir, Ipa_File_Name );
03499 _summary->Write ( Ipa_Path_Name );
03500 if ( Trace_IPAA || Trace_IPAA_Summary ) {
03501 fprintf ( TFile,
03502 "<ipaa> Writing IPAA summary to %s\n", Ipa_Path_Name );
03503 }
03504
03505
03506
03507
03508 add_to_tmp_file_list ( Ipa_Path_Name );
03509
03510
03511
03512 _summary -> ~IPAA_SUMMARY ();
03513 _summary = NULL;
03514
03515
03516 String_Hash_Table = NULL;
03517 Symref_Table = NULL;
03518 Name_Table = NULL;
03519
03520
03521 MEM_POOL_Pop ( &IPAA_Emit_Pool );
03522 IPAA_Pool = NULL;
03523 MEM_POOL_Pop ( MEM_local_pool_ptr );
03524 }
03525 #endif // _OBSOLETE