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 #define __STDC_LIMIT_MACROS
00063 #include <stdint.h>
00064 #include <alloca.h>
00065 #include <stdio.h>
00066 #include <iterator>
00067 #include "defs.h"
00068 #include "symtab.h"
00069 #include "config.h"
00070 #include "tracing.h"
00071 #include "erglob.h"
00072 #include "const.h"
00073 #include "glob.h"
00074 #include "config_asm.h"
00075 #include "wn.h"
00076 #include "ir_reader.h"
00077
00078 #include "targ_proc_properties.h"
00079 #include "strtab.h"
00080 #include "tn.h"
00081 #include "bb.h"
00082 #include "gra_live.h"
00083 #include "op.h"
00084 #include "cg_region.h"
00085 #include "tn_set.h"
00086 #include "gtn_universe.h"
00087 #include "gtn_tn_set.h"
00088 #include "note.h"
00089 #include "cgtarget.h"
00090 #include "cgexp.h"
00091 #include "irbdata.h"
00092 #include "whirl2ops.h"
00093 #include "xstats.h"
00094 #include "data_layout.h"
00095 #include "freq.h"
00096 #include "cg_loop.h"
00097 #include "label_util.h"
00098 #include "lra.h"
00099 #include "bb_set.h"
00100 #include "DaVinci.h"
00101 #include "cg.h"
00102 #ifdef TARG_IA64
00103 #include "ipfec_options.h"
00104 #include "region_bb_util.h"
00105 #include "region.h"
00106 #include <vector>
00107 #include "if_conv.h"
00108 #endif
00109
00110
00111 #define BB_Alloc() TYPE_PU_ALLOC(BB)
00112 #define BB_Alloc_N(n) TYPE_PU_ALLOC_N(BB, n)
00113 #define BB_MEM_pool_ptr MEM_pu_pool_ptr
00114 #define BB_MEM_pool MEM_pu_pool
00115
00116 mBB_NUM *bb_dfo_id;
00117 BB **bb_dfo_vec;
00118 INT min_dfo_id;
00119
00120 BB_LIST *Entry_BB_Head;
00121 BB_LIST *Exit_BB_Head;
00122 BB *REGION_First_BB;
00123 BB_NUM PU_BB_Count;
00124
00125
00126
00127 #define BB_VEC_INCR 32
00128 static BB_NUM BB_Vec_Count;
00129 BB **BB_Vec;
00130
00131 static BB_MAP bb_st_map;
00132 static INT32 bb_st_count = 0;
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 void
00145 BB_PU_Initialize(void)
00146 {
00147 BB_Vec_Count = 0;
00148 PU_BB_Count = 0;
00149 REGION_First_BB = NULL;
00150 Entry_BB_Head = NULL;
00151 Exit_BB_Head = NULL;
00152 bb_st_map = 0;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 void
00164 BB_REGION_Initialize(void)
00165 {
00166 REGION_First_BB = NULL;
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 BB *
00179 Gen_BB (void)
00180 {
00181 BB *bp;
00182
00183 bp = BB_Alloc();
00184 if (bp == NULL) ErrMsg(EC_No_Mem, "Gen_BB");
00185
00186 if (PU_BB_Count >= BB_NUM_MAX) ErrMsg(EC_Out_Of, "BB numbers", "Gen_BB");
00187 bp->id = ++PU_BB_Count;
00188 PU_BB_Cnt++;
00189
00190
00191
00192 if (PU_BB_Count + 1 > BB_Vec_Count) {
00193 if (BB_Vec_Count == 0) {
00194 BB_Vec = TYPE_PU_ALLOC_N(BB *, PU_BB_Count + 1 + BB_VEC_INCR);
00195 BB_Vec_Count = PU_BB_Count + 1 + BB_VEC_INCR;
00196 } else {
00197 BB_NUM size = BB_Vec_Count * 2;
00198 while (size <= PU_BB_Count)
00199 size *= 2;
00200 BB_Vec = TYPE_MEM_POOL_REALLOC_N(BB *,
00201 BB_MEM_pool_ptr,
00202 BB_Vec,
00203 BB_Vec_Count,
00204 size);
00205 BB_Vec_Count = size;
00206 }
00207 }
00208
00209 BB_Vec[PU_BB_Count] = bp;
00210
00211 return bp;
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 BB *
00225 Gen_BB_N (INT n)
00226 {
00227 BB *bp;
00228 INT i;
00229
00230 bp = BB_Alloc_N(n);
00231 if (bp == NULL) ErrMsg(EC_No_Mem, "Gen_BB_N");
00232
00233 if (PU_BB_Count + n > BB_NUM_MAX) ErrMsg(EC_Out_Of, "BB numbers", "Gen_BB_N");
00234
00235
00236
00237 if (PU_BB_Count + 1 + n > BB_Vec_Count) {
00238 if (BB_Vec_Count == 0) {
00239 BB_Vec = TYPE_PU_ALLOC_N(BB *, PU_BB_Count + 1 + n + BB_VEC_INCR);
00240 BB_Vec_Count = PU_BB_Count + 1 + n + BB_VEC_INCR;
00241 } else {
00242 BB_NUM size = BB_Vec_Count * 2;
00243 while (size <= PU_BB_Count + n)
00244 size *= 2;
00245 BB_Vec = TYPE_MEM_POOL_REALLOC_N(BB *,
00246 BB_MEM_pool_ptr,
00247 BB_Vec,
00248 BB_Vec_Count,
00249 size);
00250 BB_Vec_Count = size;
00251 }
00252 }
00253
00254
00255
00256 for (i = 0; i < n; i++) {
00257 PU_BB_Count++;
00258 BB_Vec[PU_BB_Count] = bp + i;
00259 bp[i].id = PU_BB_Count;
00260 }
00261
00262 return bp;
00263 }
00264
00265 BB *
00266 Gen_BB_Like (BB *model)
00267 {
00268 BB *bb = Gen_BB();
00269 if (model == NULL) model = REGION_First_BB;
00270 if (model) BB_rid(bb) = BB_rid(model);
00271 return bb;
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 BB *
00284 Gen_And_Append_BB (BB *prev_bb)
00285 {
00286 #ifdef KEY
00287
00288
00289
00290 BB *bb = Gen_BB_Like(prev_bb);
00291 #else
00292 BB *bb = Gen_BB();
00293 #endif
00294
00295 if (prev_bb != NULL) {
00296 Is_True (BB_next(prev_bb) == NULL,
00297 ("Gen_And_Append_BB: prev_bb not last one"));
00298 BB_next(prev_bb) = bb;
00299 BB_prev(bb) = prev_bb;
00300 }
00301 return bb;
00302 }
00303
00304 BB *Gen_And_Insert_BB_After(BB *point)
00305
00306
00307
00308
00309 {
00310 BB *bb = Gen_BB_Like(point);
00311 BB_prev(bb) = point;
00312 BB_next(bb) = BB_next(point);
00313 if ( BB_next(point) != NULL )
00314 BB_prev(BB_next(point)) = bb;
00315 BB_next(point) = bb;
00316
00317 return bb;
00318 }
00319
00320 BB* Gen_And_Insert_BB_Before(BB *point)
00321
00322
00323
00324
00325 {
00326 BB *bb = Gen_BB_Like(point);
00327
00328 BB_next(bb) = point;
00329 BB_prev(bb) = BB_prev(point);
00330 if (BB_prev(point))
00331 BB_next(BB_prev(point)) = bb;
00332 BB_prev(point) = bb;
00333
00334 return bb;
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 BB *
00346 Append_Region_BBs(BB *prev, RID *rid)
00347 {
00348 BB *first_bb;
00349 CGRIN *cgrin = RID_cginfo( rid );
00350 first_bb = CGRIN_first_bb( cgrin );
00351
00352 if ( first_bb == NULL )
00353 return prev;
00354
00355 if ( prev ) {
00356 BB_next( prev ) = first_bb;
00357 BB_prev( first_bb ) = prev;
00358 }
00359 else {
00360
00361
00362
00363 REGION_First_BB = first_bb;
00364 }
00365 #if 0
00366 return CGRIN_last_bb( cgrin );
00367 #endif
00368 BB *bb;
00369 for (bb = first_bb; BB_next(bb) != NULL; bb = BB_next(bb))
00370 ;
00371
00372 if (bb != CGRIN_last_bb(cgrin)) {
00373 DevWarn("CGRIN_last_bb of rid %d is not really the last one?", RID_id(rid));
00374 }
00375 return bb;
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 void
00394 Free_BB_Memory ( void )
00395 {
00396 BB *bb;
00397
00398 for ( bb = REGION_First_BB; bb; bb = BB_next(bb) ) {
00399 BBlist_Free ( &BB_preds(bb) );
00400 BBlist_Free ( &BB_succs(bb) );
00401 }
00402 REGION_First_BB = NULL;
00403
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 void
00419 Remove_BB ( BB *bb )
00420 {
00421 BB *p = BB_prev(bb);
00422 BB *n = BB_next(bb);
00423 RID *rid = BB_rid(bb);
00424 if (rid != NULL && RID_cginfo(rid) != NULL) {
00425
00426 CGRIN *cgrin = RID_cginfo( rid );
00427 if (cgrin && CGRIN_first_bb(cgrin) == bb)
00428 CGRIN_first_bb(cgrin) = n;
00429 if (cgrin && CGRIN_last_bb(cgrin) == bb)
00430 CGRIN_last_bb(cgrin) = p;
00431 }
00432
00433 if ( p != NULL ) {
00434 BB_next(p) = n;
00435 } else {
00436 REGION_First_BB = n;
00437 }
00438
00439 if ( n != NULL )
00440 BB_prev(n) = p;
00441
00442 BB_prev(bb) = BB_next(bb) = NULL;
00443 }
00444
00445
00446
00447 void
00448 Insert_BB ( BB *bb, BB *after )
00449 {
00450 BB *nx = (after!=NULL) ? BB_next(after) : REGION_First_BB;
00451
00452 BB_next(bb) = nx;
00453 BB_prev(bb) = after;
00454 if ( after != NULL ) {
00455 BB_next(after) = bb;
00456 } else {
00457 REGION_First_BB = bb;
00458 }
00459 if ( nx != NULL ) {
00460 BB_prev(nx) = bb;
00461 }
00462 if (after != NULL && BB_rid(after) != NULL && BB_rid(bb) == BB_rid(after)) {
00463
00464 CGRIN *cgrin = RID_cginfo(BB_rid(after));
00465 if (cgrin && CGRIN_last_bb(cgrin) == after)
00466 CGRIN_last_bb(cgrin) = bb;
00467 }
00468 }
00469
00470
00471
00472 void
00473 Move_BB ( BB *bb, BB *after )
00474 {
00475 Remove_BB ( bb );
00476 Insert_BB ( bb, after );
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 void
00488 Chain_BBs(
00489 BB *bb1,
00490 BB *bb2
00491 )
00492 {
00493 if (bb1) Verify_BB(bb1);
00494 if (bb2) Verify_BB(bb2);
00495 if (bb1) BB_next(bb1) = bb2;
00496 if (bb2) BB_prev(bb2) = bb1;
00497 if (bb1 && bb2 && BB_rid(bb1) != NULL && BB_rid(bb1) == BB_rid(bb2)) {
00498
00499 BB *bb;
00500 CGRIN *cgrin = RID_cginfo(BB_rid(bb1));
00501 if (cgrin && CGRIN_first_bb(cgrin) == bb2) {
00502 for (bb = bb1; BB_prev(bb); bb = BB_prev(bb))
00503 ;
00504 CGRIN_first_bb(cgrin) = bb;
00505 if (REGION_First_BB == bb2)
00506 REGION_First_BB = bb;
00507 }
00508 if (cgrin && CGRIN_last_bb(cgrin) == bb1) {
00509 for (bb = bb2; BB_next(bb); bb = BB_next(bb))
00510 ;
00511 CGRIN_last_bb(cgrin) = bb;
00512 }
00513 }
00514 }
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 void
00526 Target_Simple_Fall_Through_BB(
00527 BB *bb,
00528 BB *target_bb
00529 )
00530 {
00531 OP *br;
00532
00533 FmtAssert(BB_succs(bb) == NULL, ("Unexpected nonempty succ list."));
00534
00535 BB_next(bb) = target_bb;
00536 BB_prev(target_bb) = bb;
00537
00538 #ifdef TARG_IA64
00539 if(IPFEC_Enable_Region_Formation && RGN_Formed) {
00540 BB *bb_wo_node = NULL;
00541 REGIONAL_CFG_NODE *src_node = Regional_Cfg_Node(bb);
00542 REGIONAL_CFG_NODE *target_node = Regional_Cfg_Node(target_bb);
00543 Is_True(((src_node != NULL)||(target_node != NULL)),("Two node NULL error in Target Simple Fall Through BB"));
00544 if (target_node == NULL) {
00545 REGION *rgn = Home_Region(bb);
00546 REGIONAL_CFG *regional_cfg = rgn->Regional_Cfg();
00547 RGN_Gen_And_Insert_Node(target_bb,NULL,NULL,regional_cfg);
00548 } else if (src_node == NULL) {
00549 REGION *rgn = Home_Region(target_bb);
00550 REGIONAL_CFG *regional_cfg = rgn->Regional_Cfg();
00551 RGN_Gen_And_Insert_Node(bb,NULL,NULL,regional_cfg);
00552 }
00553 RGN_Link_Pred_Succ_With_Prob (bb, target_bb, 1.0F);
00554 } else {
00555 Link_Pred_Succ_with_Prob (bb, target_bb, 1.0F);
00556 }
00557 #else
00558 Link_Pred_Succ_with_Prob (bb, target_bb, 1.0F);
00559 #endif
00560
00561 br = BB_Remove_Branch(bb);
00562 FmtAssert(!(br && OP_cond(br)), ("Unexpected conditional branch."));
00563 }
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 void
00574 Target_Cond_Branch(
00575 BB *bb,
00576 BB *br_targ_bb,
00577 float prob
00578 )
00579 {
00580 INT32 opnd, opnd_count;
00581 OP *branch_op;
00582 LABEL_IDX targ_label = Gen_Label_For_BB(br_targ_bb);
00583 TN *targ_label_tn = Gen_Label_TN(targ_label,0);
00584
00585 branch_op = BB_branch_op(bb);
00586 FmtAssert(branch_op && OP_cond(branch_op),
00587 ("BB doesn't end in a conditional branch."));
00588
00589 Link_Pred_Succ_with_Prob (bb, br_targ_bb, prob);
00590
00591 CGTARG_Branch_Info(branch_op,&opnd,&opnd_count);
00592 FmtAssert(opnd_count == 1,("Branch with multiple bbs"));
00593 Set_OP_opnd(branch_op,opnd, targ_label_tn);
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 void
00605 Target_Logif_BB(
00606 BB *bb,
00607 BB *br_targ_bb,
00608 float br_targ_prob,
00609 BB *fall_through_bb
00610 )
00611 {
00612 INT32 opnd, opnd_count;
00613 OP *branch_op;
00614 LABEL_IDX targ_label = Gen_Label_For_BB(br_targ_bb);
00615 TN *targ_label_tn = Gen_Label_TN(targ_label,0);
00616
00617 branch_op = BB_branch_op(bb);
00618 FmtAssert(branch_op && OP_cond(branch_op),
00619 ("BB doesn't end in a conditional branch."));
00620
00621 Chain_BBs(bb,fall_through_bb);
00622
00623 Link_Pred_Succ_with_Prob (bb, br_targ_bb, br_targ_prob);
00624 Link_Pred_Succ_with_Prob (bb, fall_through_bb, 1.0F - br_targ_prob);
00625
00626 CGTARG_Branch_Info(branch_op,&opnd,&opnd_count);
00627 FmtAssert(opnd_count == 1,("Branch with multiple bbs"));
00628 Set_OP_opnd(branch_op,opnd, targ_label_tn);
00629 }
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 void
00641 Negate_Logif_BB(
00642 BB *bb
00643 )
00644 {
00645 OP *op = BB_branch_op(bb);
00646 TOP old_top = OP_code(op);
00647 TOP new_top = CGTARG_Invert(old_top);
00648
00649 Is_True(new_top != TOP_UNDEFINED,
00650 ("unable to negate branch: %s", TOP_Name(old_top)));
00651 OP_Change_Opcode(op, new_top);
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 void
00664 Add_Goto_Op
00665 (
00666 BB *bb,
00667 BB *target_bb
00668 )
00669 {
00670 TN *target_label_tn = Gen_Label_TN(Gen_Label_For_BB(target_bb),0);
00671
00672 OPS ops = OPS_EMPTY;
00673 Exp_OP1(OPC_GOTO,NULL,target_label_tn,&ops);
00674
00675
00676
00677 SRCPOS srcpos = 0;
00678 if (BB_last_op(bb) != NULL) {
00679 srcpos = OP_srcpos(BB_last_op(bb));
00680 }
00681 if (srcpos == 0 && BB_prev(bb) != NULL && BB_last_op(BB_prev(bb)) != NULL) {
00682 srcpos = OP_srcpos(BB_last_op(BB_prev(bb)));
00683 }
00684
00685 OP *op;
00686 FOR_ALL_OPS_OPs(&ops, op) {
00687 OP_srcpos(op) = srcpos;
00688 }
00689 BB_Append_Ops(bb,&ops);
00690 }
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 void
00702 Add_Goto
00703 (
00704 BB *bb,
00705 BB *target_bb
00706 )
00707 {
00708 Add_Goto_Op(bb, target_bb);
00709 Link_Pred_Succ_with_Prob(bb, target_bb, 1.0F);
00710 }
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 BB*
00721 Create_Dummy_BB(
00722 BB *dest_bb
00723 )
00724 {
00725 BB *dummy_bb;
00726
00727 dummy_bb = Gen_BB();
00728 BB_rid(dummy_bb) = BB_rid(dest_bb);
00729
00730 Target_Simple_Fall_Through_BB(dummy_bb,dest_bb);
00731
00732 return dummy_bb;
00733 }
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746 static const char * const BBKIND_names[] = {
00747 "--UNKNOWN--",
00748 "GOTO",
00749 "LOGIF",
00750 "VARGOTO",
00751 "INDGOTO",
00752 "RETURN",
00753 "CALL",
00754 "REGION_EXIT",
00755 "TAIL_CALL",
00756 #ifdef TARG_IA64
00757 "CHK",
00758 #elif defined(TARG_SL)
00759 "BBKIND_ZDL_BODY",
00760 "BBKIND_FORK",
00761 #endif
00762 };
00763
00764
00765 const char *
00766 BBKIND_Name ( BBKIND k )
00767 {
00768 static char numbuf[11];
00769
00770 if ( ! VALID_BBKIND ( k ) ) {
00771 DevWarn ("BBKIND_Name called with unknown BBKIND");
00772 sprintf ( numbuf, "%u", k );
00773 return numbuf;
00774 }
00775
00776 return BBKIND_names[k];
00777 }
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 BBKIND
00789 BB_kind(BB *bb)
00790 {
00791 OP *br;
00792 INT nsuccs;
00793 INT tcount;
00794 INT tfirst;
00795
00796
00797
00798 if (BB_exit(bb)) return BB_call(bb) ? BBKIND_TAIL_CALL : BBKIND_RETURN;
00799
00800
00801
00802 if (BB_call(bb)) return BBKIND_CALL;
00803
00804 #if defined(TARG_SL)
00805 if ( BB_zdl_body(bb)) return BBKIND_ZDL_BODY;
00806 #endif
00807
00808 #ifdef TARG_IA64
00809
00810
00811 if (BB_Last_chk_op(bb)) return BBKIND_CHK;
00812 #endif
00813
00814
00815
00816 br = BB_branch_op(bb);
00817 nsuccs = BBlist_Len(BB_succs(bb));
00818
00819
00820
00821 if (br == NULL) {
00822
00823
00824
00825
00826
00827 if (nsuccs <= 1) return BBKIND_GOTO;
00828
00829
00830
00831 DevWarn("BB_kind: Unable to determine BB_kind for BB:%d", BB_id(bb));
00832 return BBKIND_UNKNOWN;
00833 }
00834
00835 #if defined(TARG_SL) && defined(TARG_SL2)
00836 if (OP_fork(br)) {
00837 FmtAssert(nsuccs == 2, ("BB_kind: FORK BB has %d successors", nsuccs));
00838 return BBKIND_FORK;
00839 }
00840 #endif
00841
00842
00843
00844 CGTARG_Branch_Info(br, &tfirst, &tcount);
00845
00846
00847
00848 if (OP_cond(br) && !OP_ijump(br)) {
00849 if (tcount != 1) {
00850 DevWarn("BB_kind: Conditional branch in BB:%d with %d labels",
00851 BB_id(bb), tcount);
00852 return BBKIND_UNKNOWN;
00853 }
00854
00855 switch (nsuccs) {
00856 case 1:
00857
00858
00859
00860 if (BBLIST_item(BB_succs(bb)) == BB_next(bb)) break;
00861
00862 DevWarn("BB_kind: LOGIF BB:%d doesn't have a fall through, nsuccs=%d",
00863 BB_id(bb),nsuccs);
00864 return BBKIND_UNKNOWN;
00865
00866 case 2:
00867
00868
00869
00870 if (BBLIST_item(BB_succs(bb)) == BB_next(bb) ||
00871 BBLIST_item(BBLIST_next(BB_succs(bb))) == BB_next(bb)) break;
00872
00873 DevWarn("BB_kind: LOGIF BB:%d doesn't have a fall through, nsuccs=%d",
00874 BB_id(bb),nsuccs);
00875 return BBKIND_UNKNOWN;
00876
00877 default:
00878 DevWarn("BB_kind: LOGIF BB:%d with %d successors", BB_id(bb), nsuccs);
00879 return BBKIND_UNKNOWN;
00880 }
00881
00882 return BBKIND_LOGIF;
00883 }
00884
00885
00886
00887
00888
00889 if (tcount == 0) {
00890 if (nsuccs == 1) {
00891 WN *wn = BB_branch_wn(bb);
00892 if (wn && WN_opcode(wn) == OPC_GOTO) return BBKIND_GOTO;
00893 }
00894
00895 ANNOTATION *ant = ANNOT_Get(BB_annotations(bb), ANNOT_SWITCH);
00896 return ant != NULL ? BBKIND_VARGOTO : BBKIND_INDGOTO;
00897 }
00898
00899
00900
00901 if (tcount != 1) {
00902 DevWarn("BB_kind: Branch with %d labels in BB:%d", tcount, BB_id(bb));
00903 return BBKIND_UNKNOWN;
00904 }
00905
00906
00907
00908 if (nsuccs == 0) {
00909 WN *wn = BB_branch_wn(bb);
00910 if (wn && WN_opcode(wn) == OPC_REGION_EXIT) return BBKIND_REGION_EXIT;
00911 }
00912
00913 if (nsuccs != 1) {
00914 DevWarn("BB_kind: GOTO BB:%d has %d successors", BB_id(bb), nsuccs);
00915 return BBKIND_UNKNOWN;
00916 }
00917
00918 return BBKIND_GOTO;
00919 }
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 void
00930 Print_LOOPINFO(LOOPINFO *info)
00931 {
00932 WN *loop_info = LOOPINFO_wn(info);
00933 fprintf(TFile, " Head of loop body line %d\n", LOOPINFO_line(info));
00934 fprintf(TFile, " ivar = ");
00935 fdump_tree(TFile, WN_loop_induction(loop_info));
00936 fprintf(TFile, " trip count = ");
00937 fdump_tree(TFile, WN_loop_trip(loop_info));
00938 if (WN_loop_trip_est(loop_info))
00939 fprintf(TFile, " trip count estimate = %u\n",
00940 WN_loop_trip_est(loop_info));
00941 fprintf(TFile, " nesting depth = %u\n", WN_loop_depth(loop_info));
00942 fprintf(TFile, " flags = ");
00943 if (WN_Loop_Innermost(loop_info)) fprintf(TFile, "INNERMOST ");
00944 if (WN_Loop_Winddown_Reg(loop_info)) fprintf(TFile, "WINNDOWN_REG ");
00945 if (WN_Loop_Winddown_Cache(loop_info)) fprintf(TFile, "WINNDOWN_CACHE ");
00946 if (WN_Loop_Unimportant_Misc(loop_info)) fprintf(TFile, "UNIMPORTANT_MISC ");
00947 if (WN_Loop_Nz_Trip(loop_info)) fprintf(TFile, "NZ_TRIP ");
00948 if (WN_Loop_Symb_Trip(loop_info)) fprintf(TFile, "SYMB_TRIP ");
00949 fprintf(TFile, "\n");
00950 if (LOOPINFO_trip_count_tn(info)) {
00951 fprintf(TFile, " trip count TN = ");
00952 Print_TN(LOOPINFO_trip_count_tn(info),FALSE);
00953 fprintf(TFile, "\n");
00954 }
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965 void
00966 Print_BB_Header ( BB *bp, BOOL flow_info_only, BOOL print_tn_info )
00967 {
00968 BBLIST *bl;
00969 INT16 i;
00970 ANNOTATION *annot = ANNOT_Get(BB_annotations(bp), ANNOT_LOOPINFO);
00971 BOOL freqs = FREQ_Frequencies_Computed();
00972
00973 fprintf ( TFile,
00974 "BB:%d (length:%d) -- "
00975 "flags = 0x%04x",
00976 BB_id(bp), BB_length(bp), BB_flag(bp) );
00977 if (freqs || BB_freq_fb_based(bp))
00978 fprintf(TFile, ", frequency = %g (%s)", BB_freq(bp),
00979 BB_freq_fb_based(bp) ? "feedback" : "heuristic");
00980 fprintf ( TFile, "\n");
00981
00982 if (BB_unreachable(bp)) fprintf ( TFile, " Unreachable block\n");
00983 if (BB_entry(bp)) fprintf ( TFile, " Entry block\n" );
00984 if (BB_handler(bp)) fprintf ( TFile, " Handler block\n" );
00985 if (BB_asm(bp)) fprintf ( TFile, " Asm block\n" );
00986 if (BB_exit(bp)) {
00987 if (BB_call(bp)) fprintf ( TFile, " Tail call block\n" );
00988 else fprintf ( TFile, " Exit block\n" );
00989 } else if (BB_call(bp)) fprintf ( TFile, " Call block\n" );
00990 #ifdef TARG_IA64
00991 if (BB_chk_split(bp)) fprintf ( TFile, " Check split block\n" );
00992 if (BB_chk_split_head(bp)) fprintf ( TFile, " Check split head block\n" );
00993
00994 if (BB_chk_split_tail(bp)) fprintf ( TFile, " Check split tail block\n" );
00995 if (BB_recovery(bp)) fprintf ( TFile, " Recovery block\n" );
00996 if (BB_scheduled(bp)) fprintf ( TFile, " Scheduled BB\n" );
00997 #endif
00998
00999 if (BB_rid(bp)) {
01000 INT exits;
01001 RID *rid = BB_rid(bp);
01002 CGRIN *cgrin = RID_cginfo(rid);
01003 if (cgrin) {
01004 if (bp == CGRIN_entry(cgrin)) {
01005 fprintf ( TFile, " Region entry block\n" );
01006 }
01007 exits = RID_num_exits(rid);
01008 for (i = 0; i < exits; ++i) {
01009 if (bp == CGRIN_exit_i(cgrin, i)) {
01010 fprintf ( TFile, " Region exit block %d\n", i );
01011 }
01012 }
01013 }
01014 }
01015
01016 if (annot)
01017 Print_LOOPINFO(ANNOT_loopinfo(annot));
01018
01019 if (BB_loop_head_bb(bp)) {
01020 if (BB_loophead(bp)) {
01021 if (!annot) {
01022 fprintf(TFile, " Head of loop body line %d\n", BB_Loop_Lineno(bp));
01023 }
01024 } else {
01025 BB *head = BB_loop_head_bb(bp);
01026 fprintf(TFile,
01027 " Part of loop body starting at line %d with head BB:%d\n",
01028 BB_Loop_Lineno(head), BB_id(head));
01029 }
01030 }
01031
01032 if (BB_unrollings(bp) > 1)
01033 fprintf(TFile, " Unrolled %d times%s\n", BB_unrollings(bp),
01034 BB_unrolled_fully(bp) ? " (fully)" : "");
01035
01036 if ( BB_rid(bp) )
01037 RID_Fprint( TFile, BB_rid(bp) );
01038
01039 if ( BB_entry(bp) ) {
01040 ANNOTATION *ant = ANNOT_Get (BB_annotations(bp), ANNOT_ENTRYINFO);
01041 ENTRYINFO *ent = ANNOT_entryinfo (ant);
01042 OP *sp_adj = BB_entry_sp_adj_op(bp);
01043 Is_True ((sp_adj == ENTRYINFO_sp_adj(ent)),("bad sp_adj"));
01044
01045 fprintf ( TFile, "Entrypoint: %s\t Starting Line %d\n",
01046 ST_name(ENTRYINFO_name(ent)),
01047 Srcpos_To_Line(ENTRYINFO_srcpos(ent)));
01048
01049 if ( ! flow_info_only && sp_adj) {
01050 OP *op;
01051 BOOL found_sp_adj = FALSE;
01052 fprintf ( TFile, "SP entry adj: " );
01053 Print_OP_No_SrcLine (sp_adj);
01054 FOR_ALL_BB_OPs_FWD(bp,op)
01055 if (op == sp_adj)
01056 {
01057 found_sp_adj = TRUE;
01058 break;
01059 }
01060 if (found_sp_adj == FALSE)
01061 fprintf ( TFile, "******** ERROR ******** sp adjust not found in entry block\n");
01062 }
01063 }
01064
01065 if ( BB_exit(bp) ) {
01066 ANNOTATION *ant = ANNOT_Get (BB_annotations(bp), ANNOT_EXITINFO);
01067 EXITINFO *exit = ANNOT_exitinfo (ant);
01068 OP *sp_adj = BB_exit_sp_adj_op(bp);
01069 Is_True ((sp_adj == EXITINFO_sp_adj(exit)),("bad sp_adj"));
01070
01071 if ( ! flow_info_only && sp_adj) {
01072 OP *op;
01073 BOOL found_sp_adj = FALSE;
01074 fprintf ( TFile, "SP exit adj: " );
01075 Print_OP_No_SrcLine (sp_adj);
01076
01077 FOR_ALL_BB_OPs_FWD(bp,op)
01078 if (op == sp_adj)
01079 {
01080 found_sp_adj = TRUE;
01081 break;
01082 }
01083 if (found_sp_adj == FALSE)
01084 fprintf ( TFile, "******** ERROR ******** sp adjust not found in exit block\n");
01085 }
01086 }
01087
01088
01089 fprintf ( TFile, "In linear order, BB_prev == BB:%2d; BB_next == BB:%2d\n",
01090 (BB_prev(bp) ? BB_id(BB_prev(bp)) : -1),
01091 (BB_next(bp) ? BB_id(BB_next(bp)) : -1) );
01092
01093 fprintf ( TFile, "Predecessors:\t" );
01094 i = 0;
01095 FOR_ALL_BB_PREDS (bp, bl) {
01096 fprintf ( TFile, "%sBB:%2d ",
01097 ( (i == 0) ? "" : (i%5 == 0) ? ",\n\t\t" : ", " ),
01098 BB_id(BBLIST_item(bl)));
01099 ++i;
01100 }
01101 if ( i == 0 ) fprintf ( TFile, "none" );
01102 fprintf ( TFile, "\nSuccessors%s:\t", freqs ? " (w/probs)" : "" );
01103 i = 0;
01104 FOR_ALL_BB_SUCCS (bp, bl) {
01105 fprintf ( TFile, "%sBB:%2d",
01106 ( (i == 0) ? "" : (i%5 == 0) ? ",\n\t\t" : ", " ),
01107 BB_id(BBLIST_item(bl)));
01108 if (freqs) fprintf(TFile, " (%g)", BBLIST_prob(bl));
01109 ++i;
01110 }
01111 if ( i == 0 ) fprintf ( TFile, "none" );
01112 fprintf ( TFile, "\n" );
01113
01114 if (BB_has_label(bp)) {
01115 ANNOTATION *ant;
01116 fprintf(TFile, "Labeled with ");
01117 for (ant = ANNOT_First(BB_annotations(bp), ANNOT_LABEL);
01118 ant != NULL;
01119 ant = ANNOT_Next(ant, ANNOT_LABEL))
01120 {
01121 INT eh_labs = 0;
01122 LABEL_IDX label = ANNOT_label(ant);
01123 fprintf (TFile,"%s ", LABEL_name(label));
01124 FmtAssert((Get_Label_BB(label) == bp),
01125 ("Inconsistent ST for BB:%2d label", BB_id(bp)));
01126 switch (LABEL_kind(Label_Table[label])) {
01127 case LKIND_BEGIN_EH_RANGE:
01128 fprintf (TFile,"%cbegin_eh_range", eh_labs++ ? ' ' : '(');
01129 break;
01130 case LKIND_END_EH_RANGE:
01131 fprintf (TFile,"%cend_eh_range", eh_labs++ ? ' ' : '(');
01132 break;
01133 }
01134 if (eh_labs)
01135 fprintf (TFile,") ");
01136 }
01137 fprintf(TFile, "\n");
01138 }
01139
01140 if ( flow_info_only ) return;
01141
01142
01143 if ( print_tn_info )
01144 GRA_LIVE_Print_Liveness(bp);
01145 }
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156 void
01157 Print_BB_Pragmas( BB *bp )
01158 {
01159 if ( BB_has_pragma(bp) ) {
01160 ANNOTATION *ant;
01161 BOOL first = TRUE;
01162 fprintf(TFile, "Pragmas:\t");
01163 for ( ant = ANNOT_First (BB_annotations(bp), ANNOT_PRAGMA);
01164 ant != NULL;
01165 ant = ANNOT_Next (ant, ANNOT_PRAGMA))
01166 {
01167 WN *wn = ANNOT_pragma(ant);
01168 WN_PRAGMA_ID pragma = (WN_PRAGMA_ID) WN_pragma(wn);
01169 INT32 arg1 = WN_pragma_arg1(wn);
01170 INT32 arg2 = WN_pragma_arg2(wn);
01171 if (!first) fprintf(TFile, "\t\t");
01172 if ((UINT32)pragma >= (UINT32)MAX_WN_PRAGMA) {
01173 fprintf(TFile, "%d", pragma);
01174 } else {
01175 fprintf(TFile, "%s", WN_pragmas[WN_pragma(wn)].name);
01176 }
01177 switch (pragma) {
01178 case WN_PRAGMA_MIPS_FREQUENCY_HINT:
01179 switch (arg1) {
01180 case FREQUENCY_HINT_NEVER:
01181 fprintf(TFile, " NEVER\n");
01182 break;
01183 case FREQUENCY_HINT_INIT:
01184 fprintf(TFile, " INIT\n");
01185 break;
01186 case FREQUENCY_HINT_FREQUENT:
01187 fprintf(TFile, " FREQUENT\n");
01188 break;
01189 default:
01190 fprintf(TFile, " %d\n", arg1);
01191 break;
01192 }
01193 break;
01194
01195 default:
01196 fprintf(TFile, " arg1 = %d, arg2 = %d\n", arg1, arg2);
01197 break;
01198 }
01199 first = FALSE;
01200 }
01201 }
01202 }
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213 void Trace_BB ( BB *bp, char *msg )
01214 {
01215 fprintf ( TFile, "%sBB:%d %s\n%s", DBar, BB_id(bp), msg, DBar );
01216 Print_BB_Header ( bp, FALSE, TRUE );
01217 Print_BB_Pragmas ( bp );
01218 fprintf ( TFile, "\n" );
01219 NOTE_BB_Act(bp, NOTE_PRINT_TO_FILE, TFile);
01220 FREQ_Print_BB_Note(bp, TFile);
01221 if (BB_first_op(bp)) Print_OPs (BB_first_op(bp));
01222 fprintf ( TFile, "%s\n", DBar );
01223 }
01224
01225
01226
01227 void Print_BB ( BB *bp )
01228 {
01229 #if defined(VENDOR_OSP)
01230 BBLIST *bl;
01231 if ( BB_entry(bp) ) {
01232 ANNOTATION *ant = ANNOT_Get (BB_annotations(bp), ANNOT_ENTRYINFO);
01233 ENTRYINFO *ent = ANNOT_entryinfo (ant);
01234 fprintf ( TFile, "\n\t.proc %s#\n", ST_name(ENTRYINFO_name(ent)) );
01235 }
01236 fprintf ( TFile, "%s", SBar);
01237 fprintf ( TFile, "// Block: %d", BB_id(bp) );
01238 fprintf ( TFile, " Pred:" );
01239 FOR_ALL_BB_PREDS (bp, bl) {
01240 fprintf ( TFile, " %d", BB_id(BBLIST_item(bl)));
01241 }
01242 fprintf ( TFile, " Succ:" );
01243 FOR_ALL_BB_SUCCS (bp, bl) {
01244 fprintf ( TFile, " %d", BB_id(BBLIST_item(bl)));
01245 }
01246 fprintf ( TFile, "\n" );
01247 fprintf ( TFile, "%s", SBar );
01248 #else
01249 fprintf ( TFile, "%sBB:%d \n%s", SBar, BB_id(bp), SBar );
01250 #endif
01251 Print_BB_Header ( bp, FALSE, TRUE );
01252 Print_BB_Pragmas ( bp );
01253 fprintf ( TFile, "\n" );
01254 NOTE_BB_Act(bp, NOTE_PRINT_TO_FILE, TFile);
01255 FREQ_Print_BB_Note(bp, TFile);
01256 if (BB_first_op(bp)) Print_OPs (BB_first_op(bp));
01257 #if defined(VENDOR_OSP)
01258 if (BB_exit(bp) && !BB_call(bp)) { fprintf ( TFile, "\n\t.endp\n" ); }
01259 #endif
01260 }
01261
01262
01263
01264 void Print_BB_No_Srclines ( BB *bp )
01265 {
01266 fprintf ( TFile, "%sBB:%d \n%s", SBar, BB_id(bp), SBar );
01267 Print_BB_Header ( bp, FALSE, TRUE );
01268 Print_BB_Pragmas ( bp );
01269 fprintf ( TFile, "\n" );
01270 NOTE_BB_Act(bp, NOTE_PRINT_TO_FILE, TFile);
01271 FREQ_Print_BB_Note(bp, TFile);
01272 if (BB_first_op(bp)) Print_OPs_No_SrcLines(BB_first_op(bp));
01273 }
01274
01275
01276 void dump_bb (BB *bb)
01277 {
01278 FILE *f;
01279 f = TFile;
01280 Set_Trace_File_internal(stdout);
01281 Print_BB_No_Srclines(bb);
01282 Set_Trace_File_internal(f);
01283 }
01284
01285
01286
01287 void Print_All_BBs ( void )
01288 {
01289 BB *bp;
01290
01291 for (bp = REGION_First_BB; bp; bp = BB_next(bp)) {
01292 Print_BB ( bp );
01293 fprintf ( TFile,"\n" );
01294 }
01295 }
01296
01297
01298 void Print_All_BB_Headers ( void )
01299 {
01300 BB *bp;
01301
01302 for (bp = REGION_First_BB; bp; bp = BB_next(bp)) {
01303 fprintf ( TFile, "%sBB:%d \n%s", SBar, BB_id(bp), SBar );
01304 Print_BB_Header ( bp, FALSE, FALSE );
01305 fprintf ( TFile,"\n" );
01306 }
01307 }
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318 void
01319 Print_Entry_Chain ( char *banner )
01320 {
01321 BB_LIST *bbl;
01322
01323 fprintf ( TFile, "\n%s Entry chain -- %s\n%s\n",
01324 DBar, banner, DBar );
01325
01326 for (bbl = Entry_BB_Head; bbl; bbl = BB_LIST_rest(bbl)) {
01327 Print_BB_Header ( BB_LIST_first(bbl), TRUE, FALSE );
01328 fprintf ( TFile,"\n" );
01329 }
01330 }
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343 void
01344 Print_Flow_Graph ( char *banner, BOOL verbose )
01345 {
01346 BB *bb;
01347
01348 fprintf ( TFile, "\n%s Flow graph -- %s\n%s\n",
01349 DBar, banner, DBar );
01350
01351 for ( bb = REGION_First_BB; bb; bb = BB_next(bb)) {
01352 Print_BB_Header ( bb, !verbose, verbose );
01353 fprintf ( TFile,"\n" );
01354 }
01355 }
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366 OP *
01367 BB_branch_op( BB *bb )
01368 {
01369 OP *op = BB_last_op(bb);
01370
01371
01372
01373
01374 if (op) {
01375 if (OP_br(op)) return op;
01376
01377 if (PROC_has_branch_delay_slot()) {
01378 op = OP_prev(op);
01379 if (op && OP_br(op)) return op;
01380 }
01381 }
01382
01383 return NULL;
01384 }
01385
01386
01387 #ifdef TARG_IA64
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397 OP *
01398 Last_Non_Nop_op( BB *bb )
01399 {
01400 OP *op;
01401 for (op =BB_last_op(bb); op; op = OP_prev(op)) {
01402 if (!(OP_noop(op))) return op;
01403 }
01404 return NULL;
01405
01406 }
01407
01408 OP *
01409 BB_Last_chk_op( BB *bb )
01410 {
01411
01412 OP *op = Last_Non_Nop_op(bb);
01413
01414 if (!op || !OP_chk(op)){
01415 return NULL;
01416 } else {
01417 return op;
01418 }
01419 return NULL;
01420 }
01421 #endif
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432 OP*
01433 BB_xfer_op( BB *bb )
01434 {
01435 OP *op = BB_last_op(bb);
01436
01437
01438
01439
01440 if (op) {
01441 if (OP_xfer(op)) return op;
01442
01443 if (PROC_has_branch_delay_slot()) {
01444 op = OP_prev(op);
01445 if (op && OP_xfer(op)) return op;
01446 }
01447 }
01448
01449 return NULL;
01450 }
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461 OP*
01462 BB_call_op( BB *bb )
01463 {
01464 if(!BB_call(bb)) return NULL;
01465 OP *op = BB_last_op(bb);
01466
01467
01468
01469
01470 if (op) {
01471 if (OP_call(op)) return op;
01472
01473 if (PROC_has_branch_delay_slot()) {
01474 op = OP_prev(op);
01475 if (op && OP_call(op)) return op;
01476 }
01477 }
01478
01479 return NULL;
01480 }
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491 OP*
01492 BB_copy_xfer_op( BB *bb )
01493 {
01494 OP *op, *prev_op;
01495
01496 op = BB_last_op(bb);
01497
01498 #define OP_copy_xfer(o) (OP_xfer(o) || OP_copy(o) || OP_glue(o))
01499
01500
01501
01502
01503 if (op) {
01504
01505
01506 BOOL real_last_op = !OP_copy_xfer(op);
01507
01508 prev_op = OP_prev(op);
01509 if (OP_copy_xfer(op)) {
01510 if (prev_op == NULL || !OP_copy_xfer(prev_op))
01511 return op;
01512 }
01513
01514 if (prev_op) {
01515 op = OP_prev(prev_op);
01516 if (OP_copy_xfer(prev_op)) {
01517 if (op == NULL || !OP_copy_xfer(op) ||
01518
01519
01520
01521 (OP_xfer(prev_op) && real_last_op))
01522 return prev_op;
01523 } else return NULL;
01524
01525
01526 for (;op != NULL; op = prev_op) {
01527 prev_op = OP_prev(op);
01528 if (prev_op == NULL ||
01529 (!OP_copy(prev_op) && !OP_glue(prev_op)))
01530 return op;
01531 }
01532 }
01533 }
01534
01535 return NULL;
01536 }
01537
01538 UINT16 BB_New_Op_Map_Idx(BB *bb)
01539 {
01540 mUINT16 result = bb->next_op_map_idx++;
01541
01542
01543
01544
01545
01546 FmtAssert((result+1) != 0, ("ran out of OP_MAP idx's"));
01547 return result;
01548 }
01549
01550
01551
01552 void
01553 BB_Add_Annotation (BB *bb, ANNOTATION_KIND kind, void *info)
01554 {
01555 switch (kind) {
01556 case ANNOT_LABEL:
01557 Set_BB_has_label(bb); break;
01558 case ANNOT_PRAGMA:
01559 Set_BB_has_pragma(bb); break;
01560 case ANNOT_ENTRYINFO:
01561 Set_BB_entry(bb); break;
01562 case ANNOT_EXITINFO:
01563 Set_BB_exit(bb); break;
01564 case ANNOT_NOTE:
01565 Set_BB_has_note(bb); break;
01566 case ANNOT_LOOPINFO:
01567 Set_BB_loop_head_bb(bb, bb);
01568 break;
01569 case ANNOT_CALLINFO:
01570 Set_BB_call(bb); break;
01571 case ANNOT_ASMINFO:
01572 Set_BB_asm(bb); break;
01573 case ANNOT_SWITCH:
01574 break;
01575 case ANNOT_ROTATING_KERNEL:
01576 Set_BB_rotating_kernel(bb);
01577 break;
01578 default:
01579 FmtAssert(FALSE, ("unexpected annotation kind: %d", kind));
01580
01581 }
01582 BB_annotations(bb) = ANNOT_Add(BB_annotations(bb), kind, info,
01583 BB_MEM_pool_ptr);
01584 }
01585
01586
01587
01588 INT BB_Copy_Annotations(BB *to_bb, BB *from_bb, ANNOTATION_KIND kind)
01589 {
01590 ANNOTATION *ant;
01591 INT count = 0;
01592
01593 for (ant = ANNOT_First(BB_annotations(from_bb), kind);
01594 ant;
01595 ant = ANNOT_Next(ant, kind))
01596 {
01597 BB_Add_Annotation(to_bb, kind, ANNOT_info(ant));
01598 if( kind == ANNOT_LABEL ){
01599 Set_Label_BB( ANNOT_label(ant), to_bb );
01600 }
01601 ++count;
01602 }
01603
01604 return count;
01605 }
01606
01607
01608
01609
01610 INT BB_Copy_All_Annotations (BB *to_bb, BB *from_bb) {
01611 INT32 cnt = 0;
01612 ANNOTATION *ant = BB_annotations(from_bb);
01613 while (ant) {
01614 cnt ++;
01615 BB_Add_Annotation(to_bb, ANNOT_kind(ant), ANNOT_info(ant));
01616 if(ANNOT_kind(ant) == ANNOT_LABEL) {
01617 Set_Label_BB( ANNOT_label(ant), to_bb );
01618 }
01619 ant = ANNOT_next(ant);
01620 }
01621 return cnt;
01622 }
01623
01624 OP *
01625 BB_entry_sp_adj_op (BB *bb)
01626 {
01627 ANNOTATION *ant = ANNOT_Get (BB_annotations(bb), ANNOT_ENTRYINFO);
01628 return (ant != NULL) ? ENTRYINFO_sp_adj(ANNOT_entryinfo(ant)) : NULL;
01629 }
01630
01631 OP *
01632 BB_exit_sp_adj_op (BB *bb)
01633 {
01634 ANNOTATION *ant = ANNOT_Get (BB_annotations(bb), ANNOT_EXITINFO);
01635 return (ant != NULL) ? EXITINFO_sp_adj(ANNOT_exitinfo(ant)) : NULL;
01636 }
01637
01638 void Set_BB_entry_sp_adj_op (BB *bb, OP *op)
01639 {
01640 ANNOTATION *ant = ANNOT_Get (BB_annotations(bb), ANNOT_ENTRYINFO);
01641
01642 FmtAssert(ant, ("expected entry annotation"));
01643
01644 ENTRYINFO_sp_adj(ANNOT_entryinfo(ant)) = op;
01645 }
01646
01647 void Set_BB_exit_sp_adj_op (BB *bb, OP *op)
01648 {
01649 ANNOTATION *ant = ANNOT_Get (BB_annotations(bb), ANNOT_EXITINFO);
01650
01651 FmtAssert(ant, ("expected entry annotation"));
01652
01653 EXITINFO_sp_adj(ANNOT_exitinfo(ant)) = op;
01654 }
01655
01656
01657 BOOL Is_Label_For_BB(LABEL_IDX label, BB *bb)
01658
01659
01660
01661
01662 {
01663 ANNOTATION *ant = ANNOT_First(BB_annotations(bb), ANNOT_LABEL);
01664
01665 if (BB_has_label(bb) && ant == NULL) {
01666 DevWarn("BB_has_label(BB:%d) set, but found no ANNOT_LABEL", BB_id(bb));
01667 Reset_BB_has_label(bb);
01668 } else if (ant && !BB_has_label(bb)) {
01669 DevWarn("BB:%d has label(s), but BB_has_label not set", BB_id(bb));
01670 Set_BB_has_label(bb);
01671 }
01672
01673 while (ant) {
01674 if (label == ANNOT_label(ant)) return TRUE;
01675 ant = ANNOT_Next(ant, ANNOT_LABEL);
01676 }
01677 return FALSE;
01678 }
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693 LABEL_IDX
01694 Gen_Label_For_BB(BB *bb)
01695 {
01696 char *buf;
01697 LABEL_IDX lab;
01698 LABEL *label;
01699 #define EXTRA_NAME_LEN 32
01700
01701 FmtAssert (BB_id(bb) != 0, ("Gen_Label_For_BB: BB_id not set for BB"));
01702
01703
01704 if (BB_has_label(bb)) {
01705 ANNOTATION *ant = ANNOT_First(BB_annotations(bb), ANNOT_LABEL);
01706 if (ant == NULL) {
01707 DevWarn("BB_has_label(BB:%d) set, but found no ANNOT_LABEL", BB_id(bb));
01708 } else {
01709
01710 return ANNOT_label(ant);
01711 }
01712 }
01713
01714
01715 buf = (char *)alloca(strlen(Cur_PU_Name) + EXTRA_NAME_LEN);
01716 sprintf(buf, BB_Label_Format, BB_id(bb), Cur_PU_Name);
01717
01718 label = &New_LABEL(CURRENT_SYMTAB, lab);
01719 LABEL_Init (*label, Save_Str(buf), LKIND_DEFAULT);
01720
01721 Set_Label_BB (lab, bb);
01722 BB_Add_Annotation (bb, ANNOT_LABEL, (void *)(INTPTR)lab);
01723 return lab;
01724
01725 #undef EXTRA_NAME_LEN
01726 }
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737 BB *
01738 BB_Other_Successor(
01739 BB *bb,
01740 BB *succ)
01741 {
01742 BBLIST *bblst;
01743 BB *succ2 = NULL;
01744
01745 FOR_ALL_BB_SUCCS(bb, bblst) {
01746 BB *sbb = BBLIST_item(bblst);
01747 if (sbb == succ) continue;
01748 FmtAssert(succ2 == NULL, ("multiple other successors"));
01749 succ2 = sbb;
01750 }
01751
01752 FmtAssert(succ2 != NULL, ("no other successor"));
01753
01754 return succ2;
01755 }
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765 BB *
01766 BB_Other_Predecessor(
01767 BB *bb,
01768 BB *pred)
01769 {
01770 BBLIST *bblst;
01771 BB *pred2 = NULL;
01772
01773 FOR_ALL_BB_PREDS(bb, bblst) {
01774 BB *pbb = BBLIST_item(bblst);
01775 if (pbb == pred) continue;
01776 FmtAssert(pred2 == NULL, ("multiple other predecessors"));
01777 pred2 = pbb;
01778 }
01779
01780 FmtAssert(pred2 != NULL, ("no other predecessor"));
01781
01782 return pred2;
01783 }
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803 BOOL
01804 BB_Retarget_Branch(BB *bb, BB *from, BB *to)
01805 {
01806 OP *br_op = BB_branch_op(bb);
01807
01808 if (br_op) {
01809 INT opnd;
01810 INT opnd_count;
01811 CGTARG_Branch_Info(br_op, &opnd, &opnd_count);
01812 if (opnd_count > 0) {
01813
01814
01815
01816 TN *br_targ = OP_opnd(br_op, opnd);
01817 Is_True(opnd_count == 1, ("Branch with multiple bbs"));
01818 if (Is_Label_For_BB(TN_label(br_targ), from)) {
01819 LABEL_IDX label = Gen_Label_For_BB(to);
01820 Set_OP_opnd(br_op, opnd, Gen_Label_TN(label,0));
01821 Change_Succ(bb, from, to);
01822 return TRUE;
01823 }
01824 } else if (ANNOT_Get(BB_annotations(bb), ANNOT_SWITCH)) {
01825
01826
01827
01828 WN *br_wn = BB_branch_wn(bb);
01829 Is_True(br_wn,
01830 ("indirect branch ending BB:%d has no associated WHIRL node",
01831 BB_id(bb)));
01832 ST * const listvar = WN_st(br_wn);
01833 Change_Switchtable_Entries(listvar, from, to);
01834 Change_Succ(bb, from, to);
01835 return TRUE;
01836 } else {
01837
01838
01839
01840
01841
01842
01843
01844 }
01845 }
01846 return FALSE;
01847 }
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857 BOOL
01858 BB_Can_Retarget_Branch(BB *bb, BB *from)
01859 {
01860 OP *br_op = BB_branch_op(bb);
01861
01862 if (br_op) {
01863 INT opnd;
01864 INT opnd_count;
01865 CGTARG_Branch_Info(br_op, &opnd, &opnd_count);
01866 if (opnd_count > 0) {
01867
01868
01869
01870 TN *br_targ = OP_opnd(br_op, opnd);
01871 Is_True(opnd_count == 1, ("Branch with multiple bbs"));
01872 return Is_Label_For_BB(TN_label(br_targ), from);
01873 } else if (ANNOT_Get(BB_annotations(bb), ANNOT_SWITCH)) {
01874
01875
01876
01877 WN *br_wn = BB_branch_wn(bb);
01878 Is_True(br_wn,
01879 ("indirect branch ending BB:%d has no associated WHIRL node",
01880 BB_id(bb)));
01881 ST * const listvar = WN_st(br_wn);
01882 return Find_INITO_For_Symbol(listvar) != (INITO_IDX)0;
01883 } else {
01884
01885
01886
01887
01888
01889
01890
01891 }
01892 }
01893 return FALSE;
01894 }
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904 BB *BB_Unique_Successor( BB *bb )
01905 {
01906 BBLIST *slist = BB_succs(bb);
01907 BB *succ = NULL;
01908
01909 if (BBlist_Has_One_Element(slist) && BBLIST_item(slist) != bb) {
01910 succ = BBLIST_item(slist);
01911 }
01912 return succ;
01913 }
01914
01915 void
01916 Remove_Explicit_Branch (BB *bb)
01917
01918
01919
01920
01921 {
01922 if ( bb == NULL) return;
01923 BB *next = BB_next(bb);
01924
01925 if (next && BB_Find_Succ(bb, next)) {
01926
01927 OP *br_op = BB_branch_op(bb);
01928 if (br_op) {
01929 INT tfirst, tcount;
01930 CGTARG_Branch_Info(br_op, &tfirst, &tcount);
01931 if (tcount != 0) {
01932 TN *dest = OP_opnd(br_op, tfirst);
01933 DevAssert(tcount == 1, ("%d branch targets, expected 1", tcount));
01934 DevAssert(TN_is_label(dest), ("expected label"));
01935 if (Is_Label_For_BB(TN_label(dest), next)) {
01936
01937 BB_Remove_Op(bb, br_op);
01938 } else {
01939 DevAssert(OP_cond(br_op), ("BB_succs(BB:%d) wrongly contains BB:%d",
01940 BB_id(bb), BB_id(next)));
01941 }
01942 }
01943 }
01944 }
01945 }
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956 BB *BB_Fall_Thru_Successor( BB *bb )
01957 {
01958 BBLIST *list = BBlist_Fall_Thru_Succ(bb);
01959 return list ? BBLIST_item(list) : NULL;
01960 }
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970 BB *BB_Fall_Thru_Predecessor( BB *bb )
01971 {
01972 BBLIST *list = BBlist_Fall_Thru_Pred(bb);
01973 return list ? BBLIST_item(list) : NULL;
01974 }
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986 BB *BB_Unique_Successor_Not_In_Set( BB *bb, BB_MAP map )
01987 {
01988 BBLIST *slist;
01989 BB *succ;
01990 BB *ans = NULL;
01991 BOOL found = FALSE;
01992
01993 for ( slist = BB_succs( bb ); slist; slist = BBLIST_next( slist ) ) {
01994 succ = BBLIST_item( slist );
01995 if ( BB_MAP32_Get( map, succ) )
01996 continue;
01997 if ( found )
01998 return NULL;
01999 found = TRUE;
02000 ans = succ;
02001 }
02002 return ans;
02003 }
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013 BB *BB_Unique_Predecessor( BB *bb )
02014 {
02015 BBLIST *plist = BB_preds( bb );
02016 BB *pred = NULL;
02017
02018 if (BBlist_Has_One_Element(plist) && BBLIST_item(plist) != bb) {
02019 pred = BBLIST_item(plist);
02020 }
02021 return pred;
02022 }
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034 BB *BB_Unique_Source( BB *bb )
02035 {
02036 BBLIST *bl;
02037 BB *src = NULL;
02038 INT num_src = 0;
02039
02040 FOR_ALL_BB_PREDS(bb, bl) {
02041 BB *pbb = BBLIST_item(bl);
02042 if (BB_branch_op(pbb)) {
02043 src = pbb;
02044 num_src += 1;
02045 }
02046 }
02047 return (num_src == 1) ? src : NULL;
02048 }
02049
02050
02051
02052 static void
02053 Mark_Reachable (BB *bb)
02054 {
02055 BBLIST *blst;
02056
02057 Reset_BB_unreachable (bb);
02058
02059 FOR_ALL_BB_SUCCS (bb, blst) {
02060 BB *succ = BBLIST_item(blst);
02061 if (BB_unreachable(succ)) {
02062 Mark_Reachable (succ);
02063 }
02064 }
02065 }
02066
02067
02068
02069 void
02070 BB_Mark_Unreachable_Blocks (void)
02071 {
02072 BB *bb;
02073
02074
02075 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
02076 Set_BB_unreachable (bb);
02077 }
02078
02079
02080
02081
02082 if (Compiling_Proper_REGION) {
02083 Mark_Reachable (CGRIN_entry(RID_Find_Cginfo(REGION_First_BB)));
02084 }
02085 for (bb = REGION_First_BB; bb; bb = BB_next(bb)) {
02086
02087
02088
02089
02090 if (!BB_unreachable(bb)) continue;
02091
02092 #ifdef KEY
02093 if (BB_has_non_local_label(bb)) {
02094 Mark_Reachable(bb);
02095 continue;
02096 }
02097 #endif
02098
02099 if (!BB_entry(bb)) continue;
02100
02101 ANNOTATION *ant = ANNOT_Get (BB_annotations(bb), ANNOT_ENTRYINFO);
02102 ENTRYINFO *ent = ANNOT_entryinfo(ant);
02103 ST *entry_sym = ENTRYINFO_name(ent);
02104 if (ST_is_not_used(entry_sym)) continue;
02105
02106 Mark_Reachable(bb);
02107 }
02108 }
02109
02110
02111 static INT32 map_depth_first(BB_MAP map, BB_SET *region, BB *bb, INT32 max_id)
02112
02113
02114
02115
02116 {
02117 BBLIST *succs;
02118
02119 Is_True(BB_MAP32_Get(map, bb) == 0, ("BB_Depth_First_Map visited BB:%d twice", BB_id(bb)));
02120
02121 BB_MAP32_Set(map, bb, ++max_id);
02122
02123
02124
02125 FOR_ALL_BB_SUCCS(bb, succs) {
02126 BB *succ = BBLIST_item(succs);
02127 if ((region == NULL || BB_SET_MemberP(region, succ)) &&
02128 BB_MAP32_Get(map, succ) == 0)
02129 max_id = map_depth_first(map, region, succ, max_id);
02130 }
02131
02132 return max_id;
02133 }
02134
02135
02136 BB_MAP BB_Depth_First_Map(BB_SET *region, BB *entry)
02137
02138
02139
02140
02141 {
02142 BB_MAP dfo_map = BB_MAP32_Create();
02143
02144 Is_True(region == NULL || entry, ("<entry> not specified"));
02145 Is_True(region == NULL || BB_SET_MemberP(region, entry),
02146 ("<entry> not in <region>"));
02147
02148 if (region) {
02149 map_depth_first(dfo_map, region, entry, 0);
02150 } else if (Compiling_Proper_REGION) {
02151 map_depth_first(dfo_map, region,
02152 CGRIN_entry(RID_Find_Cginfo(REGION_First_BB)), 0);
02153 } else {
02154 BB_LIST *entries;
02155 INT32 max_id = 0;
02156 for (entries = Entry_BB_Head; entries; entries = BB_LIST_rest(entries)){
02157
02158
02159
02160 FmtAssert ((region == NULL || BB_SET_MemberP(region, BB_LIST_first(entries))),
02161 ("BB_Depth_First_Map visited BB:%d twice", BB_id(BB_LIST_first(entries))));
02162 #ifdef KEY
02163
02164
02165
02166 if( BB_MAP32_Get( dfo_map, BB_LIST_first(entries) ) != 0 ){
02167 FmtAssert( region == NULL,
02168 ("BB_Depth_First_Map visited a region twice") );
02169 continue;
02170 }
02171 #endif
02172 max_id = map_depth_first(dfo_map, region, BB_LIST_first(entries),
02173 max_id);
02174 }
02175 #ifdef KEY
02176
02177
02178 if (PU_Has_Nonlocal_Goto_Target) {
02179 BB *bb;
02180 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
02181 if (!BB_entry(bb) &&
02182 BB_has_non_local_label(bb) &&
02183 BB_preds(bb) == NULL) {
02184
02185
02186 if (BB_MAP32_Get(dfo_map, bb) != 0) {
02187 FmtAssert(region == NULL,
02188 ("BB_Depth_First_Map visited a region twice"));
02189 continue;
02190 }
02191 max_id = map_depth_first(dfo_map, region, bb, max_id);
02192 }
02193 }
02194 }
02195 #endif
02196 }
02197 return dfo_map;
02198 }
02199
02200
02201 static BOOL all_bbs_mapped(BBLIST *bbs, BB_MAP map)
02202
02203
02204
02205
02206 {
02207 while (bbs) {
02208 if (BB_MAP32_Get(map, BBLIST_item(bbs)) == 0)
02209 return FALSE;
02210 bbs = BBLIST_next(bbs);
02211 }
02212 return TRUE;
02213 }
02214
02215
02216 static INT32 map_topologically(BB_MAP map, BB_SET *region, BB *bb,
02217 INT32 max_id)
02218
02219
02220
02221
02222 {
02223 BBLIST *succs;
02224 BB *fall_thru = NULL;
02225
02226 BB_MAP32_Set(map, bb, ++max_id);
02227
02228
02229
02230
02231 if (BB_next(bb) && BB_Find_Succ(bb, BB_next(bb)))
02232 fall_thru = BB_next(bb);
02233 if (fall_thru && BB_MAP32_Get(map, fall_thru) == 0 &&
02234 (region == NULL || BB_SET_MemberP(region, fall_thru)) &&
02235 all_bbs_mapped(BB_preds(fall_thru), map))
02236
02237 max_id = map_topologically(map, region, fall_thru, max_id);
02238
02239
02240
02241 FOR_ALL_BB_SUCCS(bb, succs) {
02242 BB *succ = BBLIST_item(succs);
02243 if (succ != fall_thru && BB_MAP32_Get(map, succ) == 0 &&
02244 (region == NULL || BB_SET_MemberP(region, succ)) &&
02245 all_bbs_mapped(BB_preds(succ), map))
02246
02247 max_id = map_topologically(map, region, succ, max_id);
02248 }
02249
02250 return max_id;
02251 }
02252
02253
02254 BB_MAP BB_Topological_Map(BB_SET *region, BB *entry)
02255
02256
02257
02258
02259 {
02260 BB_MAP top_map = BB_MAP32_Create();
02261
02262 Is_True(region == NULL || entry, ("<entry> not specified"));
02263 Is_True(region == NULL || BB_SET_MemberP(region, entry),
02264 ("<entry> not in <region>"));
02265
02266 if (region) {
02267 map_topologically(top_map, region, entry, 0);
02268 } else if (Compiling_Proper_REGION) {
02269 map_topologically(top_map, region,
02270 CGRIN_entry(RID_Find_Cginfo(REGION_First_BB)), 0);
02271 } else {
02272 BB_LIST *entries;
02273 INT32 max_id = 0;
02274 for (entries = Entry_BB_Head; entries; entries = BB_LIST_rest(entries))
02275 max_id = map_topologically(top_map, region, BB_LIST_first(entries),
02276 max_id);
02277 }
02278 return top_map;
02279 }
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292 BOOL
02293 Change_Switchtable_Entries(
02294 ST *listvar,
02295 BB *old_target,
02296 BB *new_target)
02297 {
02298 BOOL changed;
02299 INITV_IDX initv;
02300 INITO_IDX inito = Find_INITO_For_Symbol(listvar);
02301 LABEL_IDX lab;
02302
02303 if (inito == (INITO_IDX) 0) {
02304 DevWarn("No INITO for listvar at line %d of %s", __LINE__, __FILE__);
02305 return FALSE;
02306 }
02307
02308
02309
02310 changed = FALSE;
02311 FOREACH_INITV(INITO_val(inito), initv) {
02312
02313 if (Is_Label_For_BB(INITV_lab(initv), old_target)) {
02314 if (!changed) {
02315
02316
02317
02318 lab = Gen_Label_For_BB(new_target);
02319
02320
02321
02322 changed = TRUE;
02323 }
02324 Set_INITV_lab(initv, lab);
02325 }
02326 }
02327
02328
02329
02330 if (!changed) {
02331 DevWarn("Switch table doesn't contain BB:%d as a target at line %d of %s",
02332 BB_id(old_target), __LINE__, __FILE__);
02333 }
02334
02335 return changed;
02336 }
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349 BOOL
02350 BB_Move_Delay_Slot_Op (BB *bb)
02351 {
02352 INT i;
02353
02354 FmtAssert(PROC_has_branch_delay_slot(), ("no delay slot to move"));
02355
02356 OP *delay_op = BB_last_op(bb);
02357 OP *xfer_op = NULL;
02358
02359 if (delay_op != NULL) {
02360 xfer_op = OP_prev(delay_op);
02361 }
02362 if (xfer_op == NULL || !OP_xfer(xfer_op)) return FALSE;
02363
02364
02365 BB_Move_Op_Before(bb, xfer_op, bb, delay_op);
02366
02367
02368
02369
02370 for (i = OP_results(delay_op) - 1; i >= 0; --i) {
02371 TN *result_tn = OP_result(delay_op,i);
02372 if (OP_Refs_TN (xfer_op, result_tn)) {
02373 OPS copy_ops = OPS_EMPTY;
02374 TN* tmp_tn = Dup_TN (result_tn);
02375 INT i;
02376
02377 Exp_COPY (tmp_tn, result_tn, ©_ops);
02378 BB_Insert_Ops_Before (bb, delay_op, ©_ops);
02379 for (i = 0; i < OP_opnds(xfer_op); i++) {
02380 if (OP_opnd(xfer_op,i) == result_tn) {
02381 Set_OP_opnd (xfer_op, i, tmp_tn);
02382 }
02383 }
02384 }
02385 }
02386 return TRUE;
02387 }
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398 SRCPOS
02399 BB_Loop_Srcpos(BB *bb)
02400 {
02401 OP *op;
02402 SRCPOS srcpos;
02403 ANNOTATION *annot;
02404 LOOPINFO *loopinfo;
02405
02406
02407
02408 annot = ANNOT_Get(BB_annotations(bb), ANNOT_LOOPINFO);
02409 loopinfo = NULL;
02410 srcpos = 0;
02411 if (annot) {
02412 loopinfo = ANNOT_loopinfo(annot);
02413 srcpos = LOOPINFO_srcpos(loopinfo);
02414 }
02415
02416
02417
02418
02419 if (srcpos == 0) {
02420 FOR_ALL_BB_OPs_FWD(bb, op) {
02421 srcpos = OP_srcpos(op);
02422 if (srcpos != 0) {
02423
02424
02425
02426
02427 if (loopinfo) LOOPINFO_srcpos(loopinfo) = srcpos;
02428 break;
02429 }
02430 }
02431 }
02432
02433 return srcpos;
02434 }
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445 extern void
02446 BB_Transfer_Entryinfo(BB* from, BB* to)
02447 {
02448 ANNOTATION* annot;
02449
02450 Set_BB_entry(to);
02451 Reset_BB_entry(from);
02452 if (BB_handler(from)) {
02453 Set_BB_handler(to);
02454 #ifdef TARG_IA64
02455 Reset_BB_handler(to);
02456 #else
02457 Reset_BB_handler(from);
02458 #endif
02459 }
02460 annot = ANNOT_Get(BB_annotations(from),ANNOT_ENTRYINFO);
02461 Is_True(annot != NULL,("No entryinfo annotation for BB%d",BB_id(from)));
02462 BB_Add_Annotation(to,ANNOT_ENTRYINFO,ANNOT_entryinfo(annot));
02463 BB_annotations(from) = ANNOT_Unlink(BB_annotations(from),annot);
02464 }
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474 extern void
02475 BB_Transfer_Callinfo(BB* from, BB* to)
02476 {
02477 ANNOTATION* annot;
02478 Reset_BB_call(from);
02479 annot = ANNOT_Get(BB_annotations(from),ANNOT_CALLINFO);
02480 Is_True(annot != NULL,("No callinfo annotation for BB%d",BB_id(from)));
02481 BB_Add_Annotation(to,ANNOT_CALLINFO,ANNOT_callinfo(annot));
02482 BB_annotations(from) = ANNOT_Unlink(BB_annotations(from),annot);
02483 }
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494 extern void
02495 BB_Transfer_Asminfo (BB *from, BB *to)
02496 {
02497 ANNOTATION* annot;
02498 Reset_BB_asm(from);
02499 annot = ANNOT_Get(BB_annotations(from),ANNOT_ASMINFO);
02500 Is_True(annot != NULL,("No asminfo annotation for BB%d",BB_id(from)));
02501 BB_Add_Annotation(to,ANNOT_ASMINFO,ANNOT_asminfo(annot));
02502 BB_annotations(from) = ANNOT_Unlink(BB_annotations(from),annot);
02503 }
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514 extern void
02515 BB_Transfer_Exitinfo(BB* from, BB* to)
02516 {
02517 ANNOTATION* annot;
02518
02519 Set_BB_exit(to);
02520 Reset_BB_exit(from);
02521 annot = ANNOT_Get(BB_annotations(from),ANNOT_EXITINFO);
02522 Is_True(annot != NULL,("No exitinfo annotation for BB%d",BB_id(from)));
02523 BB_Add_Annotation(to,ANNOT_EXITINFO,ANNOT_exitinfo(annot));
02524 BB_annotations(from) = ANNOT_Unlink(BB_annotations(from),annot);
02525
02526
02527
02528 if (BB_call(from)) {
02529 BB_Transfer_Callinfo(from, to);
02530 }
02531 }
02532
02533
02534 void Change_Succ(BB *pred, BB *old_succ, BB *new_succ)
02535
02536
02537
02538
02539 {
02540 float adjust;
02541 float old_succ_freq = BB_freq(old_succ);
02542 BBLIST *succs = BB_Find_Succ(pred, old_succ);
02543 FmtAssert(succs, ("<old_succ> BB:%d not in BB_succs(BB:%d)",
02544 BB_id(old_succ), BB_id(pred)));
02545
02546 BBLIST_item(succs) = new_succ;
02547 if (FREQ_Frequencies_Computed()) {
02548 adjust = BB_freq(pred) * BBLIST_prob(succs);
02549 #if !defined(TARG_SL) // embedded systems uses int for feedback
02550 if ((BB_freq(pred) == 0) && (BBLIST_prob(succs) >= 0) &&
02551 !(adjust == adjust))
02552 adjust = 0;
02553 #endif
02554 } else if (BB_freq_fb_based(pred)) {
02555
02556 adjust = BB_freq(pred) / BBlist_Len(BB_succs(pred));
02557 } else {
02558 adjust = 0.0F;
02559 }
02560
02561 FmtAssert(adjust >= 0.0F, ("negative freq or probability found"));
02562
02563 if (old_succ_freq < adjust) {
02564 if (CG_warn_bad_freqs && !FREQ_Match(old_succ_freq, adjust)) {
02565 DevWarn("Change_Succ: freq adjustment generated bad results");
02566 }
02567 adjust = old_succ_freq;
02568 }
02569
02570 BB_freq(new_succ) += adjust;
02571 BB_freq(old_succ) -= adjust;
02572
02573 BBlist_Delete_BB(&BB_preds(old_succ), pred);
02574 BBlist_Add_BB(&BB_preds(new_succ), pred);
02575 }
02576
02577
02578
02579 void Change_Succ_Prob(BB *pred, BB *succ, float prob)
02580
02581
02582
02583
02584 {
02585 BBLIST *succs = BB_Find_Succ(pred, succ);
02586 float old_prob;
02587 float factor;
02588 FmtAssert(succs, ("<succ> BB:%d not in BB_succs(BB:%d)",
02589 BB_id(succ), BB_id(pred)));
02590 old_prob = BBLIST_prob(succs);
02591 BBLIST_prob(succs) = prob;
02592
02593 factor = 1.0F + prob - old_prob;
02594 if (factor < 0.0F) {
02595 if (CG_warn_bad_freqs && !FREQ_Match(prob, old_prob)) {
02596 DevWarn("Change_Succ_Prob: freq adjustment generated bad results");
02597 }
02598 factor = 0.0F;
02599 }
02600 BB_freq(succ) *= factor;
02601 }
02602
02603
02604
02605 BOOL BB_Add_Ancestors(BB_SET **set, BB *bb, BB *start_bb, MEM_POOL *pool)
02606
02607
02608
02609
02610 {
02611 BOOL visited_twice = FALSE;
02612 BBLIST *blst;
02613
02614 *set = BB_SET_Union1D(*set, bb, pool);
02615 FOR_ALL_BB_PREDS(bb, blst) {
02616 BB *pred = BBLIST_item(blst);
02617 visited_twice |= (pred == start_bb);
02618 if (!BB_SET_MemberP(*set, pred))
02619 visited_twice |= BB_Add_Ancestors(set, pred, start_bb, pool);
02620 }
02621 return visited_twice;
02622 }
02623
02624
02625 BOOL BB_Has_Exc_Label(BB *bb)
02626
02627
02628
02629
02630 {
02631 if (BB_has_label(bb)) {
02632 ANNOTATION *ant;
02633
02634 for (ant = ANNOT_First(BB_annotations(bb), ANNOT_LABEL);
02635 ant != NULL;
02636 ant = ANNOT_Next(ant, ANNOT_LABEL)
02637 ) {
02638 LABEL_IDX lab = ANNOT_label(ant);
02639 switch (LABEL_kind(Label_Table[lab])) {
02640 case LKIND_BEGIN_EH_RANGE:
02641 case LKIND_END_EH_RANGE:
02642 return TRUE;
02643 }
02644 }
02645 }
02646
02647 return FALSE;
02648 }
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659 BOOL BB_Has_Addr_Taken_Label(BB *bb)
02660 {
02661 if (BB_has_label(bb)) {
02662 ANNOTATION *ant;
02663
02664 for (ant = ANNOT_First(BB_annotations(bb), ANNOT_LABEL);
02665 ant != NULL;
02666 ant = ANNOT_Next(ant, ANNOT_LABEL)
02667 ) {
02668 LABEL_IDX lab = ANNOT_label(ant);
02669 if (LABEL_addr_saved(lab)) return TRUE;
02670 }
02671 }
02672 return FALSE;
02673 }
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684 BOOL BB_Has_Outer_Block_Label(BB *bb)
02685 {
02686 if (BB_has_label(bb)) {
02687 ANNOTATION *ant;
02688
02689 for (ant = ANNOT_First(BB_annotations(bb), ANNOT_LABEL);
02690 ant != NULL;
02691 ant = ANNOT_Next(ant, ANNOT_LABEL)
02692 ) {
02693 LABEL_IDX lab = ANNOT_label(ant);
02694 if (LABEL_target_of_goto_outer_block(lab)) return TRUE;
02695 }
02696 }
02697 return FALSE;
02698 }
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709 BOOL BB_Is_Cold(BB *bb)
02710 {
02711 RID *r;
02712
02713
02714
02715
02716 for (r = BB_rid(bb); r; r = RID_parent(r)) {
02717 if (RID_type(r) == RID_TYPE_cold) return TRUE;
02718 }
02719 return FALSE;
02720 }
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731 ST *Gen_ST_For_BB(BB *bb)
02732 {
02733 char buf[10+1];
02734 ST *st;
02735 TY_IDX ty;
02736
02737 if (bb_st_map == NULL) {
02738 bb_st_map = BB_MAP_Create();
02739 } else {
02740 st = (ST *)BB_MAP_Get(bb_st_map, bb);
02741 if (st) return st;
02742 }
02743
02744 st = New_ST (GLOBAL_SYMTAB);
02745 sprintf(buf, "%d", bb_st_count++);
02746 ty = Make_Function_Type(MTYPE_To_TY(MTYPE_V));
02747 ST_Init (st, Save_Str2(".S.", buf), CLASS_FUNC, SCLASS_TEXT, EXPORT_LOCAL, ty);
02748 Allocate_Object(st);
02749
02750 BB_MAP_Set(bb_st_map, bb, (void *)st);
02751
02752 return st;
02753 }
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764 ST *BB_st(BB *bb)
02765 {
02766 if (bb_st_map) return (ST *)BB_MAP_Get(bb_st_map, bb);
02767 return NULL;
02768 }
02769
02770
02771 #ifdef KEY
02772 static BOOL OP_defs_argument( OP* op )
02773 {
02774 for( int resnum = 0; resnum < OP_results(op); resnum++ ){
02775 TN* tn = OP_result( op, resnum );
02776 if( TN_is_dedicated( tn ) &&
02777 REGISTER_SET_MemberP( REGISTER_CLASS_function_argument(TN_register_class(tn)), TN_register(tn) ) )
02778 return TRUE;
02779 }
02780
02781 return FALSE;
02782 }
02783 #endif
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795 static void Split_BB(BB *bb)
02796 {
02797 OP* op;
02798 INT i;
02799 const INT len = BB_length(bb);
02800 const INT high = (INT)(Split_BB_Length * 1.25);
02801 const INT low = (len <= high) ? (Split_BB_Length / 2) : (INT)(Split_BB_Length * .75);
02802 mINT8 fatpoint[ISA_REGISTER_CLASS_MAX+1];
02803 INT* regs_in_use = (INT *)alloca(sizeof(INT) * (len+1));
02804 INT* splits = (INT *)alloca(sizeof(INT) * ((len / low)+1));
02805 OP** op_vec = (OP **)alloca(sizeof(OP*) * (len+1));
02806
02807 MEM_POOL_Push(&MEM_local_pool);
02808 LRA_Estimate_Fat_Points(bb, fatpoint, regs_in_use, &MEM_local_pool);
02809 MEM_POOL_Pop(&MEM_local_pool);
02810
02811
02812
02813
02814
02815 op_vec[0] = NULL;
02816 i = 1;
02817 FOR_ALL_BB_OPs_FWD(bb, op) op_vec[i++] = op;
02818
02819
02820
02821
02822 INT min_remainder = ((high - Split_BB_Length)/2);
02823 INT min_in_use = INT_MAX;
02824 INT high_idx = high > len ? len : high;
02825 INT split_idx = 0;
02826 INT min_idx = 0;
02827 for (i = low;;) {
02828 if (i == high_idx) {
02829 if (i == len) {
02830
02831
02832
02833
02834 if ((len - min_idx) < min_remainder ) {
02835 if (split_idx == 0) {
02836
02837 return;
02838 }
02839 break;
02840 }
02841 }
02842 #ifdef TARG_X8664
02843
02844
02845 while( min_idx <= len && OP_reads_rflags(op_vec[min_idx]) ){
02846 min_idx++;
02847 }
02848 #endif
02849
02850 #ifdef KEY
02851
02852
02853
02854
02855 if( BB_call( bb ) ){
02856 while( min_idx > 1 &&
02857 OP_defs_argument( op_vec[min_idx-1] ) ){
02858 min_idx--;
02859 }
02860 }
02861 #endif
02862 splits[split_idx++] = min_idx;
02863 if (len - min_idx <= Split_BB_Length) break;
02864 i = min_idx + low;
02865 min_in_use = INT_MAX;
02866 high_idx = min_idx + high;
02867 if (high_idx > len) high_idx = len;
02868 } else {
02869 i++;
02870 }
02871 if (regs_in_use[i] < min_in_use) {
02872 min_in_use = regs_in_use[i];
02873 min_idx = i;
02874 if (regs_in_use[i] < 0) {
02875 DevWarn("Negative registers-in-use count for OP.");
02876 }
02877 }
02878 }
02879 FmtAssert(split_idx > 0, ("failed to split BB:%d", BB_id(bb)));
02880
02881
02882
02883
02884
02885 splits[split_idx] = len + 1;
02886
02887
02888
02889
02890 BB* last_bb = Gen_And_Insert_BB_After(bb);
02891 if (BB_exit(bb)) {
02892 BB_Transfer_Exitinfo(bb, last_bb);
02893 Exit_BB_Head = BB_LIST_Delete(bb, Exit_BB_Head);
02894 Exit_BB_Head = BB_LIST_Push(last_bb, Exit_BB_Head, &MEM_pu_pool);
02895 }
02896 if (BB_call(bb)) {
02897 BB_Transfer_Callinfo(bb, last_bb);
02898 }
02899 if (BB_asm(bb)) {
02900 BB_Transfer_Asminfo (bb, last_bb);
02901 }
02902
02903 BBLIST* nxt;
02904 BBLIST* succ;
02905 for (succ = BB_succs(bb); succ; succ = nxt) {
02906 BB* bb_succ = BBLIST_item(succ);
02907 nxt = BBLIST_next(succ);
02908 Unlink_Pred_Succ(bb, bb_succ);
02909 Link_Pred_Succ(last_bb, bb_succ);
02910 }
02911
02912
02913
02914
02915 INT split_id_max = split_idx - 1;
02916 BB* bb_prev = last_bb;
02917 for (i = split_id_max; i >= 0; i--) {
02918 BB* new_bb;
02919
02920 if (i == split_id_max) {
02921 new_bb = last_bb;
02922 } else {
02923 new_bb = Gen_And_Insert_BB_Before(bb_prev);
02924 bb_prev = new_bb;
02925 }
02926
02927 INT op_idx;
02928 for (op_idx = splits[i]; op_idx < splits[i+1]; op_idx++) {
02929 op = op_vec[op_idx];
02930 #ifdef Is_True_On
02931 if( !BB_call( new_bb ) &&
02932 BB_call( last_bb ) ){
02933 if( OP_defs_argument( op ) ){
02934 DevWarn( "Split_BBs: argument and call are not defined at the same BB" );
02935 }
02936 }
02937 #endif
02938 BB_Move_Op_To_End(new_bb, bb, op);
02939 }
02940 }
02941
02942
02943
02944
02945 bb_prev = bb;
02946 BB *bb_tmp, *bb_stop = BB_next(last_bb);
02947 for (bb_tmp = BB_next(bb); bb_tmp != bb_stop; bb_tmp = BB_next(bb_tmp))
02948 {
02949 Target_Simple_Fall_Through_BB(bb_prev, bb_tmp);
02950 bb_prev = bb_tmp;
02951 }
02952
02953
02954
02955
02956 if (BB_has_globals(bb)) {
02957 Reset_BB_has_globals(bb);
02958 for (bb_tmp = bb; bb_tmp != bb_stop; bb_tmp = BB_next(bb_tmp)) {
02959 BOOL has_dedicated = FALSE;
02960 FOR_ALL_BB_OPs_FWD(bb_tmp, op) {
02961 for (i = 0; i < OP_opnds(op); ++i) {
02962 TN *tn = OP_opnd(op, i);
02963 if (TN_is_dedicated(tn)) { has_dedicated = TRUE; break; }
02964 }
02965 if (has_dedicated) break;
02966 for (i = 0; i < OP_results(op); ++i) {
02967 TN *tn = OP_result(op, i);
02968 if (TN_is_dedicated(tn)) { has_dedicated = TRUE; break; }
02969 }
02970 if (has_dedicated) break;
02971 }
02972 if (has_dedicated) Set_BB_has_globals(bb_tmp);
02973 }
02974 }
02975 }
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986 void
02987 Split_BBs(void)
02988 {
02989 BB* bb;
02990
02991 if (!Enable_BB_Splitting) return;
02992
02993 for ( bb = REGION_First_BB; bb; bb = BB_next(bb) ) {
02994 if (BB_rid(bb) && (RID_level(BB_rid(bb)) >= RL_CGSCHED))
02995
02996 continue;
02997
02998 if (BB_length(bb) > Split_BB_Length)
02999 Split_BB(bb);
03000 }
03001 }
03002
03003
03004 #ifdef TARG_IA64
03005
03006
03007
03008
03009
03010
03011 BB_SET*
03012 Find_BB_Parents(BB* bb)
03013 {
03014 BB_SET* result = BB_SET_Create_Empty(PU_BB_Count+2, &BB_MEM_pool);
03015 BB_CONTAINER_ALLOC bb_mem(&BB_MEM_pool);
03016 BB_CONTAINER bb_vector(bb_mem);
03017 BB_CONTAINER::iterator iter;
03018 bb_vector.push_back(bb);
03019 BOOL bb_visited[PU_BB_Count+2];
03020 for(INT i = 0; i < PU_BB_Count+2; i++) bb_visited[i] = FALSE;
03021 bb_visited[bb->id] = TRUE;
03022 while(!bb_vector.empty()) {
03023 BBLIST* pre_bbs = NULL;
03024 iter = bb_vector.begin();
03025 result = BB_SET_Union1D(result, *iter, &BB_MEM_pool);
03026 for(pre_bbs = BB_preds(*iter),iter = bb_vector.erase(iter); pre_bbs != NULL; pre_bbs = BBLIST_next(pre_bbs))
03027 {
03028 if(!BBLIST_item(pre_bbs) || bb_visited[BBLIST_item(pre_bbs)->id]) continue;
03029 bb_vector.push_back(BBLIST_item(pre_bbs));
03030 bb_visited[BBLIST_item(pre_bbs)->id] = TRUE;
03031 }
03032 }
03033 return result;
03034 }
03035 #endif
03036
03037
03038
03039
03040
03041 struct BB_REGION_SET {
03042 BB_SET *bbs;
03043 MEM_POOL pool;
03044
03045 BOOL operator()(BB *bb) {
03046 return BB_SET_MemberP(bbs, bb);
03047 }
03048
03049 void Set(BB *bb) {
03050 bbs = BB_SET_Union1D(bbs, bb, &pool);
03051 }
03052
03053 void Reset(BB *bb) {
03054 bbs = BB_SET_Difference1D(bbs, bb);
03055 }
03056
03057 void Clear() {
03058 bbs = BB_SET_ClearD(bbs);
03059 }
03060
03061 template <class BB_VECTOR>
03062 void Set(const BB_VECTOR& v) {
03063 for (INT i = 0; i < v.size(); i++)
03064 Set(v[i]);
03065 }
03066
03067 template <class BB_VECTOR>
03068 void Reset(const BB_VECTOR& v) {
03069 for (INT i = 0; i < v.size(); i++)
03070 Reset(v[i]);
03071 }
03072
03073 BOOL Is_empty() const {
03074 return BB_SET_EmptyP(bbs);
03075 }
03076
03077 void Init() {
03078 if (bbs == NULL) {
03079 MEM_POOL_Initialize(&pool, "BB_REGION_SET pool", TRUE);
03080 MEM_POOL_Push(&pool);
03081 bbs = BB_SET_Create_Empty(PU_BB_Count+2, &pool);
03082 }
03083 }
03084
03085 BB_REGION_SET():bbs(NULL) {}
03086 };
03087
03088 static BB_REGION_SET region_exits;
03089 static BB_REGION_SET region_temp;
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099 void BB_REGION_to_Vector(vector<BB*>& bv, const BB_REGION& r)
03100 {
03101 BB_REGION_SET region_temp;
03102
03103 region_temp.Init();
03104
03105
03106 region_temp.Set(r.exits);
03107
03108
03109
03110
03111
03112 vector<BB*> stack(r.entries.begin(), r.entries.end());
03113 while (!stack.empty()) {
03114 BB *bb = stack.back();
03115 stack.pop_back();
03116 region_temp.Set(bb);
03117 bv.push_back(bb);
03118 BBLIST *succs;
03119 FOR_ALL_BB_SUCCS(bb, succs) {
03120 BB *succ = BBLIST_item(succs);
03121 if (!region_temp(succ))
03122 stack.push_back(succ);
03123 }
03124 }
03125
03126
03127 region_temp.Clear();
03128 }
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140 BB_SET *BB_REGION_to_BB_SET(BB_SET *bbs, const BB_REGION& r, MEM_POOL *pool)
03141 {
03142
03143 BB_SET_ClearD(bbs);
03144
03145 region_exits.Init();
03146
03147
03148 region_exits.Set(r.exits);
03149
03150
03151
03152
03153
03154 vector<BB*> stack(r.entries.begin(), r.entries.end());
03155 while (!stack.empty()) {
03156 BB *bb = stack.back();
03157 stack.pop_back();
03158 bbs = BB_SET_Union1D(bbs, bb, pool);
03159 BBLIST *succs;
03160 FOR_ALL_BB_SUCCS(bb, succs) {
03161 BB *succ = BBLIST_item(succs);
03162 if (!BB_SET_MemberP(bbs, succ) && !region_exits(bb))
03163 stack.push_back(succ);
03164 }
03165 }
03166
03167
03168 region_exits.Clear();
03169
03170 return bbs;
03171 }
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182 BB_REGION::BB_REGION(BB_SET *included, MEM_POOL *pool)
03183 :data_allocator(pool),
03184 entries(0, (BB*) NULL, data_allocator),
03185 exits(0, (BB*)NULL, data_allocator) ,
03186 has_omega(false)
03187 {
03188 region_exits.Init();
03189
03190 BB *bb;
03191 FOR_ALL_BB_SET_members(included, bb) {
03192 BBLIST *succs;
03193
03194
03195
03196
03197 FOR_ALL_BB_SUCCS(bb, succs) {
03198 BB *succ = BBLIST_item(succs);
03199 if (!BB_SET_MemberP(included, succ) &&
03200 !region_exits(succ)) {
03201 exits.push_back(succ);
03202 region_exits.Set(succ);
03203 }
03204 }
03205 region_exits.Reset(exits);
03206
03207
03208
03209 BBLIST *preds;
03210 if (BB_preds(bb)) {
03211 FOR_ALL_BB_PREDS(bb, preds) {
03212 BB *pred = BBLIST_item(preds);
03213 if (!BB_SET_MemberP(included, pred)) {
03214 entries.push_back(bb);
03215 break;
03216 }
03217 }
03218 } else {
03219
03220
03221
03222 entries.push_back(bb);
03223 }
03224 }
03225 }
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236 void BB_REGION::Verify() const
03237 {
03238
03239 region_exits.Init();
03240
03241
03242
03243 FmtAssert(entries.size() >= 1, ("BB_REGION should have at least 1 entry."));
03244
03245
03246
03247 FmtAssert(region_exits.Is_empty(), ("BB_REGION::Verify: temp variables in unknown state."));
03248
03249 region_exits.Set(exits);
03250
03251
03252 for (INT i = 0; i < entries.size(); i++) {
03253 FmtAssert(!region_exits(entries[i]),
03254 ("BB_REGION: BB%d in both entry ad exit.", BB_id(entries[i])));
03255 }
03256
03257
03258 if (Has_omega()) {
03259
03260 vector<BB*> stack(entries.begin(), entries.end());
03261 while (!stack.empty()) {
03262 BB *bb = stack.back();
03263 stack.pop_back();
03264 region_exits.Set(bb);
03265 OP *op;
03266 FOR_ALL_BB_OPs(bb, op) {
03267 FmtAssert(_CG_LOOP_info(op),
03268 ("BB_REGION: OP has no CG_LOOP_Info."));
03269 FmtAssert(OP_bb(op) == bb,
03270 ("BB_REGION: OP_bb(op) != bb in BB%d\n", BB_id(bb)));
03271
03272 for (INT opnd = 0; opnd < OP_opnds(op); opnd++) {
03273 TN *tn = OP_opnd(op,opnd);
03274 if (!TN_is_register(tn)) {
03275 FmtAssert(OP_omega(op, opnd) == 0,
03276 ("non-register TN must have zero omega."));
03277 }
03278 }
03279 }
03280 BBLIST *succs;
03281 FOR_ALL_BB_SUCCS(bb, succs) {
03282 BB *succ = BBLIST_item(succs);
03283 if (!region_exits(bb))
03284 stack.push_back(succ);
03285 }
03286 }
03287 region_exits.Clear();
03288 } else
03289 region_exits.Reset(exits);
03290
03291 Is_True(region_exits.Is_empty(), ("BB_REGION::Verify: bb_set is not empty."));
03292 }
03293
03294 void BB_REGION::Print(void) const
03295 {
03296 INT i;
03297 FILE *f = stdout;
03298 fprintf(f, "Has omega = %d",has_omega);
03299 fprintf(f,"Entries: ");
03300 for (i = 0; i < entries.size(); i++) {
03301 fprintf(f,"%d ",BB_id(entries[i]));
03302 }
03303 fprintf(f,"\nExits: ");
03304 for (i = 0; i < exits.size(); i++) {
03305 fprintf(f,"%d ",BB_id(exits[i]));
03306 }
03307 fprintf(f,"\n");
03308 }
03309
03310 #ifdef Is_True_On
03311 void Verify_BB(BB *bb)
03312 {
03313 INT id = BB_id(bb);
03314 FmtAssert(id >= 1 && id <= PU_BB_Count, ("Verify_BB: invalid id."));
03315 FmtAssert(BBvec(id) == bb, ("Verify_BB: inconsistency BB_Vec."));
03316 }
03317 #endif
03318
03319
03320 void
03321 draw_flow_graph(void)
03322 {
03323 if (! DaVinci::enabled (TRUE)) return;
03324
03325 char nlabel[10];
03326
03327 MEM_POOL dv_pool;
03328 dv_pool.magic_num = 0;
03329 MEM_POOL_Constructor pool (&dv_pool, "DaVinci", FALSE);
03330
03331 DaVinci dv (&dv_pool, NULL);
03332
03333 dv.Title (Cur_PU_Name);
03334
03335
03336 NODE_TYPE nt_plain, nt_entry, nt_exit, nt_multi,nt, nt_call;
03337 EDGE_TYPE et_known;
03338
03339 nt_entry.Color ("palegreen");
03340 nt_exit.Color ("pink");
03341 nt_call.Boarder(NB_DOUBLE);
03342 nt_multi.Color ("lightgoldenrod");
03343 nt_multi.Shape(NS_CIRCLE);
03344
03345 dv.Graph_Begin ();
03346
03347
03348 for (BB* bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
03349 sprintf(nlabel,"%d",BB_id(bb));
03350 nt = nt_plain;
03351 if (BBlist_Len(BB_preds(bb)) > 1 || BBlist_Len(BB_succs(bb)) > 1) nt = nt_multi;
03352 if (BB_entry(bb)) nt = nt_entry;
03353 if (BB_exit(bb)) nt = nt_exit;
03354 if (BB_call(bb)) nt = nt_call;
03355 dv.Node_Begin (NODE_ID (bb), nlabel, nt);
03356 BBLIST* sedge;
03357 FOR_ALL_BB_SUCCS(bb, sedge) {
03358 dv.Out_Edge (EDGE_ID (NODE_ID (bb), NODE_ID (BBLIST_item(sedge))),
03359 et_known,
03360 NODE_ID (BBLIST_item(sedge)));
03361 }
03362 dv.Node_End ();
03363 }
03364 dv.Graph_End ();
03365
03366 dv.Event_Loop (NULL);
03367 }
03368
03369
03370 void
03371 verify_flow_graph(void)
03372 {
03373 MEM_POOL_Push(&MEM_local_pool);
03374
03375 BB_SET *visited = BB_SET_Create_Empty(PU_BB_Count+2,&MEM_local_pool);
03376
03377 BB *bb;
03378 BB *pred, *succ;
03379 BBLIST *bl,*bl1;
03380 BOOL found;
03381
03382 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
03383
03384
03385
03386 FOR_ALL_BB_PREDS(bb,bl) {
03387 pred = BBLIST_item(bl);
03388 found = FALSE;
03389 FOR_ALL_BB_SUCCS(pred,bl1) {
03390 succ = BBLIST_item(bl1);
03391 if (succ == bb) {
03392 found = TRUE;
03393 break;
03394 }
03395 }
03396 if (!found) {
03397 fprintf(TFile,"verify_flow_graph: BB%d missing from pred BB%d succ list\n",
03398 BB_id(bb),BB_id(pred));
03399 }
03400 }
03401
03402
03403
03404
03405 FOR_ALL_BB_SUCCS(bb,bl) {
03406 succ = BBLIST_item(bl);
03407 found = FALSE;
03408 FOR_ALL_BB_PREDS(succ,bl1) {
03409 pred = BBLIST_item(bl1);
03410 if (pred == bb) {
03411 found = TRUE;
03412 break;
03413 }
03414 }
03415 if (!found) {
03416 fprintf(TFile,"verify_flow_graph: BB%d missing from succ BB%d pred list\n",
03417 BB_id(bb), BB_id(succ));
03418 }
03419 }
03420 }
03421 MEM_POOL_Pop(&MEM_local_pool);
03422 }
03423