annotate gcc/tree-ssa-dom.c @ 127:4c56639505ff

fix function.c and add CbC-example Makefile
author mir3636
date Wed, 11 Apr 2018 18:46:58 +0900
parents 04ced10e8804
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* SSA Dominator optimizations for trees
111
kono
parents: 67
diff changeset
2 Copyright (C) 2001-2017 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 Contributed by Diego Novillo <dnovillo@redhat.com>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 it under the terms of the GNU General Public License as published by
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 the Free Software Foundation; either version 3, or (at your option)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 any later version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 GNU General Public License for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 #include "coretypes.h"
111
kono
parents: 67
diff changeset
24 #include "backend.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 #include "tree.h"
111
kono
parents: 67
diff changeset
26 #include "gimple.h"
kono
parents: 67
diff changeset
27 #include "tree-pass.h"
kono
parents: 67
diff changeset
28 #include "ssa.h"
kono
parents: 67
diff changeset
29 #include "gimple-pretty-print.h"
kono
parents: 67
diff changeset
30 #include "fold-const.h"
kono
parents: 67
diff changeset
31 #include "cfganal.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 #include "cfgloop.h"
111
kono
parents: 67
diff changeset
33 #include "gimple-fold.h"
kono
parents: 67
diff changeset
34 #include "tree-eh.h"
kono
parents: 67
diff changeset
35 #include "tree-inline.h"
kono
parents: 67
diff changeset
36 #include "gimple-iterator.h"
kono
parents: 67
diff changeset
37 #include "tree-cfg.h"
kono
parents: 67
diff changeset
38 #include "tree-into-ssa.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 #include "domwalk.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 #include "tree-ssa-propagate.h"
111
kono
parents: 67
diff changeset
41 #include "tree-ssa-threadupdate.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 #include "params.h"
111
kono
parents: 67
diff changeset
43 #include "tree-ssa-scopedtables.h"
kono
parents: 67
diff changeset
44 #include "tree-ssa-threadedge.h"
kono
parents: 67
diff changeset
45 #include "tree-ssa-dom.h"
kono
parents: 67
diff changeset
46 #include "gimplify.h"
kono
parents: 67
diff changeset
47 #include "tree-cfgcleanup.h"
kono
parents: 67
diff changeset
48 #include "dbgcnt.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 /* This file implements optimizations on the dominator tree. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51
111
kono
parents: 67
diff changeset
52 /* Structure for recording edge equivalences.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 Computing and storing the edge equivalences instead of creating
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 them on-demand can save significant amounts of time, particularly
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
56 for pathological cases involving switch statements.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 These structures live for a single iteration of the dominator
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 optimizer in the edge's AUX field. At the end of an iteration we
111
kono
parents: 67
diff changeset
60 free each of these structures. */
kono
parents: 67
diff changeset
61 class edge_info
kono
parents: 67
diff changeset
62 {
kono
parents: 67
diff changeset
63 public:
kono
parents: 67
diff changeset
64 typedef std::pair <tree, tree> equiv_pair;
kono
parents: 67
diff changeset
65 edge_info (edge);
kono
parents: 67
diff changeset
66 ~edge_info ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67
111
kono
parents: 67
diff changeset
68 /* Record a simple LHS = RHS equivalence. This may trigger
kono
parents: 67
diff changeset
69 calls to derive_equivalences. */
kono
parents: 67
diff changeset
70 void record_simple_equiv (tree, tree);
kono
parents: 67
diff changeset
71
kono
parents: 67
diff changeset
72 /* If traversing this edge creates simple equivalences, we store
kono
parents: 67
diff changeset
73 them as LHS/RHS pairs within this vector. */
kono
parents: 67
diff changeset
74 vec<equiv_pair> simple_equivalences;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 /* Traversing an edge may also indicate one or more particular conditions
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
77 are true or false. */
111
kono
parents: 67
diff changeset
78 vec<cond_equivalence> cond_equivalences;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79
111
kono
parents: 67
diff changeset
80 private:
kono
parents: 67
diff changeset
81 /* Derive equivalences by walking the use-def chains. */
kono
parents: 67
diff changeset
82 void derive_equivalences (tree, tree, int);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 /* Track whether or not we have changed the control flow graph. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 static bool cfg_altered;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 /* Bitmap of blocks that have had EH statements cleaned. We should
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 remove their dead edges eventually. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 static bitmap need_eh_cleanup;
111
kono
parents: 67
diff changeset
91 static vec<gimple *> need_noreturn_fixup;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 /* Statistics for dominator optimizations. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 struct opt_stats_d
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 long num_stmts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 long num_exprs_considered;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 long num_re;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 long num_const_prop;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 long num_copy_prop;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 static struct opt_stats_d opt_stats;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 /* Local functions. */
111
kono
parents: 67
diff changeset
106 static void record_equality (tree, tree, class const_and_copies *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 static void record_equivalences_from_phis (basic_block);
111
kono
parents: 67
diff changeset
108 static void record_equivalences_from_incoming_edge (basic_block,
kono
parents: 67
diff changeset
109 class const_and_copies *,
kono
parents: 67
diff changeset
110 class avail_exprs_stack *);
kono
parents: 67
diff changeset
111 static void eliminate_redundant_computations (gimple_stmt_iterator *,
kono
parents: 67
diff changeset
112 class const_and_copies *,
kono
parents: 67
diff changeset
113 class avail_exprs_stack *);
kono
parents: 67
diff changeset
114 static void record_equivalences_from_stmt (gimple *, int,
kono
parents: 67
diff changeset
115 class avail_exprs_stack *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 static edge single_incoming_edge_ignoring_loop_edges (basic_block);
111
kono
parents: 67
diff changeset
117 static void dump_dominator_optimization_stats (FILE *file,
kono
parents: 67
diff changeset
118 hash_table<expr_elt_hasher> *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119
111
kono
parents: 67
diff changeset
120 /* Constructor for EDGE_INFO. An EDGE_INFO instance is always
kono
parents: 67
diff changeset
121 associated with an edge E. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
122
111
kono
parents: 67
diff changeset
123 edge_info::edge_info (edge e)
kono
parents: 67
diff changeset
124 {
kono
parents: 67
diff changeset
125 /* Free the old one associated with E, if it exists and
kono
parents: 67
diff changeset
126 associate our new object with E. */
kono
parents: 67
diff changeset
127 free_dom_edge_info (e);
kono
parents: 67
diff changeset
128 e->aux = this;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129
111
kono
parents: 67
diff changeset
130 /* And initialize the embedded vectors. */
kono
parents: 67
diff changeset
131 simple_equivalences = vNULL;
kono
parents: 67
diff changeset
132 cond_equivalences = vNULL;
kono
parents: 67
diff changeset
133 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134
111
kono
parents: 67
diff changeset
135 /* Destructor just needs to release the vectors. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136
111
kono
parents: 67
diff changeset
137 edge_info::~edge_info (void)
kono
parents: 67
diff changeset
138 {
kono
parents: 67
diff changeset
139 this->cond_equivalences.release ();
kono
parents: 67
diff changeset
140 this->simple_equivalences.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142
111
kono
parents: 67
diff changeset
143 /* NAME is known to have the value VALUE, which must be a constant.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144
111
kono
parents: 67
diff changeset
145 Walk through its use-def chain to see if there are other equivalences
kono
parents: 67
diff changeset
146 we might be able to derive.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
147
111
kono
parents: 67
diff changeset
148 RECURSION_LIMIT controls how far back we recurse through the use-def
kono
parents: 67
diff changeset
149 chains. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150
111
kono
parents: 67
diff changeset
151 void
kono
parents: 67
diff changeset
152 edge_info::derive_equivalences (tree name, tree value, int recursion_limit)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 {
111
kono
parents: 67
diff changeset
154 if (TREE_CODE (name) != SSA_NAME || TREE_CODE (value) != INTEGER_CST)
kono
parents: 67
diff changeset
155 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
156
111
kono
parents: 67
diff changeset
157 /* This records the equivalence for the toplevel object. Do
kono
parents: 67
diff changeset
158 this before checking the recursion limit. */
kono
parents: 67
diff changeset
159 simple_equivalences.safe_push (equiv_pair (name, value));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160
111
kono
parents: 67
diff changeset
161 /* Limit how far up the use-def chains we are willing to walk. */
kono
parents: 67
diff changeset
162 if (recursion_limit == 0)
kono
parents: 67
diff changeset
163 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164
111
kono
parents: 67
diff changeset
165 /* We can walk up the use-def chains to potentially find more
kono
parents: 67
diff changeset
166 equivalences. */
kono
parents: 67
diff changeset
167 gimple *def_stmt = SSA_NAME_DEF_STMT (name);
kono
parents: 67
diff changeset
168 if (is_gimple_assign (def_stmt))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
169 {
111
kono
parents: 67
diff changeset
170 /* We know the result of DEF_STMT was zero. See if that allows
kono
parents: 67
diff changeset
171 us to deduce anything about the SSA_NAMEs used on the RHS. */
kono
parents: 67
diff changeset
172 enum tree_code code = gimple_assign_rhs_code (def_stmt);
kono
parents: 67
diff changeset
173 switch (code)
kono
parents: 67
diff changeset
174 {
kono
parents: 67
diff changeset
175 case BIT_IOR_EXPR:
kono
parents: 67
diff changeset
176 if (integer_zerop (value))
kono
parents: 67
diff changeset
177 {
kono
parents: 67
diff changeset
178 tree rhs1 = gimple_assign_rhs1 (def_stmt);
kono
parents: 67
diff changeset
179 tree rhs2 = gimple_assign_rhs2 (def_stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
180
111
kono
parents: 67
diff changeset
181 value = build_zero_cst (TREE_TYPE (rhs1));
kono
parents: 67
diff changeset
182 derive_equivalences (rhs1, value, recursion_limit - 1);
kono
parents: 67
diff changeset
183 value = build_zero_cst (TREE_TYPE (rhs2));
kono
parents: 67
diff changeset
184 derive_equivalences (rhs2, value, recursion_limit - 1);
kono
parents: 67
diff changeset
185 }
kono
parents: 67
diff changeset
186 break;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187
111
kono
parents: 67
diff changeset
188 /* We know the result of DEF_STMT was one. See if that allows
kono
parents: 67
diff changeset
189 us to deduce anything about the SSA_NAMEs used on the RHS. */
kono
parents: 67
diff changeset
190 case BIT_AND_EXPR:
kono
parents: 67
diff changeset
191 if (!integer_zerop (value))
kono
parents: 67
diff changeset
192 {
kono
parents: 67
diff changeset
193 tree rhs1 = gimple_assign_rhs1 (def_stmt);
kono
parents: 67
diff changeset
194 tree rhs2 = gimple_assign_rhs2 (def_stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195
111
kono
parents: 67
diff changeset
196 /* If either operand has a boolean range, then we
kono
parents: 67
diff changeset
197 know its value must be one, otherwise we just know it
kono
parents: 67
diff changeset
198 is nonzero. The former is clearly useful, I haven't
kono
parents: 67
diff changeset
199 seen cases where the latter is helpful yet. */
kono
parents: 67
diff changeset
200 if (TREE_CODE (rhs1) == SSA_NAME)
kono
parents: 67
diff changeset
201 {
kono
parents: 67
diff changeset
202 if (ssa_name_has_boolean_range (rhs1))
kono
parents: 67
diff changeset
203 {
kono
parents: 67
diff changeset
204 value = build_one_cst (TREE_TYPE (rhs1));
kono
parents: 67
diff changeset
205 derive_equivalences (rhs1, value, recursion_limit - 1);
kono
parents: 67
diff changeset
206 }
kono
parents: 67
diff changeset
207 }
kono
parents: 67
diff changeset
208 if (TREE_CODE (rhs2) == SSA_NAME)
kono
parents: 67
diff changeset
209 {
kono
parents: 67
diff changeset
210 if (ssa_name_has_boolean_range (rhs2))
kono
parents: 67
diff changeset
211 {
kono
parents: 67
diff changeset
212 value = build_one_cst (TREE_TYPE (rhs2));
kono
parents: 67
diff changeset
213 derive_equivalences (rhs2, value, recursion_limit - 1);
kono
parents: 67
diff changeset
214 }
kono
parents: 67
diff changeset
215 }
kono
parents: 67
diff changeset
216 }
kono
parents: 67
diff changeset
217 break;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
218
111
kono
parents: 67
diff changeset
219 /* If LHS is an SSA_NAME and RHS is a constant integer and LHS was
kono
parents: 67
diff changeset
220 set via a widening type conversion, then we may be able to record
kono
parents: 67
diff changeset
221 additional equivalences. */
kono
parents: 67
diff changeset
222 case NOP_EXPR:
kono
parents: 67
diff changeset
223 case CONVERT_EXPR:
kono
parents: 67
diff changeset
224 {
kono
parents: 67
diff changeset
225 tree rhs = gimple_assign_rhs1 (def_stmt);
kono
parents: 67
diff changeset
226 tree rhs_type = TREE_TYPE (rhs);
kono
parents: 67
diff changeset
227 if (INTEGRAL_TYPE_P (rhs_type)
kono
parents: 67
diff changeset
228 && (TYPE_PRECISION (TREE_TYPE (name))
kono
parents: 67
diff changeset
229 >= TYPE_PRECISION (rhs_type))
kono
parents: 67
diff changeset
230 && int_fits_type_p (value, rhs_type))
kono
parents: 67
diff changeset
231 derive_equivalences (rhs,
kono
parents: 67
diff changeset
232 fold_convert (rhs_type, value),
kono
parents: 67
diff changeset
233 recursion_limit - 1);
kono
parents: 67
diff changeset
234 break;
kono
parents: 67
diff changeset
235 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
236
111
kono
parents: 67
diff changeset
237 /* We can invert the operation of these codes trivially if
kono
parents: 67
diff changeset
238 one of the RHS operands is a constant to produce a known
kono
parents: 67
diff changeset
239 value for the other RHS operand. */
kono
parents: 67
diff changeset
240 case POINTER_PLUS_EXPR:
kono
parents: 67
diff changeset
241 case PLUS_EXPR:
kono
parents: 67
diff changeset
242 {
kono
parents: 67
diff changeset
243 tree rhs1 = gimple_assign_rhs1 (def_stmt);
kono
parents: 67
diff changeset
244 tree rhs2 = gimple_assign_rhs2 (def_stmt);
kono
parents: 67
diff changeset
245
kono
parents: 67
diff changeset
246 /* If either argument is a constant, then we can compute
kono
parents: 67
diff changeset
247 a constant value for the nonconstant argument. */
kono
parents: 67
diff changeset
248 if (TREE_CODE (rhs1) == INTEGER_CST
kono
parents: 67
diff changeset
249 && TREE_CODE (rhs2) == SSA_NAME)
kono
parents: 67
diff changeset
250 derive_equivalences (rhs2,
kono
parents: 67
diff changeset
251 fold_binary (MINUS_EXPR, TREE_TYPE (rhs1),
kono
parents: 67
diff changeset
252 value, rhs1),
kono
parents: 67
diff changeset
253 recursion_limit - 1);
kono
parents: 67
diff changeset
254 else if (TREE_CODE (rhs2) == INTEGER_CST
kono
parents: 67
diff changeset
255 && TREE_CODE (rhs1) == SSA_NAME)
kono
parents: 67
diff changeset
256 derive_equivalences (rhs1,
kono
parents: 67
diff changeset
257 fold_binary (MINUS_EXPR, TREE_TYPE (rhs1),
kono
parents: 67
diff changeset
258 value, rhs2),
kono
parents: 67
diff changeset
259 recursion_limit - 1);
kono
parents: 67
diff changeset
260 break;
kono
parents: 67
diff changeset
261 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
262
111
kono
parents: 67
diff changeset
263 /* If one of the operands is a constant, then we can compute
kono
parents: 67
diff changeset
264 the value of the other operand. If both operands are
kono
parents: 67
diff changeset
265 SSA_NAMEs, then they must be equal if the result is zero. */
kono
parents: 67
diff changeset
266 case MINUS_EXPR:
kono
parents: 67
diff changeset
267 {
kono
parents: 67
diff changeset
268 tree rhs1 = gimple_assign_rhs1 (def_stmt);
kono
parents: 67
diff changeset
269 tree rhs2 = gimple_assign_rhs2 (def_stmt);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
270
111
kono
parents: 67
diff changeset
271 /* If either argument is a constant, then we can compute
kono
parents: 67
diff changeset
272 a constant value for the nonconstant argument. */
kono
parents: 67
diff changeset
273 if (TREE_CODE (rhs1) == INTEGER_CST
kono
parents: 67
diff changeset
274 && TREE_CODE (rhs2) == SSA_NAME)
kono
parents: 67
diff changeset
275 derive_equivalences (rhs2,
kono
parents: 67
diff changeset
276 fold_binary (MINUS_EXPR, TREE_TYPE (rhs1),
kono
parents: 67
diff changeset
277 rhs1, value),
kono
parents: 67
diff changeset
278 recursion_limit - 1);
kono
parents: 67
diff changeset
279 else if (TREE_CODE (rhs2) == INTEGER_CST
kono
parents: 67
diff changeset
280 && TREE_CODE (rhs1) == SSA_NAME)
kono
parents: 67
diff changeset
281 derive_equivalences (rhs1,
kono
parents: 67
diff changeset
282 fold_binary (PLUS_EXPR, TREE_TYPE (rhs1),
kono
parents: 67
diff changeset
283 value, rhs2),
kono
parents: 67
diff changeset
284 recursion_limit - 1);
kono
parents: 67
diff changeset
285 else if (integer_zerop (value))
kono
parents: 67
diff changeset
286 {
kono
parents: 67
diff changeset
287 tree cond = build2 (EQ_EXPR, boolean_type_node,
kono
parents: 67
diff changeset
288 gimple_assign_rhs1 (def_stmt),
kono
parents: 67
diff changeset
289 gimple_assign_rhs2 (def_stmt));
kono
parents: 67
diff changeset
290 tree inverted = invert_truthvalue (cond);
kono
parents: 67
diff changeset
291 record_conditions (&this->cond_equivalences, cond, inverted);
kono
parents: 67
diff changeset
292 }
kono
parents: 67
diff changeset
293 break;
kono
parents: 67
diff changeset
294 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295
111
kono
parents: 67
diff changeset
296
kono
parents: 67
diff changeset
297 case EQ_EXPR:
kono
parents: 67
diff changeset
298 case NE_EXPR:
kono
parents: 67
diff changeset
299 {
kono
parents: 67
diff changeset
300 if ((code == EQ_EXPR && integer_onep (value))
kono
parents: 67
diff changeset
301 || (code == NE_EXPR && integer_zerop (value)))
kono
parents: 67
diff changeset
302 {
kono
parents: 67
diff changeset
303 tree rhs1 = gimple_assign_rhs1 (def_stmt);
kono
parents: 67
diff changeset
304 tree rhs2 = gimple_assign_rhs2 (def_stmt);
kono
parents: 67
diff changeset
305
kono
parents: 67
diff changeset
306 /* If either argument is a constant, then record the
kono
parents: 67
diff changeset
307 other argument as being the same as that constant.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
308
111
kono
parents: 67
diff changeset
309 If neither operand is a constant, then we have a
kono
parents: 67
diff changeset
310 conditional name == name equivalence. */
kono
parents: 67
diff changeset
311 if (TREE_CODE (rhs1) == INTEGER_CST)
kono
parents: 67
diff changeset
312 derive_equivalences (rhs2, rhs1, recursion_limit - 1);
kono
parents: 67
diff changeset
313 else if (TREE_CODE (rhs2) == INTEGER_CST)
kono
parents: 67
diff changeset
314 derive_equivalences (rhs1, rhs2, recursion_limit - 1);
kono
parents: 67
diff changeset
315 }
kono
parents: 67
diff changeset
316 else
kono
parents: 67
diff changeset
317 {
kono
parents: 67
diff changeset
318 tree cond = build2 (code, boolean_type_node,
kono
parents: 67
diff changeset
319 gimple_assign_rhs1 (def_stmt),
kono
parents: 67
diff changeset
320 gimple_assign_rhs2 (def_stmt));
kono
parents: 67
diff changeset
321 tree inverted = invert_truthvalue (cond);
kono
parents: 67
diff changeset
322 if (integer_zerop (value))
kono
parents: 67
diff changeset
323 std::swap (cond, inverted);
kono
parents: 67
diff changeset
324 record_conditions (&this->cond_equivalences, cond, inverted);
kono
parents: 67
diff changeset
325 }
kono
parents: 67
diff changeset
326 break;
kono
parents: 67
diff changeset
327 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328
111
kono
parents: 67
diff changeset
329 /* For BIT_NOT and NEGATE, we can just apply the operation to the
kono
parents: 67
diff changeset
330 VALUE to get the new equivalence. It will always be a constant
kono
parents: 67
diff changeset
331 so we can recurse. */
kono
parents: 67
diff changeset
332 case BIT_NOT_EXPR:
kono
parents: 67
diff changeset
333 case NEGATE_EXPR:
kono
parents: 67
diff changeset
334 {
kono
parents: 67
diff changeset
335 tree rhs = gimple_assign_rhs1 (def_stmt);
kono
parents: 67
diff changeset
336 tree res = fold_build1 (code, TREE_TYPE (rhs), value);
kono
parents: 67
diff changeset
337 derive_equivalences (rhs, res, recursion_limit - 1);
kono
parents: 67
diff changeset
338 break;
kono
parents: 67
diff changeset
339 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
340
111
kono
parents: 67
diff changeset
341 default:
kono
parents: 67
diff changeset
342 {
kono
parents: 67
diff changeset
343 if (TREE_CODE_CLASS (code) == tcc_comparison)
kono
parents: 67
diff changeset
344 {
kono
parents: 67
diff changeset
345 tree cond = build2 (code, boolean_type_node,
kono
parents: 67
diff changeset
346 gimple_assign_rhs1 (def_stmt),
kono
parents: 67
diff changeset
347 gimple_assign_rhs2 (def_stmt));
kono
parents: 67
diff changeset
348 tree inverted = invert_truthvalue (cond);
kono
parents: 67
diff changeset
349 if (integer_zerop (value))
kono
parents: 67
diff changeset
350 std::swap (cond, inverted);
kono
parents: 67
diff changeset
351 record_conditions (&this->cond_equivalences, cond, inverted);
kono
parents: 67
diff changeset
352 break;
kono
parents: 67
diff changeset
353 }
kono
parents: 67
diff changeset
354 break;
kono
parents: 67
diff changeset
355 }
kono
parents: 67
diff changeset
356 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
357 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
358 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
359
111
kono
parents: 67
diff changeset
360 void
kono
parents: 67
diff changeset
361 edge_info::record_simple_equiv (tree lhs, tree rhs)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
362 {
111
kono
parents: 67
diff changeset
363 /* If the RHS is a constant, then we may be able to derive
kono
parents: 67
diff changeset
364 further equivalences. Else just record the name = name
kono
parents: 67
diff changeset
365 equivalence. */
kono
parents: 67
diff changeset
366 if (TREE_CODE (rhs) == INTEGER_CST)
kono
parents: 67
diff changeset
367 derive_equivalences (lhs, rhs, 4);
kono
parents: 67
diff changeset
368 else
kono
parents: 67
diff changeset
369 simple_equivalences.safe_push (equiv_pair (lhs, rhs));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
370 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
371
111
kono
parents: 67
diff changeset
372 /* Free the edge_info data attached to E, if it exists. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
373
111
kono
parents: 67
diff changeset
374 void
kono
parents: 67
diff changeset
375 free_dom_edge_info (edge e)
kono
parents: 67
diff changeset
376 {
kono
parents: 67
diff changeset
377 class edge_info *edge_info = (struct edge_info *)e->aux;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
378
111
kono
parents: 67
diff changeset
379 if (edge_info)
kono
parents: 67
diff changeset
380 delete edge_info;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
381 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
382
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
383 /* Free all EDGE_INFO structures associated with edges in the CFG.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
384 If a particular edge can be threaded, copy the redirection
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
385 target from the EDGE_INFO structure into the edge's AUX field
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386 as required by code to update the CFG and SSA graph for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
387 jump threading. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
388
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
389 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
390 free_all_edge_infos (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
391 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
392 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
393 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
394 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
395
111
kono
parents: 67
diff changeset
396 FOR_EACH_BB_FN (bb, cfun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
397 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
398 FOR_EACH_EDGE (e, ei, bb->preds)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
399 {
111
kono
parents: 67
diff changeset
400 free_dom_edge_info (e);
kono
parents: 67
diff changeset
401 e->aux = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
402 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
403 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
404 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
405
111
kono
parents: 67
diff changeset
406 /* We have finished optimizing BB, record any information implied by
kono
parents: 67
diff changeset
407 taking a specific outgoing edge from BB. */
kono
parents: 67
diff changeset
408
kono
parents: 67
diff changeset
409 static void
kono
parents: 67
diff changeset
410 record_edge_info (basic_block bb)
kono
parents: 67
diff changeset
411 {
kono
parents: 67
diff changeset
412 gimple_stmt_iterator gsi = gsi_last_bb (bb);
kono
parents: 67
diff changeset
413 class edge_info *edge_info;
kono
parents: 67
diff changeset
414
kono
parents: 67
diff changeset
415 if (! gsi_end_p (gsi))
kono
parents: 67
diff changeset
416 {
kono
parents: 67
diff changeset
417 gimple *stmt = gsi_stmt (gsi);
kono
parents: 67
diff changeset
418 location_t loc = gimple_location (stmt);
kono
parents: 67
diff changeset
419
kono
parents: 67
diff changeset
420 if (gimple_code (stmt) == GIMPLE_SWITCH)
kono
parents: 67
diff changeset
421 {
kono
parents: 67
diff changeset
422 gswitch *switch_stmt = as_a <gswitch *> (stmt);
kono
parents: 67
diff changeset
423 tree index = gimple_switch_index (switch_stmt);
kono
parents: 67
diff changeset
424
kono
parents: 67
diff changeset
425 if (TREE_CODE (index) == SSA_NAME)
kono
parents: 67
diff changeset
426 {
kono
parents: 67
diff changeset
427 int i;
kono
parents: 67
diff changeset
428 int n_labels = gimple_switch_num_labels (switch_stmt);
kono
parents: 67
diff changeset
429 tree *info = XCNEWVEC (tree, last_basic_block_for_fn (cfun));
kono
parents: 67
diff changeset
430 edge e;
kono
parents: 67
diff changeset
431 edge_iterator ei;
kono
parents: 67
diff changeset
432
kono
parents: 67
diff changeset
433 for (i = 0; i < n_labels; i++)
kono
parents: 67
diff changeset
434 {
kono
parents: 67
diff changeset
435 tree label = gimple_switch_label (switch_stmt, i);
kono
parents: 67
diff changeset
436 basic_block target_bb = label_to_block (CASE_LABEL (label));
kono
parents: 67
diff changeset
437 if (CASE_HIGH (label)
kono
parents: 67
diff changeset
438 || !CASE_LOW (label)
kono
parents: 67
diff changeset
439 || info[target_bb->index])
kono
parents: 67
diff changeset
440 info[target_bb->index] = error_mark_node;
kono
parents: 67
diff changeset
441 else
kono
parents: 67
diff changeset
442 info[target_bb->index] = label;
kono
parents: 67
diff changeset
443 }
kono
parents: 67
diff changeset
444
kono
parents: 67
diff changeset
445 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
446 {
kono
parents: 67
diff changeset
447 basic_block target_bb = e->dest;
kono
parents: 67
diff changeset
448 tree label = info[target_bb->index];
kono
parents: 67
diff changeset
449
kono
parents: 67
diff changeset
450 if (label != NULL && label != error_mark_node)
kono
parents: 67
diff changeset
451 {
kono
parents: 67
diff changeset
452 tree x = fold_convert_loc (loc, TREE_TYPE (index),
kono
parents: 67
diff changeset
453 CASE_LOW (label));
kono
parents: 67
diff changeset
454 edge_info = new class edge_info (e);
kono
parents: 67
diff changeset
455 edge_info->record_simple_equiv (index, x);
kono
parents: 67
diff changeset
456 }
kono
parents: 67
diff changeset
457 }
kono
parents: 67
diff changeset
458 free (info);
kono
parents: 67
diff changeset
459 }
kono
parents: 67
diff changeset
460 }
kono
parents: 67
diff changeset
461
kono
parents: 67
diff changeset
462 /* A COND_EXPR may create equivalences too. */
kono
parents: 67
diff changeset
463 if (gimple_code (stmt) == GIMPLE_COND)
kono
parents: 67
diff changeset
464 {
kono
parents: 67
diff changeset
465 edge true_edge;
kono
parents: 67
diff changeset
466 edge false_edge;
kono
parents: 67
diff changeset
467
kono
parents: 67
diff changeset
468 tree op0 = gimple_cond_lhs (stmt);
kono
parents: 67
diff changeset
469 tree op1 = gimple_cond_rhs (stmt);
kono
parents: 67
diff changeset
470 enum tree_code code = gimple_cond_code (stmt);
kono
parents: 67
diff changeset
471
kono
parents: 67
diff changeset
472 extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
kono
parents: 67
diff changeset
473
kono
parents: 67
diff changeset
474 /* Special case comparing booleans against a constant as we
kono
parents: 67
diff changeset
475 know the value of OP0 on both arms of the branch. i.e., we
kono
parents: 67
diff changeset
476 can record an equivalence for OP0 rather than COND.
kono
parents: 67
diff changeset
477
kono
parents: 67
diff changeset
478 However, don't do this if the constant isn't zero or one.
kono
parents: 67
diff changeset
479 Such conditionals will get optimized more thoroughly during
kono
parents: 67
diff changeset
480 the domwalk. */
kono
parents: 67
diff changeset
481 if ((code == EQ_EXPR || code == NE_EXPR)
kono
parents: 67
diff changeset
482 && TREE_CODE (op0) == SSA_NAME
kono
parents: 67
diff changeset
483 && ssa_name_has_boolean_range (op0)
kono
parents: 67
diff changeset
484 && is_gimple_min_invariant (op1)
kono
parents: 67
diff changeset
485 && (integer_zerop (op1) || integer_onep (op1)))
kono
parents: 67
diff changeset
486 {
kono
parents: 67
diff changeset
487 tree true_val = constant_boolean_node (true, TREE_TYPE (op0));
kono
parents: 67
diff changeset
488 tree false_val = constant_boolean_node (false, TREE_TYPE (op0));
kono
parents: 67
diff changeset
489
kono
parents: 67
diff changeset
490 if (code == EQ_EXPR)
kono
parents: 67
diff changeset
491 {
kono
parents: 67
diff changeset
492 edge_info = new class edge_info (true_edge);
kono
parents: 67
diff changeset
493 edge_info->record_simple_equiv (op0,
kono
parents: 67
diff changeset
494 (integer_zerop (op1)
kono
parents: 67
diff changeset
495 ? false_val : true_val));
kono
parents: 67
diff changeset
496 edge_info = new class edge_info (false_edge);
kono
parents: 67
diff changeset
497 edge_info->record_simple_equiv (op0,
kono
parents: 67
diff changeset
498 (integer_zerop (op1)
kono
parents: 67
diff changeset
499 ? true_val : false_val));
kono
parents: 67
diff changeset
500 }
kono
parents: 67
diff changeset
501 else
kono
parents: 67
diff changeset
502 {
kono
parents: 67
diff changeset
503 edge_info = new class edge_info (true_edge);
kono
parents: 67
diff changeset
504 edge_info->record_simple_equiv (op0,
kono
parents: 67
diff changeset
505 (integer_zerop (op1)
kono
parents: 67
diff changeset
506 ? true_val : false_val));
kono
parents: 67
diff changeset
507 edge_info = new class edge_info (false_edge);
kono
parents: 67
diff changeset
508 edge_info->record_simple_equiv (op0,
kono
parents: 67
diff changeset
509 (integer_zerop (op1)
kono
parents: 67
diff changeset
510 ? false_val : true_val));
kono
parents: 67
diff changeset
511 }
kono
parents: 67
diff changeset
512 }
kono
parents: 67
diff changeset
513 /* This can show up in the IL as a result of copy propagation
kono
parents: 67
diff changeset
514 it will eventually be canonicalized, but we have to cope
kono
parents: 67
diff changeset
515 with this case within the pass. */
kono
parents: 67
diff changeset
516 else if (is_gimple_min_invariant (op0)
kono
parents: 67
diff changeset
517 && TREE_CODE (op1) == SSA_NAME)
kono
parents: 67
diff changeset
518 {
kono
parents: 67
diff changeset
519 tree cond = build2 (code, boolean_type_node, op0, op1);
kono
parents: 67
diff changeset
520 tree inverted = invert_truthvalue_loc (loc, cond);
kono
parents: 67
diff changeset
521 bool can_infer_simple_equiv
kono
parents: 67
diff changeset
522 = !(HONOR_SIGNED_ZEROS (op0)
kono
parents: 67
diff changeset
523 && real_zerop (op0));
kono
parents: 67
diff changeset
524 struct edge_info *edge_info;
kono
parents: 67
diff changeset
525
kono
parents: 67
diff changeset
526 edge_info = new class edge_info (true_edge);
kono
parents: 67
diff changeset
527 record_conditions (&edge_info->cond_equivalences, cond, inverted);
kono
parents: 67
diff changeset
528
kono
parents: 67
diff changeset
529 if (can_infer_simple_equiv && code == EQ_EXPR)
kono
parents: 67
diff changeset
530 edge_info->record_simple_equiv (op1, op0);
kono
parents: 67
diff changeset
531
kono
parents: 67
diff changeset
532 edge_info = new class edge_info (false_edge);
kono
parents: 67
diff changeset
533 record_conditions (&edge_info->cond_equivalences, inverted, cond);
kono
parents: 67
diff changeset
534
kono
parents: 67
diff changeset
535 if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR)
kono
parents: 67
diff changeset
536 edge_info->record_simple_equiv (op1, op0);
kono
parents: 67
diff changeset
537 }
kono
parents: 67
diff changeset
538
kono
parents: 67
diff changeset
539 else if (TREE_CODE (op0) == SSA_NAME
kono
parents: 67
diff changeset
540 && (TREE_CODE (op1) == SSA_NAME
kono
parents: 67
diff changeset
541 || is_gimple_min_invariant (op1)))
kono
parents: 67
diff changeset
542 {
kono
parents: 67
diff changeset
543 tree cond = build2 (code, boolean_type_node, op0, op1);
kono
parents: 67
diff changeset
544 tree inverted = invert_truthvalue_loc (loc, cond);
kono
parents: 67
diff changeset
545 bool can_infer_simple_equiv
kono
parents: 67
diff changeset
546 = !(HONOR_SIGNED_ZEROS (op1)
kono
parents: 67
diff changeset
547 && (TREE_CODE (op1) == SSA_NAME || real_zerop (op1)));
kono
parents: 67
diff changeset
548 struct edge_info *edge_info;
kono
parents: 67
diff changeset
549
kono
parents: 67
diff changeset
550 edge_info = new class edge_info (true_edge);
kono
parents: 67
diff changeset
551 record_conditions (&edge_info->cond_equivalences, cond, inverted);
kono
parents: 67
diff changeset
552
kono
parents: 67
diff changeset
553 if (can_infer_simple_equiv && code == EQ_EXPR)
kono
parents: 67
diff changeset
554 edge_info->record_simple_equiv (op0, op1);
kono
parents: 67
diff changeset
555
kono
parents: 67
diff changeset
556 edge_info = new class edge_info (false_edge);
kono
parents: 67
diff changeset
557 record_conditions (&edge_info->cond_equivalences, inverted, cond);
kono
parents: 67
diff changeset
558
kono
parents: 67
diff changeset
559 if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR)
kono
parents: 67
diff changeset
560 edge_info->record_simple_equiv (op0, op1);
kono
parents: 67
diff changeset
561 }
kono
parents: 67
diff changeset
562 }
kono
parents: 67
diff changeset
563 }
kono
parents: 67
diff changeset
564 }
kono
parents: 67
diff changeset
565
kono
parents: 67
diff changeset
566
kono
parents: 67
diff changeset
567 class dom_opt_dom_walker : public dom_walker
kono
parents: 67
diff changeset
568 {
kono
parents: 67
diff changeset
569 public:
kono
parents: 67
diff changeset
570 dom_opt_dom_walker (cdi_direction direction,
kono
parents: 67
diff changeset
571 class const_and_copies *const_and_copies,
kono
parents: 67
diff changeset
572 class avail_exprs_stack *avail_exprs_stack,
kono
parents: 67
diff changeset
573 gcond *dummy_cond)
kono
parents: 67
diff changeset
574 : dom_walker (direction, true),
kono
parents: 67
diff changeset
575 m_const_and_copies (const_and_copies),
kono
parents: 67
diff changeset
576 m_avail_exprs_stack (avail_exprs_stack),
kono
parents: 67
diff changeset
577 m_dummy_cond (dummy_cond) { }
kono
parents: 67
diff changeset
578
kono
parents: 67
diff changeset
579 virtual edge before_dom_children (basic_block);
kono
parents: 67
diff changeset
580 virtual void after_dom_children (basic_block);
kono
parents: 67
diff changeset
581
kono
parents: 67
diff changeset
582 private:
kono
parents: 67
diff changeset
583
kono
parents: 67
diff changeset
584 /* Unwindable equivalences, both const/copy and expression varieties. */
kono
parents: 67
diff changeset
585 class const_and_copies *m_const_and_copies;
kono
parents: 67
diff changeset
586 class avail_exprs_stack *m_avail_exprs_stack;
kono
parents: 67
diff changeset
587
kono
parents: 67
diff changeset
588 /* Dummy condition to avoid creating lots of throw away statements. */
kono
parents: 67
diff changeset
589 gcond *m_dummy_cond;
kono
parents: 67
diff changeset
590
kono
parents: 67
diff changeset
591 /* Optimize a single statement within a basic block using the
kono
parents: 67
diff changeset
592 various tables mantained by DOM. Returns the taken edge if
kono
parents: 67
diff changeset
593 the statement is a conditional with a statically determined
kono
parents: 67
diff changeset
594 value. */
kono
parents: 67
diff changeset
595 edge optimize_stmt (basic_block, gimple_stmt_iterator);
kono
parents: 67
diff changeset
596 };
kono
parents: 67
diff changeset
597
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
598 /* Jump threading, redundancy elimination and const/copy propagation.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
599
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
600 This pass may expose new symbols that need to be renamed into SSA. For
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
601 every new symbol exposed, its corresponding bit will be set in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
602 VARS_TO_RENAME. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
603
111
kono
parents: 67
diff changeset
604 namespace {
kono
parents: 67
diff changeset
605
kono
parents: 67
diff changeset
606 const pass_data pass_data_dominator =
kono
parents: 67
diff changeset
607 {
kono
parents: 67
diff changeset
608 GIMPLE_PASS, /* type */
kono
parents: 67
diff changeset
609 "dom", /* name */
kono
parents: 67
diff changeset
610 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
611 TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */
kono
parents: 67
diff changeset
612 ( PROP_cfg | PROP_ssa ), /* properties_required */
kono
parents: 67
diff changeset
613 0, /* properties_provided */
kono
parents: 67
diff changeset
614 0, /* properties_destroyed */
kono
parents: 67
diff changeset
615 0, /* todo_flags_start */
kono
parents: 67
diff changeset
616 ( TODO_cleanup_cfg | TODO_update_ssa ), /* todo_flags_finish */
kono
parents: 67
diff changeset
617 };
kono
parents: 67
diff changeset
618
kono
parents: 67
diff changeset
619 class pass_dominator : public gimple_opt_pass
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
620 {
111
kono
parents: 67
diff changeset
621 public:
kono
parents: 67
diff changeset
622 pass_dominator (gcc::context *ctxt)
kono
parents: 67
diff changeset
623 : gimple_opt_pass (pass_data_dominator, ctxt),
kono
parents: 67
diff changeset
624 may_peel_loop_headers_p (false)
kono
parents: 67
diff changeset
625 {}
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
626
111
kono
parents: 67
diff changeset
627 /* opt_pass methods: */
kono
parents: 67
diff changeset
628 opt_pass * clone () { return new pass_dominator (m_ctxt); }
kono
parents: 67
diff changeset
629 void set_pass_param (unsigned int n, bool param)
kono
parents: 67
diff changeset
630 {
kono
parents: 67
diff changeset
631 gcc_assert (n == 0);
kono
parents: 67
diff changeset
632 may_peel_loop_headers_p = param;
kono
parents: 67
diff changeset
633 }
kono
parents: 67
diff changeset
634 virtual bool gate (function *) { return flag_tree_dom != 0; }
kono
parents: 67
diff changeset
635 virtual unsigned int execute (function *);
kono
parents: 67
diff changeset
636
kono
parents: 67
diff changeset
637 private:
kono
parents: 67
diff changeset
638 /* This flag is used to prevent loops from being peeled repeatedly in jump
kono
parents: 67
diff changeset
639 threading; it will be removed once we preserve loop structures throughout
kono
parents: 67
diff changeset
640 the compilation -- we will be able to mark the affected loops directly in
kono
parents: 67
diff changeset
641 jump threading, and avoid peeling them next time. */
kono
parents: 67
diff changeset
642 bool may_peel_loop_headers_p;
kono
parents: 67
diff changeset
643 }; // class pass_dominator
kono
parents: 67
diff changeset
644
kono
parents: 67
diff changeset
645 unsigned int
kono
parents: 67
diff changeset
646 pass_dominator::execute (function *fun)
kono
parents: 67
diff changeset
647 {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
648 memset (&opt_stats, 0, sizeof (opt_stats));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
649
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
650 /* Create our hash tables. */
111
kono
parents: 67
diff changeset
651 hash_table<expr_elt_hasher> *avail_exprs
kono
parents: 67
diff changeset
652 = new hash_table<expr_elt_hasher> (1024);
kono
parents: 67
diff changeset
653 class avail_exprs_stack *avail_exprs_stack
kono
parents: 67
diff changeset
654 = new class avail_exprs_stack (avail_exprs);
kono
parents: 67
diff changeset
655 class const_and_copies *const_and_copies = new class const_and_copies ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
656 need_eh_cleanup = BITMAP_ALLOC (NULL);
111
kono
parents: 67
diff changeset
657 need_noreturn_fixup.create (0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
658
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
659 calculate_dominance_info (CDI_DOMINATORS);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
660 cfg_altered = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
661
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
662 /* We need to know loop structures in order to avoid destroying them
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
663 in jump threading. Note that we still can e.g. thread through loop
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
664 headers to an exit edge, or through loop header to the loop body, assuming
111
kono
parents: 67
diff changeset
665 that we update the loop info.
kono
parents: 67
diff changeset
666
kono
parents: 67
diff changeset
667 TODO: We don't need to set LOOPS_HAVE_PREHEADERS generally, but due
kono
parents: 67
diff changeset
668 to several overly conservative bail-outs in jump threading, case
kono
parents: 67
diff changeset
669 gcc.dg/tree-ssa/pr21417.c can't be threaded if loop preheader is
kono
parents: 67
diff changeset
670 missing. We should improve jump threading in future then
kono
parents: 67
diff changeset
671 LOOPS_HAVE_PREHEADERS won't be needed here. */
kono
parents: 67
diff changeset
672 loop_optimizer_init (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
673
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
674 /* Initialize the value-handle array. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
675 threadedge_initialize_values ();
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
676
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
677 /* We need accurate information regarding back edges in the CFG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
678 for jump threading; this may include back edges that are not part of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
679 a single loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
680 mark_dfs_back_edges ();
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
681
111
kono
parents: 67
diff changeset
682 /* We want to create the edge info structures before the dominator walk
kono
parents: 67
diff changeset
683 so that they'll be in place for the jump threader, particularly when
kono
parents: 67
diff changeset
684 threading through a join block.
kono
parents: 67
diff changeset
685
kono
parents: 67
diff changeset
686 The conditions will be lazily updated with global equivalences as
kono
parents: 67
diff changeset
687 we reach them during the dominator walk. */
kono
parents: 67
diff changeset
688 basic_block bb;
kono
parents: 67
diff changeset
689 FOR_EACH_BB_FN (bb, fun)
kono
parents: 67
diff changeset
690 record_edge_info (bb);
kono
parents: 67
diff changeset
691
kono
parents: 67
diff changeset
692 gcond *dummy_cond = gimple_build_cond (NE_EXPR, integer_zero_node,
kono
parents: 67
diff changeset
693 integer_zero_node, NULL, NULL);
kono
parents: 67
diff changeset
694
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
695 /* Recursively walk the dominator tree optimizing statements. */
111
kono
parents: 67
diff changeset
696 dom_opt_dom_walker walker (CDI_DOMINATORS, const_and_copies,
kono
parents: 67
diff changeset
697 avail_exprs_stack, dummy_cond);
kono
parents: 67
diff changeset
698 walker.walk (fun->cfg->x_entry_block_ptr);
kono
parents: 67
diff changeset
699
kono
parents: 67
diff changeset
700 /* Look for blocks where we cleared EDGE_EXECUTABLE on an outgoing
kono
parents: 67
diff changeset
701 edge. When found, remove jump threads which contain any outgoing
kono
parents: 67
diff changeset
702 edge from the affected block. */
kono
parents: 67
diff changeset
703 if (cfg_altered)
kono
parents: 67
diff changeset
704 {
kono
parents: 67
diff changeset
705 FOR_EACH_BB_FN (bb, fun)
kono
parents: 67
diff changeset
706 {
kono
parents: 67
diff changeset
707 edge_iterator ei;
kono
parents: 67
diff changeset
708 edge e;
kono
parents: 67
diff changeset
709
kono
parents: 67
diff changeset
710 /* First see if there are any edges without EDGE_EXECUTABLE
kono
parents: 67
diff changeset
711 set. */
kono
parents: 67
diff changeset
712 bool found = false;
kono
parents: 67
diff changeset
713 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
714 {
kono
parents: 67
diff changeset
715 if ((e->flags & EDGE_EXECUTABLE) == 0)
kono
parents: 67
diff changeset
716 {
kono
parents: 67
diff changeset
717 found = true;
kono
parents: 67
diff changeset
718 break;
kono
parents: 67
diff changeset
719 }
kono
parents: 67
diff changeset
720 }
kono
parents: 67
diff changeset
721
kono
parents: 67
diff changeset
722 /* If there were any such edges found, then remove jump threads
kono
parents: 67
diff changeset
723 containing any edge leaving BB. */
kono
parents: 67
diff changeset
724 if (found)
kono
parents: 67
diff changeset
725 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
726 remove_jump_threads_including (e);
kono
parents: 67
diff changeset
727 }
kono
parents: 67
diff changeset
728 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
729
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
730 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
731 gimple_stmt_iterator gsi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
732 basic_block bb;
111
kono
parents: 67
diff changeset
733 FOR_EACH_BB_FN (bb, fun)
kono
parents: 67
diff changeset
734 {
kono
parents: 67
diff changeset
735 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
736 update_stmt_if_modified (gsi_stmt (gsi));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
739
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
740 /* If we exposed any new variables, go ahead and put them into
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
741 SSA form now, before we handle jump threading. This simplifies
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
742 interactions between rewriting of _DECL nodes into SSA form
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
743 and rewriting SSA_NAME nodes into SSA form after block
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
744 duplication and CFG manipulation. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
745 update_ssa (TODO_update_ssa);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
746
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
747 free_all_edge_infos ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
748
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
749 /* Thread jumps, creating duplicate blocks as needed. */
111
kono
parents: 67
diff changeset
750 cfg_altered |= thread_through_all_blocks (may_peel_loop_headers_p);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
751
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
752 if (cfg_altered)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
753 free_dominance_info (CDI_DOMINATORS);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
754
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
755 /* Removal of statements may make some EH edges dead. Purge
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
756 such edges from the CFG as needed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
757 if (!bitmap_empty_p (need_eh_cleanup))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
758 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
759 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
760 bitmap_iterator bi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
761
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
762 /* Jump threading may have created forwarder blocks from blocks
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
763 needing EH cleanup; the new successor of these blocks, which
111
kono
parents: 67
diff changeset
764 has inherited from the original block, needs the cleanup.
kono
parents: 67
diff changeset
765 Don't clear bits in the bitmap, as that can break the bitmap
kono
parents: 67
diff changeset
766 iterator. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
767 EXECUTE_IF_SET_IN_BITMAP (need_eh_cleanup, 0, i, bi)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
768 {
111
kono
parents: 67
diff changeset
769 basic_block bb = BASIC_BLOCK_FOR_FN (fun, i);
kono
parents: 67
diff changeset
770 if (bb == NULL)
kono
parents: 67
diff changeset
771 continue;
kono
parents: 67
diff changeset
772 while (single_succ_p (bb)
kono
parents: 67
diff changeset
773 && (single_succ_edge (bb)->flags & EDGE_EH) == 0)
kono
parents: 67
diff changeset
774 bb = single_succ (bb);
kono
parents: 67
diff changeset
775 if (bb == EXIT_BLOCK_PTR_FOR_FN (fun))
kono
parents: 67
diff changeset
776 continue;
kono
parents: 67
diff changeset
777 if ((unsigned) bb->index != i)
kono
parents: 67
diff changeset
778 bitmap_set_bit (need_eh_cleanup, bb->index);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
779 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
780
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
781 gimple_purge_all_dead_eh_edges (need_eh_cleanup);
111
kono
parents: 67
diff changeset
782 bitmap_clear (need_eh_cleanup);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
783 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
784
111
kono
parents: 67
diff changeset
785 /* Fixup stmts that became noreturn calls. This may require splitting
kono
parents: 67
diff changeset
786 blocks and thus isn't possible during the dominator walk or before
kono
parents: 67
diff changeset
787 jump threading finished. Do this in reverse order so we don't
kono
parents: 67
diff changeset
788 inadvertedly remove a stmt we want to fixup by visiting a dominating
kono
parents: 67
diff changeset
789 now noreturn call first. */
kono
parents: 67
diff changeset
790 while (!need_noreturn_fixup.is_empty ())
kono
parents: 67
diff changeset
791 {
kono
parents: 67
diff changeset
792 gimple *stmt = need_noreturn_fixup.pop ();
kono
parents: 67
diff changeset
793 if (dump_file && dump_flags & TDF_DETAILS)
kono
parents: 67
diff changeset
794 {
kono
parents: 67
diff changeset
795 fprintf (dump_file, "Fixing up noreturn call ");
kono
parents: 67
diff changeset
796 print_gimple_stmt (dump_file, stmt, 0);
kono
parents: 67
diff changeset
797 fprintf (dump_file, "\n");
kono
parents: 67
diff changeset
798 }
kono
parents: 67
diff changeset
799 fixup_noreturn_call (stmt);
kono
parents: 67
diff changeset
800 }
kono
parents: 67
diff changeset
801
kono
parents: 67
diff changeset
802 statistics_counter_event (fun, "Redundant expressions eliminated",
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
803 opt_stats.num_re);
111
kono
parents: 67
diff changeset
804 statistics_counter_event (fun, "Constants propagated",
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
805 opt_stats.num_const_prop);
111
kono
parents: 67
diff changeset
806 statistics_counter_event (fun, "Copies propagated",
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
807 opt_stats.num_copy_prop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
808
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
809 /* Debugging dumps. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
810 if (dump_file && (dump_flags & TDF_STATS))
111
kono
parents: 67
diff changeset
811 dump_dominator_optimization_stats (dump_file, avail_exprs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
812
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
813 loop_optimizer_finalize ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
814
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
815 /* Delete our main hashtable. */
111
kono
parents: 67
diff changeset
816 delete avail_exprs;
kono
parents: 67
diff changeset
817 avail_exprs = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
818
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
819 /* Free asserted bitmaps and stacks. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
820 BITMAP_FREE (need_eh_cleanup);
111
kono
parents: 67
diff changeset
821 need_noreturn_fixup.release ();
kono
parents: 67
diff changeset
822 delete avail_exprs_stack;
kono
parents: 67
diff changeset
823 delete const_and_copies;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
824
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
825 /* Free the value-handle array. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
826 threadedge_finalize_values ();
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
827
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
828 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
829 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
830
111
kono
parents: 67
diff changeset
831 } // anon namespace
kono
parents: 67
diff changeset
832
kono
parents: 67
diff changeset
833 gimple_opt_pass *
kono
parents: 67
diff changeset
834 make_pass_dominator (gcc::context *ctxt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
835 {
111
kono
parents: 67
diff changeset
836 return new pass_dominator (ctxt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
837 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
838
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
839
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
840 /* A trivial wrapper so that we can present the generic jump
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
841 threading code with a simple API for simplifying statements. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
842 static tree
111
kono
parents: 67
diff changeset
843 simplify_stmt_for_jump_threading (gimple *stmt,
kono
parents: 67
diff changeset
844 gimple *within_stmt ATTRIBUTE_UNUSED,
kono
parents: 67
diff changeset
845 class avail_exprs_stack *avail_exprs_stack,
kono
parents: 67
diff changeset
846 basic_block bb ATTRIBUTE_UNUSED)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
847 {
111
kono
parents: 67
diff changeset
848 return avail_exprs_stack->lookup_avail_expr (stmt, false, true);
kono
parents: 67
diff changeset
849 }
kono
parents: 67
diff changeset
850
kono
parents: 67
diff changeset
851 /* Valueize hook for gimple_fold_stmt_to_constant_1. */
kono
parents: 67
diff changeset
852
kono
parents: 67
diff changeset
853 static tree
kono
parents: 67
diff changeset
854 dom_valueize (tree t)
kono
parents: 67
diff changeset
855 {
kono
parents: 67
diff changeset
856 if (TREE_CODE (t) == SSA_NAME)
kono
parents: 67
diff changeset
857 {
kono
parents: 67
diff changeset
858 tree tem = SSA_NAME_VALUE (t);
kono
parents: 67
diff changeset
859 if (tem)
kono
parents: 67
diff changeset
860 return tem;
kono
parents: 67
diff changeset
861 }
kono
parents: 67
diff changeset
862 return t;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
863 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
864
111
kono
parents: 67
diff changeset
865 /* We have just found an equivalence for LHS on an edge E.
kono
parents: 67
diff changeset
866 Look backwards to other uses of LHS and see if we can derive
kono
parents: 67
diff changeset
867 additional equivalences that are valid on edge E. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
868 static void
111
kono
parents: 67
diff changeset
869 back_propagate_equivalences (tree lhs, edge e,
kono
parents: 67
diff changeset
870 class const_and_copies *const_and_copies)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
871 {
111
kono
parents: 67
diff changeset
872 use_operand_p use_p;
kono
parents: 67
diff changeset
873 imm_use_iterator iter;
kono
parents: 67
diff changeset
874 bitmap domby = NULL;
kono
parents: 67
diff changeset
875 basic_block dest = e->dest;
kono
parents: 67
diff changeset
876
kono
parents: 67
diff changeset
877 /* Iterate over the uses of LHS to see if any dominate E->dest.
kono
parents: 67
diff changeset
878 If so, they may create useful equivalences too.
kono
parents: 67
diff changeset
879
kono
parents: 67
diff changeset
880 ??? If the code gets re-organized to a worklist to catch more
kono
parents: 67
diff changeset
881 indirect opportunities and it is made to handle PHIs then this
kono
parents: 67
diff changeset
882 should only consider use_stmts in basic-blocks we have already visited. */
kono
parents: 67
diff changeset
883 FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
kono
parents: 67
diff changeset
884 {
kono
parents: 67
diff changeset
885 gimple *use_stmt = USE_STMT (use_p);
kono
parents: 67
diff changeset
886
kono
parents: 67
diff changeset
887 /* Often the use is in DEST, which we trivially know we can't use.
kono
parents: 67
diff changeset
888 This is cheaper than the dominator set tests below. */
kono
parents: 67
diff changeset
889 if (dest == gimple_bb (use_stmt))
kono
parents: 67
diff changeset
890 continue;
kono
parents: 67
diff changeset
891
kono
parents: 67
diff changeset
892 /* Filter out statements that can never produce a useful
kono
parents: 67
diff changeset
893 equivalence. */
kono
parents: 67
diff changeset
894 tree lhs2 = gimple_get_lhs (use_stmt);
kono
parents: 67
diff changeset
895 if (!lhs2 || TREE_CODE (lhs2) != SSA_NAME)
kono
parents: 67
diff changeset
896 continue;
kono
parents: 67
diff changeset
897
kono
parents: 67
diff changeset
898 /* Profiling has shown the domination tests here can be fairly
kono
parents: 67
diff changeset
899 expensive. We get significant improvements by building the
kono
parents: 67
diff changeset
900 set of blocks that dominate BB. We can then just test
kono
parents: 67
diff changeset
901 for set membership below.
kono
parents: 67
diff changeset
902
kono
parents: 67
diff changeset
903 We also initialize the set lazily since often the only uses
kono
parents: 67
diff changeset
904 are going to be in the same block as DEST. */
kono
parents: 67
diff changeset
905 if (!domby)
kono
parents: 67
diff changeset
906 {
kono
parents: 67
diff changeset
907 domby = BITMAP_ALLOC (NULL);
kono
parents: 67
diff changeset
908 basic_block bb = get_immediate_dominator (CDI_DOMINATORS, dest);
kono
parents: 67
diff changeset
909 while (bb)
kono
parents: 67
diff changeset
910 {
kono
parents: 67
diff changeset
911 bitmap_set_bit (domby, bb->index);
kono
parents: 67
diff changeset
912 bb = get_immediate_dominator (CDI_DOMINATORS, bb);
kono
parents: 67
diff changeset
913 }
kono
parents: 67
diff changeset
914 }
kono
parents: 67
diff changeset
915
kono
parents: 67
diff changeset
916 /* This tests if USE_STMT does not dominate DEST. */
kono
parents: 67
diff changeset
917 if (!bitmap_bit_p (domby, gimple_bb (use_stmt)->index))
kono
parents: 67
diff changeset
918 continue;
kono
parents: 67
diff changeset
919
kono
parents: 67
diff changeset
920 /* At this point USE_STMT dominates DEST and may result in a
kono
parents: 67
diff changeset
921 useful equivalence. Try to simplify its RHS to a constant
kono
parents: 67
diff changeset
922 or SSA_NAME. */
kono
parents: 67
diff changeset
923 tree res = gimple_fold_stmt_to_constant_1 (use_stmt, dom_valueize,
kono
parents: 67
diff changeset
924 no_follow_ssa_edges);
kono
parents: 67
diff changeset
925 if (res && (TREE_CODE (res) == SSA_NAME || is_gimple_min_invariant (res)))
kono
parents: 67
diff changeset
926 record_equality (lhs2, res, const_and_copies);
kono
parents: 67
diff changeset
927 }
kono
parents: 67
diff changeset
928
kono
parents: 67
diff changeset
929 if (domby)
kono
parents: 67
diff changeset
930 BITMAP_FREE (domby);
kono
parents: 67
diff changeset
931 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
932
111
kono
parents: 67
diff changeset
933 /* Record into CONST_AND_COPIES and AVAIL_EXPRS_STACK any equivalences implied
kono
parents: 67
diff changeset
934 by traversing edge E (which are cached in E->aux).
kono
parents: 67
diff changeset
935
kono
parents: 67
diff changeset
936 Callers are responsible for managing the unwinding markers. */
kono
parents: 67
diff changeset
937 void
kono
parents: 67
diff changeset
938 record_temporary_equivalences (edge e,
kono
parents: 67
diff changeset
939 class const_and_copies *const_and_copies,
kono
parents: 67
diff changeset
940 class avail_exprs_stack *avail_exprs_stack)
kono
parents: 67
diff changeset
941 {
kono
parents: 67
diff changeset
942 int i;
kono
parents: 67
diff changeset
943 class edge_info *edge_info = (class edge_info *) e->aux;
kono
parents: 67
diff changeset
944
kono
parents: 67
diff changeset
945 /* If we have info associated with this edge, record it into
kono
parents: 67
diff changeset
946 our equivalence tables. */
kono
parents: 67
diff changeset
947 if (edge_info)
kono
parents: 67
diff changeset
948 {
kono
parents: 67
diff changeset
949 cond_equivalence *eq;
kono
parents: 67
diff changeset
950 /* If we have 0 = COND or 1 = COND equivalences, record them
kono
parents: 67
diff changeset
951 into our expression hash tables. */
kono
parents: 67
diff changeset
952 for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i)
kono
parents: 67
diff changeset
953 avail_exprs_stack->record_cond (eq);
kono
parents: 67
diff changeset
954
kono
parents: 67
diff changeset
955 edge_info::equiv_pair *seq;
kono
parents: 67
diff changeset
956 for (i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i)
kono
parents: 67
diff changeset
957 {
kono
parents: 67
diff changeset
958 tree lhs = seq->first;
kono
parents: 67
diff changeset
959 if (!lhs || TREE_CODE (lhs) != SSA_NAME)
kono
parents: 67
diff changeset
960 continue;
kono
parents: 67
diff changeset
961
kono
parents: 67
diff changeset
962 /* Record the simple NAME = VALUE equivalence. */
kono
parents: 67
diff changeset
963 tree rhs = seq->second;
kono
parents: 67
diff changeset
964
kono
parents: 67
diff changeset
965 /* If this is a SSA_NAME = SSA_NAME equivalence and one operand is
kono
parents: 67
diff changeset
966 cheaper to compute than the other, then set up the equivalence
kono
parents: 67
diff changeset
967 such that we replace the expensive one with the cheap one.
kono
parents: 67
diff changeset
968
kono
parents: 67
diff changeset
969 If they are the same cost to compute, then do not record
kono
parents: 67
diff changeset
970 anything. */
kono
parents: 67
diff changeset
971 if (TREE_CODE (lhs) == SSA_NAME && TREE_CODE (rhs) == SSA_NAME)
kono
parents: 67
diff changeset
972 {
kono
parents: 67
diff changeset
973 gimple *rhs_def = SSA_NAME_DEF_STMT (rhs);
kono
parents: 67
diff changeset
974 int rhs_cost = estimate_num_insns (rhs_def, &eni_size_weights);
kono
parents: 67
diff changeset
975
kono
parents: 67
diff changeset
976 gimple *lhs_def = SSA_NAME_DEF_STMT (lhs);
kono
parents: 67
diff changeset
977 int lhs_cost = estimate_num_insns (lhs_def, &eni_size_weights);
kono
parents: 67
diff changeset
978
kono
parents: 67
diff changeset
979 if (rhs_cost > lhs_cost)
kono
parents: 67
diff changeset
980 record_equality (rhs, lhs, const_and_copies);
kono
parents: 67
diff changeset
981 else if (rhs_cost < lhs_cost)
kono
parents: 67
diff changeset
982 record_equality (lhs, rhs, const_and_copies);
kono
parents: 67
diff changeset
983 }
kono
parents: 67
diff changeset
984 else
kono
parents: 67
diff changeset
985 record_equality (lhs, rhs, const_and_copies);
kono
parents: 67
diff changeset
986
kono
parents: 67
diff changeset
987
kono
parents: 67
diff changeset
988 /* Any equivalence found for LHS may result in additional
kono
parents: 67
diff changeset
989 equivalences for other uses of LHS that we have already
kono
parents: 67
diff changeset
990 processed. */
kono
parents: 67
diff changeset
991 back_propagate_equivalences (lhs, e, const_and_copies);
kono
parents: 67
diff changeset
992 }
kono
parents: 67
diff changeset
993 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
994 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
995
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
996 /* PHI nodes can create equivalences too.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
997
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
998 Ignoring any alternatives which are the same as the result, if
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
999 all the alternatives are equal, then the PHI node creates an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1000 equivalence. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1001
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1002 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1003 record_equivalences_from_phis (basic_block bb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1004 {
111
kono
parents: 67
diff changeset
1005 gphi_iterator gsi;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1006
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1007 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1008 {
111
kono
parents: 67
diff changeset
1009 gphi *phi = gsi.phi ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1010
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1011 tree lhs = gimple_phi_result (phi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1012 tree rhs = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1013 size_t i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1014
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1015 for (i = 0; i < gimple_phi_num_args (phi); i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1016 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1017 tree t = gimple_phi_arg_def (phi, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1018
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1019 /* Ignore alternatives which are the same as our LHS. Since
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1020 LHS is a PHI_RESULT, it is known to be a SSA_NAME, so we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1021 can simply compare pointers. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1022 if (lhs == t)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1023 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1024
111
kono
parents: 67
diff changeset
1025 /* If the associated edge is not marked as executable, then it
kono
parents: 67
diff changeset
1026 can be ignored. */
kono
parents: 67
diff changeset
1027 if ((gimple_phi_arg_edge (phi, i)->flags & EDGE_EXECUTABLE) == 0)
kono
parents: 67
diff changeset
1028 continue;
kono
parents: 67
diff changeset
1029
kono
parents: 67
diff changeset
1030 t = dom_valueize (t);
kono
parents: 67
diff changeset
1031
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1032 /* If we have not processed an alternative yet, then set
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1033 RHS to this alternative. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1034 if (rhs == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1035 rhs = t;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1036 /* If we have processed an alternative (stored in RHS), then
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1037 see if it is equal to this one. If it isn't, then stop
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1038 the search. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1039 else if (! operand_equal_for_phi_arg_p (rhs, t))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1040 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1041 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1042
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1043 /* If we had no interesting alternatives, then all the RHS alternatives
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1044 must have been the same as LHS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1045 if (!rhs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1046 rhs = lhs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1047
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1048 /* If we managed to iterate through each PHI alternative without
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1049 breaking out of the loop, then we have a PHI which may create
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1050 a useful equivalence. We do not need to record unwind data for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1051 this, since this is a true assignment and not an equivalence
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1052 inferred from a comparison. All uses of this ssa name are dominated
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1053 by this assignment, so unwinding just costs time and space. */
111
kono
parents: 67
diff changeset
1054 if (i == gimple_phi_num_args (phi)
kono
parents: 67
diff changeset
1055 && may_propagate_copy (lhs, rhs))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1056 set_ssa_name_value (lhs, rhs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1057 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1058 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1059
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1060 /* Ignoring loop backedges, if BB has precisely one incoming edge then
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1061 return that edge. Otherwise return NULL. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1062 static edge
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1063 single_incoming_edge_ignoring_loop_edges (basic_block bb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1064 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1065 edge retval = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1066 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1067 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1068
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1069 FOR_EACH_EDGE (e, ei, bb->preds)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1070 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1071 /* A loop back edge can be identified by the destination of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1072 the edge dominating the source of the edge. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1073 if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1074 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1075
111
kono
parents: 67
diff changeset
1076 /* We can safely ignore edges that are not executable. */
kono
parents: 67
diff changeset
1077 if ((e->flags & EDGE_EXECUTABLE) == 0)
kono
parents: 67
diff changeset
1078 continue;
kono
parents: 67
diff changeset
1079
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1080 /* If we have already seen a non-loop edge, then we must have
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1081 multiple incoming non-loop edges and thus we return NULL. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1082 if (retval)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1083 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1084
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1085 /* This is the first non-loop incoming edge we have found. Record
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1086 it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1087 retval = e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1088 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1089
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1090 return retval;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1091 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1092
111
kono
parents: 67
diff changeset
1093 /* Record any equivalences created by the incoming edge to BB into
kono
parents: 67
diff changeset
1094 CONST_AND_COPIES and AVAIL_EXPRS_STACK. If BB has more than one
kono
parents: 67
diff changeset
1095 incoming edge, then no equivalence is created. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1096
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1097 static void
111
kono
parents: 67
diff changeset
1098 record_equivalences_from_incoming_edge (basic_block bb,
kono
parents: 67
diff changeset
1099 class const_and_copies *const_and_copies,
kono
parents: 67
diff changeset
1100 class avail_exprs_stack *avail_exprs_stack)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1101 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1102 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1103 basic_block parent;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1104
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1105 /* If our parent block ended with a control statement, then we may be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1106 able to record some equivalences based on which outgoing edge from
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1107 the parent was followed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1108 parent = get_immediate_dominator (CDI_DOMINATORS, bb);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1109
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1110 e = single_incoming_edge_ignoring_loop_edges (bb);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1111
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1112 /* If we had a single incoming edge from our parent block, then enter
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1113 any data associated with the edge into our tables. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1114 if (e && e->src == parent)
111
kono
parents: 67
diff changeset
1115 record_temporary_equivalences (e, const_and_copies, avail_exprs_stack);
kono
parents: 67
diff changeset
1116 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1117
111
kono
parents: 67
diff changeset
1118 /* Dump statistics for the hash table HTAB. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1119
111
kono
parents: 67
diff changeset
1120 static void
kono
parents: 67
diff changeset
1121 htab_statistics (FILE *file, const hash_table<expr_elt_hasher> &htab)
kono
parents: 67
diff changeset
1122 {
kono
parents: 67
diff changeset
1123 fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
kono
parents: 67
diff changeset
1124 (long) htab.size (),
kono
parents: 67
diff changeset
1125 (long) htab.elements (),
kono
parents: 67
diff changeset
1126 htab.collisions ());
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1127 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1128
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1129 /* Dump SSA statistics on FILE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1130
111
kono
parents: 67
diff changeset
1131 static void
kono
parents: 67
diff changeset
1132 dump_dominator_optimization_stats (FILE *file,
kono
parents: 67
diff changeset
1133 hash_table<expr_elt_hasher> *avail_exprs)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1134 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1135 fprintf (file, "Total number of statements: %6ld\n\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1136 opt_stats.num_stmts);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1137 fprintf (file, "Exprs considered for dominator optimizations: %6ld\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1138 opt_stats.num_exprs_considered);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1139
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1140 fprintf (file, "\nHash table statistics:\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1141
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1142 fprintf (file, " avail_exprs: ");
111
kono
parents: 67
diff changeset
1143 htab_statistics (file, *avail_exprs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1144 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1145
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1146
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1147 /* Similarly, but assume that X and Y are the two operands of an EQ_EXPR.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1148 This constrains the cases in which we may treat this as assignment. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1149
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1150 static void
111
kono
parents: 67
diff changeset
1151 record_equality (tree x, tree y, class const_and_copies *const_and_copies)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1152 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1153 tree prev_x = NULL, prev_y = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1154
111
kono
parents: 67
diff changeset
1155 if (tree_swap_operands_p (x, y))
kono
parents: 67
diff changeset
1156 std::swap (x, y);
kono
parents: 67
diff changeset
1157
kono
parents: 67
diff changeset
1158 /* Most of the time tree_swap_operands_p does what we want. But there
kono
parents: 67
diff changeset
1159 are cases where we know one operand is better for copy propagation than
kono
parents: 67
diff changeset
1160 the other. Given no other code cares about ordering of equality
kono
parents: 67
diff changeset
1161 comparison operators for that purpose, we just handle the special cases
kono
parents: 67
diff changeset
1162 here. */
kono
parents: 67
diff changeset
1163 if (TREE_CODE (x) == SSA_NAME && TREE_CODE (y) == SSA_NAME)
kono
parents: 67
diff changeset
1164 {
kono
parents: 67
diff changeset
1165 /* If one operand is a single use operand, then make it
kono
parents: 67
diff changeset
1166 X. This will preserve its single use properly and if this
kono
parents: 67
diff changeset
1167 conditional is eliminated, the computation of X can be
kono
parents: 67
diff changeset
1168 eliminated as well. */
kono
parents: 67
diff changeset
1169 if (has_single_use (y) && ! has_single_use (x))
kono
parents: 67
diff changeset
1170 std::swap (x, y);
kono
parents: 67
diff changeset
1171 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1172 if (TREE_CODE (x) == SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1173 prev_x = SSA_NAME_VALUE (x);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1174 if (TREE_CODE (y) == SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1175 prev_y = SSA_NAME_VALUE (y);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1176
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1177 /* If one of the previous values is invariant, or invariant in more loops
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1178 (by depth), then use that.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1179 Otherwise it doesn't matter which value we choose, just so
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1180 long as we canonicalize on one value. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1181 if (is_gimple_min_invariant (y))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1182 ;
111
kono
parents: 67
diff changeset
1183 else if (is_gimple_min_invariant (x))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1184 prev_x = x, x = y, y = prev_x, prev_x = prev_y;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1185 else if (prev_x && is_gimple_min_invariant (prev_x))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1186 x = y, y = prev_x, prev_x = prev_y;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1187 else if (prev_y)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1188 y = prev_y;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1189
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1190 /* After the swapping, we must have one SSA_NAME. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1191 if (TREE_CODE (x) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1192 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1193
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1194 /* For IEEE, -0.0 == 0.0, so we don't necessarily know the sign of a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1195 variable compared against zero. If we're honoring signed zeros,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1196 then we cannot record this value unless we know that the value is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1197 nonzero. */
111
kono
parents: 67
diff changeset
1198 if (HONOR_SIGNED_ZEROS (x)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1199 && (TREE_CODE (y) != REAL_CST
111
kono
parents: 67
diff changeset
1200 || real_equal (&dconst0, &TREE_REAL_CST (y))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1201 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1202
111
kono
parents: 67
diff changeset
1203 const_and_copies->record_const_or_copy (x, y, prev_x);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1204 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1205
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1206 /* Returns true when STMT is a simple iv increment. It detects the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1207 following situation:
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1208
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1209 i_1 = phi (..., i_2)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1210 i_2 = i_1 +/- ... */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1211
111
kono
parents: 67
diff changeset
1212 bool
kono
parents: 67
diff changeset
1213 simple_iv_increment_p (gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1214 {
111
kono
parents: 67
diff changeset
1215 enum tree_code code;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1216 tree lhs, preinc;
111
kono
parents: 67
diff changeset
1217 gimple *phi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1218 size_t i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1219
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1220 if (gimple_code (stmt) != GIMPLE_ASSIGN)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1221 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1222
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1223 lhs = gimple_assign_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1224 if (TREE_CODE (lhs) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1225 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1226
111
kono
parents: 67
diff changeset
1227 code = gimple_assign_rhs_code (stmt);
kono
parents: 67
diff changeset
1228 if (code != PLUS_EXPR
kono
parents: 67
diff changeset
1229 && code != MINUS_EXPR
kono
parents: 67
diff changeset
1230 && code != POINTER_PLUS_EXPR)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1231 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1232
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1233 preinc = gimple_assign_rhs1 (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1234 if (TREE_CODE (preinc) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1235 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1236
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1237 phi = SSA_NAME_DEF_STMT (preinc);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1238 if (gimple_code (phi) != GIMPLE_PHI)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1239 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1240
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1241 for (i = 0; i < gimple_phi_num_args (phi); i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1242 if (gimple_phi_arg_def (phi, i) == lhs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1243 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1244
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1245 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1246 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1247
111
kono
parents: 67
diff changeset
1248 /* Propagate know values from SSA_NAME_VALUE into the PHI nodes of the
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1249 successors of BB. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1250
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1251 static void
111
kono
parents: 67
diff changeset
1252 cprop_into_successor_phis (basic_block bb,
kono
parents: 67
diff changeset
1253 class const_and_copies *const_and_copies)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1254 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1255 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1256 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1257
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1258 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1259 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1260 int indx;
111
kono
parents: 67
diff changeset
1261 gphi_iterator gsi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1262
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1263 /* If this is an abnormal edge, then we do not want to copy propagate
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1264 into the PHI alternative associated with this edge. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1265 if (e->flags & EDGE_ABNORMAL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1266 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1267
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1268 gsi = gsi_start_phis (e->dest);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1269 if (gsi_end_p (gsi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1270 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1271
111
kono
parents: 67
diff changeset
1272 /* We may have an equivalence associated with this edge. While
kono
parents: 67
diff changeset
1273 we can not propagate it into non-dominated blocks, we can
kono
parents: 67
diff changeset
1274 propagate them into PHIs in non-dominated blocks. */
kono
parents: 67
diff changeset
1275
kono
parents: 67
diff changeset
1276 /* Push the unwind marker so we can reset the const and copies
kono
parents: 67
diff changeset
1277 table back to its original state after processing this edge. */
kono
parents: 67
diff changeset
1278 const_and_copies->push_marker ();
kono
parents: 67
diff changeset
1279
kono
parents: 67
diff changeset
1280 /* Extract and record any simple NAME = VALUE equivalences.
kono
parents: 67
diff changeset
1281
kono
parents: 67
diff changeset
1282 Don't bother with [01] = COND equivalences, they're not useful
kono
parents: 67
diff changeset
1283 here. */
kono
parents: 67
diff changeset
1284 class edge_info *edge_info = (class edge_info *) e->aux;
kono
parents: 67
diff changeset
1285
kono
parents: 67
diff changeset
1286 if (edge_info)
kono
parents: 67
diff changeset
1287 {
kono
parents: 67
diff changeset
1288 edge_info::equiv_pair *seq;
kono
parents: 67
diff changeset
1289 for (int i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i)
kono
parents: 67
diff changeset
1290 {
kono
parents: 67
diff changeset
1291 tree lhs = seq->first;
kono
parents: 67
diff changeset
1292 tree rhs = seq->second;
kono
parents: 67
diff changeset
1293
kono
parents: 67
diff changeset
1294 if (lhs && TREE_CODE (lhs) == SSA_NAME)
kono
parents: 67
diff changeset
1295 const_and_copies->record_const_or_copy (lhs, rhs);
kono
parents: 67
diff changeset
1296 }
kono
parents: 67
diff changeset
1297
kono
parents: 67
diff changeset
1298 }
kono
parents: 67
diff changeset
1299
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1300 indx = e->dest_idx;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1301 for ( ; !gsi_end_p (gsi); gsi_next (&gsi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1302 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1303 tree new_val;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1304 use_operand_p orig_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1305 tree orig_val;
111
kono
parents: 67
diff changeset
1306 gphi *phi = gsi.phi ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1307
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1308 /* The alternative may be associated with a constant, so verify
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1309 it is an SSA_NAME before doing anything with it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1310 orig_p = gimple_phi_arg_imm_use_ptr (phi, indx);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1311 orig_val = get_use_from_ptr (orig_p);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1312 if (TREE_CODE (orig_val) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1313 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1314
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1315 /* If we have *ORIG_P in our constant/copy table, then replace
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1316 ORIG_P with its value in our constant/copy table. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1317 new_val = SSA_NAME_VALUE (orig_val);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1318 if (new_val
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1319 && new_val != orig_val
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1320 && may_propagate_copy (orig_val, new_val))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1321 propagate_value (orig_p, new_val);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1322 }
111
kono
parents: 67
diff changeset
1323
kono
parents: 67
diff changeset
1324 const_and_copies->pop_to_marker ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1325 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1326 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1327
111
kono
parents: 67
diff changeset
1328 edge
kono
parents: 67
diff changeset
1329 dom_opt_dom_walker::before_dom_children (basic_block bb)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1330 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1331 gimple_stmt_iterator gsi;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1332
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1333 if (dump_file && (dump_flags & TDF_DETAILS))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1334 fprintf (dump_file, "\n\nOptimizing block #%d\n\n", bb->index);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1335
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1336 /* Push a marker on the stacks of local information so that we know how
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1337 far to unwind when we finalize this block. */
111
kono
parents: 67
diff changeset
1338 m_avail_exprs_stack->push_marker ();
kono
parents: 67
diff changeset
1339 m_const_and_copies->push_marker ();
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1340
111
kono
parents: 67
diff changeset
1341 record_equivalences_from_incoming_edge (bb, m_const_and_copies,
kono
parents: 67
diff changeset
1342 m_avail_exprs_stack);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1343
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1344 /* PHI nodes can create equivalences too. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1345 record_equivalences_from_phis (bb);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1346
111
kono
parents: 67
diff changeset
1347 /* Create equivalences from redundant PHIs. PHIs are only truly
kono
parents: 67
diff changeset
1348 redundant when they exist in the same block, so push another
kono
parents: 67
diff changeset
1349 marker and unwind right afterwards. */
kono
parents: 67
diff changeset
1350 m_avail_exprs_stack->push_marker ();
kono
parents: 67
diff changeset
1351 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
kono
parents: 67
diff changeset
1352 eliminate_redundant_computations (&gsi, m_const_and_copies,
kono
parents: 67
diff changeset
1353 m_avail_exprs_stack);
kono
parents: 67
diff changeset
1354 m_avail_exprs_stack->pop_to_marker ();
kono
parents: 67
diff changeset
1355
kono
parents: 67
diff changeset
1356 edge taken_edge = NULL;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1357 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
111
kono
parents: 67
diff changeset
1358 taken_edge = this->optimize_stmt (bb, gsi);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1359
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1360 /* Now prepare to process dominated blocks. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1361 record_edge_info (bb);
111
kono
parents: 67
diff changeset
1362 cprop_into_successor_phis (bb, m_const_and_copies);
kono
parents: 67
diff changeset
1363 if (taken_edge && !dbg_cnt (dom_unreachable_edges))
kono
parents: 67
diff changeset
1364 return NULL;
kono
parents: 67
diff changeset
1365
kono
parents: 67
diff changeset
1366 return taken_edge;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1367 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1368
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1369 /* We have finished processing the dominator children of BB, perform
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1370 any finalization actions in preparation for leaving this node in
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1371 the dominator tree. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1372
111
kono
parents: 67
diff changeset
1373 void
kono
parents: 67
diff changeset
1374 dom_opt_dom_walker::after_dom_children (basic_block bb)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1375 {
111
kono
parents: 67
diff changeset
1376 thread_outgoing_edges (bb, m_dummy_cond, m_const_and_copies,
kono
parents: 67
diff changeset
1377 m_avail_exprs_stack,
kono
parents: 67
diff changeset
1378 simplify_stmt_for_jump_threading);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1379
111
kono
parents: 67
diff changeset
1380 /* These remove expressions local to BB from the tables. */
kono
parents: 67
diff changeset
1381 m_avail_exprs_stack->pop_to_marker ();
kono
parents: 67
diff changeset
1382 m_const_and_copies->pop_to_marker ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1383 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1384
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1385 /* Search for redundant computations in STMT. If any are found, then
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1386 replace them with the variable holding the result of the computation.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1387
111
kono
parents: 67
diff changeset
1388 If safe, record this expression into AVAIL_EXPRS_STACK and
kono
parents: 67
diff changeset
1389 CONST_AND_COPIES. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1390
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1391 static void
111
kono
parents: 67
diff changeset
1392 eliminate_redundant_computations (gimple_stmt_iterator* gsi,
kono
parents: 67
diff changeset
1393 class const_and_copies *const_and_copies,
kono
parents: 67
diff changeset
1394 class avail_exprs_stack *avail_exprs_stack)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1395 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1396 tree expr_type;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1397 tree cached_lhs;
111
kono
parents: 67
diff changeset
1398 tree def;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1399 bool insert = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1400 bool assigns_var_p = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1401
111
kono
parents: 67
diff changeset
1402 gimple *stmt = gsi_stmt (*gsi);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1403
111
kono
parents: 67
diff changeset
1404 if (gimple_code (stmt) == GIMPLE_PHI)
kono
parents: 67
diff changeset
1405 def = gimple_phi_result (stmt);
kono
parents: 67
diff changeset
1406 else
kono
parents: 67
diff changeset
1407 def = gimple_get_lhs (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1408
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1409 /* Certain expressions on the RHS can be optimized away, but can not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1410 themselves be entered into the hash tables. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1411 if (! def
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1412 || TREE_CODE (def) != SSA_NAME
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1413 || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1414 || gimple_vdef (stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1415 /* Do not record equivalences for increments of ivs. This would create
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1416 overlapping live ranges for a very questionable gain. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1417 || simple_iv_increment_p (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1418 insert = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1419
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1420 /* Check if the expression has been computed before. */
111
kono
parents: 67
diff changeset
1421 cached_lhs = avail_exprs_stack->lookup_avail_expr (stmt, insert, true);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1422
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1423 opt_stats.num_exprs_considered++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1424
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1425 /* Get the type of the expression we are trying to optimize. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1426 if (is_gimple_assign (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1427 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1428 expr_type = TREE_TYPE (gimple_assign_lhs (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1429 assigns_var_p = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1430 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1431 else if (gimple_code (stmt) == GIMPLE_COND)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1432 expr_type = boolean_type_node;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1433 else if (is_gimple_call (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1434 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1435 gcc_assert (gimple_call_lhs (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1436 expr_type = TREE_TYPE (gimple_call_lhs (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1437 assigns_var_p = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1438 }
111
kono
parents: 67
diff changeset
1439 else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
kono
parents: 67
diff changeset
1440 expr_type = TREE_TYPE (gimple_switch_index (swtch_stmt));
kono
parents: 67
diff changeset
1441 else if (gimple_code (stmt) == GIMPLE_PHI)
kono
parents: 67
diff changeset
1442 /* We can't propagate into a phi, so the logic below doesn't apply.
kono
parents: 67
diff changeset
1443 Instead record an equivalence between the cached LHS and the
kono
parents: 67
diff changeset
1444 PHI result of this statement, provided they are in the same block.
kono
parents: 67
diff changeset
1445 This should be sufficient to kill the redundant phi. */
kono
parents: 67
diff changeset
1446 {
kono
parents: 67
diff changeset
1447 if (def && cached_lhs)
kono
parents: 67
diff changeset
1448 const_and_copies->record_const_or_copy (def, cached_lhs);
kono
parents: 67
diff changeset
1449 return;
kono
parents: 67
diff changeset
1450 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1451 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1452 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1453
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1454 if (!cached_lhs)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1455 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1456
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1457 /* It is safe to ignore types here since we have already done
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1458 type checking in the hashing and equality routines. In fact
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1459 type checking here merely gets in the way of constant
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1460 propagation. Also, make sure that it is safe to propagate
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1461 CACHED_LHS into the expression in STMT. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1462 if ((TREE_CODE (cached_lhs) != SSA_NAME
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1463 && (assigns_var_p
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1464 || useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1465 || may_propagate_copy_into_stmt (stmt, cached_lhs))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1466 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1467 gcc_checking_assert (TREE_CODE (cached_lhs) == SSA_NAME
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1468 || is_gimple_min_invariant (cached_lhs));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1469
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1470 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1471 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1472 fprintf (dump_file, " Replaced redundant expr '");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1473 print_gimple_expr (dump_file, stmt, 0, dump_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1474 fprintf (dump_file, "' with '");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1475 print_generic_expr (dump_file, cached_lhs, dump_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1476 fprintf (dump_file, "'\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1477 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1478
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1479 opt_stats.num_re++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1480
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1481 if (assigns_var_p
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1482 && !useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1483 cached_lhs = fold_convert (expr_type, cached_lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1484
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1485 propagate_tree_value_into_stmt (gsi, cached_lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1486
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1487 /* Since it is always necessary to mark the result as modified,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1488 perhaps we should move this into propagate_tree_value_into_stmt
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1489 itself. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1490 gimple_set_modified (gsi_stmt (*gsi), true);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1491 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1492 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1493
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1494 /* STMT, a GIMPLE_ASSIGN, may create certain equivalences, in either
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1495 the available expressions table or the const_and_copies table.
111
kono
parents: 67
diff changeset
1496 Detect and record those equivalences into AVAIL_EXPRS_STACK.
kono
parents: 67
diff changeset
1497
kono
parents: 67
diff changeset
1498 We handle only very simple copy equivalences here. The heavy
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1499 lifing is done by eliminate_redundant_computations. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1500
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1501 static void
111
kono
parents: 67
diff changeset
1502 record_equivalences_from_stmt (gimple *stmt, int may_optimize_p,
kono
parents: 67
diff changeset
1503 class avail_exprs_stack *avail_exprs_stack)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1504 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1505 tree lhs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1506 enum tree_code lhs_code;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1507
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1508 gcc_assert (is_gimple_assign (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1509
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1510 lhs = gimple_assign_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1511 lhs_code = TREE_CODE (lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1512
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1513 if (lhs_code == SSA_NAME
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1514 && gimple_assign_single_p (stmt))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1515 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1516 tree rhs = gimple_assign_rhs1 (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1517
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1518 /* If the RHS of the assignment is a constant or another variable that
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1519 may be propagated, register it in the CONST_AND_COPIES table. We
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1520 do not need to record unwind data for this, since this is a true
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1521 assignment and not an equivalence inferred from a comparison. All
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1522 uses of this ssa name are dominated by this assignment, so unwinding
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1523 just costs time and space. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1524 if (may_optimize_p
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1525 && (TREE_CODE (rhs) == SSA_NAME
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1526 || is_gimple_min_invariant (rhs)))
111
kono
parents: 67
diff changeset
1527 {
kono
parents: 67
diff changeset
1528 rhs = dom_valueize (rhs);
kono
parents: 67
diff changeset
1529
kono
parents: 67
diff changeset
1530 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
1531 {
kono
parents: 67
diff changeset
1532 fprintf (dump_file, "==== ASGN ");
kono
parents: 67
diff changeset
1533 print_generic_expr (dump_file, lhs);
kono
parents: 67
diff changeset
1534 fprintf (dump_file, " = ");
kono
parents: 67
diff changeset
1535 print_generic_expr (dump_file, rhs);
kono
parents: 67
diff changeset
1536 fprintf (dump_file, "\n");
kono
parents: 67
diff changeset
1537 }
kono
parents: 67
diff changeset
1538
kono
parents: 67
diff changeset
1539 set_ssa_name_value (lhs, rhs);
kono
parents: 67
diff changeset
1540 }
kono
parents: 67
diff changeset
1541 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1542
111
kono
parents: 67
diff changeset
1543 /* Make sure we can propagate &x + CST. */
kono
parents: 67
diff changeset
1544 if (lhs_code == SSA_NAME
kono
parents: 67
diff changeset
1545 && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
kono
parents: 67
diff changeset
1546 && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR
kono
parents: 67
diff changeset
1547 && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST)
kono
parents: 67
diff changeset
1548 {
kono
parents: 67
diff changeset
1549 tree op0 = gimple_assign_rhs1 (stmt);
kono
parents: 67
diff changeset
1550 tree op1 = gimple_assign_rhs2 (stmt);
kono
parents: 67
diff changeset
1551 tree new_rhs
kono
parents: 67
diff changeset
1552 = build_fold_addr_expr (fold_build2 (MEM_REF,
kono
parents: 67
diff changeset
1553 TREE_TYPE (TREE_TYPE (op0)),
kono
parents: 67
diff changeset
1554 unshare_expr (op0),
kono
parents: 67
diff changeset
1555 fold_convert (ptr_type_node,
kono
parents: 67
diff changeset
1556 op1)));
kono
parents: 67
diff changeset
1557 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
1558 {
kono
parents: 67
diff changeset
1559 fprintf (dump_file, "==== ASGN ");
kono
parents: 67
diff changeset
1560 print_generic_expr (dump_file, lhs);
kono
parents: 67
diff changeset
1561 fprintf (dump_file, " = ");
kono
parents: 67
diff changeset
1562 print_generic_expr (dump_file, new_rhs);
kono
parents: 67
diff changeset
1563 fprintf (dump_file, "\n");
kono
parents: 67
diff changeset
1564 }
kono
parents: 67
diff changeset
1565
kono
parents: 67
diff changeset
1566 set_ssa_name_value (lhs, new_rhs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1567 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1568
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1569 /* A memory store, even an aliased store, creates a useful
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1570 equivalence. By exchanging the LHS and RHS, creating suitable
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1571 vops and recording the result in the available expression table,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1572 we may be able to expose more redundant loads. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1573 if (!gimple_has_volatile_ops (stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1574 && gimple_references_memory_p (stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1575 && gimple_assign_single_p (stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1576 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1577 || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1578 && !is_gimple_reg (lhs))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1579 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1580 tree rhs = gimple_assign_rhs1 (stmt);
111
kono
parents: 67
diff changeset
1581 gassign *new_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1582
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1583 /* Build a new statement with the RHS and LHS exchanged. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1584 if (TREE_CODE (rhs) == SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1585 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1586 /* NOTE tuples. The call to gimple_build_assign below replaced
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1587 a call to build_gimple_modify_stmt, which did not set the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1588 SSA_NAME_DEF_STMT on the LHS of the assignment. Doing so
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1589 may cause an SSA validation failure, as the LHS may be a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1590 default-initialized name and should have no definition. I'm
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1591 a bit dubious of this, as the artificial statement that we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1592 generate here may in fact be ill-formed, but it is simply
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1593 used as an internal device in this pass, and never becomes
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1594 part of the CFG. */
111
kono
parents: 67
diff changeset
1595 gimple *defstmt = SSA_NAME_DEF_STMT (rhs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1596 new_stmt = gimple_build_assign (rhs, lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1597 SSA_NAME_DEF_STMT (rhs) = defstmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1598 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1599 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1600 new_stmt = gimple_build_assign (rhs, lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1601
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1602 gimple_set_vuse (new_stmt, gimple_vdef (stmt));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1603
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1604 /* Finally enter the statement into the available expression
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1605 table. */
111
kono
parents: 67
diff changeset
1606 avail_exprs_stack->lookup_avail_expr (new_stmt, true, true);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1607 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1608 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1609
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1610 /* Replace *OP_P in STMT with any known equivalent value for *OP_P from
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1611 CONST_AND_COPIES. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1612
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1613 static void
111
kono
parents: 67
diff changeset
1614 cprop_operand (gimple *stmt, use_operand_p op_p)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1615 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1616 tree val;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1617 tree op = USE_FROM_PTR (op_p);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1618
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1619 /* If the operand has a known constant value or it is known to be a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1620 copy of some other variable, use the value or copy stored in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1621 CONST_AND_COPIES. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1622 val = SSA_NAME_VALUE (op);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1623 if (val && val != op)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1624 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1625 /* Do not replace hard register operands in asm statements. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1626 if (gimple_code (stmt) == GIMPLE_ASM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1627 && !may_propagate_copy_into_asm (op))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1628 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1629
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1630 /* Certain operands are not allowed to be copy propagated due
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1631 to their interaction with exception handling and some GCC
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1632 extensions. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1633 if (!may_propagate_copy (op, val))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1634 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1635
111
kono
parents: 67
diff changeset
1636 /* Do not propagate copies into BIVs.
kono
parents: 67
diff changeset
1637 See PR23821 and PR62217 for how this can disturb IV and
kono
parents: 67
diff changeset
1638 number of iteration analysis. */
kono
parents: 67
diff changeset
1639 if (TREE_CODE (val) != INTEGER_CST)
kono
parents: 67
diff changeset
1640 {
kono
parents: 67
diff changeset
1641 gimple *def = SSA_NAME_DEF_STMT (op);
kono
parents: 67
diff changeset
1642 if (gimple_code (def) == GIMPLE_PHI
kono
parents: 67
diff changeset
1643 && gimple_bb (def)->loop_father->header == gimple_bb (def))
kono
parents: 67
diff changeset
1644 return;
kono
parents: 67
diff changeset
1645 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1646
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1647 /* Dump details. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1648 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1649 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1650 fprintf (dump_file, " Replaced '");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1651 print_generic_expr (dump_file, op, dump_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1652 fprintf (dump_file, "' with %s '",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1653 (TREE_CODE (val) != SSA_NAME ? "constant" : "variable"));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1654 print_generic_expr (dump_file, val, dump_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1655 fprintf (dump_file, "'\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1656 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1657
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1658 if (TREE_CODE (val) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1659 opt_stats.num_const_prop++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1660 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1661 opt_stats.num_copy_prop++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1662
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1663 propagate_value (op_p, val);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1664
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1665 /* And note that we modified this statement. This is now
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1666 safe, even if we changed virtual operands since we will
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1667 rescan the statement and rewrite its operands again. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1668 gimple_set_modified (stmt, true);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1669 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1670 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1671
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1672 /* CONST_AND_COPIES is a table which maps an SSA_NAME to the current
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1673 known value for that SSA_NAME (or NULL if no value is known).
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1674
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1675 Propagate values from CONST_AND_COPIES into the uses, vuses and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1676 vdef_ops of STMT. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1677
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1678 static void
111
kono
parents: 67
diff changeset
1679 cprop_into_stmt (gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1680 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1681 use_operand_p op_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1682 ssa_op_iter iter;
111
kono
parents: 67
diff changeset
1683 tree last_copy_propagated_op = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1684
111
kono
parents: 67
diff changeset
1685 FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_USE)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1686 {
111
kono
parents: 67
diff changeset
1687 tree old_op = USE_FROM_PTR (op_p);
kono
parents: 67
diff changeset
1688
kono
parents: 67
diff changeset
1689 /* If we have A = B and B = A in the copy propagation tables
kono
parents: 67
diff changeset
1690 (due to an equality comparison), avoid substituting B for A
kono
parents: 67
diff changeset
1691 then A for B in the trivially discovered cases. This allows
kono
parents: 67
diff changeset
1692 optimization of statements were A and B appear as input
kono
parents: 67
diff changeset
1693 operands. */
kono
parents: 67
diff changeset
1694 if (old_op != last_copy_propagated_op)
kono
parents: 67
diff changeset
1695 {
kono
parents: 67
diff changeset
1696 cprop_operand (stmt, op_p);
kono
parents: 67
diff changeset
1697
kono
parents: 67
diff changeset
1698 tree new_op = USE_FROM_PTR (op_p);
kono
parents: 67
diff changeset
1699 if (new_op != old_op && TREE_CODE (new_op) == SSA_NAME)
kono
parents: 67
diff changeset
1700 last_copy_propagated_op = new_op;
kono
parents: 67
diff changeset
1701 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1702 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1703 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1704
111
kono
parents: 67
diff changeset
1705 /* If STMT contains a relational test, try to convert it into an
kono
parents: 67
diff changeset
1706 equality test if there is only a single value which can ever
kono
parents: 67
diff changeset
1707 make the test true.
kono
parents: 67
diff changeset
1708
kono
parents: 67
diff changeset
1709 For example, if the expression hash table contains:
kono
parents: 67
diff changeset
1710
kono
parents: 67
diff changeset
1711 TRUE = (i <= 1)
kono
parents: 67
diff changeset
1712
kono
parents: 67
diff changeset
1713 And we have a test within statement of i >= 1, then we can safely
kono
parents: 67
diff changeset
1714 rewrite the test as i == 1 since there only a single value where
kono
parents: 67
diff changeset
1715 the test is true.
kono
parents: 67
diff changeset
1716
kono
parents: 67
diff changeset
1717 This is similar to code in VRP. */
kono
parents: 67
diff changeset
1718
kono
parents: 67
diff changeset
1719 static void
kono
parents: 67
diff changeset
1720 test_for_singularity (gimple *stmt, gcond *dummy_cond,
kono
parents: 67
diff changeset
1721 avail_exprs_stack *avail_exprs_stack)
kono
parents: 67
diff changeset
1722 {
kono
parents: 67
diff changeset
1723 /* We want to support gimple conditionals as well as assignments
kono
parents: 67
diff changeset
1724 where the RHS contains a conditional. */
kono
parents: 67
diff changeset
1725 if (is_gimple_assign (stmt) || gimple_code (stmt) == GIMPLE_COND)
kono
parents: 67
diff changeset
1726 {
kono
parents: 67
diff changeset
1727 enum tree_code code = ERROR_MARK;
kono
parents: 67
diff changeset
1728 tree lhs, rhs;
kono
parents: 67
diff changeset
1729
kono
parents: 67
diff changeset
1730 /* Extract the condition of interest from both forms we support. */
kono
parents: 67
diff changeset
1731 if (is_gimple_assign (stmt))
kono
parents: 67
diff changeset
1732 {
kono
parents: 67
diff changeset
1733 code = gimple_assign_rhs_code (stmt);
kono
parents: 67
diff changeset
1734 lhs = gimple_assign_rhs1 (stmt);
kono
parents: 67
diff changeset
1735 rhs = gimple_assign_rhs2 (stmt);
kono
parents: 67
diff changeset
1736 }
kono
parents: 67
diff changeset
1737 else if (gimple_code (stmt) == GIMPLE_COND)
kono
parents: 67
diff changeset
1738 {
kono
parents: 67
diff changeset
1739 code = gimple_cond_code (as_a <gcond *> (stmt));
kono
parents: 67
diff changeset
1740 lhs = gimple_cond_lhs (as_a <gcond *> (stmt));
kono
parents: 67
diff changeset
1741 rhs = gimple_cond_rhs (as_a <gcond *> (stmt));
kono
parents: 67
diff changeset
1742 }
kono
parents: 67
diff changeset
1743
kono
parents: 67
diff changeset
1744 /* We're looking for a relational test using LE/GE. Also note we can
kono
parents: 67
diff changeset
1745 canonicalize LT/GT tests against constants into LE/GT tests. */
kono
parents: 67
diff changeset
1746 if (code == LE_EXPR || code == GE_EXPR
kono
parents: 67
diff changeset
1747 || ((code == LT_EXPR || code == GT_EXPR)
kono
parents: 67
diff changeset
1748 && TREE_CODE (rhs) == INTEGER_CST))
kono
parents: 67
diff changeset
1749 {
kono
parents: 67
diff changeset
1750 /* For LT_EXPR and GT_EXPR, canonicalize to LE_EXPR and GE_EXPR. */
kono
parents: 67
diff changeset
1751 if (code == LT_EXPR)
kono
parents: 67
diff changeset
1752 rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (rhs),
kono
parents: 67
diff changeset
1753 rhs, build_int_cst (TREE_TYPE (rhs), 1));
kono
parents: 67
diff changeset
1754
kono
parents: 67
diff changeset
1755 if (code == GT_EXPR)
kono
parents: 67
diff changeset
1756 rhs = fold_build2 (PLUS_EXPR, TREE_TYPE (rhs),
kono
parents: 67
diff changeset
1757 rhs, build_int_cst (TREE_TYPE (rhs), 1));
kono
parents: 67
diff changeset
1758
kono
parents: 67
diff changeset
1759 /* Determine the code we want to check for in the hash table. */
kono
parents: 67
diff changeset
1760 enum tree_code test_code;
kono
parents: 67
diff changeset
1761 if (code == GE_EXPR || code == GT_EXPR)
kono
parents: 67
diff changeset
1762 test_code = LE_EXPR;
kono
parents: 67
diff changeset
1763 else
kono
parents: 67
diff changeset
1764 test_code = GE_EXPR;
kono
parents: 67
diff changeset
1765
kono
parents: 67
diff changeset
1766 /* Update the dummy statement so we can query the hash tables. */
kono
parents: 67
diff changeset
1767 gimple_cond_set_code (dummy_cond, test_code);
kono
parents: 67
diff changeset
1768 gimple_cond_set_lhs (dummy_cond, lhs);
kono
parents: 67
diff changeset
1769 gimple_cond_set_rhs (dummy_cond, rhs);
kono
parents: 67
diff changeset
1770 tree cached_lhs
kono
parents: 67
diff changeset
1771 = avail_exprs_stack->lookup_avail_expr (dummy_cond, false, false);
kono
parents: 67
diff changeset
1772
kono
parents: 67
diff changeset
1773 /* If the lookup returned 1 (true), then the expression we
kono
parents: 67
diff changeset
1774 queried was in the hash table. As a result there is only
kono
parents: 67
diff changeset
1775 one value that makes the original conditional true. Update
kono
parents: 67
diff changeset
1776 STMT accordingly. */
kono
parents: 67
diff changeset
1777 if (cached_lhs && integer_onep (cached_lhs))
kono
parents: 67
diff changeset
1778 {
kono
parents: 67
diff changeset
1779 if (is_gimple_assign (stmt))
kono
parents: 67
diff changeset
1780 {
kono
parents: 67
diff changeset
1781 gimple_assign_set_rhs_code (stmt, EQ_EXPR);
kono
parents: 67
diff changeset
1782 gimple_assign_set_rhs2 (stmt, rhs);
kono
parents: 67
diff changeset
1783 gimple_set_modified (stmt, true);
kono
parents: 67
diff changeset
1784 }
kono
parents: 67
diff changeset
1785 else
kono
parents: 67
diff changeset
1786 {
kono
parents: 67
diff changeset
1787 gimple_set_modified (stmt, true);
kono
parents: 67
diff changeset
1788 gimple_cond_set_code (as_a <gcond *> (stmt), EQ_EXPR);
kono
parents: 67
diff changeset
1789 gimple_cond_set_rhs (as_a <gcond *> (stmt), rhs);
kono
parents: 67
diff changeset
1790 gimple_set_modified (stmt, true);
kono
parents: 67
diff changeset
1791 }
kono
parents: 67
diff changeset
1792 }
kono
parents: 67
diff changeset
1793 }
kono
parents: 67
diff changeset
1794 }
kono
parents: 67
diff changeset
1795 }
kono
parents: 67
diff changeset
1796
kono
parents: 67
diff changeset
1797 /* Optimize the statement in block BB pointed to by iterator SI.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1798
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1799 We try to perform some simplistic global redundancy elimination and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1800 constant propagation:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1801
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1802 1- To detect global redundancy, we keep track of expressions that have
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1803 been computed in this block and its dominators. If we find that the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1804 same expression is computed more than once, we eliminate repeated
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1805 computations by using the target of the first one.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1806
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1807 2- Constant values and copy assignments. This is used to do very
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1808 simplistic constant and copy propagation. When a constant or copy
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1809 assignment is found, we map the value on the RHS of the assignment to
111
kono
parents: 67
diff changeset
1810 the variable in the LHS in the CONST_AND_COPIES table.
kono
parents: 67
diff changeset
1811
kono
parents: 67
diff changeset
1812 3- Very simple redundant store elimination is performed.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1813
111
kono
parents: 67
diff changeset
1814 4- We can simpify a condition to a constant or from a relational
kono
parents: 67
diff changeset
1815 condition to an equality condition. */
kono
parents: 67
diff changeset
1816
kono
parents: 67
diff changeset
1817 edge
kono
parents: 67
diff changeset
1818 dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator si)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1819 {
111
kono
parents: 67
diff changeset
1820 gimple *stmt, *old_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1821 bool may_optimize_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1822 bool modified_p = false;
111
kono
parents: 67
diff changeset
1823 bool was_noreturn;
kono
parents: 67
diff changeset
1824 edge retval = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1825
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1826 old_stmt = stmt = gsi_stmt (si);
111
kono
parents: 67
diff changeset
1827 was_noreturn = is_gimple_call (stmt) && gimple_call_noreturn_p (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1828
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1829 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1830 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1831 fprintf (dump_file, "Optimizing statement ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1832 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1833 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1834
111
kono
parents: 67
diff changeset
1835 update_stmt_if_modified (stmt);
kono
parents: 67
diff changeset
1836 opt_stats.num_stmts++;
kono
parents: 67
diff changeset
1837
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1838 /* Const/copy propagate into USES, VUSES and the RHS of VDEFs. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1839 cprop_into_stmt (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1840
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1841 /* If the statement has been modified with constant replacements,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1842 fold its RHS before checking for redundant computations. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1843 if (gimple_modified_p (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1844 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1845 tree rhs = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1846
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1847 /* Try to fold the statement making sure that STMT is kept
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1848 up to date. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1849 if (fold_stmt (&si))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1850 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1851 stmt = gsi_stmt (si);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1852 gimple_set_modified (stmt, true);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1853
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1854 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1855 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1856 fprintf (dump_file, " Folded to: ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1857 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1858 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1859 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1860
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1861 /* We only need to consider cases that can yield a gimple operand. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1862 if (gimple_assign_single_p (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1863 rhs = gimple_assign_rhs1 (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1864 else if (gimple_code (stmt) == GIMPLE_GOTO)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1865 rhs = gimple_goto_dest (stmt);
111
kono
parents: 67
diff changeset
1866 else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1867 /* This should never be an ADDR_EXPR. */
111
kono
parents: 67
diff changeset
1868 rhs = gimple_switch_index (swtch_stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1869
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1870 if (rhs && TREE_CODE (rhs) == ADDR_EXPR)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1871 recompute_tree_invariant_for_addr_expr (rhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1872
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1873 /* Indicate that maybe_clean_or_replace_eh_stmt needs to be called,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1874 even if fold_stmt updated the stmt already and thus cleared
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1875 gimple_modified_p flag on it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1876 modified_p = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1877 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1878
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1879 /* Check for redundant computations. Do this optimization only
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1880 for assignments that have no volatile ops and conditionals. */
111
kono
parents: 67
diff changeset
1881 may_optimize_p = (!gimple_has_side_effects (stmt)
kono
parents: 67
diff changeset
1882 && (is_gimple_assign (stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1883 || (is_gimple_call (stmt)
111
kono
parents: 67
diff changeset
1884 && gimple_call_lhs (stmt) != NULL_TREE)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1885 || gimple_code (stmt) == GIMPLE_COND
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1886 || gimple_code (stmt) == GIMPLE_SWITCH));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1887
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1888 if (may_optimize_p)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1889 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1890 if (gimple_code (stmt) == GIMPLE_CALL)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1891 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1892 /* Resolve __builtin_constant_p. If it hasn't been
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1893 folded to integer_one_node by now, it's fairly
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1894 certain that the value simply isn't constant. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1895 tree callee = gimple_call_fndecl (stmt);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1896 if (callee
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1897 && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1898 && DECL_FUNCTION_CODE (callee) == BUILT_IN_CONSTANT_P)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1899 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1900 propagate_tree_value_into_stmt (&si, integer_zero_node);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1901 stmt = gsi_stmt (si);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1902 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1903 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1904
111
kono
parents: 67
diff changeset
1905 if (gimple_code (stmt) == GIMPLE_COND)
kono
parents: 67
diff changeset
1906 {
kono
parents: 67
diff changeset
1907 tree lhs = gimple_cond_lhs (stmt);
kono
parents: 67
diff changeset
1908 tree rhs = gimple_cond_rhs (stmt);
kono
parents: 67
diff changeset
1909
kono
parents: 67
diff changeset
1910 /* If the LHS has a range [0..1] and the RHS has a range ~[0..1],
kono
parents: 67
diff changeset
1911 then this conditional is computable at compile time. We can just
kono
parents: 67
diff changeset
1912 shove either 0 or 1 into the LHS, mark the statement as modified
kono
parents: 67
diff changeset
1913 and all the right things will just happen below.
kono
parents: 67
diff changeset
1914
kono
parents: 67
diff changeset
1915 Note this would apply to any case where LHS has a range
kono
parents: 67
diff changeset
1916 narrower than its type implies and RHS is outside that
kono
parents: 67
diff changeset
1917 narrower range. Future work. */
kono
parents: 67
diff changeset
1918 if (TREE_CODE (lhs) == SSA_NAME
kono
parents: 67
diff changeset
1919 && ssa_name_has_boolean_range (lhs)
kono
parents: 67
diff changeset
1920 && TREE_CODE (rhs) == INTEGER_CST
kono
parents: 67
diff changeset
1921 && ! (integer_zerop (rhs) || integer_onep (rhs)))
kono
parents: 67
diff changeset
1922 {
kono
parents: 67
diff changeset
1923 gimple_cond_set_lhs (as_a <gcond *> (stmt),
kono
parents: 67
diff changeset
1924 fold_convert (TREE_TYPE (lhs),
kono
parents: 67
diff changeset
1925 integer_zero_node));
kono
parents: 67
diff changeset
1926 gimple_set_modified (stmt, true);
kono
parents: 67
diff changeset
1927 }
kono
parents: 67
diff changeset
1928 }
kono
parents: 67
diff changeset
1929
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1930 update_stmt_if_modified (stmt);
111
kono
parents: 67
diff changeset
1931 eliminate_redundant_computations (&si, m_const_and_copies,
kono
parents: 67
diff changeset
1932 m_avail_exprs_stack);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1933 stmt = gsi_stmt (si);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1934
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1935 /* Perform simple redundant store elimination. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1936 if (gimple_assign_single_p (stmt)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1937 && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1938 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1939 tree lhs = gimple_assign_lhs (stmt);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1940 tree rhs = gimple_assign_rhs1 (stmt);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1941 tree cached_lhs;
111
kono
parents: 67
diff changeset
1942 gassign *new_stmt;
kono
parents: 67
diff changeset
1943 rhs = dom_valueize (rhs);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1944 /* Build a new statement with the RHS and LHS exchanged. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1945 if (TREE_CODE (rhs) == SSA_NAME)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1946 {
111
kono
parents: 67
diff changeset
1947 gimple *defstmt = SSA_NAME_DEF_STMT (rhs);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1948 new_stmt = gimple_build_assign (rhs, lhs);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1949 SSA_NAME_DEF_STMT (rhs) = defstmt;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1950 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1951 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1952 new_stmt = gimple_build_assign (rhs, lhs);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1953 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
111
kono
parents: 67
diff changeset
1954 cached_lhs = m_avail_exprs_stack->lookup_avail_expr (new_stmt, false,
kono
parents: 67
diff changeset
1955 false);
kono
parents: 67
diff changeset
1956 if (cached_lhs && operand_equal_p (rhs, cached_lhs, 0))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1957 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1958 basic_block bb = gimple_bb (stmt);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1959 unlink_stmt_vdef (stmt);
111
kono
parents: 67
diff changeset
1960 if (gsi_remove (&si, true))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1961 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1962 bitmap_set_bit (need_eh_cleanup, bb->index);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1963 if (dump_file && (dump_flags & TDF_DETAILS))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1964 fprintf (dump_file, " Flagged to clear EH edges.\n");
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1965 }
111
kono
parents: 67
diff changeset
1966 release_defs (stmt);
kono
parents: 67
diff changeset
1967 return retval;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1968 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1969 }
111
kono
parents: 67
diff changeset
1970
kono
parents: 67
diff changeset
1971 /* If this statement was not redundant, we may still be able to simplify
kono
parents: 67
diff changeset
1972 it, which may in turn allow other part of DOM or other passes to do
kono
parents: 67
diff changeset
1973 a better job. */
kono
parents: 67
diff changeset
1974 test_for_singularity (stmt, m_dummy_cond, m_avail_exprs_stack);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1975 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1976
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1977 /* Record any additional equivalences created by this statement. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1978 if (is_gimple_assign (stmt))
111
kono
parents: 67
diff changeset
1979 record_equivalences_from_stmt (stmt, may_optimize_p, m_avail_exprs_stack);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1980
111
kono
parents: 67
diff changeset
1981 /* If STMT is a COND_EXPR or SWITCH_EXPR and it was modified, then we may
kono
parents: 67
diff changeset
1982 know where it goes. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1983 if (gimple_modified_p (stmt) || modified_p)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1984 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1985 tree val = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1986
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1987 if (gimple_code (stmt) == GIMPLE_COND)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1988 val = fold_binary_loc (gimple_location (stmt),
111
kono
parents: 67
diff changeset
1989 gimple_cond_code (stmt), boolean_type_node,
kono
parents: 67
diff changeset
1990 gimple_cond_lhs (stmt),
kono
parents: 67
diff changeset
1991 gimple_cond_rhs (stmt));
kono
parents: 67
diff changeset
1992 else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
kono
parents: 67
diff changeset
1993 val = gimple_switch_index (swtch_stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1994
111
kono
parents: 67
diff changeset
1995 if (val && TREE_CODE (val) == INTEGER_CST)
kono
parents: 67
diff changeset
1996 {
kono
parents: 67
diff changeset
1997 retval = find_taken_edge (bb, val);
kono
parents: 67
diff changeset
1998 if (retval)
kono
parents: 67
diff changeset
1999 {
kono
parents: 67
diff changeset
2000 /* Fix the condition to be either true or false. */
kono
parents: 67
diff changeset
2001 if (gimple_code (stmt) == GIMPLE_COND)
kono
parents: 67
diff changeset
2002 {
kono
parents: 67
diff changeset
2003 if (integer_zerop (val))
kono
parents: 67
diff changeset
2004 gimple_cond_make_false (as_a <gcond *> (stmt));
kono
parents: 67
diff changeset
2005 else if (integer_onep (val))
kono
parents: 67
diff changeset
2006 gimple_cond_make_true (as_a <gcond *> (stmt));
kono
parents: 67
diff changeset
2007 else
kono
parents: 67
diff changeset
2008 gcc_unreachable ();
kono
parents: 67
diff changeset
2009
kono
parents: 67
diff changeset
2010 gimple_set_modified (stmt, true);
kono
parents: 67
diff changeset
2011 }
kono
parents: 67
diff changeset
2012
kono
parents: 67
diff changeset
2013 /* Further simplifications may be possible. */
kono
parents: 67
diff changeset
2014 cfg_altered = true;
kono
parents: 67
diff changeset
2015 }
kono
parents: 67
diff changeset
2016 }
kono
parents: 67
diff changeset
2017
kono
parents: 67
diff changeset
2018 update_stmt_if_modified (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2019
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2020 /* If we simplified a statement in such a way as to be shown that it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2021 cannot trap, update the eh information and the cfg to match. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2022 if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2023 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2024 bitmap_set_bit (need_eh_cleanup, bb->index);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2025 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2026 fprintf (dump_file, " Flagged to clear EH edges.\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2027 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2028
111
kono
parents: 67
diff changeset
2029 if (!was_noreturn
kono
parents: 67
diff changeset
2030 && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
kono
parents: 67
diff changeset
2031 need_noreturn_fixup.safe_push (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2032 }
111
kono
parents: 67
diff changeset
2033 return retval;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2034 }