annotate gcc/tree-ssa-dom.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
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
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2001-2020 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"
kono
parents: 67
diff changeset
42 #include "tree-ssa-scopedtables.h"
kono
parents: 67
diff changeset
43 #include "tree-ssa-threadedge.h"
kono
parents: 67
diff changeset
44 #include "tree-ssa-dom.h"
kono
parents: 67
diff changeset
45 #include "gimplify.h"
kono
parents: 67
diff changeset
46 #include "tree-cfgcleanup.h"
kono
parents: 67
diff changeset
47 #include "dbgcnt.h"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
48 #include "alloc-pool.h"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
49 #include "tree-vrp.h"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
50 #include "vr-values.h"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
51 #include "gimple-ssa-evrp-analyze.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 /* This file implements optimizations on the dominator tree. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54
111
kono
parents: 67
diff changeset
55 /* Structure for recording edge equivalences.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 Computing and storing the edge equivalences instead of creating
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 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
59 for pathological cases involving switch statements.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 These structures live for a single iteration of the dominator
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 optimizer in the edge's AUX field. At the end of an iteration we
111
kono
parents: 67
diff changeset
63 free each of these structures. */
kono
parents: 67
diff changeset
64 class edge_info
kono
parents: 67
diff changeset
65 {
kono
parents: 67
diff changeset
66 public:
kono
parents: 67
diff changeset
67 typedef std::pair <tree, tree> equiv_pair;
kono
parents: 67
diff changeset
68 edge_info (edge);
kono
parents: 67
diff changeset
69 ~edge_info ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70
111
kono
parents: 67
diff changeset
71 /* Record a simple LHS = RHS equivalence. This may trigger
kono
parents: 67
diff changeset
72 calls to derive_equivalences. */
kono
parents: 67
diff changeset
73 void record_simple_equiv (tree, tree);
kono
parents: 67
diff changeset
74
kono
parents: 67
diff changeset
75 /* If traversing this edge creates simple equivalences, we store
kono
parents: 67
diff changeset
76 them as LHS/RHS pairs within this vector. */
kono
parents: 67
diff changeset
77 vec<equiv_pair> simple_equivalences;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 /* 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
80 are true or false. */
111
kono
parents: 67
diff changeset
81 vec<cond_equivalence> cond_equivalences;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82
111
kono
parents: 67
diff changeset
83 private:
kono
parents: 67
diff changeset
84 /* Derive equivalences by walking the use-def chains. */
kono
parents: 67
diff changeset
85 void derive_equivalences (tree, tree, int);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 };
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 /* 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
89 static bool cfg_altered;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 /* 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
92 remove their dead edges eventually. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 static bitmap need_eh_cleanup;
111
kono
parents: 67
diff changeset
94 static vec<gimple *> need_noreturn_fixup;
0
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 /* Statistics for dominator optimizations. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 struct opt_stats_d
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 long num_stmts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 long num_exprs_considered;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 long num_re;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 long num_const_prop;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 long num_copy_prop;
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 static struct opt_stats_d opt_stats;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 /* Local functions. */
111
kono
parents: 67
diff changeset
109 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
110 static void record_equivalences_from_phis (basic_block);
111
kono
parents: 67
diff changeset
111 static void record_equivalences_from_incoming_edge (basic_block,
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 eliminate_redundant_computations (gimple_stmt_iterator *,
kono
parents: 67
diff changeset
115 class const_and_copies *,
kono
parents: 67
diff changeset
116 class avail_exprs_stack *);
kono
parents: 67
diff changeset
117 static void record_equivalences_from_stmt (gimple *, int,
kono
parents: 67
diff changeset
118 class avail_exprs_stack *);
kono
parents: 67
diff changeset
119 static void dump_dominator_optimization_stats (FILE *file,
kono
parents: 67
diff changeset
120 hash_table<expr_elt_hasher> *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121
111
kono
parents: 67
diff changeset
122 /* Constructor for EDGE_INFO. An EDGE_INFO instance is always
kono
parents: 67
diff changeset
123 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
124
111
kono
parents: 67
diff changeset
125 edge_info::edge_info (edge e)
kono
parents: 67
diff changeset
126 {
kono
parents: 67
diff changeset
127 /* Free the old one associated with E, if it exists and
kono
parents: 67
diff changeset
128 associate our new object with E. */
kono
parents: 67
diff changeset
129 free_dom_edge_info (e);
kono
parents: 67
diff changeset
130 e->aux = this;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131
111
kono
parents: 67
diff changeset
132 /* And initialize the embedded vectors. */
kono
parents: 67
diff changeset
133 simple_equivalences = vNULL;
kono
parents: 67
diff changeset
134 cond_equivalences = vNULL;
kono
parents: 67
diff changeset
135 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136
111
kono
parents: 67
diff changeset
137 /* Destructor just needs to release the vectors. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138
111
kono
parents: 67
diff changeset
139 edge_info::~edge_info (void)
kono
parents: 67
diff changeset
140 {
kono
parents: 67
diff changeset
141 this->cond_equivalences.release ();
kono
parents: 67
diff changeset
142 this->simple_equivalences.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144
111
kono
parents: 67
diff changeset
145 /* 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
146
111
kono
parents: 67
diff changeset
147 Walk through its use-def chain to see if there are other equivalences
kono
parents: 67
diff changeset
148 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
149
111
kono
parents: 67
diff changeset
150 RECURSION_LIMIT controls how far back we recurse through the use-def
kono
parents: 67
diff changeset
151 chains. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152
111
kono
parents: 67
diff changeset
153 void
kono
parents: 67
diff changeset
154 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
155 {
111
kono
parents: 67
diff changeset
156 if (TREE_CODE (name) != SSA_NAME || TREE_CODE (value) != INTEGER_CST)
kono
parents: 67
diff changeset
157 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158
111
kono
parents: 67
diff changeset
159 /* This records the equivalence for the toplevel object. Do
kono
parents: 67
diff changeset
160 this before checking the recursion limit. */
kono
parents: 67
diff changeset
161 simple_equivalences.safe_push (equiv_pair (name, value));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
162
111
kono
parents: 67
diff changeset
163 /* Limit how far up the use-def chains we are willing to walk. */
kono
parents: 67
diff changeset
164 if (recursion_limit == 0)
kono
parents: 67
diff changeset
165 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
166
111
kono
parents: 67
diff changeset
167 /* We can walk up the use-def chains to potentially find more
kono
parents: 67
diff changeset
168 equivalences. */
kono
parents: 67
diff changeset
169 gimple *def_stmt = SSA_NAME_DEF_STMT (name);
kono
parents: 67
diff changeset
170 if (is_gimple_assign (def_stmt))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 {
111
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 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
175 /* If the result of an OR is zero, then its operands are, too. */
111
kono
parents: 67
diff changeset
176 case BIT_IOR_EXPR:
kono
parents: 67
diff changeset
177 if (integer_zerop (value))
kono
parents: 67
diff changeset
178 {
kono
parents: 67
diff changeset
179 tree rhs1 = gimple_assign_rhs1 (def_stmt);
kono
parents: 67
diff changeset
180 tree rhs2 = gimple_assign_rhs2 (def_stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181
111
kono
parents: 67
diff changeset
182 value = build_zero_cst (TREE_TYPE (rhs1));
kono
parents: 67
diff changeset
183 derive_equivalences (rhs1, value, recursion_limit - 1);
kono
parents: 67
diff changeset
184 value = build_zero_cst (TREE_TYPE (rhs2));
kono
parents: 67
diff changeset
185 derive_equivalences (rhs2, value, recursion_limit - 1);
kono
parents: 67
diff changeset
186 }
kono
parents: 67
diff changeset
187 break;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
189 /* If the result of an AND is nonzero, then its operands are, too. */
111
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 case EQ_EXPR:
kono
parents: 67
diff changeset
297 case NE_EXPR:
kono
parents: 67
diff changeset
298 {
kono
parents: 67
diff changeset
299 if ((code == EQ_EXPR && integer_onep (value))
kono
parents: 67
diff changeset
300 || (code == NE_EXPR && integer_zerop (value)))
kono
parents: 67
diff changeset
301 {
kono
parents: 67
diff changeset
302 tree rhs1 = gimple_assign_rhs1 (def_stmt);
kono
parents: 67
diff changeset
303 tree rhs2 = gimple_assign_rhs2 (def_stmt);
kono
parents: 67
diff changeset
304
kono
parents: 67
diff changeset
305 /* If either argument is a constant, then record the
kono
parents: 67
diff changeset
306 other argument as being the same as that constant.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307
111
kono
parents: 67
diff changeset
308 If neither operand is a constant, then we have a
kono
parents: 67
diff changeset
309 conditional name == name equivalence. */
kono
parents: 67
diff changeset
310 if (TREE_CODE (rhs1) == INTEGER_CST)
kono
parents: 67
diff changeset
311 derive_equivalences (rhs2, rhs1, recursion_limit - 1);
kono
parents: 67
diff changeset
312 else if (TREE_CODE (rhs2) == INTEGER_CST)
kono
parents: 67
diff changeset
313 derive_equivalences (rhs1, rhs2, recursion_limit - 1);
kono
parents: 67
diff changeset
314 }
kono
parents: 67
diff changeset
315 else
kono
parents: 67
diff changeset
316 {
kono
parents: 67
diff changeset
317 tree cond = build2 (code, boolean_type_node,
kono
parents: 67
diff changeset
318 gimple_assign_rhs1 (def_stmt),
kono
parents: 67
diff changeset
319 gimple_assign_rhs2 (def_stmt));
kono
parents: 67
diff changeset
320 tree inverted = invert_truthvalue (cond);
kono
parents: 67
diff changeset
321 if (integer_zerop (value))
kono
parents: 67
diff changeset
322 std::swap (cond, inverted);
kono
parents: 67
diff changeset
323 record_conditions (&this->cond_equivalences, cond, inverted);
kono
parents: 67
diff changeset
324 }
kono
parents: 67
diff changeset
325 break;
kono
parents: 67
diff changeset
326 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
327
111
kono
parents: 67
diff changeset
328 /* For BIT_NOT and NEGATE, we can just apply the operation to the
kono
parents: 67
diff changeset
329 VALUE to get the new equivalence. It will always be a constant
kono
parents: 67
diff changeset
330 so we can recurse. */
kono
parents: 67
diff changeset
331 case BIT_NOT_EXPR:
kono
parents: 67
diff changeset
332 case NEGATE_EXPR:
kono
parents: 67
diff changeset
333 {
kono
parents: 67
diff changeset
334 tree rhs = gimple_assign_rhs1 (def_stmt);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
335 tree res;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
336 /* If this is a NOT and the operand has a boolean range, then we
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
337 know its value must be zero or one. We are not supposed to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
338 have a BIT_NOT_EXPR for boolean types with precision > 1 in
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
339 the general case, see e.g. the handling of TRUTH_NOT_EXPR in
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
340 the gimplifier, but it can be generated by match.pd out of
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
341 a BIT_XOR_EXPR wrapped in a BIT_AND_EXPR. Now the handling
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
342 of BIT_AND_EXPR above already forces a specific semantics for
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
343 boolean types with precision > 1 so we must do the same here,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
344 otherwise we could change the semantics of TRUTH_NOT_EXPR for
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
345 boolean types with precision > 1. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
346 if (code == BIT_NOT_EXPR
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
347 && TREE_CODE (rhs) == SSA_NAME
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
348 && ssa_name_has_boolean_range (rhs))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
349 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
350 if ((TREE_INT_CST_LOW (value) & 1) == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
351 res = build_one_cst (TREE_TYPE (rhs));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
352 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
353 res = build_zero_cst (TREE_TYPE (rhs));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
354 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
355 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
356 res = fold_build1 (code, TREE_TYPE (rhs), value);
111
kono
parents: 67
diff changeset
357 derive_equivalences (rhs, res, recursion_limit - 1);
kono
parents: 67
diff changeset
358 break;
kono
parents: 67
diff changeset
359 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
360
111
kono
parents: 67
diff changeset
361 default:
kono
parents: 67
diff changeset
362 {
kono
parents: 67
diff changeset
363 if (TREE_CODE_CLASS (code) == tcc_comparison)
kono
parents: 67
diff changeset
364 {
kono
parents: 67
diff changeset
365 tree cond = build2 (code, boolean_type_node,
kono
parents: 67
diff changeset
366 gimple_assign_rhs1 (def_stmt),
kono
parents: 67
diff changeset
367 gimple_assign_rhs2 (def_stmt));
kono
parents: 67
diff changeset
368 tree inverted = invert_truthvalue (cond);
kono
parents: 67
diff changeset
369 if (integer_zerop (value))
kono
parents: 67
diff changeset
370 std::swap (cond, inverted);
kono
parents: 67
diff changeset
371 record_conditions (&this->cond_equivalences, cond, inverted);
kono
parents: 67
diff changeset
372 break;
kono
parents: 67
diff changeset
373 }
kono
parents: 67
diff changeset
374 break;
kono
parents: 67
diff changeset
375 }
kono
parents: 67
diff changeset
376 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
377 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
378 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
379
111
kono
parents: 67
diff changeset
380 void
kono
parents: 67
diff changeset
381 edge_info::record_simple_equiv (tree lhs, tree rhs)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
382 {
111
kono
parents: 67
diff changeset
383 /* If the RHS is a constant, then we may be able to derive
kono
parents: 67
diff changeset
384 further equivalences. Else just record the name = name
kono
parents: 67
diff changeset
385 equivalence. */
kono
parents: 67
diff changeset
386 if (TREE_CODE (rhs) == INTEGER_CST)
kono
parents: 67
diff changeset
387 derive_equivalences (lhs, rhs, 4);
kono
parents: 67
diff changeset
388 else
kono
parents: 67
diff changeset
389 simple_equivalences.safe_push (equiv_pair (lhs, rhs));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
390 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
391
111
kono
parents: 67
diff changeset
392 /* 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
393
111
kono
parents: 67
diff changeset
394 void
kono
parents: 67
diff changeset
395 free_dom_edge_info (edge e)
kono
parents: 67
diff changeset
396 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
397 class edge_info *edge_info = (class edge_info *)e->aux;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
398
111
kono
parents: 67
diff changeset
399 if (edge_info)
kono
parents: 67
diff changeset
400 delete edge_info;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
401 }
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 /* 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
404 If a particular edge can be threaded, copy the redirection
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
405 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
406 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
407 jump threading. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
408
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
410 free_all_edge_infos (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
411 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
412 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
413 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
414 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
415
111
kono
parents: 67
diff changeset
416 FOR_EACH_BB_FN (bb, cfun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
417 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
418 FOR_EACH_EDGE (e, ei, bb->preds)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
419 {
111
kono
parents: 67
diff changeset
420 free_dom_edge_info (e);
kono
parents: 67
diff changeset
421 e->aux = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
423 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
424 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
425
111
kono
parents: 67
diff changeset
426 /* We have finished optimizing BB, record any information implied by
kono
parents: 67
diff changeset
427 taking a specific outgoing edge from BB. */
kono
parents: 67
diff changeset
428
kono
parents: 67
diff changeset
429 static void
kono
parents: 67
diff changeset
430 record_edge_info (basic_block bb)
kono
parents: 67
diff changeset
431 {
kono
parents: 67
diff changeset
432 gimple_stmt_iterator gsi = gsi_last_bb (bb);
kono
parents: 67
diff changeset
433 class edge_info *edge_info;
kono
parents: 67
diff changeset
434
kono
parents: 67
diff changeset
435 if (! gsi_end_p (gsi))
kono
parents: 67
diff changeset
436 {
kono
parents: 67
diff changeset
437 gimple *stmt = gsi_stmt (gsi);
kono
parents: 67
diff changeset
438 location_t loc = gimple_location (stmt);
kono
parents: 67
diff changeset
439
kono
parents: 67
diff changeset
440 if (gimple_code (stmt) == GIMPLE_SWITCH)
kono
parents: 67
diff changeset
441 {
kono
parents: 67
diff changeset
442 gswitch *switch_stmt = as_a <gswitch *> (stmt);
kono
parents: 67
diff changeset
443 tree index = gimple_switch_index (switch_stmt);
kono
parents: 67
diff changeset
444
kono
parents: 67
diff changeset
445 if (TREE_CODE (index) == SSA_NAME)
kono
parents: 67
diff changeset
446 {
kono
parents: 67
diff changeset
447 int i;
kono
parents: 67
diff changeset
448 int n_labels = gimple_switch_num_labels (switch_stmt);
kono
parents: 67
diff changeset
449 tree *info = XCNEWVEC (tree, last_basic_block_for_fn (cfun));
kono
parents: 67
diff changeset
450 edge e;
kono
parents: 67
diff changeset
451 edge_iterator ei;
kono
parents: 67
diff changeset
452
kono
parents: 67
diff changeset
453 for (i = 0; i < n_labels; i++)
kono
parents: 67
diff changeset
454 {
kono
parents: 67
diff changeset
455 tree label = gimple_switch_label (switch_stmt, i);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
456 basic_block target_bb
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
457 = label_to_block (cfun, CASE_LABEL (label));
111
kono
parents: 67
diff changeset
458 if (CASE_HIGH (label)
kono
parents: 67
diff changeset
459 || !CASE_LOW (label)
kono
parents: 67
diff changeset
460 || info[target_bb->index])
kono
parents: 67
diff changeset
461 info[target_bb->index] = error_mark_node;
kono
parents: 67
diff changeset
462 else
kono
parents: 67
diff changeset
463 info[target_bb->index] = label;
kono
parents: 67
diff changeset
464 }
kono
parents: 67
diff changeset
465
kono
parents: 67
diff changeset
466 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
467 {
kono
parents: 67
diff changeset
468 basic_block target_bb = e->dest;
kono
parents: 67
diff changeset
469 tree label = info[target_bb->index];
kono
parents: 67
diff changeset
470
kono
parents: 67
diff changeset
471 if (label != NULL && label != error_mark_node)
kono
parents: 67
diff changeset
472 {
kono
parents: 67
diff changeset
473 tree x = fold_convert_loc (loc, TREE_TYPE (index),
kono
parents: 67
diff changeset
474 CASE_LOW (label));
kono
parents: 67
diff changeset
475 edge_info = new class edge_info (e);
kono
parents: 67
diff changeset
476 edge_info->record_simple_equiv (index, x);
kono
parents: 67
diff changeset
477 }
kono
parents: 67
diff changeset
478 }
kono
parents: 67
diff changeset
479 free (info);
kono
parents: 67
diff changeset
480 }
kono
parents: 67
diff changeset
481 }
kono
parents: 67
diff changeset
482
kono
parents: 67
diff changeset
483 /* A COND_EXPR may create equivalences too. */
kono
parents: 67
diff changeset
484 if (gimple_code (stmt) == GIMPLE_COND)
kono
parents: 67
diff changeset
485 {
kono
parents: 67
diff changeset
486 edge true_edge;
kono
parents: 67
diff changeset
487 edge false_edge;
kono
parents: 67
diff changeset
488
kono
parents: 67
diff changeset
489 tree op0 = gimple_cond_lhs (stmt);
kono
parents: 67
diff changeset
490 tree op1 = gimple_cond_rhs (stmt);
kono
parents: 67
diff changeset
491 enum tree_code code = gimple_cond_code (stmt);
kono
parents: 67
diff changeset
492
kono
parents: 67
diff changeset
493 extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
kono
parents: 67
diff changeset
494
kono
parents: 67
diff changeset
495 /* Special case comparing booleans against a constant as we
kono
parents: 67
diff changeset
496 know the value of OP0 on both arms of the branch. i.e., we
kono
parents: 67
diff changeset
497 can record an equivalence for OP0 rather than COND.
kono
parents: 67
diff changeset
498
kono
parents: 67
diff changeset
499 However, don't do this if the constant isn't zero or one.
kono
parents: 67
diff changeset
500 Such conditionals will get optimized more thoroughly during
kono
parents: 67
diff changeset
501 the domwalk. */
kono
parents: 67
diff changeset
502 if ((code == EQ_EXPR || code == NE_EXPR)
kono
parents: 67
diff changeset
503 && TREE_CODE (op0) == SSA_NAME
kono
parents: 67
diff changeset
504 && ssa_name_has_boolean_range (op0)
kono
parents: 67
diff changeset
505 && is_gimple_min_invariant (op1)
kono
parents: 67
diff changeset
506 && (integer_zerop (op1) || integer_onep (op1)))
kono
parents: 67
diff changeset
507 {
kono
parents: 67
diff changeset
508 tree true_val = constant_boolean_node (true, TREE_TYPE (op0));
kono
parents: 67
diff changeset
509 tree false_val = constant_boolean_node (false, TREE_TYPE (op0));
kono
parents: 67
diff changeset
510
kono
parents: 67
diff changeset
511 if (code == EQ_EXPR)
kono
parents: 67
diff changeset
512 {
kono
parents: 67
diff changeset
513 edge_info = new class edge_info (true_edge);
kono
parents: 67
diff changeset
514 edge_info->record_simple_equiv (op0,
kono
parents: 67
diff changeset
515 (integer_zerop (op1)
kono
parents: 67
diff changeset
516 ? false_val : true_val));
kono
parents: 67
diff changeset
517 edge_info = new class edge_info (false_edge);
kono
parents: 67
diff changeset
518 edge_info->record_simple_equiv (op0,
kono
parents: 67
diff changeset
519 (integer_zerop (op1)
kono
parents: 67
diff changeset
520 ? true_val : false_val));
kono
parents: 67
diff changeset
521 }
kono
parents: 67
diff changeset
522 else
kono
parents: 67
diff changeset
523 {
kono
parents: 67
diff changeset
524 edge_info = new class edge_info (true_edge);
kono
parents: 67
diff changeset
525 edge_info->record_simple_equiv (op0,
kono
parents: 67
diff changeset
526 (integer_zerop (op1)
kono
parents: 67
diff changeset
527 ? true_val : false_val));
kono
parents: 67
diff changeset
528 edge_info = new class edge_info (false_edge);
kono
parents: 67
diff changeset
529 edge_info->record_simple_equiv (op0,
kono
parents: 67
diff changeset
530 (integer_zerop (op1)
kono
parents: 67
diff changeset
531 ? false_val : true_val));
kono
parents: 67
diff changeset
532 }
kono
parents: 67
diff changeset
533 }
kono
parents: 67
diff changeset
534 /* This can show up in the IL as a result of copy propagation
kono
parents: 67
diff changeset
535 it will eventually be canonicalized, but we have to cope
kono
parents: 67
diff changeset
536 with this case within the pass. */
kono
parents: 67
diff changeset
537 else if (is_gimple_min_invariant (op0)
kono
parents: 67
diff changeset
538 && TREE_CODE (op1) == SSA_NAME)
kono
parents: 67
diff changeset
539 {
kono
parents: 67
diff changeset
540 tree cond = build2 (code, boolean_type_node, op0, op1);
kono
parents: 67
diff changeset
541 tree inverted = invert_truthvalue_loc (loc, cond);
kono
parents: 67
diff changeset
542 bool can_infer_simple_equiv
kono
parents: 67
diff changeset
543 = !(HONOR_SIGNED_ZEROS (op0)
kono
parents: 67
diff changeset
544 && real_zerop (op0));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
545 class edge_info *edge_info;
111
kono
parents: 67
diff changeset
546
kono
parents: 67
diff changeset
547 edge_info = new class edge_info (true_edge);
kono
parents: 67
diff changeset
548 record_conditions (&edge_info->cond_equivalences, cond, inverted);
kono
parents: 67
diff changeset
549
kono
parents: 67
diff changeset
550 if (can_infer_simple_equiv && code == EQ_EXPR)
kono
parents: 67
diff changeset
551 edge_info->record_simple_equiv (op1, op0);
kono
parents: 67
diff changeset
552
kono
parents: 67
diff changeset
553 edge_info = new class edge_info (false_edge);
kono
parents: 67
diff changeset
554 record_conditions (&edge_info->cond_equivalences, inverted, cond);
kono
parents: 67
diff changeset
555
kono
parents: 67
diff changeset
556 if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR)
kono
parents: 67
diff changeset
557 edge_info->record_simple_equiv (op1, op0);
kono
parents: 67
diff changeset
558 }
kono
parents: 67
diff changeset
559
kono
parents: 67
diff changeset
560 else if (TREE_CODE (op0) == SSA_NAME
kono
parents: 67
diff changeset
561 && (TREE_CODE (op1) == SSA_NAME
kono
parents: 67
diff changeset
562 || is_gimple_min_invariant (op1)))
kono
parents: 67
diff changeset
563 {
kono
parents: 67
diff changeset
564 tree cond = build2 (code, boolean_type_node, op0, op1);
kono
parents: 67
diff changeset
565 tree inverted = invert_truthvalue_loc (loc, cond);
kono
parents: 67
diff changeset
566 bool can_infer_simple_equiv
kono
parents: 67
diff changeset
567 = !(HONOR_SIGNED_ZEROS (op1)
kono
parents: 67
diff changeset
568 && (TREE_CODE (op1) == SSA_NAME || real_zerop (op1)));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
569 class edge_info *edge_info;
111
kono
parents: 67
diff changeset
570
kono
parents: 67
diff changeset
571 edge_info = new class edge_info (true_edge);
kono
parents: 67
diff changeset
572 record_conditions (&edge_info->cond_equivalences, cond, inverted);
kono
parents: 67
diff changeset
573
kono
parents: 67
diff changeset
574 if (can_infer_simple_equiv && code == EQ_EXPR)
kono
parents: 67
diff changeset
575 edge_info->record_simple_equiv (op0, op1);
kono
parents: 67
diff changeset
576
kono
parents: 67
diff changeset
577 edge_info = new class edge_info (false_edge);
kono
parents: 67
diff changeset
578 record_conditions (&edge_info->cond_equivalences, inverted, cond);
kono
parents: 67
diff changeset
579
kono
parents: 67
diff changeset
580 if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR)
kono
parents: 67
diff changeset
581 edge_info->record_simple_equiv (op0, op1);
kono
parents: 67
diff changeset
582 }
kono
parents: 67
diff changeset
583 }
kono
parents: 67
diff changeset
584 }
kono
parents: 67
diff changeset
585 }
kono
parents: 67
diff changeset
586
kono
parents: 67
diff changeset
587
kono
parents: 67
diff changeset
588 class dom_opt_dom_walker : public dom_walker
kono
parents: 67
diff changeset
589 {
kono
parents: 67
diff changeset
590 public:
kono
parents: 67
diff changeset
591 dom_opt_dom_walker (cdi_direction direction,
kono
parents: 67
diff changeset
592 class const_and_copies *const_and_copies,
kono
parents: 67
diff changeset
593 class avail_exprs_stack *avail_exprs_stack,
kono
parents: 67
diff changeset
594 gcond *dummy_cond)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
595 : dom_walker (direction, REACHABLE_BLOCKS),
111
kono
parents: 67
diff changeset
596 m_const_and_copies (const_and_copies),
kono
parents: 67
diff changeset
597 m_avail_exprs_stack (avail_exprs_stack),
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
598 evrp_range_analyzer (true),
111
kono
parents: 67
diff changeset
599 m_dummy_cond (dummy_cond) { }
kono
parents: 67
diff changeset
600
kono
parents: 67
diff changeset
601 virtual edge before_dom_children (basic_block);
kono
parents: 67
diff changeset
602 virtual void after_dom_children (basic_block);
kono
parents: 67
diff changeset
603
kono
parents: 67
diff changeset
604 private:
kono
parents: 67
diff changeset
605
kono
parents: 67
diff changeset
606 /* Unwindable equivalences, both const/copy and expression varieties. */
kono
parents: 67
diff changeset
607 class const_and_copies *m_const_and_copies;
kono
parents: 67
diff changeset
608 class avail_exprs_stack *m_avail_exprs_stack;
kono
parents: 67
diff changeset
609
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
610 /* VRP data. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
611 class evrp_range_analyzer evrp_range_analyzer;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
612
111
kono
parents: 67
diff changeset
613 /* Dummy condition to avoid creating lots of throw away statements. */
kono
parents: 67
diff changeset
614 gcond *m_dummy_cond;
kono
parents: 67
diff changeset
615
kono
parents: 67
diff changeset
616 /* Optimize a single statement within a basic block using the
kono
parents: 67
diff changeset
617 various tables mantained by DOM. Returns the taken edge if
kono
parents: 67
diff changeset
618 the statement is a conditional with a statically determined
kono
parents: 67
diff changeset
619 value. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
620 edge optimize_stmt (basic_block, gimple_stmt_iterator *, bool *);
111
kono
parents: 67
diff changeset
621 };
kono
parents: 67
diff changeset
622
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
623 /* Jump threading, redundancy elimination and const/copy propagation.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
624
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
625 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
626 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
627 VARS_TO_RENAME. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
628
111
kono
parents: 67
diff changeset
629 namespace {
kono
parents: 67
diff changeset
630
kono
parents: 67
diff changeset
631 const pass_data pass_data_dominator =
kono
parents: 67
diff changeset
632 {
kono
parents: 67
diff changeset
633 GIMPLE_PASS, /* type */
kono
parents: 67
diff changeset
634 "dom", /* name */
kono
parents: 67
diff changeset
635 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
636 TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */
kono
parents: 67
diff changeset
637 ( PROP_cfg | PROP_ssa ), /* properties_required */
kono
parents: 67
diff changeset
638 0, /* properties_provided */
kono
parents: 67
diff changeset
639 0, /* properties_destroyed */
kono
parents: 67
diff changeset
640 0, /* todo_flags_start */
kono
parents: 67
diff changeset
641 ( TODO_cleanup_cfg | TODO_update_ssa ), /* todo_flags_finish */
kono
parents: 67
diff changeset
642 };
kono
parents: 67
diff changeset
643
kono
parents: 67
diff changeset
644 class pass_dominator : public gimple_opt_pass
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
645 {
111
kono
parents: 67
diff changeset
646 public:
kono
parents: 67
diff changeset
647 pass_dominator (gcc::context *ctxt)
kono
parents: 67
diff changeset
648 : gimple_opt_pass (pass_data_dominator, ctxt),
kono
parents: 67
diff changeset
649 may_peel_loop_headers_p (false)
kono
parents: 67
diff changeset
650 {}
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
651
111
kono
parents: 67
diff changeset
652 /* opt_pass methods: */
kono
parents: 67
diff changeset
653 opt_pass * clone () { return new pass_dominator (m_ctxt); }
kono
parents: 67
diff changeset
654 void set_pass_param (unsigned int n, bool param)
kono
parents: 67
diff changeset
655 {
kono
parents: 67
diff changeset
656 gcc_assert (n == 0);
kono
parents: 67
diff changeset
657 may_peel_loop_headers_p = param;
kono
parents: 67
diff changeset
658 }
kono
parents: 67
diff changeset
659 virtual bool gate (function *) { return flag_tree_dom != 0; }
kono
parents: 67
diff changeset
660 virtual unsigned int execute (function *);
kono
parents: 67
diff changeset
661
kono
parents: 67
diff changeset
662 private:
kono
parents: 67
diff changeset
663 /* This flag is used to prevent loops from being peeled repeatedly in jump
kono
parents: 67
diff changeset
664 threading; it will be removed once we preserve loop structures throughout
kono
parents: 67
diff changeset
665 the compilation -- we will be able to mark the affected loops directly in
kono
parents: 67
diff changeset
666 jump threading, and avoid peeling them next time. */
kono
parents: 67
diff changeset
667 bool may_peel_loop_headers_p;
kono
parents: 67
diff changeset
668 }; // class pass_dominator
kono
parents: 67
diff changeset
669
kono
parents: 67
diff changeset
670 unsigned int
kono
parents: 67
diff changeset
671 pass_dominator::execute (function *fun)
kono
parents: 67
diff changeset
672 {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
673 memset (&opt_stats, 0, sizeof (opt_stats));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
674
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
675 /* Create our hash tables. */
111
kono
parents: 67
diff changeset
676 hash_table<expr_elt_hasher> *avail_exprs
kono
parents: 67
diff changeset
677 = new hash_table<expr_elt_hasher> (1024);
kono
parents: 67
diff changeset
678 class avail_exprs_stack *avail_exprs_stack
kono
parents: 67
diff changeset
679 = new class avail_exprs_stack (avail_exprs);
kono
parents: 67
diff changeset
680 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
681 need_eh_cleanup = BITMAP_ALLOC (NULL);
111
kono
parents: 67
diff changeset
682 need_noreturn_fixup.create (0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
683
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
684 calculate_dominance_info (CDI_DOMINATORS);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
685 cfg_altered = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
686
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
687 /* 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
688 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
689 headers to an exit edge, or through loop header to the loop body, assuming
111
kono
parents: 67
diff changeset
690 that we update the loop info.
kono
parents: 67
diff changeset
691
kono
parents: 67
diff changeset
692 TODO: We don't need to set LOOPS_HAVE_PREHEADERS generally, but due
kono
parents: 67
diff changeset
693 to several overly conservative bail-outs in jump threading, case
kono
parents: 67
diff changeset
694 gcc.dg/tree-ssa/pr21417.c can't be threaded if loop preheader is
kono
parents: 67
diff changeset
695 missing. We should improve jump threading in future then
kono
parents: 67
diff changeset
696 LOOPS_HAVE_PREHEADERS won't be needed here. */
kono
parents: 67
diff changeset
697 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
698
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
699 /* 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
700 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
701
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
702 /* We need accurate information regarding back edges in the CFG
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
703 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
704 a single loop. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
705 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
706
111
kono
parents: 67
diff changeset
707 /* We want to create the edge info structures before the dominator walk
kono
parents: 67
diff changeset
708 so that they'll be in place for the jump threader, particularly when
kono
parents: 67
diff changeset
709 threading through a join block.
kono
parents: 67
diff changeset
710
kono
parents: 67
diff changeset
711 The conditions will be lazily updated with global equivalences as
kono
parents: 67
diff changeset
712 we reach them during the dominator walk. */
kono
parents: 67
diff changeset
713 basic_block bb;
kono
parents: 67
diff changeset
714 FOR_EACH_BB_FN (bb, fun)
kono
parents: 67
diff changeset
715 record_edge_info (bb);
kono
parents: 67
diff changeset
716
kono
parents: 67
diff changeset
717 gcond *dummy_cond = gimple_build_cond (NE_EXPR, integer_zero_node,
kono
parents: 67
diff changeset
718 integer_zero_node, NULL, NULL);
kono
parents: 67
diff changeset
719
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
720 /* Recursively walk the dominator tree optimizing statements. */
111
kono
parents: 67
diff changeset
721 dom_opt_dom_walker walker (CDI_DOMINATORS, const_and_copies,
kono
parents: 67
diff changeset
722 avail_exprs_stack, dummy_cond);
kono
parents: 67
diff changeset
723 walker.walk (fun->cfg->x_entry_block_ptr);
kono
parents: 67
diff changeset
724
kono
parents: 67
diff changeset
725 /* Look for blocks where we cleared EDGE_EXECUTABLE on an outgoing
kono
parents: 67
diff changeset
726 edge. When found, remove jump threads which contain any outgoing
kono
parents: 67
diff changeset
727 edge from the affected block. */
kono
parents: 67
diff changeset
728 if (cfg_altered)
kono
parents: 67
diff changeset
729 {
kono
parents: 67
diff changeset
730 FOR_EACH_BB_FN (bb, fun)
kono
parents: 67
diff changeset
731 {
kono
parents: 67
diff changeset
732 edge_iterator ei;
kono
parents: 67
diff changeset
733 edge e;
kono
parents: 67
diff changeset
734
kono
parents: 67
diff changeset
735 /* First see if there are any edges without EDGE_EXECUTABLE
kono
parents: 67
diff changeset
736 set. */
kono
parents: 67
diff changeset
737 bool found = false;
kono
parents: 67
diff changeset
738 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
739 {
kono
parents: 67
diff changeset
740 if ((e->flags & EDGE_EXECUTABLE) == 0)
kono
parents: 67
diff changeset
741 {
kono
parents: 67
diff changeset
742 found = true;
kono
parents: 67
diff changeset
743 break;
kono
parents: 67
diff changeset
744 }
kono
parents: 67
diff changeset
745 }
kono
parents: 67
diff changeset
746
kono
parents: 67
diff changeset
747 /* If there were any such edges found, then remove jump threads
kono
parents: 67
diff changeset
748 containing any edge leaving BB. */
kono
parents: 67
diff changeset
749 if (found)
kono
parents: 67
diff changeset
750 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
751 remove_jump_threads_including (e);
kono
parents: 67
diff changeset
752 }
kono
parents: 67
diff changeset
753 }
0
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 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
756 gimple_stmt_iterator gsi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
757 basic_block bb;
111
kono
parents: 67
diff changeset
758 FOR_EACH_BB_FN (bb, fun)
kono
parents: 67
diff changeset
759 {
kono
parents: 67
diff changeset
760 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
761 update_stmt_if_modified (gsi_stmt (gsi));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
762 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
763 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
764
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
765 /* 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
766 SSA form now, before we handle jump threading. This simplifies
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
767 interactions between rewriting of _DECL nodes into SSA form
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
768 and rewriting SSA_NAME nodes into SSA form after block
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
769 duplication and CFG manipulation. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
770 update_ssa (TODO_update_ssa);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
771
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
772 free_all_edge_infos ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
773
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
774 /* Thread jumps, creating duplicate blocks as needed. */
111
kono
parents: 67
diff changeset
775 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
776
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
777 if (cfg_altered)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
778 free_dominance_info (CDI_DOMINATORS);
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 /* Removal of statements may make some EH edges dead. Purge
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
781 such edges from the CFG as needed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
782 if (!bitmap_empty_p (need_eh_cleanup))
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 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
785 bitmap_iterator bi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
786
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
787 /* Jump threading may have created forwarder blocks from blocks
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
788 needing EH cleanup; the new successor of these blocks, which
111
kono
parents: 67
diff changeset
789 has inherited from the original block, needs the cleanup.
kono
parents: 67
diff changeset
790 Don't clear bits in the bitmap, as that can break the bitmap
kono
parents: 67
diff changeset
791 iterator. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
792 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
793 {
111
kono
parents: 67
diff changeset
794 basic_block bb = BASIC_BLOCK_FOR_FN (fun, i);
kono
parents: 67
diff changeset
795 if (bb == NULL)
kono
parents: 67
diff changeset
796 continue;
kono
parents: 67
diff changeset
797 while (single_succ_p (bb)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
798 && (single_succ_edge (bb)->flags
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
799 & (EDGE_EH|EDGE_DFS_BACK)) == 0)
111
kono
parents: 67
diff changeset
800 bb = single_succ (bb);
kono
parents: 67
diff changeset
801 if (bb == EXIT_BLOCK_PTR_FOR_FN (fun))
kono
parents: 67
diff changeset
802 continue;
kono
parents: 67
diff changeset
803 if ((unsigned) bb->index != i)
kono
parents: 67
diff changeset
804 bitmap_set_bit (need_eh_cleanup, bb->index);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
805 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
806
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
807 gimple_purge_all_dead_eh_edges (need_eh_cleanup);
111
kono
parents: 67
diff changeset
808 bitmap_clear (need_eh_cleanup);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
809 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
810
111
kono
parents: 67
diff changeset
811 /* Fixup stmts that became noreturn calls. This may require splitting
kono
parents: 67
diff changeset
812 blocks and thus isn't possible during the dominator walk or before
kono
parents: 67
diff changeset
813 jump threading finished. Do this in reverse order so we don't
kono
parents: 67
diff changeset
814 inadvertedly remove a stmt we want to fixup by visiting a dominating
kono
parents: 67
diff changeset
815 now noreturn call first. */
kono
parents: 67
diff changeset
816 while (!need_noreturn_fixup.is_empty ())
kono
parents: 67
diff changeset
817 {
kono
parents: 67
diff changeset
818 gimple *stmt = need_noreturn_fixup.pop ();
kono
parents: 67
diff changeset
819 if (dump_file && dump_flags & TDF_DETAILS)
kono
parents: 67
diff changeset
820 {
kono
parents: 67
diff changeset
821 fprintf (dump_file, "Fixing up noreturn call ");
kono
parents: 67
diff changeset
822 print_gimple_stmt (dump_file, stmt, 0);
kono
parents: 67
diff changeset
823 fprintf (dump_file, "\n");
kono
parents: 67
diff changeset
824 }
kono
parents: 67
diff changeset
825 fixup_noreturn_call (stmt);
kono
parents: 67
diff changeset
826 }
kono
parents: 67
diff changeset
827
kono
parents: 67
diff changeset
828 statistics_counter_event (fun, "Redundant expressions eliminated",
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
829 opt_stats.num_re);
111
kono
parents: 67
diff changeset
830 statistics_counter_event (fun, "Constants propagated",
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
831 opt_stats.num_const_prop);
111
kono
parents: 67
diff changeset
832 statistics_counter_event (fun, "Copies propagated",
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
833 opt_stats.num_copy_prop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
834
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
835 /* Debugging dumps. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
836 if (dump_file && (dump_flags & TDF_STATS))
111
kono
parents: 67
diff changeset
837 dump_dominator_optimization_stats (dump_file, avail_exprs);
0
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 loop_optimizer_finalize ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
840
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
841 /* Delete our main hashtable. */
111
kono
parents: 67
diff changeset
842 delete avail_exprs;
kono
parents: 67
diff changeset
843 avail_exprs = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
844
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
845 /* Free asserted bitmaps and stacks. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
846 BITMAP_FREE (need_eh_cleanup);
111
kono
parents: 67
diff changeset
847 need_noreturn_fixup.release ();
kono
parents: 67
diff changeset
848 delete avail_exprs_stack;
kono
parents: 67
diff changeset
849 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
850
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
851 /* 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
852 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
853
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
854 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
855 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
856
111
kono
parents: 67
diff changeset
857 } // anon namespace
kono
parents: 67
diff changeset
858
kono
parents: 67
diff changeset
859 gimple_opt_pass *
kono
parents: 67
diff changeset
860 make_pass_dominator (gcc::context *ctxt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
861 {
111
kono
parents: 67
diff changeset
862 return new pass_dominator (ctxt);
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
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
865 /* A hack until we remove threading from tree-vrp.c and bring the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
866 simplification routine into the dom_opt_dom_walker class. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
867 static class vr_values *x_vr_values;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
868
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
869 /* 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
870 threading code with a simple API for simplifying statements. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
871 static tree
111
kono
parents: 67
diff changeset
872 simplify_stmt_for_jump_threading (gimple *stmt,
kono
parents: 67
diff changeset
873 gimple *within_stmt ATTRIBUTE_UNUSED,
kono
parents: 67
diff changeset
874 class avail_exprs_stack *avail_exprs_stack,
kono
parents: 67
diff changeset
875 basic_block bb ATTRIBUTE_UNUSED)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
876 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
877 /* First query our hash table to see if the the expression is available
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
878 there. A non-NULL return value will be either a constant or another
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
879 SSA_NAME. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
880 tree cached_lhs = avail_exprs_stack->lookup_avail_expr (stmt, false, true);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
881 if (cached_lhs)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
882 return cached_lhs;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
883
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
884 /* If the hash table query failed, query VRP information. This is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
885 essentially the same as tree-vrp's simplification routine. The
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
886 copy in tree-vrp is scheduled for removal in gcc-9. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
887 if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
888 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
889 cached_lhs
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
890 = x_vr_values->vrp_evaluate_conditional (gimple_cond_code (cond_stmt),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
891 gimple_cond_lhs (cond_stmt),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
892 gimple_cond_rhs (cond_stmt),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
893 within_stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
894 return cached_lhs;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
895 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
896
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
897 if (gswitch *switch_stmt = dyn_cast <gswitch *> (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
898 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
899 tree op = gimple_switch_index (switch_stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
900 if (TREE_CODE (op) != SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
901 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
902
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
903 const value_range_equiv *vr = x_vr_values->get_value_range (op);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
904 if (vr->undefined_p ()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
905 || vr->varying_p ()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
906 || vr->symbolic_p ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
907 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
908
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
909 if (vr->kind () == VR_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
910 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
911 size_t i, j;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
912
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
913 find_case_label_range (switch_stmt, vr->min (), vr->max (), &i, &j);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
914
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
915 /* Is there only one such label? */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
916 if (i == j)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
917 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
918 tree label = gimple_switch_label (switch_stmt, i);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
919 tree singleton;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
920
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
921 /* The i'th label will only be taken if the value range of the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
922 operand is entirely within the bounds of this label. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
923 if (CASE_HIGH (label) != NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
924 ? (tree_int_cst_compare (CASE_LOW (label), vr->min ()) <= 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
925 && tree_int_cst_compare (CASE_HIGH (label), vr->max ()) >= 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
926 : (vr->singleton_p (&singleton)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
927 && tree_int_cst_equal (CASE_LOW (label), singleton)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
928 return label;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
929 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
930
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
931 /* If there are no such labels, then the default label
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
932 will be taken. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
933 if (i > j)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
934 return gimple_switch_label (switch_stmt, 0);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
935 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
936
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
937 if (vr->kind () == VR_ANTI_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
938 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
939 unsigned n = gimple_switch_num_labels (switch_stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
940 tree min_label = gimple_switch_label (switch_stmt, 1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
941 tree max_label = gimple_switch_label (switch_stmt, n - 1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
942
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
943 /* The default label will be taken only if the anti-range of the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
944 operand is entirely outside the bounds of all the (non-default)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
945 case labels. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
946 if (tree_int_cst_compare (vr->min (), CASE_LOW (min_label)) <= 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
947 && (CASE_HIGH (max_label) != NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
948 ? tree_int_cst_compare (vr->max (), CASE_HIGH (max_label)) >= 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
949 : tree_int_cst_compare (vr->max (), CASE_LOW (max_label)) >= 0))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
950 return gimple_switch_label (switch_stmt, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
951 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
952 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
953 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
954
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
955 if (gassign *assign_stmt = dyn_cast <gassign *> (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
956 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
957 tree lhs = gimple_assign_lhs (assign_stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
958 if (TREE_CODE (lhs) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
959 && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
960 || POINTER_TYPE_P (TREE_TYPE (lhs)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
961 && stmt_interesting_for_vrp (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
962 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
963 edge dummy_e;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
964 tree dummy_tree;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
965 value_range_equiv new_vr;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
966 x_vr_values->extract_range_from_stmt (stmt, &dummy_e,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
967 &dummy_tree, &new_vr);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
968 tree singleton;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
969 if (new_vr.singleton_p (&singleton))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
970 return singleton;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
971 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
972 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
973 return NULL;
111
kono
parents: 67
diff changeset
974 }
kono
parents: 67
diff changeset
975
kono
parents: 67
diff changeset
976 /* Valueize hook for gimple_fold_stmt_to_constant_1. */
kono
parents: 67
diff changeset
977
kono
parents: 67
diff changeset
978 static tree
kono
parents: 67
diff changeset
979 dom_valueize (tree t)
kono
parents: 67
diff changeset
980 {
kono
parents: 67
diff changeset
981 if (TREE_CODE (t) == SSA_NAME)
kono
parents: 67
diff changeset
982 {
kono
parents: 67
diff changeset
983 tree tem = SSA_NAME_VALUE (t);
kono
parents: 67
diff changeset
984 if (tem)
kono
parents: 67
diff changeset
985 return tem;
kono
parents: 67
diff changeset
986 }
kono
parents: 67
diff changeset
987 return t;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
988 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
989
111
kono
parents: 67
diff changeset
990 /* We have just found an equivalence for LHS on an edge E.
kono
parents: 67
diff changeset
991 Look backwards to other uses of LHS and see if we can derive
kono
parents: 67
diff changeset
992 additional equivalences that are valid on edge E. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
993 static void
111
kono
parents: 67
diff changeset
994 back_propagate_equivalences (tree lhs, edge e,
kono
parents: 67
diff changeset
995 class const_and_copies *const_and_copies)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
996 {
111
kono
parents: 67
diff changeset
997 use_operand_p use_p;
kono
parents: 67
diff changeset
998 imm_use_iterator iter;
kono
parents: 67
diff changeset
999 bitmap domby = NULL;
kono
parents: 67
diff changeset
1000 basic_block dest = e->dest;
kono
parents: 67
diff changeset
1001
kono
parents: 67
diff changeset
1002 /* Iterate over the uses of LHS to see if any dominate E->dest.
kono
parents: 67
diff changeset
1003 If so, they may create useful equivalences too.
kono
parents: 67
diff changeset
1004
kono
parents: 67
diff changeset
1005 ??? If the code gets re-organized to a worklist to catch more
kono
parents: 67
diff changeset
1006 indirect opportunities and it is made to handle PHIs then this
kono
parents: 67
diff changeset
1007 should only consider use_stmts in basic-blocks we have already visited. */
kono
parents: 67
diff changeset
1008 FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
kono
parents: 67
diff changeset
1009 {
kono
parents: 67
diff changeset
1010 gimple *use_stmt = USE_STMT (use_p);
kono
parents: 67
diff changeset
1011
kono
parents: 67
diff changeset
1012 /* Often the use is in DEST, which we trivially know we can't use.
kono
parents: 67
diff changeset
1013 This is cheaper than the dominator set tests below. */
kono
parents: 67
diff changeset
1014 if (dest == gimple_bb (use_stmt))
kono
parents: 67
diff changeset
1015 continue;
kono
parents: 67
diff changeset
1016
kono
parents: 67
diff changeset
1017 /* Filter out statements that can never produce a useful
kono
parents: 67
diff changeset
1018 equivalence. */
kono
parents: 67
diff changeset
1019 tree lhs2 = gimple_get_lhs (use_stmt);
kono
parents: 67
diff changeset
1020 if (!lhs2 || TREE_CODE (lhs2) != SSA_NAME)
kono
parents: 67
diff changeset
1021 continue;
kono
parents: 67
diff changeset
1022
kono
parents: 67
diff changeset
1023 /* Profiling has shown the domination tests here can be fairly
kono
parents: 67
diff changeset
1024 expensive. We get significant improvements by building the
kono
parents: 67
diff changeset
1025 set of blocks that dominate BB. We can then just test
kono
parents: 67
diff changeset
1026 for set membership below.
kono
parents: 67
diff changeset
1027
kono
parents: 67
diff changeset
1028 We also initialize the set lazily since often the only uses
kono
parents: 67
diff changeset
1029 are going to be in the same block as DEST. */
kono
parents: 67
diff changeset
1030 if (!domby)
kono
parents: 67
diff changeset
1031 {
kono
parents: 67
diff changeset
1032 domby = BITMAP_ALLOC (NULL);
kono
parents: 67
diff changeset
1033 basic_block bb = get_immediate_dominator (CDI_DOMINATORS, dest);
kono
parents: 67
diff changeset
1034 while (bb)
kono
parents: 67
diff changeset
1035 {
kono
parents: 67
diff changeset
1036 bitmap_set_bit (domby, bb->index);
kono
parents: 67
diff changeset
1037 bb = get_immediate_dominator (CDI_DOMINATORS, bb);
kono
parents: 67
diff changeset
1038 }
kono
parents: 67
diff changeset
1039 }
kono
parents: 67
diff changeset
1040
kono
parents: 67
diff changeset
1041 /* This tests if USE_STMT does not dominate DEST. */
kono
parents: 67
diff changeset
1042 if (!bitmap_bit_p (domby, gimple_bb (use_stmt)->index))
kono
parents: 67
diff changeset
1043 continue;
kono
parents: 67
diff changeset
1044
kono
parents: 67
diff changeset
1045 /* At this point USE_STMT dominates DEST and may result in a
kono
parents: 67
diff changeset
1046 useful equivalence. Try to simplify its RHS to a constant
kono
parents: 67
diff changeset
1047 or SSA_NAME. */
kono
parents: 67
diff changeset
1048 tree res = gimple_fold_stmt_to_constant_1 (use_stmt, dom_valueize,
kono
parents: 67
diff changeset
1049 no_follow_ssa_edges);
kono
parents: 67
diff changeset
1050 if (res && (TREE_CODE (res) == SSA_NAME || is_gimple_min_invariant (res)))
kono
parents: 67
diff changeset
1051 record_equality (lhs2, res, const_and_copies);
kono
parents: 67
diff changeset
1052 }
kono
parents: 67
diff changeset
1053
kono
parents: 67
diff changeset
1054 if (domby)
kono
parents: 67
diff changeset
1055 BITMAP_FREE (domby);
kono
parents: 67
diff changeset
1056 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1057
111
kono
parents: 67
diff changeset
1058 /* Record into CONST_AND_COPIES and AVAIL_EXPRS_STACK any equivalences implied
kono
parents: 67
diff changeset
1059 by traversing edge E (which are cached in E->aux).
kono
parents: 67
diff changeset
1060
kono
parents: 67
diff changeset
1061 Callers are responsible for managing the unwinding markers. */
kono
parents: 67
diff changeset
1062 void
kono
parents: 67
diff changeset
1063 record_temporary_equivalences (edge e,
kono
parents: 67
diff changeset
1064 class const_and_copies *const_and_copies,
kono
parents: 67
diff changeset
1065 class avail_exprs_stack *avail_exprs_stack)
kono
parents: 67
diff changeset
1066 {
kono
parents: 67
diff changeset
1067 int i;
kono
parents: 67
diff changeset
1068 class edge_info *edge_info = (class edge_info *) e->aux;
kono
parents: 67
diff changeset
1069
kono
parents: 67
diff changeset
1070 /* If we have info associated with this edge, record it into
kono
parents: 67
diff changeset
1071 our equivalence tables. */
kono
parents: 67
diff changeset
1072 if (edge_info)
kono
parents: 67
diff changeset
1073 {
kono
parents: 67
diff changeset
1074 cond_equivalence *eq;
kono
parents: 67
diff changeset
1075 /* If we have 0 = COND or 1 = COND equivalences, record them
kono
parents: 67
diff changeset
1076 into our expression hash tables. */
kono
parents: 67
diff changeset
1077 for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i)
kono
parents: 67
diff changeset
1078 avail_exprs_stack->record_cond (eq);
kono
parents: 67
diff changeset
1079
kono
parents: 67
diff changeset
1080 edge_info::equiv_pair *seq;
kono
parents: 67
diff changeset
1081 for (i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i)
kono
parents: 67
diff changeset
1082 {
kono
parents: 67
diff changeset
1083 tree lhs = seq->first;
kono
parents: 67
diff changeset
1084 if (!lhs || TREE_CODE (lhs) != SSA_NAME)
kono
parents: 67
diff changeset
1085 continue;
kono
parents: 67
diff changeset
1086
kono
parents: 67
diff changeset
1087 /* Record the simple NAME = VALUE equivalence. */
kono
parents: 67
diff changeset
1088 tree rhs = seq->second;
kono
parents: 67
diff changeset
1089
kono
parents: 67
diff changeset
1090 /* If this is a SSA_NAME = SSA_NAME equivalence and one operand is
kono
parents: 67
diff changeset
1091 cheaper to compute than the other, then set up the equivalence
kono
parents: 67
diff changeset
1092 such that we replace the expensive one with the cheap one.
kono
parents: 67
diff changeset
1093
kono
parents: 67
diff changeset
1094 If they are the same cost to compute, then do not record
kono
parents: 67
diff changeset
1095 anything. */
kono
parents: 67
diff changeset
1096 if (TREE_CODE (lhs) == SSA_NAME && TREE_CODE (rhs) == SSA_NAME)
kono
parents: 67
diff changeset
1097 {
kono
parents: 67
diff changeset
1098 gimple *rhs_def = SSA_NAME_DEF_STMT (rhs);
kono
parents: 67
diff changeset
1099 int rhs_cost = estimate_num_insns (rhs_def, &eni_size_weights);
kono
parents: 67
diff changeset
1100
kono
parents: 67
diff changeset
1101 gimple *lhs_def = SSA_NAME_DEF_STMT (lhs);
kono
parents: 67
diff changeset
1102 int lhs_cost = estimate_num_insns (lhs_def, &eni_size_weights);
kono
parents: 67
diff changeset
1103
kono
parents: 67
diff changeset
1104 if (rhs_cost > lhs_cost)
kono
parents: 67
diff changeset
1105 record_equality (rhs, lhs, const_and_copies);
kono
parents: 67
diff changeset
1106 else if (rhs_cost < lhs_cost)
kono
parents: 67
diff changeset
1107 record_equality (lhs, rhs, const_and_copies);
kono
parents: 67
diff changeset
1108 }
kono
parents: 67
diff changeset
1109 else
kono
parents: 67
diff changeset
1110 record_equality (lhs, rhs, const_and_copies);
kono
parents: 67
diff changeset
1111
kono
parents: 67
diff changeset
1112
kono
parents: 67
diff changeset
1113 /* Any equivalence found for LHS may result in additional
kono
parents: 67
diff changeset
1114 equivalences for other uses of LHS that we have already
kono
parents: 67
diff changeset
1115 processed. */
kono
parents: 67
diff changeset
1116 back_propagate_equivalences (lhs, e, const_and_copies);
kono
parents: 67
diff changeset
1117 }
kono
parents: 67
diff changeset
1118 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1119 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1120
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1121 /* PHI nodes can create equivalences too.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1122
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1123 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
1124 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
1125 equivalence. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1126
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1127 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1128 record_equivalences_from_phis (basic_block bb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1129 {
111
kono
parents: 67
diff changeset
1130 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
1131
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1132 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1133 {
111
kono
parents: 67
diff changeset
1134 gphi *phi = gsi.phi ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1135
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1136 /* We might eliminate the PHI, so advance GSI now. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1137 gsi_next (&gsi);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1138
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1139 tree lhs = gimple_phi_result (phi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1140 tree rhs = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1141 size_t i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1142
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1143 for (i = 0; i < gimple_phi_num_args (phi); i++)
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 tree t = gimple_phi_arg_def (phi, i);
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 /* Ignore alternatives which are the same as our LHS. Since
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1148 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
1149 can simply compare pointers. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1150 if (lhs == t)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1151 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1152
111
kono
parents: 67
diff changeset
1153 /* If the associated edge is not marked as executable, then it
kono
parents: 67
diff changeset
1154 can be ignored. */
kono
parents: 67
diff changeset
1155 if ((gimple_phi_arg_edge (phi, i)->flags & EDGE_EXECUTABLE) == 0)
kono
parents: 67
diff changeset
1156 continue;
kono
parents: 67
diff changeset
1157
kono
parents: 67
diff changeset
1158 t = dom_valueize (t);
kono
parents: 67
diff changeset
1159
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1160 /* If T is an SSA_NAME and its associated edge is a backedge,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1161 then quit as we cannot utilize this equivalence. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1162 if (TREE_CODE (t) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1163 && (gimple_phi_arg_edge (phi, i)->flags & EDGE_DFS_BACK))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1164 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1165
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1166 /* If we have not processed an alternative yet, then set
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1167 RHS to this alternative. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1168 if (rhs == NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1169 rhs = t;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1170 /* If we have processed an alternative (stored in RHS), then
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1171 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
1172 the search. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1173 else if (! operand_equal_for_phi_arg_p (rhs, t))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1174 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1175 }
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 we had no interesting alternatives, then all the RHS alternatives
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1178 must have been the same as LHS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1179 if (!rhs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1180 rhs = lhs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1181
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1182 /* If we managed to iterate through each PHI alternative without
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1183 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
1184 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
1185 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
1186 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
1187 by this assignment, so unwinding just costs time and space. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1188 if (i == gimple_phi_num_args (phi))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1189 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1190 if (may_propagate_copy (lhs, rhs))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1191 set_ssa_name_value (lhs, rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1192 else if (virtual_operand_p (lhs))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1193 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1194 gimple *use_stmt;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1195 imm_use_iterator iter;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1196 use_operand_p use_p;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1197 /* For virtual operands we have to propagate into all uses as
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1198 otherwise we will create overlapping life-ranges. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1199 FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1200 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1201 SET_USE (use_p, rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1202 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1203 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1204 gimple_stmt_iterator tmp_gsi = gsi_for_stmt (phi);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1205 remove_phi_node (&tmp_gsi, true);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1206 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1207 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1208 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1209 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1210
111
kono
parents: 67
diff changeset
1211 /* Record any equivalences created by the incoming edge to BB into
kono
parents: 67
diff changeset
1212 CONST_AND_COPIES and AVAIL_EXPRS_STACK. If BB has more than one
kono
parents: 67
diff changeset
1213 incoming edge, then no equivalence is created. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1214
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1215 static void
111
kono
parents: 67
diff changeset
1216 record_equivalences_from_incoming_edge (basic_block bb,
kono
parents: 67
diff changeset
1217 class const_and_copies *const_and_copies,
kono
parents: 67
diff changeset
1218 class avail_exprs_stack *avail_exprs_stack)
0
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 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1221 basic_block parent;
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 /* 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
1224 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
1225 the parent was followed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1226 parent = get_immediate_dominator (CDI_DOMINATORS, bb);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1227
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1228 e = single_pred_edge_ignoring_loop_edges (bb, true);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1229
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1230 /* 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
1231 any data associated with the edge into our tables. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1232 if (e && e->src == parent)
111
kono
parents: 67
diff changeset
1233 record_temporary_equivalences (e, const_and_copies, avail_exprs_stack);
kono
parents: 67
diff changeset
1234 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1235
111
kono
parents: 67
diff changeset
1236 /* Dump statistics for the hash table HTAB. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1237
111
kono
parents: 67
diff changeset
1238 static void
kono
parents: 67
diff changeset
1239 htab_statistics (FILE *file, const hash_table<expr_elt_hasher> &htab)
kono
parents: 67
diff changeset
1240 {
kono
parents: 67
diff changeset
1241 fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
kono
parents: 67
diff changeset
1242 (long) htab.size (),
kono
parents: 67
diff changeset
1243 (long) htab.elements (),
kono
parents: 67
diff changeset
1244 htab.collisions ());
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1245 }
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 /* Dump SSA statistics on FILE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1248
111
kono
parents: 67
diff changeset
1249 static void
kono
parents: 67
diff changeset
1250 dump_dominator_optimization_stats (FILE *file,
kono
parents: 67
diff changeset
1251 hash_table<expr_elt_hasher> *avail_exprs)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1252 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1253 fprintf (file, "Total number of statements: %6ld\n\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1254 opt_stats.num_stmts);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1255 fprintf (file, "Exprs considered for dominator optimizations: %6ld\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1256 opt_stats.num_exprs_considered);
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 fprintf (file, "\nHash table statistics:\n");
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 fprintf (file, " avail_exprs: ");
111
kono
parents: 67
diff changeset
1261 htab_statistics (file, *avail_exprs);
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1264
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1265 /* 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
1266 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
1267
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1268 static void
111
kono
parents: 67
diff changeset
1269 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
1270 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1271 tree prev_x = NULL, prev_y = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1272
111
kono
parents: 67
diff changeset
1273 if (tree_swap_operands_p (x, y))
kono
parents: 67
diff changeset
1274 std::swap (x, y);
kono
parents: 67
diff changeset
1275
kono
parents: 67
diff changeset
1276 /* Most of the time tree_swap_operands_p does what we want. But there
kono
parents: 67
diff changeset
1277 are cases where we know one operand is better for copy propagation than
kono
parents: 67
diff changeset
1278 the other. Given no other code cares about ordering of equality
kono
parents: 67
diff changeset
1279 comparison operators for that purpose, we just handle the special cases
kono
parents: 67
diff changeset
1280 here. */
kono
parents: 67
diff changeset
1281 if (TREE_CODE (x) == SSA_NAME && TREE_CODE (y) == SSA_NAME)
kono
parents: 67
diff changeset
1282 {
kono
parents: 67
diff changeset
1283 /* If one operand is a single use operand, then make it
kono
parents: 67
diff changeset
1284 X. This will preserve its single use properly and if this
kono
parents: 67
diff changeset
1285 conditional is eliminated, the computation of X can be
kono
parents: 67
diff changeset
1286 eliminated as well. */
kono
parents: 67
diff changeset
1287 if (has_single_use (y) && ! has_single_use (x))
kono
parents: 67
diff changeset
1288 std::swap (x, y);
kono
parents: 67
diff changeset
1289 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1290 if (TREE_CODE (x) == SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1291 prev_x = SSA_NAME_VALUE (x);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1292 if (TREE_CODE (y) == SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1293 prev_y = SSA_NAME_VALUE (y);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1294
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1295 /* 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
1296 (by depth), then use that.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1297 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
1298 long as we canonicalize on one value. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1299 if (is_gimple_min_invariant (y))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1300 ;
111
kono
parents: 67
diff changeset
1301 else if (is_gimple_min_invariant (x))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1302 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
1303 else if (prev_x && is_gimple_min_invariant (prev_x))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1304 x = y, y = prev_x, prev_x = prev_y;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1305 else if (prev_y)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1306 y = prev_y;
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 /* After the swapping, we must have one SSA_NAME. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1309 if (TREE_CODE (x) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1310 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1311
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1312 /* 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
1313 variable compared against zero. If we're honoring signed zeros,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1314 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
1315 nonzero. */
111
kono
parents: 67
diff changeset
1316 if (HONOR_SIGNED_ZEROS (x)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1317 && (TREE_CODE (y) != REAL_CST
111
kono
parents: 67
diff changeset
1318 || real_equal (&dconst0, &TREE_REAL_CST (y))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1319 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1320
111
kono
parents: 67
diff changeset
1321 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
1322 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1323
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1324 /* 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
1325 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
1326
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1327 i_1 = phi (..., i_k)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1328 [...]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1329 i_j = i_{j-1} for each j : 2 <= j <= k-1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1330 [...]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1331 i_k = i_{k-1} +/- ... */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1332
111
kono
parents: 67
diff changeset
1333 bool
kono
parents: 67
diff changeset
1334 simple_iv_increment_p (gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1335 {
111
kono
parents: 67
diff changeset
1336 enum tree_code code;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1337 tree lhs, preinc;
111
kono
parents: 67
diff changeset
1338 gimple *phi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1339 size_t i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1340
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1341 if (gimple_code (stmt) != GIMPLE_ASSIGN)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1342 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1343
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1344 lhs = gimple_assign_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1345 if (TREE_CODE (lhs) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1346 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1347
111
kono
parents: 67
diff changeset
1348 code = gimple_assign_rhs_code (stmt);
kono
parents: 67
diff changeset
1349 if (code != PLUS_EXPR
kono
parents: 67
diff changeset
1350 && code != MINUS_EXPR
kono
parents: 67
diff changeset
1351 && code != POINTER_PLUS_EXPR)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1352 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1353
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1354 preinc = gimple_assign_rhs1 (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1355 if (TREE_CODE (preinc) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1356 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1357
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1358 phi = SSA_NAME_DEF_STMT (preinc);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1359 while (gimple_code (phi) != GIMPLE_PHI)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1360 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1361 /* Follow trivial copies, but not the DEF used in a back edge,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1362 so that we don't prevent coalescing. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1363 if (!gimple_assign_ssa_name_copy_p (phi))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1364 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1365 preinc = gimple_assign_rhs1 (phi);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1366 phi = SSA_NAME_DEF_STMT (preinc);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1367 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1368
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1369 for (i = 0; i < gimple_phi_num_args (phi); i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1370 if (gimple_phi_arg_def (phi, i) == lhs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1371 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1372
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1373 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1374 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1375
111
kono
parents: 67
diff changeset
1376 /* 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
1377 successors of BB. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1378
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1379 static void
111
kono
parents: 67
diff changeset
1380 cprop_into_successor_phis (basic_block bb,
kono
parents: 67
diff changeset
1381 class const_and_copies *const_and_copies)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1382 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1383 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1384 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1385
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1386 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1387 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1388 int indx;
111
kono
parents: 67
diff changeset
1389 gphi_iterator gsi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1390
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1391 /* 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
1392 into the PHI alternative associated with this edge. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1393 if (e->flags & EDGE_ABNORMAL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1394 continue;
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 gsi = gsi_start_phis (e->dest);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1397 if (gsi_end_p (gsi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1398 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1399
111
kono
parents: 67
diff changeset
1400 /* We may have an equivalence associated with this edge. While
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1401 we cannot propagate it into non-dominated blocks, we can
111
kono
parents: 67
diff changeset
1402 propagate them into PHIs in non-dominated blocks. */
kono
parents: 67
diff changeset
1403
kono
parents: 67
diff changeset
1404 /* Push the unwind marker so we can reset the const and copies
kono
parents: 67
diff changeset
1405 table back to its original state after processing this edge. */
kono
parents: 67
diff changeset
1406 const_and_copies->push_marker ();
kono
parents: 67
diff changeset
1407
kono
parents: 67
diff changeset
1408 /* Extract and record any simple NAME = VALUE equivalences.
kono
parents: 67
diff changeset
1409
kono
parents: 67
diff changeset
1410 Don't bother with [01] = COND equivalences, they're not useful
kono
parents: 67
diff changeset
1411 here. */
kono
parents: 67
diff changeset
1412 class edge_info *edge_info = (class edge_info *) e->aux;
kono
parents: 67
diff changeset
1413
kono
parents: 67
diff changeset
1414 if (edge_info)
kono
parents: 67
diff changeset
1415 {
kono
parents: 67
diff changeset
1416 edge_info::equiv_pair *seq;
kono
parents: 67
diff changeset
1417 for (int i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i)
kono
parents: 67
diff changeset
1418 {
kono
parents: 67
diff changeset
1419 tree lhs = seq->first;
kono
parents: 67
diff changeset
1420 tree rhs = seq->second;
kono
parents: 67
diff changeset
1421
kono
parents: 67
diff changeset
1422 if (lhs && TREE_CODE (lhs) == SSA_NAME)
kono
parents: 67
diff changeset
1423 const_and_copies->record_const_or_copy (lhs, rhs);
kono
parents: 67
diff changeset
1424 }
kono
parents: 67
diff changeset
1425
kono
parents: 67
diff changeset
1426 }
kono
parents: 67
diff changeset
1427
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1428 indx = e->dest_idx;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1429 for ( ; !gsi_end_p (gsi); gsi_next (&gsi))
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 tree new_val;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1432 use_operand_p orig_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1433 tree orig_val;
111
kono
parents: 67
diff changeset
1434 gphi *phi = gsi.phi ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1435
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1436 /* The alternative may be associated with a constant, so verify
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1437 it is an SSA_NAME before doing anything with it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1438 orig_p = gimple_phi_arg_imm_use_ptr (phi, indx);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1439 orig_val = get_use_from_ptr (orig_p);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1440 if (TREE_CODE (orig_val) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1441 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1442
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1443 /* 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
1444 ORIG_P with its value in our constant/copy table. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1445 new_val = SSA_NAME_VALUE (orig_val);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1446 if (new_val
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1447 && new_val != orig_val
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1448 && may_propagate_copy (orig_val, new_val))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1449 propagate_value (orig_p, new_val);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1450 }
111
kono
parents: 67
diff changeset
1451
kono
parents: 67
diff changeset
1452 const_and_copies->pop_to_marker ();
0
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 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1455
111
kono
parents: 67
diff changeset
1456 edge
kono
parents: 67
diff changeset
1457 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
1458 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1459 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
1460
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1461 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
1462 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
1463
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1464 evrp_range_analyzer.enter (bb);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1465
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1466 /* 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
1467 far to unwind when we finalize this block. */
111
kono
parents: 67
diff changeset
1468 m_avail_exprs_stack->push_marker ();
kono
parents: 67
diff changeset
1469 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
1470
111
kono
parents: 67
diff changeset
1471 record_equivalences_from_incoming_edge (bb, m_const_and_copies,
kono
parents: 67
diff changeset
1472 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
1473
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1474 /* 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
1475 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
1476
111
kono
parents: 67
diff changeset
1477 /* Create equivalences from redundant PHIs. PHIs are only truly
kono
parents: 67
diff changeset
1478 redundant when they exist in the same block, so push another
kono
parents: 67
diff changeset
1479 marker and unwind right afterwards. */
kono
parents: 67
diff changeset
1480 m_avail_exprs_stack->push_marker ();
kono
parents: 67
diff changeset
1481 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
kono
parents: 67
diff changeset
1482 eliminate_redundant_computations (&gsi, m_const_and_copies,
kono
parents: 67
diff changeset
1483 m_avail_exprs_stack);
kono
parents: 67
diff changeset
1484 m_avail_exprs_stack->pop_to_marker ();
kono
parents: 67
diff changeset
1485
kono
parents: 67
diff changeset
1486 edge taken_edge = NULL;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1487 /* Initialize visited flag ahead of us, it has undefined state on
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1488 pass entry. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1489 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1490 gimple_set_visited (gsi_stmt (gsi), false);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1491 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1492 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1493 /* Do not optimize a stmt twice, substitution might end up with
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1494 _3 = _3 which is not valid. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1495 if (gimple_visited_p (gsi_stmt (gsi)))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1496 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1497 gsi_next (&gsi);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1498 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1499 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1500
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1501 /* Compute range information and optimize the stmt. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1502 evrp_range_analyzer.record_ranges_from_stmt (gsi_stmt (gsi), false);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1503 bool removed_p = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1504 taken_edge = this->optimize_stmt (bb, &gsi, &removed_p);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1505 if (!removed_p)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1506 gimple_set_visited (gsi_stmt (gsi), true);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1507
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1508 /* Go back and visit stmts inserted by folding after substituting
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1509 into the stmt at gsi. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1510 if (gsi_end_p (gsi))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1511 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1512 gcc_checking_assert (removed_p);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1513 gsi = gsi_last_bb (bb);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1514 while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi)))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1515 gsi_prev (&gsi);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1516 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1517 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1518 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1519 do
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1520 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1521 gsi_prev (&gsi);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1522 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1523 while (!gsi_end_p (gsi) && !gimple_visited_p (gsi_stmt (gsi)));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1524 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1525 if (gsi_end_p (gsi))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1526 gsi = gsi_start_bb (bb);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1527 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1528 gsi_next (&gsi);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1529 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1530
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1531 /* 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
1532 record_edge_info (bb);
111
kono
parents: 67
diff changeset
1533 cprop_into_successor_phis (bb, m_const_and_copies);
kono
parents: 67
diff changeset
1534 if (taken_edge && !dbg_cnt (dom_unreachable_edges))
kono
parents: 67
diff changeset
1535 return NULL;
kono
parents: 67
diff changeset
1536
kono
parents: 67
diff changeset
1537 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
1538 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1539
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1540 /* 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
1541 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
1542 the dominator tree. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1543
111
kono
parents: 67
diff changeset
1544 void
kono
parents: 67
diff changeset
1545 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
1546 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1547 x_vr_values = evrp_range_analyzer.get_vr_values ();
111
kono
parents: 67
diff changeset
1548 thread_outgoing_edges (bb, m_dummy_cond, m_const_and_copies,
kono
parents: 67
diff changeset
1549 m_avail_exprs_stack,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1550 &evrp_range_analyzer,
111
kono
parents: 67
diff changeset
1551 simplify_stmt_for_jump_threading);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1552 x_vr_values = NULL;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1553
111
kono
parents: 67
diff changeset
1554 /* These remove expressions local to BB from the tables. */
kono
parents: 67
diff changeset
1555 m_avail_exprs_stack->pop_to_marker ();
kono
parents: 67
diff changeset
1556 m_const_and_copies->pop_to_marker ();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1557 evrp_range_analyzer.leave (bb);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1558 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1559
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1560 /* 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
1561 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
1562
111
kono
parents: 67
diff changeset
1563 If safe, record this expression into AVAIL_EXPRS_STACK and
kono
parents: 67
diff changeset
1564 CONST_AND_COPIES. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1565
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1566 static void
111
kono
parents: 67
diff changeset
1567 eliminate_redundant_computations (gimple_stmt_iterator* gsi,
kono
parents: 67
diff changeset
1568 class const_and_copies *const_and_copies,
kono
parents: 67
diff changeset
1569 class avail_exprs_stack *avail_exprs_stack)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1570 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1571 tree expr_type;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1572 tree cached_lhs;
111
kono
parents: 67
diff changeset
1573 tree def;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1574 bool insert = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1575 bool assigns_var_p = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1576
111
kono
parents: 67
diff changeset
1577 gimple *stmt = gsi_stmt (*gsi);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1578
111
kono
parents: 67
diff changeset
1579 if (gimple_code (stmt) == GIMPLE_PHI)
kono
parents: 67
diff changeset
1580 def = gimple_phi_result (stmt);
kono
parents: 67
diff changeset
1581 else
kono
parents: 67
diff changeset
1582 def = gimple_get_lhs (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1583
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1584 /* Certain expressions on the RHS can be optimized away, but cannot
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1585 themselves be entered into the hash tables. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1586 if (! def
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1587 || TREE_CODE (def) != SSA_NAME
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1588 || 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
1589 || gimple_vdef (stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1590 /* 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
1591 overlapping live ranges for a very questionable gain. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1592 || simple_iv_increment_p (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1593 insert = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1594
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1595 /* Check if the expression has been computed before. */
111
kono
parents: 67
diff changeset
1596 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
1597
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1598 opt_stats.num_exprs_considered++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1599
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1600 /* 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
1601 if (is_gimple_assign (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1602 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1603 expr_type = TREE_TYPE (gimple_assign_lhs (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1604 assigns_var_p = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1605 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1606 else if (gimple_code (stmt) == GIMPLE_COND)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1607 expr_type = boolean_type_node;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1608 else if (is_gimple_call (stmt))
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 gcc_assert (gimple_call_lhs (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1611 expr_type = TREE_TYPE (gimple_call_lhs (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1612 assigns_var_p = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1613 }
111
kono
parents: 67
diff changeset
1614 else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
kono
parents: 67
diff changeset
1615 expr_type = TREE_TYPE (gimple_switch_index (swtch_stmt));
kono
parents: 67
diff changeset
1616 else if (gimple_code (stmt) == GIMPLE_PHI)
kono
parents: 67
diff changeset
1617 /* We can't propagate into a phi, so the logic below doesn't apply.
kono
parents: 67
diff changeset
1618 Instead record an equivalence between the cached LHS and the
kono
parents: 67
diff changeset
1619 PHI result of this statement, provided they are in the same block.
kono
parents: 67
diff changeset
1620 This should be sufficient to kill the redundant phi. */
kono
parents: 67
diff changeset
1621 {
kono
parents: 67
diff changeset
1622 if (def && cached_lhs)
kono
parents: 67
diff changeset
1623 const_and_copies->record_const_or_copy (def, cached_lhs);
kono
parents: 67
diff changeset
1624 return;
kono
parents: 67
diff changeset
1625 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1626 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1627 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1628
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1629 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
1630 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1631
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1632 /* 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
1633 type checking in the hashing and equality routines. In fact
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1634 type checking here merely gets in the way of constant
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1635 propagation. Also, make sure that it is safe to propagate
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1636 CACHED_LHS into the expression in STMT. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1637 if ((TREE_CODE (cached_lhs) != SSA_NAME
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1638 && (assigns_var_p
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1639 || useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1640 || may_propagate_copy_into_stmt (stmt, cached_lhs))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1641 {
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
1642 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
1643 || is_gimple_min_invariant (cached_lhs));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1644
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1645 if (dump_file && (dump_flags & TDF_DETAILS))
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 fprintf (dump_file, " Replaced redundant expr '");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1648 print_gimple_expr (dump_file, stmt, 0, dump_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1649 fprintf (dump_file, "' with '");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1650 print_generic_expr (dump_file, cached_lhs, dump_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1651 fprintf (dump_file, "'\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1652 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1653
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1654 opt_stats.num_re++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1655
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1656 if (assigns_var_p
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1657 && !useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1658 cached_lhs = fold_convert (expr_type, cached_lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1659
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1660 propagate_tree_value_into_stmt (gsi, cached_lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1661
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1662 /* 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
1663 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
1664 itself. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1665 gimple_set_modified (gsi_stmt (*gsi), true);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1666 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1667 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1668
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1669 /* STMT, a GIMPLE_ASSIGN, may create certain equivalences, in either
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1670 the available expressions table or the const_and_copies table.
111
kono
parents: 67
diff changeset
1671 Detect and record those equivalences into AVAIL_EXPRS_STACK.
kono
parents: 67
diff changeset
1672
kono
parents: 67
diff changeset
1673 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
1674 lifing is done by eliminate_redundant_computations. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1675
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1676 static void
111
kono
parents: 67
diff changeset
1677 record_equivalences_from_stmt (gimple *stmt, int may_optimize_p,
kono
parents: 67
diff changeset
1678 class avail_exprs_stack *avail_exprs_stack)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1679 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1680 tree lhs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1681 enum tree_code lhs_code;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1682
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1683 gcc_assert (is_gimple_assign (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1684
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1685 lhs = gimple_assign_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1686 lhs_code = TREE_CODE (lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1687
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1688 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
1689 && gimple_assign_single_p (stmt))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1690 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1691 tree rhs = gimple_assign_rhs1 (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1692
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1693 /* 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
1694 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
1695 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
1696 assignment and not an equivalence inferred from a comparison. All
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1697 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
1698 just costs time and space. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1699 if (may_optimize_p
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1700 && (TREE_CODE (rhs) == SSA_NAME
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1701 || is_gimple_min_invariant (rhs)))
111
kono
parents: 67
diff changeset
1702 {
kono
parents: 67
diff changeset
1703 rhs = dom_valueize (rhs);
kono
parents: 67
diff changeset
1704
kono
parents: 67
diff changeset
1705 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
1706 {
kono
parents: 67
diff changeset
1707 fprintf (dump_file, "==== ASGN ");
kono
parents: 67
diff changeset
1708 print_generic_expr (dump_file, lhs);
kono
parents: 67
diff changeset
1709 fprintf (dump_file, " = ");
kono
parents: 67
diff changeset
1710 print_generic_expr (dump_file, rhs);
kono
parents: 67
diff changeset
1711 fprintf (dump_file, "\n");
kono
parents: 67
diff changeset
1712 }
kono
parents: 67
diff changeset
1713
kono
parents: 67
diff changeset
1714 set_ssa_name_value (lhs, rhs);
kono
parents: 67
diff changeset
1715 }
kono
parents: 67
diff changeset
1716 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1717
111
kono
parents: 67
diff changeset
1718 /* Make sure we can propagate &x + CST. */
kono
parents: 67
diff changeset
1719 if (lhs_code == SSA_NAME
kono
parents: 67
diff changeset
1720 && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
kono
parents: 67
diff changeset
1721 && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR
kono
parents: 67
diff changeset
1722 && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST)
kono
parents: 67
diff changeset
1723 {
kono
parents: 67
diff changeset
1724 tree op0 = gimple_assign_rhs1 (stmt);
kono
parents: 67
diff changeset
1725 tree op1 = gimple_assign_rhs2 (stmt);
kono
parents: 67
diff changeset
1726 tree new_rhs
kono
parents: 67
diff changeset
1727 = build_fold_addr_expr (fold_build2 (MEM_REF,
kono
parents: 67
diff changeset
1728 TREE_TYPE (TREE_TYPE (op0)),
kono
parents: 67
diff changeset
1729 unshare_expr (op0),
kono
parents: 67
diff changeset
1730 fold_convert (ptr_type_node,
kono
parents: 67
diff changeset
1731 op1)));
kono
parents: 67
diff changeset
1732 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
1733 {
kono
parents: 67
diff changeset
1734 fprintf (dump_file, "==== ASGN ");
kono
parents: 67
diff changeset
1735 print_generic_expr (dump_file, lhs);
kono
parents: 67
diff changeset
1736 fprintf (dump_file, " = ");
kono
parents: 67
diff changeset
1737 print_generic_expr (dump_file, new_rhs);
kono
parents: 67
diff changeset
1738 fprintf (dump_file, "\n");
kono
parents: 67
diff changeset
1739 }
kono
parents: 67
diff changeset
1740
kono
parents: 67
diff changeset
1741 set_ssa_name_value (lhs, new_rhs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1742 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1743
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1744 /* A memory store, even an aliased store, creates a useful
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1745 equivalence. By exchanging the LHS and RHS, creating suitable
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1746 vops and recording the result in the available expression table,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1747 we may be able to expose more redundant loads. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1748 if (!gimple_has_volatile_ops (stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1749 && gimple_references_memory_p (stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1750 && gimple_assign_single_p (stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1751 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1752 || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1753 && !is_gimple_reg (lhs))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1754 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1755 tree rhs = gimple_assign_rhs1 (stmt);
111
kono
parents: 67
diff changeset
1756 gassign *new_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1757
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1758 /* Build a new statement with the RHS and LHS exchanged. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1759 if (TREE_CODE (rhs) == SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1760 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1761 /* NOTE tuples. The call to gimple_build_assign below replaced
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1762 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
1763 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
1764 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
1765 default-initialized name and should have no definition. I'm
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1766 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
1767 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
1768 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
1769 part of the CFG. */
111
kono
parents: 67
diff changeset
1770 gimple *defstmt = SSA_NAME_DEF_STMT (rhs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1771 new_stmt = gimple_build_assign (rhs, lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1772 SSA_NAME_DEF_STMT (rhs) = defstmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1773 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1774 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1775 new_stmt = gimple_build_assign (rhs, lhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1776
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1777 gimple_set_vuse (new_stmt, gimple_vdef (stmt));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1778
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1779 /* Finally enter the statement into the available expression
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1780 table. */
111
kono
parents: 67
diff changeset
1781 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
1782 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1783 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1784
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1785 /* 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
1786 CONST_AND_COPIES. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1787
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1788 static void
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1789 cprop_operand (gimple *stmt, use_operand_p op_p, vr_values *vr_values)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1790 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1791 tree val;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1792 tree op = USE_FROM_PTR (op_p);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1793
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1794 /* 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
1795 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
1796 CONST_AND_COPIES. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1797 val = SSA_NAME_VALUE (op);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1798 if (!val)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1799 val = vr_values->op_with_constant_singleton_value_range (op);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1800
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1801 if (val && val != op)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1802 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1803 /* Do not replace hard register operands in asm statements. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1804 if (gimple_code (stmt) == GIMPLE_ASM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1805 && !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
1806 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1807
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1808 /* Certain operands are not allowed to be copy propagated due
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1809 to their interaction with exception handling and some GCC
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1810 extensions. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1811 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
1812 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1813
111
kono
parents: 67
diff changeset
1814 /* Do not propagate copies into BIVs.
kono
parents: 67
diff changeset
1815 See PR23821 and PR62217 for how this can disturb IV and
kono
parents: 67
diff changeset
1816 number of iteration analysis. */
kono
parents: 67
diff changeset
1817 if (TREE_CODE (val) != INTEGER_CST)
kono
parents: 67
diff changeset
1818 {
kono
parents: 67
diff changeset
1819 gimple *def = SSA_NAME_DEF_STMT (op);
kono
parents: 67
diff changeset
1820 if (gimple_code (def) == GIMPLE_PHI
kono
parents: 67
diff changeset
1821 && gimple_bb (def)->loop_father->header == gimple_bb (def))
kono
parents: 67
diff changeset
1822 return;
kono
parents: 67
diff changeset
1823 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1824
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1825 /* Dump details. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1826 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1827 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1828 fprintf (dump_file, " Replaced '");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1829 print_generic_expr (dump_file, op, dump_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1830 fprintf (dump_file, "' with %s '",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1831 (TREE_CODE (val) != SSA_NAME ? "constant" : "variable"));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1832 print_generic_expr (dump_file, val, dump_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1833 fprintf (dump_file, "'\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1834 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1835
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1836 if (TREE_CODE (val) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1837 opt_stats.num_const_prop++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1838 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1839 opt_stats.num_copy_prop++;
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 propagate_value (op_p, val);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1842
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1843 /* And note that we modified this statement. This is now
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1844 safe, even if we changed virtual operands since we will
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1845 rescan the statement and rewrite its operands again. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1846 gimple_set_modified (stmt, true);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1847 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1848 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1849
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1850 /* 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
1851 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
1852
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1853 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
1854 vdef_ops of STMT. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1855
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1856 static void
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1857 cprop_into_stmt (gimple *stmt, vr_values *vr_values)
0
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 use_operand_p op_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1860 ssa_op_iter iter;
111
kono
parents: 67
diff changeset
1861 tree last_copy_propagated_op = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1862
111
kono
parents: 67
diff changeset
1863 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
1864 {
111
kono
parents: 67
diff changeset
1865 tree old_op = USE_FROM_PTR (op_p);
kono
parents: 67
diff changeset
1866
kono
parents: 67
diff changeset
1867 /* If we have A = B and B = A in the copy propagation tables
kono
parents: 67
diff changeset
1868 (due to an equality comparison), avoid substituting B for A
kono
parents: 67
diff changeset
1869 then A for B in the trivially discovered cases. This allows
kono
parents: 67
diff changeset
1870 optimization of statements were A and B appear as input
kono
parents: 67
diff changeset
1871 operands. */
kono
parents: 67
diff changeset
1872 if (old_op != last_copy_propagated_op)
kono
parents: 67
diff changeset
1873 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1874 cprop_operand (stmt, op_p, vr_values);
111
kono
parents: 67
diff changeset
1875
kono
parents: 67
diff changeset
1876 tree new_op = USE_FROM_PTR (op_p);
kono
parents: 67
diff changeset
1877 if (new_op != old_op && TREE_CODE (new_op) == SSA_NAME)
kono
parents: 67
diff changeset
1878 last_copy_propagated_op = new_op;
kono
parents: 67
diff changeset
1879 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1880 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1881 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1882
111
kono
parents: 67
diff changeset
1883 /* If STMT contains a relational test, try to convert it into an
kono
parents: 67
diff changeset
1884 equality test if there is only a single value which can ever
kono
parents: 67
diff changeset
1885 make the test true.
kono
parents: 67
diff changeset
1886
kono
parents: 67
diff changeset
1887 For example, if the expression hash table contains:
kono
parents: 67
diff changeset
1888
kono
parents: 67
diff changeset
1889 TRUE = (i <= 1)
kono
parents: 67
diff changeset
1890
kono
parents: 67
diff changeset
1891 And we have a test within statement of i >= 1, then we can safely
kono
parents: 67
diff changeset
1892 rewrite the test as i == 1 since there only a single value where
kono
parents: 67
diff changeset
1893 the test is true.
kono
parents: 67
diff changeset
1894
kono
parents: 67
diff changeset
1895 This is similar to code in VRP. */
kono
parents: 67
diff changeset
1896
kono
parents: 67
diff changeset
1897 static void
kono
parents: 67
diff changeset
1898 test_for_singularity (gimple *stmt, gcond *dummy_cond,
kono
parents: 67
diff changeset
1899 avail_exprs_stack *avail_exprs_stack)
kono
parents: 67
diff changeset
1900 {
kono
parents: 67
diff changeset
1901 /* We want to support gimple conditionals as well as assignments
kono
parents: 67
diff changeset
1902 where the RHS contains a conditional. */
kono
parents: 67
diff changeset
1903 if (is_gimple_assign (stmt) || gimple_code (stmt) == GIMPLE_COND)
kono
parents: 67
diff changeset
1904 {
kono
parents: 67
diff changeset
1905 enum tree_code code = ERROR_MARK;
kono
parents: 67
diff changeset
1906 tree lhs, rhs;
kono
parents: 67
diff changeset
1907
kono
parents: 67
diff changeset
1908 /* Extract the condition of interest from both forms we support. */
kono
parents: 67
diff changeset
1909 if (is_gimple_assign (stmt))
kono
parents: 67
diff changeset
1910 {
kono
parents: 67
diff changeset
1911 code = gimple_assign_rhs_code (stmt);
kono
parents: 67
diff changeset
1912 lhs = gimple_assign_rhs1 (stmt);
kono
parents: 67
diff changeset
1913 rhs = gimple_assign_rhs2 (stmt);
kono
parents: 67
diff changeset
1914 }
kono
parents: 67
diff changeset
1915 else if (gimple_code (stmt) == GIMPLE_COND)
kono
parents: 67
diff changeset
1916 {
kono
parents: 67
diff changeset
1917 code = gimple_cond_code (as_a <gcond *> (stmt));
kono
parents: 67
diff changeset
1918 lhs = gimple_cond_lhs (as_a <gcond *> (stmt));
kono
parents: 67
diff changeset
1919 rhs = gimple_cond_rhs (as_a <gcond *> (stmt));
kono
parents: 67
diff changeset
1920 }
kono
parents: 67
diff changeset
1921
kono
parents: 67
diff changeset
1922 /* We're looking for a relational test using LE/GE. Also note we can
kono
parents: 67
diff changeset
1923 canonicalize LT/GT tests against constants into LE/GT tests. */
kono
parents: 67
diff changeset
1924 if (code == LE_EXPR || code == GE_EXPR
kono
parents: 67
diff changeset
1925 || ((code == LT_EXPR || code == GT_EXPR)
kono
parents: 67
diff changeset
1926 && TREE_CODE (rhs) == INTEGER_CST))
kono
parents: 67
diff changeset
1927 {
kono
parents: 67
diff changeset
1928 /* For LT_EXPR and GT_EXPR, canonicalize to LE_EXPR and GE_EXPR. */
kono
parents: 67
diff changeset
1929 if (code == LT_EXPR)
kono
parents: 67
diff changeset
1930 rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (rhs),
kono
parents: 67
diff changeset
1931 rhs, build_int_cst (TREE_TYPE (rhs), 1));
kono
parents: 67
diff changeset
1932
kono
parents: 67
diff changeset
1933 if (code == GT_EXPR)
kono
parents: 67
diff changeset
1934 rhs = fold_build2 (PLUS_EXPR, TREE_TYPE (rhs),
kono
parents: 67
diff changeset
1935 rhs, build_int_cst (TREE_TYPE (rhs), 1));
kono
parents: 67
diff changeset
1936
kono
parents: 67
diff changeset
1937 /* Determine the code we want to check for in the hash table. */
kono
parents: 67
diff changeset
1938 enum tree_code test_code;
kono
parents: 67
diff changeset
1939 if (code == GE_EXPR || code == GT_EXPR)
kono
parents: 67
diff changeset
1940 test_code = LE_EXPR;
kono
parents: 67
diff changeset
1941 else
kono
parents: 67
diff changeset
1942 test_code = GE_EXPR;
kono
parents: 67
diff changeset
1943
kono
parents: 67
diff changeset
1944 /* Update the dummy statement so we can query the hash tables. */
kono
parents: 67
diff changeset
1945 gimple_cond_set_code (dummy_cond, test_code);
kono
parents: 67
diff changeset
1946 gimple_cond_set_lhs (dummy_cond, lhs);
kono
parents: 67
diff changeset
1947 gimple_cond_set_rhs (dummy_cond, rhs);
kono
parents: 67
diff changeset
1948 tree cached_lhs
kono
parents: 67
diff changeset
1949 = avail_exprs_stack->lookup_avail_expr (dummy_cond, false, false);
kono
parents: 67
diff changeset
1950
kono
parents: 67
diff changeset
1951 /* If the lookup returned 1 (true), then the expression we
kono
parents: 67
diff changeset
1952 queried was in the hash table. As a result there is only
kono
parents: 67
diff changeset
1953 one value that makes the original conditional true. Update
kono
parents: 67
diff changeset
1954 STMT accordingly. */
kono
parents: 67
diff changeset
1955 if (cached_lhs && integer_onep (cached_lhs))
kono
parents: 67
diff changeset
1956 {
kono
parents: 67
diff changeset
1957 if (is_gimple_assign (stmt))
kono
parents: 67
diff changeset
1958 {
kono
parents: 67
diff changeset
1959 gimple_assign_set_rhs_code (stmt, EQ_EXPR);
kono
parents: 67
diff changeset
1960 gimple_assign_set_rhs2 (stmt, rhs);
kono
parents: 67
diff changeset
1961 gimple_set_modified (stmt, true);
kono
parents: 67
diff changeset
1962 }
kono
parents: 67
diff changeset
1963 else
kono
parents: 67
diff changeset
1964 {
kono
parents: 67
diff changeset
1965 gimple_set_modified (stmt, true);
kono
parents: 67
diff changeset
1966 gimple_cond_set_code (as_a <gcond *> (stmt), EQ_EXPR);
kono
parents: 67
diff changeset
1967 gimple_cond_set_rhs (as_a <gcond *> (stmt), rhs);
kono
parents: 67
diff changeset
1968 gimple_set_modified (stmt, true);
kono
parents: 67
diff changeset
1969 }
kono
parents: 67
diff changeset
1970 }
kono
parents: 67
diff changeset
1971 }
kono
parents: 67
diff changeset
1972 }
kono
parents: 67
diff changeset
1973 }
kono
parents: 67
diff changeset
1974
kono
parents: 67
diff changeset
1975 /* 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
1976
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1977 We try to perform some simplistic global redundancy elimination and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1978 constant propagation:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1979
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1980 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
1981 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
1982 same expression is computed more than once, we eliminate repeated
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1983 computations by using the target of the first one.
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 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
1986 simplistic constant and copy propagation. When a constant or copy
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1987 assignment is found, we map the value on the RHS of the assignment to
111
kono
parents: 67
diff changeset
1988 the variable in the LHS in the CONST_AND_COPIES table.
kono
parents: 67
diff changeset
1989
kono
parents: 67
diff changeset
1990 3- Very simple redundant store elimination is performed.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1991
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1992 4- We can simplify a condition to a constant or from a relational
111
kono
parents: 67
diff changeset
1993 condition to an equality condition. */
kono
parents: 67
diff changeset
1994
kono
parents: 67
diff changeset
1995 edge
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1996 dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator *si,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1997 bool *removed_p)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1998 {
111
kono
parents: 67
diff changeset
1999 gimple *stmt, *old_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2000 bool may_optimize_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2001 bool modified_p = false;
111
kono
parents: 67
diff changeset
2002 bool was_noreturn;
kono
parents: 67
diff changeset
2003 edge retval = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2004
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2005 old_stmt = stmt = gsi_stmt (*si);
111
kono
parents: 67
diff changeset
2006 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
2007
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2008 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2009 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2010 fprintf (dump_file, "Optimizing statement ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2011 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2012 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2013
111
kono
parents: 67
diff changeset
2014 update_stmt_if_modified (stmt);
kono
parents: 67
diff changeset
2015 opt_stats.num_stmts++;
kono
parents: 67
diff changeset
2016
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2017 /* Const/copy propagate into USES, VUSES and the RHS of VDEFs. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2018 cprop_into_stmt (stmt, evrp_range_analyzer.get_vr_values ());
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 the statement has been modified with constant replacements,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2021 fold its RHS before checking for redundant computations. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2022 if (gimple_modified_p (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 tree rhs = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2025
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2026 /* 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
2027 up to date. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2028 if (fold_stmt (si))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2029 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2030 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
2031 gimple_set_modified (stmt, true);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2032
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2033 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2034 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2035 fprintf (dump_file, " Folded to: ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2036 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2037 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2038 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2039
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2040 /* 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
2041 if (gimple_assign_single_p (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2042 rhs = gimple_assign_rhs1 (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2043 else if (gimple_code (stmt) == GIMPLE_GOTO)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2044 rhs = gimple_goto_dest (stmt);
111
kono
parents: 67
diff changeset
2045 else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2046 /* This should never be an ADDR_EXPR. */
111
kono
parents: 67
diff changeset
2047 rhs = gimple_switch_index (swtch_stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2048
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2049 if (rhs && TREE_CODE (rhs) == ADDR_EXPR)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2050 recompute_tree_invariant_for_addr_expr (rhs);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2051
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2052 /* 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
2053 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
2054 gimple_modified_p flag on it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2055 modified_p = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2056 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2057
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2058 /* Check for redundant computations. Do this optimization only
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2059 for assignments that have no volatile ops and conditionals. */
111
kono
parents: 67
diff changeset
2060 may_optimize_p = (!gimple_has_side_effects (stmt)
kono
parents: 67
diff changeset
2061 && (is_gimple_assign (stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2062 || (is_gimple_call (stmt)
111
kono
parents: 67
diff changeset
2063 && gimple_call_lhs (stmt) != NULL_TREE)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2064 || gimple_code (stmt) == GIMPLE_COND
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2065 || gimple_code (stmt) == GIMPLE_SWITCH));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2066
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2067 if (may_optimize_p)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2068 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2069 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
2070 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2071 /* 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
2072 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
2073 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
2074 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
2075 if (callee
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2076 && fndecl_built_in_p (callee, BUILT_IN_CONSTANT_P))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2077 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2078 propagate_tree_value_into_stmt (si, integer_zero_node);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2079 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
2080 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2081 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2082
111
kono
parents: 67
diff changeset
2083 if (gimple_code (stmt) == GIMPLE_COND)
kono
parents: 67
diff changeset
2084 {
kono
parents: 67
diff changeset
2085 tree lhs = gimple_cond_lhs (stmt);
kono
parents: 67
diff changeset
2086 tree rhs = gimple_cond_rhs (stmt);
kono
parents: 67
diff changeset
2087
kono
parents: 67
diff changeset
2088 /* If the LHS has a range [0..1] and the RHS has a range ~[0..1],
kono
parents: 67
diff changeset
2089 then this conditional is computable at compile time. We can just
kono
parents: 67
diff changeset
2090 shove either 0 or 1 into the LHS, mark the statement as modified
kono
parents: 67
diff changeset
2091 and all the right things will just happen below.
kono
parents: 67
diff changeset
2092
kono
parents: 67
diff changeset
2093 Note this would apply to any case where LHS has a range
kono
parents: 67
diff changeset
2094 narrower than its type implies and RHS is outside that
kono
parents: 67
diff changeset
2095 narrower range. Future work. */
kono
parents: 67
diff changeset
2096 if (TREE_CODE (lhs) == SSA_NAME
kono
parents: 67
diff changeset
2097 && ssa_name_has_boolean_range (lhs)
kono
parents: 67
diff changeset
2098 && TREE_CODE (rhs) == INTEGER_CST
kono
parents: 67
diff changeset
2099 && ! (integer_zerop (rhs) || integer_onep (rhs)))
kono
parents: 67
diff changeset
2100 {
kono
parents: 67
diff changeset
2101 gimple_cond_set_lhs (as_a <gcond *> (stmt),
kono
parents: 67
diff changeset
2102 fold_convert (TREE_TYPE (lhs),
kono
parents: 67
diff changeset
2103 integer_zero_node));
kono
parents: 67
diff changeset
2104 gimple_set_modified (stmt, true);
kono
parents: 67
diff changeset
2105 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2106 else if (TREE_CODE (lhs) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2107 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2108 /* Exploiting EVRP data is not yet fully integrated into DOM
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2109 but we need to do something for this case to avoid regressing
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2110 udr4.f90 and new1.C which have unexecutable blocks with
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2111 undefined behavior that get diagnosed if they're left in the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2112 IL because we've attached range information to new
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2113 SSA_NAMES. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2114 update_stmt_if_modified (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2115 edge taken_edge = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2116 evrp_range_analyzer.vrp_visit_cond_stmt (as_a <gcond *> (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2117 &taken_edge);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2118 if (taken_edge)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2119 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2120 if (taken_edge->flags & EDGE_TRUE_VALUE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2121 gimple_cond_make_true (as_a <gcond *> (stmt));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2122 else if (taken_edge->flags & EDGE_FALSE_VALUE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2123 gimple_cond_make_false (as_a <gcond *> (stmt));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2124 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2125 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2126 gimple_set_modified (stmt, true);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2127 update_stmt (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2128 cfg_altered = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2129 return taken_edge;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2130 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2131 }
111
kono
parents: 67
diff changeset
2132 }
kono
parents: 67
diff changeset
2133
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2134 update_stmt_if_modified (stmt);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2135 eliminate_redundant_computations (si, m_const_and_copies,
111
kono
parents: 67
diff changeset
2136 m_avail_exprs_stack);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2137 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
2138
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
2139 /* 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
2140 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
2141 && 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
2142 {
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
2143 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
2144 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
2145 tree cached_lhs;
111
kono
parents: 67
diff changeset
2146 gassign *new_stmt;
kono
parents: 67
diff changeset
2147 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
2148 /* 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
2149 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
2150 {
111
kono
parents: 67
diff changeset
2151 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
2152 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
2153 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
2154 }
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
2155 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
2156 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
2157 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
111
kono
parents: 67
diff changeset
2158 cached_lhs = m_avail_exprs_stack->lookup_avail_expr (new_stmt, false,
kono
parents: 67
diff changeset
2159 false);
kono
parents: 67
diff changeset
2160 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
2161 {
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
2162 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
2163 unlink_stmt_vdef (stmt);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2164 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
2165 {
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
2166 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
2167 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
2168 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
2169 }
111
kono
parents: 67
diff changeset
2170 release_defs (stmt);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2171 *removed_p = true;
111
kono
parents: 67
diff changeset
2172 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
2173 }
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
2174 }
111
kono
parents: 67
diff changeset
2175
kono
parents: 67
diff changeset
2176 /* If this statement was not redundant, we may still be able to simplify
kono
parents: 67
diff changeset
2177 it, which may in turn allow other part of DOM or other passes to do
kono
parents: 67
diff changeset
2178 a better job. */
kono
parents: 67
diff changeset
2179 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
2180 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2181
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2182 /* Record any additional equivalences created by this statement. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2183 if (is_gimple_assign (stmt))
111
kono
parents: 67
diff changeset
2184 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
2185
111
kono
parents: 67
diff changeset
2186 /* If STMT is a COND_EXPR or SWITCH_EXPR and it was modified, then we may
kono
parents: 67
diff changeset
2187 know where it goes. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2188 if (gimple_modified_p (stmt) || modified_p)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2189 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2190 tree val = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2191
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2192 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
2193 val = fold_binary_loc (gimple_location (stmt),
111
kono
parents: 67
diff changeset
2194 gimple_cond_code (stmt), boolean_type_node,
kono
parents: 67
diff changeset
2195 gimple_cond_lhs (stmt),
kono
parents: 67
diff changeset
2196 gimple_cond_rhs (stmt));
kono
parents: 67
diff changeset
2197 else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
kono
parents: 67
diff changeset
2198 val = gimple_switch_index (swtch_stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2199
111
kono
parents: 67
diff changeset
2200 if (val && TREE_CODE (val) == INTEGER_CST)
kono
parents: 67
diff changeset
2201 {
kono
parents: 67
diff changeset
2202 retval = find_taken_edge (bb, val);
kono
parents: 67
diff changeset
2203 if (retval)
kono
parents: 67
diff changeset
2204 {
kono
parents: 67
diff changeset
2205 /* Fix the condition to be either true or false. */
kono
parents: 67
diff changeset
2206 if (gimple_code (stmt) == GIMPLE_COND)
kono
parents: 67
diff changeset
2207 {
kono
parents: 67
diff changeset
2208 if (integer_zerop (val))
kono
parents: 67
diff changeset
2209 gimple_cond_make_false (as_a <gcond *> (stmt));
kono
parents: 67
diff changeset
2210 else if (integer_onep (val))
kono
parents: 67
diff changeset
2211 gimple_cond_make_true (as_a <gcond *> (stmt));
kono
parents: 67
diff changeset
2212 else
kono
parents: 67
diff changeset
2213 gcc_unreachable ();
kono
parents: 67
diff changeset
2214
kono
parents: 67
diff changeset
2215 gimple_set_modified (stmt, true);
kono
parents: 67
diff changeset
2216 }
kono
parents: 67
diff changeset
2217
kono
parents: 67
diff changeset
2218 /* Further simplifications may be possible. */
kono
parents: 67
diff changeset
2219 cfg_altered = true;
kono
parents: 67
diff changeset
2220 }
kono
parents: 67
diff changeset
2221 }
kono
parents: 67
diff changeset
2222
kono
parents: 67
diff changeset
2223 update_stmt_if_modified (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2224
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2225 /* 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
2226 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
2227 if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2228 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2229 bitmap_set_bit (need_eh_cleanup, bb->index);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2230 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2231 fprintf (dump_file, " Flagged to clear EH edges.\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2232 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2233
111
kono
parents: 67
diff changeset
2234 if (!was_noreturn
kono
parents: 67
diff changeset
2235 && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
kono
parents: 67
diff changeset
2236 need_noreturn_fixup.safe_push (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2237 }
111
kono
parents: 67
diff changeset
2238 return retval;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2239 }