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
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
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
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00438 #ifndef MD_RCS_ID
00439 #define MD_RCS_ID
00440 #ifdef _KEEP_RCS_ID
00441 static char *model_rcs_id = "$Source: ../../be/lno/SCCS/s.model.h $ $Revision: 1.8 $";
00442 #endif
00443 #endif
00444
00445 #define USE_STANDARD_TYPES
00446 #include <bstring.h>
00447 #include "defs.h"
00448 #ifndef access_vector_INCLUDED
00449 #include "access_vector.h"
00450 #endif
00451 #ifndef cxx_graph_INCLUDED
00452 #include "cxx_graph.h"
00453 #endif
00454 #ifndef graph_template_INCLUDED
00455 #include "graph_template.h"
00456 #endif
00457 #ifndef lnoutils_INCLUDED
00458 #include "lnoutils.h"
00459 #endif
00460 #ifndef dep_INCLUDED
00461 #include "dep.h"
00462 #endif
00463 #ifndef lno_scc_INCLUDED
00464 #include "lno_scc.h"
00465 #endif
00466 #ifndef lnopt_main_INCLUDED
00467 #include "lnopt_main.h"
00468 #endif
00469 #ifndef snl_nest_INCLUDED
00470 #include "snl_nest.h"
00471 #endif
00472 #include <sys/types.h>
00473 #include "sxlist.h"
00474 #ifndef _lno_bv_INCLUDED
00475 #include "lno_bv.h"
00476 #endif
00477
00478
00479 #ifndef MODEL_DELCARE
00480 #define MODEL_DELCARE
00481
00482 #ifdef TARG_MIPS
00483 #define Target_INTRs 32
00484 #endif
00485 #ifdef TARG_IA64
00486 #define Target_INTRs 128
00487 #endif
00488 #ifdef TARG_IA32
00489 #define Target_INTRs 8
00490 #endif
00491 #ifdef TARG_X8664
00492 #define Target_INTRs 16
00493 #endif
00494
00495 typedef HASH_TABLE<WN*,INT> WN2INT;
00496
00497
00498 struct ti_res_count;
00499 typedef struct ti_res_count TI_RES_COUNT;
00500
00501
00502
00503
00504 extern BOOL Is_Bad_Array(WN* wn_ref, INT nloops);
00505 #ifdef TARG_X8664
00506 extern BOOL Is_Vectorizable_Loop(WN* loop);
00507 extern BOOL Is_Vectorization_Beneficial(WN* loop);
00508
00509
00510 extern BOOL Is_Aggressive_Vintr_Loop(WN *loop);
00511 #endif
00512
00513 class LOOP_MODEL {
00514 INT *_block_number_inner;
00515 INT *_iloop_inner;
00516 INT *_stripsz_inner;
00517 INT *_striplevel_inner;
00518 INT _nstrips_inner;
00519 INT _stripdepth_inner;
00520 INT *_new_order_inner;
00521 INT _inner_loop_inner;
00522 INT _num_fp_array_refs;
00523 INT _num_fp_scalar_refs;
00524 INT _num_int_array_refs;
00525 INT _num_int_scalar_refs;
00526 BOOL *_can_be_inner;
00527 INT _num_loops;
00528 double _num_cycles_inner;
00529 INT _num_fp_regs_inner;
00530 INT _num_fp_refs_inner;
00531 INT _num_int_regs_inner;
00532 INT _num_int_refs_inner;
00533 INT _unroll_prod_inner;
00534 INT64 *_est_num_iterations;
00535 INT *_required_unroll;
00536 INT *_required_blocksize;
00537 INT *_required_permutation;
00538
00539 INT *_block_number;
00540 INT *_new_order;
00541 INT *_iloop;
00542 INT *_stripsz;
00543 INT *_striplevel;
00544 INT _nstrips;
00545 INT _stripdepth;
00546 INT _inner_loop;
00547 double _num_cycles;
00548 INT _num_fp_regs;
00549 INT _num_fp_refs;
00550 INT _num_int_regs;
00551 INT _num_int_refs;
00552 INT _num_tlb;
00553 INT _unroll_prod;
00554
00555 INT _num_evaluations;
00556
00557 static INT _model_no;
00558 mBOOL _blocking_disabled;
00559
00560 static TI_RES_COUNT *OP_Resources(WN *wn, double *num_fp_instr,
00561 HASH_TABLE<WN *,BIT_VECTOR *> *invar_table);
00562 static double OP_Cycles(class REGISTER_MODEL *rmodel,
00563 double *num_fp_instr,
00564 HASH_TABLE<WN *,BIT_VECTOR *> *invar_table,
00565 MEM_POOL *pool);
00566 static INT OP_Resources_R(WN *wn,TI_RES_COUNT *resource_count,
00567 double *num_fp_instr,HASH_TABLE<WN *,BIT_VECTOR *> *invar_table);
00568 static INT FP_Cycles_Madd(WN *wn,TI_RES_COUNT *resource_count,
00569 double *num_fp_instr, HASH_TABLE<WN *,BIT_VECTOR *> *invar_table);
00570 static INT OP_Cycles_Cvt(OPCODE opcode,TI_RES_COUNT *resource_count,
00571 double *num_fp_instr);
00572 static INT FP_Cycles_Intrinsic(WN *wn,TI_RES_COUNT *resource_count,
00573 double *num_fp_instr);
00574 INT Unique_Unstored_Fp_Scalar_Refs(WN *wn, class ARRAY_REF *ar,
00575 SX_INFO *pi);
00576 INT Unique_Unstored_Int_Scalar_Refs(WN *wn, class ARRAY_REF *ar,
00577 SX_INFO *pi);
00578 void Try_Inner(BOOL *can_be_unrolled, INT outermost_can_be_tiled,
00579 INT inner, INT num_loops);
00580 void Try_Unroll(BOOL *can_be_unrolled, INT inner, INT num_loops,
00581 INT *unroll_factors,INT l, INT unroll_product,
00582 BOOL *can_reg_allocate, BOOL *try_further_unroll,
00583 class ARRAY_REF *arl);
00584 void Evaluate(INT inner, INT num_loops, INT *unroll_factors,
00585 INT unroll_product, BOOL *can_reg_allocate, BOOL *try_further_unroll,
00586 ARRAY_REF *arl, BOOL *can_be_unrolled);
00587 void Model_Results_Analysis(INT inner, INT num_loops,INT outermost_can_be_tiled,
00588 double machine_cycles, double cache_cycles, double overhead_cycles);
00589
00590 class ARRAY_REF *_arl;
00591 class LAT_DIRECTED_GRAPH16 *_lat_graph;
00592 WN *_wn;
00593
00594
00595 TI_RES_COUNT *_OP_resource_count;
00596 double *_loop_rcycles_unroll_by;
00597 double _LOOP_INIT_issue;
00598 double _OP_issue;
00599 double _issue_rate;
00600 double _latency_cycles;
00601 INT _base_fp_regs;
00602 INT _base_int_regs;
00603 INT _scalar_fp_regs;
00604 INT _scalar_int_regs;
00605 double _num_mem_units;
00606
00607 enum MODEL_LIMIT {MODEL_LIMIT_UNSET, MODEL_LIMIT_IDEAL, MODEL_LIMIT_RES,
00608 MODEL_LIMIT_LAT};
00609 MODEL_LIMIT _model_limit;
00610 public:
00611 friend class REGISTER_MODEL;
00612 INT Num_Fp_Regs() const {return _num_fp_regs;}
00613 INT Num_Fp_Refs() const {return _num_fp_refs;}
00614 INT Num_Int_Regs() const {return _num_int_regs;}
00615 INT Num_Int_Refs() const {return _num_int_refs;}
00616 INT Num_TLB() const {return _num_tlb;}
00617 static INT Model_No() {return _model_no;}
00618 INT Block_Number(INT i) const { return _block_number[i];}
00619 INT Iloop(INT i) const {
00620 Is_True(_iloop[i] >= _stripdepth, ("Bad cache blocking info in model"));
00621 return _iloop[i];
00622 }
00623 INT *Iloop() { return _iloop;}
00624 INT Stripsz(INT i) const { return _stripsz[i];}
00625 INT *Stripsz() const { return _stripsz;}
00626 INT Striplevel(INT i) const { return _striplevel[i];}
00627 INT *Striplevel() const { return _striplevel;}
00628 INT& Nstrips() { return _nstrips;}
00629 INT Stripdepth() const { return _stripdepth;}
00630 INT New_Order(INT i) const { return _new_order[i];}
00631 INT Inner_Loop() const { return _inner_loop; }
00632 double Num_Cycles() const { return _num_cycles; }
00633 LOOP_MODEL() {;};
00634 LOOP_MODEL(WN *wn, BOOL *can_be_inner, BOOL *can_be_unrolled,
00635 INT outermost_can_be_tiled,
00636 class ARRAY_DIRECTED_GRAPH16 *array_graph,
00637 class SX_INFO *pi, INT SNL_Depth,
00638 HASH_TABLE<WN *,BIT_VECTOR *> *invar_table) {
00639 Model(wn,can_be_inner,can_be_unrolled,outermost_can_be_tiled,array_graph,
00640 pi,SNL_Depth,invar_table);
00641 }
00642 void Model(WN *wn, BOOL *can_be_inner, BOOL *can_be_unrolled,
00643 INT outermost_can_be_tiled,
00644 class ARRAY_DIRECTED_GRAPH16 *array_graph,
00645 class SX_INFO *pi, INT SNL_Depth,
00646 HASH_TABLE<WN *,BIT_VECTOR *> *invar_table);
00647 ~LOOP_MODEL();
00648 };
00649
00650 typedef STACK<WN *> STATEMENT_STACK;
00651
00652 class REGISTER_MODEL {
00653 MEM_POOL *_pool;
00654 STATEMENT_STACK *_statement_stack;
00655 double Count_Op();
00656 double Count_Op(WN *wn);
00657 public:
00658 REGISTER_MODEL() {
00659 _pool = NULL;
00660 _statement_stack = NULL;
00661 }
00662 WN *Statement(INT i) {
00663 return _statement_stack->Bottom_nth(i);
00664 }
00665 INT Num_Statements() {
00666 return _statement_stack->Elements();
00667 }
00668 REGISTER_MODEL(MEM_POOL *pool) {
00669 _pool = pool;
00670 _statement_stack = CXX_NEW(STATEMENT_STACK(_pool),_pool);
00671 }
00672 void Init(MEM_POOL *pool) {
00673 _pool = pool;
00674 _statement_stack = CXX_NEW(STATEMENT_STACK(_pool),_pool);
00675
00676 }
00677 void Add_Statement(WN *wn) {
00678 _statement_stack->Push(wn);
00679 }
00680 void Calculate_Register_Usage(
00681 WN *inner, INT *fp_regs_used_out, INT *int_regs_used_out, INT *tlb_out);
00682 void Evaluate(WN *inner,
00683 WN2INT *se_needed,
00684 HASH_TABLE<WN *,BIT_VECTOR *> *invar_table,
00685 double *loop_cycles,
00686 INT *fp_regs_used_out,
00687 INT *int_regs_used_out,
00688 INT *tlb_out);
00689 ~REGISTER_MODEL() { CXX_DELETE(_statement_stack,_pool); };
00690 };
00691
00692
00693 class ARRAY_REF_NODE: public SLIST_NODE {
00694 DECLARE_SLIST_NODE_CLASS( ARRAY_REF_NODE);
00695 mUINT16 _lex_number;
00696 mUINT16 _unroll_copy[LNO_MAX_DO_LOOP_DEPTH];
00697
00698 mUINT16 _first_ref_store;
00699 mBOOL _is_invariant;
00700 mBOOL _is_cse;
00701 mINT16 _max_inner_offset;
00702
00703
00704 mINT16 _min_inner_offset;
00705
00706
00707 mBOOL _is_dup;
00708 mBOOL _has_dup_loads;
00709
00710 mBOOL _has_store;
00711 mBOOL _has_load;
00712 INT _element_size;
00713 public:
00714 ACCESS_ARRAY *Array;
00715 WN *Wn;
00716 ARRAY_REF_NODE(ACCESS_ARRAY *array, WN* wn, BOOL is_store, INT element_size,
00717 mUINT16 lex_number) {
00718 Array = array;
00719 Wn = wn;
00720 _lex_number = lex_number;
00721 for (INT i=0; i<array->Dim(0)->Nest_Depth(); i++) {
00722 _unroll_copy[i] = 0;
00723 }
00724 _is_invariant=FALSE;
00725 _is_cse=FALSE;
00726 _is_dup=FALSE;
00727 _has_dup_loads=FALSE;
00728 _max_inner_offset = INT16_MIN;
00729 _min_inner_offset = INT16_MAX;
00730 _has_store = is_store;
00731 _first_ref_store = is_store;
00732 _has_load = !is_store;
00733 _element_size = element_size;
00734 }
00735 ARRAY_REF_NODE(ARRAY_REF_NODE *in, MEM_POOL *pool) {
00736 Array = CXX_NEW(ACCESS_ARRAY(in->Array,pool),pool);
00737 Wn = in->Wn;
00738 _lex_number = in->_lex_number;
00739 INT bound = Array->Dim(0)->Nest_Depth();
00740 for (INT i=0; i<bound; i++) {
00741 _unroll_copy[i] = in->_unroll_copy[i];
00742 }
00743 _is_invariant = in->_is_invariant;
00744 _is_cse = in->_is_cse;
00745 _max_inner_offset = in->_max_inner_offset;
00746 _min_inner_offset = in->_min_inner_offset;
00747 _is_dup = in->_is_dup;
00748 _has_dup_loads = in->_has_dup_loads;
00749 _first_ref_store = in->_first_ref_store;
00750 _has_store = in->_has_store;
00751 _has_load = in->_has_load;
00752 _element_size = in->_element_size;
00753 }
00754 INT Element_Size() const {return _element_size;}
00755 void Print(FILE *fp) const;
00756 BOOL Lexically_Before(ARRAY_REF_NODE *node2);
00757 BOOL Has_Store() const {return _has_store;}
00758 };
00759
00760 class ARRAY_REF_LIST: public SLIST {
00761 DECLARE_SLIST_CLASS( ARRAY_REF_LIST, ARRAY_REF_NODE )
00762 MEM_POOL *_pool;
00763 mBOOL _is_scalar_expanded;
00764 public:
00765 ARRAY_REF_LIST(MEM_POOL *pool, SYMBOL *base_array) :
00766 _pool(pool), Base_Array(base_array) { _is_scalar_expanded = FALSE; }
00767 ARRAY_REF_LIST(ARRAY_REF_LIST *orig, MEM_POOL *pool);
00768 void Calc_Regs_And_Refs(
00769 INT *num_fp_regs, INT *num_fp_refs,
00770 INT *num_fp_variant_stores, INT *num_fp_invariant_stores,
00771 INT *num_int_regs, INT *num_int_refs,
00772 INT *num_int_variant_stores, INT *num_int_invariant_stores) ;
00773 INT Conflict_Refs(INT max_dim, BOOL *can_be_unrolled, INT num_loops);
00774 void Remove_Cse(INT inner, INT max_dist, INT step);
00775 void Remove_Invariants(INT loop_no);
00776 void Mark_Invariants(INT loop_no);
00777 void Unroll(INT loop_no, INT num_copies);
00778 INT Num_Invariants(INT loop_no);
00779 BOOL Is_Scalar_Expanded() const { return _is_scalar_expanded;}
00780 INT Num_Fp_Refs() const;
00781 INT Num_Int_Refs() const;
00782 SYMBOL *Base_Array;
00783 void Print(FILE *fp) const;
00784 ~ARRAY_REF_LIST();
00785 };
00786
00787 class ARRAY_REF_ITER: public SLIST_ITER {
00788 DECLARE_SLIST_ITER_CLASS( ARRAY_REF_ITER, ARRAY_REF_NODE ,ARRAY_REF_LIST)
00789 public:
00790 ~ARRAY_REF_ITER() {}
00791 };
00792
00793 class ARRAY_REF_CONST_ITER: public SLIST_ITER {
00794 DECLARE_SLIST_CONST_ITER_CLASS( ARRAY_REF_CONST_ITER, ARRAY_REF_NODE ,ARRAY_REF_LIST)
00795 public:
00796 ~ARRAY_REF_CONST_ITER() {}
00797 };
00798
00799 typedef STACK<ARRAY_REF_LIST *> ARRAY_REF_STACK;
00800 typedef STACK<DO_LOOP_INFO *> DLI_STACK;
00801 class ARRAY_REF
00802 {
00803 public:
00804 void Calc_Regs_And_Refs(
00805 INT *num_fp_regs, INT *num_fp_refs,
00806 INT *num_fp_variant_stores, INT *num_fp_invariant_stores,
00807 INT *num_int_regs, INT *num_int_refs,
00808 INT *num_int_variant_stores, INT *num_int_invariant_stores) ;
00809 INT Conflict_Refs(BOOL *can_be_unrolled, INT num_loops);
00810 void Remove_Cse(INT inner, INT max_dist, INT step);
00811 void Remove_Invariants(INT loop_no);
00812 void Unroll(INT loop_no, INT num_copies);
00813 void Mark_Invariants(INT loop_no);
00814 INT Num_Invariants(INT loop_no);
00815 ARRAY_REF(WN *wn, INT SNL_Depth, MEM_POOL *pool,
00816 HASH_TABLE<WN *,BIT_VECTOR *> *invar_table) : _stack(pool) {
00817 _pool = pool;
00818 _num_bad_fp = 0;
00819 _num_bad_int = 0;
00820 _lex_number = 0;
00821 Build(wn, SNL_Depth,invar_table);
00822 }
00823 INT Num_Fp_Refs() const;
00824 INT Num_Int_Refs() const;
00825 ARRAY_REF(MEM_POOL *pool) : _stack(pool) {
00826 _pool = pool;
00827 _num_bad_fp = 0;
00828 _num_bad_int = 0;
00829 }
00830 void Add_References(WN *wn, INT SNL_Depth,HASH_TABLE<WN *,BIT_VECTOR *> *invar_table) {
00831 Build(wn, SNL_Depth,invar_table);
00832 }
00833
00834 void Enter_Scalar_Expand(WN *wn,SX_PNODE *pnode, BOOL *can_be_inner,
00835 INT num_loops);
00836 void Enter_Scalar_Expand(BIT_VECTOR *bv, WN *wn);
00837 void Enter_Innermost_Scalar_Expand(WN *wn);
00838 ARRAY_REF(ARRAY_REF *orig, MEM_POOL *pool);
00839 void Push(ARRAY_REF_LIST *arl) { _stack.Push(arl); }
00840 INT Num_Fp_Bad() const { return _num_bad_fp; };
00841 INT Num_Int_Bad() const { return _num_bad_int; };
00842 INT Num_Bad() const { return _num_bad_int+_num_bad_fp; };
00843 ARRAY_REF_LIST *Array_Ref_List(INT i) { return _stack.Bottom_nth(i); }
00844 const ARRAY_REF_LIST *Array_Ref_List(INT i) const { return _stack.Bottom_nth(i); }
00845 INT Elements() const { return _stack.Elements(); }
00846 void Print(FILE *fp) const;
00847 ~ARRAY_REF() {};
00848 private:
00849 ARRAY_REF_STACK _stack;
00850 MEM_POOL *_pool;
00851 INT _num_bad_fp;
00852 INT _num_bad_int;
00853 void Build(WN *wn, INT SNL_Depth,HASH_TABLE<WN *,BIT_VECTOR *> *invar_table);
00854 void Build_Rec(WN *wn, DLI_STACK *dli_stack, INT SNL_Depth,
00855 HASH_TABLE<WN *,BIT_VECTOR *> *invar_table);
00856 void Build_Array(WN *wn, BOOL is_store, DLI_STACK *dli_stack, INT SNL_Depth);
00857 mUINT16 _lex_number;
00858 };
00859
00860
00861
00862
00863 class LAT_VERTEX16: public VERTEX16 {
00864 WN *_wn;
00865 public:
00866 LAT_VERTEX16(WN *wn) {_wn = wn;};
00867 friend class LAT_DIRECTED_GRAPH16;
00868 };
00869
00870 class LAT_EDGE16 : public EDGE16 {
00871 public:
00872 UINT16 Latency;
00873 UINT16 _num_unused_dim;
00874 friend class LAT_DIRECTED_GRAPH16;
00875 DEPV *Depv;
00876
00877 };
00878
00879 class LAT_DIRECTED_GRAPH16 :
00880 public DIRECTED_GRAPH16<LAT_EDGE16,LAT_VERTEX16> {
00881 MEM_POOL *_pool;
00882 mUINT8 _num_dim;
00883 mUINT8 _num_bad;
00884 HASH_TABLE<VINDEX16,VINDEX16>
00885 _hash_table;
00886 ARRAY_DIRECTED_GRAPH16 *_array_graph;
00887 public:
00888 LAT_DIRECTED_GRAPH16(mUINT16 num_v, mUINT16 num_e,
00889 mUINT8 num_dim, mUINT8 num_bad, MEM_POOL *pool,
00890 ARRAY_DIRECTED_GRAPH16 *array_graph) :
00891 DIRECTED_GRAPH16<LAT_EDGE16,LAT_VERTEX16>(num_v,num_e),
00892 _hash_table(200,pool) {
00893 _num_dim = num_dim;
00894 _num_bad = num_bad;
00895 _array_graph = array_graph;
00896 _pool = pool;
00897 Lat_scc_vertex_map = NULL;
00898 Scc_lat_vertex_map = NULL;
00899 }
00900 ~LAT_DIRECTED_GRAPH16() {
00901 if (Scc_lat_vertex_map) CXX_DELETE_ARRAY(Scc_lat_vertex_map,_pool);
00902 }
00903 VINDEX16 *Lat_scc_vertex_map;
00904 VINDEX16 *Scc_lat_vertex_map;
00905 void Set_Scc_Graph(SCC_DIRECTED_GRAPH16 *scc_graph, INT inner);
00906 double Max_Cycle(INT inner,double lower_bound);
00907 BOOL Is_Valid(INT inner, EINDEX16 e);
00908 void Print(FILE *fp);
00909 EINDEX16 Add_Edge(VINDEX16 from, VINDEX16 to, DEPV *depv, INT latency,
00910 UINT16 num_unused_dim) {
00911 EINDEX16 result =
00912 DIRECTED_GRAPH16<LAT_EDGE16,LAT_VERTEX16>::Add_Edge(from,to);
00913 if (result != 0) {
00914 _e[result].Depv = depv;
00915 _e[result].Latency = latency;
00916 _e[result]._num_unused_dim = num_unused_dim;
00917 }
00918 return result;
00919 }
00920 INT Latency(EINDEX16 edge) {
00921 return(_e[edge].Latency);
00922 }
00923 DEPV *Depv(EINDEX16 edge) {
00924 return(_e[edge].Depv);
00925 }
00926 UINT16 Num_Unused_Dim(EINDEX16 edge) {
00927 return(_e[edge]._num_unused_dim);
00928 }
00929 VINDEX16 Add_Vertex(WN *wn) {
00930 VINDEX16 result =
00931 DIRECTED_GRAPH16<LAT_EDGE16,LAT_VERTEX16>::Add_Vertex();
00932 _v[result]._wn = wn;
00933 return result;
00934 }
00935 WN *Wn(VINDEX16 v) {
00936 return _v[v]._wn;
00937 }
00938 void Remove_Edge(EINDEX16 e) {
00939 DIRECTED_GRAPH16<LAT_EDGE16,LAT_VERTEX16>::Delete_Edge(e);
00940 }
00941 void Delete_Edge(EINDEX16 e) {
00942 CXX_DELETE_ARRAY(_e[e].Depv,_pool);
00943 DIRECTED_GRAPH16<LAT_EDGE16,LAT_VERTEX16>::Delete_Edge(e);
00944 }
00945 void Map_Vertex(VINDEX16 oldv, VINDEX16 newv) {
00946 _hash_table.Enter(oldv, newv);
00947 }
00948 INT Add_Flow_Edges();
00949 INT Add_Vertices_Op_Edges(WN *wn, HASH_TABLE<WN *,BIT_VECTOR *> *invar_table);
00950 mUINT8 Num_Dim() { return(_num_dim); }
00951 mUINT8 Num_Bad() { return(_num_bad); }
00952 private:
00953 INT Add_Vertices_Op_Edges_Rec(VINDEX16 store,WN *wn, INT latency,
00954 HASH_TABLE<WN *,BIT_VECTOR *> *invar_table);
00955 INT FP_Latency_Madd(VINDEX16 store,WN *wn, INT latency,
00956 HASH_TABLE<WN *,BIT_VECTOR *> *invar_table);
00957 INT FP_Latency_Cvt(OPCODE opcode);
00958 INT FP_Latency_Intrinsic(WN *wn);
00959 };
00960
00961
00962
00963 class COST {
00964 public:
00965 UINT16 Distance;
00966 UINT16 Latency;
00967 };
00968
00969 class COST_V {
00970 UINT16 _length;
00971 UINT16 _alloc_length;
00972 COST *_costs;
00973 public:
00974 COST_V();
00975 void Init() { _length = 0; }
00976 COST *Costs() { return _costs;};
00977 UINT16 Length() { return _length; }
00978 void Set_Length(UINT16 length) { _length = length; }
00979 void Push(UINT16 latency, UINT16 distance, MEM_POOL *pool);
00980 };
00981
00982 class COST_TABLE {
00983 UINT16 _maxn;
00984 UINT16 _n;
00985 COST_V *_data;
00986 MEM_POOL *_pool;
00987 double _min_ii;
00988 public:
00989 COST_TABLE(UINT16 n, MEM_POOL *pool);
00990 void Realloc(UINT16 n);
00991 double Init(INT inner, LAT_DIRECTED_GRAPH16 *graph,
00992 SCC_DIRECTED_GRAPH16 *scc_graph, INT scc_id, INT *scc_pos);
00993 void Print(FILE *fp);
00994 COST_V *Cost_V(UINT16 v1, UINT16 v2) { return &_data[_n*v1+v2];};
00995 double Solve(double init_min_ii);
00996 private:
00997 void Push(UINT16 v1, UINT16 v2, UINT16 latency, UINT16 distance) {
00998 _data[_n*v1+v2].Push(latency,distance,_pool);
00999 }
01000 void Add_Maximal_Costs(COST_V *cvij, COST_V *cvik, COST_V *cvkj);
01001 BOOL Is_Max_Cost(INT dist, INT latency, COST_V *cv, INT offset);
01002 void Update_Min_II(COST_V *cv1, COST_V *cv2);
01003 };
01004
01005
01006
01007
01008 class SYMBOL_TREE_NODE
01009 {
01010 SYMBOL_TREE_NODE *_left;
01011 SYMBOL_TREE_NODE *_right;
01012 SYMBOL _symbol;
01013 BOOL _is_store;
01014 INT _weight;
01015 public:
01016 SYMBOL_TREE_NODE(SYMBOL symbol, BOOL is_store, INT weight) {
01017 _symbol = symbol;
01018 _is_store = is_store;
01019 _left = _right = NULL;
01020 _weight = weight;
01021 }
01022 INT Num_Fp_Unstored() const;
01023 INT Num_Int_Unstored() const;
01024 INT Symbol_Compare(SYMBOL *s) {
01025 if (_symbol.ST_Base() < s->ST_Base()) return(-1);
01026 else if (_symbol.ST_Base() > s->ST_Base()) return(1);
01027 else if (_symbol.ST_Offset() < s->ST_Offset()) return(-1);
01028 else if (_symbol.ST_Offset() > s->ST_Offset()) return(1);
01029 else if (_symbol.WN_Offset() < s->WN_Offset()) return(-1);
01030 else if (_symbol.WN_Offset() > s->WN_Offset()) return(1);
01031 else return(0);
01032 }
01033 void Enter(SYMBOL *symbol, MEM_POOL *pool, BOOL Is_Store, INT weight);
01034
01035 };
01036
01037
01038 class SYMBOL_TREE
01039 {
01040 SYMBOL_TREE_NODE *_symbol_node;
01041 BOOL _is_floating_point;
01042 MEM_POOL *_pool;
01043 SYMBOL _innermost_loop_var_symb;
01044 public:
01045 SYMBOL_TREE(BOOL is_floating_point, MEM_POOL *pool){
01046 _is_floating_point= is_floating_point;
01047 _symbol_node = NULL; _pool = pool; };
01048
01049 void Initialize_Innermost_Loop_Var_Symbol(WN* wn);
01050 BOOL Integer_Ref_Needs_Reg(WN* wn);
01051 void Enter(SYMBOL *symbol, BOOL is_store, INT weight) {
01052 if (!_symbol_node) {
01053 _symbol_node = CXX_NEW(SYMBOL_TREE_NODE(*symbol,is_store,weight),_pool);
01054 } else {
01055 _symbol_node->Enter(symbol,_pool,is_store,weight);
01056 }
01057 };
01058 void Enter_Scalar_Refs(WN *wn, INT *num_scalar_refs,
01059 WN2INT* se_needed=NULL, ARRAY_REF *ar=NULL);
01060 void Enter_Scalar_Refs(WN *wn, ARRAY_REF *ar, SX_INFO *pi,
01061 BOOL *can_be_inner, INT num_loops, INT outer,
01062 INT *num_scalar_refs);
01063 INT Num_Fp_Unstored() const {
01064 if (_symbol_node) return _symbol_node->Num_Fp_Unstored();
01065 return(0);
01066 }
01067 INT Num_Int_Unstored() const {
01068 if (_symbol_node) return _symbol_node->Num_Int_Unstored();
01069 return(0);
01070 }
01071 };
01072
01073
01074
01075 #endif // MODEL_DELCARE
01076