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 #ifndef if_conv_INCLUDED
00031 #define if_conv_INCLUDED
00032
00033 #include <vector>
00034 #include <set>
00035 #include "bb.h"
00036 #include "defs.h"
00037 #include "mempool.h"
00038 #include "error.h"
00039 #include "bb_set.h"
00040 #include "region.h"
00041 #include "cgtarget.h"
00042
00043
00044
00045 #define IF_CONV_BIASE_THRESHOLD 20 //in percent
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 class IF_CONV_AREA;
00060 class BB_PREDICATE_INFO;
00061
00062 typedef mempool_allocator<IF_CONV_AREA *> IF_CONV_ALLOC;
00063 typedef std::vector<IF_CONV_AREA *, IF_CONV_ALLOC> AREA_CONTAINER;
00064
00065 typedef mempool_allocator<TN*> TN_CONTAINER_ALLOC;
00066 typedef std::vector<TN*, TN_CONTAINER_ALLOC> TN_CONTAINER;
00067
00068 typedef mempool_allocator<BB *> BB_CONTAINER_ALLOC;
00069 typedef std::vector<BB *, BB_CONTAINER_ALLOC> BB_CONTAINER;
00070
00071 class TN_INFO_MEM
00072 {
00073 public:
00074 MEM_POOL _m;
00075
00076 TN_INFO_MEM(void) {
00077 MEM_POOL_Initialize(&_m, "TN_INFO_MEM", true);
00078 MEM_POOL_Push(&_m);
00079 }
00080
00081 ~TN_INFO_MEM(void) {
00082 MEM_POOL_Pop( &_m );
00083 MEM_POOL_Delete(&_m );
00084 };
00085 };
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 enum AREA_TYPE
00105 {
00106 SUITABLE_FOR_IF_CONV = 0x00,
00107 UPWARD_UNSUITABLE = 0x01,
00108 DOWNWARD_UNSUITABLE = 0x02,
00109 UNSUITABLE = 0x03
00110 };
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 enum IF_CONV_TYPE
00125 {
00126 NO_IF_CONV = 0x1,
00127 PARTIAL_IF_CONV = 0x2,
00128 FULLY_IF_CONV = 0x4
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 enum CFLOW_TYPE
00162 {
00163 NO_TYPE = 0x1,
00164 SERIAL_TYPE = 0x2,
00165 IF_THEN_TYPE = 0x4,
00166 IF_THEN_ELSE_TYPE = 0x8
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 enum BB_MERGE_TYPE
00200 {
00201 CASE_ALL_IN_AREA = 0x1,
00202 CASE_CALL_OUT = 0x2,
00203 CASE_CALL_IN = 0x3,
00204 CASE_UNCOND_BR = 0x4,
00205 CASE_FALL_OUT = 0x5,
00206 CASE_IF_FALL_IN = 0x6,
00207 CASE_IF_FALL_OUT = 0x7,
00208 CASE_IF_OUT = 0x8,
00209 CASE_CHECK_IN = 0x9,
00210 CASE_CHECK_OUT = 0x10
00211 };
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 class IF_CONVERTOR;
00227
00228 class CNTL_DEP
00229 {
00230 private:
00231 BB *_entry;
00232
00233
00234
00235 BB_SET *_bb_set;
00236
00237
00238 BB_MAP _control_dependences;
00239
00240
00241
00242 BB_MAP _true_edges;
00243
00244
00245
00246 void _Post_Order_Helper(BB_CONTAINER& result, BB *bb, IF_CONVERTOR*);
00247 public:
00248
00249
00250
00251 CNTL_DEP(BB *, BB_CONTAINER&, MEM_POOL *);
00252 ~CNTL_DEP()
00253 {
00254 BB_MAP_Delete(_control_dependences);
00255 BB_MAP_Delete(_true_edges);
00256 }
00257
00258
00259 BB_SET *Cntl_Dep_Parents(BB *bb)
00260 {
00261 BB_SET* set = (BB_SET*)BB_MAP_Get(_control_dependences, bb);
00262 Is_True( set != NULL, ("NULL cntl-dep-parents set!\n"));
00263 return set;
00264 }
00265
00266 BB_SET *True_Cntl_Dep_Parents(BB *bb){
00267 BB_SET* set = (BB_SET*)BB_MAP_Get(_true_edges, bb);
00268 Is_True( set != NULL, ("NULL true-edges-set set!\n"));
00269 return set;
00270 }
00271
00272
00273 BOOL Is_Cntl_Dep(BB *bb1, BB *bb2);
00274
00275
00276
00277 void Cntl_Dep_Children(BB_SET* &result, BB *, MEM_POOL *);
00278
00279
00280 void Get_Post_Order(BB_CONTAINER& result, IF_CONVERTOR *);
00281
00282
00283 void Print(FILE* file = stderr);
00284 };
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 class IF_CONV_MEM
00299 {
00300 protected:
00301 MEM_POOL _m;
00302
00303 IF_CONV_MEM(void) {
00304 MEM_POOL_Initialize(&_m, "IF_CONV_MEM", true);
00305 MEM_POOL_Push(&_m);
00306 }
00307
00308 ~IF_CONV_MEM(void) {
00309 MEM_POOL_Pop( &_m );
00310 MEM_POOL_Delete(&_m );
00311 };
00312 };
00313
00314 class IF_CONVERTOR : public IF_CONV_MEM
00315 {
00316 friend class IF_CONV_AREA;
00317 friend class CNTL_DEP;
00318 protected:
00319
00320 AREA_TYPE Suitable_For_If_Conv(BB *);
00321 BOOL Is_Partial_Redundant_Def(BB* bb, OP* op,TN* tn);
00322 void Compute_Min_Cycle(INT32&,BB_CONTAINER&);
00323 float Prob_Of_Area(IF_CONV_AREA *, IF_CONV_AREA *);
00324 INT32 Compute_Critical_Path_Len(BB *, BOOL);
00325 AREA_CONTAINER::iterator
00326 Find_Area(AREA_CONTAINER&, IF_CONV_AREA *);
00327 void Add_Edge(IF_CONV_AREA *, IF_CONV_AREA *);
00328 BOOL Is_BB_Container_Member(BB_CONTAINER&, BB*);
00329
00330 private:
00331
00332 INT32 _loop_length;
00333
00334
00335 void If_Conversion_Init(REGION *region,
00336 AREA_CONTAINER& area_list);
00337
00338
00339 void Select_Candidates (AREA_CONTAINER&, BOOL forced=FALSE);
00340 CFLOW_TYPE
00341 Detect_Type (IF_CONV_AREA *,
00342 AREA_CONTAINER&,
00343 BOOL forced = FALSE);
00344 BOOL Worth_If_Convert (AREA_CONTAINER&,
00345 CFLOW_TYPE,
00346 BOOL forced=FALSE);
00347 void Reduce_By_Type(AREA_CONTAINER&,
00348 CFLOW_TYPE,
00349 AREA_CONTAINER&);
00350
00351
00352 BOOL Check_If_Gen_Useless_Predicate(BB_PREDICATE_INFO *);
00353 void Find_Start_Node(IF_CONV_AREA *, BB *);
00354 void Record_Para_Comp_Info(IF_CONV_AREA *, BB *);
00355 void Detect_Para_Comp(IF_CONV_AREA *);
00356 void Gen_Para_Comp(IF_CONV_AREA *area);
00357 void Gen_Predicate_Assign(TN *, TN *, OP *, COMPARE_TYPE, TOP, TN *,
00358 OPS *);
00359 TN *Get_1_Pred_And_Erase(TN_CONTAINER&);
00360 BOOL Get_2_Pred_And_Erase(TN*&, TN*&, COMPARE_TYPE&, BB*,
00361 BB_PREDICATE_INFO *);
00362 BOOL Has_Para_Comp_Top(OP*);
00363 TOP Get_Para_Comp_Top(OP*, COMPARE_TYPE);
00364 TN* Get_Start_Node_Pred(TN *, BB *, IF_CONV_AREA *);
00365
00366
00367 BOOL Insert_Predicate(IF_CONV_AREA *area);
00368
00369
00370 BOOL Convert_Candidates(AREA_CONTAINER& areas);
00371 BB_MERGE_TYPE
00372 Classify_BB(BB *,IF_CONV_AREA *);
00373 void Merge_Blocks(BB *, BB *);
00374 void Merge_Area(IF_CONV_AREA *area);
00375 void Set_Fall_Thru(BB* , BB* );
00376 BOOL Can_Merge_Into_One_BB(IF_CONV_AREA*);
00377 BOOL Can_Merge_Into_One_Area(AREA_CONTAINER&);
00378
00379 void Print_All_Areas(AREA_CONTAINER&, FILE* file = stderr);
00380 void Print_BB_Merge_Type(BB_MERGE_TYPE, FILE* file = stderr);
00381 INT32 Calculate_Loop_Critical_Length (IF_CONV_AREA* area);
00382 INT32 Calculate_Loop_Cycled_Critical_Length (IF_CONV_AREA* area);
00383
00384 public:
00385 IF_CONVERTOR(void);
00386 IF_CONVERTOR(REGION_TREE *);
00387 ~IF_CONVERTOR(void) {}
00388
00389 BB *Force_If_Convert(LOOP_DESCR *, BOOL);
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 class EXIT_TARGET_INFO {
00417 private:
00418 BB *_target;
00419 TN_CONTAINER _main_predicates;
00420 TN_CONTAINER _aux_predicates;
00421
00422 public:
00423 EXIT_TARGET_INFO(BB* tgt, MEM_POOL* mem_pool):
00424 _aux_predicates(TN_CONTAINER_ALLOC(mem_pool))
00425 {
00426 _target = tgt;
00427 }
00428 ~EXIT_TARGET_INFO(void);
00429
00430 BB *Target(void) { return _target; }
00431 TN_CONTAINER& Main_Predicate(void) { return _main_predicates; }
00432 TN_CONTAINER& Aux_Predicates(void) { return _aux_predicates; }
00433 void Add_Main_Predicate(TN* tn) { _main_predicates.push_back(tn); }
00434 void Del_Main_Predicate(TN* tn);
00435 void Add_Aux_Predicate(TN* tn) { _aux_predicates.push_back(tn); }
00436
00437 BOOL Is_Main_Predicate(TN*);
00438 void Assign_Aux_Predicates(BB* bb, OP *br);
00439 void Update_Predicate(TN *old_tn, TN* new_tn);
00440
00441 };
00442
00443 typedef mempool_allocator<EXIT_TARGET_INFO*> EXIT_CONTAINER_ALLOC;
00444 typedef std::vector<EXIT_TARGET_INFO*, EXIT_CONTAINER_ALLOC> EXIT_CONTAINER;
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 class IF_CONV_AREA
00462 {
00463 friend class IF_CONVERTOR;
00464 private:
00465
00466
00467 BB *_head;
00468
00469 BB_CONTAINER _included_blocks;
00470
00471
00472 INT32 _cycled_critical_length;
00473
00474 INT32 _critical_length;
00475
00476 AREA_CONTAINER _predecessors;
00477 AREA_CONTAINER _successors;
00478
00479
00480
00481 AREA_TYPE _if_suitable;
00482 IF_CONV_TYPE _need_if_convert;
00483
00484
00485 CNTL_DEP *_control_deps;
00486
00487
00488
00489 BB_MAP _pred_assign_info;
00490
00491 EXIT_CONTAINER _exit_targets;
00492
00493
00494 BOOL _Find_Area(AREA_CONTAINER&, IF_CONV_AREA*);
00495 public:
00496
00497 IF_CONV_AREA(BB *, IF_CONVERTOR *);
00498 ~IF_CONV_AREA(void)
00499 {
00500 if ( _pred_assign_info )
00501 BB_MAP_Delete( _pred_assign_info);
00502 }
00503
00504 protected:
00505
00506 BB *Entry_BB(void) { return _head; }
00507 mBB_NUM Area_Label(void){ return BB_id(_head); }
00508 BB_CONTAINER& Blocks(void) { return _included_blocks; }
00509 void Remove_BB(BB*);
00510
00511 EXIT_CONTAINER& Exit_Targets(void) { return _exit_targets; }
00512
00513 AREA_TYPE Area_Type(void) { return _if_suitable; }
00514 void Area_Type(AREA_TYPE t)
00515 { _if_suitable = (AREA_TYPE)(((INT)_if_suitable)|t);
00516 }
00517
00518 IF_CONV_TYPE Conv_Type(void) { return _need_if_convert; }
00519 void Conv_Type (IF_CONV_TYPE t) { _need_if_convert = t; }
00520
00521 INT32 Cycled_Critical_Len(void) { return _cycled_critical_length;}
00522 void Cycled_Critical_Len(INT32 len) { _cycled_critical_length = len; }
00523
00524 INT32 Critical_Len(void) { return _critical_length; }
00525 void Critical_Len(INT32 len) { _critical_length = len; }
00526
00527 AREA_CONTAINER& Pred_Set(void){ return _predecessors; }
00528 AREA_CONTAINER& Succ_Set(void){ return _successors; }
00529 INT Pred_Num(void){ return _predecessors.size(); }
00530 INT Succ_Num(void){ return _successors.size(); }
00531
00532 CNTL_DEP *Cntl_Dep_Info(void){ return _control_deps; }
00533 BB_PREDICATE_INFO *Pred_Assign_Info(BB *bb)
00534 {
00535 return (BB_PREDICATE_INFO*)BB_MAP_Get(_pred_assign_info, bb);
00536 }
00537
00538 BOOL Is_Succ(IF_CONV_AREA *area,IF_CONVERTOR *convertor)
00539 {
00540 if (convertor -> Find_Area(_successors, area) != _successors.end())
00541 return true;
00542 return false;
00543 }
00544 BOOL Is_Pred(IF_CONV_AREA *area, IF_CONVERTOR *convertor)
00545 {
00546 if (convertor -> Find_Area(_predecessors, area) != _predecessors.end())
00547 return true;
00548 return false;
00549 }
00550 void Add_Succ(IF_CONV_AREA *area, IF_CONVERTOR *convertor)
00551 {
00552 if ( !Is_Succ(area,convertor))
00553 _successors.push_back(area);
00554 }
00555 void Add_Pred(IF_CONV_AREA *area, IF_CONVERTOR *convertor)
00556 {
00557 if ( !Is_Pred(area,convertor))
00558 _predecessors.push_back(area);
00559 }
00560 void Del_Succ(IF_CONV_AREA *area, IF_CONVERTOR *convertor)
00561 {
00562 if ( Is_Succ(area,convertor))
00563 _successors.erase( convertor ->Find_Area(_successors, area));
00564 }
00565 void Del_Pred(IF_CONV_AREA *area, IF_CONVERTOR *convertor)
00566 {
00567 if ( area -> Is_Succ(this,convertor))
00568 _predecessors.erase(convertor -> Find_Area(_predecessors, area));
00569 }
00570
00571
00572
00573 void Init_Conversion_Info(MEM_POOL *);
00574
00575 EXIT_TARGET_INFO* Exit_Target(BB*);
00576 void Add_Exit_Target(BB* target, TN* predicate, MEM_POOL*);
00577
00578
00579 void Combine_Blocks_With(IF_CONV_AREA *, MEM_POOL *);
00580
00581 void Print(FILE *file = stderr);
00582 void Print_IR(FILE *file = stderr);
00583 };
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605 class BB_PREDICATE_INFO
00606 {
00607 private:
00608
00609 BB_MAP _start_nodes;
00610
00611 TN *_predicate;
00612
00613
00614
00615 TN *_orig_pred;
00616
00617
00618 BOOL _is_transitional;
00619 BOOL _eqv_class_head;
00620 BB* _eqv_class_head_bb;
00621
00622
00623
00624 TN *_true_tn;
00625 TN *_false_tn;
00626
00627 TN_CONTAINER _or_tns;
00628 TN_CONTAINER _orcm_tns;
00629 TN_CONTAINER _and_tns;
00630 TN_CONTAINER _andcm_tns;
00631
00632 public:
00633
00634 BB_PREDICATE_INFO(MEM_POOL *mem_pool):
00635 _or_tns(TN_CONTAINER_ALLOC(mem_pool)),
00636 _orcm_tns(TN_CONTAINER_ALLOC(mem_pool)),
00637 _and_tns(TN_CONTAINER_ALLOC(mem_pool)),
00638 _andcm_tns(TN_CONTAINER_ALLOC(mem_pool))
00639 {
00640 _start_nodes = 0;
00641 _predicate = 0;
00642 _orig_pred = 0;
00643 _is_transitional = false;
00644 _eqv_class_head = false;
00645 _true_tn = 0;
00646 _false_tn = 0;
00647 }
00648 ~BB_PREDICATE_INFO(void)
00649 {
00650 if (_start_nodes)
00651 BB_MAP_Delete(_start_nodes);
00652 }
00653
00654
00655 BOOL Transitional(void) { return _is_transitional; }
00656 void Set_Transitional(void) { _is_transitional = true; }
00657
00658 BOOL Eqv_Class_Head(void) { return _eqv_class_head; }
00659 void Set_Eqv_Class_Head(void){ _eqv_class_head = true; }
00660
00661 BB* Eqv_Class_Head_BB(void) { return _eqv_class_head_bb; }
00662 void Eqv_Class_Head_BB(BB* bb){ _eqv_class_head_bb = bb; }
00663
00664
00665 BOOL Has_Start_Node(void) { return _start_nodes != 0; }
00666 BB *Start_Node(BB *pred)
00667 {
00668 return (BB*)BB_MAP_Get(_start_nodes, pred);
00669 }
00670 void Start_Node(BB *start_node, BB *pred)
00671 {
00672 if (! _start_nodes)
00673 _start_nodes = BB_MAP_Create();
00674 BB_MAP_Set( _start_nodes, pred, start_node);
00675 }
00676
00677 TN *Predicate(void) { return _predicate; }
00678 void Predicate(TN *p) { _predicate = p; }
00679
00680 TN *Orig_Pred(void) { return _orig_pred; }
00681 void Orig_Pred(TN *p) { _orig_pred = p; }
00682
00683 TN *True_TN(void) { return _true_tn; }
00684 void True_TN(TN *tn) { _true_tn = tn; }
00685 TN *False_TN(void) { return _false_tn; }
00686 void False_TN(TN *tn) { _false_tn = tn; }
00687
00688 TN_CONTAINER& Or_TNs(void) { return _or_tns; }
00689 TN_CONTAINER& Orcm_TNs(void){ return _orcm_tns; }
00690 TN_CONTAINER& And_TNs(void) { return _and_tns; }
00691 TN_CONTAINER& Andcm_TNs(void){ return _andcm_tns; }
00692
00693 void Add_Or_TNs(TN *tn)
00694 {
00695 _or_tns.push_back(tn);
00696 }
00697 void Add_Orcm_TNs(TN *tn)
00698 {
00699 _orcm_tns.push_back(tn);
00700 }
00701 void Add_And_TNs(TN *tn)
00702 {
00703 _and_tns.push_back(tn);
00704 }
00705 void Add_Andcm_TNs(TN *tn)
00706 {
00707 _andcm_tns.push_back(tn);
00708 }
00709 };
00710
00711 extern hTN_MAPf frequency_of_predicates;
00712 extern hTN_MAP init_op_info;
00713 extern TN_INFO_MEM info_mem;
00714
00715 BOOL Is_Para_Comp_May_Def(OP* op);
00716 BOOL Is_In_Infinite_Loop(REGION*);
00717 BOOL Is_Abnormal_Loop(REGION*);
00718 static OP* TN_Defined_At_Op (TN *tn, OP *op, std::vector<OP *> *ops);
00719
00720 #endif