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
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 #ifdef _KEEP_RCS_ID
00142 static const char source_file[] = __FILE__;
00143 static const char rcs_id[] = "";
00144 #endif
00145
00146 #include <alloca.h>
00147 #include "defs.h"
00148 #include "resource.h"
00149 #include "config.h"
00150 #include "errors.h"
00151 #include "mempool.h"
00152 #include "cg.h"
00153 #include "cgir.h"
00154 #include "tracing.h"
00155 #include "cgtarget.h"
00156 #include "cgprep.h"
00157 #include "op.h"
00158 #include "op_list.h"
00159 #include "op_map.h"
00160 #include "bb.h"
00161 #include "register.h"
00162 #include "bbregs.h"
00163 #include "cg_loop.h"
00164 #include "cgexp.h"
00165 #include "annotations.h"
00166 #include "gtn_universe.h"
00167 #include "gtn_set.h"
00168 #include "cg_cflow.h"
00169 #include "whirl2ops.h"
00170 #include "cg_db_op.h"
00171 #include "cio.h"
00172 #include "cio_rwtran.h"
00173 #include "gra_live.h"
00174 #include "data_layout.h"
00175
00176 #include <vector>
00177 #include <map>
00178 #include "cxx_memory.h"
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 BOOL CIO_enable_copy_removal = TRUE;
00200 BOOL CIO_enable_read_removal = TRUE;
00201 BOOL CIO_enable_write_removal = TRUE;
00202 BOOL CIO_enable_cse_removal = TRUE;
00203 INT32 CIO_rw_max_omega = 8;
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 typedef std::pair< OP *, UINT8 > OP_OMEGA;
00317
00318 struct OP_OMEGA_less_prolog
00319 {
00320 bool operator()( const OP_OMEGA& s1, const OP_OMEGA& s2 ) const {
00321 if ( s1.second < s2.second ) return true;
00322 if ( s1.second > s2.second ) return false;
00323 return OP_Precedes( s1.first, s2.first );
00324 }
00325 };
00326
00327 struct OP_OMEGA_less_epilog
00328 {
00329 bool operator()( const OP_OMEGA& s1, const OP_OMEGA& s2 ) const {
00330 if ( s1.second > s2.second ) return true;
00331 if ( s1.second < s2.second ) return false;
00332 return OP_Precedes( s1.first, s2.first );
00333 }
00334 };
00335
00336
00337 struct CICSE_entry;
00338 struct CICSE_change;
00339
00340
00341 class CIO_RWTRAN {
00342 private:
00343
00344
00345
00346
00347 MEM_POOL *_loc_mem_pool;
00348
00349
00350
00351 const BOOL _trace_CG_DupTN;
00352 const BOOL _trace_CG_RTran;
00353 const BOOL _trace_CG_Chkpnt;
00354
00355
00356
00357
00358
00359 TN *_trip_count_tn;
00360
00361
00362
00363
00364
00365 BOOL CIO_Copy_Remove( BB *body );
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 typedef std::pair< const OP_OMEGA, OP * > op_copy_pair;
00384 #if defined(BUILD_OS_DARWIN)
00385
00386 typedef std::map< OP_OMEGA, OP *, OP_OMEGA_less_prolog
00387 > op_copy_map_prolog;
00388 typedef std::map< OP_OMEGA, OP *, OP_OMEGA_less_epilog
00389 > op_copy_map_epilog;
00390 #else
00391 typedef std::map< OP_OMEGA, OP *, OP_OMEGA_less_prolog,
00392 mempool_allocator< op_copy_pair > > op_copy_map_prolog;
00393 typedef std::map< OP_OMEGA, OP *, OP_OMEGA_less_epilog,
00394 mempool_allocator< op_copy_pair > > op_copy_map_epilog;
00395 #endif
00396
00397 op_copy_map_prolog _op_prolog_map;
00398 op_copy_map_epilog _op_epilog_map;
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 OP * Mark_Op_For_Prolog( OP *op, const UINT8 omega );
00418 BOOL Backpatch_Op_In_Prolog( OP *op, TN *new_tns[],
00419 const UINT8 start_omega,
00420 const UINT8 end_omega );
00421 void Copy_Ops_To_Prolog();
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 void Generate_Black_Holes();
00436 BOOL Safe_Offset( INT64 offset, OP *op );
00437
00438
00439
00440
00441
00442 void Predicate_Write( OPS *ops, OP *op, TN *tn_predicate );
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 OP * Mark_Op_For_Epilog( OP *op, const UINT8 omega );
00461 BOOL Backpatch_Op_In_Epilog( OP *op, const UINT8 start_omega );
00462 void Copy_Ops_To_Epilog();
00463
00464
00465
00466
00467
00468 BOOL Read_CICSE_Candidate_Op( OP *op );
00469 BOOL Write_Candidate_Op( OP *op );
00470 BOOL Read_Candidate_Arc( ARC *arc );
00471 BOOL Write_Candidate_Arc( ARC *arc );
00472
00473
00474
00475
00476
00477 void Trace_CICSE_Entries( CICSE_entry *table, INT count,
00478 const char *message );
00479 void Trace_CICSE_Changes( CICSE_change *table, INT count,
00480 const char *message );
00481 INT CICSE_Lookup_Op( CICSE_entry *cicse_table, INT op_count, OP *op );
00482 void Replace_Tn( BB *body, TN *tn_old, TN *tn_new, UINT8 omega_change );
00483 OP * Append_TN_Copy( TN *tn_dest, TN *tn_from, OP *point, UINT8 omega );
00484 BOOL CICSE_Transform( BB *body );
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 INT _ordering_count;
00504 OP **_op_ordering;
00505 ARC **_arc_ordering;
00506
00507
00508
00509
00510 void Print_Ops( const char *Msg );
00511 void Print_Arcs( const char *Msg );
00512
00513
00514
00515
00516 void Sort_Ops_Preorder( OP *currentOP, BOOL current_has_arc );
00517 void Sort_Ops( BB *body );
00518 void Sort_Arcs( void );
00519
00520
00521
00522
00523 void Transform_Arcs( BB *body );
00524
00525 BOOL Write_Removal( BB *body );
00526
00527
00528
00529
00530 CIO_RWTRAN( void );
00531 CIO_RWTRAN( const CIO_RWTRAN & );
00532 CIO_RWTRAN & operator=( const CIO_RWTRAN & );
00533
00534 public:
00535
00536
00537
00538 CIO_RWTRAN( LOOP_DESCR *loop, MEM_POOL *mem_pool )
00539 : _loc_mem_pool( mem_pool ),
00540 _trace_CG_DupTN( Get_Trace( TP_CGLOOP, 0x100,
00541 LOOP_DESCR_loophead( loop ) ) ),
00542 _trace_CG_RTran( Get_Trace( TP_CGLOOP, 0x200,
00543 LOOP_DESCR_loophead( loop ) ) ),
00544 _trace_CG_Chkpnt( Get_Trace( TP_CGLOOP, 0x400,
00545 LOOP_DESCR_loophead( loop ) ) ),
00546 _trip_count_tn( CG_LOOP_Trip_Count( loop ) ),
00547 _ordering_count( 0 ),
00548 _op_ordering( NULL ),
00549 _arc_ordering( NULL ) {}
00550
00551 ~CIO_RWTRAN( void ) {}
00552
00553
00554
00555
00556
00557 BOOL Read_CICSE_Write_Removal( LOOP_DESCR *loop );
00558 };
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 struct CIO_copy {
00576 TN *tn_result;
00577 OP *op;
00578 };
00579
00580
00581 BOOL
00582 CIO_RWTRAN::CIO_Copy_Remove( BB *body )
00583 {
00584
00585
00586
00587
00588
00589 INT eligible_OP_count = 0;
00590 OP *op;
00591 FOR_ALL_BB_OPs_FWD( body, op ) {
00592
00593
00594 if ( OP_copy( op ) &&
00595 ( ! OP_has_predicate( op ) ||
00596 TN_is_true_pred( OP_opnd( op, OP_PREDICATE_OPND ) ) ) &&
00597 OP_omega( op, OP_COPY_OPND ) > 0 ) {
00598 Set_OP_flag1( op );
00599 eligible_OP_count++;
00600
00601
00602
00603 Is_True( OP_results( op ) == 1,
00604 ( "CIO_RWTRAN::CIO_Copy_Remove copy OP has %d != 1"
00605 " result TNs", OP_results( op ) ) );
00606 } else {
00607 Reset_OP_flag1( op );
00608 }
00609 }
00610
00611
00612 if ( eligible_OP_count == 0 ) return FALSE;
00613
00614
00615
00616 BOOL predicated_OPs = FALSE;
00617
00618
00619
00620
00621
00622
00623 CIO_copy *cio_copy_table = (CIO_copy *) CXX_NEW_ARRAY( CIO_copy,
00624 eligible_OP_count,
00625 _loc_mem_pool );
00626 INT cio_copy_table_size = 0;
00627
00628
00629
00630 FOR_ALL_BB_OPs_FWD( body, op ) {
00631 if ( OP_has_predicate( op ) &&
00632 ! TN_is_true_pred( OP_opnd( op, OP_PREDICATE_OPND ) ) )
00633 predicated_OPs = TRUE;
00634 else {
00635 for ( INT res = OP_results( op ) - 1; res >= 0; --res ) {
00636 TN *tn = OP_result( op, res );
00637 INT index;
00638 for ( index = cio_copy_table_size - 1; index >= 0; --index )
00639 if ( cio_copy_table[index].tn_result == tn ){
00640 #ifdef KEY
00641
00642
00643
00644 if( OP_cond_def( op ) ){
00645 Reset_OP_flag1( cio_copy_table[index].op );
00646 }
00647 #endif
00648 break;
00649 }
00650 if ( index < 0 && OP_flag1( op ) ) {
00651 index = cio_copy_table_size;
00652 cio_copy_table[index].tn_result = tn;
00653 cio_copy_table_size++;
00654 }
00655 if ( index >= 0 )
00656 cio_copy_table[index].op = op;
00657 }
00658 }
00659 }
00660 Is_True( cio_copy_table_size <= cio_copy_table_size,
00661 ( "CIO_RWTRAN::CIO_Copy_Remove cio_copy_table_size(%d)"
00662 " > eligible_OP_count(%d)",
00663 cio_copy_table_size, eligible_OP_count ) );
00664
00665
00666
00667
00668 if ( predicated_OPs ) {
00669 FOR_ALL_BB_OPs_FWD( body, op ) {
00670 BOOL predicated
00671 = ( OP_has_predicate( op ) &&
00672 ! TN_is_true_pred( OP_opnd( op, OP_PREDICATE_OPND ) ) );
00673 for ( INT res = OP_results( op ) - 1; res >= 0; --res ) {
00674 TN *tn = OP_result( op, res );
00675 for ( INT index = cio_copy_table_size - 1; index >= 0; --index )
00676 if ( cio_copy_table[index].tn_result == tn ) {
00677 if ( predicated ) {
00678
00679 Reset_OP_flag1( cio_copy_table[index].op );
00680 } else {
00681
00682 cio_copy_table[index].op = op;
00683 }
00684 break;
00685 }
00686 }
00687 }
00688 }
00689
00690
00691
00692
00693
00694
00695
00696
00697 INT index;
00698 for ( index = cio_copy_table_size - 1; index >= 0; --index ) {
00699 OP *op = cio_copy_table[index].op;
00700 if ( ! OP_flag1( op ) ) continue;
00701
00702 TN *tn_old = OP_result( op, 0 );
00703 TN *tn_new = OP_opnd( op, OP_COPY_OPND );
00704 UINT8 omega_change = OP_omega( op, OP_COPY_OPND );
00705
00706
00707 CG_LOOP_BACKPATCH *bp;
00708 for ( bp = CG_LOOP_Backpatch_First( CG_LOOP_prolog, tn_old );
00709 bp != NULL; bp = CG_LOOP_Backpatch_Next( bp ) ) {
00710 UINT8 omega = CG_LOOP_BACKPATCH_omega( bp ) + omega_change;
00711 if ( CG_LOOP_Backpatch_Find_Non_Body_TN( CG_LOOP_prolog,
00712 tn_new, omega ) ) {
00713
00714 Reset_OP_flag1( op );
00715 DevWarn( "CIO_RWTRAN::CIO_Copy_Remove prolog backpatch conflict"
00716 " prevent copy removal of TN%d <-- TN%d[%d], when omega"
00717 " == %d", TN_number( tn_old ), TN_number( tn_new ),
00718 omega_change, omega );
00719 break;
00720 }
00721 }
00722 }
00723
00724
00725
00726
00727
00728
00729
00730 FOR_ALL_BB_OPs_FWD( body, op ) {
00731
00732
00733 for ( INT opnd = OP_opnds( op ) - 1; opnd >= 0; --opnd ) {
00734 TN *tn = OP_opnd( op, opnd );
00735 if ( TN_is_register( tn ) && OP_omega( op, opnd ) == 0 )
00736 for ( INT index = cio_copy_table_size - 1; index >= 0; --index )
00737 if ( cio_copy_table[index].tn_result == tn ) {
00738 OP *op_src = cio_copy_table[index].op;
00739 if ( OP_flag1( op_src ) ) {
00740 #ifdef KEY
00741
00742
00743
00744 TN *copy_src_opnd = OP_opnd( op_src, OP_COPY_OPND );
00745 if ( TN_is_dedicated( copy_src_opnd ) ) {
00746 Reset_OP_flag1( op_src );
00747 break;
00748 }
00749 #endif
00750 Set_OP_opnd( op, opnd, OP_opnd( op_src, OP_COPY_OPND ) );
00751 Set_OP_omega( op, opnd, OP_omega( op, opnd )
00752 + OP_omega( op_src, OP_COPY_OPND ) );
00753 }
00754 break;
00755 }
00756 }
00757
00758
00759 if (! OP_has_predicate( op ) ||
00760 TN_is_true_pred( OP_opnd( op, OP_PREDICATE_OPND ) ) )
00761 for ( INT res = OP_results( op ) - 1; res >= 0; --res ) {
00762 TN *tn = OP_result( op, res );
00763 for ( INT index = cio_copy_table_size - 1; index >= 0; --index )
00764 if ( cio_copy_table[index].tn_result == tn ) {
00765 cio_copy_table[index].op = op;
00766 break;
00767 }
00768 }
00769 }
00770
00771
00772
00773
00774 for ( index = cio_copy_table_size - 1; index >= 0; --index ) {
00775 OP *op = cio_copy_table[index].op;
00776 if ( ! OP_flag1( op ) ) continue;
00777
00778
00779 if ( OP_omega( op, OP_COPY_OPND ) > 0 ) {
00780 TN *tn = OP_opnd( op, OP_COPY_OPND );
00781 for ( INT index = cio_copy_table_size - 1; index >= 0; --index )
00782 if ( cio_copy_table[index].tn_result == tn ) {
00783 OP *op_src = cio_copy_table[index].op;
00784 if ( ! OP_flag1( op_src ) )
00785 break;
00786 #ifdef KEY
00787
00788 if (OP_opnd(op_src, OP_COPY_OPND) == tn)
00789 break;
00790 #endif
00791 tn = OP_opnd( op_src, OP_COPY_OPND );
00792 Set_OP_opnd( op, OP_COPY_OPND, tn );
00793 Set_OP_omega( op, OP_COPY_OPND, OP_omega( op, OP_COPY_OPND )
00794 + OP_omega( op_src, OP_COPY_OPND ) );
00795
00796 index = cio_copy_table_size;
00797 Is_True( OP_omega( op, OP_COPY_OPND ) < MAX_OMEGA,
00798 ( "CIO_RWTRAN::CIO_Copy_Remove overflowed MAX_OMEGA;"
00799 " infinite loop?" ) );
00800 }
00801 }
00802 }
00803
00804
00805
00806 FOR_ALL_BB_OPs_FWD( body, op ) {
00807
00808
00809 for ( INT opnd = OP_opnds( op ) - 1; opnd >= 0; --opnd )
00810 if ( OP_omega( op, opnd ) > 0 ) {
00811 TN *tn = OP_opnd( op, opnd );
00812 for ( INT index = cio_copy_table_size - 1; index >= 0; --index )
00813 if ( cio_copy_table[index].tn_result == tn ) {
00814 OP *op_src = cio_copy_table[index].op;
00815 if ( OP_flag1( op_src )
00816 #ifdef KEY
00817
00818
00819
00820
00821
00822 && ( OP_result(op_src,0) != OP_opnd(op_src,0) )
00823 #endif
00824 ) {
00825 Set_OP_opnd( op, opnd, OP_opnd( op_src, OP_COPY_OPND ) );
00826 Set_OP_omega( op, opnd, OP_omega( op, opnd )
00827 + OP_omega( op_src, OP_COPY_OPND ) );
00828 }
00829 break;
00830 }
00831 }
00832 }
00833
00834
00835
00836 for ( index = cio_copy_table_size - 1; index >= 0; --index ) {
00837 OP *op = cio_copy_table[index].op;
00838 if ( ! OP_flag1( op ) ) continue;
00839
00840
00841 TN *tn_old = cio_copy_table[index].tn_result;
00842 TN *tn_new = OP_opnd( op, OP_COPY_OPND );
00843
00844 #ifdef KEY
00845
00846
00847
00848
00849
00850
00851
00852 if( tn_old == tn_new ){
00853 continue;
00854 }
00855 #endif // KEY
00856
00857 UINT8 omega_change = OP_omega( op, OP_COPY_OPND );
00858 CG_LOOP_Backpatch_Replace_Body_TN( CG_LOOP_epilog,
00859 tn_old, tn_new, omega_change );
00860 CG_LOOP_Backpatch_Replace_Body_TN( CG_LOOP_prolog,
00861 tn_old, tn_new, omega_change );
00862 }
00863
00864
00865 BOOL change = FALSE;
00866 OP *next_op;
00867 for ( op = BB_first_op( body ); op != NULL; op = next_op ) {
00868 next_op = OP_next( op );
00869 if ( ! OP_flag1( op ) ) continue;
00870
00871
00872 if ( _trace_CG_RTran ) {
00873 #pragma mips_frequency_hint NEVER
00874 fprintf( TFile, "CIO_RWTRAN::CIO_Copy_Remove removes:\n\t" );
00875 Print_OP_No_SrcLine( op );
00876 }
00877 BB_Remove_Op( body, op );
00878 change = TRUE;
00879 }
00880
00881 return change;
00882 }
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896 static inline INT OP_lookup_opnd( const OP *op, const TN *tn )
00897 {
00898 for ( INT opnd = OP_opnds( op ) - 1; opnd >= 0; --opnd )
00899 if ( OP_opnd( op, opnd ) == tn )
00900 return opnd;
00901 FmtAssert( FALSE, ( "OP_lookup_opnd failed to find operand" ) );
00902
00903 }
00904
00905
00906 static inline INT OP_lookup_result( const OP *op, const TN *tn )
00907 {
00908 for ( INT res = OP_results( op ) - 1; res >= 0; --res )
00909 if ( OP_result( op, res ) == tn )
00910 return res;
00911 FmtAssert( FALSE, ( "OP_lookup_result failed to find result" ) );
00912
00913 }
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937 OP *
00938 CIO_RWTRAN::Mark_Op_For_Prolog( OP *op, const UINT8 omega )
00939 {
00940
00941 op_copy_map_prolog::iterator
00942 op_find = _op_prolog_map.find( OP_OMEGA( op, omega ) );
00943 if ( op_find != _op_prolog_map.end() )
00944 return op_find->second;
00945
00946
00947 if ( OP_has_implicit_interactions( op ) )
00948 return NULL;
00949
00950 #ifdef TARG_X8664
00951
00952
00953
00954
00955 if (OP_reads_rflags(op))
00956 return NULL;
00957 #endif
00958
00959
00960 OP *op_prolog = Dup_OP( op );
00961 #ifdef KEY
00962 CG_LOOP_Init_Op(op_prolog);
00963 Copy_WN_For_Memory_OP( op_prolog, op );
00964 #endif
00965 if ( Is_DB_OP_Init( op ) )
00966 DB_Copy_Aux_OP( op_prolog, op );
00967
00968
00969 ARC_LIST *arcs = ARC_LIST_Find( OP_preds( op ), CG_DEP_REGIN, DONT_CARE );
00970 while ( arcs ) {
00971 ARC *arc = ARC_LIST_first( arcs );
00972 if ( omega > ARC_omega( arc ) ) {
00973 OP *op_new = Mark_Op_For_Prolog( ARC_pred( arc ),
00974 omega - ARC_omega( arc ) );
00975 if ( op_new == NULL )
00976 return NULL;
00977 TN *tn_old = OP_opnd( op, ARC_opnd( arc ) );
00978 TN *tn_new = OP_result( op_new,
00979 OP_lookup_result( ARC_pred( arc ), tn_old ) );
00980 Set_OP_opnd( op_prolog, ARC_opnd( arc ), tn_new );
00981 }
00982 arcs = ARC_LIST_Find( ARC_LIST_rest( arcs ), CG_DEP_REGIN, DONT_CARE );
00983 }
00984
00985 if ( OP_cond_def( op ) ) {
00986
00987
00988
00989
00990 UINT8 res;
00991 TN **result = (TN **) alloca( OP_results( op ) * sizeof( TN * ) );
00992 for ( res = 0; res < OP_results( op ); ++res )
00993 result[res] = NULL;
00994
00995 ARC_LIST *arcs = ARC_LIST_Find( OP_preds( op ), CG_DEP_REGOUT, DONT_CARE );
00996 while ( arcs ) {
00997 ARC *arc = ARC_LIST_first( arcs );
00998 if ( omega > ARC_omega( arc ) ) {
00999 OP *op_old = ARC_pred( arc );
01000 OP *op_new = Mark_Op_For_Prolog( ARC_pred( arc ),
01001 omega - ARC_omega( arc ) );
01002 if ( op_new == NULL )
01003 return NULL;
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027 UINT8 count = 0;
01028 for ( UINT8 i = 0; i < OP_results( op ); ++i )
01029 for ( UINT8 j = 0; j < OP_results( op_old ); ++j )
01030 if ( OP_result( op, i ) == OP_result( op_old, j ) ) {
01031 ++count;
01032 TN *tn_new = OP_result( op_new, j );
01033 Is_True(j < OP_results(op), ("result index too large"));
01034 result[j] = tn_new;
01035 }
01036 if ( count != 1 ) {
01037 Is_True( FALSE, ( "CIO_RWTRAN::Mark_Op_For_Prolog found"
01038 " count %u != 1", count ) );
01039 return NULL;
01040 }
01041 }
01042 arcs = ARC_LIST_Find( ARC_LIST_rest( arcs ), CG_DEP_REGOUT, DONT_CARE );
01043 }
01044
01045 for ( res = 0; res < OP_results( op ); ++res ) {
01046 TN *tn_new = result[res];
01047 if ( tn_new == NULL ) {
01048
01049
01050 TN *tn_old = OP_result( op, res );
01051 tn_new = CGPREP_Dup_TN( tn_old );
01052 CGPREP_Copy_TN_Into_BB( tn_new, tn_old, CG_LOOP_prolog,
01053 NULL, 0, FALSE );
01054 }
01055 Set_OP_result( op_prolog, res, tn_new );
01056 }
01057
01058 } else {
01059
01060
01061
01062 for ( UINT8 i = 0; i < OP_results( op ); ++i ) {
01063 Set_OP_result( op_prolog, i, CGPREP_Dup_TN( OP_result( op, i ) ) );
01064 }
01065 }
01066
01067
01068 if ( _trace_CG_RTran ) {
01069 #pragma mips_frequency_hint NEVER
01070 fprintf( TFile,
01071 "<cio> Mark_Op_For_Prolog(op 0x%p, omega %u) ---> op 0x%p\n\t",
01072 op, omega, op_prolog );
01073 Print_OP_No_SrcLine( op );
01074 fprintf( TFile, "\t" );
01075 Print_OP_No_SrcLine( op_prolog );
01076 }
01077 _op_prolog_map[ OP_OMEGA( op, omega ) ] = op_prolog;
01078 return op_prolog;
01079 }
01080
01081
01082 void
01083 CIO_RWTRAN::Copy_Ops_To_Prolog()
01084 {
01085 if ( _trace_CG_RTran ) {
01086 #pragma mips_frequency_hint NEVER
01087 fprintf( TFile, "\n<cio> Copy_Ops_To_Prolog copying:\n" );
01088 }
01089
01090
01091
01092 for ( op_copy_map_prolog::const_iterator op_iter = _op_prolog_map.begin();
01093 op_iter != _op_prolog_map.end();
01094 ++op_iter ) {
01095
01096
01097 BB_Insert_Op( CG_LOOP_prolog, NULL, op_iter->second, FALSE );
01098 if ( _trace_CG_RTran ) {
01099 #pragma mips_frequency_hint NEVER
01100 fprintf( TFile, "(op 0x%p, omega %u) ---> op 0x%p\n\t",
01101 op_iter->first.first, op_iter->first.second, op_iter->second );
01102 Print_OP_No_SrcLine( op_iter->second );
01103 }
01104 }
01105
01106 if ( _trace_CG_RTran ) {
01107 #pragma mips_frequency_hint NEVER
01108 fprintf( TFile, "\n" );
01109 }
01110 _op_prolog_map.clear();
01111 }
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143 #if 0 // Would prefer to use preceding algorithms
01144
01145
01146 OP *
01147 CIO_RWTRAN::Mark_Op_For_Prolog( const OP *op, const UINT8 omega )
01148 {
01149
01150
01151
01152
01153
01154
01155
01156 op_copy_map_prolog::iterator
01157 copy_find = _op_prolog_map.find( OP_OMEGA( op, omega ) );
01158 if ( copy_find != _op_prolog_map.end() )
01159 return copy_find->second;
01160
01161
01162 if ( OP_has_implicit_interactions( op ) )
01163 return NULL;
01164
01165
01166 ARC_LIST *arcs = ARC_LIST_Find( OP_preds( op ), CG_DEP_REGIN, DONT_CARE );
01167 while ( arcs ) {
01168 ARC *arc = ARC_LIST_first( arcs );
01169 if ( omega >= ARC_omega( arc ) ) {
01170 OP *op_new = Mark_Op_For_Prolog( ARC_pred( arc ),
01171 omega - ARC_omega( arc ) );
01172 if ( op_new == NULL )
01173 return NULL;
01174 }
01175 arcs = ARC_LIST_Find( ARC_LIST_rest( arcs ), CG_DEP_REGIN, DONT_CARE );
01176 }
01177
01178
01179
01180 if ( OP_cond_def( op ) ) {
01181 ARC_LIST *arcs = ARC_LIST_Find( OP_preds( op ), CG_DEP_REGOUT, DONT_CARE );
01182 while ( arcs ) {
01183 ARC *arc = ARC_LIST_first( arcs );
01184 if ( omega >= ARC_omega( arc ) ) {
01185 OP *op_new = Mark_Op_For_Prolog( ARC_pred( arc ),
01186 omega - ARC_omega( arc ) );
01187 if ( op_new == NULL )
01188 return NULL;
01189 }
01190 arcs = ARC_LIST_Find( ARC_LIST_rest( arcs ), CG_DEP_REGOUT, DONT_CARE );
01191 }
01192 }
01193
01194
01195 OP *op_prolog = Dup_OP( op );
01196 if ( Is_DB_OP_Init( op ) )
01197 DB_Copy_Aux_OP( op_prolog, op );
01198
01199
01200 if ( _trace_CG_RTran ) {
01201 #pragma mips_frequency_hint NEVER
01202 fprintf( TFile,
01203 "<cio> Mark_Op_For_Prolog(op 0x%lx, omega %u) ---> op 0x%lx\n\t",
01204 op, omega, op_prolog );
01205 Print_OP_No_SrcLine( op );
01206 fprintf( TFile, "\t" );
01207 Print_OP_No_SrcLine( op_prolog );
01208 }
01209 _op_prolog_map[ OP_OMEGA( op, omega ) ] = op_prolog;
01210 return op_prolog;
01211 }
01212
01213
01214 void
01215 CIO_RWTRAN::Copy_Ops_To_Prolog()
01216 {
01217 if ( _trace_CG_RTran ) {
01218 #pragma mips_frequency_hint NEVER
01219 fprintf( TFile, "<cio> Copy_Ops_To_Prolog copying:\n" );
01220 }
01221
01222 typedef std::pair< TN *, UINT8 > TN_OMEGA;
01223 typedef std::pair< TN_OMEGA, TN * > tn_copy_pair;
01224 typedef std:map< TN_OMEGA, TN *, less< TN_OMEGA >,
01225 mempool_allocator< tn_copy_pair > > tn_copy_map;
01226
01227 tn_copy_map tn_prolog_map;
01228
01229
01230
01231 for ( op_copy_map_prolog::const_iterator op_iter = _op_prolog_map.begin();
01232 op_iter != _op_prolog_map.end();
01233 ++op_iter ) {
01234
01235 UINT8 omega = op_iter->first.second;
01236 OP *op = op_iter->second;
01237
01238
01239 for ( UINT8 i = 0; i < OP_opnds( op ); ++i ) {
01240 TN *tn_old = OP_opnd( op, i );
01241 if ( ! TN_is_register( tn_old ) ) continue;
01242
01243
01244 UINT8 tn_om = omega - OP_OMEGA( op, i );
01245 tn_copy_map::iterator
01246 tn_find = tn_prolog_map.find( TN_OMEGA( tn_old, tn_om ) );
01247 while ( tn_find == tn_prolog_map.end() && tn_om > 0 ) {
01248 --tn_om;
01249 tn_find = tn_prolog_map.find( TN_OMEGA( tn_old, tn_om ) );
01250 }
01251
01252
01253 if ( tn_find != tn_prolog_map.end() )
01254 Set_OP_opnd( op, i, tn_find->second );
01255 }
01256
01257
01258 if ( OP_cond_def( op ) ) {
01259
01260
01261 for ( UINT8 i = 0; i < OP_results( op ); ++i ) {
01262 TN *tn_old = OP_result( op, i );
01263 UINT8 tn_om = omega;
01264
01265
01266 tn_copy_map::iterator
01267 tn_find = tn_prolog_map.find( TN_OMEGA( tn_old, tn_om ) );
01268 while ( tn_find == tn_prolog_map.end() && tn_om > 0 ) {
01269 --tn_om;
01270 tn_find = tn_prolog_map.find( TN_OMEGA( tn_old, tn_om ) );
01271 }
01272
01273
01274
01275 TN *tn_new;
01276 if ( tn_find != tn_prolog_map.end() )
01277 tn_new = tn_find->second;
01278 else {
01279 tn_new = CGPREP_Dup_TN( tn_old );
01280 CGPREP_Copy_TN_Into_BB( tn_new, tn_old, CG_LOOP_prolog,
01281 NULL, 0, FALSE );
01282 }
01283 Set_OP_result( op, i, tn_new );
01284 tn_prolog_map[ TN_OMEGA( tn_old, omega ) ] = tn_new;
01285 }
01286
01287 } else {
01288
01289
01290 for ( UINT8 i = 0; i < OP_results( op ); ++i ) {
01291 TN *tn_old = OP_result( op, i );
01292 TN *tn_new = CGPREP_Dup_TN( tn_old );
01293 Set_OP_result( op, i, tn_new );
01294 tn_prolog_map[ TN_OMEGA( tn_old, omega ) ] = tn_new;
01295 }
01296 }
01297
01298
01299 BB_Insert_Op( CG_LOOP_prolog, NULL, op, FALSE );
01300 }
01301 _op_prolog_map.clear();
01302 }
01303
01304 #endif
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328 BOOL
01329 CIO_RWTRAN::Backpatch_Op_In_Prolog( OP *op, TN *new_tns[],
01330 const UINT8 start_omega,
01331 const UINT8 end_omega )
01332 {
01333 if ( _trace_CG_RTran ) {
01334 #pragma mips_frequency_hint NEVER
01335 fprintf( TFile, "<cio> Backpatch_Op_In_Prolog(%u...%u) with results in",
01336 start_omega, end_omega );
01337 for ( INT res = 0; res < OP_results( op ); ++res ) {
01338 fprintf( TFile, " " );
01339 Print_TN( new_tns[res], FALSE );
01340 }
01341 fprintf( TFile, "\n\t" );
01342 Print_OP_No_SrcLine( op );
01343 }
01344
01345 for ( UINT8 omega = start_omega; omega <= end_omega; ++omega ) {
01346
01347 OP *opr = Mark_Op_For_Prolog( op, end_omega - omega + 1 );
01348 if ( opr == NULL )
01349 return FALSE;
01350 for ( INT res = 0; res < OP_results( opr ); ++res ) {
01351 TN *tn = OP_result( opr, res );
01352 TN *tn_new = new_tns[res];
01353 CG_LOOP_Backpatch_Add( CG_LOOP_prolog, tn, tn_new, omega );
01354 if ( _trace_CG_RTran ) {
01355 #pragma mips_frequency_hint NEVER
01356 fprintf( TFile, "<cio> Backpatch_Op_In_Prolog backpatch: " );
01357 Print_TN( tn_new, FALSE );
01358 fprintf( TFile, "[%d] <-- ", omega );
01359 Print_TN( tn, FALSE );
01360 fprintf( TFile, "\n" );
01361 }
01362 }
01363 }
01364 return TRUE;
01365 }
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390 static ST *cgbh_node_int = NULL;
01391 static ST *cgbh_node_float = NULL;
01392 static ST *latest_pu = NULL;
01393
01394
01395 void
01396 CIO_RWTRAN::Generate_Black_Holes()
01397 {
01398
01399 if ( latest_pu == Get_Current_PU_ST() )
01400 return;
01401
01402 latest_pu = Get_Current_PU_ST();
01403
01404 cgbh_node_int = Gen_Temp_Symbol( Spill_Int_Type, "cg_blackhole_int" );
01405 cgbh_node_float = Gen_Temp_Symbol( Spill_Float_Type, "cg_blackhole_float" );
01406 Allocate_Temp_To_Memory( cgbh_node_int );
01407 Allocate_Temp_To_Memory( cgbh_node_float );
01408 }
01409
01410
01411 #define MAX_BLACK_HOLE_OFFSET 0x800
01412
01413
01414 BOOL
01415 CIO_RWTRAN::Safe_Offset( INT64 offset, OP *op )
01416 {
01417 return offset > - (0x8000 - MAX_BLACK_HOLE_OFFSET);
01418 }
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433 void
01434 CIO_RWTRAN::Predicate_Write( OPS *ops, OP *op, TN *tn_predicate )
01435 {
01436 Is_True( ops != NULL, ( "OPS are NULL" ) );
01437 Is_True( OP_memory( op ), ( "OP_memory(op) == FALSE" ) );
01438 Is_True( OP_store( op ), ( "OP_store(op) == FALSE" ) );
01439 Is_True( tn_predicate != NULL, ( "tn_predicate == NULL" ) );
01440
01441
01442 if ( OP_has_predicate( op ) ) {
01443 TN *tn_pred = tn_predicate;
01444 if ( ! TN_is_true_pred( OP_opnd( op, OP_PREDICATE_OPND ) ) ) {
01445 ;
01446 }
01447 Set_OP_opnd( op, OP_PREDICATE_OPND, tn_pred );
01448 return;
01449 }
01450
01451 Generate_Black_Holes();
01452
01453
01454
01455
01456
01457
01458
01459 UINT8 opnd_base = OP_find_opnd_use( op, OU_base );
01460 UINT8 opnd_offset = OP_find_opnd_use( op, OU_offset );
01461 TN *tn_offset = OP_opnd( op, opnd_offset );
01462 if ( ! TN_is_constant( tn_offset ) || ! TN_has_value( tn_offset ) ||
01463 Safe_Offset( TN_value( tn_offset ), op ) == FALSE ) {
01464
01465 OPS ops_addr = OPS_EMPTY;
01466 TN *tn_zero = Gen_Literal_TN( 0, 4 );
01467 TN *tn_new_base = Build_TN_Like( OP_opnd( op, opnd_base ) );
01468
01469 Exp_OP2( Pointer_Size == 4 ? OPC_I4ADD : OPC_I8ADD,
01470 tn_new_base, OP_opnd( op, opnd_base ), tn_offset, &ops_addr );
01471
01472 OPS_Insert_Ops_Before( ops, op, &ops_addr );
01473
01474
01475
01476 TOP new_opcode = CGTARG_Equiv_Nonindex_Memory_Op( op );
01477 if ( new_opcode != TOP_UNDEFINED ) {
01478 OP_Change_Opcode( op, new_opcode );
01479 }
01480 Set_OP_opnd( op, opnd_base, tn_new_base );
01481 Set_OP_opnd( op, opnd_offset, tn_zero );
01482 tn_offset = tn_zero;
01483 }
01484
01485
01486
01487
01488 TN *tn_storeval = OP_opnd( op, OP_find_opnd_use( op, OU_storeval ) );
01489 ST *st_addr = TN_is_float( tn_storeval ) ? cgbh_node_float : cgbh_node_int;
01490 TN *tn_hole_base = Build_TN_Like( OP_opnd( op, opnd_base ) );
01491 OPS ops_hole = OPS_EMPTY;
01492 Exp_Lda( Pointer_type, tn_hole_base, st_addr,
01493 - TN_value( tn_offset ), OPERATOR_UNKNOWN, &ops_hole );
01494 OPS_Insert_Ops_Before( ops, op, &ops_hole );
01495
01496
01497
01498
01499 TN *tn_base = OP_opnd( op, opnd_base );
01500 TN *tn_safe_base = Build_TN_Like( tn_base );
01501 #if defined KEY && defined TARG_MIPS
01502 Build_OP(TOP_or, tn_safe_base, tn_base, Zero_TN, ops);
01503 if (TN_register_class(tn_predicate) == ISA_REGISTER_CLASS_fcc)
01504 Build_OP(TOP_movt, tn_safe_base, tn_hole_base, tn_predicate, ops);
01505 else
01506 Build_OP(TOP_movn, tn_safe_base, tn_hole_base, tn_predicate, ops);
01507 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01508 Set_OP_opnd( op, opnd_base, tn_safe_base );
01509 #else
01510 TOP code = CGTARG_Which_OP_Select( TN_size( tn_base ) * 8, FALSE, FALSE );
01511 OP *op_select = Mk_OP( code, tn_safe_base, Zero_TN, Zero_TN, Zero_TN );
01512 Set_OP_selcondopnd( op_select, tn_predicate );
01513
01514 Set_OP_selndfopnd( op_select, tn_base );
01515 Set_OP_seldefopnd( op_select, tn_hole_base );
01516 Set_OP_result( op_select, 0 , tn_safe_base );
01517
01518
01519
01520 Set_OP_opnd( op, opnd_base, tn_safe_base );
01521 OPS_Insert_Op_Before( ops, op, op_select );
01522 #endif
01523 }
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543 OP *
01544 CIO_RWTRAN::Mark_Op_For_Epilog( OP *op, const UINT8 omega )
01545 {
01546 Is_True( OP_store( op ),
01547 ( "CIO_RWTRAN::Mark_Op_For_Epilog op is not store" ) );
01548
01549
01550 if ( TN_has_value( _trip_count_tn ) && TN_value( _trip_count_tn ) < omega )
01551 return NULL;
01552
01553
01554
01555 op_copy_map_epilog::iterator
01556 op_find = _op_epilog_map.find( OP_OMEGA( op, omega ) );
01557 if ( op_find != _op_epilog_map.end() )
01558 return op_find->second;
01559
01560
01561 OP *op_epilog = Dup_OP( op );
01562 if ( Is_DB_OP_Init( op ) )
01563 DB_Copy_Aux_OP( op_epilog, op );
01564
01565
01566
01567
01568
01569
01570
01571
01572 UINT8 i;
01573 UINT8 *opnd_state = (UINT8 *) alloca( OP_opnds( op ) * sizeof( UINT8 ) );
01574 for ( i = 0; i < OP_opnds( op ); ++i )
01575 opnd_state[i] = 0;
01576
01577
01578 ARC_LIST *arcs = ARC_LIST_Find( OP_succs( op ), CG_DEP_REGANTI, DONT_CARE );
01579 while ( arcs ) {
01580 ARC *arc = ARC_LIST_first( arcs );
01581 arcs = ARC_LIST_Find( ARC_LIST_rest( arcs ), CG_DEP_REGANTI, DONT_CARE );
01582
01583 UINT8 opnd = ARC_opnd( arc );
01584 if ( ARC_omega( arc ) == 0 )
01585 opnd_state[ opnd ] = 2;
01586 else if ( opnd_state[ opnd ] == 0 )
01587 opnd_state[ opnd ] = 1;
01588 }
01589
01590
01591 arcs = ARC_LIST_Find( OP_preds( op ), CG_DEP_REGIN, DONT_CARE );
01592 while ( arcs ) {
01593 ARC *arc = ARC_LIST_first( arcs );
01594 arcs = ARC_LIST_Find( ARC_LIST_rest( arcs ), CG_DEP_REGIN, DONT_CARE );
01595 UINT8 opnd = ARC_opnd( arc );
01596 if ( ARC_omega( arc ) == 0 ) {
01597 if ( opnd_state[ opnd ] == 2 )
01598 opnd_state[ opnd ] = 3;
01599 else
01600 opnd_state[ opnd ] = 1;
01601 } else if ( ARC_omega( arc ) == 1 ) {
01602 if ( opnd_state[ opnd ] < 3 )
01603 opnd_state[ opnd ] = 2;
01604 }
01605 }
01606
01607
01608
01609 for ( UINT8 opnd = 0; opnd < OP_opnds( op ); ++opnd ) {
01610 UINT8 state = opnd_state[ opnd ];
01611 if ( state == 0 ) continue;
01612
01613 TN *tn_old = OP_opnd( op, opnd );
01614 if ( state == 3 ) {
01615
01616 TN *tn_new = CGPREP_Dup_TN( tn_old );
01617 CGPREP_Copy_TN( tn_new, tn_old, op, 0, FALSE );
01618 tn_old = tn_new;
01619 }
01620
01621
01622 UINT8 omega_bp = ( state == 2 ? omega : omega - 1 );
01623 TN *tn_new = CG_LOOP_Backpatch_Find_Non_Body_TN( CG_LOOP_epilog,
01624 tn_old, omega_bp );
01625 if ( tn_new == NULL ) {
01626 tn_new = CGPREP_Dup_TN( tn_old );
01627 CG_LOOP_Backpatch_Add( CG_LOOP_epilog, tn_new, tn_old, omega_bp );
01628 }
01629 if ( _trace_CG_RTran ) {
01630 #pragma mips_frequency_hint NEVER
01631 fprintf( TFile, "<cio> Mark_Op_For_Epilog backpatch: "
01632 "TN%d[%d] --> TN%d\n",
01633 TN_number( tn_old ), omega_bp, TN_number( tn_new ) );
01634 }
01635 Set_OP_opnd( op_epilog, opnd, tn_new );
01636 }
01637
01638
01639 Is_True( OP_results( op ) == 0,
01640 ( "CIO_RWTRAN::Mark_Op_For_Epilog expected zero results" ) );
01641
01642
01643 if ( _trace_CG_RTran ) {
01644 #pragma mips_frequency_hint NEVER
01645 fprintf( TFile,
01646 "<cio> Mark_Op_For_Epilog(op 0x%p, omega %u) ---> op 0x%p\n\t",
01647 op, omega, op_epilog );
01648 Print_OP_No_SrcLine( op );
01649 fprintf( TFile, "\t" );
01650 Print_OP_No_SrcLine( op_epilog );
01651 }
01652 _op_epilog_map[ OP_OMEGA( op, omega ) ] = op_epilog;
01653 return op_epilog;
01654 }
01655
01656
01657 void
01658 CIO_RWTRAN::Copy_Ops_To_Epilog()
01659 {
01660 if ( _trace_CG_RTran ) {
01661 #pragma mips_frequency_hint NEVER
01662 fprintf( TFile, "\n<cio> CIO_RWTRAN::Copy_Ops_To_Epilog copying:\n" );
01663 }
01664
01665 UINT8 omega = MAX_OMEGA;
01666 TN *tn_predicate = NULL;
01667 OPS ops = OPS_EMPTY;
01668
01669
01670
01671 for ( op_copy_map_epilog::const_iterator op_iter = _op_epilog_map.begin();
01672 op_iter != _op_epilog_map.end();
01673 ++op_iter ) {
01674
01675
01676 if ( omega != op_iter->first.second ) {
01677 omega = op_iter->first.second;
01678 if ( ! TN_has_value( _trip_count_tn ) ) {
01679
01680
01681 tn_predicate = Gen_Predicate_TN();
01682
01683
01684 INT size = TN_size( _trip_count_tn );
01685 TN *tn_omega = Gen_Literal_TN( omega, size );
01686 if ( CGTARG_Can_Predicate() ) {
01687 TN *tn_predicate_false = Gen_Predicate_TN();
01688 VARIANT variant = ( size == 4 ? V_BR_I4GE : V_BR_I8GE );
01689 Exp_Pred_Compare( tn_predicate, tn_predicate_false,
01690 _trip_count_tn, tn_omega, variant, &ops );
01691 } else {
01692 OPCODE opcode = ( size == 4 ? OPC_I4I4GE : OPC_I4I8GE );
01693 Exp_OP2( opcode, tn_predicate, _trip_count_tn, tn_omega, &ops );
01694 }
01695 if ( _trace_CG_RTran ) {
01696 #pragma mips_frequency_hint NEVER
01697 fprintf( TFile,
01698 "\tAdded: predicate TN%d :- trip_count TN%d >= omega %d\n",
01699 TN_number( tn_predicate ), TN_number( _trip_count_tn ),
01700 omega );
01701 }
01702 }
01703 }
01704
01705 if ( ! TN_has_value( _trip_count_tn )
01706 || TN_value( _trip_count_tn ) >= omega ) {
01707
01708
01709 OPS_Append_Op( &ops, op_iter->second );
01710 if ( ! TN_has_value( _trip_count_tn ) ) {
01711 Predicate_Write( &ops, op_iter->second, tn_predicate );
01712 }
01713 if ( _trace_CG_RTran ) {
01714 #pragma mips_frequency_hint NEVER
01715 fprintf( TFile, "\t(op 0x%p, omega %u) ---> op 0x%p\n\t",
01716 op_iter->first.first, omega, op_iter->second );
01717 Print_OP_No_SrcLine( op_iter->second );
01718 }
01719 }
01720 }
01721
01722 if ( _trace_CG_RTran ) {
01723 #pragma mips_frequency_hint NEVER
01724 fprintf( TFile, "<cio> Copy_Ops_To_Epilog prepends to epilog:\n" );
01725 Print_OPS( &ops );
01726 fprintf( TFile, "\n" );
01727 }
01728
01729 BB_Prepend_Ops( CG_LOOP_epilog, &ops );
01730
01731 _op_epilog_map.clear();
01732 }
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746 BOOL
01747 CIO_RWTRAN::Backpatch_Op_In_Epilog( OP *op, const UINT8 start_omega )
01748 {
01749 if ( _trace_CG_RTran ) {
01750 #pragma mips_frequency_hint NEVER
01751 fprintf( TFile, "<cio> Backpatch_Op_In_Epilog for [%u...1]\n\t",
01752 start_omega );
01753 Print_OP_No_SrcLine( op );
01754 }
01755
01756 for ( UINT8 omega = start_omega; omega > 0; --omega )
01757 if ( Mark_Op_For_Epilog( op, omega ) == NULL ) return FALSE;
01758 return TRUE;
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
01791
01792
01793
01794
01795
01796 inline BOOL
01797 CIO_RWTRAN::Read_CICSE_Candidate_Op( OP *op )
01798 {
01799 #ifdef TARG_X8664
01800
01801
01802 if( OP_icmp(op ) )
01803 return FALSE;
01804
01805 if (OP_code(op) == TOP_lddqu || OP_code(op) == TOP_lddqa)
01806 return FALSE;
01807 #endif
01808
01809 #ifdef TARG_MIPS
01810
01811
01812
01813 if (OP_results(op) &&
01814 TN_register_class(OP_result(op, 0)) == ISA_REGISTER_CLASS_fcc) {
01815 return FALSE;
01816 }
01817 #endif
01818
01819 if ( OP_has_implicit_interactions( op ) ||
01820 OP_opnds( op ) > OP_MAX_FIXED_OPNDS )
01821 return FALSE;
01822
01823 if ( ! OP_memory( op ) )
01824 return TRUE;
01825
01826 if ( OP_prefetch( op ) ||
01827 OP_unalign_store( op ) ||
01828 OP_unalign_ld( op ) ||
01829
01830
01831 ( OP_store( op ) && OP_cond_def( op ) ) ||
01832
01833
01834
01835
01836
01837
01838 CGTARG_Mem_Ref_Bytes( op ) < 4 )
01839 return FALSE;
01840
01841 return TRUE;
01842 }
01843
01844
01845 inline BOOL
01846 CIO_RWTRAN::Write_Candidate_Op( OP *op )
01847 {
01848 return ( OP_store( op )
01849 && ! ( OP_unalign_store( op ) ||
01850 OP_has_implicit_interactions( op ) ||
01851
01852
01853
01854
01855
01856
01857 CGTARG_Mem_Ref_Bytes( op ) < 4 ) );
01858 }
01859
01860
01861 inline BOOL
01862 CIO_RWTRAN::Read_Candidate_Arc( ARC *arc )
01863 {
01864 return ( ( ARC_kind( arc ) == CG_DEP_MEMIN ||
01865 ARC_kind( arc ) == CG_DEP_MEMREAD )
01866 && ARC_is_definite( arc )
01867 && ARC_pred( arc ) != ARC_succ( arc )
01868 && ARC_omega( arc ) <= CIO_rw_max_omega
01869 && ARC_omega( arc ) < MAX_OMEGA );
01870 }
01871
01872
01873 inline BOOL
01874 CIO_RWTRAN::Write_Candidate_Arc( ARC *arc )
01875 {
01876 return ( ARC_kind( arc ) == CG_DEP_MEMOUT
01877 && ARC_is_definite( arc )
01878 && ARC_pred( arc ) != ARC_succ( arc )
01879 && ARC_omega( arc ) <= CIO_rw_max_omega
01880 && ARC_omega( arc ) < MAX_OMEGA );
01881 }
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920 struct CICSE_entry {
01921 OP *op;
01922 INT source;
01923 UINT8 omega;
01924 BOOL basis;
01925 INT potential_match;
01926 INT last_nonzero_opnd_source;
01927 INT opnd_source[OP_MAX_FIXED_OPNDS];
01928 INT opnd_result[OP_MAX_FIXED_OPNDS];
01929 UINT8 opnd_omega[OP_MAX_FIXED_OPNDS];
01930 BOOL result_unique[OP_MAX_FIXED_RESULTS];
01931 };
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955 struct CICSE_change {
01956 BOOL okay;
01957 BOOL duplicate_source;
01958 OP *op;
01959 OP *source;
01960 UINT8 omega;
01961 TN *new_tns[OP_MAX_FIXED_RESULTS];
01962 BOOL need_copy[OP_MAX_FIXED_RESULTS];
01963 };
01964
01965
01966
01967
01968
01969
01970
01971
01972 void
01973 CIO_RWTRAN::Trace_CICSE_Entries( CICSE_entry *table, INT count,
01974 const char *message )
01975 {
01976 Is_True( TFile, ( "CIO_RWTRAN::Trace_CICSE_Entries -- TFile is NULL\n" ) );
01977 fprintf( TFile, "<cio> CIO_RWTRAN::Trace_CICSE_Entries(count %d) -- %s",
01978 count, message );
01979
01980
01981 for ( INT index = 1; index <= count; ++index ) {
01982 CICSE_entry& entry = table[index];
01983 fprintf( TFile, "\n%2d: ", index );
01984 Print_OP_No_SrcLine( entry.op );
01985
01986 fprintf( TFile, " op 0x%p, source %2d, omega %u, basis %d,"
01987 " match %d, lnz_opnd %d\n opnds:",
01988 entry.op, entry.source, entry.omega, entry.basis,
01989 entry.potential_match, entry.last_nonzero_opnd_source );
01990 if ( entry.source == 0 )
01991 fprintf( TFile, " OP_opnds(entry.op) == %d", OP_opnds( entry.op ) );
01992 else if ( OP_opnds( entry.op ) > OP_MAX_FIXED_OPNDS )
01993 fprintf( TFile, " OP_opnds(entry.op) %d > OP_MAX_FIXED_OPNDS %d",
01994 OP_opnds( entry.op ), OP_MAX_FIXED_OPNDS );
01995 else
01996 for ( INT opnd = 0; opnd < OP_opnds( entry.op ); ++opnd )
01997 fprintf( TFile, " opnd %d: src %2d, om %u;",
01998 opnd, entry.opnd_source[opnd], entry.opnd_omega[opnd] );
01999 fprintf( TFile, "\n results:" );
02000 for ( INT res = 0; res < OP_results( entry.op ); ++res )
02001 fprintf( TFile, " res %d: unique %d;", res, entry.result_unique[res] );
02002 }
02003 fprintf( TFile, "\n\n" );
02004 }
02005
02006
02007 void
02008 CIO_RWTRAN::Trace_CICSE_Changes( CICSE_change *table, INT count,
02009 const char *message )
02010 {
02011 Is_True( TFile, ( "CIO_RWTRAN::Trace_CICSE_Changes -- TFile is NULL" ) );
02012 fprintf( TFile, "<cio> CIO_RWTRAN::Trace_CICSE_Changes(count %d) -- %s",
02013 count, message );
02014 for ( INT index = 0; index < count; ++index ) {
02015 CICSE_change& change = table[index];
02016 fprintf( TFile, "\n%2d: okay %d, duplicate %d, op 0x%p, source 0x%p,"
02017 " omega %u\n op: ",
02018 index, change.okay, change.duplicate_source,
02019 change.op, change.source, change.omega );
02020 Print_OP_No_SrcLine( change.op );
02021 fprintf( TFile, " source: " );
02022 Print_OP_No_SrcLine( change.source );
02023 fprintf( TFile, " results: " );
02024 if ( OP_results( change.op ) > 0 ) {
02025 Print_TN( change.new_tns[0], FALSE );
02026 for ( INT res = 1; res < OP_results( change.op ); ++res ) {
02027 fprintf( TFile, ", " );
02028 Print_TN( change.new_tns[res], FALSE );
02029 fprintf( TFile, " %d", change.need_copy[res] );
02030 }
02031 }
02032 }
02033 fprintf( TFile, "\n\n" );
02034 }
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045 INT
02046 CIO_RWTRAN::CICSE_Lookup_Op( CICSE_entry *cicse_table, INT count, OP *op )
02047 {
02048
02049 INT left = 1;
02050 INT right = count;
02051 while ( left <= right ) {
02052 INT middle = ( left + right ) / 2;
02053 OP *middle_op = cicse_table[middle].op;
02054 if ( op == middle_op )
02055 return middle;
02056 if ( OP_Precedes( op, middle_op ) )
02057 right = middle - 1;
02058 else
02059 left = middle + 1;
02060 }
02061 return 0;
02062 }
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086 void
02087 CIO_RWTRAN::Replace_Tn( BB *body, TN *tn_old, TN *tn_new, UINT8 omega_change )
02088 {
02089 Is_True( TN_is_float( tn_old ) == TN_is_float( tn_new ),
02090 ( "CIO_RWTRAN::Replace_Tn old TN%d and new TN%d have incompatible"
02091 " types", TN_number( tn_old ), TN_number( tn_new ) ) );
02092
02093 if ( _trace_CG_RTran ) {
02094 #pragma mips_frequency_hint NEVER
02095 fprintf( TFile, "CIO_RWTRAN::Replace_Tn changing " );
02096 Print_TN( tn_old, FALSE );
02097 fprintf( TFile, " to " );
02098 Print_TN( tn_new, FALSE );
02099 fprintf( TFile, "[%u] in BB:%d\n", omega_change, BB_id( body ) );
02100 }
02101
02102
02103 OP *op;
02104 FOR_ALL_BB_OPs_FWD( body, op ) {
02105
02106
02107 for ( INT opnd = OP_opnds( op ) - 1; opnd >= 0; --opnd ) {
02108 if ( OP_opnd( op, opnd ) == tn_old ) {
02109
02110
02111 Set_OP_opnd( op, opnd, tn_new );
02112 Set_OP_omega( op, opnd, OP_omega( op, opnd ) + omega_change );
02113 }
02114 }
02115 }
02116
02117 #ifdef KEY
02118
02119 CG_LOOP_Backpatch_Replace_Body_TN( CG_LOOP_prolog,
02120 tn_old, tn_new, omega_change );
02121 #else
02122
02123
02124 CG_LOOP_BACKPATCH *bp, *bp_next = NULL;
02125 for ( bp = CG_LOOP_Backpatch_First( CG_LOOP_prolog, tn_old );
02126 bp != NULL; bp = bp_next ) {
02127 bp_next = CG_LOOP_Backpatch_Next( bp );
02128 CG_LOOP_Backpatch_Delete( CG_LOOP_prolog, bp );
02129 }
02130 #endif
02131
02132
02133 CG_LOOP_Backpatch_Replace_Body_TN( CG_LOOP_epilog,
02134 tn_old, tn_new, omega_change );
02135
02136
02137 if ( GRA_LIVE_TN_Live_Outof_BB( tn_old, CG_LOOP_epilog ) )
02138 CG_LOOP_Backpatch_Add( CG_LOOP_epilog, tn_old, tn_new, omega_change );
02139 }
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150 OP *
02151 CIO_RWTRAN::Append_TN_Copy( TN *tn_dest, TN *tn_from, OP *point, UINT8 omega )
02152 {
02153
02154 OP *old_op_next = OP_next( point );
02155 CGPREP_Copy_TN( tn_dest, tn_from, point, omega, FALSE );
02156 OP *op_copy = OP_next( point );
02157
02158 Is_True( OP_next( op_copy ) == old_op_next,
02159 ( "CIO_RWTRAN::Append_TN_Copy appended more than one new OP" ) );
02160 OP_srcpos( op_copy ) = OP_srcpos( point );
02161 if ( Is_DB_OP_Init( point ) )
02162 DB_Copy_Aux_OP( op_copy, point );
02163 return op_copy;
02164 }
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183 #define CICHT_SIZELOG2 6
02184 #define CICHT_SIZE (1 << CICHT_SIZELOG2)
02185 #define CICHT_MASK (CICHT_SIZE - 1)
02186
02187
02188 BOOL
02189 CIO_RWTRAN::CICSE_Transform( BB *body )
02190 {
02191 #ifdef TARG_X8664
02192 TN* rflags_tn = Rflags_TN();
02193 #endif
02194
02195
02196 OP *op;
02197 INT op_count = 0;
02198 FOR_ALL_BB_OPs_FWD( body, op ) {
02199 ++op_count;
02200 }
02201
02202
02203
02204
02205 CICSE_entry *cicse_table
02206 = (CICSE_entry *) CXX_NEW_ARRAY( CICSE_entry, op_count + 1,
02207 _loc_mem_pool );
02208
02209
02210
02211 hTN_MAP32 tn_last_op = hTN_MAP32_Create( _loc_mem_pool );
02212
02213
02214
02215
02216 INT index;
02217 op = BB_first_op( body );
02218 for ( index = 1; index <= op_count; ++index ) {
02219
02220
02221 CICSE_entry& entry = cicse_table[index];
02222 entry.op = op;
02223 entry.basis = FALSE;
02224 entry.potential_match = 0;
02225
02226
02227 for ( INT res = OP_results( op ) - 1; res >= 0; --res )
02228 hTN_MAP32_Set( tn_last_op, OP_result( op, res ), index );
02229
02230 if ( Read_CICSE_Candidate_Op( op ) ) {
02231 Set_OP_flag1( op );
02232 entry.source = index;
02233 } else {
02234 Reset_OP_flag1( op );
02235 entry.source = 0;
02236 }
02237
02238 op = OP_next( op );
02239 }
02240
02241
02242 for ( index = 1; index <= op_count; ++index ) {
02243 CICSE_entry& entry = cicse_table[index];
02244 OP *op = entry.op;
02245
02246
02247
02248 for ( INT opnd = OP_opnds( op ) - 1; opnd >= 0; --opnd ) {
02249 INT source = 0;
02250 TN *opnd_op = OP_opnd( op, opnd );
02251 if ( TN_is_register( opnd_op ) ) {
02252 source = hTN_MAP32_Get( tn_last_op, opnd_op );
02253 #ifdef TARG_X8664
02254
02255
02256 if (opnd_op == rflags_tn) {
02257 CICSE_entry &source_entry = cicse_table[source];
02258 Reset_OP_flag1(source_entry.op);
02259 source_entry.source = 0;
02260 source = 0;
02261 }
02262 #endif
02263 }
02264
02265 #ifdef KEY
02266
02267
02268 for (INT res = OP_results(op) - 1; res >= 0; res--) {
02269 TN *tn = OP_result(op, res);
02270 if (TN_is_global_reg(tn)) {
02271 CICSE_entry &source_entry = cicse_table[index];
02272 Reset_OP_flag1(source_entry.op);
02273 source_entry.source = 0;
02274 source = 0;
02275 break;
02276 }
02277 }
02278 #endif
02279 entry.opnd_source[opnd] = source;
02280 entry.opnd_omega[opnd] = OP_omega( op, opnd );
02281
02282
02283 INT res;
02284 if ( source > 0 ) {
02285 OP *op_src = cicse_table[source].op;
02286 for ( res = OP_results( op_src ) - 1; res >= 0; --res )
02287 if ( OP_result( op_src, res ) == opnd_op )
02288 break;
02289 Is_True( res >= 0, ( "CIO_RWTRAN::CICSE_Transform"
02290 " unable to find result TN" ) );
02291 } else
02292 res = 0;
02293 entry.opnd_result[opnd] = res;
02294 }
02295
02296
02297 for ( INT res = OP_results( op ) - 1; res >= 0; --res ) {
02298 INT32 old_index = hTN_MAP32_Get_And_Set( tn_last_op,
02299 OP_result( op, res ), index );
02300 entry.result_unique[res] = ( old_index == index );
02301 }
02302 #ifdef TARG_X8664
02303
02304 if (TOP_is_change_rflags(OP_code(op))) {
02305 hTN_MAP32_Set( tn_last_op, rflags_tn, index);
02306 }
02307 #endif
02308 }
02309
02310
02311
02312 BOOL change = FALSE;
02313 for ( index = op_count; index > 0; --index ) {
02314 CICSE_entry& entry = cicse_table[index];
02315 if ( OP_load( entry.op ) && OP_flag1( entry.op ) ) {
02316
02317 ARC_LIST *arcs = OP_preds( entry.op );
02318 while ( arcs ) {
02319 ARC *arc = ARC_LIST_first( arcs );
02320 arcs = ARC_LIST_rest( arcs );
02321
02322 if ( Read_Candidate_Arc( arc ) && OP_flag1( ARC_pred( arc ) ) ) {
02323
02324 INT index_pred = CICSE_Lookup_Op( cicse_table,
02325 op_count, ARC_pred( arc ) );
02326 Is_True( index_pred > 0,
02327 ( "CIO_RWTRAN::CICSE_Transform didn't find op_pred" ) );
02328 entry.source = index_pred;
02329 entry.omega = ARC_omega( arc );
02330 entry.basis = TRUE;
02331 cicse_table[index_pred].basis = TRUE;
02332 change = TRUE;
02333 }
02334 }
02335 }
02336 }
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346 if ( ! change ) return FALSE;
02347
02348
02349
02350
02351
02352 for ( index = op_count; index > 0; --index ) {
02353 CICSE_entry& entry = cicse_table[index];
02354 if ( entry.basis )
02355 while ( entry.source > 0 &&
02356 cicse_table[entry.source].source < entry.source ) {
02357 entry.omega += cicse_table[entry.source].omega;
02358 entry.source = cicse_table[entry.source].source;
02359 }
02360 else
02361 if ( OP_memory( entry.op ) )
02362 entry.source = 0;
02363 }
02364
02365 for ( index = op_count; index > 0; --index ) {
02366 CICSE_entry& entry = cicse_table[index];
02367 if ( entry.basis )
02368 while ( entry.source > 0 &&
02369 cicse_table[entry.source].source != entry.source ) {
02370 entry.omega += cicse_table[entry.source].omega;
02371 entry.source = cicse_table[entry.source].source;
02372 }
02373 }
02374
02375
02376 if ( CIO_enable_cse_removal ) {
02377
02378
02379 do {
02380 change = FALSE;
02381
02382 for ( INT index = 1; index <= op_count; ++index ) {
02383 CICSE_entry& entry = cicse_table[index];
02384 if ( entry.source > 0 && ! entry.basis )
02385 for ( INT opnd = OP_opnds( entry.op ) - 1; opnd >= 0; --opnd ) {
02386 INT source = entry.opnd_source[opnd];
02387 if ( source > 0 && cicse_table[source].source == 0 ) {
02388 entry.source = 0;
02389 change = TRUE;
02390 }
02391 }
02392 }
02393 } while ( change );
02394
02395
02396 for ( index = op_count; index > 1; --index ) {
02397 CICSE_entry& entry = cicse_table[index];
02398 if ( entry.source == 0 || entry.basis ) continue;
02399
02400
02401 INT opnd = OP_opnds( entry.op ) - 1;
02402 while ( opnd >= 0 && entry.opnd_source[opnd] == 0 )
02403 --opnd;
02404 entry.last_nonzero_opnd_source = opnd;
02405 }
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416 INT hash_buckets[CICHT_SIZE];
02417 INT bucket;
02418 for ( bucket = 0; bucket < CICHT_SIZE; ++bucket )
02419 hash_buckets[bucket] = 0;
02420
02421
02422 for ( index = 1; index <= op_count; ++index ) {
02423 CICSE_entry& entry = cicse_table[index];
02424 if ( entry.source == 0 || entry.basis ) continue;
02425
02426
02427 bucket = ( OP_code( entry.op ) + entry.last_nonzero_opnd_source )
02428 & CICHT_MASK;
02429 entry.potential_match = hash_buckets[bucket];
02430 hash_buckets[bucket] = index;
02431 }
02432
02433
02434
02435
02436 for ( bucket = 0; bucket < CICHT_SIZE; ++bucket ) {
02437 INT index2, next_index2;
02438 for ( index2 = hash_buckets[bucket]; index2 > 0; index2 = next_index2 ) {
02439 CICSE_entry& entry2 = cicse_table[index2];
02440 next_index2 = entry2.potential_match;
02441
02442 INT index1, next_index1;
02443 for ( index1 = next_index2; index1 > 0; index1 = next_index1 ) {
02444 CICSE_entry& entry1 = cicse_table[index1];
02445 next_index1 = entry1.potential_match;
02446
02447 if ( OP_code( entry1.op ) != OP_code( entry2.op ) ||
02448 entry1.last_nonzero_opnd_source
02449 != entry2.last_nonzero_opnd_source ) continue;
02450 Is_True( OP_opnds( entry1.op ) == OP_opnds( entry2.op ),
02451 ( "CIO_RWTRAN::CICSE_Transform operand counts differ" ) );
02452
02453
02454 INT opnd;
02455 for ( opnd = OP_opnds( entry2.op ) - 1; opnd >= 0; --opnd )
02456 if ( entry2.opnd_source[opnd] == 0 &&
02457 OP_opnd( entry1.op, opnd ) != OP_opnd( entry2.op, opnd ) )
02458 break;
02459
02460 if (opnd >= 0) continue;
02461
02462
02463 break;
02464 }
02465
02466 entry2.potential_match = index1;
02467 }
02468 }
02469
02470
02471
02472
02473
02474
02475 for ( INT index2 = 2; index2 <= op_count; ++index2 ) {
02476 CICSE_entry& entry2 = cicse_table[index2];
02477 if ( entry2.last_nonzero_opnd_source >= 0 ) continue;
02478
02479 INT index1 = entry2.potential_match;
02480 if ( index1 > 0 ) {
02481
02482
02483 while ( cicse_table[index1].potential_match != 0 )
02484 index1 = cicse_table[index1].potential_match;
02485
02486
02487 entry2.source = index1;
02488 entry2.omega = 0;
02489 }
02490 }
02491
02492
02493
02494 do {
02495
02496
02497 INT index;
02498 for ( index = op_count; index > 0; --index ) {
02499 CICSE_entry& entry = cicse_table[index];
02500 while ( entry.source > 0 &&
02501 cicse_table[entry.source].source != entry.source ) {
02502 entry.omega += cicse_table[entry.source].omega;
02503 entry.source = cicse_table[entry.source].source;
02504 }
02505 }
02506
02507
02508 for ( index = op_count; index > 0; --index ) {
02509 CICSE_entry& entry = cicse_table[index];
02510 if ( entry.source > 0 && ! entry.basis )
02511 for ( INT opnd = OP_opnds( entry.op ) - 1; opnd >= 0; --opnd ) {
02512 INT source = entry.opnd_source[opnd];
02513 if ( source > 0 && cicse_table[source].source != source ) {
02514 entry.opnd_source[opnd] = cicse_table[source].source;
02515 entry.opnd_omega[opnd] += cicse_table[source].omega;
02516
02517 }
02518 }
02519 }
02520
02521
02522
02523
02524
02525
02526 change = FALSE;
02527
02528 for ( INT index2 = 2; index2 <= op_count; ++index2 ) {
02529 CICSE_entry& entry2 = cicse_table[index2];
02530 if ( entry2.source != index2 ||
02531 entry2.last_nonzero_opnd_source < 0 ) continue;
02532
02533
02534 INT index1 = entry2.potential_match;
02535 if ( index1 > 0 && cicse_table[index1].source != index1 ) {
02536 do {
02537 index1 = cicse_table[index1].potential_match;
02538 } while ( index1 > 0 && cicse_table[index1].source != index1 );
02539 entry2.potential_match = index1;
02540 }
02541
02542
02543
02544
02545 while ( index1 > 0 ) {
02546 CICSE_entry& entry1 = cicse_table[index1];
02547
02548
02549
02550 INT opnd;
02551 for ( opnd = OP_opnds( entry2.op ) - 1; opnd >= 0; --opnd )
02552 if ( entry1.opnd_source[opnd] != entry2.opnd_source[opnd] ||
02553 #ifdef OSP_OPT
02554
02555
02556 (entry1.opnd_source[opnd] > index1 && entry1.opnd_source[opnd] < index2) ||
02557 #endif
02558 entry1.opnd_result[opnd] != entry2.opnd_result[opnd] )
02559 break;
02560
02561 if (opnd < 0) {
02562
02563
02564 opnd = entry2.last_nonzero_opnd_source;
02565 UINT8 omega1 = entry1.opnd_omega[opnd];
02566 UINT8 omega2 = entry2.opnd_omega[opnd];
02567 for ( --opnd; opnd >= 0; --opnd )
02568 if ( entry1.opnd_source[opnd] > 0 &&
02569 entry1.opnd_omega[opnd] + omega2
02570 != entry2.opnd_omega[opnd] + omega1 )
02571 break;
02572 if ( opnd < 0 ) {
02573
02574
02575 change = TRUE;
02576 if ( omega1 > omega2 ) {
02577 entry1.source = index2;
02578 entry1.omega = omega1 - omega2;
02579
02580 } else {
02581 entry2.source = index1;
02582 entry2.omega = omega2 - omega1;
02583 break;
02584 }
02585 }
02586 }
02587
02588
02589 index1 = entry1.potential_match;
02590 if ( index1 > 0 && cicse_table[index1].source != index1 ) {
02591 do {
02592 index1 = cicse_table[index1].potential_match;
02593 } while ( index1 > 0 && cicse_table[index1].source != index1 );
02594 entry1.potential_match = index1;
02595 }
02596 }
02597 }
02598 } while ( change );
02599 }
02600
02601
02602 if ( _trace_CG_RTran ) {
02603 #pragma mips_frequency_hint NEVER
02604 Trace_CICSE_Entries( cicse_table, op_count, "After CSE Analysis" );
02605 }
02606
02607
02608 INT oppor_count = 0;
02609 for ( index = op_count; index > 0; --index )
02610 if ( cicse_table[index].source != index && cicse_table[index].source > 0 )
02611 ++oppor_count;
02612 Is_True( oppor_count > 0,
02613 ( "CIO_RWTRAN::CICSE_Transform didn't abort early" ) );
02614
02615 #ifdef KEY
02616
02617 if( oppor_count >= ( REGISTER_MAX >> 1 ) ){
02618 return FALSE;
02619 }
02620 #endif
02621
02622
02623 CICSE_change *opportunities
02624 = (CICSE_change *) CXX_NEW_ARRAY( CICSE_change, oppor_count,
02625 _loc_mem_pool );
02626
02627 INT oppor_index = 0;
02628 for ( index = 1; index <= op_count; ++index ) {
02629 CICSE_entry& entry = cicse_table[index];
02630 if ( entry.source == 0 || entry.source == index ) continue;
02631
02632 CICSE_change& change = opportunities[oppor_index];
02633 ++oppor_index;
02634
02635 change.okay = TRUE;
02636 change.duplicate_source = FALSE;
02637 change.op = entry.op;
02638 change.source = cicse_table[entry.source].op;
02639 change.omega = entry.omega;
02640
02641
02642 INT index_dup;
02643 for ( index_dup = oppor_index - 2; index_dup >= 0; --index_dup )
02644 if ( opportunities[index_dup].source == change.source
02645 && ! opportunities[index_dup].duplicate_source ) break;
02646
02647
02648 if ( index_dup >= 0 ) {
02649 CICSE_change& change_dup = opportunities[index_dup];
02650
02651
02652 if ( change.omega > change_dup.omega )
02653 change_dup.duplicate_source = TRUE;
02654 else
02655 change.duplicate_source = TRUE;
02656
02657
02658 if ( OP_store( change.source ) )
02659 change.new_tns[0] = change_dup.new_tns[0];
02660 else
02661 for ( INT res = OP_results( change.source ) - 1; res >= 0; --res )
02662 change.new_tns[res] = change_dup.new_tns[res];
02663
02664 } else if ( OP_store( change.source ) ) {
02665
02666
02667 INT opnd = OP_find_opnd_use( change.source, OU_storeval );
02668 Is_True( opnd >= 0, ( "CIO_RWTRAN::CICSE_Transform can't find"
02669 " storeval operand for %s",
02670 TOP_Name( OP_code( change.source ) ) ) );
02671 change.new_tns[0] = OP_opnd( change.source, opnd );
02672
02673
02674 Is_True( OP_results( change.op ) == 1,
02675 ( "CIO_RWTRAN:CICSE_Transform: Read has multiple results" ) );
02676
02677
02678
02679 Is_True( ! OP_has_predicate( change.source )
02680 || OP_opnd( change.source, OP_PREDICATE_OPND ) == True_TN,
02681 ( "Can't handle predicated write source" ) );
02682
02683
02684
02685 INT tn_index = hTN_MAP32_Get( tn_last_op, change.new_tns[0] );
02686 #ifdef KEY
02687
02688 if( tn_index == 0 )
02689 change.new_tns[0] = Build_TN_Like( change.new_tns[0] );
02690 else
02691 #endif // KEY
02692 if ( OP_Precedes( change.source, cicse_table[tn_index].op ) )
02693 change.new_tns[0] = Build_TN_Like( change.new_tns[0] );
02694
02695 } else {
02696
02697
02698 for ( INT res = OP_results( change.source ) - 1; res >= 0; --res )
02699 change.new_tns[res] = OP_result( change.source, res );
02700
02701
02702 if ( OP_has_predicate( change.source )
02703 && OP_opnd( change.source, OP_PREDICATE_OPND ) != True_TN )
02704 for ( INT res = OP_results( change.source ) - 1; res >= 0; --res )
02705 change.new_tns[res] = Build_TN_Like( change.new_tns[res] );
02706
02707 else
02708
02709
02710 for ( INT res = OP_results( change.source ) - 1; res >= 0; --res ) {
02711 INT tn_index = hTN_MAP32_Get( tn_last_op, change.new_tns[res] );
02712 if ( cicse_table[tn_index].op != change.source )
02713 change.new_tns[res] = Build_TN_Like( change.new_tns[res] );
02714 }
02715 }
02716
02717
02718
02719 if ( ! OP_has_predicate( change.op )
02720 || OP_opnd( change.op, OP_PREDICATE_OPND ) == True_TN ){
02721 for ( INT res = OP_results( change.op ) - 1; res >= 0; --res ) {
02722 TN *tn_result = OP_result( change.op, res );
02723 change.need_copy[res] =
02724 ( ! entry.result_unique[res] ||
02725 GRA_LIVE_TN_Live_Outof_BB( tn_result, CG_LOOP_epilog ) ||
02726 change.new_tns[res] == tn_result );
02727 #ifdef KEY
02728
02729 if( !change.need_copy[res] ){
02730 for( index_dup = oppor_index - 2; index_dup >= 0; index_dup-- ){
02731 if( tn_result == opportunities[index_dup].new_tns[res] ){
02732 change.need_copy[res] = TRUE;
02733 break;
02734 }
02735 }
02736 }
02737 #endif
02738 }
02739 }
02740
02741 #ifdef KEY
02742
02743
02744
02745 for( int start_omega = 1; start_omega <= change.omega; start_omega++ ){
02746 for( INT res = OP_results( change.op ) - 1; res >= 0; --res ){
02747 if( CG_LOOP_Backpatch_Find_Non_Body_TN(CG_LOOP_prolog,
02748 change.new_tns[res],
02749 start_omega) != NULL ){
02750 change.new_tns[res] = Build_TN_Like( change.new_tns[res] );
02751 change.need_copy[res] = true;
02752 }
02753 }
02754 }
02755 #endif
02756 }
02757
02758
02759 if ( _trace_CG_RTran ) {
02760 #pragma mips_frequency_hint NEVER
02761 Trace_CICSE_Changes( opportunities, oppor_count,
02762 "During CIO_RWTRAN:CICSE_Transform" );
02763 }
02764
02765
02766
02767 for ( index = oppor_count - 1; index >= 0; --index ) {
02768 CICSE_change& change = opportunities[index];
02769 if ( change.duplicate_source ) continue;
02770
02771 if ( ! Backpatch_Op_In_Prolog( change.op, change.new_tns,
02772 1, change.omega ) ) {
02773
02774
02775 for ( INT ch_index = oppor_count; ch_index >= 0; --ch_index )
02776 if ( opportunities[ch_index].source == change.source )
02777 opportunities[ch_index].okay = FALSE;
02778 }
02779 }
02780
02781
02782 Copy_Ops_To_Prolog();
02783
02784
02785
02786
02787 for ( index = oppor_count - 1; index >= 0; --index ) {
02788 CICSE_change& change = opportunities[index];
02789 if ( change.duplicate_source || ! change.okay ) continue;
02790
02791 if ( OP_store( change.source ) ) {
02792
02793
02794
02795 Is_True( OP_results( change.op ) == 1,
02796 ( "CIO_RWTRAN:CICSE_Transform: Read has multiple results" ) );
02797
02798
02799
02800
02801
02802 INT opnd = OP_find_opnd_use( change.source, OU_storeval );
02803 TN *tn_old = OP_opnd( change.source, opnd );
02804 TN *tn_new = change.new_tns[0];
02805 if ( tn_old != tn_new ) {
02806
02807
02808 OP *op_copy = Append_TN_Copy( tn_new, tn_old, change.source,
02809 OP_omega( change.source, opnd ) );
02810 if ( _trace_CG_RTran ) {
02811 #pragma mips_frequency_hint NEVER
02812 fprintf( TFile, "CIO_RWTRAN::Transform_Arcs inserts:\n\t" );
02813 Print_OP_No_SrcLine( op_copy );
02814 }
02815 }
02816
02817 } else {
02818
02819
02820
02821
02822 if ( OP_has_predicate( change.source )
02823 && OP_opnd( change.source, OP_PREDICATE_OPND ) != True_TN ) {
02824 TN *tn_pred = OP_opnd( change.source, OP_PREDICATE_OPND );
02825 Set_OP_opnd( change.source, OP_PREDICATE_OPND, True_TN );
02826 for ( INT res = OP_results( change.source ) - 1; res >= 0; --res ) {
02827 TN *tn_old = OP_result( change.source, res );
02828 TN *tn_new = change.new_tns[res];
02829 Set_OP_result( change.source, res, tn_new );
02830
02831
02832 OP *op_copy = Append_TN_Copy( tn_old, tn_new, change.source, 0 );
02833 Set_OP_opnd( op_copy, OP_PREDICATE_OPND, tn_pred );
02834 if ( _trace_CG_RTran ) {
02835 #pragma mips_frequency_hint NEVER
02836 fprintf( TFile, "CIO_RWTRAN::Transform_Arcs inserts:\n\t" );
02837 Print_OP_No_SrcLine( op_copy );
02838 }
02839 }
02840
02841 } else
02842
02843
02844 for ( INT res = OP_results( change.source ) - 1; res >= 0; --res ) {
02845 TN *tn_old = OP_result( change.source, res );
02846 TN *tn_new = change.new_tns[res];
02847 if ( tn_old == tn_new ) continue;
02848
02849
02850 OP *op_copy = Append_TN_Copy( tn_new, tn_old, change.source, 0 );
02851 if ( _trace_CG_RTran ) {
02852 #pragma mips_frequency_hint NEVER
02853 fprintf( TFile, "CIO_RWTRAN::Transform_Arcs inserts:\n\t" );
02854 Print_OP_No_SrcLine( op_copy );
02855 }
02856 }
02857 }
02858 }
02859
02860
02861 for ( index = oppor_count - 1; index >= 0; --index ) {
02862 CICSE_change& change = opportunities[index];
02863 if ( ! change.okay ) continue;
02864
02865 if ( _trace_CG_RTran ) {
02866 #pragma mips_frequency_hint NEVER
02867 fprintf( TFile, "CIO_RWTRAN::CICSE_Transform replaces:\n\t" );
02868 Print_OP_No_SrcLine( change.op );
02869 fprintf( TFile, "with:" );
02870 }
02871
02872
02873 if ( OP_has_predicate( change.op )
02874 && OP_opnd( change.op, OP_PREDICATE_OPND ) != True_TN ) {
02875 TN *tn_pred = OP_opnd( change.op, OP_PREDICATE_OPND );
02876 for ( INT res = OP_results( change.op ) - 1; res >= 0; --res ) {
02877 TN *tn_old = OP_result( change.op, res );
02878 TN *tn_new = change.new_tns[res];
02879
02880
02881 OP *op_copy = Append_TN_Copy( tn_old, tn_new,
02882 change.op, change.omega );
02883 Set_OP_opnd( op_copy, OP_PREDICATE_OPND, tn_pred );
02884 if ( _trace_CG_RTran ) {
02885 #pragma mips_frequency_hint NEVER
02886 fprintf( TFile, "\t" );
02887 Print_OP_No_SrcLine( op_copy );
02888 }
02889 }
02890
02891 } else
02892 for ( INT res = OP_results( change.op ) - 1; res >= 0; --res ) {
02893 TN *tn_old = OP_result( change.op, res );
02894 TN *tn_new = change.new_tns[res];
02895 if ( change.need_copy[res] ) {
02896
02897 OP *op_copy = Append_TN_Copy( tn_old, tn_new,
02898 change.op, change.omega );
02899 if ( _trace_CG_RTran ) {
02900 #pragma mips_frequency_hint NEVER
02901 fprintf( TFile, "\t" );
02902 Print_OP_No_SrcLine( op_copy );
02903 }
02904 } else {
02905
02906 Replace_Tn( body, tn_old, tn_new, change.omega );
02907 }
02908 }
02909 BB_Remove_Op( body, change.op );
02910 }
02911
02912 if ( _trace_CG_RTran ) {
02913 #pragma mips_frequency_hint NEVER
02914 fprintf( TFile, "\n" );
02915 }
02916
02917 return TRUE;
02918 }
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929 void
02930 CIO_RWTRAN::Print_Ops( const char *message )
02931 {
02932 Is_True( TFile, ( "CIO_RWTRAN::Print_Ops -- TFile is NULL" ) );
02933 fprintf( TFile, "<cio> CIO_RWTRAN::Print_Ops -- %s\n", message );
02934 for ( INT t = 0; t < _ordering_count; ++t ) {
02935 OP *op = _op_ordering[t];
02936 if ( op )
02937 Print_OP_No_SrcLine( op );
02938 else
02939 fprintf( TFile, "NULL\n" );
02940 }
02941 fprintf( TFile, "\n" );
02942 }
02943
02944
02945 void
02946 CIO_RWTRAN::Print_Arcs( const char *message )
02947 {
02948 Is_True( TFile, ( "CIO_RWTRAN::Print_Arcs -- TFile is NULL" ) );
02949 fprintf( TFile, "<cio> CIO_RWTRAN::Print_Arcs -- %s\n", message );
02950 for ( INT t = 0; t < _ordering_count; ++t ) {
02951 ARC *arc = _arc_ordering[t];
02952 if ( arc )
02953 CG_DEP_Trace_Arc( arc, FALSE, TRUE );
02954 else
02955 fprintf( TFile, "NULL\n" );
02956 }
02957 fprintf( TFile, "\n" );
02958 }
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978 void
02979 CIO_RWTRAN::Sort_Ops_Preorder( OP *op_current, BOOL current_has_arc )
02980 {
02981
02982 Reset_OP_flag1( op_current );
02983
02984
02985 for ( ARC_LIST *arclist = OP_preds( op_current );
02986 arclist != NULL;
02987 arclist = ARC_LIST_rest( arclist ) ) {
02988
02989
02990 ARC *arc = ARC_LIST_first( arclist );
02991 if ( ! Write_Candidate_Arc( arc ) ) continue;
02992 OP *op_pred = ARC_pred( arc );
02993 if ( ! OP_flag1( op_pred ) ) continue;
02994
02995
02996 current_has_arc = TRUE;
02997 Sort_Ops_Preorder( op_pred, TRUE );
02998 }
02999
03000
03001
03002 if ( current_has_arc )
03003 _op_ordering[_ordering_count++] = op_current;
03004 else
03005
03006 Set_OP_flag1( op_current );
03007 }
03008
03009
03010 void
03011 CIO_RWTRAN::Sort_Ops( BB *body )
03012 {
03013
03014 OP *op;
03015 INT op_count = 0;
03016 FOR_ALL_BB_OPs_FWD( body, op ) {
03017 if ( Write_Candidate_Op( op ) ) {
03018 Set_OP_flag1( op );
03019 ++op_count;
03020 } else
03021 Reset_OP_flag1( op );
03022 }
03023
03024
03025
03026 _ordering_count = 0;
03027 if ( op_count == 0 ) return;
03028 _op_ordering = (OP **) CXX_NEW_ARRAY( OP *, op_count, _loc_mem_pool );
03029
03030
03031
03032
03033 FOR_ALL_BB_OPs_REV( body, op ) {
03034 if ( ! OP_flag1( op ) ) continue;
03035 BOOL current_has_arc = FALSE;
03036 OP *op_current = op;
03037 ARC_LIST *arclist;
03038 do {
03039
03040
03041 Sort_Ops_Preorder( op_current, current_has_arc );
03042
03043
03044 for ( arclist = OP_succs( op_current );
03045 arclist != NULL;
03046 arclist = ARC_LIST_rest( arclist ) ) {
03047
03048
03049 ARC *arc = ARC_LIST_first( arclist );
03050 if ( ! Write_Candidate_Arc( arc ) ) continue;
03051 OP *op_succ = ARC_succ( arc );
03052 if ( ! OP_flag1( op_succ ) ) continue;
03053
03054
03055 op_current = op_succ;
03056 current_has_arc = TRUE;
03057 break;
03058 }
03059 } while ( arclist != NULL );
03060 }
03061
03062
03063 if ( _trace_CG_RTran ) {
03064 #pragma mips_frequency_hint NEVER
03065 Print_Ops( "After CIO_RWTRAN::Sort_Ops" );
03066 }
03067 }
03068
03069
03070 void
03071 CIO_RWTRAN::Sort_Arcs( void )
03072 {
03073
03074 if ( _ordering_count == 0 ) return;
03075 _arc_ordering = (ARC **) CXX_NEW_ARRAY( ARC *, _ordering_count,
03076 _loc_mem_pool );
03077
03078 OP *op_succ = _op_ordering[0];
03079 INT t;
03080 for ( t = 1; t < _ordering_count; ++t ) {
03081 OP *op_pred = op_succ;
03082 op_succ = _op_ordering[t];
03083
03084
03085 _arc_ordering[t - 1] = NULL;
03086 for ( ARC_LIST *arcs = OP_preds( op_succ );
03087 arcs != NULL; arcs = ARC_LIST_rest( arcs ) ) {
03088 ARC *arc = ARC_LIST_first( arcs );
03089 if ( ARC_pred( arc ) == op_pred && Write_Candidate_Arc( arc ) ) {
03090 _arc_ordering[t - 1] = arc;
03091 break;
03092 }
03093 }
03094 }
03095 _arc_ordering[_ordering_count - 1] = NULL;
03096
03097
03098 BOOL within_chain = FALSE;
03099 for ( t = _ordering_count - 2; t >= 0; --t ) {
03100 if ( _arc_ordering[t] == NULL )
03101 within_chain = FALSE;
03102 else if ( ! within_chain ) {
03103 if ( OP_cond_def( _op_ordering[t + 1] ) )
03104 _arc_ordering[t] = NULL;
03105 else
03106 within_chain = TRUE;
03107 }
03108 }
03109
03110
03111 if ( _trace_CG_RTran ) {
03112 #pragma mips_frequency_hint NEVER
03113 Print_Arcs( "After CIO_RWTRAN::Sort_Arcs" );
03114 }
03115 }
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126 void
03127 CIO_RWTRAN::Transform_Arcs( BB *body )
03128 {
03129
03130 if ( _trace_CG_RTran ) {
03131 #pragma mips_frequency_hint NEVER
03132 Print_Arcs( "Before CIO_RWTRAN::Transform_Arcs" );
03133 }
03134
03135
03136 for ( INT t = 0; t < _ordering_count; ++t ) {
03137 ARC *arc = _arc_ordering[t];
03138 if ( arc == NULL ) continue;
03139 Is_True( ARC_kind( arc ) == CG_DEP_MEMOUT,
03140 ( "CIO_RWTRAN::Transform_Arcs found unexpected arc type" ) );
03141 OP *op_base = ARC_pred( arc );
03142
03143
03144 if ( ! Backpatch_Op_In_Epilog( op_base, ARC_omega( arc ) ) )
03145 continue;
03146
03147
03148 if ( _trace_CG_RTran ) {
03149 #pragma mips_frequency_hint NEVER
03150 fprintf( TFile, "CIO_RWTRAN::Transform_Arcs removes:\n\t" );
03151 Print_OP_No_SrcLine( op_base );
03152 }
03153 BB_Remove_Op( body, op_base );
03154 }
03155
03156
03157 Copy_Ops_To_Epilog();
03158 }
03159
03160
03161
03162
03163
03164 BOOL
03165 CIO_RWTRAN::Write_Removal( BB *body )
03166 {
03167
03168
03169
03170 #ifndef KEY
03171 if ( ! TN_has_value( _trip_count_tn ) && ! CGTARG_Can_Predicate() ) {
03172 #else
03173 if ( 0 ) {
03174 #endif
03175 DevWarn( "CIO_RWTRAN::Read_Write_Removal predication not activated" );
03176 return FALSE;
03177 }
03178
03179
03180 Sort_Ops( body );
03181 if ( _ordering_count == 0 ) return FALSE;
03182 Sort_Arcs();
03183
03184
03185 if ( TN_has_value( _trip_count_tn )
03186 && TN_value( _trip_count_tn ) < MAX_OMEGA ) {
03187 for ( INT t = _ordering_count - 1; t >= 0; --t ) {
03188 ARC *arc = _arc_ordering[t];
03189 if ( arc != NULL && ARC_omega( arc ) >= TN_value( _trip_count_tn ) )
03190 _arc_ordering[t] = NULL;
03191 }
03192 }
03193
03194
03195 INT t;
03196 for ( t = _ordering_count - 1; t >= 0; --t )
03197 if ( _arc_ordering[t] != NULL ) break;
03198 if ( t < 0 ) return FALSE;
03199
03200
03201 Transform_Arcs( body );
03202
03203
03204
03205
03206 _op_ordering = NULL;
03207 _arc_ordering = NULL;
03208 return TRUE;
03209 }
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221 BOOL
03222 CIO_RWTRAN::Read_CICSE_Write_Removal( LOOP_DESCR *loop )
03223 {
03224 BB *body = LOOP_DESCR_loophead( loop );
03225 BB *head = LOOP_DESCR_loophead( loop );
03226
03227
03228
03229
03230
03231
03232
03233 BOOL save_CG_DEP_Addr_Analysis = CG_DEP_Addr_Analysis;
03234 CG_DEP_Addr_Analysis = FALSE;
03235
03236
03237 if ( _trace_CG_RTran ) {
03238 #pragma mips_frequency_hint NEVER
03239 fprintf( TFile, "\n<cio> %s<cio> Read/CICSE/Write Removal:\n<cio> %s\n",
03240 SBar, SBar );
03241 CG_LOOP_Trace_Loop( loop, "<cio> Before CIO Copy Propagation" );
03242 }
03243
03244
03245 BOOL changed_loop_copy = FALSE;
03246 if ( CIO_enable_copy_removal )
03247 changed_loop_copy = CIO_Copy_Remove( body );
03248
03249
03250 CG_DEP_Compute_Graph( head, NO_ASSIGNED_REG_DEPS, CYCLIC,
03251 INCLUDE_MEMREAD_ARCS, INCLUDE_MEMIN_ARCS,
03252 NO_CONTROL_ARCS, NULL );
03253
03254
03255 if ( _trace_CG_RTran ) {
03256 #pragma mips_frequency_hint NEVER
03257 if ( changed_loop_copy ) {
03258 CG_LOOP_Trace_Loop( loop, "<cio> Between Copy Propagation"
03259 " and Read/CICSE Removal" );
03260 } else {
03261 fprintf( TFile, "<cio> Between Copy Propagation"
03262 " and Read/CICSE Removal: No Change\n\n" );
03263 }
03264 CG_DEP_Trace_Graph( body );
03265 }
03266
03267
03268 BOOL changed_loop_read = FALSE;
03269 if ( CIO_enable_read_removal )
03270 changed_loop_read = CICSE_Transform( body );
03271
03272
03273 if ( changed_loop_read ) {
03274 CG_DEP_Delete_Graph( head );
03275 CG_DEP_Compute_Graph( head, NO_ASSIGNED_REG_DEPS, CYCLIC,
03276 NO_MEMREAD_ARCS, INCLUDE_MEMIN_ARCS,
03277 NO_CONTROL_ARCS, NULL );
03278 }
03279
03280
03281 if ( _trace_CG_RTran ) {
03282 #pragma mips_frequency_hint NEVER
03283 if ( changed_loop_read ) {
03284 CG_LOOP_Trace_Loop( loop, "<cio> Between Read/CICSE and Write Removal" );
03285 CG_DEP_Trace_Graph( body );
03286 } else
03287 fprintf( TFile,
03288 "<cio> Between Read/CICSE and Write Removal: No Change\n\n" );
03289 }
03290
03291
03292 BOOL changed_loop_write = FALSE;
03293 if ( CIO_enable_write_removal )
03294 changed_loop_write = Write_Removal( body );
03295
03296
03297 if ( _trace_CG_RTran || _trace_CG_Chkpnt ) {
03298 #pragma mips_frequency_hint NEVER
03299 if ( changed_loop_write )
03300 CG_LOOP_Trace_Loop( loop, "<cio> After Write Removal\n" );
03301 else
03302 fprintf( TFile, "<cio> After Write Removal: No Change\n" );
03303 fprintf( TFile, "\n" );
03304 }
03305
03306 CG_DEP_Addr_Analysis = save_CG_DEP_Addr_Analysis;
03307
03308 CG_DEP_Delete_Graph( head );
03309
03310 return ( changed_loop_read || changed_loop_write || changed_loop_copy );
03311 }
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327 BOOL Perform_Read_Write_Removal( LOOP_DESCR *loop )
03328 {
03329 if ( ! CIO_enable_copy_removal &&
03330 ! CIO_enable_read_removal && ! CIO_enable_write_removal )
03331 return FALSE;
03332
03333
03334 MEM_POOL local_mem_pool;
03335 MEM_POOL_Initialize( &local_mem_pool, "CIO_RWTRAN local pool", FALSE );
03336 MEM_POOL_Push( &local_mem_pool );
03337
03338 BOOL changed_loop = FALSE;
03339 {
03340
03341 CIO_RWTRAN cio_rwtran( loop, &local_mem_pool );
03342 changed_loop = cio_rwtran.Read_CICSE_Write_Removal( loop );
03343 }
03344
03345
03346 MEM_POOL_Pop( &local_mem_pool );
03347 MEM_POOL_Delete( &local_mem_pool );
03348
03349 if ( changed_loop )
03350 CG_LOOP_Recompute_Liveness( loop );
03351
03352 return changed_loop;
03353 }
03354
03355
03356