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 #ifndef ipaa_INCLUDED
00059 #define ipaa_INCLUDED
00060
00061 #ifndef cxx_sparse_bv_INCLUDED
00062 #include "sparse_bv.h"
00063 #endif
00064
00065 #include "ipo_tlog_utils.h"
00066 #include "ipa_option.h"
00067
00068 class IPAA_SUMMARY;
00069 class IPAA;
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 class FBV
00085 {
00086 private:
00087 union {
00088 mINT32 _fbits;
00089 mINT64 *_fdata;
00090 } _fbv;
00091
00092 public:
00093
00094
00095 FBV ( INT32 fcount, MEM_POOL *pool ) {
00096 if ( fcount > 32 ) {
00097 INT32 dw = (fcount+63)/64;
00098 _fbv._fdata = (INT64 *) MEM_POOL_Alloc ( pool, dw*sizeof(INT64) );
00099 BZERO ( _fbv._fdata, dw*sizeof(INT64) );
00100 } else
00101 _fbv._fbits = 0;
00102 }
00103
00104 FBV (const FBV& fbv, INT32 fcount, MEM_POOL *pool) {
00105 if (fcount > 32) {
00106 INT32 dw = (fcount+63)/64;
00107 _fbv._fdata = (INT64 *) MEM_POOL_Alloc ( pool, dw*sizeof(INT64) );
00108 BCOPY (fbv._fbv._fdata, _fbv._fdata, dw*sizeof(INT64));
00109 } else
00110 _fbv._fbits = fbv._fbv._fbits;
00111 }
00112
00113
00114 void FBV_free ( INT32 fcount, MEM_POOL *pool ) {
00115 if ( fcount > 32 ) {
00116 MEM_POOL_FREE ( pool, _fbv._fdata );
00117 }
00118 }
00119
00120
00121 void Print ( FILE *f, INT16 fcount ) const {
00122 fprintf ( f, "FBV:" );
00123 if ( fcount > 32 ) {
00124 INT32 i;
00125 for ( i = 0; i <= (fcount+63)/64; i++ ) {
00126 fprintf ( f, ":%016llx", _fbv._fdata[i] );
00127 if ( IPA_Trace_Mod_Ref ) {
00128 Ipa_tlog("MOD_REF", 0, ":%016llx", _fbv._fdata[i] );
00129 }
00130 }
00131 } else {
00132 fprintf ( f, ":%08x", _fbv._fbits );
00133 if ( IPA_Trace_Mod_Ref ) {
00134 Ipa_tlog("MOD_REF", 0, ":%08x", _fbv._fbits );
00135 }
00136 }
00137 }
00138
00139
00140 void Add_element ( INT32 fcount, INT32 elmt ) {
00141 if ( fcount > 32 ) {
00142 *(_fbv._fdata+elmt/64) |= (mINT64)1 << (elmt&63);
00143 } else {
00144 _fbv._fbits |= 1 << elmt;
00145 }
00146 }
00147
00148
00149 BOOL Is_element ( INT32 fcount, INT32 elmt ) {
00150 if ( fcount > 32 ) {
00151 return ( *(_fbv._fdata+elmt/64) & ( (mINT64)1 << (elmt&63) ) ) != 0;
00152 } else {
00153 return ( _fbv._fbits & ( 1 << elmt ) ) != 0;
00154 }
00155 }
00156 };
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 class IPAA_OBJECT_REF_SET
00176 {
00177 friend class IPAA;
00178
00179 private:
00180 SPARSE_BV _data;
00181 FBV _dformals;
00182 FBV _iformals;
00183 mINT32 _fcount;
00184
00185 public:
00186
00187
00188 IPAA_OBJECT_REF_SET (INT32 fcount) :
00189 _fcount (fcount),
00190 _dformals (fcount, Malloc_Mem_Pool),
00191 _iformals (fcount, Malloc_Mem_Pool),
00192 _data () {}
00193
00194
00195 IPAA_OBJECT_REF_SET (const IPAA_OBJECT_REF_SET& set) :
00196 _fcount (set._fcount),
00197 _data (set._data),
00198 _dformals (set._dformals, set._fcount, Malloc_Mem_Pool),
00199 _iformals (set._iformals, set._fcount, Malloc_Mem_Pool) {}
00200
00201
00202 ~IPAA_OBJECT_REF_SET () {
00203 _dformals.FBV_free (_fcount, Malloc_Mem_Pool);
00204 _iformals.FBV_free (_fcount, Malloc_Mem_Pool);
00205 }
00206
00207
00208 void Print ( FILE * ) const;
00209 void Trace ( void ) const;
00210
00211
00212
00213
00214 void Add_elmt ( INT32 elmt )
00215 { _data.Set ( elmt ); }
00216 void Add_direct_formal_elmt ( INT32 elmt )
00217 { _dformals.Add_element ( _fcount, elmt ); }
00218 void Add_indirect_formal_elmt ( INT32 elmt )
00219 { _iformals.Add_element ( _fcount, elmt ); }
00220
00221
00222 BOOL Is_elmt ( INT32 elmt ) const
00223 { return _data.Is_Set ( elmt ); }
00224 BOOL Is_direct_formal_elmt ( INT32 elmt )
00225 { return _dformals.Is_element ( _fcount, elmt ); }
00226 BOOL Is_indirect_formal_elmt ( INT32 elmt )
00227 { return _iformals.Is_element ( _fcount, elmt ); }
00228
00229
00230
00231
00232
00233
00234 void Union_2 ( const IPAA_OBJECT_REF_SET *set ) {
00235 _data.Union_2 (set->_data);
00236 }
00237
00238
00239
00240 BOOL Union_2_diff ( const IPAA_OBJECT_REF_SET *sbv ) {
00241 return _data.Union_2_diff (sbv->_data);
00242 }
00243 };
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 class IPAA_FORMAL_MAP;
00254
00255 class IPAA_NODE_INFO
00256 {
00257 private:
00258 IPAA_OBJECT_REF_SET *_eref;
00259 IPAA_OBJECT_REF_SET *_def;
00260 IPAA_OBJECT_REF_SET *_kill;
00261 IPAA_FORMAL_MAP **_fmap;
00262 mINT32 _pu_info;
00263 mINT32 _seq_id;
00264 mINT32 _fcount;
00265 mINT16 _changed_iter;
00266 mINT16 _flags;
00267
00268
00269 typedef enum {
00270 INITIALIZED = 0x01,
00271 BACK_EDGE = 0x02,
00272 DEPENDS_ON_BACK_EDGE = 0x04,
00273 INDIRECT_EDGE = 0x08,
00274 PASS_FORMALS_BYVAL = 0x10,
00275 PASS_GLOBALS_BYREF = 0x20,
00276 UNKNOWN_CALL_EFFECTS = 0x40,
00277
00278 VISITED = 0x80,
00279 LOCAL_ADDR_TAKEN_MOD = 0x100,
00280 FULL_MASK = 0x1ff,
00281 } FLAG_MASK;
00282
00283 public:
00284
00285 IPAA_NODE_INFO ( INT32 formal_count ) {
00286 BZERO ( this, sizeof(IPAA_NODE_INFO) );
00287 _fcount = formal_count;
00288 }
00289
00290
00291
00292
00293
00294 IPAA_NODE_INFO (const IPAA_NODE_INFO& node_info) :
00295 _fmap (NULL),
00296 _pu_info (-1),
00297 _seq_id (-1),
00298 _fcount (node_info._fcount),
00299 _changed_iter (-1),
00300 _flags (node_info._flags) {
00301
00302 if (node_info._eref) {
00303 _eref = CXX_NEW (IPAA_OBJECT_REF_SET (*node_info._eref),
00304 Malloc_Mem_Pool);
00305 }
00306 if (node_info._def) {
00307 _def = CXX_NEW (IPAA_OBJECT_REF_SET (*node_info._def),
00308 Malloc_Mem_Pool);
00309 }
00310 if (node_info._kill) {
00311 _kill = CXX_NEW (IPAA_OBJECT_REF_SET (*node_info._kill),
00312 Malloc_Mem_Pool);
00313 }
00314 }
00315
00316 void Free_Ref_Sets () {
00317 if (_eref) CXX_DELETE (_eref, Malloc_Mem_Pool);
00318 if (_def) CXX_DELETE (_def, Malloc_Mem_Pool);
00319 if (_kill) CXX_DELETE (_kill, Malloc_Mem_Pool);
00320 }
00321
00322
00323 void Print ( FILE *, const char *pfx = NULL ) const;
00324 void Trace ( const char *pfx = NULL ) const;
00325
00326
00327 IPAA_FORMAL_MAP **Get_fmap() const { return _fmap; }
00328 void Set_fmap ( IPAA_FORMAL_MAP **f ) { _fmap = f; }
00329 IPAA_FORMAL_MAP *Get_fmap ( INT32 i ) const {
00330 return (_fmap == NULL) ? NULL : _fmap[i];
00331 }
00332 void Set_fmap ( INT32 i, IPAA_FORMAL_MAP *f ) { _fmap[i] = f; }
00333 INT32 Get_pu_info() const { return _pu_info; }
00334 void Set_pu_info ( INT32 cnt ) { _pu_info = cnt; }
00335 INT32 Get_seq_id() const { return _seq_id; }
00336 void Set_seq_id ( INT32 seq ) { _seq_id = seq; }
00337 INT32 Get_fcount() const { return _fcount; }
00338 void Set_fcount ( INT32 cnt ) { _fcount = cnt; }
00339 INT32 Get_changed_iter() const { return _changed_iter; }
00340 void Set_changed_iter ( INT32 i ) { _changed_iter = i; }
00341
00342
00343 BOOL Is_initialized() const { return _flags & INITIALIZED; }
00344 void Set_initialized () { _flags |= INITIALIZED; }
00345 BOOL Has_back_edge() const { return _flags & BACK_EDGE; }
00346 void Set_has_back_edge () { _flags |= BACK_EDGE; }
00347 BOOL Depends_on_back_edge() const {
00348 return _flags & DEPENDS_ON_BACK_EDGE;
00349 }
00350 void Set_depends_on_back_edge () { _flags |= DEPENDS_ON_BACK_EDGE; }
00351 BOOL Has_indirect_edge() const { return _flags & INDIRECT_EDGE; }
00352 void Set_has_indirect_edge () { _flags |= INDIRECT_EDGE; }
00353 BOOL Passes_formals_by_value() const {
00354 return _flags & PASS_FORMALS_BYVAL;
00355 }
00356 void Set_passes_formals_by_value () { _flags |= PASS_FORMALS_BYVAL; }
00357 BOOL Passes_globals_by_reference() const {
00358 return _flags & PASS_GLOBALS_BYREF;
00359 }
00360 void Set_passes_globals_by_reference () { _flags |= PASS_GLOBALS_BYREF; }
00361 BOOL Has_unknown_call_effects() const {
00362 return _flags & UNKNOWN_CALL_EFFECTS;
00363 }
00364 void Set_has_unknown_call_effects () { _flags |= UNKNOWN_CALL_EFFECTS; }
00365 BOOL Is_visited() const { return _flags & VISITED; }
00366 void Set_visited () { _flags |= VISITED; }
00367 BOOL Local_addr_taken_mods() const {
00368 return _flags & LOCAL_ADDR_TAKEN_MOD;
00369 }
00370 void Set_local_addr_taken_mods () { _flags |= LOCAL_ADDR_TAKEN_MOD; }
00371
00372
00373 void Compress ( MEM_POOL *pool ) const;
00374
00375
00376 void New_eref_set ( INT32 fsize );
00377 void New_def_set ( INT32 fsize );
00378 void New_kill_set ( INT32 fsize );
00379
00380
00381 IPAA_OBJECT_REF_SET * Get_eref_set() const { return _eref;};
00382 IPAA_OBJECT_REF_SET * Get_def_set() const { return _def;};
00383 IPAA_OBJECT_REF_SET * Get_kill_set() const { return _kill;};
00384
00385
00386 void Add_eref_elmt( INT32 g ) { Get_eref_set()->Add_elmt(g); };
00387 void Add_def_elmt( INT32 g ) { Get_def_set ()->Add_elmt(g); };
00388 void Add_kill_elmt( INT32 g ) { Get_kill_set()->Add_elmt(g); };
00389
00390
00391 void Add_formal_dref_elmt( INT32 f )
00392 { Get_eref_set()->Add_direct_formal_elmt(f); };
00393 void Add_formal_iref_elmt( INT32 f )
00394 { Get_eref_set()->Add_indirect_formal_elmt(f); };
00395 void Add_formal_dmod_elmt ( INT32 f )
00396 { Get_def_set ()->Add_direct_formal_elmt(f); };
00397 void Add_formal_imod_elmt ( INT32 f )
00398 { Get_def_set ()->Add_indirect_formal_elmt(f); };
00399 void Add_formal_dkill_elmt( INT32 f )
00400 { Get_kill_set()->Add_direct_formal_elmt(f); };
00401 void Add_formal_ikill_elmt( INT32 f )
00402 { Get_kill_set()->Add_indirect_formal_elmt(f); };
00403
00404
00405 BOOL Is_eref_elmt( INT32 g ) const
00406 { return Get_eref_set()->Is_elmt(g); };
00407 BOOL Is_def_elmt( INT32 g ) const
00408 { return Get_def_set ()->Is_elmt(g); };
00409 BOOL Is_kill_elmt( INT32 g ) const
00410 { return Get_kill_set()->Is_elmt(g); };
00411
00412
00413 BOOL Is_formal_dref_elmt ( INT32 f ) const
00414 { return Get_eref_set()->Is_direct_formal_elmt(f); };
00415 BOOL Is_formal_iref_elmt ( INT32 f ) const
00416 { return Get_eref_set()->Is_indirect_formal_elmt(f); };
00417 BOOL Is_formal_dmod_elmt ( INT32 f ) const
00418 { return Get_def_set ()->Is_direct_formal_elmt(f); };
00419 BOOL Is_formal_imod_elmt ( INT32 f ) const
00420 { return Get_def_set ()->Is_indirect_formal_elmt(f); };
00421 BOOL Is_formal_dkill_elmt( INT32 f ) const
00422 { return Get_kill_set()->Is_direct_formal_elmt(f); };
00423 BOOL Is_formal_ikill_elmt( INT32 f ) const
00424 { return Get_kill_set()->Is_indirect_formal_elmt(f); };
00425
00426
00427 BOOL Is_actual_in_map ( INT32 f, UINT32 glob ) const;
00428 };
00429
00430
00431
00432
00433
00434
00435
00436 class IPAA
00437 {
00438 private:
00439 MEM_POOL *_m;
00440 IPA_CALL_GRAPH *_cg;
00441 IPAA_SUMMARY *_summary;
00442
00443
00444 INT32 Emit_name ( const char *name );
00445 INT32 Emit_global_name ( INT32 merged_id );
00446 INT32 Emit_pu_name ( const char *name );
00447
00448
00449 INT32 Emit_global ( INT32 merged_id, BOOL reuse_ok );
00450
00451
00452 void Emit_IPAA_node ( const IPA_NODE &node );
00453
00454
00455 void Emit_IPAA_callsites ( IPA_NODE &node );
00456
00457 public:
00458 IPAA ( MEM_POOL *m );
00459
00460 void Set_IPAA_Mem_Pool ( MEM_POOL *pool ) { _m = pool; };
00461 MEM_POOL * Get_IPAA_Mem_Pool ( void ) const { return _m; };
00462 IPA_CALL_GRAPH * Get_cg ( void ) const { return _cg; }
00463
00464 void Do_Simple_IPAA ( IPA_CALL_GRAPH &cg );
00465
00466 void Emit_Simple_IPAA ( IPA_CALL_GRAPH &cg );
00467 };
00468
00469
00470 extern IPAA_OBJECT_REF_SET* icall_eref;
00471 extern IPAA_OBJECT_REF_SET *icall_def;
00472 extern IPAA_OBJECT_REF_SET *icall_kill;
00473
00474 #endif