00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "coretypes.h"
00024 #include "tm.h"
00025 #include "tree.h"
00026 #include "rtl.h"
00027 #include "real.h"
00028 #include "flags.h"
00029 #include "tree-flow.h"
00030 #include "tree-gimple.h"
00031 #include "tree-iterator.h"
00032 #include "tree-pass.h"
00033 #include "tree-ssa-propagate.h"
00034 #include "diagnostic.h"
00035
00036
00037
00038
00039
00040
00041 typedef enum
00042 {
00043 UNINITIALIZED = 0,
00044 ONLY_REAL = 1,
00045 ONLY_IMAG = 2,
00046 VARYING = 3
00047 } complex_lattice_t;
00048
00049 #define PAIR(a, b) ((a) << 2 | (b))
00050
00051 DEF_VEC_I(complex_lattice_t);
00052 DEF_VEC_ALLOC_I(complex_lattice_t, heap);
00053
00054 static VEC(complex_lattice_t, heap) *complex_lattice_values;
00055
00056
00057
00058 static htab_t complex_variable_components;
00059
00060
00061 static VEC(tree, heap) *complex_ssa_name_components;
00062
00063
00064
00065 static tree
00066 cvc_lookup (unsigned int uid)
00067 {
00068 struct int_tree_map *h, in;
00069 in.uid = uid;
00070 h = htab_find_with_hash (complex_variable_components, &in, uid);
00071 return h ? h->to : NULL;
00072 }
00073
00074
00075
00076 static void
00077 cvc_insert (unsigned int uid, tree to)
00078 {
00079 struct int_tree_map *h;
00080 void **loc;
00081
00082 h = XNEW (struct int_tree_map);
00083 h->uid = uid;
00084 h->to = to;
00085 loc = htab_find_slot_with_hash (complex_variable_components, h,
00086 uid, INSERT);
00087 *(struct int_tree_map **) loc = h;
00088 }
00089
00090
00091
00092
00093 static int
00094 some_nonzerop (tree t)
00095 {
00096 int zerop = false;
00097
00098 if (TREE_CODE (t) == REAL_CST)
00099 zerop = REAL_VALUES_IDENTICAL (TREE_REAL_CST (t), dconst0);
00100 else if (TREE_CODE (t) == INTEGER_CST)
00101 zerop = integer_zerop (t);
00102
00103 return !zerop;
00104 }
00105
00106
00107
00108
00109 static complex_lattice_t
00110 find_lattice_value (tree t)
00111 {
00112 tree real, imag;
00113 int r, i;
00114 complex_lattice_t ret;
00115
00116 switch (TREE_CODE (t))
00117 {
00118 case SSA_NAME:
00119 return VEC_index (complex_lattice_t, complex_lattice_values,
00120 SSA_NAME_VERSION (t));
00121
00122 case COMPLEX_CST:
00123 real = TREE_REALPART (t);
00124 imag = TREE_IMAGPART (t);
00125 break;
00126
00127 case COMPLEX_EXPR:
00128 real = TREE_OPERAND (t, 0);
00129 imag = TREE_OPERAND (t, 1);
00130 break;
00131
00132 default:
00133 gcc_unreachable ();
00134 }
00135
00136 r = some_nonzerop (real);
00137 i = some_nonzerop (imag);
00138 ret = r*ONLY_REAL + i*ONLY_IMAG;
00139
00140
00141
00142
00143 if (ret == UNINITIALIZED)
00144 ret = ONLY_REAL;
00145
00146 return ret;
00147 }
00148
00149
00150
00151
00152 static bool
00153 is_complex_reg (tree lhs)
00154 {
00155 return TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE && is_gimple_reg (lhs);
00156 }
00157
00158
00159
00160 static void
00161 init_parameter_lattice_values (void)
00162 {
00163 tree parm;
00164
00165 for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = TREE_CHAIN (parm))
00166 if (is_complex_reg (parm) && var_ann (parm) != NULL)
00167 {
00168 tree ssa_name = default_def (parm);
00169 VEC_replace (complex_lattice_t, complex_lattice_values,
00170 SSA_NAME_VERSION (ssa_name), VARYING);
00171 }
00172 }
00173
00174
00175
00176
00177
00178 static bool
00179 init_dont_simulate_again (void)
00180 {
00181 basic_block bb;
00182 block_stmt_iterator bsi;
00183 tree phi;
00184 bool saw_a_complex_op = false;
00185
00186 FOR_EACH_BB (bb)
00187 {
00188 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00189 DONT_SIMULATE_AGAIN (phi) = !is_complex_reg (PHI_RESULT (phi));
00190
00191 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
00192 {
00193 tree orig_stmt, stmt, rhs = NULL;
00194 bool dsa;
00195
00196 orig_stmt = stmt = bsi_stmt (bsi);
00197
00198
00199
00200 dsa = !stmt_ends_bb_p (stmt);
00201
00202 switch (TREE_CODE (stmt))
00203 {
00204 case RETURN_EXPR:
00205
00206
00207 dsa = true;
00208 stmt = TREE_OPERAND (stmt, 0);
00209 if (!stmt || TREE_CODE (stmt) != MODIFY_EXPR)
00210 break;
00211
00212
00213 case MODIFY_EXPR:
00214 dsa = !is_complex_reg (TREE_OPERAND (stmt, 0));
00215 rhs = TREE_OPERAND (stmt, 1);
00216 break;
00217
00218 case COND_EXPR:
00219 rhs = TREE_OPERAND (stmt, 0);
00220 break;
00221
00222 default:
00223 break;
00224 }
00225
00226 if (rhs)
00227 switch (TREE_CODE (rhs))
00228 {
00229 case EQ_EXPR:
00230 case NE_EXPR:
00231 rhs = TREE_OPERAND (rhs, 0);
00232
00233
00234 case PLUS_EXPR:
00235 case MINUS_EXPR:
00236 case MULT_EXPR:
00237 case TRUNC_DIV_EXPR:
00238 case CEIL_DIV_EXPR:
00239 case FLOOR_DIV_EXPR:
00240 case ROUND_DIV_EXPR:
00241 case RDIV_EXPR:
00242 case NEGATE_EXPR:
00243 case CONJ_EXPR:
00244 if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE)
00245 saw_a_complex_op = true;
00246 break;
00247
00248 default:
00249 break;
00250 }
00251
00252 DONT_SIMULATE_AGAIN (orig_stmt) = dsa;
00253 }
00254 }
00255
00256 return saw_a_complex_op;
00257 }
00258
00259
00260
00261
00262 static enum ssa_prop_result
00263 complex_visit_stmt (tree stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
00264 tree *result_p)
00265 {
00266 complex_lattice_t new_l, old_l, op1_l, op2_l;
00267 unsigned int ver;
00268 tree lhs, rhs;
00269
00270 if (TREE_CODE (stmt) != MODIFY_EXPR)
00271 return SSA_PROP_VARYING;
00272
00273 lhs = TREE_OPERAND (stmt, 0);
00274 rhs = TREE_OPERAND (stmt, 1);
00275
00276
00277
00278 gcc_assert (TREE_CODE (lhs) == SSA_NAME);
00279 gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
00280
00281 *result_p = lhs;
00282 ver = SSA_NAME_VERSION (lhs);
00283 old_l = VEC_index (complex_lattice_t, complex_lattice_values, ver);
00284
00285 switch (TREE_CODE (rhs))
00286 {
00287 case SSA_NAME:
00288 case COMPLEX_EXPR:
00289 case COMPLEX_CST:
00290 new_l = find_lattice_value (rhs);
00291 break;
00292
00293 case PLUS_EXPR:
00294 case MINUS_EXPR:
00295 op1_l = find_lattice_value (TREE_OPERAND (rhs, 0));
00296 op2_l = find_lattice_value (TREE_OPERAND (rhs, 1));
00297
00298
00299
00300 new_l = op1_l | op2_l;
00301 break;
00302
00303 case MULT_EXPR:
00304 case RDIV_EXPR:
00305 case TRUNC_DIV_EXPR:
00306 case CEIL_DIV_EXPR:
00307 case FLOOR_DIV_EXPR:
00308 case ROUND_DIV_EXPR:
00309 op1_l = find_lattice_value (TREE_OPERAND (rhs, 0));
00310 op2_l = find_lattice_value (TREE_OPERAND (rhs, 1));
00311
00312
00313 if (op1_l == VARYING || op2_l == VARYING)
00314 new_l = VARYING;
00315
00316
00317 else if (op1_l == UNINITIALIZED)
00318 new_l = op2_l;
00319 else if (op2_l == UNINITIALIZED)
00320 new_l = op1_l;
00321 else
00322 {
00323
00324
00325
00326
00327 new_l = ((op1_l - ONLY_REAL) ^ (op2_l - ONLY_REAL)) + ONLY_REAL;
00328
00329
00330 new_l |= old_l;
00331 }
00332 break;
00333
00334 case NEGATE_EXPR:
00335 case CONJ_EXPR:
00336 new_l = find_lattice_value (TREE_OPERAND (rhs, 0));
00337 break;
00338
00339 default:
00340 new_l = VARYING;
00341 break;
00342 }
00343
00344
00345 if (new_l == old_l)
00346 return SSA_PROP_NOT_INTERESTING;
00347
00348 VEC_replace (complex_lattice_t, complex_lattice_values, ver, new_l);
00349 return new_l == VARYING ? SSA_PROP_VARYING : SSA_PROP_INTERESTING;
00350 }
00351
00352
00353
00354 static enum ssa_prop_result
00355 complex_visit_phi (tree phi)
00356 {
00357 complex_lattice_t new_l, old_l;
00358 unsigned int ver;
00359 tree lhs;
00360 int i;
00361
00362 lhs = PHI_RESULT (phi);
00363
00364
00365
00366 gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
00367
00368
00369 new_l = UNINITIALIZED;
00370 for (i = PHI_NUM_ARGS (phi) - 1; i >= 0; --i)
00371 new_l |= find_lattice_value (PHI_ARG_DEF (phi, i));
00372
00373 ver = SSA_NAME_VERSION (lhs);
00374 old_l = VEC_index (complex_lattice_t, complex_lattice_values, ver);
00375
00376 if (new_l == old_l)
00377 return SSA_PROP_NOT_INTERESTING;
00378
00379 VEC_replace (complex_lattice_t, complex_lattice_values, ver, new_l);
00380 return new_l == VARYING ? SSA_PROP_VARYING : SSA_PROP_INTERESTING;
00381 }
00382
00383
00384
00385 static tree
00386 create_one_component_var (tree type, tree orig, const char *prefix,
00387 const char *suffix, enum tree_code code)
00388 {
00389 tree r = create_tmp_var (type, prefix);
00390 add_referenced_var (r);
00391
00392 DECL_SOURCE_LOCATION (r) = DECL_SOURCE_LOCATION (orig);
00393 DECL_ARTIFICIAL (r) = 1;
00394
00395 if (DECL_NAME (orig) && !DECL_IGNORED_P (orig))
00396 {
00397 const char *name = IDENTIFIER_POINTER (DECL_NAME (orig));
00398 tree inner_type;
00399
00400 DECL_NAME (r) = get_identifier (ACONCAT ((name, suffix, NULL)));
00401
00402 inner_type = TREE_TYPE (TREE_TYPE (orig));
00403 SET_DECL_DEBUG_EXPR (r, build1 (code, type, orig));
00404 DECL_DEBUG_EXPR_IS_FROM (r) = 1;
00405 DECL_IGNORED_P (r) = 0;
00406 TREE_NO_WARNING (r) = TREE_NO_WARNING (orig);
00407 }
00408 else
00409 {
00410 DECL_IGNORED_P (r) = 1;
00411 TREE_NO_WARNING (r) = 1;
00412 }
00413
00414 return r;
00415 }
00416
00417
00418
00419 static tree
00420 get_component_var (tree var, bool imag_p)
00421 {
00422 size_t decl_index = DECL_UID (var) * 2 + imag_p;
00423 tree ret = cvc_lookup (decl_index);
00424
00425 if (ret == NULL)
00426 {
00427 ret = create_one_component_var (TREE_TYPE (TREE_TYPE (var)), var,
00428 imag_p ? "CI" : "CR",
00429 imag_p ? "$imag" : "$real",
00430 imag_p ? IMAGPART_EXPR : REALPART_EXPR);
00431 cvc_insert (decl_index, ret);
00432 }
00433
00434 return ret;
00435 }
00436
00437
00438
00439 static tree
00440 get_component_ssa_name (tree ssa_name, bool imag_p)
00441 {
00442 complex_lattice_t lattice = find_lattice_value (ssa_name);
00443 size_t ssa_name_index;
00444 tree ret;
00445
00446 if (lattice == (imag_p ? ONLY_REAL : ONLY_IMAG))
00447 {
00448 tree inner_type = TREE_TYPE (TREE_TYPE (ssa_name));
00449 if (SCALAR_FLOAT_TYPE_P (inner_type))
00450 return build_real (inner_type, dconst0);
00451 else
00452 return build_int_cst (inner_type, 0);
00453 }
00454
00455 ssa_name_index = SSA_NAME_VERSION (ssa_name) * 2 + imag_p;
00456 ret = VEC_index (tree, complex_ssa_name_components, ssa_name_index);
00457 if (ret == NULL)
00458 {
00459 ret = get_component_var (SSA_NAME_VAR (ssa_name), imag_p);
00460 ret = make_ssa_name (ret, NULL);
00461
00462
00463
00464 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ret)
00465 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name);
00466 if (TREE_CODE (SSA_NAME_VAR (ssa_name)) == VAR_DECL
00467 && IS_EMPTY_STMT (SSA_NAME_DEF_STMT (ssa_name)))
00468 {
00469 SSA_NAME_DEF_STMT (ret) = SSA_NAME_DEF_STMT (ssa_name);
00470 set_default_def (SSA_NAME_VAR (ret), ret);
00471 }
00472
00473 VEC_replace (tree, complex_ssa_name_components, ssa_name_index, ret);
00474 }
00475
00476 return ret;
00477 }
00478
00479
00480
00481
00482 static tree
00483 set_component_ssa_name (tree ssa_name, bool imag_p, tree value)
00484 {
00485 complex_lattice_t lattice = find_lattice_value (ssa_name);
00486 size_t ssa_name_index;
00487 tree comp, list, last;
00488
00489
00490
00491
00492 if (lattice == (imag_p ? ONLY_REAL : ONLY_IMAG))
00493 return NULL;
00494
00495
00496
00497
00498
00499 ssa_name_index = SSA_NAME_VERSION (ssa_name) * 2 + imag_p;
00500 comp = VEC_index (tree, complex_ssa_name_components, ssa_name_index);
00501 if (comp)
00502 ;
00503
00504
00505
00506
00507 else if (is_gimple_min_invariant (value))
00508 {
00509 VEC_replace (tree, complex_ssa_name_components, ssa_name_index, value);
00510 return NULL;
00511 }
00512 else if (TREE_CODE (value) == SSA_NAME
00513 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
00514 {
00515
00516
00517 if (DECL_IGNORED_P (SSA_NAME_VAR (value))
00518 && !DECL_IGNORED_P (SSA_NAME_VAR (ssa_name)))
00519 {
00520 comp = get_component_var (SSA_NAME_VAR (ssa_name), imag_p);
00521 replace_ssa_name_symbol (value, comp);
00522 }
00523
00524 VEC_replace (tree, complex_ssa_name_components, ssa_name_index, value);
00525 return NULL;
00526 }
00527
00528
00529
00530 else
00531 comp = get_component_ssa_name (ssa_name, imag_p);
00532
00533
00534 value = force_gimple_operand (value, &list, false, NULL);
00535 last = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, value);
00536 append_to_statement_list (last, &list);
00537
00538 gcc_assert (SSA_NAME_DEF_STMT (comp) == NULL);
00539 SSA_NAME_DEF_STMT (comp) = last;
00540
00541 return list;
00542 }
00543
00544
00545
00546
00547
00548 static tree
00549 extract_component (block_stmt_iterator *bsi, tree t, bool imagpart_p,
00550 bool gimple_p)
00551 {
00552 switch (TREE_CODE (t))
00553 {
00554 case COMPLEX_CST:
00555 return imagpart_p ? TREE_IMAGPART (t) : TREE_REALPART (t);
00556
00557 case COMPLEX_EXPR:
00558 return TREE_OPERAND (t, imagpart_p);
00559
00560 case VAR_DECL:
00561 case RESULT_DECL:
00562 case PARM_DECL:
00563 case INDIRECT_REF:
00564 case COMPONENT_REF:
00565 case ARRAY_REF:
00566 {
00567 tree inner_type = TREE_TYPE (TREE_TYPE (t));
00568
00569 t = build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR),
00570 inner_type, unshare_expr (t));
00571
00572 if (gimple_p)
00573 t = gimplify_val (bsi, inner_type, t);
00574
00575 return t;
00576 }
00577
00578 case SSA_NAME:
00579 return get_component_ssa_name (t, imagpart_p);
00580
00581 default:
00582 gcc_unreachable ();
00583 }
00584 }
00585
00586
00587
00588 static void
00589 update_complex_components (block_stmt_iterator *bsi, tree stmt, tree r, tree i)
00590 {
00591 tree lhs = TREE_OPERAND (stmt, 0);
00592 tree list;
00593
00594 list = set_component_ssa_name (lhs, false, r);
00595 if (list)
00596 bsi_insert_after (bsi, list, BSI_CONTINUE_LINKING);
00597
00598 list = set_component_ssa_name (lhs, true, i);
00599 if (list)
00600 bsi_insert_after (bsi, list, BSI_CONTINUE_LINKING);
00601 }
00602
00603 static void
00604 update_complex_components_on_edge (edge e, tree lhs, tree r, tree i)
00605 {
00606 tree list;
00607
00608 list = set_component_ssa_name (lhs, false, r);
00609 if (list)
00610 bsi_insert_on_edge (e, list);
00611
00612 list = set_component_ssa_name (lhs, true, i);
00613 if (list)
00614 bsi_insert_on_edge (e, list);
00615 }
00616
00617
00618
00619 static void
00620 update_complex_assignment (block_stmt_iterator *bsi, tree r, tree i)
00621 {
00622 tree stmt, mod;
00623 tree type;
00624
00625 mod = stmt = bsi_stmt (*bsi);
00626 if (TREE_CODE (stmt) == RETURN_EXPR)
00627 mod = TREE_OPERAND (mod, 0);
00628 else if (in_ssa_p)
00629 update_complex_components (bsi, stmt, r, i);
00630
00631 type = TREE_TYPE (TREE_OPERAND (mod, 1));
00632 TREE_OPERAND (mod, 1) = build2 (COMPLEX_EXPR, type, r, i);
00633 update_stmt (stmt);
00634 }
00635
00636
00637
00638
00639 static void
00640 update_parameter_components (void)
00641 {
00642 edge entry_edge = single_succ_edge (ENTRY_BLOCK_PTR);
00643 tree parm;
00644
00645 for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = TREE_CHAIN (parm))
00646 {
00647 tree type = TREE_TYPE (parm);
00648 tree ssa_name, r, i;
00649
00650 if (TREE_CODE (type) != COMPLEX_TYPE || !is_gimple_reg (parm))
00651 continue;
00652
00653 type = TREE_TYPE (type);
00654 ssa_name = default_def (parm);
00655 if (!ssa_name)
00656 continue;
00657
00658 r = build1 (REALPART_EXPR, type, ssa_name);
00659 i = build1 (IMAGPART_EXPR, type, ssa_name);
00660 update_complex_components_on_edge (entry_edge, ssa_name, r, i);
00661 }
00662 }
00663
00664
00665
00666
00667 static void
00668 update_phi_components (basic_block bb)
00669 {
00670 tree phi;
00671
00672 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00673 if (is_complex_reg (PHI_RESULT (phi)))
00674 {
00675 tree lr, li, pr = NULL, pi = NULL;
00676 unsigned int i, n;
00677
00678 lr = get_component_ssa_name (PHI_RESULT (phi), false);
00679 if (TREE_CODE (lr) == SSA_NAME)
00680 {
00681 pr = create_phi_node (lr, bb);
00682 SSA_NAME_DEF_STMT (lr) = pr;
00683 }
00684
00685 li = get_component_ssa_name (PHI_RESULT (phi), true);
00686 if (TREE_CODE (li) == SSA_NAME)
00687 {
00688 pi = create_phi_node (li, bb);
00689 SSA_NAME_DEF_STMT (li) = pi;
00690 }
00691
00692 for (i = 0, n = PHI_NUM_ARGS (phi); i < n; ++i)
00693 {
00694 tree comp, arg = PHI_ARG_DEF (phi, i);
00695 if (pr)
00696 {
00697 comp = extract_component (NULL, arg, false, false);
00698 SET_PHI_ARG_DEF (pr, i, comp);
00699 }
00700 if (pi)
00701 {
00702 comp = extract_component (NULL, arg, true, false);
00703 SET_PHI_ARG_DEF (pi, i, comp);
00704 }
00705 }
00706 }
00707 }
00708
00709
00710
00711 static void
00712 update_all_vops (tree stmt)
00713 {
00714 ssa_op_iter iter;
00715 tree sym;
00716
00717 FOR_EACH_SSA_TREE_OPERAND (sym, stmt, iter, SSA_OP_ALL_VIRTUALS)
00718 {
00719 if (TREE_CODE (sym) == SSA_NAME)
00720 sym = SSA_NAME_VAR (sym);
00721 mark_sym_for_renaming (sym);
00722 }
00723 }
00724
00725
00726
00727 static void
00728 expand_complex_move (block_stmt_iterator *bsi, tree stmt, tree type,
00729 tree lhs, tree rhs)
00730 {
00731 tree inner_type = TREE_TYPE (type);
00732 tree r, i;
00733
00734 if (TREE_CODE (lhs) == SSA_NAME)
00735 {
00736 if (is_ctrl_altering_stmt (bsi_stmt (*bsi)))
00737 {
00738 edge_iterator ei;
00739 edge e;
00740
00741
00742
00743
00744 FOR_EACH_EDGE (e, ei, bsi->bb->succs)
00745 if (e->flags & EDGE_FALLTHRU)
00746 goto found_fallthru;
00747 gcc_unreachable ();
00748 found_fallthru:
00749
00750 r = build1 (REALPART_EXPR, inner_type, lhs);
00751 i = build1 (IMAGPART_EXPR, inner_type, lhs);
00752 update_complex_components_on_edge (e, lhs, r, i);
00753 }
00754 else if (TREE_CODE (rhs) == CALL_EXPR || TREE_SIDE_EFFECTS (rhs))
00755 {
00756 r = build1 (REALPART_EXPR, inner_type, lhs);
00757 i = build1 (IMAGPART_EXPR, inner_type, lhs);
00758 update_complex_components (bsi, stmt, r, i);
00759 }
00760 else
00761 {
00762 update_all_vops (bsi_stmt (*bsi));
00763 r = extract_component (bsi, rhs, 0, true);
00764 i = extract_component (bsi, rhs, 1, true);
00765 update_complex_assignment (bsi, r, i);
00766 }
00767 }
00768 else if (TREE_CODE (rhs) == SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
00769 {
00770 tree x;
00771
00772 r = extract_component (bsi, rhs, 0, false);
00773 i = extract_component (bsi, rhs, 1, false);
00774
00775 x = build1 (REALPART_EXPR, inner_type, unshare_expr (lhs));
00776 x = build2 (MODIFY_EXPR, inner_type, x, r);
00777 bsi_insert_before (bsi, x, BSI_SAME_STMT);
00778
00779 if (stmt == bsi_stmt (*bsi))
00780 {
00781 x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
00782 TREE_OPERAND (stmt, 0) = x;
00783 TREE_OPERAND (stmt, 1) = i;
00784 TREE_TYPE (stmt) = inner_type;
00785 }
00786 else
00787 {
00788 x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
00789 x = build2 (MODIFY_EXPR, inner_type, x, i);
00790 bsi_insert_before (bsi, x, BSI_SAME_STMT);
00791
00792 stmt = bsi_stmt (*bsi);
00793 gcc_assert (TREE_CODE (stmt) == RETURN_EXPR);
00794 TREE_OPERAND (stmt, 0) = lhs;
00795 }
00796
00797 update_all_vops (stmt);
00798 update_stmt (stmt);
00799 }
00800 }
00801
00802
00803
00804
00805
00806
00807 static void
00808 expand_complex_addition (block_stmt_iterator *bsi, tree inner_type,
00809 tree ar, tree ai, tree br, tree bi,
00810 enum tree_code code,
00811 complex_lattice_t al, complex_lattice_t bl)
00812 {
00813 tree rr, ri;
00814
00815 switch (PAIR (al, bl))
00816 {
00817 case PAIR (ONLY_REAL, ONLY_REAL):
00818 rr = gimplify_build2 (bsi, code, inner_type, ar, br);
00819 ri = ai;
00820 break;
00821
00822 case PAIR (ONLY_REAL, ONLY_IMAG):
00823 rr = ar;
00824 if (code == MINUS_EXPR)
00825 ri = gimplify_build2 (bsi, MINUS_EXPR, inner_type, ai, bi);
00826 else
00827 ri = bi;
00828 break;
00829
00830 case PAIR (ONLY_IMAG, ONLY_REAL):
00831 if (code == MINUS_EXPR)
00832 rr = gimplify_build2 (bsi, MINUS_EXPR, inner_type, ar, br);
00833 else
00834 rr = br;
00835 ri = ai;
00836 break;
00837
00838 case PAIR (ONLY_IMAG, ONLY_IMAG):
00839 rr = ar;
00840 ri = gimplify_build2 (bsi, code, inner_type, ai, bi);
00841 break;
00842
00843 case PAIR (VARYING, ONLY_REAL):
00844 rr = gimplify_build2 (bsi, code, inner_type, ar, br);
00845 ri = ai;
00846 break;
00847
00848 case PAIR (VARYING, ONLY_IMAG):
00849 rr = ar;
00850 ri = gimplify_build2 (bsi, code, inner_type, ai, bi);
00851 break;
00852
00853 case PAIR (ONLY_REAL, VARYING):
00854 if (code == MINUS_EXPR)
00855 goto general;
00856 rr = gimplify_build2 (bsi, code, inner_type, ar, br);
00857 ri = bi;
00858 break;
00859
00860 case PAIR (ONLY_IMAG, VARYING):
00861 if (code == MINUS_EXPR)
00862 goto general;
00863 rr = br;
00864 ri = gimplify_build2 (bsi, code, inner_type, ai, bi);
00865 break;
00866
00867 case PAIR (VARYING, VARYING):
00868 general:
00869 rr = gimplify_build2 (bsi, code, inner_type, ar, br);
00870 ri = gimplify_build2 (bsi, code, inner_type, ai, bi);
00871 break;
00872
00873 default:
00874 gcc_unreachable ();
00875 }
00876
00877 update_complex_assignment (bsi, rr, ri);
00878 }
00879
00880
00881
00882
00883 static void
00884 expand_complex_libcall (block_stmt_iterator *bsi, tree ar, tree ai,
00885 tree br, tree bi, enum tree_code code)
00886 {
00887 enum machine_mode mode;
00888 enum built_in_function bcode;
00889 tree args, fn, stmt, type;
00890
00891 args = tree_cons (NULL, bi, NULL);
00892 args = tree_cons (NULL, br, args);
00893 args = tree_cons (NULL, ai, args);
00894 args = tree_cons (NULL, ar, args);
00895
00896 stmt = bsi_stmt (*bsi);
00897 type = TREE_TYPE (TREE_OPERAND (stmt, 1));
00898
00899 mode = TYPE_MODE (type);
00900 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
00901 if (code == MULT_EXPR)
00902 bcode = BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT;
00903 else if (code == RDIV_EXPR)
00904 bcode = BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT;
00905 else
00906 gcc_unreachable ();
00907 fn = built_in_decls[bcode];
00908
00909 TREE_OPERAND (stmt, 1)
00910 = build3 (CALL_EXPR, type, build_fold_addr_expr (fn), args, NULL);
00911 update_stmt (stmt);
00912
00913 if (in_ssa_p)
00914 {
00915 tree lhs = TREE_OPERAND (stmt, 0);
00916 type = TREE_TYPE (type);
00917 update_complex_components (bsi, stmt,
00918 build1 (REALPART_EXPR, type, lhs),
00919 build1 (IMAGPART_EXPR, type, lhs));
00920 }
00921 }
00922
00923
00924
00925
00926
00927 static void
00928 expand_complex_multiplication (block_stmt_iterator *bsi, tree inner_type,
00929 tree ar, tree ai, tree br, tree bi,
00930 complex_lattice_t al, complex_lattice_t bl)
00931 {
00932 tree rr, ri;
00933
00934 if (al < bl)
00935 {
00936 complex_lattice_t tl;
00937 rr = ar, ar = br, br = rr;
00938 ri = ai, ai = bi, bi = ri;
00939 tl = al, al = bl, bl = tl;
00940 }
00941
00942 switch (PAIR (al, bl))
00943 {
00944 case PAIR (ONLY_REAL, ONLY_REAL):
00945 rr = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
00946 ri = ai;
00947 break;
00948
00949 case PAIR (ONLY_IMAG, ONLY_REAL):
00950 rr = ar;
00951 if (TREE_CODE (ai) == REAL_CST
00952 && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ai), dconst1))
00953 ri = br;
00954 else
00955 ri = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
00956 break;
00957
00958 case PAIR (ONLY_IMAG, ONLY_IMAG):
00959 rr = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
00960 rr = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, rr);
00961 ri = ar;
00962 break;
00963
00964 case PAIR (VARYING, ONLY_REAL):
00965 rr = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
00966 ri = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
00967 break;
00968
00969 case PAIR (VARYING, ONLY_IMAG):
00970 rr = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
00971 rr = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, rr);
00972 ri = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, bi);
00973 break;
00974
00975 case PAIR (VARYING, VARYING):
00976 if (flag_complex_method == 2 && SCALAR_FLOAT_TYPE_P (inner_type))
00977 {
00978 expand_complex_libcall (bsi, ar, ai, br, bi, MULT_EXPR);
00979 return;
00980 }
00981 else
00982 {
00983 tree t1, t2, t3, t4;
00984
00985 t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
00986 t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
00987 t3 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, bi);
00988
00989
00990
00991 if (ar == br && ai == bi)
00992 t4 = t3;
00993 else
00994 t4 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
00995
00996 rr = gimplify_build2 (bsi, MINUS_EXPR, inner_type, t1, t2);
00997 ri = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t3, t4);
00998 }
00999 break;
01000
01001 default:
01002 gcc_unreachable ();
01003 }
01004
01005 update_complex_assignment (bsi, rr, ri);
01006 }
01007
01008
01009
01010
01011
01012
01013 static void
01014 expand_complex_div_straight (block_stmt_iterator *bsi, tree inner_type,
01015 tree ar, tree ai, tree br, tree bi,
01016 enum tree_code code)
01017 {
01018 tree rr, ri, div, t1, t2, t3;
01019
01020 t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, br, br);
01021 t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, bi, bi);
01022 div = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, t2);
01023
01024 t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
01025 t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
01026 t3 = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, t2);
01027 rr = gimplify_build2 (bsi, code, inner_type, t3, div);
01028
01029 t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
01030 t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, bi);
01031 t3 = gimplify_build2 (bsi, MINUS_EXPR, inner_type, t1, t2);
01032 ri = gimplify_build2 (bsi, code, inner_type, t3, div);
01033
01034 update_complex_assignment (bsi, rr, ri);
01035 }
01036
01037
01038
01039
01040 static void
01041 expand_complex_div_wide (block_stmt_iterator *bsi, tree inner_type,
01042 tree ar, tree ai, tree br, tree bi,
01043 enum tree_code code)
01044 {
01045 tree rr, ri, ratio, div, t1, t2, tr, ti, cond;
01046 basic_block bb_cond, bb_true, bb_false, bb_join;
01047
01048
01049 t1 = gimplify_build1 (bsi, ABS_EXPR, inner_type, br);
01050 t2 = gimplify_build1 (bsi, ABS_EXPR, inner_type, bi);
01051 cond = fold_build2 (LT_EXPR, boolean_type_node, t1, t2);
01052 STRIP_NOPS (cond);
01053
01054 bb_cond = bb_true = bb_false = bb_join = NULL;
01055 rr = ri = tr = ti = NULL;
01056 if (!TREE_CONSTANT (cond))
01057 {
01058 edge e;
01059
01060 cond = build3 (COND_EXPR, void_type_node, cond, NULL_TREE, NULL_TREE);
01061 bsi_insert_before (bsi, cond, BSI_SAME_STMT);
01062
01063
01064 e = split_block (bsi->bb, cond);
01065 bb_cond = e->src;
01066 bb_join = e->dest;
01067 bb_true = create_empty_bb (bb_cond);
01068 bb_false = create_empty_bb (bb_true);
01069
01070 t1 = build1 (GOTO_EXPR, void_type_node, tree_block_label (bb_true));
01071 t2 = build1 (GOTO_EXPR, void_type_node, tree_block_label (bb_false));
01072 COND_EXPR_THEN (cond) = t1;
01073 COND_EXPR_ELSE (cond) = t2;
01074
01075
01076 e->flags = EDGE_TRUE_VALUE;
01077 redirect_edge_succ (e, bb_true);
01078 make_edge (bb_cond, bb_false, EDGE_FALSE_VALUE);
01079 make_edge (bb_true, bb_join, EDGE_FALLTHRU);
01080 make_edge (bb_false, bb_join, EDGE_FALLTHRU);
01081
01082
01083
01084 if (dom_info_available_p (CDI_DOMINATORS))
01085 {
01086 set_immediate_dominator (CDI_DOMINATORS, bb_true, bb_cond);
01087 set_immediate_dominator (CDI_DOMINATORS, bb_false, bb_cond);
01088 }
01089
01090 rr = make_rename_temp (inner_type, NULL);
01091 ri = make_rename_temp (inner_type, NULL);
01092 }
01093
01094
01095
01096
01097
01098
01099
01100
01101 if (bb_true || integer_nonzerop (cond))
01102 {
01103 if (bb_true)
01104 {
01105 *bsi = bsi_last (bb_true);
01106 bsi_insert_after (bsi, build_empty_stmt (), BSI_NEW_STMT);
01107 }
01108
01109 ratio = gimplify_build2 (bsi, code, inner_type, br, bi);
01110
01111 t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, br, ratio);
01112 div = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, bi);
01113
01114 t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, ratio);
01115 tr = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, ai);
01116
01117 t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, ratio);
01118 ti = gimplify_build2 (bsi, MINUS_EXPR, inner_type, t1, ar);
01119
01120 tr = gimplify_build2 (bsi, code, inner_type, tr, div);
01121 ti = gimplify_build2 (bsi, code, inner_type, ti, div);
01122
01123 if (bb_true)
01124 {
01125 t1 = build2 (MODIFY_EXPR, inner_type, rr, tr);
01126 bsi_insert_before (bsi, t1, BSI_SAME_STMT);
01127 t1 = build2 (MODIFY_EXPR, inner_type, ri, ti);
01128 bsi_insert_before (bsi, t1, BSI_SAME_STMT);
01129 bsi_remove (bsi, true);
01130 }
01131 }
01132
01133
01134
01135
01136
01137
01138
01139
01140 if (bb_false || integer_zerop (cond))
01141 {
01142 if (bb_false)
01143 {
01144 *bsi = bsi_last (bb_false);
01145 bsi_insert_after (bsi, build_empty_stmt (), BSI_NEW_STMT);
01146 }
01147
01148 ratio = gimplify_build2 (bsi, code, inner_type, bi, br);
01149
01150 t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, bi, ratio);
01151 div = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, br);
01152
01153 t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, ratio);
01154 tr = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, ar);
01155
01156 t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, ratio);
01157 ti = gimplify_build2 (bsi, MINUS_EXPR, inner_type, ai, t1);
01158
01159 tr = gimplify_build2 (bsi, code, inner_type, tr, div);
01160 ti = gimplify_build2 (bsi, code, inner_type, ti, div);
01161
01162 if (bb_false)
01163 {
01164 t1 = build2 (MODIFY_EXPR, inner_type, rr, tr);
01165 bsi_insert_before (bsi, t1, BSI_SAME_STMT);
01166 t1 = build2 (MODIFY_EXPR, inner_type, ri, ti);
01167 bsi_insert_before (bsi, t1, BSI_SAME_STMT);
01168 bsi_remove (bsi, true);
01169 }
01170 }
01171
01172 if (bb_join)
01173 *bsi = bsi_start (bb_join);
01174 else
01175 rr = tr, ri = ti;
01176
01177 update_complex_assignment (bsi, rr, ri);
01178 }
01179
01180
01181
01182 static void
01183 expand_complex_division (block_stmt_iterator *bsi, tree inner_type,
01184 tree ar, tree ai, tree br, tree bi,
01185 enum tree_code code,
01186 complex_lattice_t al, complex_lattice_t bl)
01187 {
01188 tree rr, ri;
01189
01190 switch (PAIR (al, bl))
01191 {
01192 case PAIR (ONLY_REAL, ONLY_REAL):
01193 rr = gimplify_build2 (bsi, code, inner_type, ar, br);
01194 ri = ai;
01195 break;
01196
01197 case PAIR (ONLY_REAL, ONLY_IMAG):
01198 rr = ai;
01199 ri = gimplify_build2 (bsi, code, inner_type, ar, bi);
01200 ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ri);
01201 break;
01202
01203 case PAIR (ONLY_IMAG, ONLY_REAL):
01204 rr = ar;
01205 ri = gimplify_build2 (bsi, code, inner_type, ai, br);
01206 break;
01207
01208 case PAIR (ONLY_IMAG, ONLY_IMAG):
01209 rr = gimplify_build2 (bsi, code, inner_type, ai, bi);
01210 ri = ar;
01211 break;
01212
01213 case PAIR (VARYING, ONLY_REAL):
01214 rr = gimplify_build2 (bsi, code, inner_type, ar, br);
01215 ri = gimplify_build2 (bsi, code, inner_type, ai, br);
01216 break;
01217
01218 case PAIR (VARYING, ONLY_IMAG):
01219 rr = gimplify_build2 (bsi, code, inner_type, ai, bi);
01220 ri = gimplify_build2 (bsi, code, inner_type, ar, bi);
01221 ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ri);
01222
01223 case PAIR (ONLY_REAL, VARYING):
01224 case PAIR (ONLY_IMAG, VARYING):
01225 case PAIR (VARYING, VARYING):
01226 switch (flag_complex_method)
01227 {
01228 case 0:
01229
01230 expand_complex_div_straight (bsi, inner_type, ar, ai, br, bi, code);
01231 break;
01232
01233 case 2:
01234 if (SCALAR_FLOAT_TYPE_P (inner_type))
01235 {
01236 expand_complex_libcall (bsi, ar, ai, br, bi, code);
01237 break;
01238 }
01239
01240
01241 case 1:
01242
01243 expand_complex_div_wide (bsi, inner_type, ar, ai, br, bi, code);
01244 break;
01245
01246 default:
01247 gcc_unreachable ();
01248 }
01249 return;
01250
01251 default:
01252 gcc_unreachable ();
01253 }
01254
01255 update_complex_assignment (bsi, rr, ri);
01256 }
01257
01258
01259
01260
01261
01262 static void
01263 expand_complex_negation (block_stmt_iterator *bsi, tree inner_type,
01264 tree ar, tree ai)
01265 {
01266 tree rr, ri;
01267
01268 rr = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ar);
01269 ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ai);
01270
01271 update_complex_assignment (bsi, rr, ri);
01272 }
01273
01274
01275
01276
01277
01278 static void
01279 expand_complex_conjugate (block_stmt_iterator *bsi, tree inner_type,
01280 tree ar, tree ai)
01281 {
01282 tree ri;
01283
01284 ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ai);
01285
01286 update_complex_assignment (bsi, ar, ri);
01287 }
01288
01289
01290
01291 static void
01292 expand_complex_comparison (block_stmt_iterator *bsi, tree ar, tree ai,
01293 tree br, tree bi, enum tree_code code)
01294 {
01295 tree cr, ci, cc, stmt, expr, type;
01296
01297 cr = gimplify_build2 (bsi, code, boolean_type_node, ar, br);
01298 ci = gimplify_build2 (bsi, code, boolean_type_node, ai, bi);
01299 cc = gimplify_build2 (bsi,
01300 (code == EQ_EXPR ? TRUTH_AND_EXPR : TRUTH_OR_EXPR),
01301 boolean_type_node, cr, ci);
01302
01303 stmt = expr = bsi_stmt (*bsi);
01304
01305 switch (TREE_CODE (stmt))
01306 {
01307 case RETURN_EXPR:
01308 expr = TREE_OPERAND (stmt, 0);
01309
01310 case MODIFY_EXPR:
01311 type = TREE_TYPE (TREE_OPERAND (expr, 1));
01312 TREE_OPERAND (expr, 1) = fold_convert (type, cc);
01313 break;
01314 case COND_EXPR:
01315 TREE_OPERAND (stmt, 0) = cc;
01316 break;
01317 default:
01318 gcc_unreachable ();
01319 }
01320
01321 update_stmt (stmt);
01322 }
01323
01324
01325
01326 static void
01327 expand_complex_operations_1 (block_stmt_iterator *bsi)
01328 {
01329 tree stmt = bsi_stmt (*bsi);
01330 tree rhs, type, inner_type;
01331 tree ac, ar, ai, bc, br, bi;
01332 complex_lattice_t al, bl;
01333 enum tree_code code;
01334
01335 switch (TREE_CODE (stmt))
01336 {
01337 case RETURN_EXPR:
01338 stmt = TREE_OPERAND (stmt, 0);
01339 if (!stmt)
01340 return;
01341 if (TREE_CODE (stmt) != MODIFY_EXPR)
01342 return;
01343
01344
01345 case MODIFY_EXPR:
01346 rhs = TREE_OPERAND (stmt, 1);
01347 break;
01348
01349 case COND_EXPR:
01350 rhs = TREE_OPERAND (stmt, 0);
01351 break;
01352
01353 default:
01354 return;
01355 }
01356
01357 type = TREE_TYPE (rhs);
01358 code = TREE_CODE (rhs);
01359
01360
01361 switch (code)
01362 {
01363 case PLUS_EXPR:
01364 case MINUS_EXPR:
01365 case MULT_EXPR:
01366 case TRUNC_DIV_EXPR:
01367 case CEIL_DIV_EXPR:
01368 case FLOOR_DIV_EXPR:
01369 case ROUND_DIV_EXPR:
01370 case RDIV_EXPR:
01371 case NEGATE_EXPR:
01372 case CONJ_EXPR:
01373 if (TREE_CODE (type) != COMPLEX_TYPE)
01374 return;
01375 inner_type = TREE_TYPE (type);
01376 break;
01377
01378 case EQ_EXPR:
01379 case NE_EXPR:
01380 inner_type = TREE_TYPE (TREE_OPERAND (rhs, 1));
01381 if (TREE_CODE (inner_type) != COMPLEX_TYPE)
01382 return;
01383 break;
01384
01385 default:
01386 {
01387 tree lhs = TREE_OPERAND (stmt, 0);
01388 tree rhs = TREE_OPERAND (stmt, 1);
01389
01390 if (TREE_CODE (type) == COMPLEX_TYPE)
01391 expand_complex_move (bsi, stmt, type, lhs, rhs);
01392 else if ((TREE_CODE (rhs) == REALPART_EXPR
01393 || TREE_CODE (rhs) == IMAGPART_EXPR)
01394 && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
01395 {
01396 TREE_OPERAND (stmt, 1)
01397 = extract_component (bsi, TREE_OPERAND (rhs, 0),
01398 TREE_CODE (rhs) == IMAGPART_EXPR, false);
01399 update_stmt (stmt);
01400 }
01401 }
01402 return;
01403 }
01404
01405
01406
01407 ac = TREE_OPERAND (rhs, 0);
01408 ar = extract_component (bsi, ac, 0, true);
01409 ai = extract_component (bsi, ac, 1, true);
01410
01411 if (TREE_CODE_CLASS (code) == tcc_unary)
01412 bc = br = bi = NULL;
01413 else
01414 {
01415 bc = TREE_OPERAND (rhs, 1);
01416 if (ac == bc)
01417 br = ar, bi = ai;
01418 else
01419 {
01420 br = extract_component (bsi, bc, 0, true);
01421 bi = extract_component (bsi, bc, 1, true);
01422 }
01423 }
01424
01425 if (in_ssa_p)
01426 {
01427 al = find_lattice_value (ac);
01428 if (al == UNINITIALIZED)
01429 al = VARYING;
01430
01431 if (TREE_CODE_CLASS (code) == tcc_unary)
01432 bl = UNINITIALIZED;
01433 else if (ac == bc)
01434 bl = al;
01435 else
01436 {
01437 bl = find_lattice_value (bc);
01438 if (bl == UNINITIALIZED)
01439 bl = VARYING;
01440 }
01441 }
01442 else
01443 al = bl = VARYING;
01444
01445 switch (code)
01446 {
01447 case PLUS_EXPR:
01448 case MINUS_EXPR:
01449 expand_complex_addition (bsi, inner_type, ar, ai, br, bi, code, al, bl);
01450 break;
01451
01452 case MULT_EXPR:
01453 expand_complex_multiplication (bsi, inner_type, ar, ai, br, bi, al, bl);
01454 break;
01455
01456 case TRUNC_DIV_EXPR:
01457 case CEIL_DIV_EXPR:
01458 case FLOOR_DIV_EXPR:
01459 case ROUND_DIV_EXPR:
01460 case RDIV_EXPR:
01461 expand_complex_division (bsi, inner_type, ar, ai, br, bi, code, al, bl);
01462 break;
01463
01464 case NEGATE_EXPR:
01465 expand_complex_negation (bsi, inner_type, ar, ai);
01466 break;
01467
01468 case CONJ_EXPR:
01469 expand_complex_conjugate (bsi, inner_type, ar, ai);
01470 break;
01471
01472 case EQ_EXPR:
01473 case NE_EXPR:
01474 expand_complex_comparison (bsi, ar, ai, br, bi, code);
01475 break;
01476
01477 default:
01478 gcc_unreachable ();
01479 }
01480 }
01481
01482
01483
01484
01485 static unsigned int
01486 tree_lower_complex (void)
01487 {
01488 int old_last_basic_block;
01489 block_stmt_iterator bsi;
01490 basic_block bb;
01491
01492 if (!init_dont_simulate_again ())
01493 return 0;
01494
01495 complex_lattice_values = VEC_alloc (complex_lattice_t, heap, num_ssa_names);
01496 VEC_safe_grow (complex_lattice_t, heap,
01497 complex_lattice_values, num_ssa_names);
01498 memset (VEC_address (complex_lattice_t, complex_lattice_values), 0,
01499 num_ssa_names * sizeof(complex_lattice_t));
01500
01501 init_parameter_lattice_values ();
01502 ssa_propagate (complex_visit_stmt, complex_visit_phi);
01503
01504 complex_variable_components = htab_create (10, int_tree_map_hash,
01505 int_tree_map_eq, free);
01506
01507 complex_ssa_name_components = VEC_alloc (tree, heap, 2*num_ssa_names);
01508 VEC_safe_grow (tree, heap, complex_ssa_name_components, 2*num_ssa_names);
01509 memset (VEC_address (tree, complex_ssa_name_components), 0,
01510 2 * num_ssa_names * sizeof(tree));
01511
01512 update_parameter_components ();
01513
01514
01515 old_last_basic_block = last_basic_block;
01516 FOR_EACH_BB (bb)
01517 {
01518 if (bb->index >= old_last_basic_block)
01519 continue;
01520 update_phi_components (bb);
01521 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
01522 expand_complex_operations_1 (&bsi);
01523 }
01524
01525 bsi_commit_edge_inserts ();
01526
01527 htab_delete (complex_variable_components);
01528 VEC_free (tree, heap, complex_ssa_name_components);
01529 VEC_free (complex_lattice_t, heap, complex_lattice_values);
01530 return 0;
01531 }
01532
01533 struct tree_opt_pass pass_lower_complex =
01534 {
01535 "cplxlower",
01536 0,
01537 tree_lower_complex,
01538 NULL,
01539 NULL,
01540 0,
01541 0,
01542 PROP_ssa,
01543 0,
01544 PROP_smt_usage,
01545 0,
01546 TODO_dump_func | TODO_ggc_collect
01547 | TODO_update_smt_usage
01548 | TODO_update_ssa
01549 | TODO_verify_stmts,
01550 0
01551 };
01552
01553
01554
01555
01556 static unsigned int
01557 tree_lower_complex_O0 (void)
01558 {
01559 int old_last_basic_block = last_basic_block;
01560 block_stmt_iterator bsi;
01561 basic_block bb;
01562
01563 FOR_EACH_BB (bb)
01564 {
01565 if (bb->index >= old_last_basic_block)
01566 continue;
01567 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
01568 expand_complex_operations_1 (&bsi);
01569 }
01570 return 0;
01571 }
01572
01573 static bool
01574 gate_no_optimization (void)
01575 {
01576
01577
01578 return optimize == 0 || sorrycount || errorcount;
01579 }
01580
01581 struct tree_opt_pass pass_lower_complex_O0 =
01582 {
01583 "cplxlower0",
01584 gate_no_optimization,
01585 tree_lower_complex_O0,
01586 NULL,
01587 NULL,
01588 0,
01589 0,
01590 PROP_cfg,
01591 0,
01592 0,
01593 0,
01594 TODO_dump_func | TODO_ggc_collect
01595 | TODO_verify_stmts,
01596 0
01597 };