Mercurial > hg > CbC > CbC_gcc
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, ®no, NULL); | 2747 walk_tree (&expr, prepare_decl_rtl, ®no, 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 |