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 #ifdef USE_PCH
00064 #include "cg_pch.h"
00065 #endif // USE_PCH
00066 #pragma hdrstop
00067
00068 #define __STDC_LIMIT_MACROS
00069 #include <stdint.h>
00070
00071 #define USE_STANDARD_TYPES
00072 #include <sys/types.h>
00073 #include <list>
00074 #include <vector>
00075 #include <map>
00076 #include "defs.h"
00077 #include "mempool.h"
00078 #include "errors.h"
00079 #include "ercg.h"
00080 #include "wn.h"
00081 #include "dvector.h"
00082 #include "dep_graph.h"
00083 #include "import.h"
00084 #include "opt_alias_interface.h"
00085 #include "opt_points_to.h"
00086
00087 #include "cg.h"
00088 #include "cgir.h"
00089 #include "tn_set.h"
00090 #include "tn_map.h"
00091 #include "tn_list.h"
00092 #include "ti_latency.h"
00093 #include "register.h"
00094 #include "bitset.h"
00095 #include "tracing.h"
00096 #include "cgtarget.h"
00097 #include "cgprep.h"
00098 #include "op_list.h"
00099 #include "whirl2ops.h"
00100 #include "cg_loop.h"
00101 #include "pf_cg.h"
00102 #include "wn_map.h"
00103 #include "cg_db_op.h"
00104 #include "cg_cflow.h"
00105 #include "cg_loop_scc.h"
00106 #include "cg_flags.h"
00107 #include "cg_spill.h"
00108 #include "cg_swp_target.h"
00109 #include "dominate.h"
00110 #include "bb_set.h"
00111 #include "freq.h"
00112 #include "gra_live.h"
00113 #include "reg_live.h"
00114 #include "targ_proc_properties.h"
00115 #include "pqs_cg.h"
00116 #include "gtn_universe.h"
00117 #include "gtn_set.h"
00118 #include "gcm.h"
00119
00120 #include "cg_dep_graph.h"
00121 #include "cg_dep_graph_util.h"
00122
00123 #ifdef TARG_IA64
00124 #include "speculation.h"
00125 #include "recovery.h"
00126 #endif
00127
00128 #include "data_layout.h"
00129
00130 #if defined(TARG_SL) || defined(TARG_MIPS) // Build_LUT_Insn
00131 #include <iostream>
00132 #include <vector>
00133 #include <stdlib.h>
00134 #include <strings.h>
00135 #include <map>
00136 #include <fstream>
00137 #include <string>
00138 #include <ctype.h>
00139 #include "glob.h"
00140 #include "lib_phase_dir.h"
00141 #include "dag.h"
00142 #endif
00143
00144 #ifdef TARG_IA64
00145
00146 #include <set>
00147 #include <ext/hash_map>
00148 #include "ipfec_defs.h"
00149 #include "region_bb_util.h"
00150 #include "dag.h"
00151 #include "prdb.h"
00152 #include "op_targ.h"
00153 #include "dag.h"
00154
00155
00156 #include "targ_cache_info.h"
00157 #include "cache_analysis.h"
00158
00159
00160 #endif
00161
00162
00163 #ifdef DONT_INLINE
00164 #define inline static
00165 #endif
00166
00167 #ifdef TARG_X8664
00168 #define OP_Load(o) ( OP_load(o) || OP_load_exe(o) )
00169 #else
00170 #define OP_Load(o) OP_load(o)
00171 #endif
00172
00173 #define Set_OP_opnds(o,n) ((o)->opnds = (n))
00174 #define Set_OP_results(o,n) ((o)->results = (n))
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 typedef enum {
00185 CYC_UNKNOWN,
00186 CYC_ISSUE,
00187 CYC_ISSUED,
00188 CYC_COMMIT,
00189 CYC_READ,
00190 CYC_WRITE,
00191 CYC_LOAD,
00192 CYC_STORE,
00193 CYC_NUM_KIND
00194 } CYC_KIND;
00195
00196
00197
00198
00199 struct dep_info {
00200 CG_DEP_KIND kind;
00201 char name[8];
00202 mINT16 tail;
00203 mINT16 head;
00204 mINT16 adjust;
00205 };
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 static const struct dep_info *dep_info[CG_DEP_NUM_KIND];
00222
00223
00224
00225 #define DEP_INFO_name(k) (dep_info[k]->name)
00226 #define DEP_INFO_tail(k) (dep_info[k]->tail)
00227 #define DEP_INFO_head(k) (dep_info[k]->head)
00228 #define DEP_INFO_adjust(k) (dep_info[k]->adjust)
00229
00230
00231
00232
00233
00234
00235
00236 static const struct dep_info dep_info_data[] = {
00237 { CG_DEP_REGIN, "REGIN", CYC_WRITE, CYC_READ, 0 },
00238 { CG_DEP_REGOUT, "REGOUT", CYC_WRITE, CYC_WRITE, 1 },
00239 { CG_DEP_REGANTI, "REGANTI", CYC_READ, CYC_WRITE, 1 },
00240 { CG_DEP_MEMIN, "MEMIN", CYC_STORE, CYC_LOAD, 1 },
00241 { CG_DEP_MEMOUT, "MEMOUT", CYC_STORE, CYC_STORE, 1 },
00242 { CG_DEP_MEMANTI, "MEMANTI", CYC_LOAD, CYC_STORE, 1 },
00243 { CG_DEP_MEMVOL, "MEMVOL", CYC_LOAD, CYC_LOAD, 1 },
00244 { CG_DEP_MEMREAD, "MEMREAD", CYC_LOAD, CYC_LOAD, 1 },
00245 { CG_DEP_SPILLIN, "SPILLIN", CYC_STORE, CYC_LOAD, 1 },
00246 { CG_DEP_PREFIN, "PREFIN", CYC_LOAD, CYC_LOAD, 1 },
00247 { CG_DEP_PREFOUT, "PREFOUT", CYC_STORE, CYC_STORE, 1 },
00248 { CG_DEP_PREBR, "PREBR", CYC_ISSUED, CYC_COMMIT, 1 },
00249 { CG_DEP_POSTBR, "POSTBR", CYC_ISSUED, CYC_COMMIT, 1 },
00250 { CG_DEP_SCC, "SCC", CYC_UNKNOWN, CYC_UNKNOWN, 0 },
00251 #ifdef TARG_IA64
00252 { CG_DEP_PRECHK, "PRECHK", CYC_ISSUED, CYC_COMMIT, 1 },
00253 { CG_DEP_POSTCHK, "POSTCHK", CYC_ISSUED, CYC_COMMIT, 1 },
00254 { CG_DEP_CTLSPEC, "CTLSPEC", CYC_WRITE, CYC_READ, 0 },
00255 #endif
00256 { CG_DEP_MISC, "MISC", CYC_ISSUE, CYC_ISSUE, 0 },
00257 };
00258
00259
00260
00261
00262
00263
00264
00265 BB_MAP _cg_dep_op_info;
00266 enum { PRUNE_NONE, PRUNE_NON_CYCLIC, PRUNE_NON_CYCLIC_WITH_REG,
00267 PRUNE_CYCLIC_0, PRUNE_CYCLIC_1 };
00268
00269 BOOL CG_DEP_Ignore_LNO = FALSE;
00270 BOOL CG_DEP_Ignore_WOPT = FALSE;
00271 BOOL CG_DEP_Addr_Analysis = TRUE;
00272 BOOL CG_DEP_Verify_Mem_Deps = FALSE;
00273 #ifdef TARG_IA64
00274 BOOL CG_DEP_Add_Alloca_Arcs = FALSE;
00275 BOOL CG_DEP_Relax_Xfer_Dependence = TRUE;
00276 BOOL CG_DEP_Prune_Dependence = TRUE;
00277 #else
00278 BOOL CG_DEP_Add_Alloca_Arcs = TRUE;
00279 BOOL CG_DEP_Relax_Xfer_Dependence = FALSE;
00280 BOOL CG_DEP_Prune_Dependence = FALSE;
00281 #endif
00282 BOOL CG_DEP_Adjust_OOO_Latency = TRUE;
00283 INT32 CG_DEP_Mem_Arc_Pruning = PRUNE_NONE;
00284
00285 BB * _cg_dep_bb;
00286
00287
00288 static std::list<BB*> _cg_dep_bbs;
00289 static MEM_POOL dep_map_nz_pool;
00290 MEM_POOL dep_nz_pool;
00291 static BOOL include_assigned_registers;
00292 static BOOL cyclic;
00293 static BOOL include_memread_arcs;
00294 static BOOL include_memin_arcs;
00295 static BOOL include_control_arcs;
00296 static BOOL tracing;
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 inline BOOL OP_like_barrier(OP *op)
00311 {
00312 return (CGTARG_Is_OP_Barrier(op) || OP_Alloca_Barrier(op));
00313 }
00314
00315 BOOL OP_like_store(OP *op)
00316 {
00317 BOOL like_store = (OP_store(op) || CGTARG_Is_OP_Intrinsic(op) ||
00318 #if defined(TARG_SL)
00319 OP_code(op) == TOP_c2_joint ||
00320 #endif
00321 CGTARG_Is_OP_Barrier(op) || OP_code(op) == TOP_asm);
00322
00323 #ifdef TARG_X8664
00324 like_store |= OP_load_exe_store(op);
00325 #endif
00326
00327 like_store |= OP_like_barrier(op);
00328
00329 return like_store;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338 BOOL
00339 is_xfer_depndnce_reqd(const void *op, const void *xfer_op)
00340
00341 {
00342
00343 if (!CG_DEP_Relax_Xfer_Dependence) return TRUE;
00344
00345
00346 if (OP_xfer((OP *) op)) return TRUE;
00347
00348
00349 if (OP_call((OP*) xfer_op) &&
00350 CG_DEP_Can_OP_Move_Across_Call((OP*) op, (OP*) xfer_op, TRUE, TRUE))
00351 goto safe_dependence;
00352
00353
00354 if (OP_cond((OP *) xfer_op)) {
00355
00356 if (!CGTARG_Can_Be_Speculative((OP *) op)) return TRUE;
00357
00358 BBLIST *succ_list;
00359 BOOL live_out = FALSE;
00360 for (INT i = 0; i < OP_results((OP *) op); ++i) {
00361 TN *result_tn = OP_result((OP *) op, i);
00362 FOR_ALL_BB_SUCCS(OP_bb((OP *) xfer_op), succ_list) {
00363
00364
00365 BB *succ_bb = BBLIST_item(succ_list);
00366 if (succ_bb == OP_bb((OP *) op)) continue;
00367 live_out |= GRA_LIVE_TN_Live_Into_BB(result_tn, succ_bb);
00368
00369
00370
00371 if (TN_is_register(result_tn)) {
00372 ISA_REGISTER_CLASS result_cl = TN_register_class (result_tn);
00373 REGISTER result_reg = TN_register (result_tn);
00374 live_out |= REG_LIVE_Into_BB (result_cl, result_reg, succ_bb);
00375 }
00376 }
00377 }
00378 if (!live_out) goto safe_dependence;
00379 }
00380
00381
00382
00383 return TRUE;
00384
00385
00386
00387 safe_dependence:
00388 return FALSE;
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 #define ARC_pred_idx(arc) (OP_map_idx((arc)->pred+0))
00402
00403 #define ARC_succ_idx(arc) (OP_map_idx((arc)->succ+0))
00404
00405 #define ARC_rest_preds(arc) ((arc)->next[0])
00406
00407 #define ARC_rest_succs(arc) ((arc)->next[1])
00408
00409 #define Set_ARC_pred(arc, predop) ((arc)->pred = (predop))
00410
00411 #define Set_ARC_succ(arc, succop) ((arc)->succ = (succop))
00412
00413 #define Set_ARC_omega(arc, val) ((arc)->omega = (val))
00414
00415 #define Set_ARC_kind(arc, val) { \
00416 ARC *_arc = arc; \
00417 _arc->kind_def_opnd &= ~0xff; \
00418 _arc->kind_def_opnd |= val; \
00419 }
00420
00421 #define Set_ARC_is_definite(arc, val) { \
00422 ARC *_arc = arc; \
00423 _arc->kind_def_opnd &= ~0x0100; \
00424 _arc->kind_def_opnd |= (val != 0) << 8; \
00425 }
00426
00427 #define Set_ARC_opnd(arc, val) { \
00428 ARC *_arc = arc; \
00429 _arc->kind_def_opnd &= ~0xf000; \
00430 _arc->kind_def_opnd |= val << 12; \
00431 }
00432
00433 #define Set_ARC_latency(arc, val) ((arc)->latency = (val))
00434
00435 #define Set_ARC_rest_preds(arc, val) ((arc)->next[0] = (val))
00436
00437 #define Set_ARC_rest_succs(arc, val) ((arc)->next[1] = (val))
00438
00439 #define ARC_LIST_is_succ_list(list) ((INTPTR)list & 1)
00440 #define ARC_LIST_is_pred_list(list) (!((INTPTR)list & 1))
00441
00442 ARC_LIST*
00443 ARC_LIST_Find(ARC_LIST *list, CG_DEP_KIND kind, INT16 opnd)
00444
00445
00446
00447
00448 {
00449 for (; list; list = ARC_LIST_rest(list)) {
00450 ARC *arc = ARC_LIST_first(list);
00451 if (ARC_kind(arc) == kind &&
00452 (!ARC_has_opnd(arc) || opnd == DONT_CARE || ARC_opnd(arc) == opnd))
00453 return list;
00454 }
00455 return NULL;
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465 OP *
00466 ARC_LIST_Find_Defining_Op(OP *op, INT16 rslt, CG_DEP_KIND kind, INT16 opnd)
00467
00468
00469
00470
00471 {
00472 INT32 iteration_count = 0;
00473 ARC_LIST *list = OP_preds(op);
00474 OP *first_match = NULL;
00475 for (; list; list = ARC_LIST_rest(list)) {
00476 ARC *arc = ARC_LIST_first(list);
00477 if (ARC_kind(arc) == kind &&
00478 (!ARC_has_opnd(arc) || opnd == DONT_CARE || ARC_opnd(arc) == opnd)) {
00479 OP *new_op = ARC_pred(arc);
00480 if (op == new_op) continue;
00481 if (rslt == -1) {
00482 return new_op;
00483 }
00484 if (!(Is_CG_LOOP_Op(op) && Is_CG_LOOP_Op(new_op)) ||
00485 (OP_omega(op,rslt) < OP_omega(new_op,opnd)) ) {
00486 if (first_match != NULL) return NULL;
00487 first_match = new_op;
00488 continue;
00489 }
00490 if (++iteration_count > 10000) {
00491 DevWarn("cg_dep_graph: ARC count exceeded. Entering fail-safe node.\n");
00492 return NULL;
00493 }
00494 }
00495 }
00496 return first_match;
00497 }
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 #define next_free_op_info(op_info) (*(_CG_DEP_OP_INFO **)op_info)
00526 static _CG_DEP_OP_INFO *free_op_info = NULL;
00527
00528
00529 #define init_op_info() (free_op_info = NULL)
00530
00531 #if !defined(TARG_IA64) && !defined(TARG_SL) && !defined(TARG_MIPS)
00532 static
00533 #endif
00534 _CG_DEP_OP_INFO *new_op_info(void)
00535
00536 {
00537 _CG_DEP_OP_INFO *result = free_op_info;
00538
00539 if (result) {
00540
00541 free_op_info = next_free_op_info(result);
00542 } else {
00543
00544 result = TYPE_MEM_POOL_ALLOC(_CG_DEP_OP_INFO, &dep_nz_pool);
00545 }
00546
00547
00548
00549
00550 result->succs = result->preds = NULL;
00551
00552 return result;
00553 }
00554
00555 inline void delete_op_info(OP *op)
00556
00557 {
00558 BB_OP_MAP omap = (BB_OP_MAP)BB_MAP_Get(_cg_dep_op_info, OP_bb(op));
00559 _CG_DEP_OP_INFO *info = (_CG_DEP_OP_INFO *)BB_OP_MAP_Get(omap, op);
00560 next_free_op_info(info) = free_op_info;
00561 free_op_info = info;
00562 }
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 BOOL
00582 OP_has_subset_predicate(const void *value1, const void *value2)
00583 {
00584 #ifdef TARG_IA64
00585
00586 if(PRDB_Valid()){
00587 PRDB_GEN* prdb = Get_PRDB();
00588 if(Home_Region(OP_bb((OP*)value1)) != Home_Region(OP_bb((OP*)value2))) return FALSE;
00589 if(Home_Region(OP_bb((OP*)value1))->Region_Type() == IMPROPER ||
00590 Home_Region(OP_bb((OP*)value1))->Is_No_Further_Opt()) return FALSE;
00591 if(!OP_has_predicate((OP*)value1) || !OP_has_predicate((OP*)value2)) return FALSE;
00592 return prdb->Partition_Graph(Home_Region(OP_bb((OP*)value1)))->Is_Subset(
00593 TN_OP_PAIR(OP_opnd((OP*)value2, OP_PREDICATE_OPND),(OP*)value2),
00594 TN_OP_PAIR(OP_opnd((OP*)value1, OP_PREDICATE_OPND),(OP*)value1));
00595 }
00596 #endif
00597
00598 BOOL v1P = FALSE;
00599 BOOL v2P = FALSE;
00600
00601
00602
00603
00604 TN *p1, *p2;
00605 if (OP_has_predicate((OP *) value1) && OP_has_predicate((OP *) value2)) {
00606
00607 p1 = OP_opnd((OP*) value1, OP_PREDICATE_OPND);
00608 p2 = OP_opnd((OP*) value2, OP_PREDICATE_OPND);
00609 v1P = v2P = TRUE;
00610
00611 } else if (OP_has_predicate((OP *) value1) &&
00612 !OP_has_predicate((OP *) value2)) {
00613
00614 p1 = OP_opnd((OP*) value1, OP_PREDICATE_OPND);
00615 p2 = True_TN;
00616 v1P = TRUE;
00617 v2P = FALSE;
00618
00619 } else if (!OP_has_predicate((OP *) value1) &&
00620 OP_has_predicate((OP *) value2)) {
00621
00622 p1 = True_TN;
00623 p2 = OP_opnd((OP*) value2, OP_PREDICATE_OPND);
00624 v1P = FALSE;
00625 v2P = TRUE;
00626
00627 }
00628
00629 if (v1P || v2P) {
00630
00631
00632 if (p1 == p2) return TRUE;
00633
00634
00635 if (!PQSCG_pqs_valid()) return FALSE;
00636
00637
00638 return (PQSCG_is_subset_of(p2, p1));
00639 }
00640
00641 return TRUE;
00642 }
00643
00644 BOOL
00645 OP_has_disjoint_predicate(const OP *value1, const OP *value2)
00646 {
00647 #ifdef TARG_IA64
00648
00649 if(PRDB_Valid()){
00650 PRDB_GEN* prdb = Get_PRDB();
00651 if(Home_Region(OP_bb(value1)) != Home_Region(OP_bb(value2))) return FALSE;
00652 if(Home_Region(OP_bb(value1))->Region_Type() == IMPROPER ||
00653 Home_Region(OP_bb(value1))->Is_No_Further_Opt()) return FALSE;
00654 if(!OP_has_predicate(value1) || !OP_has_predicate(value2)) return FALSE;
00655 return prdb->Partition_Graph(Home_Region(OP_bb(value1)))->Is_Disjoint(
00656 TN_OP_PAIR(OP_opnd(value1, OP_PREDICATE_OPND),value1),
00657 TN_OP_PAIR(OP_opnd(value2, OP_PREDICATE_OPND),value2));
00658 }
00659 #endif
00660
00661
00662
00663
00664 if (PQSCG_pqs_valid() &&
00665 OP_has_predicate(value1) &&
00666 OP_has_predicate(value2)) {
00667
00668 TN *p1 = OP_opnd(value1, OP_PREDICATE_OPND);
00669 TN *p2 = OP_opnd(value2, OP_PREDICATE_OPND);
00670
00671
00672 if (PQSCG_is_disjoint(p1, p2)) return TRUE;
00673 }
00674
00675 return FALSE;
00676 }
00677
00678
00679 BOOL
00680 OP_has_subset_predicate_cyclic(OP *op1, OP *op2)
00681 {
00682 if (!OP_cond_def(op1)) return TRUE;
00683
00684 TN *p1 = OP_has_predicate(op1) ? OP_opnd(op1, OP_PREDICATE_OPND) : True_TN;
00685 TN *p2 = OP_has_predicate(op2) ? OP_opnd(op2, OP_PREDICATE_OPND) : True_TN;
00686
00687 if (!PQSCG_pqs_valid()) return FALSE;
00688
00689 return (PQSCG_is_subset_of(p2, p1));
00690 }
00691
00692
00693 BOOL
00694 OP_has_disjoint_predicate_cyclic(OP *op1, OP *op2)
00695 {
00696 if (PQSCG_pqs_valid() &&
00697 OP_has_predicate(op1) &&
00698 OP_has_predicate(op2)) {
00699
00700 TN *p1 = OP_opnd(op1, OP_PREDICATE_OPND);
00701 TN *p2 = OP_opnd(op2, OP_PREDICATE_OPND);
00702
00703
00704 if (PQSCG_is_disjoint(p1, p2)) return TRUE;
00705 }
00706
00707 return FALSE;
00708 }
00709
00710 static BOOL maintain_prebr;
00711 static void maintain_prebr_arc(OP *op);
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733 inline BOOL has_assigned_reg(TN *tn)
00734
00735 {
00736 return TN_is_register(tn) &&
00737 (TN_is_dedicated(tn) ||
00738 include_assigned_registers && ((TN_register(tn) != REGISTER_UNDEFINED) ||
00739 !TN_is_true_pred(tn)));
00740 }
00741
00742 TN_LIST *same_reg[REGISTER_MAX+1][ISA_REGISTER_CLASS_MAX+1];
00743
00744 #define init_reg_assignments() bzero(same_reg, sizeof(same_reg))
00745
00746
00747 inline void add_reg_assignment(TN *tn)
00748 {
00749 REGISTER rnum = TN_register(tn);
00750 ISA_REGISTER_CLASS rclass = TN_register_class(tn);
00751 TN_LIST *tns;
00752 Is_True(has_assigned_reg(tn), ("no register (or ignored)"));
00753 for (tns = same_reg[rnum][rclass]; tns; tns = TN_LIST_rest(tns))
00754 if (TN_LIST_first(tns) == tn)
00755 return;
00756 same_reg[rnum][rclass] = TN_LIST_Push(tn, same_reg[rnum][rclass],
00757 &dep_nz_pool);
00758 }
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810 #define next_free_arc(arc) (*(ARC **)arc)
00811 static ARC *free_arcs = NULL;
00812
00813
00814
00815 #define init_arcs() (free_arcs = NULL)
00816
00817
00818
00819 static ARC *create_arc(void)
00820 {
00821 ARC *arc = free_arcs;
00822 if (arc) {
00823
00824 Is_True(arc->kind_def_opnd == 0xff, ("non-deleted arc on free list"));
00825 #ifdef Is_True_On
00826 arc->kind_def_opnd = 0;
00827 #endif
00828 free_arcs = next_free_arc(arc);
00829 } else {
00830
00831 arc = TYPE_MEM_POOL_ALLOC(ARC, &dep_nz_pool);
00832 }
00833 return arc;
00834 }
00835
00836
00837 inline void detach_arc_from_succ(ARC *arc)
00838 {
00839 ARC_LIST **prevp = &_CG_DEP_op_info(ARC_succ(arc))->preds;
00840 while (ARC_LIST_first(*prevp) != arc)
00841 prevp = &ARC_rest_preds(ARC_LIST_first(*prevp));
00842 *prevp = ARC_rest_preds(*prevp);
00843 #ifdef Is_True_On
00844
00845 Set_ARC_rest_preds(arc, (ARC *)~0);
00846 #endif
00847 }
00848
00849
00850 inline void detach_arc_from_pred(ARC *arc)
00851 {
00852 OP *pred = ARC_pred(arc);
00853 ARC_LIST **prevp = &_CG_DEP_op_info(pred)->succs;
00854 while (ARC_LIST_first(*prevp) != arc)
00855 prevp = &ARC_rest_succs(ARC_LIST_first(*prevp));
00856 *prevp = ARC_rest_succs(arc);
00857 #ifdef Is_True_On
00858
00859 Set_ARC_rest_succs(arc, (ARC *)~0);
00860 #endif
00861 if (maintain_prebr && ARC_kind(arc) != CG_DEP_PREBR && ARC_omega(arc) == 0 &&
00862 ARC_latency(arc) >= 0)
00863 maintain_prebr_arc(pred);
00864 }
00865
00866
00867 inline void detach_arc(ARC *arc)
00868 {
00869 detach_arc_from_succ(arc);
00870 detach_arc_from_pred(arc);
00871 }
00872
00873 void CG_DEP_Detach_Arc(ARC *arc)
00874 {
00875 detach_arc(arc);
00876 }
00877
00878
00879 inline void attach_arc_to_succ(ARC *arc)
00880 {
00881 OP *succ = ARC_succ(arc);
00882 Set_ARC_rest_preds(arc, OP_preds(succ));
00883 _CG_DEP_op_info(succ)->preds = arc;
00884 }
00885
00886
00887 inline void attach_arc_to_pred(ARC *arc)
00888 {
00889 OP *pred = ARC_pred(arc);
00890 Set_ARC_rest_succs(arc, OP_succs(pred));
00891 _CG_DEP_op_info(pred)->succs = (ARC_LIST *)((INTPTR)arc | 1);
00892 if (maintain_prebr && ARC_kind(arc) != CG_DEP_PREBR) maintain_prebr_arc(pred);
00893 }
00894
00895
00896 inline void attach_arc(ARC *arc)
00897 {
00898 attach_arc_to_succ(arc);
00899 attach_arc_to_pred(arc);
00900 }
00901
00902 inline BOOL dir_has_eq(DIRECTION dir)
00903
00904
00905
00906
00907
00908 {
00909 return dir == DIR_EQ || dir == DIR_NEGEQ || dir == DIR_POSEQ ||
00910 dir == DIR_STAR;
00911 }
00912
00913
00914 inline BOOL ALIAS_RESULT_positive(ALIAS_RESULT result)
00915 {
00916 return result == POSSIBLY_ALIASED || result == SAME_LOCATION;
00917 }
00918
00919
00920
00921
00922 #if !(defined(TARG_IA64) || defined(TARG_SL) || defined(TARG_MIPS))
00923 static
00924 #endif
00925 ARC *new_arc_with_latency(CG_DEP_KIND kind, OP *pred, OP *succ,
00926 INT16 latency, UINT8 omega,
00927 UINT8 opnd, BOOL is_definite)
00928 {
00929 ARC *arc;
00930 BB_OP_MAP pmap = (BB_OP_MAP)BB_MAP_Get(_cg_dep_op_info, OP_bb(pred));
00931 BB_OP_MAP smap = (BB_OP_MAP)BB_MAP_Get(_cg_dep_op_info, OP_bb(succ));
00932
00933 if (BB_OP_MAP_Get(pmap, pred) == NULL)
00934 BB_OP_MAP_Set(pmap, pred, new_op_info());
00935 if (BB_OP_MAP_Get(smap, succ) == NULL)
00936 BB_OP_MAP_Set(smap, succ, new_op_info());
00937
00938 arc = create_arc();
00939
00940
00941 if ((kind == CG_DEP_MEMIN || kind == CG_DEP_MEMOUT ||
00942 kind == CG_DEP_MEMANTI || kind == CG_DEP_MEMREAD) &&
00943 OP_volatile(pred) && OP_volatile(succ))
00944 kind = CG_DEP_MEMVOL;
00945
00946
00947 if (kind == CG_DEP_MEMIN && CGSPILL_Is_Spill_Op(pred) &&
00948 CGSPILL_Is_Spill_Op(succ) &&
00949 OP_store(pred) && OP_load(succ)) {
00950 kind = CG_DEP_SPILLIN;
00951 latency = CG_DEP_Latency(pred, succ, kind, opnd);
00952 }
00953
00954
00955 if (kind == CG_DEP_SPILLIN && cyclic)
00956 omega = OP_restore_omega(succ);
00957
00958 Set_ARC_kind(arc, kind);
00959 Set_ARC_opnd(arc, opnd);
00960 Set_ARC_is_definite(arc, is_definite);
00961 Set_ARC_pred(arc, pred);
00962 Set_ARC_succ(arc, succ);
00963 Set_ARC_omega(arc, omega);
00964 Set_ARC_latency(arc, latency);
00965 Set_ARC_is_dotted(arc, FALSE);
00966
00967 attach_arc(arc);
00968 return arc;
00969 }
00970
00971
00972 ARC *new_arc(CG_DEP_KIND kind, OP *pred, OP *succ, UINT8 omega,
00973 UINT8 opnd, BOOL is_definite)
00974 {
00975 INT16 latency = (CG_DEP_Adjust_OOO_Latency && PROC_is_out_of_order() &&
00976 (kind == CG_DEP_REGOUT || kind == CG_DEP_REGANTI))
00977 ? 0 : CG_DEP_Latency(pred, succ, kind, opnd);
00978 ARC *arc = new_arc_with_latency(kind, pred, succ, latency, omega, opnd,
00979 is_definite);
00980 return arc;
00981 }
00982
00983
00984
00985 inline void delete_arc(ARC *arc)
00986 {
00987 Is_True(((INTPTR)arc & 1) == 0, ("delete_arc passed ARC_LIST"));
00988 Is_True(arc->kind_def_opnd != 0xff, ("deleting already-deleted arc"));
00989 #ifdef Is_True_On
00990
00991 arc->kind_def_opnd = 0xff;
00992
00993 Set_ARC_rest_succs(arc, (ARC *)~0);
00994 Set_ARC_rest_preds(arc, (ARC *)~0);
00995 #endif
00996 next_free_arc(arc) = free_arcs;
00997 free_arcs = arc;
00998 }
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049 #define ARC_LIST_prev ARC_rest_succs
01050 #define Set_ARC_LIST_prev Set_ARC_rest_succs
01051 #define Set_ARC_LIST_rest Set_ARC_rest_preds
01052
01053 TN_MAP gtn_use_map;
01054
01055
01056 #define init_gtn_use_arcs() (gtn_use_map = TN_MAP_Create())
01057 #define delete_gtn_use_arcs() { \
01058 TN_MAP_Delete(gtn_use_map); \
01059 gtn_use_map = NULL; \
01060 }
01061
01062
01063 ARC_LIST *CG_DEP_GTN_Use_Arcs(TN *tn)
01064 {
01065 ARC_LIST *result = (ARC_LIST *)TN_MAP_Get(gtn_use_map, tn);
01066 return result;
01067 }
01068
01069
01070 void add_gtn_use_arc(OP *op, UINT8 opnd)
01071 {
01072 TN *tn = OP_opnd(op, opnd);
01073 ARC_LIST *arcs = CG_DEP_GTN_Use_Arcs(tn);
01074 ARC *arc = create_arc();
01075
01076 Is_True(TN_is_register(tn), ("add_gtn_use_arc called w/const TN"));
01077
01078 Set_ARC_kind(arc, CG_DEP_REGIN);
01079 Set_ARC_opnd(arc, opnd);
01080 Set_ARC_is_definite(arc, FALSE);
01081 Set_ARC_succ(arc, op);
01082 Set_ARC_omega(arc, 0);
01083
01084 if (arcs) {
01085
01086 ARC_LIST *rest = ARC_LIST_rest(arcs);
01087
01088 Set_ARC_LIST_rest((ARC_LIST *)arc, rest);
01089 Set_ARC_LIST_rest(arcs, (ARC_LIST *)arc);
01090
01091 Set_ARC_LIST_prev((ARC_LIST *)arc, arcs);
01092 if (rest) Set_ARC_LIST_prev(rest, (ARC_LIST *)arc);
01093 } else {
01094
01095 Set_ARC_LIST_rest((ARC_LIST *)arc, NULL);
01096
01097 Set_ARC_LIST_prev((ARC_LIST *)arc, NULL);
01098 TN_MAP_Set(gtn_use_map, tn, (ARC_LIST *)arc);
01099 }
01100 }
01101
01102
01103 static void detach_gtn_use_arc(ARC *arc)
01104 {
01105 TN *tn = OP_opnd(ARC_succ(arc), ARC_opnd(arc));
01106 if (TN_is_register(tn)) {
01107 ARC_LIST *before = ARC_LIST_prev(arc);
01108 ARC_LIST *after = ARC_LIST_rest(arc);
01109 if (after) Set_ARC_LIST_prev(after, before);
01110 if (before) Set_ARC_LIST_rest(before, after);
01111 else TN_MAP_Set(gtn_use_map, tn, after);
01112 }
01113 }
01114
01115
01116 static void delete_gtn_use_arc(OP *op, UINT8 opnd)
01117 {
01118 TN *tn = OP_opnd(op, opnd);
01119 if (TN_is_register(tn)) {
01120 ARC_LIST *arcs = CG_DEP_GTN_Use_Arcs(tn);
01121 #ifdef Is_True_On
01122 BOOL found = FALSE;
01123 #endif
01124 while (arcs) {
01125 ARC *arc = ARC_LIST_first(arcs);
01126 UINT8 aopnd = ARC_opnd(arc);
01127 INT16 asidx = ARC_succ_idx(arc);
01128 arcs = ARC_LIST_rest(arcs);
01129 if (asidx == OP_map_idx(op) && aopnd == opnd) {
01130 detach_gtn_use_arc(arc);
01131 delete_arc(arc);
01132 #ifdef Is_True_On
01133 if (found)
01134 DevWarn("more than one gtn use arc for opnd %d of OP%d; "
01135 "removing",
01136 aopnd, asidx);
01137 found = TRUE;
01138 #else
01139 return;
01140 #endif
01141 }
01142 }
01143 }
01144 }
01145
01146 #undef ARC_LIST_prev // ARC_rest_succs
01147 #undef Set_ARC_LIST_prev // Set_ARC_rest_succs
01148 #undef Set_ARC_LIST_rest // Set_ARC_rest_preds
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167 inline INT16 get_cycle(TOP opcode, INT16 ckind, UINT8 opnd)
01168 {
01169 switch ( ckind ) {
01170 case CYC_LOAD:
01171 return TI_LATENCY_Load_Cycle(opcode);
01172 case CYC_STORE:
01173 return TI_LATENCY_Store_Cycle(opcode);
01174 case CYC_ISSUE:
01175 return 0;
01176 case CYC_ISSUED:
01177 return TI_LATENCY_Last_Issue_Cycle(opcode);
01178 case CYC_COMMIT:
01179 return TI_LATENCY_Commit_Cycle(opcode);
01180 case CYC_READ:
01181 return TI_LATENCY_Operand_Access_Cycle(opcode, opnd);
01182 case CYC_WRITE:
01183 return TI_LATENCY_Result_Available_Cycle(opcode, 0 );
01184 }
01185
01186 ErrMsg(EC_Ill_Cycle, ckind, "get_cycle");
01187 return 0;
01188 }
01189
01190 #ifdef TARG_IA64
01191
01192
01193
01194
01195
01196 INT16
01197 CG_DEP_Oper_cycle(TOP oper, CG_DEP_KIND kind)
01198 {
01199
01200 INT i;
01201 for (i = 0; i < sizeof(dep_info_data) / sizeof(dep_info_data[0]); i++) {
01202 CG_DEP_KIND kind = dep_info_data[i].kind;
01203 dep_info[kind] = dep_info_data + i;
01204 }
01205
01206 FmtAssert(DEP_INFO_tail(kind) == CYC_WRITE, ("Failed option to get the cycle of the last op "));
01207 return get_cycle(oper, DEP_INFO_tail(kind), 0);
01208 }
01209 #endif
01210
01211
01212
01213
01214
01215 INT16
01216 CG_DEP_Oper_Latency(TOP pred_oper, TOP succ_oper, CG_DEP_KIND kind, UINT8 opnd)
01217 {
01218
01219
01220 INT i;
01221 for (i = 0; i < sizeof(dep_info_data) / sizeof(dep_info_data[0]); i++) {
01222 CG_DEP_KIND kind = dep_info_data[i].kind;
01223 dep_info[kind] = dep_info_data + i;
01224 }
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240 INT16 cyc_pred, cyc_succ, latency;
01241
01242
01243 cyc_pred = get_cycle(pred_oper, DEP_INFO_tail(kind), opnd);
01244
01245
01246 cyc_succ = get_cycle(succ_oper, DEP_INFO_head(kind), opnd);
01247
01248 latency = (cyc_pred - cyc_succ) + DEP_INFO_adjust(kind);
01249
01250
01251 if (latency < 0 &&
01252 (kind == CG_DEP_REGIN || kind == CG_DEP_REGOUT ||
01253 kind == CG_DEP_REGANTI || kind == CG_DEP_MEMIN ||
01254 kind == CG_DEP_SPILLIN || kind == CG_DEP_MEMOUT ||
01255 kind == CG_DEP_MEMANTI || kind == CG_DEP_MEMVOL))
01256 latency = 0;
01257
01258 return latency;
01259 }
01260
01261
01262
01263
01264
01265
01266 INT16
01267 CG_DEP_Latency(OP *pred, OP *succ, CG_DEP_KIND kind, UINT8 opnd)
01268 {
01269 TOP popcode = OP_code(pred);
01270 TOP sopcode = OP_code(succ);
01271 INT16 latency = CG_DEP_Oper_Latency(popcode, sopcode, kind, opnd);
01272
01273 if (OP_load(pred) && kind == CG_DEP_REGIN) {
01274 INT32 ld_latency_adjust = 0;
01275 WN *wn, *pf_wn;
01276 PF_POINTER *pf_ptr;
01277 UINT32 confidence;
01278
01279 if (CGTARG_Use_Load_Latency(pred, OP_opnd(succ, opnd))) {
01280
01281 if ( ( wn = Get_WN_From_Memory_OP( pred ) )
01282 && ( pf_ptr = (PF_POINTER *) WN_MAP_Get(WN_MAP_PREFETCH,wn) ) ) {
01283
01284 if ( ( pf_wn = PF_PTR_wn_pref_1L(pf_ptr) )
01285 && ( (confidence = WN_pf_confidence( pf_wn )) != 1 )
01286 && ( ! Prefetch_Kind_Enabled( pf_wn ) ) ) {
01287
01288 if ( confidence )
01289 ld_latency_adjust = MAX(ld_latency_adjust, CG_L1_ld_latency);
01290 else
01291 ld_latency_adjust = MAX(ld_latency_adjust, CG_z_conf_L1_ld_latency);
01292 }
01293
01294 if (pf_wn = PF_PTR_wn_pref_2L(pf_ptr)) {
01295
01296
01297
01298
01299 ld_latency_adjust = 0;
01300
01301 if ( (confidence = WN_pf_confidence( pf_wn )) != 1
01302 && ( ! Prefetch_Kind_Enabled( pf_wn ))) {
01303
01304 if ( confidence )
01305 ld_latency_adjust = MAX(ld_latency_adjust, CG_L2_ld_latency);
01306 else
01307 ld_latency_adjust = MAX(ld_latency_adjust, CG_z_conf_L2_ld_latency);
01308 }
01309 }
01310 }
01311 #ifdef TARG_IA64
01312
01313 if (Cache_L2_Has_Data(pred)) {
01314 ld_latency_adjust = Cache_Read_Cycle(CACHE_L2) - Cache_Read_Cycle(CACHE_L1D);
01315 }
01316 #endif
01317 ld_latency_adjust = MAX(ld_latency_adjust, CG_ld_latency);
01318
01319 latency += ld_latency_adjust;
01320
01321 }
01322 }
01323
01324
01325
01326 CGTARG_Adjust_Latency(pred, succ, kind, opnd, &latency);
01327
01328 return latency;
01329 }
01330
01331
01332
01333
01334
01335
01336 void
01337 CG_DEP_Trace_Arc(ARC *arc, BOOL is_succ, BOOL verbose)
01338 {
01339 UINT16 pred_id = ARC_pred_idx(arc);
01340 UINT16 succ_id = ARC_succ_idx(arc);
01341 CG_DEP_KIND kind = ARC_kind(arc);
01342
01343 OP *pred_op = ARC_pred(arc);
01344 OP *succ_op = ARC_succ(arc);
01345 if (verbose) {
01346
01347 fprintf (TFile, "<arc>%4d >>> ", pred_id);
01348 Print_OP_No_SrcLine(pred_op);
01349 }
01350
01351 fprintf(TFile, "<arc> %c %-10s%4d", verbose ? ' ' : is_succ ? 's' : 'p',
01352 DEP_INFO_name(kind), pred_id);
01353
01354 if (kind == CG_DEP_REGIN || kind == CG_DEP_REGOUT)
01355 fprintf(TFile, "(res) (BB:%d) ", BB_id(OP_bb(pred_op)));
01356 else if (kind == CG_DEP_REGANTI)
01357 fprintf(TFile, "(opd%d) (BB:%d) ", ARC_opnd(arc), BB_id(OP_bb(pred_op)));
01358 else fprintf(TFile, " (BB:%d) ", BB_id(OP_bb(pred_op)));
01359 fprintf(TFile, " ->%4d", succ_id);
01360
01361 if (kind == CG_DEP_REGANTI || kind == CG_DEP_REGOUT)
01362 fprintf(TFile, "(res) (BB:%d) ", BB_id(OP_bb(succ_op)));
01363 else if (kind == CG_DEP_REGIN)
01364 fprintf(TFile, "(opd%d) (BB:%d) ", ARC_opnd(arc), BB_id(OP_bb(succ_op)));
01365 else fprintf(TFile, " (BB:%d) ", BB_id(OP_bb(succ_op)));
01366
01367 fprintf(TFile, " latency%3d omega%3d",
01368 ARC_latency(arc), ARC_omega(arc));
01369 if (ARC_is_mem(arc) && ARC_is_definite(arc))
01370 fprintf(TFile, " definite");
01371 #ifdef TARG_IA64
01372 if (ARC_is_dotted(arc))
01373 fprintf(TFile, " dotted");
01374 #endif
01375 fprintf(TFile, "\n");
01376
01377 if (verbose) {
01378
01379 fprintf(TFile, "<arc>%4d >>> ", succ_id);
01380 Print_OP_No_SrcLine(succ_op);
01381 }
01382 }
01383
01384 void
01385 CG_DEP_Trace_Op_SCC_Arcs(OP *op)
01386 {
01387 ARC_LIST *arcs;
01388 if (!Is_CG_LOOP_Op(op)) {
01389 fprintf(TFile, "<arc> No SCC arcs - not a loop OP\n");
01390 } else {
01391 if (_CG_DEP_op_info(op) == NULL) {
01392 fprintf(TFile, "<arc> CG_DEP INFO is NULL\n");
01393 } else {
01394 for (arcs = OP_scc_ancestors(op); arcs; arcs = ARC_LIST_rest(arcs))
01395 CG_DEP_Trace_Arc(ARC_LIST_first(arcs), FALSE, FALSE);
01396 }
01397 }
01398 fprintf(TFile, "<arc> %3d >>> ", OP_map_idx(op));
01399 Print_OP_No_SrcLine(op);
01400 if (Is_CG_LOOP_Op(op) && _CG_DEP_op_info(op)) {
01401 for (arcs = OP_scc_descendents(op); arcs; arcs = ARC_LIST_rest(arcs))
01402 CG_DEP_Trace_Arc(ARC_LIST_first(arcs), TRUE, FALSE);
01403 }
01404 }
01405
01406 void
01407 CG_DEP_Trace_Op_Arcs(OP *op)
01408 {
01409 ARC_LIST *arcs;
01410 if (_CG_DEP_op_info(op) == NULL) {
01411 fprintf(TFile, "<arc> CG_DEP INFO is NULL\n");
01412 } else {
01413 for (arcs = OP_preds(op); arcs; arcs = ARC_LIST_rest(arcs))
01414 CG_DEP_Trace_Arc(ARC_LIST_first(arcs), FALSE, FALSE);
01415 }
01416 fprintf(TFile, "<arc> %3d >>> ", OP_map_idx(op));
01417 Print_OP_No_SrcLine(op);
01418 if (_CG_DEP_op_info(op)) {
01419 for (arcs = OP_succs(op); arcs; arcs = ARC_LIST_rest(arcs))
01420 CG_DEP_Trace_Arc(ARC_LIST_first(arcs), TRUE, FALSE);
01421 }
01422 }
01423
01424 void
01425 CG_DEP_Trace_Graph(BB *bb)
01426 {
01427 OP *op;
01428
01429 if (bb == NULL) {
01430 fprintf(TFile, "CG_DEP_Trace_Graph: no dep graph instantiated\n");
01431 return;
01432 }
01433
01434 op = BB_first_op(bb);
01435 fprintf(TFile,
01436 "%sCG %s dependence graph for BB:%d (line %d)\n"
01437 " current phase: %s\n"
01438 " %s dependences due to register assignments\n%s",
01439 DBar,
01440 cyclic ? "cyclic" : "non-cyclic",
01441 BB_id(bb),
01442 op ? Srcpos_To_Line(OP_srcpos(op)) : 0,
01443 Get_Error_Phase(),
01444 include_assigned_registers ? "includes" : "does not include",
01445 DBar);
01446
01447 if (Get_Trace(TP_CG, 2)) {
01448 Print_OPs_No_SrcLines(op);
01449 }
01450
01451 FOR_ALL_BB_OPs(bb, op) {
01452 fprintf (TFile, "\n");
01453 CG_DEP_Trace_Op_Arcs(op);
01454 }
01455 fprintf(TFile, "%s\n", DBar);
01456 }
01457
01458 void
01459 CG_DEP_Trace_HB_Graph(std::list<BB*> bblist)
01460 {
01461
01462 if (bblist.empty()) {
01463 fprintf(TFile, "CG_DEP_Trace_HB_Graph: no dep graph instantiated\n");
01464 return;
01465 }
01466
01467 std::list<BB*>::iterator bbi;
01468 FOR_ALL_BB_STLLIST_ITEMS_FWD(bblist, bbi) {
01469 CG_DEP_Trace_Graph(*bbi);
01470 }
01471
01472 fprintf(TFile, "%s\n", DBar);
01473 }
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508 static TN_MAP defop_by_tn;
01509 OP_LIST *defop_by_reg[ISA_REGISTER_CLASS_MAX+1][REGISTER_MAX+1];
01510
01511
01512 inline void defop_init(void)
01513 {
01514 defop_by_tn = TN_MAP_Create();
01515 bzero(defop_by_reg, sizeof(defop_by_reg));
01516 }
01517
01518
01519
01520
01521
01522
01523 inline REGISTER defop_get_reg_for_tn(TN *tn)
01524 {
01525 return TN_is_dedicated(tn) || include_assigned_registers ?
01526 TN_register(tn) : REGISTER_UNDEFINED;
01527 }
01528
01529
01530 inline void defop_set(OP *op)
01531 {
01532 INT i;
01533 for (i = 0; i < OP_results(op); ++i) {
01534 TN *result_tn = OP_result(op,i);
01535 REGISTER reg = defop_get_reg_for_tn(result_tn);
01536 if (reg != REGISTER_UNDEFINED) {
01537 defop_by_reg[TN_register_class(result_tn)][reg] =
01538 OP_LIST_Push(op, defop_by_reg[TN_register_class(result_tn)][reg],
01539 &MEM_pu_pool);
01540 }
01541 CG_DEP_Add_Def(op, i, defop_by_tn, &MEM_pu_pool);
01542 }
01543 #if defined(TARG_SL)
01544 TN_LIST * extra_results = op->extra_result;
01545 while( extra_results ) {
01546 TN *result_tn = TN_LIST_first( extra_results );
01547 REGISTER reg = defop_get_reg_for_tn(result_tn);
01548 if (reg != REGISTER_UNDEFINED) {
01549 defop_by_reg[TN_register_class(result_tn)][reg] =
01550 OP_LIST_Push(op, defop_by_reg[TN_register_class(result_tn)][reg],
01551 &MEM_pu_pool);
01552 }
01553 CG_DEP_Add_Def_By_TN(op, result_tn, defop_by_tn, &MEM_pu_pool);
01554 extra_results = TN_LIST_rest( extra_results );
01555 }
01556 #endif
01557 }
01558
01559
01560 inline OP_LIST* defop_for_tn(TN *tn)
01561 {
01562 return TN_is_register(tn) ? (OP_LIST *)CG_DEP_Get_Defs(tn, defop_by_tn) : NULL;
01563 }
01564
01565
01566 inline OP_LIST* defop_for_op(OP *op, UINT8 res, BOOL is_result)
01567 {
01568 TN *tn = is_result ? OP_result(op, res) : OP_opnd(op, res);
01569 if (is_result || TN_is_register(tn)) {
01570 if (TN_is_true_pred(tn)) {
01571 return NULL;
01572 } else {
01573 REGISTER reg = defop_get_reg_for_tn (tn);
01574 return (reg != REGISTER_UNDEFINED) ?
01575 defop_by_reg[TN_register_class(tn)][reg] :
01576 (OP_LIST *)CG_DEP_Get_Defs(tn, defop_by_tn);
01577 }
01578 } else {
01579 return NULL;
01580 }
01581 }
01582
01583
01584 inline void defop_finish(void)
01585 {
01586 TN_MAP_Delete(defop_by_tn);
01587 defop_by_tn = NULL;
01588 }
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598 typedef enum { DISTINCT, IDENTICAL, OVERLAPPING, DONT_KNOW } SAME_ADDR_RESULT;
01599
01600
01601 static UINT16 num_mem_ops;
01602 static OP **mem_ops;
01603
01604 static OP **xfer_ops;
01605 static INT32 **mem_op_lat_0;
01606 #define NO_DEP INT32_MIN
01607
01608
01609
01610
01611 static void make_prefetch_arcs(OP *op, BB *bb)
01612
01613
01614
01615
01616 {
01617 if ( !CG_enable_prefetch ) return;
01618 if ( !cyclic) return;
01619 if ( !OP_store(op) && !OP_load(op)) return;
01620
01621 WN *memwn = Get_WN_From_Memory_OP(op);
01622 PF_POINTER *pf_ptr = memwn ? (PF_POINTER *) WN_MAP_Get(WN_MAP_PREFETCH,memwn) : NULL;
01623 if ( !pf_ptr) return;
01624
01625 OP *pref_op;
01626 FOR_ALL_BB_OPs(bb, pref_op) {
01627
01628 if (OP_prefetch(pref_op)) {
01629 WN *prefwn = Get_WN_From_Memory_OP(pref_op);
01630 PF_POINTER *pf_ptr2 = prefwn ? (PF_POINTER *) WN_MAP_Get(WN_MAP_PREFETCH,prefwn) : NULL;
01631
01632 if (pf_ptr2 == pf_ptr) {
01633 ARC *pref_arc;
01634 CG_DEP_KIND kind = OP_store(op) ? CG_DEP_PREFOUT : CG_DEP_PREFIN;
01635 pref_arc = new_arc(kind, pref_op, op, 0, 0, TRUE);
01636
01637 INT pf_lat = (WN_pf_stride_2L(prefwn) != 0) ? CG_L2_pf_latency : CG_L1_pf_latency;
01638 Set_ARC_latency(pref_arc, pf_lat);
01639 }
01640 }
01641 }
01642 }
01643
01644 inline UINT8 addr_omega(OP *memop, UINT8 n)
01645
01646
01647
01648
01649
01650
01651 {
01652 Is_True(OP_Load(memop) || OP_store(memop), ("not a load or store"));
01653 return Is_CG_LOOP_Op(memop) ? OP_omega(memop, n) : 0;
01654 }
01655
01656 inline BOOL addr_invariant_in_loop(OP *memop)
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666 {
01667 INT opnd_base = OP_find_opnd_use( memop, OU_base );
01668 #ifdef TARG_X8664
01669 INT opnd_offset = OP_find_opnd_use( memop, OU_index );
01670 #else
01671 INT opnd_offset = OP_find_opnd_use( memop, OU_offset );
01672 #endif
01673 ARC_LIST *arcs = ARC_LIST_Find( OP_preds( memop ), CG_DEP_REGIN, DONT_CARE );
01674 while ( arcs != NULL ) {
01675 INT opnd = ARC_opnd( ARC_LIST_first( arcs ) );
01676 if ( opnd == opnd_base || opnd == opnd_offset )
01677 return FALSE;
01678 arcs = ARC_LIST_Find( ARC_LIST_rest( arcs ), CG_DEP_REGIN, DONT_CARE );
01679 }
01680 return TRUE;
01681 }
01682
01683
01684
01685
01686
01687
01688
01689 static OP *addr_base_offset(OP *op, ST **initial_sym, ST **sym, TN **base_tn, INT64 *offset)
01690 {
01691 TN *defop_base_tn = NULL;
01692 OP *defop;
01693 BB *bb = OP_bb(op);
01694
01695 Is_True(OP_Load(op) || OP_store(op), ("not a load or store"));
01696
01697 INT offset_num = OP_find_opnd_use (op, OU_offset);
01698 INT base_num = OP_find_opnd_use (op, OU_base);
01699 INT result_num = -1;
01700
01701 *initial_sym = NULL;
01702 *sym = NULL;
01703 *base_tn = OP_opnd(op, base_num);
01704 *offset = (offset_num < 0) ? 0 : TN_value(OP_opnd(op, offset_num));
01705 defop_base_tn = *base_tn;
01706 defop = op;
01707
01708 #ifdef TARG_X8664
01709 TN* ofst_tn = OP_opnd( op, offset_num );
01710 if( TN_is_symbol( ofst_tn ) ){
01711 *initial_sym = *sym = TN_var( ofst_tn );
01712
01713 ST* root_sym = NULL;
01714 INT64 root_offset = 0;
01715 Base_Symbol_And_Offset( *sym, &root_sym, &root_offset);
01716 if (*sym != root_sym) {
01717 *sym = root_sym;
01718 *offset += root_offset;
01719 }
01720 }
01721 #endif
01722
01723 while (defop && defop_base_tn) {
01724 TN *defop_offset_tn = NULL;
01725 defop_base_tn = NULL;
01726
01727 OP *new_defop = ARC_LIST_Find_Defining_Op(defop, base_num, CG_DEP_REGIN, base_num);
01728 #ifdef TARG_X8664
01729 if( new_defop == NULL ){
01730 break;
01731 }
01732 #endif
01733 if (new_defop == defop) {
01734 defop = NULL;
01735 } else defop = new_defop;
01736 if (defop &&
01737 (OP_bb(defop) == bb)) {
01738
01739 if (OP_iadd(defop)) {
01740
01741 result_num = 0;
01742 defop_offset_tn = OP_opnd(defop, 1);
01743 #ifdef TARG_IA64 // in pathscale-3.0 is #ifdef KEY
01744 defop_base_tn = OP_opnd(defop, 2);
01745 #else
01746 defop_base_tn = OP_opnd(defop, 0);
01747 #endif
01748 if (TN_is_constant(defop_offset_tn)) {
01749 *base_tn = defop_base_tn;
01750 #ifdef TARG_IA64
01751 base_num = 2;
01752 #else
01753 base_num = 0;
01754 #endif
01755 } else if (TN_is_constant(defop_base_tn)) {
01756 *base_tn = defop_offset_tn;
01757 defop_offset_tn = defop_base_tn;
01758 defop_base_tn = *base_tn;
01759 base_num = 1;
01760 } else {
01761 defop_base_tn = NULL;
01762 }
01763 } else if (OP_memory(defop)) {
01764 #if !defined(TARG_MIPS) && !defined(TARG_X8664)
01765 INT postinc_num = OP_find_opnd_use(defop, OU_postincr);
01766 base_num = OP_find_opnd_use (defop, OU_base);
01767 if ((postinc_num >= 0) &&
01768 TNs_Are_Equivalent(*base_tn, OP_opnd(defop, base_num))) {
01769 result_num = 1;
01770 defop_offset_tn = OP_opnd(defop, postinc_num);
01771 defop_base_tn = *base_tn;
01772 } else {
01773 defop_base_tn = NULL;
01774 }
01775 #endif
01776 } else if (OP_copy(defop)) {
01777 result_num = 0;
01778 defop_base_tn = OP_opnd(defop, OP_COPY_OPND);
01779 *base_tn = defop_base_tn;
01780 #ifdef TARG_X8664
01781 } else if( OP_code(defop) == TOP_ldc64 ){
01782 base_num = 0;
01783 *base_tn = defop_base_tn = OP_opnd(defop,base_num);
01784 if( TN_is_symbol( defop_base_tn ) ){
01785 *initial_sym = *sym = TN_var( defop_base_tn );
01786 *offset += TN_offset( defop_base_tn );
01787
01788 ST* root_sym = NULL;
01789 INT64 root_offset = 0;
01790 Base_Symbol_And_Offset( *sym, &root_sym, &root_offset );
01791 if( *sym != root_sym ){
01792 *sym = root_sym;
01793 *offset += root_offset;
01794 }
01795
01796 } else if( TN_has_value( defop_base_tn ) ){
01797 *offset += TN_value( defop_base_tn );
01798
01799 } else {
01800 FmtAssert( false, ("NYI") );
01801 }
01802 #endif
01803 } else {
01804 defop_base_tn = NULL;
01805 #ifdef TARG_X8664
01806 int base = TOP_Find_Operand_Use( OP_code(defop), OU_base );
01807 if( base >= 0 &&
01808 TOP_Find_Operand_Use( OP_code(defop), OU_index ) < 0 ){
01809 base_num = base;
01810 *base_tn = defop_base_tn = OP_opnd( defop, base );
01811 }
01812 #endif
01813 }
01814 } else {
01815 defop_base_tn = NULL;
01816 }
01817
01818 if (defop_offset_tn != NULL) {
01819 if (TN_is_symbol(defop_offset_tn)) {
01820 if (*sym != NULL) return defop;
01821 *offset += TN_offset(defop_offset_tn);
01822 *sym = TN_var(defop_offset_tn);
01823 *initial_sym = *sym;
01824 #ifndef TARG_X8664
01825 defop_base_tn = NULL;
01826 #endif
01827 ST *root_sym;
01828 INT64 root_offset;
01829 Base_Symbol_And_Offset( *sym, &root_sym, &root_offset);
01830 if (*sym != root_sym) {
01831 *sym = root_sym;
01832 *offset += root_offset;
01833 }
01834 } else if (TN_has_value(defop_offset_tn)) {
01835 *offset += TN_value(defop_offset_tn);
01836 }
01837 }
01838 }
01839
01840 return defop;
01841 }
01842
01843
01844
01845
01846
01847
01848
01849
01850 static BOOL symbolic_addr_subtract(OP *pred_op, OP *succ_op, SAME_ADDR_RESULT *res)
01851 {
01852 ST *pred_initial_sym;
01853 ST *succ_initial_sym;
01854 ST *pred_sym;
01855 ST *succ_sym;
01856 TN *pred_base;
01857 TN *succ_base;
01858 INT64 pred_offset;
01859 INT64 succ_offset;
01860
01861 OP *pred_root = addr_base_offset(pred_op, &pred_initial_sym, &pred_sym, &pred_base, &pred_offset);
01862 OP *succ_root = addr_base_offset(succ_op, &succ_initial_sym, &succ_sym, &succ_base, &succ_offset);
01863
01864 if ((pred_root != NULL) && (pred_base != NULL) &&
01865 (succ_root != NULL) && (succ_base != NULL)) {
01866 if ((pred_sym != NULL) && (succ_sym != NULL) &&
01867 (ST_sclass(pred_initial_sym) != SCLASS_UNKNOWN) && (ST_sclass(
01868 succ_initial_sym) != SCLASS_UNKNOWN)) {
01869 if ((pred_sym != succ_sym) ||
01870 (ST_sclass(pred_initial_sym) != ST_sclass(succ_initial_sym)
01871 #ifdef KEY
01872 && ST_sclass(pred_initial_sym) != SCLASS_EXTERN
01873 && ST_sclass(succ_initial_sym) != SCLASS_EXTERN
01874 #endif
01875 )) {
01876
01877 *res = DISTINCT;
01878 return TRUE;
01879 } else {
01880
01881 #ifdef TARG_X8664
01882
01883 if( pred_base != succ_base )
01884 return FALSE;
01885 #endif
01886 }
01887 } else if ((pred_root == succ_root) && (pred_base == succ_base)) {
01888
01889
01890 } else {
01891 #ifdef TARG_X8664
01892 if( pred_base != succ_base ||
01893 pred_root != pred_op ||
01894 succ_root != succ_op ){
01895 return FALSE;
01896 }
01897 #else
01898
01899 return FALSE;
01900 #endif
01901 }
01902
01903
01904 INT32 size1 = CGTARG_Mem_Ref_Bytes(pred_op);
01905 INT32 size2 = CGTARG_Mem_Ref_Bytes(succ_op);
01906 if (pred_offset == succ_offset) {
01907 *res = (size1 == size2) ? IDENTICAL : OVERLAPPING;
01908 } else if (pred_offset < succ_offset) {
01909 *res = ((pred_offset + size1) <= succ_offset) ? DISTINCT : OVERLAPPING;
01910 } else {
01911 *res = ((succ_offset + size2) <= pred_offset) ? DISTINCT : OVERLAPPING;
01912 }
01913 return TRUE;
01914 }
01915
01916 return FALSE;
01917 }
01918
01919 static BOOL addr_subtract(OP *pred_op, OP *succ_op, TN *pred_tn,
01920 TN *succ_tn, INT64 *diff)
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932 {
01933 if (pred_tn && succ_tn) {
01934 if (TN_is_constant(pred_tn) && TN_is_constant(succ_tn)) {
01935 if (TN_has_value(pred_tn) && TN_has_value(succ_tn)) {
01936 *diff = TN_value(pred_tn) - TN_value(succ_tn);
01937 return TRUE;
01938 } else if (TN_is_symbol(pred_tn) && TN_is_symbol(succ_tn) &&
01939 TN_var(pred_tn) == TN_var(succ_tn)) {
01940 *diff = TN_offset(pred_tn) - TN_offset(succ_tn);
01941 return TRUE;
01942 #ifdef TARG_X8664
01943 } else if (TN_is_symbol(pred_tn) && TN_is_symbol(succ_tn) ){
01944 ST* pred_var = TN_var(pred_tn);
01945 ST* succ_var = TN_var(succ_tn);
01946 ST* base_st = NULL;
01947 ST* base_st1 = NULL;
01948 INT64 val = 0, val1 = 0;
01949
01950 Base_Symbol_And_Offset( pred_var, &base_st, &val );
01951 Base_Symbol_And_Offset( succ_var, &base_st1, &val1 );
01952
01953 if( ( base_st == SP_Sym || base_st == FP_Sym ) &&
01954 base_st == base_st1 ){
01955 val += TN_offset(pred_tn);
01956 val1 += TN_offset(succ_tn);
01957 *diff = val - val1;
01958 return TRUE;
01959 }
01960 #endif
01961 } else if (TN_is_label(pred_tn) && TN_is_label(succ_tn) &&
01962 TN_label(pred_tn) == TN_label(succ_tn)) {
01963 *diff = TN_offset(pred_tn) - TN_offset(succ_tn);
01964 return TRUE;
01965 }
01966 }
01967 else if (pred_tn == succ_tn) {
01968 INT pi = TN_Opernum_In_OP (pred_op, pred_tn);
01969 INT si = TN_Opernum_In_OP (succ_op, succ_tn);
01970
01971 if (addr_omega(pred_op, pi) == addr_omega(succ_op, si)) {
01972 ARC *parc = ARC_LIST_Find_First(OP_preds(pred_op), CG_DEP_REGIN, pi);
01973 ARC *sarc = ARC_LIST_Find_First(OP_preds(succ_op), CG_DEP_REGIN, si);
01974 if ((!parc && !sarc) ||
01975 (parc && sarc && ARC_pred(parc) == ARC_pred(sarc))) {
01976 *diff = 0;
01977 return TRUE;
01978 }
01979 }
01980 }
01981 }
01982 return FALSE;
01983 }
01984
01985 static const char *same_addr_result_name(SAME_ADDR_RESULT res)
01986 {
01987 switch (res) {
01988 case DISTINCT:
01989 return "DISTINCT";
01990 case IDENTICAL:
01991 return "IDENTICAL";
01992 case OVERLAPPING:
01993 return "OVERLAPPING";
01994 default:
01995 return "DONT_KNOW";
01996 }
01997 }
01998
01999 inline SAME_ADDR_RESULT analyze_overlap(OP *memop1, OP *memop2, INT64 diff)
02000
02001
02002
02003
02004
02005
02006
02007 {
02008 INT32 size1 = CGTARG_Mem_Ref_Bytes(memop1);
02009 INT32 size2 = CGTARG_Mem_Ref_Bytes(memop2);
02010 if (diff == 0) {
02011 return size1 == size2 ? IDENTICAL : OVERLAPPING;
02012 } else if (diff > 0 && size2 > diff || diff < 0 && size1 > -diff) {
02013 return OVERLAPPING;
02014 } else {
02015 return DISTINCT;
02016 }
02017 }
02018
02019 BOOL
02020 CG_DEP_Mem_Ops_Offsets_Overlap(OP *memop1, OP *memop2, BOOL *identical)
02021
02022
02023
02024
02025 {
02026 Is_True(OP_memory(memop1) && OP_memory(memop2), ("not a load or store"));
02027
02028 TN *base1, *offset1;
02029 (void) OP_Base_Offset_TNs (memop1, &base1, &offset1);
02030
02031 TN *base2, *offset2;
02032 (void) OP_Base_Offset_TNs (memop2, &base2, &offset2);
02033
02034 Is_True(TNs_Are_Equivalent(base1, base2),
02035 ("Assumes that the base TNs are equivalent"));
02036
02037 if (offset1 && offset2 && TN_has_value(offset1) && TN_has_value(offset2)) {
02038 INT64 diff = TN_value(offset1) - TN_value(offset2);
02039 switch (analyze_overlap(memop1, memop2, diff)) {
02040 case IDENTICAL:
02041 if (*identical) *identical = TRUE;
02042 return TRUE;
02043 case OVERLAPPING:
02044 if (*identical) *identical = FALSE;
02045 return TRUE;
02046 case DISTINCT:
02047 return FALSE;
02048 }
02049 }
02050
02051 if (identical) *identical = FALSE;
02052 return TRUE;
02053 }
02054
02055 #if defined(TARG_SL)
02056
02057
02058
02059
02060 static inline bool C2_LDST_Sbuf(OP *op)
02061 {
02062 switch (OP_code(op)) {
02063 case TOP_c2_ldi_s_h_u:
02064 case TOP_c2_ldi_s_h:
02065 case TOP_c2_ldi_s_w:
02066 case TOP_c2_ldi_c:
02067
02068 case TOP_c2_sti_c:
02069 case TOP_c2_sti_s_h:
02070 case TOP_c2_sti_s_w:
02071 return true;
02072 break;
02073 default:
02074 return false;
02075 break;
02076 }
02077 return false;
02078 }
02079
02080 static inline bool C2_LDST_Vbuf(OP *op)
02081 {
02082 switch (OP_code(op)) {
02083 case TOP_c2_ldi_v2g_b_u:
02084 case TOP_c2_ldi_v2g_b:
02085 case TOP_c2_ldi_v2g_h_u:
02086 case TOP_c2_ldi_v2g_h:
02087 case TOP_c2_ldi_v2g_w:
02088 case TOP_c2_ldi_v_b_u:
02089 case TOP_c2_ldi_v_b:
02090 case TOP_c2_ldi_v_h:
02091 case TOP_c2_ldi_v_w:
02092 case TOP_c2_ldi_v_m_b_u:
02093 case TOP_c2_ldi_v_m_b:
02094 case TOP_c2_ldi_v_m_h:
02095 case TOP_c2_ldi_v_m_w:
02096
02097 case TOP_c2_sti_v_b:
02098 case TOP_c2_sti_v_h:
02099 case TOP_c2_sti_v_w:
02100 case TOP_c2_sti_v_m_b:
02101 case TOP_c2_sti_v_m_h:
02102 case TOP_c2_sti_v_m_w:
02103 case TOP_c2_sti_g2v_b:
02104 case TOP_c2_sti_g2v_h:
02105 case TOP_c2_sti_g2v_w:
02106 return true;
02107 break;
02108 default:
02109 return false;
02110 break;
02111 }
02112 return false;
02113 }
02114
02115 #endif
02116
02117 static SAME_ADDR_RESULT CG_DEP_Address_Analyze(OP *pred_op, OP *succ_op)
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138 {
02139 SAME_ADDR_RESULT res = DONT_KNOW;
02140 INT64 diff0, diff1;
02141
02142 #if defined (TARG_SL)
02143 if (CG_ignore_mem_alias)
02144 return DONT_KNOW;
02145 #endif
02146
02147 #ifndef TARG_X8664
02148
02149
02150
02151
02152 if (OP_unalign_mem(pred_op) || OP_unalign_mem(succ_op))
02153 return DONT_KNOW;
02154 #endif // !TARG_X8664
02155
02156 #ifdef TARG_X8664
02157
02158
02159 if( ( OP_code(pred_op) == OP_code(succ_op) ) &&
02160 OP_load_exe(pred_op) &&
02161 OP_fmul(pred_op) ){
02162 return DONT_KNOW;
02163 }
02164
02165
02166
02167 const TOP pred_top = OP_code(pred_op);
02168 const TOP succ_top = OP_code(succ_op);
02169 const int pred_index = TOP_Find_Operand_Use( pred_top, OU_index );
02170 const int succ_index = TOP_Find_Operand_Use( succ_top, OU_index );
02171
02172 if( ( pred_index >= 0 && succ_index < 0 ) ||
02173 ( pred_index < 0 && succ_index >= 0 ) )
02174 return DONT_KNOW;
02175
02176 if( pred_index >= 0 ){
02177 TN* pred_index_tn = OP_opnd( pred_op, pred_index );
02178 TN* succ_index_tn = OP_opnd( succ_op, succ_index );
02179 if( pred_index_tn != succ_index_tn )
02180 return DONT_KNOW;
02181
02182 TN* pred_scale = OP_opnd( pred_op, TOP_Find_Operand_Use( pred_top, OU_index ) );
02183 TN* succ_scale = OP_opnd( succ_op, TOP_Find_Operand_Use( succ_top, OU_index ) );
02184 if( TN_value( pred_scale ) != TN_value( succ_scale ) )
02185 return DONT_KNOW;
02186 }
02187 #endif // TARG_X8664
02188
02189 if (symbolic_addr_subtract(pred_op, succ_op, &res)) {
02190 return res;
02191 }
02192
02193 TN *pred_base, *pred_offset;
02194 (void) OP_Base_Offset_TNs (pred_op, &pred_base, &pred_offset);
02195
02196 TN *succ_base, *succ_offset;
02197 (void) OP_Base_Offset_TNs (succ_op, &succ_base, &succ_offset);
02198
02199 diff0 = 0;
02200
02201 if( pred_base && succ_base ) {
02202 if (addr_subtract(pred_op, succ_op, pred_base, succ_base, &diff0) &&
02203 addr_subtract(pred_op, succ_op, pred_offset, succ_offset, &diff1)) {
02204 return analyze_overlap(pred_op, succ_op, diff0 + diff1);
02205 #ifdef TARG_IA64
02206 } else {
02207
02208
02209 if (pred_base == succ_base && pred_offset == succ_offset) {
02210 if (CGTARG_Mem_Ref_Bytes (pred_op) == CGTARG_Mem_Ref_Bytes (succ_op)) {
02211 return IDENTICAL;
02212 } else {
02213 return OVERLAPPING ;
02214 }
02215 }
02216 #endif
02217 }
02218 }
02219
02220 return DONT_KNOW;
02221 }
02222
02223 inline BOOL under_same_cond_tn(OP *pred_op, OP *succ_op, UINT8 omega)
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237 {
02238 #ifdef TARG_X8664 // merged from pathscale-3.0
02239 #ifdef KEY
02240
02241
02242 if (omega >= 1 && OP_store(pred_op) && OP_store(succ_op))
02243 return FALSE;
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254 if (omega >= 1 && OP_store(pred_op) && OP_load(succ_op)) {
02255 BOOL not_predicated = TRUE;
02256 ARC_LIST *arcs = OP_preds(pred_op);
02257 while (arcs) {
02258 ARC *arc = ARC_LIST_first(arcs);
02259 arcs = ARC_LIST_rest(arcs);
02260 if ( ARC_kind(arc) == CG_DEP_REGIN &&
02261 OP_cond_def(ARC_pred(arc))) {
02262 not_predicated = FALSE;
02263 break;
02264 }
02265 }
02266 if (!not_predicated)
02267 return FALSE;
02268 }
02269 #endif
02270 #endif // TARG_X8664
02271
02272 TN *pred_guard, *succ_guard;
02273 UINT8 pred_guard_omega, succ_guard_omega;
02274 BOOL pred_invguard, succ_invguard;
02275
02276 Get_Memory_OP_Predicate_Info(pred_op, &pred_guard, &pred_guard_omega,
02277 &pred_invguard);
02278 Get_Memory_OP_Predicate_Info(succ_op, &succ_guard, &succ_guard_omega,
02279 &succ_invguard);
02280
02281 return omega ? !pred_guard && !succ_guard :
02282 pred_guard == succ_guard && pred_invguard == succ_invguard &&
02283 pred_guard_omega == succ_guard_omega;
02284 }
02285
02286 static void report_bad_mem_dep(BOOL result, BOOL definite,
02287 OP *pred_op, OP *succ_op,
02288 SAME_ADDR_RESULT same_addr_res,
02289 const char *result_src,
02290 BOOL new_result, BOOL new_definite)
02291
02292
02293
02294
02295
02296
02297 {
02298 static BOOL last_result;
02299 static BOOL last_definite;
02300 static SAME_ADDR_RESULT last_same_addr_res;
02301 static const char *last_result_src;
02302 static BOOL last_new_result;
02303 static BOOL last_new_definite;
02304 static UINT64 repeat_count;
02305
02306 WN *pred_wn;
02307 WN *succ_wn;
02308 char pbuf[512], sbuf[512];
02309
02310 if (pred_op == NULL && succ_op == NULL) {
02311
02312 if (repeat_count > 2)
02313 DevWarn("verify_mem: last warning reoccurred %lld times "
02314 "(possibly for different OPs/BBs)", repeat_count);
02315 repeat_count = 0;
02316 return;
02317 }
02318
02319 if (repeat_count > 0 &&
02320 result == last_result && same_addr_res == last_same_addr_res &&
02321 definite == last_definite && last_result_src == result_src &&
02322 new_result == last_new_result && new_definite == last_new_definite) {
02323 ++repeat_count;
02324 return;
02325 } else {
02326 if (repeat_count > 2)
02327 DevWarn("verify_mem: last warning reoccurred %lld times", repeat_count);
02328 last_result = result;
02329 last_same_addr_res = same_addr_res;
02330 last_result_src = result_src;
02331 last_definite = definite;
02332 last_new_result = new_result;
02333 last_new_definite = new_definite;
02334 repeat_count = 1;
02335 }
02336
02337 pred_wn = OP_hoisted(pred_op) ? NULL : Get_WN_From_Memory_OP(pred_op);
02338 succ_wn = OP_hoisted(succ_op) ? NULL : Get_WN_From_Memory_OP(succ_op);
02339 pbuf[0] = sbuf[0] = '\0';
02340 #ifdef Is_True_On
02341 if (pred_wn && Alias_Manager) Print_alias_info(pbuf, Alias_Manager, pred_wn);
02342 if (succ_wn && Alias_Manager) Print_alias_info(sbuf, Alias_Manager, succ_wn);
02343 #endif
02344 DevWarn("verify_mem: CG addr analysis says %s but %s says %s ALIASED "
02345 "for OPs %d (WN=0x%p%s%s) and %d (WN=0x%p%s%s) "
02346 "in BB:%d (assuming %s ALIASED)",
02347 same_addr_result_name(same_addr_res), result_src,
02348 result ? (definite ? "DEFINITELY" : "POSSIBLY") : "NOT",
02349 OP_map_idx(pred_op), pred_wn, pbuf[0] ? " " : "", pbuf,
02350 OP_map_idx(succ_op), succ_wn, sbuf[0] ? " " : "", sbuf,
02351 BB_id(OP_bb(pred_op)),
02352 new_result ? (new_definite ? "DEFINITELY" : "POSSIBLY") : "NOT");
02353 if (tracing) {
02354 fprintf(TFile," ");Print_OP_No_SrcLine(pred_op);
02355 fprintf(TFile," ");Print_OP_No_SrcLine(succ_op);
02356 }
02357
02358 }
02359
02360 static BOOL verify_mem(BOOL result,
02361 BOOL *definite,
02362 UINT8 *omega,
02363 OP *pred_op,
02364 OP *succ_op,
02365 SAME_ADDR_RESULT same_addr_res,
02366 const char *result_src)
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385 {
02386
02387 if (!*definite && OP_load(pred_op) && OP_load(succ_op)) return FALSE;
02388
02389 #ifdef TARG_X8664
02390
02391
02392 if( !*definite && OP_load_exe(pred_op) && OP_load_exe(succ_op) ){
02393 if( !OP_fmul(pred_op) ||
02394 !OP_fmul(succ_op) )
02395 return FALSE;
02396 }
02397 #endif
02398
02399 if (!CG_DEP_Verify_Mem_Deps || !CG_DEP_Addr_Analysis) return result;
02400
02401 if (!result &&
02402 (same_addr_res == IDENTICAL &&
02403 under_same_cond_tn(pred_op, succ_op, omega ? *omega : 0) ||
02404 same_addr_res == OVERLAPPING)) {
02405 *definite = same_addr_res == IDENTICAL;
02406
02407
02408
02409
02410 if (!OP_load(pred_op) || !OP_load(succ_op))
02411 report_bad_mem_dep(result, FALSE, pred_op, succ_op, same_addr_res,
02412 result_src, TRUE, *definite);
02413 return TRUE;
02414 }
02415
02416 if (result) {
02417 if (*definite) {
02418 if (same_addr_res == DISTINCT) {
02419 report_bad_mem_dep(result, *definite, pred_op, succ_op, same_addr_res,
02420 result_src, FALSE, FALSE);
02421 return FALSE;
02422 } else if (same_addr_res == OVERLAPPING) {
02423 report_bad_mem_dep(result, *definite, pred_op, succ_op, same_addr_res,
02424 result_src, TRUE, FALSE);
02425 *definite = FALSE;
02426 return TRUE;
02427 }
02428 } else {
02429
02430
02431
02432
02433
02434 switch (same_addr_res) {
02435 case DISTINCT:
02436 return FALSE;
02437 case IDENTICAL:
02438 *definite = TRUE;
02439 return TRUE;
02440 case OVERLAPPING:
02441 return TRUE;
02442 }
02443 }
02444 }
02445
02446 return result;
02447 }
02448
02449
02450 #if defined(TARG_SL)
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461 static INT32 Real_Memory_WN( OP *op, WN *input, WN **real_mems )
02462 {
02463 real_mems[0] = NULL;
02464 real_mems[1] = NULL;
02465
02466
02467
02468 if( !input )
02469 return 0;
02470
02471 TOP opcode = OP_code(op);
02472 if(!(OP_c2_load(op) || OP_c2_store(op) ||
02473 OP_c3_load(op) || OP_c3_store(op))) {
02474 real_mems[0] = input;
02475 real_mems[1] = NULL;
02476 return 1;
02477 }
02478
02479 INT32 kids = WN_kid_count(input);
02480 INT32 id = 0;
02481 INT32 num = 0;
02482 for( ; id < kids; id++ ){
02483 WN *kid = WN_kid(input,id);
02484 OPERATOR kid_opr = WN_operator(kid);
02485 if( kid_opr == OPR_PARM ){
02486 if( WN_Parm_Dereference(kid) )
02487 real_mems[num++] = kid;
02488 }
02489 }
02490
02491 Is_True( (num<=2), ("more than two load addr in an intrinsic") );
02492
02493 if( num==0 ){
02494 real_mems[0] = input;
02495 real_mems[1] = NULL;
02496 return 1;
02497 }
02498
02499 return num;
02500 }
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510 static void Aliased_By_WOPT( WN *pred_wn, WN *succ_wn,
02511 OP *pred_op, OP *succ_op,
02512 SAME_ADDR_RESULT cg_result,
02513 UINT8 *omega,
02514 const char *info_src,
02515 BOOL *verify_mem_res ,
02516 BOOL *definite )
02517 {
02518
02519
02520
02521 if(succ_wn && OP_Alloca_Barrier(succ_op)){
02522
02523 switch (Aliased_with_region(Alias_Manager, pred_wn, succ_wn,
02524 READ_AND_WRITE)) {
02525 case SAME_LOCATION:
02526 case POSSIBLY_ALIASED:
02527 *definite = TRUE;
02528 *verify_mem_res = verify_mem(TRUE, definite, omega, pred_op, succ_op,
02529 cg_result, info_src);
02530 break;
02531 case NOT_ALIASED:
02532 *definite = FALSE;
02533 *verify_mem_res = verify_mem(FALSE, definite, omega, pred_op, succ_op,
02534 cg_result, info_src);
02535 break;
02536 default:
02537 Is_True(FALSE, ("bad return value from Aliased_with_region"));
02538 }
02539 }else{
02540 switch (Aliased(Alias_Manager, pred_wn, succ_wn, !cyclic)) {
02541 case SAME_LOCATION:
02542 *definite = TRUE;
02543 *verify_mem_res = verify_mem(TRUE, definite, omega, pred_op, succ_op,
02544 cg_result, info_src);
02545 break;
02546 case POSSIBLY_ALIASED:
02547
02548 *definite = cg_result == IDENTICAL;
02549 *verify_mem_res = verify_mem(TRUE, definite, omega, pred_op, succ_op,
02550 cg_result, info_src);
02551 break;
02552 case NOT_ALIASED:
02553 *verify_mem_res = verify_mem(FALSE, definite, omega, pred_op, succ_op,
02554 cg_result, info_src);
02555 break;
02556 default:
02557 Is_True(FALSE, ("bad return value from Aliased"));
02558 }
02559 }
02560 return;
02561 }
02562 #endif // TARG_SL
02563
02564
02565 #if !(defined(TARG_IA64) || defined(TARG_SL) || defined(TARG_MIPS))
02566 static
02567 #endif
02568 BOOL get_mem_dep(OP *pred_op, OP *succ_op, BOOL *definite, UINT8 *omega)
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580 {
02581 WN *pred_wn, *succ_wn;
02582 UINT8 pred_unrollings = 0, succ_unrollings = 0;
02583 #ifdef TARG_IA64
02584 BOOL lex_neg = (!OP_Precedes(pred_op, succ_op)) &&
02585 (OP_bb(pred_op) == OP_bb(succ_op)) ;
02586 #else
02587 BOOL lex_neg = !OP_Precedes(pred_op, succ_op);
02588 #endif
02589 SAME_ADDR_RESULT cg_result = DONT_KNOW;
02590 const char *info_src = "";
02591 UINT8 min_omega = 0;
02592 BOOL memread = OP_Load(pred_op) && OP_Load(succ_op);
02593
02594 *definite = FALSE;
02595
02596
02597
02598
02599 if (omega == NULL && lex_neg)
02600 return FALSE;
02601
02602
02603 if (OP_prefetch(pred_op) || OP_prefetch(succ_op))
02604 return FALSE;
02605
02606
02607 if (OP_no_alias(pred_op) || OP_no_alias(succ_op))
02608 return FALSE;
02609
02610 #ifdef TARG_IA64
02611
02612
02613
02614 if ((OP_load(pred_op) && CGTARG_Is_OP_Advanced_Load(pred_op)) &&
02615 (OP_store(succ_op)))
02616 return TRUE;
02617 #else
02618
02619
02620 if ((OP_load(pred_op) && CGTARG_Is_OP_Advanced_Load(pred_op)) ||
02621 (OP_load(succ_op) && CGTARG_Is_OP_Advanced_Load(succ_op)))
02622 return FALSE;
02623 #endif
02624
02625
02626
02627
02628 if ((OP_volatile(pred_op) && OP_volatile(succ_op))
02629 #ifdef KEY
02630 || (CGTARG_Is_OP_Barrier(pred_op) || CGTARG_Is_OP_Barrier(succ_op))
02631 #endif
02632 ) {
02633 *definite = FALSE;
02634 if (omega) *omega = lex_neg;
02635 return TRUE;
02636 }
02637
02638
02639
02640
02641
02642
02643 if (memread &&
02644 (!include_memread_arcs ||
02645 CGSPILL_Is_Spill_Op(pred_op) || CGSPILL_Is_Spill_Op(succ_op)))
02646 return FALSE;
02647
02648
02649
02650
02651 if (cyclic && OP_store(succ_op) && CGSPILL_Is_Spill_Op(succ_op))
02652 return FALSE;
02653
02654
02655
02656
02657 if (OP_no_ci_alias(pred_op) && OP_no_ci_alias(succ_op)) {
02658 if (OP_orig_idx(pred_op) == OP_orig_idx(succ_op) &&
02659 OP_unrolling(pred_op) != OP_unrolling(succ_op))
02660 return FALSE;
02661 }
02662
02663 #if defined(TARG_SL)
02664 BOOL pred_acc_vbuf=FALSE;
02665 BOOL succ_acc_vbuf=FALSE;
02666 if(OP_vbuf_load(pred_op)|| OP_vbuf_store(pred_op))
02667 pred_acc_vbuf=TRUE;
02668 if(OP_vbuf_load(succ_op)|| OP_vbuf_store(succ_op))
02669 succ_acc_vbuf=TRUE;
02670
02671 if((pred_acc_vbuf && (!succ_acc_vbuf)) || (succ_acc_vbuf && (!pred_acc_vbuf)))
02672 return FALSE;
02673
02674 #endif
02675
02676
02677
02678 if (CG_DEP_Addr_Analysis && !lex_neg &&
02679 (OP_Load(pred_op) || OP_store(pred_op)) &&
02680 (OP_Load(succ_op) || OP_store(succ_op))) {
02681
02682 switch (cg_result = CG_DEP_Address_Analyze(pred_op, succ_op)) {
02683 case IDENTICAL:
02684 if (omega) *omega = lex_neg;
02685 *definite = under_same_cond_tn(pred_op, succ_op, omega ? *omega : 0);
02686
02687 if (!*definite && memread) return FALSE;
02688 if (!CG_DEP_Verify_Mem_Deps) return TRUE;
02689 break;
02690 case OVERLAPPING:
02691 #ifdef TARG_IA64
02692 *definite = TRUE;
02693 #else
02694 *definite = FALSE;
02695 #endif
02696
02697 if (memread) return FALSE;
02698 if (omega) *omega = lex_neg;
02699 if (!CG_DEP_Verify_Mem_Deps) return TRUE;
02700 break;
02701
02702 case DISTINCT:
02703
02704 if (omega == NULL) {
02705 if (!CG_DEP_Verify_Mem_Deps) return FALSE;
02706 } else {
02707
02708
02709
02710
02711
02712 cg_result = DONT_KNOW;
02713 min_omega = 1;
02714 }
02715 break;
02716 }
02717 }
02718
02719
02720
02721
02722
02723 #if !defined(TARG_SL)
02724 pred_wn = OP_hoisted(pred_op) ? NULL : Get_WN_From_Memory_OP(pred_op);
02725 succ_wn = OP_hoisted(succ_op) ? NULL : Get_WN_From_Memory_OP(succ_op);
02726 #else
02727 pred_wn = Get_WN_From_Memory_OP(pred_op);
02728 succ_wn = Get_WN_From_Memory_OP(succ_op);
02729
02730
02731
02732 WN *pred_real_mem_wns[2];
02733 WN *succ_real_mem_wns[2];
02734 INT pred_real_mem_num = 0;
02735 INT succ_real_mem_num = 0;
02736 pred_real_mem_num = Real_Memory_WN(pred_op, pred_wn, pred_real_mem_wns);
02737 succ_real_mem_num = Real_Memory_WN(succ_op, succ_wn, succ_real_mem_wns);
02738
02739
02740 pred_wn = pred_real_mem_wns[0];
02741 succ_wn = succ_real_mem_wns[0];
02742 #endif
02743
02744 if (OP_unroll_bb(pred_op))
02745 pred_unrollings = BB_unrollings(OP_unroll_bb(pred_op));
02746 if (OP_unroll_bb(succ_op))
02747 succ_unrollings = BB_unrollings(OP_unroll_bb(succ_op));
02748
02749 if (pred_wn == NULL || succ_wn == NULL) {
02750 ST *pred_spill_st = CGSPILL_OP_Spill_Location(pred_op);
02751 ST *succ_spill_st = CGSPILL_OP_Spill_Location(succ_op);
02752 info_src = "CG (spill info)";
02753 if (pred_spill_st && succ_spill_st) {
02754 if (succ_spill_st == pred_spill_st) {
02755
02756
02757
02758 if ((cg_result == DISTINCT) &&
02759 (OP_load(pred_op) && OP_store(succ_op)) &&
02760 (OP_results(pred_op) == 1) &&
02761 TNs_Are_Equivalent(OP_result(pred_op,0),
02762 OP_opnd(succ_op, TOP_Find_Operand_Use(OP_code(succ_op), OU_storeval)))) {
02763
02764
02765
02766 return verify_mem(FALSE, definite, omega, pred_op, succ_op, cg_result, info_src);
02767 }
02768 *definite = TRUE;
02769 } else {
02770
02771
02772
02773 return verify_mem(FALSE, definite, omega, pred_op, succ_op, cg_result,
02774 info_src);
02775 }
02776 } else if (pred_spill_st || succ_spill_st) {
02777
02778
02779 return verify_mem(FALSE, definite, omega, pred_op, succ_op, cg_result,
02780 info_src);
02781
02782 } else {
02783
02784 #if 0
02785
02786
02787
02788
02789
02790 DevWarn("get_mem_dep: can't find WHIRL node for memory OP");
02791 #endif
02792
02793
02794
02795 *definite &= cg_result == IDENTICAL;
02796
02797 }
02798
02799 } else {
02800
02801
02802 if (pred_wn == succ_wn && succ_op != pred_op &&
02803 (pred_unrollings < 2 && succ_unrollings < 2 ||
02804 OP_orig_idx(pred_op) != OP_orig_idx(succ_op))) {
02805 info_src = "CG (shared-wn analysis)";
02806
02807
02808
02809
02810
02811 *definite = FALSE;
02812 if (omega) *omega = MAX(lex_neg, min_omega);
02813 return verify_mem(TRUE, definite, omega, pred_op, succ_op, cg_result,
02814 info_src);
02815 }
02816
02817
02818 if (!CG_DEP_Ignore_LNO && Current_Dep_Graph != NULL &&
02819 #ifdef TARG_X8664
02820
02821
02822 !TOP_is_vector_op(OP_code(pred_op)) &&
02823 !TOP_is_vector_op(OP_code(succ_op)) &&
02824 #endif
02825 OP_unroll_bb(pred_op) == OP_unroll_bb(succ_op)) {
02826 VINDEX16 v1 = Current_Dep_Graph->Get_Vertex(pred_wn);
02827 VINDEX16 v2 = Current_Dep_Graph->Get_Vertex(succ_wn);
02828 info_src = "LNO";
02829 if (v1 != 0 && v2 != 0) {
02830 EINDEX16 edge = Current_Dep_Graph->Get_Edge(v1, v2);
02831 BOOL is_must, is_distance;
02832 DIRECTION dir;
02833 INT32 dist;
02834 #ifdef TARG_X8664
02835 if( Is_Target_32bit() &&
02836 edge != 0 &&
02837 OP_memory_hi( pred_op ) != OP_memory_hi( succ_op ) ){
02838 edge = 0;
02839 }
02840 #endif
02841 if (edge) {
02842 DEP dep = Current_Dep_Graph->Dep(edge);
02843 is_distance = DEP_IsDistance(dep);
02844 dir = DEP_Direction(dep);
02845 is_must = Current_Dep_Graph->Is_Must(edge);
02846 dist = is_distance ? DEP_Distance(dep) : DEP_DistanceBound(dep);
02847 }
02848 if (!lex_neg && (edge == 0 || dist > 0)) {
02849
02850
02851
02852
02853
02854
02855
02856
02857 EINDEX16 inv_edge = Current_Dep_Graph->Get_Edge(v2, v1);
02858 if (inv_edge) {
02859 DEP inv_dep = Current_Dep_Graph->Dep(inv_edge);
02860 INT32 inv_dist = DEP_IsDistance(inv_dep) ?
02861 DEP_Distance(inv_dep) : DEP_DistanceBound(inv_dep);
02862 if (inv_dist == 0) {
02863
02864
02865
02866
02867
02868 BOOL inv_must = Current_Dep_Graph->Is_Must(inv_edge);
02869 if (edge) {
02870 DEP udep = DEP_UnionDirection(inv_dep, dir);
02871 dir = DEP_Direction(udep);
02872 is_distance &= DEP_IsDistance(inv_dep) && inv_dist == dist;
02873 is_must &= inv_must && inv_dist == dist;
02874 dist = MIN(dist, inv_dist);
02875 } else {
02876 dir = DEP_Direction(inv_dep);
02877 is_distance = DEP_IsDistance(inv_dep);
02878 is_must = inv_must;
02879 dist = inv_dist;
02880 }
02881 edge = inv_edge;
02882 }
02883 }
02884 }
02885 if (edge == 0) {
02886
02887 return verify_mem(FALSE, definite, omega, pred_op, succ_op, cg_result,
02888 info_src);
02889 } else {
02890 if (dist < 0) {
02891 DevWarn("LNO edge %d has dist of %d; ignoring", edge, dist);
02892 return verify_mem(FALSE, definite, omega, pred_op, succ_op,
02893 cg_result, info_src);
02894 }
02895 if (dir == DIR_POS && dist == 0) {
02896 DevWarn("LNO POS(+) edge %d has dist of 0; assuming 1", edge);
02897 dist = 1;
02898 }
02899 if (pred_unrollings > 1) {
02900 INT32 adjust = dist + OP_unrolling(pred_op)-OP_unrolling(succ_op);
02901 info_src = "LNO (+ CG unrolling info)";
02902 if (is_distance && adjust % (INT32)pred_unrollings != 0) {
02903 return verify_mem(FALSE, definite, omega, pred_op, succ_op,
02904 cg_result, info_src);
02905 } else {
02906 dist = adjust / (INT32)pred_unrollings;
02907 }
02908 }
02909 *definite = cg_result == IDENTICAL && *definite ||
02910 is_must && dist < MAX_OMEGA;
02911 if (lex_neg && dist == 0) {
02912
02913 if (is_distance)
02914 return verify_mem(FALSE, definite, omega, pred_op, succ_op,
02915 cg_result, info_src);
02916 dist = 1;
02917 }
02918 if (omega == NULL && dist > 0)
02919 return verify_mem(FALSE, definite, omega, pred_op, succ_op,
02920 cg_result, info_src);
02921 if (omega)
02922 *omega = MIN(MAX(dist, min_omega), MAX_OMEGA);
02923 if (*definite)
02924 *definite = under_same_cond_tn(pred_op, succ_op,
02925 omega ? *omega : 0);
02926 return verify_mem(TRUE, definite, omega, pred_op, succ_op, cg_result,
02927 info_src);
02928 }
02929 }
02930 }
02931
02932 if (pred_wn == succ_wn) {
02933
02934
02935
02936
02937
02938
02939 info_src = "CG (same-WN analysis, part II)";
02940 *definite = cg_result == IDENTICAL && *definite ||
02941 Is_CG_LOOP_Op(pred_op) && addr_invariant_in_loop(pred_op);
02942
02943 } else {
02944
02945
02946 info_src = "WOPT";
02947 if (Alias_Manager != NULL && !CG_DEP_Ignore_WOPT) {
02948 #if !defined(TARG_SL)
02949
02950
02951
02952 if (succ_wn && OP_Alloca_Barrier(succ_op)) {
02953 switch (Aliased_with_region(Alias_Manager, pred_wn, succ_wn,
02954 READ_AND_WRITE)) {
02955 case SAME_LOCATION:
02956 case POSSIBLY_ALIASED:
02957 *definite = TRUE;
02958 break;
02959 case NOT_ALIASED:
02960 *definite = FALSE;
02961 break;
02962 default:
02963 Is_True(FALSE, ("bad return value from Aliased_with_region"));
02964 }
02965 }
02966 else {
02967 BOOL ignore_loop_carried =
02968 (omega == NULL && OP_unrolling(pred_op)==OP_unrolling(succ_op));
02969 switch (Aliased(Alias_Manager, pred_wn, succ_wn, ignore_loop_carried)) {
02970 case SAME_LOCATION:
02971 *definite = TRUE;
02972 break;
02973 case POSSIBLY_ALIASED:
02974
02975 *definite = cg_result == IDENTICAL;
02976 break;
02977 case NOT_ALIASED:
02978 return verify_mem(FALSE, definite, omega, pred_op, succ_op,
02979 cg_result, info_src);
02980 default:
02981 Is_True(FALSE, ("bad return value from Aliased"));
02982 }
02983
02984 if (omega &&
02985 OP_unrolling(pred_op)==OP_unrolling(succ_op) &&
02986 min_omega <= 0 &&
02987 Aliased(Alias_Manager, pred_wn, succ_wn, TRUE) == NOT_ALIASED) {
02988
02989
02990
02991
02992 min_omega = 1;
02993 }
02994 }
02995 #else
02996 BOOL definite_1 = FALSE, definite_2 = FALSE,
02997 definite_3 = FALSE, definite_4 = FALSE;
02998 BOOL ret_1 = FALSE, ret_2 = FALSE, ret_3 = FALSE, ret_4 = FALSE;
02999 BOOL res_1 = FALSE, res_2 = FALSE, res_3 = FALSE, res_4 = FALSE;
03000 Aliased_By_WOPT( pred_real_mem_wns[0],
03001 succ_real_mem_wns[0], pred_op, succ_op,
03002 cg_result, omega, info_src,
03003 &res_1, &definite_1 );
03004 if( pred_real_mem_wns[1] )
03005 Aliased_By_WOPT( pred_real_mem_wns[1],
03006 succ_real_mem_wns[0], pred_op, succ_op,
03007 cg_result, omega, info_src,
03008 &res_2, &definite_2 );
03009 if( succ_real_mem_wns[1] )
03010 Aliased_By_WOPT( pred_real_mem_wns[0],
03011 succ_real_mem_wns[1], pred_op, succ_op,
03012 cg_result, omega, info_src,
03013 &res_3, &definite_3 );
03014 if( pred_real_mem_wns[1] && succ_real_mem_wns[1] )
03015 Aliased_By_WOPT( pred_real_mem_wns[1],
03016 succ_real_mem_wns[1], pred_op, succ_op,
03017 cg_result, omega, info_src,
03018 &res_4, &definite_4 );
03019 *definite = definite_1 || definite_2 || definite_3 || definite_4;
03020 BOOL res = (res_1 || res_2 || res_3 || res_4);
03021 if (omega)
03022 *omega = MAX(lex_neg, min_omega);
03023 return res;
03024 #endif // !TARG_SL
03025 } else {
03026
03027
03028
03029
03030 *definite &= cg_result == IDENTICAL;
03031
03032 }
03033 }
03034 }
03035
03036
03037
03038
03039
03040 if (*definite &&
03041 (OP_unroll_bb(pred_op) != OP_unroll_bb(succ_op) ||
03042 pred_unrollings > 1 &&
03043 OP_unrolling(pred_op) != OP_unrolling(succ_op)) &&
03044 (!Is_CG_LOOP_Op(pred_op) || !addr_invariant_in_loop(pred_op) ||
03045 !addr_invariant_in_loop(succ_op))) {
03046
03047
03048
03049
03050
03051
03052 *definite &= cg_result == IDENTICAL;
03053 }
03054
03055
03056 if (omega) *omega = MAX(lex_neg, min_omega);
03057
03058
03059
03060
03061
03062
03063 if (*definite)
03064 *definite = under_same_cond_tn(pred_op, succ_op, omega ? *omega : 0);
03065
03066 return verify_mem(TRUE, definite, omega, pred_op, succ_op, cg_result,
03067 info_src);
03068 }
03069
03070 BOOL
03071 CG_DEP_Call_Aliases(OP *call_op, OP *op, BOOL read, BOOL write)
03072
03073
03074
03075
03076 {
03077
03078
03079 if (CG_DEP_Ignore_WOPT) return TRUE;
03080
03081 WN *call_wn = Get_WN_From_Memory_OP(call_op);
03082 WN *wn = Get_WN_From_Memory_OP(op);
03083 UINT8 i;
03084 static READ_WRITE rw[2][2] = {{NO_READ_NO_WRITE, WRITE},
03085 {READ, READ_AND_WRITE}};
03086
03087
03088 if (Alias_Manager && wn && call_wn) {
03089 BOOL alias_result =
03090 ALIAS_RESULT_positive(Aliased_with_region(Alias_Manager, wn, call_wn,
03091 rw[read][write]));
03092
03093
03094 for (i = 0; i < OP_results(op); i++) {
03095 TN *res = OP_result(op,i);
03096 if (TN_is_dedicated(res)) {
03097
03098
03099
03100
03101
03102 return TRUE;
03103 }
03104 }
03105 for (i = 0; i < OP_opnds(op); i++) {
03106 TN *opnd = OP_opnd(op, i);
03107 if (TN_is_dedicated(opnd)) {
03108
03109
03110
03111
03112
03113 return TRUE;
03114 }
03115 }
03116
03117
03118
03119 if (!alias_result) return FALSE;
03120 }
03121
03122 return TRUE;
03123 }
03124
03125 BOOL
03126 CG_DEP_Mem_Ops_Alias(OP *memop1, OP *memop2, BOOL *identical)
03127
03128
03129
03130
03131 {
03132 WN *wn1, *wn2;
03133 BB *bb1 = OP_bb(memop1), *bb2 = OP_bb(memop2);
03134 BOOL in_same_loop = BB_loop_head_bb(bb1) &&
03135 (bb1 == bb2 ||
03136 BB_loop_head_bb(bb1) == BB_loop_head_bb(bb2) &&
03137 !BB_unrolled_fully(bb1) && !BB_unrolled_fully(bb2));
03138 UINT8 unrollings1 = in_same_loop && OP_unroll_bb(memop1) ?
03139 BB_unrollings(bb1) : 0;
03140 UINT8 unrollings2 = in_same_loop && OP_unroll_bb(memop2) ?
03141 BB_unrollings(bb2) : 0;
03142
03143
03144
03145
03146 if (memop1 == memop2) {
03147 if (identical) *identical = TRUE;
03148 return TRUE;
03149 }
03150
03151
03152 if (OP_no_alias(memop1) || OP_no_alias(memop2))
03153 return FALSE;
03154
03155 wn1 = OP_hoisted(memop1) ? NULL : Get_WN_From_Memory_OP(memop1);
03156 wn2 = OP_hoisted(memop2) ? NULL : Get_WN_From_Memory_OP(memop2);
03157
03158 if (wn1 == NULL || wn2 == NULL) {
03159 ST *spill_st1 = CGSPILL_OP_Spill_Location(memop1);
03160 ST *spill_st2 = CGSPILL_OP_Spill_Location(memop2);
03161 if (spill_st1 && spill_st2) {
03162 if (spill_st2 == spill_st1) {
03163
03164
03165
03166 if (identical) *identical = TRUE;
03167 return TRUE;
03168 } else {
03169
03170
03171
03172 return FALSE;
03173 }
03174 } else if (spill_st1 || spill_st2) {
03175
03176 #ifdef KEY
03177
03178
03179 if (OP_opnd(memop1, TOP_Find_Operand_Use(OP_code(memop1), OU_offset)) ==
03180 OP_opnd(memop2, TOP_Find_Operand_Use(OP_code(memop2), OU_offset))) {
03181 if (identical) *identical = TRUE;
03182 return TRUE;
03183 }
03184 else
03185 #endif
03186 return FALSE;
03187 }
03188
03189 } else {
03190
03191
03192 if (wn1 == wn2 && memop2 != memop1 &&
03193 (unrollings1 < 2 && unrollings2 < 2 ||
03194 OP_orig_idx(memop1) != OP_orig_idx(memop2))) {
03195
03196
03197
03198
03199
03200 if (identical) *identical = FALSE;
03201 return TRUE;
03202 }
03203
03204
03205
03206
03207
03208 if (wn1 == wn2) {
03209
03210
03211
03212
03213 if (identical) *identical = FALSE;
03214 return TRUE;
03215
03216 } else {
03217
03218
03219 if (Alias_Manager != NULL && !CG_DEP_Ignore_WOPT) {
03220 switch (Aliased(Alias_Manager, wn1, wn2)) {
03221 case SAME_LOCATION:
03222 if (identical)
03223 *identical = (OP_unroll_bb(memop1) == OP_unroll_bb(memop2) &&
03224 unrollings1 < 2 ||
03225 OP_unrolling(memop1) == OP_unrolling(memop2)) &&
03226 under_same_cond_tn(memop1, memop2, 0);
03227 return TRUE;
03228 case POSSIBLY_ALIASED:
03229 if (identical) *identical = FALSE;
03230 return TRUE;
03231 case NOT_ALIASED:
03232 return FALSE;
03233 default:
03234 Is_True(FALSE, ("bad return value from Aliased"));
03235 }
03236 }
03237 }
03238 }
03239
03240
03241
03242 if (identical) *identical = FALSE;
03243 return TRUE;
03244 }
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256 BOOL
03257 CG_DEP_Can_OP_Move_Across_Call(OP *cur_op, OP *call_op, BOOL forw,
03258 BOOL Ignore_TN_Dep)
03259 {
03260 if (call_op) {
03261 BOOL in_same_bb = OP_bb(cur_op) == OP_bb(call_op);
03262
03263
03264 BOOL mov_across_call = in_same_bb &&
03265 ((forw && OP_Follows(cur_op, call_op)) ||
03266 (!forw && OP_Follows(call_op, cur_op)));
03267 if ((mov_across_call || (!mov_across_call && !in_same_bb)) &&
03268 !GCM_Motion_Across_Calls) return FALSE;
03269 }
03270
03271
03272 if (call_op) {
03273
03274
03275 if (OP_defs_fcr(cur_op) || OP_defs_fcc(cur_op) || OP_refs_fcr(cur_op))
03276 return FALSE;
03277
03278 INT i;
03279 for (i = 0; i < OP_results(cur_op); i++) {
03280 TN *result = OP_result(cur_op,i);
03281 if (Ignore_TN_Dep) {
03282 REGISTER reg = TN_register(result);
03283 #ifdef TARG_IA64
03284 if (reg == REGISTER_UNDEFINED) continue;
03285
03286 #endif
03287 ISA_REGISTER_CLASS rclass = TN_register_class (result);
03288
03289
03290 if(REGISTER_SET_MemberP(REGISTER_CLASS_function_value(rclass), reg) ||
03291 REGISTER_SET_MemberP(REGISTER_CLASS_function_argument(rclass),
03292 reg) ||
03293 REGISTER_SET_MemberP(REGISTER_CLASS_caller_saves(rclass), reg))
03294 return FALSE;
03295
03296
03297
03298
03299 #ifdef HAS_STACKED_REGISTERS
03300 if (REGISTER_Is_Stacked_Output(rclass, reg))
03301 return FALSE;
03302 #endif
03303 } else {
03304
03305
03306 if (TN_is_dedicated(result))
03307 return FALSE;
03308 }
03309 }
03310
03311 for (i = 0; i < OP_opnds(cur_op); i++) {
03312 TN *opnd_tn = OP_opnd(cur_op, i);
03313 if (TN_is_constant(opnd_tn)) continue;
03314 if (Ignore_TN_Dep) {
03315 REGISTER opnd_reg = TN_register(opnd_tn);
03316 #ifdef TARG_IA64
03317 if (opnd_reg == REGISTER_UNDEFINED) continue;
03318
03319 #endif
03320 ISA_REGISTER_CLASS opnd_cl = TN_register_class (opnd_tn);
03321
03322
03323 if(REGISTER_SET_MemberP(REGISTER_CLASS_function_value(opnd_cl),
03324 opnd_reg) ||
03325 REGISTER_SET_MemberP(REGISTER_CLASS_function_argument(opnd_cl),
03326 opnd_reg) ||
03327 REGISTER_SET_MemberP(REGISTER_CLASS_caller_saves(opnd_cl),
03328 opnd_reg))
03329 return FALSE;
03330 } else {
03331
03332
03333 if (TN_is_dedicated(opnd_tn))
03334 return FALSE;
03335 }
03336 }
03337 }
03338
03339
03340 if (call_op && CG_DEP_Call_Aliases(call_op, cur_op, TRUE, TRUE))
03341 return FALSE;
03342
03343 return TRUE;
03344 }
03345
03346 inline ARC_LIST *first_mem_arc(ARC_LIST *arcs)
03347
03348
03349
03350
03351
03352
03353 {
03354 while (arcs) {
03355 ARC *arc = ARC_LIST_first(arcs);
03356 if (ARC_is_mem(arc))
03357 return arcs;
03358 arcs = ARC_LIST_rest(arcs);
03359 }
03360 return NULL;
03361 }
03362
03363 inline ARC_LIST *first_definite_mem_arc(ARC_LIST *arcs)
03364
03365
03366
03367
03368
03369
03370 {
03371 while (arcs) {
03372 ARC *arc = ARC_LIST_first(arcs);
03373 if (ARC_is_mem(arc) && ARC_is_definite(arc))
03374 return arcs;
03375 arcs = ARC_LIST_rest(arcs);
03376 }
03377 return NULL;
03378 }
03379
03380 inline INT16 get_bb_idx(BB *bb, std::list<BB*> bb_list)
03381 {
03382 std::list<BB*>::iterator bb_iter;
03383 INT idx = -1;
03384
03385
03386 FOR_ALL_BB_STLLIST_ITEMS_FWD(bb_list, bb_iter) {
03387 ++idx;
03388 if (*bb_iter == bb) break;
03389 }
03390
03391 return idx;
03392 }
03393
03394
03395
03396
03397
03398
03399
03400 void
03401 Add_BRANCH_Arcs(BB* bb, std::list<BB*> bb_list, BOOL include_latency)
03402 {
03403
03404 INT16 pred_idx;
03405 INT16 bb_idx = get_bb_idx(bb, bb_list);
03406 OP *op, *cur_xfer_op;
03407
03408 FOR_ALL_BB_OPs(bb, op) {
03409
03410
03411 for (pred_idx = bb_idx; pred_idx < bb_list.size(); pred_idx++) {
03412 cur_xfer_op = xfer_ops[pred_idx];
03413 if (cur_xfer_op && cur_xfer_op != op) {
03414
03415
03416 if ((pred_idx == bb_list.size() - 1) ||
03417 is_xfer_depndnce_reqd(op, cur_xfer_op)) {
03418 if (include_latency) {
03419 new_arc_with_latency(CG_DEP_PREBR, op, cur_xfer_op, 0,0,0, FALSE);
03420 } else {
03421 new_arc(CG_DEP_PREBR, op, cur_xfer_op, 0, 0, FALSE);
03422 }
03423 break;
03424 }
03425
03426
03427 if (CGTARG_Dependence_Required(op, cur_xfer_op)) {
03428 if (include_latency) {
03429 new_arc_with_latency(CG_DEP_MISC, op, cur_xfer_op, 0, 0, 0, FALSE);
03430 } else {
03431 new_arc(CG_DEP_MISC, op, cur_xfer_op, 0, 0, FALSE);
03432 }
03433 break;
03434 }
03435 }
03436 }
03437
03438
03439 for (pred_idx = bb_idx - 1; pred_idx >= 0 ; pred_idx--) {
03440 cur_xfer_op = xfer_ops[pred_idx];
03441 if (cur_xfer_op) {
03442
03443 if (is_xfer_depndnce_reqd(op, cur_xfer_op)) {
03444 if (include_latency) {
03445 new_arc_with_latency(CG_DEP_POSTBR, cur_xfer_op, op, 0,0,0,FALSE);
03446 } else {
03447 new_arc(CG_DEP_POSTBR, cur_xfer_op, op, 0, 0, FALSE);
03448 }
03449 break;
03450 }
03451
03452
03453 if (CGTARG_Dependence_Required(cur_xfer_op, op)) {
03454 if (include_latency) {
03455 new_arc_with_latency(CG_DEP_MISC, cur_xfer_op, op, 0, 0, 0,FALSE);
03456 } else {
03457 new_arc(CG_DEP_MISC, cur_xfer_op, op, 0, 0, FALSE);
03458 }
03459 break;
03460 }
03461 }
03462 }
03463
03464 }
03465 }
03466
03467
03468
03469
03470
03471
03472
03473 void
03474 Add_MISC_Arcs(BB* bb)
03475 {
03476
03477 OP *op;
03478 OP *prev_op, *next_op;
03479
03480 FOR_ALL_BB_OPs(bb, op) {
03481
03482
03483 if (cyclic) {
03484 for (prev_op = BB_last_op(bb); prev_op && prev_op != op;
03485 prev_op = OP_prev(prev_op)) {
03486
03487
03488
03489
03490
03491 if (CGTARG_Dependence_Required(prev_op, op)) {
03492 new_arc_with_latency(CG_DEP_MISC, prev_op, op, 0, 1, 0, FALSE);
03493 }
03494 }
03495 }
03496
03497
03498
03499 for (next_op = OP_next(op); next_op; next_op = OP_next(next_op)) {
03500 if (CGTARG_Dependence_Required(op, next_op)) {
03501 #ifdef TARG_IA64
03502 new_arc(CG_DEP_MISC, op, next_op, 0, 0, FALSE);
03503 #else
03504 new_arc_with_latency(CG_DEP_MISC, op, next_op, 0, 0, 0, FALSE);
03505 #endif
03506 }
03507 }
03508 }
03509 }
03510
03511 inline BOOL is_closer_loop_succ(OP *pred,
03512 OP *succ1, UINT8 omega1,
03513 OP *succ2, UINT8 omega2)
03514
03515
03516
03517
03518
03519
03520 {
03521 BOOL closer = omega1 < omega2 ||
03522 omega1 == omega2 && OP_Ordering(succ1, pred) < OP_Ordering(succ2, pred);
03523
03524
03525 Is_True(OP_Follows(succ1, pred) || omega1 > 0, ("omega1 can't be 0"));
03526 Is_True(OP_Follows(succ2, pred) || omega2 > 0, ("omega2 can't be 0"));
03527
03528 return closer;
03529 }
03530
03531 inline BOOL is_closer_succ(OP *pred, OP *succ1, OP *succ2)
03532
03533
03534
03535
03536
03537
03538 {
03539 BOOL closer = is_closer_loop_succ(pred,
03540 succ1, !OP_Follows(succ1, pred),
03541 succ2, !OP_Follows(succ2, pred));
03542 return closer;
03543 }
03544
03545 inline OP *closer_succ(OP *pred, OP *succ1, OP *succ2)
03546
03547
03548
03549
03550
03551 {
03552 OP *closer = is_closer_succ(pred, succ1, succ2) ? succ1 : succ2;
03553 return closer;
03554 }
03555
03556 inline BOOL succ_arc_shorter(ARC *arc1, ARC *arc2)
03557
03558
03559
03560
03561
03562
03563
03564 {
03565 BOOL closer = is_closer_loop_succ(ARC_pred(arc1),
03566 ARC_succ(arc1), ARC_omega(arc1),
03567 ARC_succ(arc2), ARC_omega(arc2));
03568 Is_True(ARC_pred(arc1) == ARC_pred(arc2), ("arc preds not the same"));
03569 return closer;
03570 }
03571
03572 ARC *shorter_succ_arc(ARC *arc1, ARC *arc2)
03573
03574
03575
03576
03577
03578 {
03579 ARC *shorter = succ_arc_shorter(arc1, arc2) ? arc1 : arc2;
03580 return shorter;
03581 }
03582
03583 inline BOOL is_closer_loop_pred(OP *succ,
03584 OP *pred1, UINT8 omega1,
03585 OP *pred2, UINT8 omega2)
03586
03587
03588
03589
03590
03591
03592 {
03593 BOOL closer = omega1 < omega2 ||
03594 omega1 == omega2 && OP_Ordering(succ, pred1) < OP_Ordering(succ, pred2);
03595
03596
03597 Is_True(OP_Follows(succ, pred1) || omega1 > 0, ("omega1 can't be 0"));
03598 Is_True(OP_Follows(succ, pred2) || omega2 > 0, ("omega2 can't be 0"));
03599
03600 return closer;
03601 }
03602
03603 inline BOOL pred_arc_shorter(ARC *arc1, ARC *arc2)
03604
03605
03606
03607
03608
03609
03610
03611 {
03612 BOOL closer = is_closer_loop_pred(ARC_succ(arc1),
03613 ARC_pred(arc1), ARC_omega(arc1),
03614 ARC_pred(arc2), ARC_omega(arc2));
03615 Is_True(ARC_succ(arc1) == ARC_succ(arc2), ("arc succs not the same"));
03616 return closer;
03617 }
03618
03619 inline ARC *shorter_pred_arc(ARC *arc1, ARC *arc2)
03620
03621
03622
03623
03624
03625 {
03626 ARC *shorter = pred_arc_shorter(arc1, arc2) ? arc1 : arc2;
03627 return shorter;
03628 }
03629
03630 static void adjust_arc_for_rw_elim(ARC *arc, BOOL is_succ, ARC *shortest,
03631 ARC *shortest_to_from_store)
03632
03633
03634
03635
03636 {
03637 OP *pred = ARC_pred(arc);
03638 OP *succ = ARC_succ(arc);
03639 CG_DEP_KIND kind = ARC_kind(arc);
03640
03641
03642
03643
03644
03645
03646 if (kind == CG_DEP_MEMIN &&
03647 ((
03648 #ifdef KEY
03649
03650 ( OP_results(succ) > 0 ) &&
03651 #endif
03652 (TN_is_float(OP_opnd(pred, 0)) ^ TN_is_float(OP_result(succ,0 )))) ||
03653 CGTARG_Mem_Ref_Bytes(pred) != CGTARG_Mem_Ref_Bytes(succ))) {
03654
03655 Set_ARC_is_definite(arc, FALSE);
03656 } else if (kind == CG_DEP_MEMREAD &&
03657 #ifdef KEY
03658
03659 OP_results(succ) > 0 &&
03660 OP_results(pred) > 0 &&
03661 #endif
03662 ((TN_is_float(OP_result(pred,0 )) ^ TN_is_float(OP_result(succ,0 ))) ||
03663 CGTARG_Mem_Ref_Bytes(pred) != CGTARG_Mem_Ref_Bytes(succ))) {
03664
03665 detach_arc(arc);
03666 delete_arc(arc);
03667 } else if (kind == CG_DEP_MEMOUT &&
03668 CGTARG_Mem_Ref_Bytes(pred) > CGTARG_Mem_Ref_Bytes(succ)) {
03669
03670 Set_ARC_is_definite(arc, FALSE);
03671 } else
03672
03673
03674
03675 if (OP_unalign_mem(pred) || OP_unalign_mem(succ) ||
03676 kind == CG_DEP_MEMOUT && arc != shortest ||
03677 shortest_to_from_store &&
03678 (is_succ && succ_arc_shorter(shortest_to_from_store, arc) ||
03679 !is_succ && pred_arc_shorter(shortest_to_from_store, arc))) {
03680 if (kind == CG_DEP_MEMREAD) {
03681
03682 detach_arc(arc);
03683 delete_arc(arc);
03684 } else {
03685
03686 Set_ARC_is_definite(arc, FALSE);
03687 }
03688 }
03689 }
03690
03691 void adjust_for_rw_elim(ARC_LIST *arcs, UINT32 num_definite_arcs,
03692 ARC *shortest, ARC *shortest_to_from_store)
03693
03694
03695
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709
03710
03711
03712
03713
03714
03715
03716
03717
03718
03719
03720
03721
03722
03723 {
03724 BOOL are_succs = ARC_LIST_is_succ_list(arcs);
03725 while (num_definite_arcs-- > 0) {
03726 ARC *arc;
03727 arcs = first_definite_mem_arc(arcs);
03728 Is_True(arcs, ("num_definite_arcs is too high"));
03729 arc = ARC_LIST_first(arcs);
03730 arcs = ARC_LIST_rest(arcs);
03731 adjust_arc_for_rw_elim(arc, are_succs, shortest, shortest_to_from_store);
03732 }
03733 Is_True(first_definite_mem_arc(arcs) == NULL,
03734 ("num_definite_arcs is too low"));
03735 }
03736
03737 void add_mem_arcs_from(UINT16 op_idx)
03738
03739
03740
03741
03742
03743
03744
03745
03746 {
03747 OP *op = mem_ops[op_idx];
03748 UINT16 succ_idx, s, num_definite_arcs = 0;
03749 ARC *shortest = NULL, *shortest_to_store = NULL;
03750
03751 UINT16 first_poss_succ_idx = cyclic ? 0 : op_idx+1;
03752
03753 UINT16 num_poss_0_succs = num_mem_ops - op_idx - 1;
03754 BOOL found_definite_memread_succ = FALSE;
03755
03756
03757 if (mem_op_lat_0) {
03758 if (mem_op_lat_0[op_idx]) {
03759
03760 return;
03761 } else {
03762
03763
03764
03765
03766
03767 mem_op_lat_0[op_idx] = TYPE_L_ALLOC_N(INT32, num_poss_0_succs);
03768 for (s = 0; s < num_poss_0_succs; s++) mem_op_lat_0[op_idx][s] = NO_DEP;
03769 }
03770 }
03771
03772
03773
03774 for (succ_idx = first_poss_succ_idx; succ_idx < num_mem_ops; succ_idx++) {
03775 BOOL definite, have_latency = FALSE;
03776 UINT8 omega = 0;
03777 OP *succ = mem_ops[succ_idx];
03778 ARC *arc;
03779 INT16 latency;
03780 CG_DEP_KIND kind = OP_Load(op) ?
03781 (OP_Load(succ) ? CG_DEP_MEMREAD : CG_DEP_MEMANTI) :
03782 (OP_Load(succ) ? CG_DEP_MEMIN : CG_DEP_MEMOUT);
03783
03784 if (OP_volatile(succ) && OP_volatile(op)) kind = CG_DEP_MEMVOL;
03785
03786 if (kind == CG_DEP_MEMREAD && !include_memread_arcs)
03787 continue;
03788
03789 if (!cyclic && CG_DEP_Mem_Arc_Pruning >= PRUNE_NON_CYCLIC ||
03790 cyclic && omega == 0 && CG_DEP_Mem_Arc_Pruning >= PRUNE_CYCLIC_0) {
03791 if (kind == CG_DEP_MEMREAD) {
03792
03793 if (found_definite_memread_succ) continue;
03794
03795 latency = 0;
03796 } else {
03797 latency = CG_DEP_Latency(op, succ, kind, 0);
03798 }
03799 have_latency = TRUE;
03800
03801 if (latency <= mem_op_lat_0[op_idx][succ_idx-op_idx-1]) continue;
03802 }
03803
03804 if (get_mem_dep(op, succ, &definite, cyclic ? &omega : NULL)) {
03805
03806
03807
03808
03809
03810 if (!have_latency) latency =
03811 (CG_DEP_Adjust_OOO_Latency && PROC_is_out_of_order() && !definite) ?
03812 0 : CG_DEP_Latency(op, succ, kind, 0);
03813 #ifdef TARG_IA64
03814 if (omega == 0) Cache_Adjust_Latency(op,succ,kind,&latency);
03815 #endif
03816
03817 arc = new_arc_with_latency(kind, op, succ, latency, omega, 0, definite);
03818
03819 #ifdef TARG_IA64
03820
03821 if (kind == CG_DEP_MEMIN && !definite &&
03822 !CGTARG_Is_OP_Check_Load(succ) &&
03823 !OP_volatile (op) && !OP_volatile(succ) &&
03824 !OP_asm(op) && !OP_asm(succ)) {
03825 Set_ARC_is_dotted (arc, TRUE);
03826 }
03827 #else
03828
03829
03830
03831 if (!CGTARG_Is_OP_Check_Load(succ) &&
03832 kind == CG_DEP_MEMIN && !definite && !include_memin_arcs)
03833 Set_ARC_is_dotted(arc, TRUE);
03834 #endif
03835 found_definite_memread_succ |= (kind == CG_DEP_MEMREAD && definite);
03836
03837
03838
03839
03840
03841 if (omega == 0 && mem_op_lat_0 && kind != CG_DEP_MEMREAD) {
03842
03843
03844
03845
03846
03847
03848
03849 Is_True(succ_idx > op_idx, ("0-omega arc not lexically forward"));
03850 add_mem_arcs_from(succ_idx);
03851
03852
03853
03854
03855
03856
03857
03858
03859 mem_op_lat_0[op_idx][succ_idx-op_idx-1] = latency;
03860
03861
03862
03863
03864 for (s = succ_idx+1; s < num_mem_ops; s++) {
03865 if (mem_op_lat_0[succ_idx] &&
03866 mem_op_lat_0[succ_idx][s-succ_idx-1] != NO_DEP) {
03867 INT16 new_latency = latency + mem_op_lat_0[succ_idx][s-succ_idx-1];
03868 INT16 old_latency = mem_op_lat_0[op_idx][s-op_idx-1];
03869
03870 mem_op_lat_0[op_idx][s-op_idx-1] = MAX(old_latency, new_latency);
03871 }
03872 }
03873 }
03874
03875
03876 num_definite_arcs += definite;
03877 shortest = shortest ? shorter_succ_arc(shortest, arc) : arc;
03878 if (OP_like_store(succ))
03879 shortest_to_store = shortest_to_store ?
03880 shorter_succ_arc(shortest_to_store, arc) : arc;
03881 }
03882 }
03883
03884 if (num_definite_arcs)
03885 adjust_for_rw_elim(OP_succs(op), num_definite_arcs, shortest,
03886 shortest_to_store);
03887 }
03888
03889 #ifdef KEY
03890
03891
03892
03893 void
03894 add_home_mem_arcs_for_op (OP *op, TN *home_tn, int prev_mem_ops_seen)
03895 {
03896 int i;
03897
03898 for (i = 0; i < num_mem_ops; i++) {
03899 OP *mem_op = mem_ops[i];
03900 if (mem_op == op)
03901 continue;
03902 WN* wn = Get_WN_From_Memory_OP(mem_op);
03903 if (wn != NULL &&
03904 Aliased(Alias_Manager, TN_home(home_tn), wn) == SAME_LOCATION) {
03905 if (i < prev_mem_ops_seen) {
03906
03907 new_arc(CG_DEP_MISC, mem_op, op, 0, 0, FALSE);
03908 } else {
03909
03910 new_arc(CG_DEP_MISC, op, mem_op, 0, 0, FALSE);
03911 }
03912 }
03913 }
03914 }
03915
03916 void
03917 add_home_mem_arcs (BB *bb)
03918 {
03919 OP *op;
03920 int i, mem_ops_seen;
03921
03922 mem_ops_seen = 0;
03923 FOR_ALL_BB_OPs(bb, op) {
03924 if (OP_Load(op) || OP_like_store(op))
03925 mem_ops_seen++;
03926
03927 for (i = 0; i < OP_opnds(op); i++) {
03928 TN *opnd = OP_opnd(op, i);
03929 if (TN_is_register(opnd) &&
03930 TN_is_gra_homeable(opnd)) {
03931 add_home_mem_arcs_for_op(op, opnd, mem_ops_seen);
03932 }
03933 }
03934 for (i = 0; i < OP_results(op); i++) {
03935 TN *result = OP_result(op, i);
03936 if (TN_is_register(result) &&
03937 TN_is_gra_homeable(result)) {
03938 add_home_mem_arcs_for_op(op, result, mem_ops_seen);
03939 }
03940 }
03941 }
03942 }
03943 #endif
03944
03945 inline BOOL op_defines_sp(OP *op)
03946 {
03947 INT i;
03948 for (i = 0; i < OP_results(op); ++i) {
03949 TN *result = OP_result(op,i);
03950 if (TN_register_and_class(result) == CLASS_AND_REG_sp) return TRUE;
03951 }
03952 return FALSE;
03953 }
03954
03955 typedef enum {
03956 STACKREF_NO,
03957 STACKREF_YES,
03958 STACKREF_MAYBE
03959 } STACKREF_KIND;
03960
03961
03962
03963
03964 static STACKREF_KIND Memory_OP_References_Stack(OP *op)
03965 {
03966
03967
03968
03969 if (!OP_memory(op)) return STACKREF_NO;
03970
03971
03972
03973 if ( OP_load(op)
03974 && OP_results(op) == 1
03975 && TN_is_rematerializable(OP_result(op,0)))
03976 {
03977 TN *result = OP_result(op,0);
03978 WN *home = TN_home(result);
03979 #ifdef TARG_MIPS
03980
03981
03982
03983
03984
03985 if (WN_operator(home) == OPR_INTCONST)
03986 return STACKREF_NO;
03987 #endif
03988
03989 ST *st = WN_st(home);
03990 return (ST_sclass(st) == SCLASS_AUTO) ? STACKREF_YES : STACKREF_NO;
03991 }
03992
03993
03994
03995
03996 WN *wn = Get_WN_From_Memory_OP(op);
03997 if (wn) {
03998
03999
04000
04001
04002 if (Alias_Manager && Valid_alias(Alias_Manager, wn)) {
04003 BOOL on_stack = (Points_to(Alias_Manager, wn)->Local() != 0);
04004 return on_stack ? STACKREF_YES : STACKREF_NO;
04005 }
04006
04007
04008
04009
04010
04011
04012
04013
04014
04015
04016 ST *st = NULL;
04017 if (WN_has_sym(wn)) {
04018 st = WN_st(wn);
04019 #ifdef KEY
04020 Is_True(ST_class(st) == CLASS_VAR || ST_class(st) == CLASS_CONST ||
04021 ST_class(st) == CLASS_FUNC || ST_class(st) == CLASS_BLOCK,
04022 ("expected CLASS_VAR/CONST/FUNC/BLOCK symbol"));
04023 #else
04024 Is_True(ST_class(st) == CLASS_VAR, ("expected CLASS_VAR symbol"));
04025 #endif
04026 } else {
04027 WN *lda = NULL;
04028 switch (WN_operator(wn)) {
04029 case OPR_ILOAD:
04030 case OPR_ILDBITS:
04031 case OPR_ILOADX:
04032 lda = WN_kid0(wn);
04033 break;
04034 case OPR_ISTORE:
04035 case OPR_ISTBITS:
04036 case OPR_ISTOREX:
04037 lda = WN_kid1(wn);
04038 break;
04039 #ifdef KEY
04040 case OPR_CVT:
04041 return STACKREF_MAYBE;
04042 default:
04043 return STACKREF_MAYBE;
04044 #endif
04045 }
04046 if (WN_operator_is(lda, OPR_LDA)) st = WN_st(lda);
04047 }
04048
04049
04050
04051
04052 if (st) return (ST_sclass(st) == SCLASS_AUTO) ? STACKREF_YES : STACKREF_NO;
04053 }
04054
04055
04056
04057
04058 return STACKREF_MAYBE;
04059 }
04060
04061
04062
04063
04064 void maybe_add_exit_sp_adj_arc (OP *mem_op, OP *exit_sp_adj_op)
04065 {
04066 if ( Memory_OP_References_Stack(mem_op) != STACKREF_NO
04067 && OP_Precedes(mem_op, exit_sp_adj_op))
04068 {
04069 new_arc_with_latency(CG_DEP_MISC, mem_op, exit_sp_adj_op, 0, 0, 0, FALSE);
04070 }
04071 }
04072
04073 BOOL
04074 CG_DEP_Alloca_Aliases(OP *mem_op)
04075 {
04076 WN * mem_wn = Get_WN_From_Memory_OP(mem_op);
04077
04078 if (Alias_Manager == NULL)
04079
04080 return TRUE;
04081
04082 if (mem_wn && May_refer_to_alloca_mem(Alias_Manager, mem_wn))
04083 return TRUE;
04084
04085 return FALSE;
04086 }
04087
04088 static void Add_MEM_Arcs(BB *bb)
04089
04090
04091
04092 {
04093 OP *op;
04094 UINT16 i;
04095 UINT32 sp_defs = 0;
04096
04097
04098 num_mem_ops = 0;
04099 FOR_ALL_BB_OPs(bb, op) {
04100 if (OP_Load(op) || OP_like_store(op))
04101 num_mem_ops++;
04102
04103 if (CG_DEP_Add_Alloca_Arcs && op_defines_sp(op))
04104 ++sp_defs;
04105 }
04106
04107
04108 if (num_mem_ops < 1) return;
04109
04110
04111
04112
04113
04114 if (BB_exit(bb)) {
04115 OP *exit_sp_adj = BB_exit_sp_adj_op(bb);
04116 #ifdef KEY
04117
04118
04119
04120 if (exit_sp_adj &&
04121 OP_bb(exit_sp_adj) == bb)
04122 #endif // KEY
04123 {
04124 for (op = exit_sp_adj; op != NULL; op = OP_prev(op)) {
04125 maybe_add_exit_sp_adj_arc (op, exit_sp_adj);
04126 }
04127 }
04128 }
04129
04130 #ifdef KEY
04131
04132
04133
04134
04135 {
04136 FOR_ALL_BB_OPs(bb, op) {
04137 if (OP_code(op) == TOP_asm) {
04138 OP *op_tmp;
04139 BOOL tail = FALSE;
04140
04141 FOR_ALL_BB_OPs(bb, op_tmp) {
04142 if (op_tmp == op) {
04143 tail = TRUE;
04144 continue;
04145 }
04146 if (!tail)
04147 new_arc_with_latency(CG_DEP_MEMOUT, op_tmp, op, 1, 0, 0,FALSE);
04148 else
04149 new_arc_with_latency(CG_DEP_MEMOUT, op, op_tmp, 1, 0, 0,FALSE);
04150 }
04151 }
04152 }
04153 }
04154 #endif
04155 if (!cyclic && num_mem_ops == 1) return;
04156
04157
04158 MEM_POOL_Push(&MEM_local_pool);
04159 mem_ops = TYPE_L_ALLOC_N(OP *, num_mem_ops);
04160 i = 0;
04161 FOR_ALL_BB_OPs(bb, op) {
04162 if (OP_Load(op) || OP_like_store(op)){
04163 mem_ops[i++] = op;
04164 }
04165 }
04166 if (CG_DEP_Mem_Arc_Pruning >= PRUNE_CYCLIC_0 ||
04167 !cyclic && CG_DEP_Mem_Arc_Pruning >= PRUNE_NON_CYCLIC)
04168 mem_op_lat_0 = TYPE_L_ALLOC_N(INT32 *, num_mem_ops);
04169
04170
04171 for (i = 0; i < num_mem_ops; i++)
04172 add_mem_arcs_from(i);
04173
04174
04175
04176
04177 if (CG_DEP_Add_Alloca_Arcs) {
04178 for (op = BB_first_op(bb); op && sp_defs > 0; op = OP_next(op)) {
04179 if (op_defines_sp(op)) {
04180 --sp_defs;
04181 for (i = 0; i < num_mem_ops; i++) {
04182 #ifdef KEY
04183 if (op == mem_ops[i])
04184 continue;
04185 #endif
04186 if (CG_DEP_Alloca_Aliases(mem_ops[i])) {
04187 if (OP_Precedes(op, mem_ops[i]))
04188 new_arc(CG_DEP_MISC, op, mem_ops[i], 0, 0, FALSE);
04189 else
04190 new_arc(CG_DEP_MISC, mem_ops[i], op, 0, 0, FALSE);
04191 }
04192 }
04193 }
04194 }
04195 }
04196
04197 #ifdef KEY
04198
04199
04200
04201
04202 add_home_mem_arcs(bb);
04203 #endif
04204
04205 MEM_POOL_Pop(&MEM_local_pool);
04206
04207
04208 mem_op_lat_0 = NULL;
04209
04210
04211 mem_ops = NULL;
04212 }
04213
04214 #if defined(TARG_SL)
04215 static void Add_Vbuf_MEM_Arcs(BB *bb)
04216
04217
04218
04219 {
04220 OP *op;
04221 UINT16 i;
04222 UINT32 sp_defs = 0;
04223
04224
04225 num_mem_ops = 0;
04226 FOR_ALL_BB_OPs(bb, op) {
04227 if (OP_vbuf_load(op) || OP_vbuf_store(op))
04228 num_mem_ops++;
04229 }
04230
04231
04232 if (num_mem_ops < 1) return;
04233
04234
04235
04236
04237
04238 if (BB_exit(bb)) {
04239 OP *exit_sp_adj = BB_exit_sp_adj_op(bb);
04240 #ifdef KEY
04241
04242
04243
04244 if (exit_sp_adj &&
04245 OP_bb(exit_sp_adj) == bb)
04246 #endif // KEY
04247 {
04248 for (op = exit_sp_adj; op != NULL; op = OP_prev(op)) {
04249 maybe_add_exit_sp_adj_arc (op, exit_sp_adj);
04250 }
04251 }
04252 }
04253
04254 #ifdef KEY
04255
04256
04257
04258
04259 {
04260 FOR_ALL_BB_OPs(bb, op) {
04261 if (OP_code(op) == TOP_asm) {
04262 OP *op_tmp;
04263 BOOL tail = FALSE;
04264
04265 FOR_ALL_BB_OPs(bb, op_tmp) {
04266 if (op_tmp == op) {
04267 tail = TRUE;
04268 continue;
04269 }
04270 if (!tail)
04271 new_arc_with_latency(CG_DEP_MEMOUT, op_tmp, op, 1, 0, 0,FALSE);
04272 else
04273 new_arc_with_latency(CG_DEP_MEMOUT, op, op_tmp, 1, 0, 0,FALSE);
04274 }
04275 }
04276 }
04277 }
04278 #endif
04279 if (!cyclic && num_mem_ops == 1) return;
04280
04281
04282 MEM_POOL_Push(&MEM_local_pool);
04283 mem_ops = TYPE_L_ALLOC_N(OP *, num_mem_ops);
04284 i = 0;
04285 FOR_ALL_BB_OPs(bb, op) {
04286 if (OP_vbuf_load(op) || OP_vbuf_store(op)){
04287 mem_ops[i++] = op;
04288 }
04289 }
04290 if (CG_DEP_Mem_Arc_Pruning >= PRUNE_CYCLIC_0 ||
04291 !cyclic && CG_DEP_Mem_Arc_Pruning >= PRUNE_NON_CYCLIC)
04292 mem_op_lat_0 = TYPE_L_ALLOC_N(INT32 *, num_mem_ops);
04293
04294
04295 for (i = 0; i < num_mem_ops; i++)
04296 add_mem_arcs_from(i);
04297
04298
04299
04300
04301 if (CG_DEP_Add_Alloca_Arcs) {
04302 for (op = BB_first_op(bb); op && sp_defs > 0; op = OP_next(op)) {
04303 if (op_defines_sp(op)) {
04304 --sp_defs;
04305 for (i = 0; i < num_mem_ops; i++) {
04306 if (CG_DEP_Alloca_Aliases(mem_ops[i])) {
04307 if (OP_Precedes(op, mem_ops[i]))
04308 new_arc(CG_DEP_MISC, op, mem_ops[i], 0, 0, FALSE);
04309 else
04310 new_arc(CG_DEP_MISC, mem_ops[i], op, 0, 0, FALSE);
04311 }
04312 }
04313 }
04314 }
04315 }
04316
04317 MEM_POOL_Pop(&MEM_local_pool);
04318
04319
04320 mem_op_lat_0 = NULL;
04321
04322
04323 mem_ops = NULL;
04324 }
04325 #endif
04326
04327 static void make_virtual_anti_or_output_arc(CG_DEP_KIND kind, OP *pred,
04328 OP *succ, UINT8 opnd)
04329
04330
04331
04332
04333
04334
04335
04336
04337 {
04338 INT16 search_opnd = (kind == CG_DEP_REGOUT) ? DONT_CARE : (INT16)opnd;
04339 ARC *arc = _CG_DEP_op_info(pred) ?
04340 ARC_LIST_Find_First(OP_succs(pred), kind, search_opnd) : NULL;
04341
04342 Is_True(kind == CG_DEP_REGOUT || kind == CG_DEP_REGANTI,
04343 ("kind not REGOUT or REGANTI"));
04344 Is_True(cyclic || OP_Precedes(pred, succ),
04345 ("cannot make non-cyclic backwards arc"));
04346
04347 if (arc) {
04348 OP *other_succ = ARC_succ(arc);
04349
04350
04351
04352
04353
04354
04355
04356
04357 if (is_closer_succ(pred, succ, other_succ)) {
04358 detach_arc_from_succ(arc);
04359 Set_ARC_succ(arc, succ);
04360 Set_ARC_kind(arc, kind);
04361 Set_ARC_omega(arc, !OP_Follows(succ, pred));
04362 attach_arc_to_succ(arc);
04363 if (maintain_prebr) maintain_prebr_arc(pred);
04364 }
04365
04366 } else {
04367
04368
04369
04370
04371 if (_CG_DEP_op_info(succ)) {
04372 do {
04373 arc = ARC_LIST_Find_First(OP_preds(succ), CG_DEP_REGOUT, DONT_CARE);
04374 Is_True(!arc || ARC_pred(arc) != succ, ("found REGOUT arc to self"));
04375 if (arc)
04376 succ = closer_succ(pred, succ, ARC_pred(arc));
04377 } while (arc && ARC_pred(arc) == succ);
04378 }
04379
04380
04381
04382 new_arc(kind, pred, succ, !OP_Follows(succ, pred), opnd, FALSE);
04383 }
04384 }
04385
04386
04387
04388
04389
04390
04391 static BOOL
04392 OP_Shadowed_By_Prev_OPs(OP *defop,
04393 OP_LIST *prev_list,
04394 COMPARE_FUNCTION comp_func)
04395 {
04396 OP *op;
04397 while (prev_list) {
04398 op = OP_LIST_first(prev_list);
04399 if (comp_func(op, defop)) return TRUE;
04400 prev_list = OP_LIST_rest(prev_list);
04401 }
04402 return FALSE;
04403 }
04404
04405
04406 #if defined(TARG_SL)
04407 static
04408 INT Get_Word_Size_For_Multi_Mode(TOP opcode)
04409 {
04410 switch(opcode)
04411 {
04412 case TOP_c2_ldi_v_m_b_u:
04413 case TOP_c2_ldi_v_m_b:
04414 case TOP_c2_ld_v_m_b:
04415 case TOP_c2_ld_v_m_b_u:
04416 case TOP_c2_sti_v_m_b:
04417 case TOP_c2_st_v_m_b:
04418 return 1;
04419 break;
04420 case TOP_c2_ldi_v_m_h:
04421 case TOP_c2_ld_v_m_h:
04422 case TOP_c2_sti_v_m_h:
04423 case TOP_c2_st_v_m_h:
04424 return 2;
04425 break;
04426 case TOP_c2_ldi_v_m_w:
04427 case TOP_c2_ld_v_m_w:
04428 case TOP_c2_sti_v_m_w:
04429 case TOP_c2_st_v_m_w:
04430 return 4;
04431 break;
04432 default:
04433 FmtAssert(FALSE, ("invalid opcode for multi-mode c2.ld/st"));
04434 }
04435 }
04436 #endif
04437
04438
04439
04440
04441
04442
04443
04444
04445 static void
04446 Add_Forw_REG_Arcs(BB *bb)
04447 {
04448 OP *op;
04449
04450 FOR_ALL_BB_OPs(bb, op) {
04451 INT32 i;
04452
04453 if (OP_store(op) || OP_load(op)) {
04454
04455 make_prefetch_arcs(op, bb);
04456 }
04457
04458 for (i = 0; i < OP_opnds(op); i++) {
04459 OP_LIST *defop_list = defop_for_op(op, i, FALSE);
04460 if (has_assigned_reg(OP_opnd(op,i)))
04461 add_reg_assignment(OP_opnd(op,i));
04462
04463 OP_LIST *prev_list = NULL;
04464 while (defop_list) {
04465
04466
04467
04468
04469 OP *defop = OP_LIST_first(defop_list);
04470 if (!OP_Shadowed_By_Prev_OPs(defop, prev_list,
04471 OP_has_subset_predicate)) {
04472
04473
04474
04475
04476
04477
04478
04479
04480 #ifdef TARG_IA64
04481 if ((!PRDB_Valid() && include_assigned_registers) ||
04482 #else
04483 if (include_assigned_registers ||
04484 #endif
04485 !OP_has_disjoint_predicate(defop,op)) {
04486 #ifdef TARG_SL2
04487 if(TOP_is_c2_multi_mode_load(OP_code(defop))) {
04488 Is_True( defop->extra_result,
04489 (" multi mode defop should have already been created with extra opnds/results") );
04490 TN_LIST * more_tns = defop->extra_operand;
04491 INT32 row_count = 0;
04492 while( more_tns ){
04493 row_count++;
04494 more_tns = TN_LIST_rest( more_tns );
04495 }
04496 Is_True( (row_count >= 0),
04497 ("Invalid row_count in multi_mode c2.ld/st"));
04498 INT word_size = Get_Word_Size_For_Multi_Mode(OP_code(defop));
04499 new_arc_with_latency(CG_DEP_REGIN, defop, op, row_count*word_size, 0, i, FALSE);
04500 }
04501 else {
04502 new_arc(CG_DEP_REGIN, defop, op, 0, i, FALSE);
04503 }
04504 #else
04505 new_arc(CG_DEP_REGIN, defop, op, 0, i, FALSE);
04506 #endif
04507 }
04508 }
04509 prev_list = OP_LIST_Push(defop, prev_list, &dep_nz_pool);
04510 defop_list = OP_LIST_rest(defop_list);
04511 }
04512 }
04513
04514 #if defined(TARG_SL)
04515 TN_LIST * extra_opnds = op->extra_operand;
04516 while( extra_opnds ){
04517
04518
04519
04520
04521 TN* opnd_tn = TN_LIST_first( extra_opnds );
04522 OP_LIST *defop_list = defop_for_tn( opnd_tn );
04523 if( has_assigned_reg(opnd_tn) )
04524 add_reg_assignment(opnd_tn);
04525
04526 OP_LIST *prev_list = NULL;
04527 while (defop_list) {
04528 OP *defop = OP_LIST_first(defop_list);
04529 if (!OP_Shadowed_By_Prev_OPs(defop, prev_list,
04530 OP_has_subset_predicate)) {
04531 if (include_assigned_registers ||
04532 !OP_has_disjoint_predicate(defop,op)) {
04533
04534
04535
04536 if(TOP_is_c2_multi_mode_load(OP_code(defop))) {
04537 Is_True( defop->extra_result,
04538 (" multi mode defop should have already been created with extra opnds/results") );
04539 TN_LIST * more_tns = defop->extra_operand;
04540 INT32 row_count = 0;
04541 while( more_tns ){
04542 row_count++;
04543 more_tns = TN_LIST_rest( more_tns );
04544 }
04545 Is_True( (row_count >= 0),
04546 ("Invalid row_count in multi_mode c2.ld/st") );
04547 INT word_size = Get_Word_Size_For_Multi_Mode(OP_code(defop));
04548 new_arc_with_latency(CG_DEP_REGIN, defop, op, row_count*word_size, 0, 0, FALSE);
04549 }
04550 else {
04551 new_arc(CG_DEP_REGIN, defop, op, 0, 0, FALSE);
04552 }
04553 }
04554 }
04555 prev_list = OP_LIST_Push(defop, prev_list, &dep_nz_pool);
04556 defop_list = OP_LIST_rest(defop_list);
04557 }
04558 extra_opnds = TN_LIST_rest( extra_opnds );
04559 }
04560 #endif
04561
04562 for (i = 0; i < OP_results(op); i++) {
04563 OP_LIST *prev_defop_list = defop_for_op(op, i, TRUE);
04564 if (has_assigned_reg(OP_result(op,i)))
04565 add_reg_assignment(OP_result(op,i));
04566
04567 OP_LIST *prev_list = NULL;
04568 while (prev_defop_list) {
04569
04570
04571
04572
04573
04574
04575
04576 OP *prev_defop = OP_LIST_first(prev_defop_list);
04577
04578 if (!OP_Shadowed_By_Prev_OPs(prev_defop, prev_list, OP_has_subset_predicate)) {
04579
04580
04581
04582
04583
04584
04585
04586
04587 #ifdef TARG_IA64
04588 if ((!PRDB_Valid() && include_assigned_registers) ||
04589 #else
04590 if (include_assigned_registers ||
04591 #endif
04592 !OP_has_disjoint_predicate(prev_defop,op)) {
04593 new_arc(CG_DEP_REGOUT, prev_defop, op, 0, 0, FALSE);
04594 }
04595 }
04596
04597 prev_list = OP_LIST_Push(prev_defop, prev_list, &dep_nz_pool);
04598 prev_defop_list = OP_LIST_rest(prev_defop_list);
04599 }
04600 }
04601
04602 #if defined(TARG_SL)
04603
04604 TN_LIST * extra_results = op->extra_result;
04605 while( extra_results ) {
04606 TN* tn = TN_LIST_first( extra_results );
04607 OP_LIST *prev_defop_list = defop_for_tn(tn);
04608 if( has_assigned_reg(tn) )
04609 add_reg_assignment(tn);
04610
04611 OP_LIST *prev_list = NULL;
04612 while (prev_defop_list) {
04613 OP *prev_defop = OP_LIST_first(prev_defop_list);
04614
04615 if (!OP_Shadowed_By_Prev_OPs(prev_defop, prev_list, OP_has_subset_predicate)) {
04616
04617 if (include_assigned_registers ||
04618 !OP_has_disjoint_predicate(prev_defop,op)) {
04619 new_arc(CG_DEP_REGOUT, prev_defop, op, 0, 0, FALSE);
04620 }
04621 }
04622
04623 prev_list = OP_LIST_Push(prev_defop, prev_list, &dep_nz_pool);
04624 prev_defop_list = OP_LIST_rest(prev_defop_list);
04625 }
04626 extra_results = TN_LIST_rest( extra_results );
04627 }
04628 #endif
04629 defop_set(op);
04630 }
04631 }
04632
04633
04634
04635
04636
04637
04638
04639
04640
04641 static void
04642 Add_Bkwd_REG_Arcs(BB *bb, TN_SET *need_anti_out_dep)
04643 {
04644 OP *op;
04645 FOR_ALL_BB_OPs_REV(bb, op) {
04646 INT32 i;
04647 defop_set(op);
04648
04649 for (i = 0; i < OP_opnds(op); i++) {
04650 TN *opnd = OP_opnd(op,i);
04651 if (TN_is_register(opnd) && !TN_is_const_reg(opnd)) {
04652 BOOL tn_def_found = FALSE;
04653 OP_LIST *defop_list = defop_for_op(op, i, FALSE);
04654 OP_LIST *prev_list = NULL;
04655 while (defop_list) {
04656 OP *defop = OP_LIST_first(defop_list);
04657 if (defop != op &&
04658 !OP_Shadowed_By_Prev_OPs(defop, prev_list, OP_has_subset_predicate)) {
04659
04660
04661
04662
04663
04664
04665
04666
04667 #ifdef TARG_IA64
04668 if ((!PRDB_Valid() && include_assigned_registers) ||
04669 !OP_has_disjoint_predicate(defop,op) ||
04670 TN_is_predicate(OP_opnd(op,i))) {
04671 #else
04672 if (include_assigned_registers ||
04673 !OP_has_disjoint_predicate(defop,op)) {
04674 #endif
04675 tn_def_found = TRUE;
04676
04677
04678
04679 new_arc(CG_DEP_REGANTI, op, defop, 0, i, FALSE);
04680 }
04681 }
04682 prev_list = OP_LIST_Push(defop, prev_list, &dep_nz_pool);
04683 defop_list = OP_LIST_rest(defop_list);
04684 }
04685 if (!tn_def_found && !ARC_LIST_Find(OP_preds(op), CG_DEP_REGIN, i))
04686 add_gtn_use_arc(op, i);
04687 }
04688 }
04689 #if defined(TARG_SL)
04690 TN_LIST * extra_operands = op->extra_operand;
04691 while( extra_operands ) {
04692 TN *opnd = TN_LIST_first( extra_operands );
04693 if (TN_is_register(opnd) && !TN_is_const_reg(opnd)) {
04694 BOOL tn_def_found = FALSE;
04695 OP_LIST *defop_list = defop_for_tn(opnd);
04696 OP_LIST *prev_list = NULL;
04697 while (defop_list) {
04698 OP *defop = OP_LIST_first(defop_list);
04699 if (defop != op &&
04700 !OP_Shadowed_By_Prev_OPs(defop, prev_list, OP_has_subset_predicate)) {
04701
04702 if (include_assigned_registers ||
04703 !OP_has_disjoint_predicate(defop,op)) {
04704 tn_def_found = TRUE;
04705 new_arc(CG_DEP_REGANTI, op, defop, 0, 0, FALSE);
04706 }
04707 }
04708 prev_list = OP_LIST_Push(defop, prev_list, &dep_nz_pool);
04709 defop_list = OP_LIST_rest(defop_list);
04710 }
04711
04712
04713
04714 if(!tn_def_found && !ARC_LIST_Find(OP_preds(op), CG_DEP_REGIN, 0))
04715 add_gtn_use_arc(op, 0);
04716 }
04717 extra_operands = TN_LIST_rest( extra_operands );
04718 }
04719 #endif // TARG_SL
04720 }
04721 }
04722
04723
04724
04725
04726
04727 struct TN_2_DEFS_VECTOR_MAP {
04728 typedef std::vector<int> DEFS_VECTOR_TYPE;
04729 typedef std::map<TN*, DEFS_VECTOR_TYPE> TN_2_DEFS_VECTOR_MAP_TYPE;
04730 typedef TN_2_DEFS_VECTOR_MAP_TYPE::iterator iterator;
04731
04732 private:
04733 TN_2_DEFS_VECTOR_MAP_TYPE tn_2_defs_vector_map;
04734
04735 public:
04736
04737 iterator begin() { return tn_2_defs_vector_map.begin(); }
04738 iterator end() { return tn_2_defs_vector_map.end(); }
04739 iterator find(TN *tn) { return tn_2_defs_vector_map.find(tn); }
04740
04741 DEFS_VECTOR_TYPE& operator[](TN *tn) {
04742 return tn_2_defs_vector_map[tn];
04743 }
04744
04745 TN_2_DEFS_VECTOR_MAP(OP_VECTOR& op_vec, bool trace) {
04746 #ifdef TARG_X8664
04747 static TN* rflags = Rflags_TN();
04748 #endif
04749
04750 for (INT op_num = 0; op_num < op_vec.size(); op_num++) {
04751 OP *op = op_vec[op_num];
04752 for (INT i = 0; i < OP_results(op); i++) {
04753 TN *tn = OP_result(op,i);
04754 if (TN_is_register(tn) &&
04755 #ifdef TARG_X8664
04756 tn != rflags &&
04757 #endif
04758 !TN_is_const_reg(tn)) {
04759 if (tn_2_defs_vector_map.find(tn) == tn_2_defs_vector_map.end())
04760 tn_2_defs_vector_map[tn] = DEFS_VECTOR_TYPE();
04761 tn_2_defs_vector_map[tn].push_back(op_num);
04762 }
04763 }
04764 }
04765 }
04766 };
04767
04768
04769
04770
04771 void Build_Cyclic_Arcs(BB *bb)
04772 {
04773 OP_VECTOR op_vec(bb);
04774 TN_2_DEFS_VECTOR_MAP tn_map(op_vec, false);
04775
04776 for (INT use_num = 0; use_num < op_vec.size(); use_num++) {
04777 OP *op = op_vec[use_num];
04778 for (INT opnd = 0; opnd < OP_opnds(op); opnd++) {
04779 TN *tn = OP_opnd(op, opnd);
04780
04781
04782
04783 if (!TN_is_register(tn) || TN_is_const_reg(tn))
04784 continue;
04785
04786 if (tn_map.find(tn) == tn_map.end())
04787 continue;
04788
04789 TN_2_DEFS_VECTOR_MAP::DEFS_VECTOR_TYPE& tn_defs = tn_map[tn];
04790 INT omega = OP_omega(op, opnd);
04791
04792
04793 bool local_lr = !TN_is_global_reg(tn) || !GTN_SET_MemberP(BB_live_in(bb), tn);
04794 bool definite_dep = !local_lr || !TN_is_dedicated(tn);
04795 bool single_def = tn_defs.size() == 1;
04796
04797 INT i;
04798 for (i = 0; i < tn_defs.size(); i++) {
04799 INT def_num = tn_defs[i];
04800 OP *op = op_vec[def_num];
04801 if (Base_update_tn(op) == tn)
04802 definite_dep = false;
04803 }
04804
04805 Is_True(omega <= 1 || definite_dep,
04806 ("Build_Cyclic_Arcs: cannot have omega=%d for non-definite dependence.",
04807 omega));
04808
04809
04810 if (single_def) {
04811
04812 INT def_num = tn_defs[0];
04813 new_arc(CG_DEP_REGIN, op_vec[def_num], op, omega, opnd, FALSE);
04814
04815 } else {
04816
04817 INT i;
04818
04819 for (i = tn_defs.size()-1; i >= 0; i--) {
04820 INT def_num = tn_defs[i];
04821 if (def_num >= use_num) continue;
04822
04823 if (!OP_has_disjoint_predicate_cyclic(op_vec[def_num], op))
04824 new_arc(CG_DEP_REGIN, op_vec[def_num], op, omega, opnd, FALSE);
04825
04826 if (OP_has_subset_predicate_cyclic(op_vec[def_num], op))
04827 break;
04828 }
04829
04830
04831 if (!local_lr) {
04832 if (!definite_dep ||
04833 (definite_dep && omega > 0)) {
04834 for (i = tn_defs.size()-1; i >= 0; i--) {
04835 INT def_num = tn_defs[i];
04836 if (def_num < use_num) break;
04837 new_arc(CG_DEP_REGIN, op_vec[def_num], op, definite_dep ? omega : 1, opnd, FALSE);
04838 }
04839 }
04840 }
04841 }
04842
04843
04844 if (single_def) {
04845
04846 if (!definite_dep) {
04847 INT def_num = tn_defs[0];
04848 INT omega = (def_num <= use_num) ? 1 : 0;
04849 if (def_num != use_num)
04850 new_arc(CG_DEP_REGANTI, op, op_vec[def_num], omega, opnd, FALSE);
04851 }
04852
04853 } else {
04854
04855
04856 INT i;
04857 for (i = 0; i < tn_defs.size(); i++) {
04858 INT def_num = tn_defs[i];
04859 if (def_num <= use_num) continue;
04860
04861 if (!OP_has_disjoint_predicate_cyclic(op_vec[def_num], op))
04862 new_arc(CG_DEP_REGANTI, op, op_vec[def_num], 0, opnd, FALSE);
04863
04864 if (OP_has_subset_predicate_cyclic(op_vec[def_num], op))
04865 break;
04866 }
04867
04868
04869 if (!definite_dep) {
04870 for (i = 0; i < tn_defs.size(); i++) {
04871 INT def_num = tn_defs[i];
04872 if (def_num >= use_num) break;
04873
04874
04875 new_arc(CG_DEP_REGANTI, op, op_vec[def_num], 1, opnd, FALSE);
04876 }
04877 }
04878 }
04879 }
04880 }
04881
04882 for (TN_2_DEFS_VECTOR_MAP::iterator it = tn_map.begin(); it != tn_map.end(); it++) {
04883 TN *tn = (*it).first;
04884 TN_2_DEFS_VECTOR_MAP::DEFS_VECTOR_TYPE& tn_defs = (*it).second;
04885
04886
04887 bool local_lr = !TN_is_global_reg(tn) || !GTN_SET_MemberP(BB_live_in(bb), tn);
04888 bool definite_dep = !local_lr && !TN_is_dedicated(tn);
04889 bool single_def = tn_defs.size() == 1;
04890
04891 INT i;
04892 for (i = 0; i < tn_defs.size(); i++) {
04893 INT def_num = tn_defs[i];
04894 OP *op = op_vec[def_num];
04895 if (Base_update_tn(op) == tn)
04896 definite_dep = false;
04897 }
04898
04899
04900 if (!single_def) {
04901 INT last_i = tn_defs.size()-2;
04902 for (INT i = 0; i <= last_i; i++) {
04903 INT d1 = tn_defs[i];
04904 INT d2 = tn_defs[i+1];
04905 OP *op1 = op_vec[d1];
04906 OP *op2 = op_vec[d2];
04907
04908
04909 if (i == 0 ||
04910 i == last_i ||
04911 !OP_has_disjoint_predicate_cyclic(op1, op2))
04912 new_arc(CG_DEP_REGOUT, op1, op2, 0, 0, FALSE);
04913 }
04914
04915
04916 if (!definite_dep) {
04917 INT d1 = tn_defs[tn_defs.size()-1];
04918 INT d2 = tn_defs[0];
04919 new_arc(CG_DEP_REGOUT, op_vec[d1], op_vec[d2], 1, 0, FALSE);
04920 }
04921 }
04922 }
04923
04924 #ifdef Is_True_On
04925 if (Get_Trace(TP_CG, 0x02))
04926 {
04927 for (INT i = 0; i < op_vec.size(); i++) {
04928 OP *op = op_vec[i];
04929 for (ARC_LIST *arcs = OP_succs(op); arcs; arcs = ARC_LIST_rest(arcs)) {
04930 ARC *arc = ARC_LIST_first(arcs);
04931 if (ARC_omega(arc) == 0) {
04932 OP *succ = ARC_succ(arc);
04933 if (!OP_Precedes(op, succ)) {
04934 CG_DEP_Trace_Graph(bb);
04935 fprintf(TFile, "OP:\t");
04936 Print_OP_No_SrcLine(op);
04937 fprintf(TFile, "Succ:\t");
04938 Print_OP_No_SrcLine(succ);
04939 Is_True(FALSE,
04940 ("Build_Cyclic_Graphs: omega == 0 but pred OP does not precedes succ OP."));
04941 }
04942 }
04943 }
04944 }
04945 }
04946 #endif
04947 }
04948
04949
04950 #ifdef TARG_IA64
04951
04952
04953
04954
04955
04956
04957
04958
04959
04960
04961
04962 void
04963 Add_CHK_Arcs(BB *bb)
04964 {
04965 BOOL is_recovery = BB_recovery(bb);
04966
04967 if(BB_length(bb) < 2)
04968 return;
04969
04970 OP* barrier = NULL;
04971 if(is_recovery) {
04972 barrier = BB_first_op(bb);
04973 }
04974
04975 for(OP* op = BB_first_op(bb); op; op = OP_next(op)){
04976 if(barrier == op) continue;
04977 if(barrier){
04978 if(OP_chk(barrier)){
04979 new_arc_with_latency (CG_DEP_POSTCHK , barrier, op, 0, 0, 0, FALSE);
04980 } else if(OP_xfer(barrier) || OP_call(barrier)){
04981 new_arc_with_latency(CG_DEP_POSTBR, barrier, op, 0, 0, 0, FALSE);
04982 }else{
04983 new_arc_with_latency(CG_DEP_MISC, barrier, op, 0, 0, 0, FALSE);
04984 }
04985 }
04986 if(OP_chk(op) || OP_xfer(op) || OP_call(op))
04987 barrier = op;
04988 }
04989
04990 barrier = NULL;
04991 for(OP* op = BB_last_op(bb); op; op = OP_prev(op)){
04992 if(barrier && !OP_xfer(op) && !OP_call(op) && !OP_chk(op)){
04993 if(OP_chk(barrier)){
04994 if(OP_store(op) && OP_chk_a(barrier)){
04995 new_arc_with_latency(CG_DEP_PRECHK, op, barrier, 1, 0, 0, FALSE);
04996 }else{
04997 new_arc_with_latency(CG_DEP_PRECHK, op, barrier, 0, 0, 0, FALSE);
04998 }
04999 }else{
05000 new_arc_with_latency(CG_DEP_PREBR, op, barrier, 0, 0, 0, FALSE);
05001 }
05002 }
05003 if(OP_chk(op) || OP_xfer(op) || OP_call(op))
05004 barrier = op;
05005 }
05006 }
05007 #endif
05008
05009
05010
05011
05012
05013
05014
05015
05016
05017
05018
05019
05020
05021
05022 static void
05023 Compute_BB_Graph(BB *bb, TN_SET *need_anti_out_dep)
05024 {
05025 OP *op;
05026 BB_OP_MAP omap = BB_OP_MAP_Create(bb, &dep_map_nz_pool);
05027
05028 BB_MAP_Set(_cg_dep_op_info, bb, omap);
05029 OP *xfer_op = BB_xfer_op(bb);
05030 xfer_ops = TYPE_L_ALLOC_N(OP *, 1);
05031
05032
05033 INT i = 0;
05034
05035 FOR_ALL_BB_OPs(bb, op) {
05036 BB_OP_MAP_Set(omap, op, new_op_info());
05037 }
05038
05039 if (xfer_op) { xfer_ops[i++] = xfer_op; }
05040 else { xfer_ops[i++] = NULL; }
05041
05042
05043
05044
05045
05046
05047 if (cyclic) {
05048
05049 Build_Cyclic_Arcs(bb);
05050
05051 } else {
05052
05053 defop_init();
05054 Add_Forw_REG_Arcs(bb);
05055 defop_finish();
05056
05057 defop_init();
05058 Add_Bkwd_REG_Arcs(bb, need_anti_out_dep);
05059 defop_finish();
05060 }
05061
05062
05063 Add_MEM_Arcs(bb);
05064
05065 std::list<BB*> bb_list;
05066 bb_list.push_back(bb);
05067
05068 if (include_control_arcs) {
05069 Add_BRANCH_Arcs(bb, bb_list, TRUE);
05070 }
05071
05072
05073 Add_MISC_Arcs(bb);
05074 #ifdef TARG_IA64
05075
05076 Add_CHK_Arcs(bb);
05077 #endif
05078 }
05079
05080
05081
05082
05083 CYCLIC_DEP_GRAPH::CYCLIC_DEP_GRAPH( BB *body, MEM_POOL *pool )
05084 : _body( body )
05085 {
05086 CG_DEP_Compute_Graph( _body,
05087 NO_ASSIGNED_REG_DEPS,
05088 CYCLIC,
05089 NO_MEMREAD_ARCS,
05090 INCLUDE_MEMIN_ARCS,
05091 NO_CONTROL_ARCS,
05092 NULL);
05093 }
05094
05095 CYCLIC_DEP_GRAPH::~CYCLIC_DEP_GRAPH()
05096 {
05097 CG_DEP_Delete_Graph( _body );
05098 }
05099
05100
05101
05102
05103
05104
05105
05106
05107
05108
05109 static void
05110 Compute_Region_Graph(std::list<BB*> bb_list)
05111 {
05112
05113 std::list<BB*>::iterator bb_iter;
05114 FOR_ALL_BB_STLLIST_ITEMS_FWD(bb_list, bb_iter) {
05115 BB_OP_MAP omap = BB_OP_MAP_Create(*bb_iter, &dep_map_nz_pool);
05116 BB_MAP_Set(_cg_dep_op_info, *bb_iter, omap);
05117
05118 OP *op;
05119 FOR_ALL_BB_OPs(*bb_iter, op) {
05120 BB_OP_MAP_Set(omap, op, new_op_info());
05121 }
05122 }
05123
05124 defop_init();
05125 FOR_ALL_BB_STLLIST_ITEMS_FWD(bb_list, bb_iter) {
05126
05127
05128
05129
05130
05131
05132 Add_Forw_REG_Arcs(*bb_iter);
05133 }
05134 defop_finish();
05135
05136 defop_init();
05137 std::list<BB*>::reverse_iterator bb_riter;
05138 FOR_ALL_BB_STLLIST_ITEMS_BKWD(bb_list, bb_riter) {
05139
05140
05141
05142
05143 Add_Bkwd_REG_Arcs(*bb_riter, NULL);
05144 }
05145 defop_finish();
05146
05147 FOR_ALL_BB_STLLIST_ITEMS_FWD(bb_list, bb_iter) {
05148
05149 Add_MEM_Arcs(*bb_iter);
05150
05151
05152 Add_MISC_Arcs(*bb_iter);
05153 }
05154
05155
05156 if (include_control_arcs) {
05157
05158 xfer_ops = TYPE_L_ALLOC_N(OP *, bb_list.size());
05159 INT i = 0;
05160 FOR_ALL_BB_STLLIST_ITEMS_FWD(bb_list, bb_iter) {
05161
05162 OP *xfer_op;
05163
05164
05165
05166
05167 if (xfer_op = BB_xfer_op(*bb_iter)) {
05168 xfer_ops[i++] = xfer_op;
05169 } else {
05170 xfer_ops[i++] = NULL;
05171 }
05172 }
05173
05174 FOR_ALL_BB_STLLIST_ITEMS_FWD(bb_list, bb_iter) {
05175
05176 Add_BRANCH_Arcs(*bb_iter, bb_list, TRUE);
05177 }
05178 }
05179 }
05180
05181
05182
05183
05184
05185
05186
05187
05188 static BOOL
05189 has_no_0_omega_non_neg_latency_succ(const void *op, const void *br_op)
05190
05191
05192
05193
05194
05195 {
05196 ARC_LIST *arcs;
05197
05198 for (arcs = OP_succs((OP*) op); arcs; arcs = ARC_LIST_rest(arcs)) {
05199 ARC *arc = ARC_LIST_first(arcs);
05200 if (ARC_succ(arc) != (OP*) br_op &&
05201 ARC_omega(arc) == 0 && ARC_latency(arc) >= 0)
05202 return FALSE;
05203 }
05204 return TRUE;
05205 }
05206
05207 static void maintain_prebr_arc(OP *op)
05208
05209
05210
05211
05212
05213 {
05214 OP *br_op = BB_branch_op(OP_bb(op));
05215 if (br_op != op) {
05216 BOOL needs_prebr_arc =
05217 has_no_0_omega_non_neg_latency_succ((void*) op, (void *) br_op);
05218 ARC_LIST *arcs = ARC_LIST_Find(OP_succs(op), CG_DEP_PREBR, DONT_CARE);
05219 if (needs_prebr_arc && arcs == NULL) {
05220 new_arc(CG_DEP_PREBR, op, br_op, 0, 0, FALSE);
05221 } else if (!needs_prebr_arc && arcs) {
05222 ARC *prebr = ARC_LIST_first(arcs);
05223 detach_arc(prebr);
05224 delete_arc(prebr);
05225 }
05226 }
05227 }
05228
05229
05230
05231
05232
05233
05234 void
05235 CG_DEP_Add_Op_Same_Res_Arcs(OP *op)
05236
05237
05238
05239
05240 {
05241 BB *bb = OP_bb(op);
05242 INT16 which = CGPREP_Same_Res_Opnd(op);
05243 TN *opnd = OP_opnd(op, which);
05244 ARC_LIST *arcs = ARC_LIST_Find(OP_preds(op), CG_DEP_REGIN, which);
05245
05246 Is_True(CG_DEP_Has_Graph(bb),
05247 ("no current CG dep graph for BB:%d", BB_id(bb)));
05248
05249 FmtAssert(which >= 0, ("neither operand of select can be default"));
05250
05251 if (arcs) {
05252 ARC *def_arc = ARC_LIST_first(arcs);
05253 OP *def_op = ARC_pred(def_arc);
05254 Is_True(!ARC_LIST_Find(ARC_LIST_rest(arcs), CG_DEP_REGIN, which),
05255 ("in BB:%d multiple REGIN arcs to opnd %d of OP%d",
05256 BB_id(OP_bb(op)), which, OP_map_idx(op)));
05257 arcs = ARC_LIST_Find(OP_succs(def_op), CG_DEP_REGIN, DONT_CARE);
05258
05259 if (op != def_op) {
05260
05261 make_virtual_anti_or_output_arc(CG_DEP_REGOUT, op, def_op, 0);
05262 make_virtual_anti_or_output_arc(CG_DEP_REGOUT, def_op, op, 0);
05263 }
05264
05265 } else {
05266 arcs = CG_DEP_GTN_Use_Arcs(opnd);
05267 }
05268
05269 while (arcs) {
05270 ARC *arc = ARC_LIST_first(arcs);
05271 OP *use_op = ARC_succ(arc);
05272 UINT8 which = ARC_opnd(arc);
05273 arcs = ARC_LIST_Find(ARC_LIST_rest(arcs), CG_DEP_REGIN, DONT_CARE);
05274 if (use_op != op && (cyclic || OP_Precedes(use_op, op)))
05275 make_virtual_anti_or_output_arc(CG_DEP_REGANTI, use_op, op, which);
05276 }
05277
05278 if (tracing) {
05279 fprintf(TFile, "\n<arc> CG %sdependence graph for BB:%d updated "
05280 "with same-res arcs for:\n", cyclic ? "cyclic " : "",
05281 BB_id(bb));
05282 CG_DEP_Trace_Op_Arcs(op);
05283 }
05284 }
05285
05286 BOOL
05287 CG_DEP_Add_Same_Res_Arcs()
05288
05289
05290
05291
05292
05293 {
05294 Is_True(_cg_dep_bb == NULL,
05295 ("Need to Invoke CG_DEP_Compute_Graph first"));
05296
05297 OP *op;
05298 BOOL any = FALSE;
05299 FOR_ALL_BB_OPs(_cg_dep_bb, op) {
05300 if (OP_same_res(op)) {
05301 any = TRUE;
05302 CG_DEP_Add_Op_Same_Res_Arcs(op);
05303 }
05304 }
05305 return any;
05306 }
05307
05308 void remove_unnecessary_anti_or_output_arcs(ARC_LIST *arcs)
05309
05310
05311
05312
05313
05314
05315 {
05316 while (arcs) {
05317 ARC *arc = ARC_LIST_first(arcs);
05318 CG_DEP_KIND kind = ARC_kind(arc);
05319 arcs = ARC_LIST_rest(arcs);
05320 if (kind == CG_DEP_REGANTI || kind == CG_DEP_REGOUT) {
05321 TN *succ_tn = OP_result(ARC_succ(arc),0 );
05322 OP *pred = ARC_pred(arc);
05323 TN *pred_tn = (kind == CG_DEP_REGOUT) ?
05324 OP_result(pred,0 ) : OP_opnd(pred, ARC_opnd(arc));
05325 if (succ_tn != pred_tn &&
05326 (!has_assigned_reg(succ_tn) || !has_assigned_reg(pred_tn) ||
05327 TN_register(succ_tn) != TN_register(pred_tn) ||
05328 TN_register_class(succ_tn) != TN_register_class(pred_tn))) {
05329 detach_arc(arc);
05330 delete_arc(arc);
05331 }
05332 }
05333 }
05334 }
05335
05336 void
05337 CG_DEP_Remove_Op_Same_Res_Arcs(OP *op)
05338
05339
05340
05341
05342 {
05343 Is_True(OP_same_res(op), ("<op> not a same-res OP"));
05344 remove_unnecessary_anti_or_output_arcs(OP_preds(op));
05345 remove_unnecessary_anti_or_output_arcs(OP_succs(op));
05346 if (tracing) {
05347 fprintf(TFile, "\n<arc> CG %sdependence graph for BB:%d updated "
05348 "by removing same-res arcs for:\n", cyclic ? "cyclic " : "",
05349 BB_id(OP_bb(op)));
05350 CG_DEP_Trace_Op_Arcs(op);
05351 }
05352 }
05353
05354 void
05355 CG_DEP_Remove_Same_Res_Arcs()
05356
05357
05358
05359
05360
05361 {
05362 Is_True(_cg_dep_bb == NULL,
05363 ("Need to Invoke CG_DEP_Compute_Graph first"));
05364
05365 OP *op;
05366 FOR_ALL_BB_OPs(_cg_dep_bb, op) {
05367 if (OP_same_res(op)) CG_DEP_Remove_Op_Same_Res_Arcs(op);
05368 }
05369 }
05370
05371
05372
05373
05374
05375
05376 void
05377 CG_DEP_Set_SCC_ARC_omega(ARC *arc, UINT8 omega)
05378
05379
05380
05381
05382 {
05383 Set_ARC_omega(arc, omega);
05384 }
05385
05386 void
05387 CG_DEP_Add_SCC_Arc(OP *pred, OP *succ, UINT8 omega, INT16 latency,
05388 ARC_LIST **scc_ancestor_list,
05389 ARC_LIST **scc_descendent_list)
05390
05391
05392
05393
05394 {
05395 ARC *arc = create_arc();
05396
05397 Set_ARC_kind(arc, CG_DEP_SCC);
05398 Set_ARC_pred(arc, pred);
05399 Set_ARC_succ(arc, succ);
05400 Set_ARC_omega(arc, omega);
05401 Set_ARC_latency(arc, latency);
05402 Set_ARC_rest_preds(arc, *scc_ancestor_list);
05403 Set_ARC_rest_succs(arc, *scc_descendent_list);
05404
05405 *scc_ancestor_list = arc;
05406 *scc_descendent_list = (ARC_LIST *)((INTPTR)arc | 1);
05407 }
05408
05409 void
05410 CG_DEP_Delete_SCC_Arcs(ARC_LIST *arcs)
05411
05412
05413
05414
05415 {
05416 while (arcs) {
05417 ARC *arc = ARC_LIST_first(arcs);
05418 arcs = ARC_LIST_rest(arcs);
05419 delete_arc(arc);
05420 }
05421 }
05422
05423 BOOL
05424 CG_DEP_Graph_Is_Cyclic(BB *bb)
05425
05426
05427
05428
05429
05430 {
05431 return bb == _cg_dep_bb && cyclic;
05432 }
05433
05434 void
05435 CG_DEP_Delete_Graph(void *item)
05436
05437
05438
05439
05440 {
05441 Is_True(item != NULL,
05442 ("NULL value passed to CG_DEP_Delete_Graph routine"));
05443
05444 Is_True( _cg_dep_bb != NULL || ! _cg_dep_bbs.empty(),
05445 ( "CG_DEP_Delete_Graph: no dep graph currently exists" ) );
05446
05447 delete_gtn_use_arcs();
05448 BB_MAP_Delete(_cg_dep_op_info);
05449
05450 MEM_POOL_Pop(&dep_map_nz_pool);
05451 MEM_POOL_Pop(&dep_nz_pool);
05452 MEM_POOL_Delete(&dep_map_nz_pool);
05453 MEM_POOL_Delete(&dep_nz_pool);
05454
05455 _cg_dep_bb = NULL;
05456 _cg_dep_bbs.clear();
05457
05458 }
05459
05460 #if defined(TARG_IA64) || defined(TARG_SL) || defined(TARG_MIPS)
05461 void
05462 CG_DEP_Delete_DAG(void)
05463
05464
05465
05466
05467 {
05468 delete_gtn_use_arcs();
05469 BB_MAP_Delete(_cg_dep_op_info);
05470
05471 MEM_POOL_Pop(&dep_map_nz_pool);
05472 MEM_POOL_Pop(&dep_nz_pool);
05473 MEM_POOL_Delete(&dep_map_nz_pool);
05474 MEM_POOL_Delete(&dep_nz_pool);
05475 }
05476 #endif
05477
05478
05479
05480
05481
05482 void
05483 Invoke_Init_Routines()
05484 {
05485
05486 MEM_POOL_Initialize(&dep_nz_pool, "CG_Dep_Graph", FALSE);
05487 MEM_POOL_Initialize(&dep_map_nz_pool, "CG_Dep_Graph_BB_OP_MAP", FALSE);
05488 MEM_POOL_Push(&dep_nz_pool);
05489 MEM_POOL_Push(&dep_map_nz_pool);
05490
05491
05492
05493 init_op_info();
05494 init_reg_assignments();
05495 init_arcs();
05496 init_gtn_use_arcs();
05497 maintain_prebr = FALSE;
05498
05499
05500 INT i;
05501 for (i = 0; i < sizeof(dep_info_data) / sizeof(dep_info_data[0]); i++) {
05502 CG_DEP_KIND kind = dep_info_data[i].kind;
05503 dep_info[kind] = dep_info_data + i;
05504 }
05505
05506
05507 _cg_dep_op_info = BB_MAP_Create();
05508 }
05509
05510 static char *multiple_inst = const_cast<char*>("multiple_instance");
05511
05512
05513
05514
05515
05516
05517
05518
05519
05520 static void
05521 Update_Entry_For_TN(
05522 TN *vtn,
05523 OP *cur_op,
05524 TN_MAP vmap,
05525 void *register_ops[ISA_REGISTER_CLASS_MAX+1][REGISTER_MAX+1],
05526 OP_MAP omap,
05527 BOOL is_result)
05528 {
05529
05530
05531 OP *get_op = (OP*) TN_MAP_Get(vmap, vtn);
05532
05533 if (!get_op) {
05534 TN_MAP_Set(vmap, vtn, cur_op);
05535 } else if (get_op != cur_op) {
05536
05537
05538
05539
05540
05541 if (is_result || ((void*) get_op == (void*) multiple_inst) ||
05542 !OP_has_subset_predicate(cur_op, get_op)) {
05543 TN_MAP_Set(vmap, vtn, multiple_inst);
05544 OP_MAP_Set(omap, cur_op, multiple_inst);
05545 }
05546 }
05547
05548
05549 if (TN_register(vtn) != REGISTER_UNDEFINED) {
05550 REGISTER reg = TN_register(vtn);
05551 ISA_REGISTER_CLASS rc = TN_register_class(vtn);
05552 OP *get_op = (OP*) register_ops[rc][reg];
05553
05554 if (get_op == NULL) {
05555 register_ops[rc][reg] = (void*) get_op;
05556 } else if (get_op != cur_op) {
05557
05558
05559
05560
05561
05562 if (is_result || ((void*) get_op == (void*) multiple_inst) ||
05563 !OP_has_subset_predicate(cur_op, get_op)) {
05564 register_ops[rc][reg] = (void*) multiple_inst;
05565 OP_MAP_Set(omap, cur_op, multiple_inst);
05566 }
05567 }
05568 }
05569 }
05570
05571
05572
05573
05574
05575 void
05576 CG_DEP_Prune_Dependence_Arcs(std::list<BB*> bblist,
05577 BOOL prune_predicate_arcs,
05578 BOOL trace)
05579 {
05580 std::list<BB*>::iterator bbi;
05581 TN_MAP tn_usage_map = TN_MAP_Create();
05582 void *reg_ops[ISA_REGISTER_CLASS_MAX+1][REGISTER_MAX+1];
05583 OP_MAP omap = OP_MAP_Create();
05584 bzero(reg_ops, sizeof(reg_ops));
05585
05586
05587
05588
05589 FOR_ALL_BB_STLLIST_ITEMS_FWD(bblist, bbi) {
05590 OP *cur_op;
05591 FOR_ALL_BB_OPs(*bbi, cur_op) {
05592 INT i;
05593 for (i = 0; i < OP_opnds(cur_op); ++i) {
05594 TN *otn = OP_opnd(cur_op, i);
05595 if (TN_is_constant(otn)) continue;
05596 Update_Entry_For_TN(otn, cur_op, tn_usage_map, reg_ops, omap, FALSE);
05597 }
05598
05599 for (i = 0; i < OP_results(cur_op); ++i) {
05600 TN *rtn = OP_result(cur_op, i);
05601 Update_Entry_For_TN(rtn, cur_op, tn_usage_map, reg_ops, omap, TRUE);
05602 }
05603 }
05604 }
05605
05606 if (prune_predicate_arcs) {
05607 FOR_ALL_BB_STLLIST_ITEMS_FWD(bblist, bbi) {
05608 OP *cur_op;
05609
05610 FOR_ALL_BB_OPs(*bbi, cur_op) {
05611
05612
05613 if (OP_MAP_Get(omap, cur_op) == multiple_inst) continue;
05614
05615
05616 if (OP_memory(cur_op) || OP_xfer(cur_op)) continue;
05617
05618 BOOL cond_use = TRUE;
05619 if (OP_has_predicate(cur_op)) {
05620 if (!TN_is_true_pred(OP_opnd(cur_op, OP_PREDICATE_OPND)) &&
05621 CGTARG_Can_Be_Speculative(cur_op)) {
05622
05623 INT i;
05624 cond_use = FALSE;
05625
05626 for (i = 0; i < OP_results(cur_op); ++i) {
05627 TN *result_tn = OP_result(cur_op, i);
05628
05629 BOOL live_out = FALSE;
05630 BOOL live_in = FALSE;
05631
05632
05633
05634
05635
05636
05637
05638 if (Is_Predicate_REGISTER_CLASS( TN_register_class(result_tn)))
05639 { cond_use = TRUE; break; }
05640
05641
05642
05643 if (TN_is_global_reg(result_tn)) {
05644 live_out |= GRA_LIVE_TN_Live_Outof_BB(result_tn, *bbi);
05645 }
05646
05647
05648
05649 if (TN_is_global_reg(result_tn)) {
05650 live_in |= GRA_LIVE_TN_Live_Into_BB(result_tn, *bbi);
05651 }
05652
05653
05654 if (TN_register(result_tn) != REGISTER_UNDEFINED) {
05655 ISA_REGISTER_CLASS result_cl = TN_register_class (result_tn);
05656 REGISTER result_reg = TN_register (result_tn);
05657 live_out |= REG_LIVE_Outof_BB (result_cl, result_reg, *bbi);
05658
05659 if (reg_ops[result_cl][result_reg] == multiple_inst)
05660 { cond_use = TRUE; break; }
05661
05662 }
05663
05664
05665
05666
05667 if (live_in ||
05668 live_out ||
05669 (TN_MAP_Get(tn_usage_map, result_tn) == multiple_inst))
05670 { cond_use = TRUE; break;}
05671
05672 }
05673
05674
05675
05676
05677 for (i = 0; i < OP_opnds(cur_op); ++i) {
05678 TN *opnd_tn = OP_opnd(cur_op, i);
05679 if (TN_is_constant(opnd_tn)) continue;
05680 OP *defop = (OP *) TN_MAP_Get(tn_usage_map, opnd_tn);
05681
05682
05683
05684 if (defop && ((void *) defop != (void *) multiple_inst) &&
05685 OP_has_predicate(defop)) {
05686 if (!TN_is_true_pred(OP_opnd(defop, OP_PREDICATE_OPND)))
05687 { cond_use = TRUE; break; }
05688 }
05689 }
05690 }
05691
05692
05693
05694
05695
05696 if (!cond_use) {
05697 #ifdef Is_True_On
05698
05699 {
05700 TN *pred = OP_opnd(cur_op, OP_PREDICATE_OPND);
05701 BOOL pred_modified = FALSE;
05702 for (OP *op = OP_next(cur_op); op != NULL; op = OP_next(op)) {
05703 if (pred_modified) {
05704 for (INT i = 0; i < OP_results(cur_op); ++i) {
05705 TN *result_tn = OP_result(cur_op, i);
05706 Is_True(!OP_Refs_TN(op, result_tn),
05707 ("CG_DEP_Prune_Dependence_Arcs: predicate TN modified"));
05708 }
05709 } else {
05710 if (!TN_is_true_pred(pred) && OP_Defs_TN(op, pred))
05711 pred_modified = TRUE;
05712 }
05713 }
05714 }
05715 #endif
05716 Set_OP_opnd(cur_op, OP_PREDICATE_OPND, True_TN);
05717 Set_OP_cond_def_kind(cur_op, OP_ALWAYS_UNC_DEF);
05718 if (trace) {
05719 fprintf(TFile, "<pred promotion> ");
05720 Print_OP_No_SrcLine(cur_op);
05721 }
05722 }
05723 }
05724 }
05725 }
05726 }
05727
05728 TN_MAP_Delete(tn_usage_map);
05729 OP_MAP_Delete(omap);
05730 }
05731
05732
05733
05734
05735
05736 void
05737 CG_DEP_Compute_Graph(BB *bb,
05738 BOOL assigned_regs,
05739 BOOL compute_cyclic,
05740 BOOL memread_arcs,
05741 BOOL memin_arcs,
05742 BOOL control_arcs,
05743 TN_SET *need_anti_out_dep)
05744 {
05745 Is_True(BB_rid(bb) == NULL || RID_level(BB_rid(bb)) < RL_CGSCHED
05746 #if defined(TARG_SL)
05747 || RID_TYPE_major(BB_rid(bb)) || RID_TYPE_minor(BB_rid(bb))
05748 #endif
05749 ,
05750 ("cannot compute dep graph for SWP replication BB:%d", BB_id(bb)));
05751
05752 tracing = Get_Trace(TP_CG, 1);
05753
05754
05755 Is_True( _cg_dep_bb == NULL && _cg_dep_bbs.empty(),
05756 ( "CG_DEP_Compute_Graph: another dep graph currently exists" ) );
05757 _cg_dep_bb = bb;
05758
05759 include_assigned_registers = assigned_regs;
05760 cyclic = compute_cyclic;
05761 include_memread_arcs = memread_arcs;
05762 include_memin_arcs = memin_arcs;
05763 include_control_arcs = control_arcs;
05764
05765 Invoke_Init_Routines();
05766
05767 Compute_BB_Graph(_cg_dep_bb, need_anti_out_dep);
05768
05769 if (tracing) CG_DEP_Trace_Graph(_cg_dep_bb);
05770 }
05771
05772
05773
05774
05775
05776 void
05777 CG_DEP_Compute_Region_Graph(std::list<BB*> bb_region,
05778 BOOL assigned_regs,
05779 BOOL memread_arcs,
05780 BOOL control_arcs)
05781 {
05782 tracing = Get_Trace(TP_CG, 1);
05783
05784 Is_True( _cg_dep_bb == NULL && _cg_dep_bbs.empty(),
05785 ( "CG_DEP_Compute_Region_Graph:"
05786 " another dep graph currently exists" ) );
05787 _cg_dep_bbs = bb_region;
05788
05789 include_assigned_registers = assigned_regs;
05790 cyclic = FALSE;
05791 include_memread_arcs = memread_arcs;
05792 include_control_arcs = control_arcs;
05793
05794 Invoke_Init_Routines();
05795
05796 Compute_Region_Graph(_cg_dep_bbs);
05797 if (tracing) {
05798 CG_DEP_Trace_HB_Graph(_cg_dep_bbs);
05799 }
05800 }
05801
05802 #if defined(TARG_IA64) || defined(TARG_SL) || defined(TARG_MIPS)
05803 OP* get_def_op(OP* op , CG_DEP_KIND kind, UINT8 opnd)
05804
05805
05806
05807 {
05808 BB* bb=OP_bb(op);
05809 OP *def_op=NULL;
05810
05811 ARC_LIST *list = OP_preds(op);
05812 mUINT16 max_op_order=0;
05813 OP* nearest_op=NULL;
05814
05815 for (; list; list = ARC_LIST_rest(list)) {
05816 ARC *arc = ARC_LIST_first(list);
05817 if ( ARC_kind(arc) == kind && ARC_opnd(arc)==opnd ) {
05818 def_op = ARC_pred(arc);
05819 if (def_op->order > max_op_order ) {
05820 max_op_order = def_op->order;
05821 nearest_op = def_op;
05822 }
05823 }
05824 }
05825
05826 if (nearest_op==NULL || nearest_op==op || OP_bb(nearest_op) != bb) return NULL;
05827 else {
05828
05829 #if defined(TARG_IA64)
05830 if (OP_code(nearest_op)==TOP_mov) {
05831 def_op = nearest_op;
05832
05833 list = OP_preds(def_op);
05834 max_op_order=0; nearest_op=NULL;
05835 for (; list; list = ARC_LIST_rest(list)) {
05836 ARC *arc = ARC_LIST_first(list);
05837 if ( ARC_kind(arc) == CG_DEP_REGIN && ARC_opnd(arc)==1 ) {
05838 def_op = ARC_pred(arc);
05839 if (def_op->order > max_op_order ) {
05840 max_op_order = def_op->order;
05841 nearest_op = def_op;
05842 }
05843 }
05844 }
05845 if (nearest_op==NULL || nearest_op==op || OP_bb(nearest_op) != bb) return NULL;
05846 else return nearest_op ;
05847
05848 }
05849 else return nearest_op;
05850 #else
05851 return nearest_op;
05852 #endif // TARG_IA64
05853 }
05854
05855 return NULL;
05856 }
05857
05858 BOOL similar_ops(OP * op1 , OP* op2)
05859
05860
05861 {
05862 if ( ( OP_iadd(op1) ||OP_isub(op1)||OP_imul(op1)||OP_idiv(op1) ) && \
05863 OP_code(op1)==OP_code(op2)
05864 ) return TRUE;
05865 else
05866 return FALSE;
05867 }
05868
05869 TN* get_const_tn(OP* op)
05870 {
05871 TN* tn1 = OP_opnd(op, 1);
05872 TN* tn2 = OP_opnd(op, 2);
05873 if (TN_is_constant(tn1)) {
05874 return tn1;
05875 }
05876 else if (TN_is_constant(tn2)) {
05877 return tn2;
05878 }
05879 else {
05880 return NULL;
05881 }
05882 }
05883
05884 UINT get_var_tn_idx(OP* op)
05885 {
05886 TN* tn1 = OP_opnd(op, 1);
05887 TN* tn2 = OP_opnd(op, 2);
05888 if (TN_is_constant(tn1)) {
05889 return 2;
05890 }
05891 else if (TN_is_constant(tn2)) {
05892 return 1;
05893 }
05894 else {
05895 return 0;
05896 }
05897 }
05898
05899 BOOL get_definite_alias_info(OP *pred_op, OP *succ_op)
05900
05901
05902 {
05903 #if defined(TARG_SL)
05904 if (OP_code(pred_op) == TOP_asm || OP_code(succ_op) == TOP_asm)
05905 return TRUE;
05906
05907 if(OP_code(pred_op) == TOP_c2_joint || OP_code(succ_op) == TOP_c2_joint)
05908 return TRUE;
05909 #endif
05910
05911 Is_True((OP_load(pred_op) || OP_like_store(pred_op)) &&
05912 (OP_load(succ_op) || OP_like_store(succ_op)) ,
05913 ("not a load or store"));
05914
05915 if (OP_like_store (pred_op) && !OP_store (pred_op) ||
05916 OP_like_store (succ_op) && !OP_store (succ_op)) {
05917 return FALSE;
05918 }
05919
05920 BB* pred_bb = OP_bb(pred_op);
05921 BB* succ_bb = OP_bb(succ_op);
05922
05923
05924 INT pred_op_base_num = OP_find_opnd_use (pred_op, OU_base);
05925 INT succ_op_base_num = OP_find_opnd_use (succ_op, OU_base);
05926
05927 TN* pred_op_base_tn = OP_opnd(pred_op, pred_op_base_num);
05928 TN* succ_op_base_tn = OP_opnd(succ_op, succ_op_base_num);
05929
05930
05931
05932
05933
05934
05935
05936
05937 OP *def_of_pred_op = get_def_op(pred_op, CG_DEP_REGIN, pred_op_base_num);
05938 OP *def_of_succ_op = get_def_op(succ_op, CG_DEP_REGIN, succ_op_base_num);
05939
05940
05941 UINT pred_op_opnd_idx = pred_op_base_num;
05942 UINT succ_op_opnd_idx = succ_op_base_num;
05943
05944 for ( ; (def_of_pred_op != NULL) && (def_of_succ_op != NULL) ;
05945 def_of_pred_op = get_def_op(def_of_pred_op,CG_DEP_REGIN,pred_op_opnd_idx) ,
05946 def_of_succ_op = get_def_op(def_of_succ_op,CG_DEP_REGIN,succ_op_opnd_idx) ) {
05947
05948
05949 if ( OP_code(def_of_pred_op) != OP_code(def_of_succ_op) )return FALSE ;
05950
05951
05952 if ( OP_load(def_of_pred_op) && OP_load(def_of_succ_op) ) {
05953 if ( OP_opnd(def_of_pred_op, OP_find_opnd_use (def_of_pred_op, OU_base)) == \
05954 OP_opnd(def_of_succ_op, OP_find_opnd_use (def_of_succ_op, OU_base))
05955 ){
05956 return TRUE;
05957 }
05958 else
05959 return FALSE;
05960 }
05961
05962
05963 if ( similar_ops(def_of_pred_op,def_of_succ_op) ) {
05964 TN* pred_const_tn = get_const_tn(def_of_pred_op);
05965 TN* succ_const_tn = get_const_tn(def_of_succ_op);
05966 if ( (pred_const_tn != NULL ) && (succ_const_tn!=NULL) && \
05967 ( TN_value(pred_const_tn)==TN_value(succ_const_tn) )
05968 ) {
05969
05970 pred_op_opnd_idx = get_var_tn_idx(def_of_pred_op);
05971 succ_op_opnd_idx = get_var_tn_idx(def_of_succ_op);
05972 continue;
05973
05974 }
05975 else
05976 return FALSE;
05977
05978 }
05979
05980 }
05981
05982 return FALSE;
05983 }
05984
05985 void
05986 DAG_BUILDER::Build_Mem_Arcs(OP *op)
05987 {
05988 UINT16 s, num_definite_arcs = 0;
05989 ARC *shortest = NULL, *shortest_to_store = NULL;
05990 BOOL found_definite_memread_succ = FALSE;
05991
05992
05993 for (OPs::iterator ops_iter = _bb_ops_map[OP_bb(op)].begin();
05994 ops_iter != _bb_ops_map[OP_bb(op)].end();
05995 ops_iter++) {
05996 if (!(OP_load(*ops_iter) || OP_like_store(*ops_iter))) {
05997 continue;
05998 }
05999
06000 BOOL definite, have_latency = FALSE;
06001 UINT8 omega = 0;
06002 OP *pred = *ops_iter;
06003 ARC *arc;
06004 INT16 latency;
06005 CG_DEP_KIND kind = OP_load(pred) ?
06006 (OP_load(op) ? CG_DEP_MEMREAD : CG_DEP_MEMANTI) :
06007 (OP_load(op) ? CG_DEP_MEMIN : CG_DEP_MEMOUT);
06008
06009 if (kind == CG_DEP_MEMREAD &&
06010 OP_volatile(pred) && OP_volatile(op)) kind = CG_DEP_MEMVOL;
06011
06012 #if defined(TARG_SL)
06013 if (kind == CG_DEP_MEMOUT && OP_code(op) == TOP_asm) kind = CG_DEP_MEMVOL;
06014 #endif
06015
06016 if (kind == CG_DEP_MEMREAD && !_include_memread_arcs
06017 #if defined(TARG_IA64)
06018 && !Cache_Has_Conflict(pred,op,kind)
06019 #endif
06020 )
06021 continue;
06022
06023 if (!_cyclic && CG_DEP_Mem_Arc_Pruning >= PRUNE_NON_CYCLIC ||
06024 _cyclic && omega == 0 && CG_DEP_Mem_Arc_Pruning >= PRUNE_CYCLIC_0) {
06025 if (kind == CG_DEP_MEMREAD) {
06026
06027 if (found_definite_memread_succ) continue;
06028
06029 latency = 0;
06030 } else {
06031 latency = CG_DEP_Latency(pred, op, kind, 0);
06032 }
06033 have_latency = TRUE;
06034 }
06035
06036 if (get_mem_dep(pred, op, &definite, _cyclic ? &omega : NULL) ||
06037 (kind == CG_DEP_MEMREAD
06038 #if defined(TARG_IA64)
06039 && Cache_Has_Conflict(pred,op,kind)
06040 #endif
06041 )) {
06042
06043
06044
06045
06046
06047 if (!have_latency) latency =
06048 (CG_DEP_Adjust_OOO_Latency && PROC_is_out_of_order() && !definite) ?
06049 0 : CG_DEP_Latency(pred, op, kind, 0);
06050
06051 #if defined(TARG_IA64)
06052 if (omega == 0)
06053 Cache_Adjust_Latency(pred,op,kind, &latency);
06054 #endif
06055 if(!definite) {
06056 definite = get_definite_alias_info(pred, op);
06057 }
06058
06059
06060 arc = new_arc_with_latency(kind, pred, op, latency, omega, 0, definite);
06061
06062
06063
06064
06065
06066 if (!CGTARG_Is_OP_Check_Load(op) &&
06067 kind == CG_DEP_MEMIN && !definite && !_include_memin_arcs) {
06068
06069
06070
06071
06072
06073
06074 if ((!OP_volatile (pred) || !OP_volatile(op))
06075 #if !defined(TARG_SL) && !defined(TARG_MIPS)
06076 && !OP_asm(pred)
06077 #endif
06078 ) {
06079 Set_ARC_is_dotted(arc, TRUE);
06080 _num_data_spec_arcs++;
06081 }
06082 }
06083
06084 found_definite_memread_succ |= (kind == CG_DEP_MEMREAD && definite);
06085 }
06086 }
06087 }
06088
06089 void
06090 DAG_BUILDER::Build_Branch_Arcs(OP* op, BOOL include_latency)
06091 {
06092 ARC *arc;
06093
06094 for (OPs::iterator ops_iter = _bb_ops_map[OP_bb(op)].begin();
06095 ops_iter != _bb_ops_map[OP_bb(op)].end();
06096 ops_iter++) {
06097 OP* xfer_op = *ops_iter;
06098
06099 if (OP_xfer(xfer_op) &&
06100 OP_bb(xfer_op) != OP_bb(op) &&
06101 is_xfer_depndnce_reqd(op, xfer_op)) {
06102 if (include_latency) {
06103 arc = new_arc_with_latency(CG_DEP_POSTBR, xfer_op, op, 0,0,0, FALSE);
06104 } else {
06105 arc = new_arc(CG_DEP_POSTBR, xfer_op, op, 0, 0, FALSE);
06106 }
06107
06108 if (Is_Control_Speculative(xfer_op, op)) {
06109 Set_ARC_is_dotted(arc, TRUE);
06110 _num_cntl_spec_arcs++;
06111 }
06112 }
06113 }
06114
06115
06116 OP* xfer_op = BB_xfer_op(OP_bb(op));
06117
06118 if (xfer_op && op != xfer_op) {
06119 if (include_latency) {
06120 arc = new_arc_with_latency(CG_DEP_PREBR, op, xfer_op, 0,0,0, FALSE);
06121 } else {
06122 arc = new_arc(CG_DEP_PREBR, op, xfer_op, 0, 0, FALSE);
06123 }
06124 }
06125 }
06126
06127 void
06128 DAG_BUILDER::Build_Misc_Arcs(OP* op)
06129 {
06130 for (OPs::iterator ops_iter = _bb_ops_map[OP_bb(op)].begin();
06131 ops_iter != _bb_ops_map[OP_bb(op)].end();
06132 ops_iter++) {
06133 if (CGTARG_Dependence_Required(*ops_iter, op)) {
06134 new_arc(CG_DEP_MISC, *ops_iter, op, 0, 0, FALSE);
06135 }
06136
06137
06138
06139
06140 if (CG_DEP_Add_Alloca_Arcs &&
06141 op_defines_sp(op) &&
06142 CG_DEP_Alloca_Aliases(*ops_iter)) {
06143 new_arc(CG_DEP_MISC, *ops_iter, op, 0, 0, FALSE);
06144 }
06145 }
06146 }
06147
06148 void
06149 DAG_BUILDER::Build_Reg_Arcs(OP* op)
06150 {
06151 INT32 i;
06152
06153 TN * tn_ptr = OP_opnd (op, OP_PREDICATE_OPND);
06154
06155
06156
06157
06158
06159 for (i = 0; i < OP_opnds(op); i++) {
06160
06161 #ifndef DAG_BITSET_SWITCH_ON
06162
06163 OPs& def_ops = Get_Def_Use_OPs(op, i, CG_DEP_REGIN);
06164
06165 for (OPs::iterator ops_iter = def_ops.begin();
06166 ops_iter != def_ops.end();
06167 ops_iter++) {
06168
06169 #else
06170
06171 Get_Define_OPs(op, i, CG_DEP_REGIN);
06172 for(DEFINE_OPS_ITER ops_iter=_Define_OPs.begin();
06173 ops_iter!=_Define_OPs.end();
06174 ops_iter++ ){
06175
06176 #endif
06177
06178
06179
06180
06181
06182
06183
06184
06185 if (!OP_has_disjoint_predicate(*ops_iter, op)) {
06186 #if defined(TARG_IA64)
06187 if(i == OP_PREDICATE_OPND) {
06188 ARC *arc_ptr = new_arc(CG_DEP_CTLSPEC, *ops_iter, op, 0, i, FALSE);
06189 Set_ARC_is_dotted (arc_ptr, TRUE);
06190 } else
06191 #endif
06192 ARC *arc_ptr = new_arc(CG_DEP_REGIN, *ops_iter, op, 0, i, FALSE);
06193 }
06194 }
06195 }
06196
06197
06198
06199
06200
06201
06202 for (i = 0; i < OP_results(op); i++) {
06203
06204 #ifndef DAG_BITSET_SWITCH_ON
06205
06206 OPs& prev_def_ops = Get_Def_Use_OPs(op, i, CG_DEP_REGOUT);
06207
06208 for (OPs::iterator ops_iter = prev_def_ops.begin();
06209 ops_iter != prev_def_ops.end();
06210 ops_iter++) {
06211
06212 #else
06213
06214 Get_Define_OPs(op, i, CG_DEP_REGOUT);
06215 for(DEFINE_OPS_ITER ops_iter=_Define_OPs.begin();
06216 ops_iter!=_Define_OPs.end();
06217 ops_iter++ ){
06218
06219 #endif
06220
06221
06222
06223
06224 if (!OP_has_disjoint_predicate(*ops_iter, op)) {
06225 new_arc(CG_DEP_REGOUT, *ops_iter, op, 0, 0, FALSE);
06226 }
06227 }
06228 }
06229
06230
06231
06232
06233
06234
06235 #ifndef DAG_BITSET_SWITCH_ON
06236
06237 for(i = 0; i < OP_results(op); i++){
06238 OPs& use_ops = Get_Def_Use_OPs(op, i, CG_DEP_REGANTI);
06239 for (OPs::iterator ops_iter = use_ops.begin();
06240 ops_iter != use_ops.end();
06241 ops_iter++) {
06242
06243 BOOL tn_def_found = FALSE;
06244
06245
06246
06247
06248 TN * tn = OP_result(op,i) ;
06249 if (TN_is_register(tn) && TN_register_class(tn) ==
06250 ISA_REGISTER_CLASS_predicate) {
06251 tn_def_found = TRUE;
06252 INT16 opnd_idx = get_opnd_idx (*ops_iter,tn);
06253 Is_True (opnd_idx >= 0, ("fail to find opnd!"));
06254 new_arc(CG_DEP_REGANTI, *ops_iter, op, 0, (UINT8)opnd_idx, FALSE);
06255 }
06256 else{
06257
06258 if (!OP_has_disjoint_predicate(*ops_iter, op)) {
06259 tn_def_found = TRUE;
06260
06261 INT16 opnd_idx = get_opnd_idx (*ops_iter,tn);
06262 Is_True (opnd_idx >= 0, ("fail to find opnd!"));
06263 ARC * arc = new_arc(CG_DEP_REGANTI, *ops_iter, op, 0,
06264 (UINT8)opnd_idx, FALSE);
06265 adjust_reganti_latency (arc) ;
06266 }
06267 }
06268 }
06269 }
06270
06271 #else // defined DAG_BITSET_SWITCH_ON
06272
06273 for(i = 0; i < OP_opnds(op); i++){
06274
06275 Get_Define_OPs(op, i, CG_DEP_REGANTI);
06276 for(DEFINE_OPS_ITER ops_iter=_Define_OPs.begin();
06277 ops_iter!=_Define_OPs.end();
06278 ops_iter++ ){
06279
06280
06281
06282 BOOL OUT = FALSE;
06283 for(INT32 j = 0; (j < OP_results(*ops_iter)) && (OUT==FALSE); j++){
06284
06285 BOOL tn_def_found = FALSE;
06286
06287 #if defined(TARG_IA64)
06288
06289 TN * tn = OP_result(*ops_iter,j) ;
06290 if (TN_is_register(tn) && TN_register_class(tn) ==
06291 ISA_REGISTER_CLASS_predicate) {
06292 tn_def_found = TRUE;
06293
06294 new_arc(CG_DEP_REGANTI, op, *ops_iter, 0, (UINT8)i, FALSE);
06295 OUT = TRUE;
06296
06297 }
06298 else{
06299
06300 if (!_prdb ||!OP_has_predicate(op) ||!OP_has_predicate(*ops_iter)||
06301 (_prdb && !_prdb->Partition_Graph(Home_Region(OP_bb(op)))->Is_Disjoint(
06302 TN_OP_PAIR(OP_opnd(op, OP_PREDICATE_OPND),op),
06303 TN_OP_PAIR(OP_opnd(*ops_iter, OP_PREDICATE_OPND),*ops_iter)))) {
06304 tn_def_found = TRUE;
06305
06306 ARC * arc = new_arc(CG_DEP_REGANTI, op, *ops_iter, 0, (UINT8)i, FALSE);
06307 OUT = TRUE;
06308 adjust_reganti_latency (arc) ;
06309 }
06310 }
06311 #else
06312 ARC * arc = new_arc(CG_DEP_REGANTI, op, *ops_iter, 0, (UINT8)i, FALSE);
06313 OUT = TRUE;
06314 adjust_reganti_latency (arc) ;
06315 #endif
06316 }
06317 }
06318 }
06319
06320 #endif // end of #ifndef DAG_BITSET_SWITCH_ON
06321
06322
06323 }
06324 #endif