comparison gcc/tree-ssa-loop-ivopts.c @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents 77e2b8dfacca
children f6334be47118
comparison
equal deleted inserted replaced
56:3c8a44c06a95 63:b7f97abdc517
1 /* Induction variable optimizations. 1 /* Induction variable optimizations.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify it 7 GCC is free software; you can redistribute it and/or modify it
65 #include "config.h" 65 #include "config.h"
66 #include "system.h" 66 #include "system.h"
67 #include "coretypes.h" 67 #include "coretypes.h"
68 #include "tm.h" 68 #include "tm.h"
69 #include "tree.h" 69 #include "tree.h"
70 #include "rtl.h"
71 #include "tm_p.h" 70 #include "tm_p.h"
72 #include "hard-reg-set.h"
73 #include "basic-block.h" 71 #include "basic-block.h"
74 #include "output.h" 72 #include "output.h"
75 #include "diagnostic.h" 73 #include "diagnostic.h"
74 #include "tree-pretty-print.h"
75 #include "gimple-pretty-print.h"
76 #include "tree-flow.h" 76 #include "tree-flow.h"
77 #include "tree-dump.h" 77 #include "tree-dump.h"
78 #include "timevar.h" 78 #include "timevar.h"
79 #include "cfgloop.h" 79 #include "cfgloop.h"
80 #include "varray.h"
81 #include "expr.h" 80 #include "expr.h"
82 #include "tree-pass.h" 81 #include "tree-pass.h"
83 #include "ggc.h" 82 #include "ggc.h"
84 #include "insn-config.h" 83 #include "insn-config.h"
85 #include "recog.h" 84 #include "recog.h"
118 { 117 {
119 tree name; /* The ssa name. */ 118 tree name; /* The ssa name. */
120 struct iv *iv; /* Induction variable description. */ 119 struct iv *iv; /* Induction variable description. */
121 bool has_nonlin_use; /* For a loop-level invariant, whether it is used in 120 bool has_nonlin_use; /* For a loop-level invariant, whether it is used in
122 an expression that is not an induction variable. */ 121 an expression that is not an induction variable. */
122 bool preserve_biv; /* For the original biv, whether to preserve it. */
123 unsigned inv_id; /* Id of an invariant. */ 123 unsigned inv_id; /* Id of an invariant. */
124 bool preserve_biv; /* For the original biv, whether to preserve it. */
125 }; 124 };
126 125
127 /* Types of uses. */ 126 /* Types of uses. */
128 enum use_type 127 enum use_type
129 { 128 {
190 struct iv_cand 189 struct iv_cand
191 { 190 {
192 unsigned id; /* The number of the candidate. */ 191 unsigned id; /* The number of the candidate. */
193 bool important; /* Whether this is an "important" candidate, i.e. such 192 bool important; /* Whether this is an "important" candidate, i.e. such
194 that it should be considered by all uses. */ 193 that it should be considered by all uses. */
195 enum iv_position pos; /* Where it is computed. */ 194 ENUM_BITFIELD(iv_position) pos : 8; /* Where it is computed. */
196 gimple incremented_at;/* For original biv, the statement where it is 195 gimple incremented_at;/* For original biv, the statement where it is
197 incremented. */ 196 incremented. */
198 tree var_before; /* The variable used for it before increment. */ 197 tree var_before; /* The variable used for it before increment. */
199 tree var_after; /* The variable used for it after increment. */ 198 tree var_after; /* The variable used for it after increment. */
200 struct iv *iv; /* The value of the candidate. NULL for 199 struct iv *iv; /* The value of the candidate. NULL for
1535 base_type = TREE_TYPE (base); 1534 base_type = TREE_TYPE (base);
1536 base_align = TYPE_ALIGN (base_type); 1535 base_align = TYPE_ALIGN (base_type);
1537 1536
1538 if (mode != BLKmode) 1537 if (mode != BLKmode)
1539 { 1538 {
1540 double_int mul; 1539 unsigned mode_align = GET_MODE_ALIGNMENT (mode);
1541 tree al = build_int_cst (TREE_TYPE (step), 1540
1542 GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT); 1541 if (base_align < mode_align
1543 1542 || (bitpos % mode_align) != 0
1544 if (base_align < GET_MODE_ALIGNMENT (mode) 1543 || (bitpos % BITS_PER_UNIT) != 0)
1545 || bitpos % GET_MODE_ALIGNMENT (mode) != 0
1546 || bitpos % BITS_PER_UNIT != 0)
1547 return true; 1544 return true;
1548 1545
1549 if (!constant_multiple_of (step, al, &mul)) 1546 if (toffset
1547 && (highest_pow2_factor (toffset) * BITS_PER_UNIT) < mode_align)
1548 return true;
1549
1550 if ((highest_pow2_factor (step) * BITS_PER_UNIT) < mode_align)
1550 return true; 1551 return true;
1551 } 1552 }
1552 1553
1553 return false; 1554 return false;
1554 } 1555 }
1684 { 1685 {
1685 tree *ref = &TREE_OPERAND (base, 0); 1686 tree *ref = &TREE_OPERAND (base, 0);
1686 while (handled_component_p (*ref)) 1687 while (handled_component_p (*ref))
1687 ref = &TREE_OPERAND (*ref, 0); 1688 ref = &TREE_OPERAND (*ref, 0);
1688 if (TREE_CODE (*ref) == INDIRECT_REF) 1689 if (TREE_CODE (*ref) == INDIRECT_REF)
1689 *ref = fold_indirect_ref (*ref); 1690 {
1691 tree tem = gimple_fold_indirect_ref (TREE_OPERAND (*ref, 0));
1692 if (tem)
1693 *ref = tem;
1694 }
1690 } 1695 }
1691 } 1696 }
1692 1697
1693 civ = alloc_iv (base, step); 1698 civ = alloc_iv (base, step);
1694 record_use (data, op_p, civ, stmt, USE_ADDRESS); 1699 record_use (data, op_p, civ, stmt, USE_ADDRESS);
2732 rtx seq, rslt; 2737 rtx seq, rslt;
2733 tree type = TREE_TYPE (expr); 2738 tree type = TREE_TYPE (expr);
2734 unsigned cost; 2739 unsigned cost;
2735 /* Avoid using hard regs in ways which may be unsupported. */ 2740 /* Avoid using hard regs in ways which may be unsupported. */
2736 int regno = LAST_VIRTUAL_REGISTER + 1; 2741 int regno = LAST_VIRTUAL_REGISTER + 1;
2737 enum function_frequency real_frequency = cfun->function_frequency; 2742 struct cgraph_node *node = cgraph_node (current_function_decl);
2738 2743 enum node_frequency real_frequency = node->frequency;
2739 cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL; 2744
2745 node->frequency = NODE_FREQUENCY_NORMAL;
2740 crtl->maybe_hot_insn_p = speed; 2746 crtl->maybe_hot_insn_p = speed;
2741 walk_tree (&expr, prepare_decl_rtl, &regno, NULL); 2747 walk_tree (&expr, prepare_decl_rtl, &regno, NULL);
2742 start_sequence (); 2748 start_sequence ();
2743 rslt = expand_expr (expr, NULL_RTX, TYPE_MODE (type), EXPAND_NORMAL); 2749 rslt = expand_expr (expr, NULL_RTX, TYPE_MODE (type), EXPAND_NORMAL);
2744 seq = get_insns (); 2750 seq = get_insns ();
2745 end_sequence (); 2751 end_sequence ();
2746 default_rtl_profile (); 2752 default_rtl_profile ();
2747 cfun->function_frequency = real_frequency; 2753 node->frequency = real_frequency;
2748 2754
2749 cost = seq_cost (seq, speed); 2755 cost = seq_cost (seq, speed);
2750 if (MEM_P (rslt)) 2756 if (MEM_P (rslt))
2751 cost += address_cost (XEXP (rslt, 0), TYPE_MODE (type), 2757 cost += address_cost (XEXP (rslt, 0), TYPE_MODE (type),
2752 TYPE_ADDR_SPACE (type), speed); 2758 TYPE_ADDR_SPACE (type), speed);
4083 tree bound = NULL_TREE; 4089 tree bound = NULL_TREE;
4084 struct iv *cmp_iv; 4090 struct iv *cmp_iv;
4085 bitmap depends_on_elim = NULL, depends_on_express = NULL, depends_on; 4091 bitmap depends_on_elim = NULL, depends_on_express = NULL, depends_on;
4086 comp_cost elim_cost, express_cost, cost; 4092 comp_cost elim_cost, express_cost, cost;
4087 bool ok; 4093 bool ok;
4094 tree *control_var, *bound_cst;
4088 4095
4089 /* Only consider real candidates. */ 4096 /* Only consider real candidates. */
4090 if (!cand->iv) 4097 if (!cand->iv)
4091 { 4098 {
4092 set_use_iv_cost (data, use, cand, infinite_cost, NULL, NULL_TREE); 4099 set_use_iv_cost (data, use, cand, infinite_cost, NULL, NULL_TREE);
4104 else 4111 else
4105 elim_cost = infinite_cost; 4112 elim_cost = infinite_cost;
4106 4113
4107 /* Try expressing the original giv. If it is compared with an invariant, 4114 /* Try expressing the original giv. If it is compared with an invariant,
4108 note that we cannot get rid of it. */ 4115 note that we cannot get rid of it. */
4109 ok = extract_cond_operands (data, use->stmt, NULL, NULL, NULL, &cmp_iv); 4116 ok = extract_cond_operands (data, use->stmt, &control_var, &bound_cst,
4117 NULL, &cmp_iv);
4110 gcc_assert (ok); 4118 gcc_assert (ok);
4119
4120 /* When the condition is a comparison of the candidate IV against
4121 zero, prefer this IV.
4122
4123 TODO: The constant that we're substracting from the cost should
4124 be target-dependent. This information should be added to the
4125 target costs for each backend. */
4126 if (!infinite_cost_p (elim_cost) /* Do not try to decrease infinite! */
4127 && integer_zerop (*bound_cst)
4128 && (operand_equal_p (*control_var, cand->var_after, 0)
4129 || operand_equal_p (*control_var, cand->var_before, 0)))
4130 elim_cost.cost -= 1;
4111 4131
4112 express_cost = get_computation_cost (data, use, cand, false, 4132 express_cost = get_computation_cost (data, use, cand, false,
4113 &depends_on_express, NULL); 4133 &depends_on_express, NULL);
4114 fd_ivopts_data = data; 4134 fd_ivopts_data = data;
4115 walk_tree (&cmp_iv->base, find_depends, &depends_on_express, NULL); 4135 walk_tree (&cmp_iv->base, find_depends, &depends_on_express, NULL);
5497 copy_ref_info (tree new_ref, tree old_ref) 5517 copy_ref_info (tree new_ref, tree old_ref)
5498 { 5518 {
5499 if (TREE_CODE (old_ref) == TARGET_MEM_REF) 5519 if (TREE_CODE (old_ref) == TARGET_MEM_REF)
5500 copy_mem_ref_info (new_ref, old_ref); 5520 copy_mem_ref_info (new_ref, old_ref);
5501 else 5521 else
5502 TMR_ORIGINAL (new_ref) = unshare_and_remove_ssa_names (old_ref); 5522 {
5523 TMR_ORIGINAL (new_ref) = unshare_and_remove_ssa_names (old_ref);
5524 TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (old_ref);
5525 TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (old_ref);
5526 }
5503 } 5527 }
5504 5528
5505 /* Rewrites USE (address that is an iv) using candidate CAND. */ 5529 /* Rewrites USE (address that is an iv) using candidate CAND. */
5506 5530
5507 static void 5531 static void