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 #include <stdint.h>
00049
00050 #define USE_STANDARD_TYPES
00051 #include <map>
00052 #include "defs.h"
00053 #include "mempool.h"
00054 #include "tn.h"
00055 #include "tn_set.h"
00056 #include "bb.h"
00057 #include "op.h"
00058 #include "op_list.h"
00059 #include "op_map.h"
00060 #include "cgexp.h"
00061 #include "cgtarget.h"
00062 #include "register.h"
00063 #include "cg_loop.h"
00064 #include "cg_swp_options.h"
00065 #include "cg_swp.h"
00066 #include "cg_swp_target.h"
00067 #include "tracing.h"
00068 #include "pf_cg.h"
00069 #include "cg_loop.h"
00070 #include "calls.h"
00071 #include "tag.h"
00072 #include "targ_issue_port.h"
00073
00074
00075
00076
00077
00078
00079
00080 void Gen_SWP_Branch(CG_LOOP &cl, bool is_doloop)
00081 {
00082 BB *body = cl.Loop_header();
00083 OP *br_op = BB_branch_op(body);
00084 TN *label_tn = OP_opnd(br_op, Branch_Target_Operand(br_op));
00085 OPS ops = OPS_EMPTY;
00086 OP *op;
00087 TN *ar_ec = Build_Dedicated_TN ( ISA_REGISTER_CLASS_application,
00088 (REGISTER)(REGISTER_MIN + 66),
00089 8);
00090
00091 if (is_doloop) {
00092
00093
00094
00095 if(PROCESSOR_Version == 2)
00096 Build_OP (TOP_br_ctop,
00097 ar_ec, LC_TN,
00098 Gen_Enum_TN(ECV_bwh_sptk),
00099 Gen_Enum_TN(ECV_ph_few),
00100 Gen_Enum_TN(ECV_dh),
00101 label_tn,
00102 ar_ec, LC_TN, &ops);
00103 else
00104 Build_OP (TOP_br_ctop,
00105 ar_ec, LC_TN,
00106 Gen_Enum_TN(ECV_bwh_dptk),
00107 Gen_Enum_TN(ECV_ph_few),
00108 Gen_Enum_TN(ECV_dh),
00109 label_tn,
00110 ar_ec, LC_TN, &ops);
00111
00112 Is_True(OP_code(br_op) == TOP_br_cloop,
00113 ("Gen_SWP_Branch: SWP doloop must use TOP_br_cloop."));
00114 LC_Used_In_PU = TRUE;
00115
00116 } else {
00117
00118 TN *predicate = OP_opnd(br_op, OP_PREDICATE_OPND);
00119
00120 Build_OP (TOP_br_wtop,
00121 ar_ec,
00122 predicate,
00123 Gen_Enum_TN(ECV_bwh_dptk),
00124 Gen_Enum_TN(ECV_ph_few),
00125 Gen_Enum_TN(ECV_dh),
00126 label_tn,
00127 ar_ec, &ops);
00128
00129 Is_True(OP_code(br_op) == TOP_br_cond,
00130 ("Gen_SWP_Branch: SWP whileloop must use TOP_br."));
00131
00132 }
00133
00134 op = OPS_last(&ops);
00135 Set_OP_Tag (op, Gen_Tag());
00136
00137 BB_Remove_Op(body, br_op);
00138 BB_Append_Ops(body, &ops);
00139 }
00140
00141
00142
00143
00144
00145
00146
00147 void Gen_SWP_Branch_Predict(BB *body, BB *prolog, BB *epilog)
00148 {
00149
00150
00151
00152
00153 OPS prolog_ops = OPS_EMPTY;
00154 OP *br_op = BB_branch_op(body);
00155
00156 TN *dest_label = OP_opnd(br_op, Branch_Target_Operand(br_op));
00157
00158 TN *src_label = Gen_Tag_TN (Get_OP_Tag (br_op));
00159
00160 Build_OP(TOP_brp,
00161 Gen_Enum_TN(ECV_ipwh_loop),
00162 Gen_Enum_TN(ECV_ih_imp),
00163 dest_label,
00164 src_label,
00165 &prolog_ops);
00166
00167 BB_Prepend_Ops(prolog, &prolog_ops);
00168 }
00169
00170
00171
00172
00173
00174
00175
00176 void Undo_SWP_Branch(CG_LOOP &cl, bool is_doloop)
00177 {
00178 BB *body = cl.Loop_header();
00179 OP *br_op = BB_branch_op(body);
00180 TN *label_tn = OP_opnd(br_op, Branch_Target_Operand(br_op));
00181 OPS ops = OPS_EMPTY;
00182
00183 if (is_doloop) {
00184
00185
00186
00187 if(PROCESSOR_Version == 2)
00188 Build_OP (TOP_br_cloop,
00189 LC_TN,
00190 Gen_Enum_TN(ECV_bwh_sptk),
00191 Gen_Enum_TN(ECV_ph_few),
00192 Gen_Enum_TN(ECV_dh),
00193 label_tn,
00194 LC_TN, &ops);
00195 else
00196 Build_OP (TOP_br_cloop,
00197 LC_TN,
00198 Gen_Enum_TN(ECV_bwh_dptk),
00199 Gen_Enum_TN(ECV_ph_few),
00200 Gen_Enum_TN(ECV_dh),
00201 label_tn,
00202 LC_TN, &ops);
00203
00204
00205 Is_True(OP_code(br_op) == TOP_br_ctop,
00206 ("Undo_SWP_Branch: SWP doloop must use TOP_br_ctop."));
00207 LC_Used_In_PU = TRUE;
00208
00209 } else {
00210
00211 TN *predicate = OP_opnd(br_op, OP_PREDICATE_OPND);
00212
00213 Build_OP (TOP_br_cond,
00214 predicate,
00215 Gen_Enum_TN(ECV_bwh_dptk),
00216 Gen_Enum_TN(ECV_ph_few),
00217 Gen_Enum_TN(ECV_dh),
00218 label_tn, &ops);
00219
00220 Is_True(OP_code(br_op) == TOP_br_wtop,
00221 ("Undo_SWP_Branch: SWP whileloop must use TOP_br_wtop."));
00222
00223 }
00224
00225 BB_Remove_Op(body, br_op);
00226 BB_Append_Ops(body, &ops);
00227
00228 CG_LOOP_Init_Op(BB_branch_op(body));
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 void
00240 SWP_Loop_Init_Fini(bool is_doloop,
00241 INT stage_count,
00242 OPS *prolog_ops,
00243 OPS *body_ops,
00244 OPS *epilog_ops)
00245 {
00246
00247
00248 INT tn_size = 4;
00249
00250 TN *ar_ec = Build_Dedicated_TN ( ISA_REGISTER_CLASS_application,
00251 (REGISTER)(REGISTER_MIN + 66),
00252 8);
00253
00254 TN *epilog_count = Gen_Literal_TN(stage_count, tn_size);
00255
00256 const ISA_OPERAND_INFO *oinfo;
00257 oinfo = ISA_OPERAND_Info(TOP_mov_t_ar_i_i);
00258 const ISA_OPERAND_VALTYP *vtype = ISA_OPERAND_INFO_Operand(oinfo, 1);
00259 ISA_LIT_CLASS lc = ISA_OPERAND_VALTYP_Literal_Class(vtype);
00260 if (ISA_LC_Value_In_Class(stage_count, lc)){
00261 Build_OP (TOP_mov_t_ar_i_i, ar_ec, True_TN, epilog_count, prolog_ops);
00262 }
00263 else{
00264 TN *tmp_tn = Gen_Register_TN (ISA_REGISTER_CLASS_integer, tn_size);
00265 Exp_COPY(tmp_tn, epilog_count, prolog_ops);
00266 Exp_COPY(ar_ec, tmp_tn, prolog_ops);
00267 }
00268
00269
00270 Build_OP(TOP_clrrrb_pr, prolog_ops);
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 TN *pr_mask = Gen_Literal_TN(is_doloop ? 1 << 16: 0, 4);
00284 Build_OP(TOP_mov_t_pr_i,
00285 True_TN,
00286 pr_mask,
00287 prolog_ops);
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297 void SWP_Exp_COPY(TN *result, TN *opnd, OPS *ops)
00298 {
00299 if (TN_register_class(result) == ISA_REGISTER_CLASS_predicate) {
00300 if (opnd == True_TN) {
00301 Build_OP (TOP_cmp_i_eq, result, True_TN,
00302 True_TN, Gen_Literal_TN(0, 4), Zero_TN, ops);
00303 return;
00304 }
00305 }
00306 Exp_COPY(result, opnd, ops);
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 INT32 SWP_Max_Slots_Per_Cycle()
00319 {
00320
00321 return 6;
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331 void Remove_Invariant_Predicates(CG_LOOP& cl, bool trace)
00332 {
00333 BB *prolog = cl.Prolog_end();
00334 BB *body = cl.Loop_header();
00335 CXX_MEM_POOL pool("Temp TN_SET", FALSE);
00336
00337 TN_SET *predicate_tn_defs = TN_SET_Create_Empty(Last_TN + 1, pool());
00338
00339
00340
00341 OP *op;
00342 FOR_ALL_BB_OPs(body, op) {
00343 for (INT i = 0; i < OP_results(op); i++) {
00344 TN *tn = OP_result(op, i);
00345 if (TN_is_register(tn) &&
00346 !TN_is_dedicated(tn) &&
00347 TN_register_class(tn) == ISA_REGISTER_CLASS_predicate)
00348 predicate_tn_defs = TN_SET_Union1D(predicate_tn_defs, tn, pool());
00349 }
00350 }
00351
00352
00353
00354
00355 std::map<TN*, TN*> tn_map;
00356 OPS prolog_ops = OPS_EMPTY;
00357 OPS body_ops = OPS_EMPTY;
00358 FOR_ALL_BB_OPs(body, op) {
00359 if (OP_has_predicate(op)) {
00360 TN *predicate_tn = OP_opnd(op, OP_PREDICATE_OPND);
00361 if (!TN_is_dedicated(predicate_tn) &&
00362 !TN_SET_MemberP(predicate_tn_defs, predicate_tn)) {
00363 TN *new_tn;
00364 if (tn_map.find(predicate_tn) == tn_map.end()) {
00365
00366 new_tn = Dup_TN(predicate_tn);
00367 tn_map[predicate_tn] = new_tn;
00368 TN *int_tn = Build_TN_Of_Mtype(MTYPE_I4);
00369
00370
00371
00372
00373 Build_OP(TOP_adds,
00374 int_tn,
00375 True_TN,
00376 Gen_Literal_TN(0, 4),
00377 Zero_TN,
00378 &prolog_ops);
00379 Build_OP(TOP_adds,
00380 int_tn,
00381 predicate_tn,
00382 Gen_Literal_TN(1, 4),
00383 Zero_TN,
00384 &prolog_ops);
00385 Build_OP(TOP_cmp_i_ne,
00386 new_tn,
00387 True_TN,
00388 True_TN,
00389 Gen_Literal_TN(0, 4), int_tn,
00390 &body_ops);
00391
00392 if (trace)
00393 fprintf(TFile, "Remove_Invariant_Predicates: TN%d\n",
00394 TN_number(predicate_tn));
00395 } else
00396 new_tn = tn_map[predicate_tn];
00397 Set_OP_opnd(op, OP_PREDICATE_OPND, new_tn);
00398 }
00399 }
00400 }
00401 BB_Append_Ops(prolog, &prolog_ops);
00402 BB_Prepend_Ops(body, &body_ops);
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412 void Unc_Promotion(CG_LOOP& cl, bool trace)
00413 {
00414 BB *prolog = cl.Prolog_end();
00415 BB *body = cl.Loop_header();
00416 CXX_MEM_POOL pool("Temp TN_SET", FALSE);
00417
00418 OP *op;
00419 FOR_ALL_BB_OPs(body, op) {
00420 if (OP_has_predicate(op) &&
00421 !OP_cond_def(op)) {
00422
00423
00424 TOP unc_top = CGTARG_Get_unc_Variant(OP_code(op));
00425 if (unc_top != TOP_UNDEFINED && unc_top != OP_code(op)) {
00426 OP_Change_Opcode(op, unc_top);
00427 CGTARG_Init_OP_cond_def_kind(op);
00428 }
00429 }
00430 }
00431 }
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 void Hoist_MOVL(CG_LOOP& cl, bool trace)
00443 {
00444 BB *prolog = cl.Prolog_end();
00445 BB *body = cl.Loop_header();
00446
00447
00448 std::vector<OP*> movl_ops;
00449
00450 OP *op;
00451 FOR_ALL_BB_OPs(body, op) {
00452 if (OP_code(op) == TOP_movl)
00453 movl_ops.push_back(op);
00454 }
00455
00456 for (INT i = 0; i < movl_ops.size(); i++) {
00457 OP *op = movl_ops[i];
00458 TN *tn = OP_result(op, 0);
00459 TN *new_tn = Dup_TN(tn);
00460 OPS ops = OPS_EMPTY;
00461 Exp_COPY(tn, new_tn, &ops);
00462
00463
00464
00465 if (OP_has_predicate(op)) {
00466 TN *pre_opnd_tn = OP_opnd(op, OP_PREDICATE_OPND);
00467 Set_OP_opnd(ops.first, OP_PREDICATE_OPND, pre_opnd_tn);
00468 Set_OP_opnd(ops.last, OP_PREDICATE_OPND, pre_opnd_tn);
00469 }
00470 BB_Insert_Ops(body, op, &ops, TRUE );
00471 BB_Remove_Op(body, op);
00472 BB_Append_Op(prolog, op);
00473 Set_OP_result(op, 0, new_tn);
00474 Set_OP_opnd(op, OP_PREDICATE_OPND, True_TN);
00475 if (trace)
00476 fprintf(TFile, "Hoist_MOVL: TN%d\n", TN_number(tn));
00477 }
00478 }
00479
00480
00481
00482
00483
00484
00485 struct TN_DU {
00486 typedef OP_VECTOR::index_type index_type;
00487 std::vector<index_type> defs;
00488 std::vector<index_type> uses;
00489
00490 bool TN_is_invariant() const {
00491 return defs.size() == 0;
00492 }
00493
00494
00495 bool TN_unchanged(index_type first, index_type last) {
00496 for (int i = 0; i < defs.size(); i++) {
00497 index_type t = defs[i];
00498 if (first <= t && t < last)
00499 return false;
00500 }
00501 return true;
00502 }
00503
00504
00505 bool TN_can_use_non_rotating_reg(TN *tn, OP_VECTOR& op_vec) {
00506
00507
00508 index_type d = defs.size() > 0 ? defs[0] : INT32_MAX;
00509
00510
00511
00512
00513
00514 for (int j = 0; j < uses.size(); j++) {
00515 index_type u = uses[j];
00516 OP *op = op_vec[u];
00517
00518 for (int i = 0; i < OP_opnds(op); i++) {
00519 if (tn == OP_opnd(op, i)) {
00520 int omega = OP_omega(op, i);
00521 if (omega >= 1) {
00522 if (omega > 1)
00523 return false;
00524 if (d < u)
00525 return false;
00526 }
00527 }
00528 }
00529 }
00530 return true;
00531 }
00532 };
00533
00534
00535
00536
00537 struct TN_DU_MAP {
00538
00539 typedef std::map<TN *, TN_DU>::iterator iterator;
00540 std::map<TN *, TN_DU> TN_DU_map;
00541
00542 iterator begin() {
00543 return TN_DU_map.begin();
00544 }
00545
00546 iterator end() {
00547 return TN_DU_map.end();
00548 }
00549
00550 TN_DU& operator[](TN *tn) {
00551 return TN_DU_map[tn];
00552 }
00553
00554
00555
00556
00557
00558
00559 TN_DU_MAP(OP_VECTOR& op_vec, bool trace) {
00560
00561 for (INT op_num = 0; op_num < op_vec.size(); op_num++) {
00562 OP *op = op_vec[op_num];
00563 INT i;
00564 for (i = 0; i < OP_results(op); i++) {
00565 TN *tn = OP_result(op,i);
00566 if (TN_is_register(tn) &&
00567 !TN_is_dedicated(tn) &&
00568 !TN_is_const_reg(tn)) {
00569 if (TN_DU_map.find(tn) == TN_DU_map.end())
00570 TN_DU_map[tn] = TN_DU();
00571 TN_DU_map[tn].defs.push_back(op_num);
00572 }
00573 }
00574 for (i = 0; i < OP_opnds(op); i++) {
00575 TN *tn = OP_opnd(op,i);
00576 if (TN_is_register(tn) &&
00577 !TN_is_dedicated(tn) &&
00578 !TN_is_const_reg(tn)) {
00579 if (TN_DU_map.find(tn) == TN_DU_map.end())
00580 TN_DU_map[tn] = TN_DU();
00581 TN_DU_map[tn].uses.push_back(op_num);
00582 }
00583 }
00584 }
00585
00586
00587 if (trace) {
00588 for (iterator it = TN_DU_map.begin(); it != TN_DU_map.end(); it++) {
00589 TN *tn = (*it).first;
00590 TN_DU &lrs = (*it).second;
00591 fprintf(TFile, "Remove_Non_Definite_Dependence: TN_DU of TN%d: defs={", TN_number(tn));
00592 {
00593 for (int i = 0; i < lrs.defs.size(); i++) {
00594 fprintf(TFile, "%d", lrs.defs[i]);
00595 if (i != lrs.defs.size()-1) fputc(',', TFile);
00596 }
00597 }
00598 fprintf(TFile, "}, uses={");
00599 {
00600 for (int i = 0; i < lrs.uses.size(); i++) {
00601 fprintf(TFile, "%d", lrs.uses[i]);
00602 if (i != lrs.uses.size()-1) fputc(',', TFile);
00603 }
00604 }
00605 fprintf(TFile, "}\n");
00606 }
00607 }
00608 }
00609 };
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 BOOL static tn_is_needed_in_epilog (TN *tn)
00626 { BB *epilog = CG_LOOP_epilog;
00627 CG_LOOP_BACKPATCH *bp;
00628 for (bp = CG_LOOP_Backpatch_First(epilog, NULL); bp; bp = CG_LOOP_Backpatch_Next(bp)) {
00629 TN *body_tn = CG_LOOP_BACKPATCH_body_tn(bp);
00630 if (body_tn == tn) {
00631 return TRUE;
00632 }
00633 }
00634 return FALSE;
00635 }
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648 bool OP_owns_the_base_TN(OP *op, TN *base, TN_DU& tn_du, OP_VECTOR& op_vec)
00649 {
00650 for (int j = 0; j < tn_du.uses.size(); j++) {
00651 int u = tn_du.uses[j];
00652 OP *op2 = op_vec[u];
00653
00654 if (op != op2 && OP_memory(op2)) {
00655 if (OP_store(op) || OP_store(op2))
00656 return false;
00657 }
00658 }
00659 return true;
00660 }
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 BOOL Remove_Non_Definite_Dependence(CG_LOOP &cl, bool cg_loop_init, bool trace)
00672 {
00673 BB *body = cl.Loop_header();
00674
00675 OP_VECTOR op_vec(body);
00676 TN_DU_MAP TN_DU_map(op_vec, trace);
00677
00678
00679
00680
00681 int copy_inserted = 0;
00682 OPS ops = OPS_EMPTY;
00683
00684 for (TN_DU_MAP::iterator it = TN_DU_map.begin(); it != TN_DU_map.end(); it++) {
00685
00686 TN *tn = (*it).first;
00687 TN_DU &lrs = (*it).second;
00688
00689 if (TN_is_dedicated(tn)) continue;
00690
00691 bool need_copy = true;
00692
00693
00694 if (lrs.TN_is_invariant())
00695 need_copy = false;
00696
00697
00698 if (need_copy)
00699 if (lrs.defs.size() > 0) {
00700 OP *op = op_vec[lrs.defs[0]];
00701 if (!OP_cond_def(op))
00702 need_copy = false;
00703 }
00704
00705
00706
00707 if (need_copy) {
00708 if (lrs.defs.size() >= 2 && lrs.uses.size() > 0) {
00709 if (lrs.defs[0] < lrs.uses[0] && lrs.defs[1] < lrs.uses[0]) {
00710 OP *def1 = op_vec[lrs.defs[0]];
00711 OP *def2 = op_vec[lrs.defs[1]];
00712 if (OP_cond_def(def1) && OP_cond_def(def2)) {
00713 TN *pred1 = OP_opnd(def1, OP_PREDICATE_OPND);
00714 TN *pred2 = OP_opnd(def2, OP_PREDICATE_OPND);
00715 if (pred1 != pred2) {
00716 DEF_KIND kind;
00717 OP *pred1_def = TN_Reaching_Value_At_Op(pred1,def1,&kind,TRUE);
00718 OP *pred2_def = TN_Reaching_Value_At_Op(pred2,def2,&kind,TRUE);
00719 if (kind == VAL_KNOWN && pred1_def && pred1_def == pred2_def) {
00720 need_copy = false;
00721 }
00722 }
00723 }
00724 }
00725 }
00726 }
00727
00728
00729
00730 if (need_copy) {
00731 bool all_uses_covered = true;
00732 for (int i = 0; i < lrs.uses.size(); i++) {
00733 bool found_covering_def = false;
00734 OP *op = op_vec[lrs.uses[i]];
00735 if (OP_cond_def(op)) {
00736 TN *pred_tn = OP_opnd(op, OP_PREDICATE_OPND);
00737 for (int j = lrs.defs.size() - 1; j >= 0; j--) {
00738 if (lrs.defs[j] < lrs.uses[i]) {
00739 OP *defop = op_vec[lrs.defs[j]];
00740 TN *def_pred_tn = OP_opnd(defop, OP_PREDICATE_OPND);
00741 if (def_pred_tn == pred_tn &&
00742 TN_DU_map[pred_tn].TN_unchanged(lrs.defs[j], lrs.defs[i])) {
00743 found_covering_def = true;
00744 break;
00745 }
00746 }
00747 }
00748 }
00749 if (!found_covering_def) {
00750 all_uses_covered = false;
00751 break;
00752 }
00753 }
00754 if (all_uses_covered) {
00755 BB *epilog = CG_LOOP_epilog;
00756 CG_LOOP_BACKPATCH *bp;
00757 for (bp = CG_LOOP_Backpatch_First(epilog, NULL); bp; bp = CG_LOOP_Backpatch_Next(bp)) {
00758 TN *body_tn = CG_LOOP_BACKPATCH_body_tn(bp);
00759 if (body_tn == tn) {
00760 all_uses_covered = false;
00761 break;
00762 }
00763 }
00764 }
00765 if (all_uses_covered)
00766 need_copy = false;
00767 }
00768
00769 if (need_copy) {
00770
00771 Exp_COPY(tn, tn, &ops);
00772 copy_inserted++;
00773 if (trace)
00774 fprintf(TFile, "Remove_Non_Definite_Dependence: TN%d\n", TN_number(tn));
00775 }
00776 }
00777
00778 OP *old_first_op = BB_first_op(body);
00779 BB_Prepend_Ops(body, &ops);
00780
00781 if (cg_loop_init) {
00782 for (OP *op = BB_first_op(body); op != old_first_op; op = OP_next(op)) {
00783 CG_LOOP_Init_Op(op);
00784 for (INT i = 0; i < OP_opnds(op); i++) {
00785 if (i != OP_PREDICATE_OPND && TN_is_register(OP_opnd(op,i))
00786 && ! TN_is_dedicated(OP_opnd(op,i)))
00787 Set_OP_omega(op, i, 1);
00788 }
00789 }
00790 }
00791
00792 if (trace)
00793 fprintf(TFile, "Remove_Non_Definite_Dependence: %d copy inserted\n",
00794 copy_inserted);
00795
00796 return TRUE;
00797 }
00798
00799
00800
00801
00802 BASE_UPDATE
00803 OP_convertible_to_base_update(OP *op)
00804 {
00805 if (OP_load(op) || OP_store(op)) {
00806 switch (OP_code(op)) {
00807 case TOP_ld1:
00808 case TOP_ld2:
00809 case TOP_ld4:
00810 case TOP_ld8:
00811 case TOP_ldf8:
00812 case TOP_ldfd:
00813 case TOP_ldfe:
00814 case TOP_ldfs:
00815 return (BASE_UPDATE) (REG_BASE_UPDATE | IMM_BASE_UPDATE);
00816 case TOP_st1:
00817 case TOP_st2:
00818 case TOP_st4:
00819 case TOP_st8:
00820 case TOP_stf8:
00821 case TOP_stfd:
00822 case TOP_stfe:
00823 case TOP_stfs:
00824 return IMM_BASE_UPDATE;
00825 }
00826 }
00827 return NO_BASE_UPDATE;
00828 }
00829
00830
00831 BASE_UPDATE OP_base_update_kind(OP *op)
00832 {
00833 if (OP_load(op) || OP_store(op)) {
00834 switch (OP_code(op)) {
00835 case TOP_ld1_i:
00836 case TOP_ld2_i:
00837 case TOP_ld4_i:
00838 case TOP_ld8_i:
00839 case TOP_ldf8_i:
00840 case TOP_ldfd_i:
00841 case TOP_ldfe_i:
00842 case TOP_ldfs_i:
00843 case TOP_st1_i:
00844 case TOP_st2_i:
00845 case TOP_st4_i:
00846 case TOP_st8_i:
00847 case TOP_stf8_i:
00848 case TOP_stfd_i:
00849 case TOP_stfe_i:
00850 case TOP_stfs_i:
00851 return IMM_BASE_UPDATE;
00852 case TOP_ld1_r:
00853 case TOP_ld2_r:
00854 case TOP_ld4_r:
00855 case TOP_ld8_r:
00856 case TOP_ldf8_r:
00857 case TOP_ldfd_r:
00858 case TOP_ldfe_r:
00859 case TOP_ldfs_r:
00860 return REG_BASE_UPDATE;
00861 }
00862 }
00863 return NO_BASE_UPDATE;
00864 }
00865
00866
00867
00868 INT OP_base_opnd_num(OP *op)
00869 {
00870 if (OP_load(op) || OP_store(op)) {
00871 switch (OP_code(op)) {
00872 case TOP_ld1:
00873 case TOP_ld2:
00874 case TOP_ld4:
00875 case TOP_ld8:
00876 case TOP_ldf8:
00877 case TOP_ldfd:
00878 case TOP_ldfe:
00879 case TOP_ldfs:
00880 case TOP_st1:
00881 case TOP_st2:
00882 case TOP_st4:
00883 case TOP_st8:
00884 case TOP_ld1_i:
00885 case TOP_ld2_i:
00886 case TOP_ld4_i:
00887 case TOP_ld8_i:
00888 case TOP_ldf8_i:
00889 case TOP_ldfd_i:
00890 case TOP_ldfe_i:
00891 case TOP_ldfs_i:
00892 case TOP_st1_i:
00893 case TOP_st2_i:
00894 case TOP_st4_i:
00895 case TOP_st8_i:
00896 case TOP_ld1_r:
00897 case TOP_ld2_r:
00898 case TOP_ld4_r:
00899 case TOP_ld8_r:
00900 case TOP_ldf8_r:
00901 case TOP_ldfd_r:
00902 case TOP_ldfe_r:
00903 case TOP_ldfs_r:
00904 return 3;
00905 case TOP_stf8:
00906 case TOP_stfd:
00907 case TOP_stfe:
00908 case TOP_stfs:
00909 case TOP_stf8_i:
00910 case TOP_stfd_i:
00911 case TOP_stfe_i:
00912 case TOP_stfs_i:
00913 return 2;
00914 }
00915 }
00916 return -1;
00917 }
00918
00919
00920
00921 INT OP_base_res_num(OP *op)
00922 {
00923 if (OP_load(op) || OP_store(op)) {
00924 switch (OP_code(op)) {
00925 case TOP_ld1:
00926 case TOP_ld2:
00927 case TOP_ld4:
00928 case TOP_ld8:
00929 case TOP_ldf8:
00930 case TOP_ldfd:
00931 case TOP_ldfe:
00932 case TOP_ldfs:
00933 case TOP_ld1_i:
00934 case TOP_ld2_i:
00935 case TOP_ld4_i:
00936 case TOP_ld8_i:
00937 case TOP_ldf8_i:
00938 case TOP_ldfd_i:
00939 case TOP_ldfe_i:
00940 case TOP_ldfs_i:
00941 case TOP_ld1_r:
00942 case TOP_ld2_r:
00943 case TOP_ld4_r:
00944 case TOP_ld8_r:
00945 case TOP_ldf8_r:
00946 case TOP_ldfd_r:
00947 case TOP_ldfe_r:
00948 case TOP_ldfs_r:
00949 return 1;
00950 case TOP_st1:
00951 case TOP_st2:
00952 case TOP_st4:
00953 case TOP_st8:
00954 case TOP_st1_i:
00955 case TOP_st2_i:
00956 case TOP_st4_i:
00957 case TOP_st8_i:
00958 case TOP_stf8:
00959 case TOP_stfd:
00960 case TOP_stfe:
00961 case TOP_stfs:
00962 case TOP_stf8_i:
00963 case TOP_stfd_i:
00964 case TOP_stfe_i:
00965 case TOP_stfs_i:
00966 return 0;
00967 }
00968 }
00969 return -1;
00970 }
00971
00972
00973
00974 INT OP_imm_opnd_num(OP *op)
00975 {
00976 if (OP_load(op) || OP_store(op)) {
00977 switch (OP_code(op)) {
00978 case TOP_ld1_i:
00979 case TOP_ld2_i:
00980 case TOP_ld4_i:
00981 case TOP_ld8_i:
00982 case TOP_ldf8_i:
00983 case TOP_ldfd_i:
00984 case TOP_ldfe_i:
00985 case TOP_ldfs_i:
00986 return 4;
00987 case TOP_st1_i:
00988 case TOP_st2_i:
00989 case TOP_st4_i:
00990 case TOP_st8_i:
00991 return 5;
00992 case TOP_stf8_i:
00993 case TOP_stfd_i:
00994 case TOP_stfe_i:
00995 case TOP_stfs_i:
00996 return 4;
00997 }
00998 }
00999 return -1;
01000 }
01001
01002
01003 INT32 OP_incr_opnd_num(TOP top)
01004 {
01005
01006 return (TOP_fixed_opnds(top) - 1);
01007 }
01008
01009 INT32 OP_incr_opnd_num(OP *op)
01010 {
01011
01012 return (OP_opnds(op) - 1);
01013 }
01014
01015
01016 BOOL Imm_Value_In_Range(OP *op, INT64 imm)
01017 {
01018 TOP new_opc;
01019 switch (OP_code(op)) {
01020 case TOP_ld1: new_opc = TOP_ld1_i; break;
01021 case TOP_ld2: new_opc = TOP_ld2_i; break;
01022 case TOP_ld4: new_opc = TOP_ld4_i; break;
01023 case TOP_ld8: new_opc = TOP_ld8_i; break;
01024 case TOP_ldf8: new_opc = TOP_ldf8_i; break;
01025 case TOP_ldfd: new_opc = TOP_ldfd_i; break;
01026 case TOP_ldfe: new_opc = TOP_ldfe_i; break;
01027 case TOP_ldfs: new_opc = TOP_ldfs_i; break;
01028 case TOP_st1: new_opc = TOP_st1_i; break;
01029 case TOP_st2: new_opc = TOP_st2_i; break;
01030 case TOP_st4: new_opc = TOP_st4_i; break;
01031 case TOP_st8: new_opc = TOP_st8_i; break;
01032 case TOP_stf8: new_opc = TOP_stf8_i; break;
01033 case TOP_stfd: new_opc = TOP_stfd_i; break;
01034 case TOP_stfe: new_opc = TOP_stfe_i; break;
01035 case TOP_stfs: new_opc = TOP_stfs_i; break;
01036
01037 case TOP_ld1_i:
01038 case TOP_ld2_i:
01039 case TOP_ld4_i:
01040 case TOP_ld8_i:
01041 case TOP_ldf8_i:
01042 case TOP_ldfd_i:
01043 case TOP_ldfe_i:
01044 case TOP_ldfs_i:
01045 case TOP_st1_i:
01046 case TOP_st2_i:
01047 case TOP_st4_i:
01048 case TOP_st8_i:
01049 case TOP_stf8_i:
01050 case TOP_stfd_i:
01051 case TOP_stfe_i:
01052 case TOP_stfs_i:
01053 new_opc = OP_code(op);
01054 break;
01055
01056 default:
01057 return FALSE;
01058 }
01059
01060 INT opnd = OP_incr_opnd_num(new_opc);
01061 const ISA_OPERAND_INFO *oinfo = ISA_OPERAND_Info(new_opc);
01062 const ISA_OPERAND_VALTYP *vtype = ISA_OPERAND_INFO_Operand(oinfo, opnd);
01063 ISA_LIT_CLASS lc = ISA_OPERAND_VALTYP_Literal_Class(vtype);
01064 BOOL retv = ISA_LC_Value_In_Class(imm, lc);
01065 return retv;
01066 }
01067
01068 static INT32 Num_defs(BB *body, TN *def_tn)
01069 {
01070 INT32 count = 0;
01071 OP *op;
01072 FOR_ALL_BB_OPs(body, op) {
01073 for (INT i = 0; i < OP_results(op); i++) {
01074 TN *tn = OP_result(op, i);
01075 if (tn == def_tn)
01076 count++;
01077 }
01078 }
01079 return count;
01080 }
01081
01082
01083 BOOL Mem_stride_ge_access(OP *op, INT64 stride)
01084 {
01085 stride = stride > 0 ? stride : -stride;
01086 switch (OP_code(op)) {
01087 case TOP_ld1:
01088 case TOP_ld1_i:
01089 case TOP_st1:
01090 case TOP_st1_i:
01091 return (stride >= 1);
01092
01093 case TOP_ld2:
01094 case TOP_ld2_i:
01095 case TOP_st2:
01096 case TOP_st2_i:
01097 return (stride >= 2);
01098
01099 case TOP_ld4:
01100 case TOP_ld4_i:
01101 case TOP_st4:
01102 case TOP_st4_i:
01103 case TOP_ldfs:
01104 case TOP_ldfs_i:
01105 case TOP_stfs:
01106 case TOP_stfs_i:
01107 return (stride >= 4);
01108
01109 case TOP_ld8:
01110 case TOP_ld8_i:
01111 case TOP_st8:
01112 case TOP_st8_i:
01113 case TOP_ldf8:
01114 case TOP_ldf8_i:
01115 case TOP_stf8:
01116 case TOP_stf8_i:
01117 case TOP_ldfd:
01118 case TOP_ldfd_i:
01119 case TOP_stfd:
01120 case TOP_stfd_i:
01121 return (stride >= 8);
01122
01123 case TOP_ldfe:
01124 case TOP_ldfe_i:
01125 case TOP_stfe:
01126 case TOP_stfe_i:
01127 return (stride >= 16);
01128 }
01129 return FALSE;
01130 }
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 void Init_OP_no_ci_alias(CG_LOOP& cl, BOOL trace)
01142 {
01143 BB *body = cl.Loop_header();
01144 CG_LOOP_DEF tn_def(body);
01145
01146 OP *op;
01147 FOR_ALL_BB_OPs(body, op) {
01148 if ((OP_load(op) || OP_store(op)) &&
01149 OP_convertible_to_base_update(op) != NO_BASE_UPDATE) {
01150 INT addr_opnd = OP_base_opnd_num(op);
01151 TN *addr_tn = OP_opnd(op, addr_opnd);
01152 OP *incr_op = tn_def.Get(addr_tn);
01153 if (incr_op) {
01154 switch (OP_code(incr_op)) {
01155 case TOP_adds:
01156 case TOP_addl:
01157 if (OP_opnd(incr_op, 2) == addr_tn &&
01158 TN_is_constant(OP_opnd(incr_op, 1)) &&
01159 Num_defs(body, addr_tn) == 1 &&
01160 Mem_stride_ge_access(op, TN_value(OP_opnd(incr_op, 1))) &&
01161 OP_opnd(incr_op, OP_PREDICATE_OPND) == True_TN) {
01162 Set_OP_no_ci_alias(op);
01163 if (trace)
01164 fprintf(TFile, "Set OP%d to no ci alias\n",
01165 OP_map_idx(op));
01166 }
01167 break;
01168 }
01169 }
01170 }
01171 }
01172 }
01173
01174
01175
01176
01177
01178
01179 static TN *
01180 Identify_and_delete_incr(BB *bb, OP *memop, INT base_opnd_num, BASE_UPDATE up)
01181 {
01182 Is_True(OP_load(memop) || OP_store(memop), ("invalid op."));
01183
01184 TN *base = OP_opnd(memop, base_opnd_num);
01185
01186 bool allow_imm = (up & IMM_BASE_UPDATE) != 0;
01187 bool allow_reg = (up & REG_BASE_UPDATE) != 0;
01188 bool incr_kill = false;
01189
01190 TN *pred_tn = OP_opnd(memop, OP_PREDICATE_OPND);
01191
01192 for (OP *incr_op = OP_next(memop); incr_op != NULL; incr_op = OP_next(incr_op)) {
01193
01194 if (OP_opnd(incr_op, OP_PREDICATE_OPND) == pred_tn) {
01195
01196
01197 if (allow_imm &&
01198 (OP_code(incr_op) == TOP_adds || OP_code(incr_op) == TOP_addl) &&
01199 OP_result(incr_op, 0) == base &&
01200 OP_opnd(incr_op, 2) == base &&
01201 OP_omega(incr_op, 2) == OP_omega(memop, base_opnd_num) &&
01202 Imm_Value_In_Range(memop, TN_value(OP_opnd(incr_op, 1)))) {
01203 BB_Remove_Op(bb, incr_op);
01204 return OP_opnd(incr_op, 1);
01205 }
01206
01207
01208
01209 if (allow_reg &&
01210 OP_code(incr_op) == TOP_add &&
01211 OP_result(incr_op, 0) == base) {
01212 if ((OP_opnd(incr_op, 1) == base) &&
01213 (OP_omega(incr_op, 1) == OP_omega(memop, base_opnd_num)) &&
01214 TN_is_global_reg(OP_opnd(incr_op, 2))) {
01215
01216
01217
01218
01219
01220
01221
01222 for(OP *def_op = OP_next(memop);!incr_kill && def_op!=incr_op;def_op=OP_next(def_op))
01223 {
01224 if (OP_Defs_TN(def_op, OP_opnd(incr_op, 2))) incr_kill = true;
01225 }
01226 if(!incr_kill){
01227 BB_Remove_Op(bb, incr_op);
01228 return OP_opnd(incr_op, 2);
01229 }
01230 else
01231 return NULL;
01232 }
01233 else if ((OP_opnd(incr_op, 2) == base) &&
01234 (OP_omega(incr_op, 2) == OP_omega(memop, base_opnd_num)) &&
01235 TN_is_global_reg(OP_opnd(incr_op, 1))) {
01236 for(OP *def_op = OP_next(memop);!incr_kill && def_op!=incr_op;def_op=OP_next(def_op))
01237 {
01238 if (OP_Defs_TN(def_op, OP_opnd(incr_op, 1))) incr_kill = true;
01239 }
01240 if(!incr_kill){
01241 BB_Remove_Op(bb, incr_op);
01242 return OP_opnd(incr_op, 1);
01243 }
01244 else
01245 return NULL;
01246 }
01247 }
01248 }
01249
01250
01251
01252
01253 if (OP_Defs_TN(incr_op, base)) break;
01254 if (OP_Refs_TN(incr_op, base)) break;
01255 if (OP_Defs_TN(incr_op, pred_tn)) break;
01256 }
01257 return NULL;
01258 }
01259
01260
01261 void Convert_OP_to_base_update_form(BB *body, OP *op, TN *incr, BASE_UPDATE up,
01262 INT base_opnd_num, bool trace)
01263 {
01264 TOP new_opc;
01265 if (TN_is_register(incr)) {
01266 Is_True(up & REG_BASE_UPDATE, ("reg base-update form not allowed"));
01267 switch (OP_code(op)) {
01268 case TOP_ld1: new_opc = TOP_ld1_r; break;
01269 case TOP_ld2: new_opc = TOP_ld2_r; break;
01270 case TOP_ld4: new_opc = TOP_ld4_r; break;
01271 case TOP_ld8: new_opc = TOP_ld8_r; break;
01272 case TOP_ldf8: new_opc = TOP_ldf8_r; break;
01273 case TOP_ldfd: new_opc = TOP_ldfd_r; break;
01274 case TOP_ldfe: new_opc = TOP_ldfe_r; break;
01275 case TOP_ldfs: new_opc = TOP_ldfs_r; break;
01276 default:
01277 Is_True(FALSE, ("unimplemented opcode."));
01278 }
01279 } else {
01280 Is_True(up & IMM_BASE_UPDATE, ("reg base-update form not allowed"));
01281 Is_True(Imm_Value_In_Range(op, TN_value(incr)), ("incr literal too big."));
01282 switch (OP_code(op)) {
01283 case TOP_ld1: new_opc = TOP_ld1_i; break;
01284 case TOP_ld2: new_opc = TOP_ld2_i; break;
01285 case TOP_ld4: new_opc = TOP_ld4_i; break;
01286 case TOP_ld8: new_opc = TOP_ld8_i; break;
01287 case TOP_ldf8: new_opc = TOP_ldf8_i; break;
01288 case TOP_ldfd: new_opc = TOP_ldfd_i; break;
01289 case TOP_ldfe: new_opc = TOP_ldfe_i; break;
01290 case TOP_ldfs: new_opc = TOP_ldfs_i; break;
01291 case TOP_st1: new_opc = TOP_st1_i; break;
01292 case TOP_st2: new_opc = TOP_st2_i; break;
01293 case TOP_st4: new_opc = TOP_st4_i; break;
01294 case TOP_st8: new_opc = TOP_st8_i; break;
01295 case TOP_stf8: new_opc = TOP_stf8_i; break;
01296 case TOP_stfd: new_opc = TOP_stfd_i; break;
01297 case TOP_stfe: new_opc = TOP_stfe_i; break;
01298 case TOP_stfs: new_opc = TOP_stfs_i; break;
01299 default:
01300 Is_True(FALSE, ("unimplemented opcode."));
01301 }
01302 }
01303 OP *new_op;
01304 if (OP_load(op)) {
01305 new_op = Mk_OP (new_opc,
01306 OP_result(op, 0),
01307 OP_opnd(op, base_opnd_num),
01308 OP_opnd(op, 0),
01309 OP_opnd(op, 1),
01310 OP_opnd(op, 2),
01311 OP_opnd(op, 3),
01312 incr);
01313 Is_True(OP_opnds(new_op) == 5, ("postincr load has 5 opnds."));
01314 } else {
01315 if (OP_opnds(op) == 5) {
01316 new_op = Mk_OP (new_opc,
01317 OP_opnd(op, base_opnd_num),
01318 OP_opnd(op, 0),
01319 OP_opnd(op, 1),
01320 OP_opnd(op, 2),
01321 OP_opnd(op, 3),
01322 OP_opnd(op, 4),
01323 incr);
01324 Is_True(OP_opnds(new_op) == 6, ("postincr store has 6 opnds."));
01325 } else {
01326 new_op = Mk_OP (new_opc,
01327 OP_opnd(op, base_opnd_num),
01328 OP_opnd(op, 0),
01329 OP_opnd(op, 1),
01330 OP_opnd(op, 2),
01331 OP_opnd(op, 3),
01332 incr);
01333 Is_True(OP_opnds(new_op) == 5, ("postincr store has 5 opnds."));
01334 }
01335 }
01336
01337
01338 CG_LOOP_Init_Op(new_op);
01339 for (INT i = 0; i < OP_opnds(op); i++) {
01340 if (TN_is_register(OP_opnd(op,i))) {
01341 Is_True(OP_opnd(op, i) == OP_opnd(new_op, i),
01342 ("Convert_Post_Incr: can't transfer omega."));
01343 Set_OP_omega(new_op, i, OP_omega(op, i));
01344 }
01345 }
01346
01347
01348 OP_flags(new_op) = OP_flags(op);
01349 Set_OP_unrolling(new_op, OP_unrolling(op));
01350 Set_OP_orig_idx(new_op, OP_orig_idx(op));
01351
01352 if (trace) {
01353 fprintf(TFile, "<postincr>: replacing ");
01354 Print_OP_No_SrcLine(op);
01355 fprintf(TFile, "with ");
01356 Print_OP_No_SrcLine(new_op);
01357 }
01358 BB_Insert_Op(body, op, new_op, TRUE);
01359 BB_Remove_Op(body, op);
01360 Copy_WN_For_Memory_OP (new_op, op);
01361 op = new_op;
01362 }
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373 void Gen_Post_Incr_Memop(CG_LOOP& cl, bool trace)
01374 {
01375 BB *body = cl.Loop_header();
01376 OP_VECTOR op_vec(body);
01377 TN_DU_MAP TN_DU_map(op_vec, trace);
01378
01379 OP *next_op;
01380 for (OP *op = BB_first_op(body); op != NULL; op = next_op) {
01381
01382
01383 next_op = OP_next(op);
01384
01385 BASE_UPDATE up = OP_convertible_to_base_update(op);
01386 if (up != NO_BASE_UPDATE) {
01387
01388 INT base_opnd_num = OP_base_opnd_num(op);
01389 TN *base = OP_opnd(op, base_opnd_num);
01390
01391
01392
01393
01394 bool can_use_non_rotating_reg = TN_DU_map[base].TN_can_use_non_rotating_reg(base, op_vec);
01395 bool owns_the_base = can_use_non_rotating_reg &&
01396 OP_owns_the_base_TN(op, base, TN_DU_map[base], op_vec);
01397 bool base_needed_in_epilog = tn_is_needed_in_epilog(base);
01398 TN *incr = NULL;
01399 incr = (owns_the_base && !base_needed_in_epilog)
01400 ? Identify_and_delete_incr(body, op, base_opnd_num, up) : NULL;
01401 if (incr != NULL)
01402 Convert_OP_to_base_update_form(body, op, incr, up, base_opnd_num, trace);
01403
01404 if (trace) {
01405 if (!can_use_non_rotating_reg)
01406 fprintf(TFile, "<postincr> TN%d cannot use non-rotating reg\n", TN_number(base));
01407 else if (!owns_the_base)
01408 fprintf(TFile, "<postincr> OP does not own the base TN%d\n", TN_number(base));
01409 else if (base_needed_in_epilog)
01410 fprintf(TFile, "<postincr> TN%d[1] needed in epilog\n", TN_number(base));
01411 else if (incr == NULL)
01412 fprintf(TFile, "<postincr> cannot delete incr TN%d\n", TN_number(base));
01413 }
01414 }
01415 }
01416 }
01417
01418
01419
01420
01421
01422
01423
01424
01425 static BOOL Expand_Simulated_Ops(CG_LOOP& cl, bool trace)
01426 {
01427 BB *body = cl.Loop_header();
01428 OP *op;
01429 FOR_ALL_BB_OPs(body, op) {
01430 TOP top = OP_code(op);
01431 if (OP_simulated(op) && top != TOP_asm) {
01432 if (trace)
01433 fprintf(TFile, "<swp> expand simulated op %s\n", TOP_Name(top));
01434 switch (top) {
01435 case TOP_mov_t_ar_r:
01436 {
01437 const ISA_OPERAND_INFO *oinfo = ISA_OPERAND_Info(top);
01438 const ISA_OPERAND_VALTYP *vtype = ISA_OPERAND_INFO_Result(oinfo, 0);
01439 const ISA_REGISTER_SUBCLASS sc = ISA_OPERAND_VALTYP_Register_Subclass(vtype);
01440 if (sc == ISA_REGISTER_SUBCLASS_ar_i)
01441 OP_Change_Opcode(op, TOP_mov_t_ar_r_i);
01442 else
01443 OP_Change_Opcode(op, TOP_mov_t_ar_r_m);
01444 break;
01445 }
01446 default:
01447 DevWarn("SWP: support of simulated OP %s not implemented.", TOP_Name(top));
01448 return FALSE;
01449 }
01450 }
01451 }
01452 return TRUE;
01453 }
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464 BOOL Prepare_Loop_For_SWP_1(CG_LOOP& cl, bool trace)
01465 {
01466 if (!Expand_Simulated_Ops(cl, trace))
01467 return FALSE;
01468
01469 if (!Remove_Non_Definite_Dependence(cl, false, trace))
01470 return FALSE;
01471
01472 Remove_Invariant_Predicates(cl, trace);
01473
01474 Unc_Promotion(cl, trace);
01475
01476 Hoist_MOVL(cl, trace);
01477
01478 Init_OP_no_ci_alias(cl, trace);
01479
01480 return TRUE;
01481 }
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492 BOOL Prepare_Loop_For_SWP_2(CG_LOOP& cl, bool trace)
01493 {
01494 if (SWP_Options.Enable_Post_Incr)
01495 Gen_Post_Incr_Memop(cl, trace);
01496
01497 if (!Remove_Non_Definite_Dependence(cl, true, trace))
01498 return FALSE;
01499
01500 return TRUE;
01501 }
01502
01503
01504
01505 TOP Get_Predicated_Form(TOP top)
01506 {
01507 switch (top) {
01508 case TOP_fcmp_eq_unc: return TOP_fcmp_eq;
01509 case TOP_fcmp_ge_unc: return TOP_fcmp_ge;
01510 case TOP_fcmp_gt_unc: return TOP_fcmp_gt;
01511 case TOP_fcmp_le_unc: return TOP_fcmp_le;
01512 case TOP_fcmp_lt_unc: return TOP_fcmp_lt;
01513 case TOP_fcmp_neq_unc: return TOP_fcmp_neq;
01514 case TOP_fcmp_nge_unc: return TOP_fcmp_nge;
01515 case TOP_fcmp_ngt_unc: return TOP_fcmp_ngt;
01516 case TOP_fcmp_nle_unc: return TOP_fcmp_nle;
01517 case TOP_fcmp_nlt_unc: return TOP_fcmp_nlt;
01518 case TOP_fcmp_ord_unc: return TOP_fcmp_ord;
01519 case TOP_fcmp_unord_unc: return TOP_fcmp_unord;
01520 case TOP_cmp_eq_unc: return TOP_cmp_eq;
01521 case TOP_cmp_lt_unc: return TOP_cmp_lt;
01522 case TOP_cmp_ltu_unc: return TOP_cmp_ltu;
01523 case TOP_cmp_i_eq_unc: return TOP_cmp_i_eq;
01524 case TOP_cmp_i_lt_unc: return TOP_cmp_i_lt;
01525 case TOP_cmp_i_ltu_unc: return TOP_cmp_i_ltu;
01526 case TOP_cmp4_eq_unc: return TOP_cmp4_eq;
01527 case TOP_cmp4_lt_unc: return TOP_cmp4_lt;
01528 case TOP_cmp4_ltu_unc: return TOP_cmp4_ltu;
01529 case TOP_cmp4_i_eq_unc: return TOP_cmp4_i_eq;
01530 case TOP_cmp4_i_lt_unc: return TOP_cmp4_i_lt;
01531 case TOP_cmp4_i_ltu_unc: return TOP_cmp4_i_ltu;
01532 case TOP_cmp_ne_unc: return TOP_cmp_ne;
01533 case TOP_cmp_le_unc: return TOP_cmp_le;
01534 case TOP_cmp_gt_unc: return TOP_cmp_gt;
01535 case TOP_cmp_ge_unc: return TOP_cmp_ge;
01536 case TOP_cmp_leu_unc: return TOP_cmp_leu;
01537 case TOP_cmp_gtu_unc: return TOP_cmp_gtu;
01538 case TOP_cmp_geu_unc: return TOP_cmp_geu;
01539 case TOP_cmp_i_ne_unc: return TOP_cmp_i_ne;
01540 case TOP_cmp_i_le_unc: return TOP_cmp_i_le;
01541 case TOP_cmp_i_gt_unc: return TOP_cmp_i_gt;
01542 case TOP_cmp_i_ge_unc: return TOP_cmp_i_ge;
01543 case TOP_cmp_i_leu_unc: return TOP_cmp_i_leu;
01544 case TOP_cmp_i_gtu_unc: return TOP_cmp_i_gtu;
01545 case TOP_cmp_i_geu_unc: return TOP_cmp_i_geu;
01546 case TOP_cmp4_ne_unc: return TOP_cmp4_ne;
01547 case TOP_cmp4_le_unc: return TOP_cmp4_le;
01548 case TOP_cmp4_gt_unc: return TOP_cmp4_gt;
01549 case TOP_cmp4_ge_unc: return TOP_cmp4_ge;
01550 case TOP_cmp4_leu_unc: return TOP_cmp4_leu;
01551 case TOP_cmp4_gtu_unc: return TOP_cmp4_gtu;
01552 case TOP_cmp4_geu_unc: return TOP_cmp4_geu;
01553 case TOP_cmp4_i_ne_unc: return TOP_cmp4_i_ne;
01554 case TOP_cmp4_i_le_unc: return TOP_cmp4_i_le;
01555 case TOP_cmp4_i_gt_unc: return TOP_cmp4_i_gt;
01556 case TOP_cmp4_i_ge_unc: return TOP_cmp4_i_ge;
01557 case TOP_cmp4_i_leu_unc: return TOP_cmp4_i_leu;
01558 case TOP_cmp4_i_gtu_unc: return TOP_cmp4_i_gtu;
01559 case TOP_cmp4_i_geu_unc: return TOP_cmp4_i_geu;
01560 case TOP_tbit_nz_unc: return TOP_tbit_nz;
01561 case TOP_tbit_z_unc: return TOP_tbit_z;
01562 case TOP_tnat_nz_unc: return TOP_tnat_nz;
01563 case TOP_tnat_z_unc: return TOP_tnat_z;
01564 case TOP_fcmp_eq:
01565 case TOP_fcmp_ge:
01566 case TOP_fcmp_gt:
01567 case TOP_fcmp_le:
01568 case TOP_fcmp_lt:
01569 case TOP_fcmp_neq:
01570 case TOP_fcmp_nge:
01571 case TOP_fcmp_ngt:
01572 case TOP_fcmp_nle:
01573 case TOP_fcmp_nlt:
01574 case TOP_fcmp_ord:
01575 case TOP_fcmp_unord:
01576 case TOP_cmp_eq:
01577 case TOP_cmp_lt:
01578 case TOP_cmp_ltu:
01579 case TOP_cmp_i_eq:
01580 case TOP_cmp_i_lt:
01581 case TOP_cmp_i_ltu:
01582 case TOP_cmp4_eq:
01583 case TOP_cmp4_lt:
01584 case TOP_cmp4_ltu:
01585 case TOP_cmp4_i_eq:
01586 case TOP_cmp4_i_lt:
01587 case TOP_cmp4_i_ltu:
01588 case TOP_cmp_ne:
01589 case TOP_cmp_le:
01590 case TOP_cmp_gt:
01591 case TOP_cmp_ge:
01592 case TOP_cmp_leu:
01593 case TOP_cmp_gtu:
01594 case TOP_cmp_geu:
01595 case TOP_cmp_i_ne:
01596 case TOP_cmp_i_le:
01597 case TOP_cmp_i_gt:
01598 case TOP_cmp_i_ge:
01599 case TOP_cmp_i_leu:
01600 case TOP_cmp_i_gtu:
01601 case TOP_cmp_i_geu:
01602 case TOP_cmp4_ne:
01603 case TOP_cmp4_le:
01604 case TOP_cmp4_gt:
01605 case TOP_cmp4_ge:
01606 case TOP_cmp4_leu:
01607 case TOP_cmp4_gtu:
01608 case TOP_cmp4_geu:
01609 case TOP_cmp4_i_ne:
01610 case TOP_cmp4_i_le:
01611 case TOP_cmp4_i_gt:
01612 case TOP_cmp4_i_ge:
01613 case TOP_cmp4_i_leu:
01614 case TOP_cmp4_i_gtu:
01615 case TOP_cmp4_i_geu:
01616 case TOP_tbit_nz:
01617 case TOP_tbit_z:
01618 case TOP_tnat_nz:
01619 case TOP_tnat_z:
01620 return top;
01621 }
01622 return TOP_UNDEFINED;
01623 }
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634 void Convert_While_Loop_to_Fully_Predicated_Form(CG_LOOP& cl)
01635 {
01636 BB *body = cl.Loop_header();
01637 OP *br_op = BB_branch_op(body);
01638 TN *predicate_tn = OP_opnd(br_op, OP_PREDICATE_OPND);
01639 if (TN_is_dedicated(predicate_tn))
01640 return;
01641
01642
01643
01644 if (CG_LOOP_Backpatch_First(cl.Prolog_end(), predicate_tn) != NULL)
01645 return;
01646
01647 OP *op;
01648 FOR_ALL_BB_OPs(body, op) {
01649 if (OP_has_predicate(op) &&
01650 TN_is_true_pred(OP_opnd(op, OP_PREDICATE_OPND))) {
01651
01652 if (OP_results(op) == 2 &&
01653 (OP_result(op, 0) == predicate_tn ||
01654 OP_result(op, 1) == predicate_tn)) {
01655
01656 TOP pred_top = Get_Predicated_Form(OP_code(op));
01657 Is_True(pred_top != TOP_UNDEFINED,
01658 ("Convert_While_Loop_to_Fully_Predicated_Form: unable to generate unc form of the OP."));
01659 if (pred_top != OP_code(op))
01660 OP_Change_Opcode(op, pred_top);
01661 } else {
01662
01663
01664 TOP unc_top = CGTARG_Get_unc_Variant(OP_code(op));
01665 if (unc_top != TOP_UNDEFINED) {
01666 OP_Change_Opcode(op, unc_top);
01667 CGTARG_Init_OP_cond_def_kind(op);
01668 }
01669 }
01670
01671 Set_OP_opnd(op, OP_PREDICATE_OPND, predicate_tn);
01672 Set_OP_omega(op, OP_PREDICATE_OPND, 1);
01673 }
01674 }
01675 CG_LOOP_Backpatch_Add(cl.Prolog_end(), True_TN, predicate_tn, 1);
01676 }
01677
01678
01679
01680
01681 void Gen_Implicit_Prefetches(CG_LOOP& cl, bool trace)
01682 {
01683 if (!SWP_Options.Implicit_Prefetch)
01684 return;
01685
01686 BB *body = cl.Loop_header();
01687 OP *next_op;
01688
01689 std::vector<OP*> prune_pref;
01690
01691
01692 for (OP *op = BB_first_op(body); op != NULL; op = next_op) {
01693 next_op = OP_next(op);
01694 if (OP_memory(op)) {
01695 WN *wn = Get_WN_From_Memory_OP( op);
01696 if (wn == NULL)
01697 continue;
01698 PF_POINTER *pf_ptr = (PF_POINTER *) WN_MAP_Get(WN_MAP_PREFETCH,wn);
01699 if (pf_ptr == NULL)
01700 continue;
01701
01702 INT stride = 0;
01703 INT offset = 0;
01704 WN *pref = PF_PTR_wn_pref_2L(pf_ptr);
01705 if (pref && Prefetch_Kind_Enabled(pref)) {
01706 stride = WN_pf_stride_2L(pref);
01707 offset = PF_PTR_distance_2L(pf_ptr);
01708 }
01709 else {
01710 pref = PF_PTR_wn_pref_1L(pf_ptr);
01711 if (pref && Prefetch_Kind_Enabled(pref)) {
01712 stride = WN_pf_stride_1L(pref);
01713 offset = PF_PTR_distance_1L(pf_ptr);
01714 }
01715 }
01716 if (stride != 0 && (OP_unrolling(op) % stride) == 0) {
01717 if (trace)
01718 fprintf(TFile, "<swp_pref> offset=%d stride=%d\n", offset, stride);
01719
01720 switch (OP_base_update_kind(op)) {
01721 case IMM_BASE_UPDATE:
01722 {
01723 INT base_opnd_num = OP_base_opnd_num(op);
01724 INT imm_opnd_num = OP_imm_opnd_num(op);
01725 INT adjusted_offset = TN_value(OP_opnd(op, imm_opnd_num)) - offset;
01726 if (Imm_Value_In_Range(op, offset)) {
01727 OPS ops = OPS_EMPTY;
01728 Build_OP(TOP_adds,
01729 OP_opnd(op, base_opnd_num),
01730 True_TN,
01731 Gen_Literal_TN(adjusted_offset, 4),
01732 OP_opnd(op, base_opnd_num),
01733 &ops);
01734 CG_LOOP_Init_OPS(&ops);
01735 BB_Insert_Ops_Before(body, next_op, &ops);
01736 TN *imm = Gen_Literal_TN(offset, 4);
01737 Set_OP_opnd(op, imm_opnd_num, imm);
01738 SET_PF_PRUNED(pf_ptr);
01739
01740
01741 if (PF_PTR_wn_pref_2L(pf_ptr)) {
01742 PF_POINTER* pf2_pf_ptr = (PF_POINTER*)
01743 WN_MAP_Get(WN_MAP_PREFETCH, PF_PTR_wn_pref_2L(pf_ptr));
01744 if (pf2_pf_ptr) {
01745 SET_PF_PRUNED(pf2_pf_ptr);
01746 }
01747 }
01748 }
01749 }
01750 }
01751 }
01752 }
01753 }
01754
01755
01756
01757 {
01758 for (OP *op = BB_first_op(body); op != NULL; op = next_op) {
01759 next_op = OP_next(op);
01760 if (OP_prefetch(op)) {
01761 WN *wn = Get_WN_From_Memory_OP( op);
01762 PF_POINTER *pf_ptr = (PF_POINTER *) WN_MAP_Get(WN_MAP_PREFETCH,wn);
01763 if (pf_ptr && PF_PRUNED(pf_ptr)) {
01764 if (trace)
01765 fprintf(TFile, "<swp_pref> removing prefetch OP%d\n", OP_map_idx(op));
01766 BB_Remove_Op(body, op);
01767 }
01768 }
01769 }
01770 }
01771 }
01772
01773