Mercurial > hg > CbC > CbC_gcc
annotate gcc/tree-ssa-ccp.c @ 117:f81c5aa9f14f
fix
author | mir3636 |
---|---|
date | Tue, 28 Nov 2017 21:17:15 +0900 |
parents | 04ced10e8804 |
children | 84e7813d76e9 |
rev | line source |
---|---|
0 | 1 /* Conditional constant propagation pass for the GNU compiler. |
111 | 2 Copyright (C) 2000-2017 Free Software Foundation, Inc. |
0 | 3 Adapted from original RTL SSA-CCP by Daniel Berlin <dberlin@dberlin.org> |
4 Adapted to GIMPLE trees by Diego Novillo <dnovillo@redhat.com> | |
5 | |
6 This file is part of GCC. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
7 |
0 | 8 GCC is free software; you can redistribute it and/or modify it |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 3, or (at your option) any | |
11 later version. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
12 |
0 | 13 GCC is distributed in the hope that it will be useful, but WITHOUT |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
17 |
0 | 18 You should have received a copy of the GNU General Public License |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 /* Conditional constant propagation (CCP) is based on the SSA | |
23 propagation engine (tree-ssa-propagate.c). Constant assignments of | |
24 the form VAR = CST are propagated from the assignments into uses of | |
25 VAR, which in turn may generate new constants. The simulation uses | |
26 a four level lattice to keep track of constant values associated | |
27 with SSA names. Given an SSA name V_i, it may take one of the | |
28 following values: | |
29 | |
30 UNINITIALIZED -> the initial state of the value. This value | |
31 is replaced with a correct initial value | |
32 the first time the value is used, so the | |
33 rest of the pass does not need to care about | |
34 it. Using this value simplifies initialization | |
35 of the pass, and prevents us from needlessly | |
36 scanning statements that are never reached. | |
37 | |
38 UNDEFINED -> V_i is a local variable whose definition | |
39 has not been processed yet. Therefore we | |
40 don't yet know if its value is a constant | |
41 or not. | |
42 | |
43 CONSTANT -> V_i has been found to hold a constant | |
44 value C. | |
45 | |
46 VARYING -> V_i cannot take a constant value, or if it | |
47 does, it is not possible to determine it | |
48 at compile time. | |
49 | |
50 The core of SSA-CCP is in ccp_visit_stmt and ccp_visit_phi_node: | |
51 | |
52 1- In ccp_visit_stmt, we are interested in assignments whose RHS | |
53 evaluates into a constant and conditional jumps whose predicate | |
54 evaluates into a boolean true or false. When an assignment of | |
55 the form V_i = CONST is found, V_i's lattice value is set to | |
56 CONSTANT and CONST is associated with it. This causes the | |
57 propagation engine to add all the SSA edges coming out the | |
58 assignment into the worklists, so that statements that use V_i | |
59 can be visited. | |
60 | |
61 If the statement is a conditional with a constant predicate, we | |
62 mark the outgoing edges as executable or not executable | |
63 depending on the predicate's value. This is then used when | |
64 visiting PHI nodes to know when a PHI argument can be ignored. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
65 |
0 | 66 |
67 2- In ccp_visit_phi_node, if all the PHI arguments evaluate to the | |
68 same constant C, then the LHS of the PHI is set to C. This | |
69 evaluation is known as the "meet operation". Since one of the | |
70 goals of this evaluation is to optimistically return constant | |
71 values as often as possible, it uses two main short cuts: | |
72 | |
73 - If an argument is flowing in through a non-executable edge, it | |
74 is ignored. This is useful in cases like this: | |
75 | |
76 if (PRED) | |
77 a_9 = 3; | |
78 else | |
79 a_10 = 100; | |
80 a_11 = PHI (a_9, a_10) | |
81 | |
82 If PRED is known to always evaluate to false, then we can | |
83 assume that a_11 will always take its value from a_10, meaning | |
84 that instead of consider it VARYING (a_9 and a_10 have | |
85 different values), we can consider it CONSTANT 100. | |
86 | |
87 - If an argument has an UNDEFINED value, then it does not affect | |
88 the outcome of the meet operation. If a variable V_i has an | |
89 UNDEFINED value, it means that either its defining statement | |
90 hasn't been visited yet or V_i has no defining statement, in | |
91 which case the original symbol 'V' is being used | |
92 uninitialized. Since 'V' is a local variable, the compiler | |
93 may assume any initial value for it. | |
94 | |
95 | |
96 After propagation, every variable V_i that ends up with a lattice | |
97 value of CONSTANT will have the associated constant value in the | |
98 array CONST_VAL[i].VALUE. That is fed into substitute_and_fold for | |
99 final substitution and folding. | |
100 | |
111 | 101 This algorithm uses wide-ints at the max precision of the target. |
102 This means that, with one uninteresting exception, variables with | |
103 UNSIGNED types never go to VARYING because the bits above the | |
104 precision of the type of the variable are always zero. The | |
105 uninteresting case is a variable of UNSIGNED type that has the | |
106 maximum precision of the target. Such variables can go to VARYING, | |
107 but this causes no loss of infomation since these variables will | |
108 never be extended. | |
109 | |
0 | 110 References: |
111 | |
112 Constant propagation with conditional branches, | |
113 Wegman and Zadeck, ACM TOPLAS 13(2):181-210. | |
114 | |
115 Building an Optimizing Compiler, | |
116 Robert Morgan, Butterworth-Heinemann, 1998, Section 8.9. | |
117 | |
118 Advanced Compiler Design and Implementation, | |
119 Steven Muchnick, Morgan Kaufmann, 1997, Section 12.6 */ | |
120 | |
121 #include "config.h" | |
122 #include "system.h" | |
123 #include "coretypes.h" | |
111 | 124 #include "backend.h" |
125 #include "target.h" | |
0 | 126 #include "tree.h" |
111 | 127 #include "gimple.h" |
128 #include "tree-pass.h" | |
129 #include "ssa.h" | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
130 #include "gimple-pretty-print.h" |
111 | 131 #include "fold-const.h" |
132 #include "gimple-fold.h" | |
133 #include "tree-eh.h" | |
134 #include "gimplify.h" | |
135 #include "gimple-iterator.h" | |
136 #include "tree-cfg.h" | |
0 | 137 #include "tree-ssa-propagate.h" |
111 | 138 #include "dbgcnt.h" |
139 #include "params.h" | |
140 #include "builtins.h" | |
141 #include "tree-chkp.h" | |
142 #include "cfgloop.h" | |
143 #include "stor-layout.h" | |
144 #include "optabs-query.h" | |
145 #include "tree-ssa-ccp.h" | |
146 #include "tree-dfa.h" | |
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
|
147 #include "diagnostic-core.h" |
111 | 148 #include "stringpool.h" |
149 #include "attribs.h" | |
0 | 150 |
151 /* Possible lattice values. */ | |
152 typedef enum | |
153 { | |
154 UNINITIALIZED, | |
155 UNDEFINED, | |
156 CONSTANT, | |
157 VARYING | |
158 } ccp_lattice_t; | |
159 | |
111 | 160 struct ccp_prop_value_t { |
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
|
161 /* Lattice value. */ |
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
|
162 ccp_lattice_t lattice_val; |
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
|
163 |
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
|
164 /* Propagated value. */ |
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
|
165 tree value; |
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
|
166 |
111 | 167 /* Mask that applies to the propagated value during CCP. For X |
168 with a CONSTANT lattice value X & ~mask == value & ~mask. The | |
169 zero bits in the mask cover constant values. The ones mean no | |
170 information. */ | |
171 widest_int mask; | |
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
|
172 }; |
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
|
173 |
0 | 174 /* Array of propagated constant values. After propagation, |
175 CONST_VAL[I].VALUE holds the constant value for SSA_NAME(I). If | |
176 the constant is held in an SSA name representing a memory store | |
177 (i.e., a VDEF), CONST_VAL[I].MEM_REF will contain the actual | |
178 memory reference used to store (i.e., the LHS of the assignment | |
179 doing the store). */ | |
111 | 180 static ccp_prop_value_t *const_val; |
181 static unsigned n_const_val; | |
182 | |
183 static void canonicalize_value (ccp_prop_value_t *); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
184 static bool ccp_fold_stmt (gimple_stmt_iterator *); |
111 | 185 static void ccp_lattice_meet (ccp_prop_value_t *, ccp_prop_value_t *); |
0 | 186 |
187 /* Dump constant propagation value VAL to file OUTF prefixed by PREFIX. */ | |
188 | |
189 static void | |
111 | 190 dump_lattice_value (FILE *outf, const char *prefix, ccp_prop_value_t val) |
0 | 191 { |
192 switch (val.lattice_val) | |
193 { | |
194 case UNINITIALIZED: | |
195 fprintf (outf, "%sUNINITIALIZED", prefix); | |
196 break; | |
197 case UNDEFINED: | |
198 fprintf (outf, "%sUNDEFINED", prefix); | |
199 break; | |
200 case VARYING: | |
201 fprintf (outf, "%sVARYING", prefix); | |
202 break; | |
203 case CONSTANT: | |
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
|
204 if (TREE_CODE (val.value) != INTEGER_CST |
111 | 205 || val.mask == 0) |
206 { | |
207 fprintf (outf, "%sCONSTANT ", prefix); | |
208 print_generic_expr (outf, val.value, dump_flags); | |
209 } | |
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
|
210 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
|
211 { |
111 | 212 widest_int cval = wi::bit_and_not (wi::to_widest (val.value), |
213 val.mask); | |
214 fprintf (outf, "%sCONSTANT ", prefix); | |
215 print_hex (cval, outf); | |
216 fprintf (outf, " ("); | |
217 print_hex (val.mask, outf); | |
218 fprintf (outf, ")"); | |
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
|
219 } |
0 | 220 break; |
221 default: | |
222 gcc_unreachable (); | |
223 } | |
224 } | |
225 | |
226 | |
227 /* Print lattice value VAL to stderr. */ | |
228 | |
111 | 229 void debug_lattice_value (ccp_prop_value_t val); |
0 | 230 |
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
|
231 DEBUG_FUNCTION void |
111 | 232 debug_lattice_value (ccp_prop_value_t val) |
0 | 233 { |
234 dump_lattice_value (stderr, "", val); | |
235 fprintf (stderr, "\n"); | |
236 } | |
237 | |
111 | 238 /* Extend NONZERO_BITS to a full mask, based on sgn. */ |
239 | |
240 static widest_int | |
241 extend_mask (const wide_int &nonzero_bits, signop sgn) | |
242 { | |
243 return widest_int::from (nonzero_bits, sgn); | |
244 } | |
0 | 245 |
246 /* Compute a default value for variable VAR and store it in the | |
247 CONST_VAL array. The following rules are used to get default | |
248 values: | |
249 | |
250 1- Global and static variables that are declared constant are | |
251 considered CONSTANT. | |
252 | |
253 2- Any other value is considered UNDEFINED. This is useful when | |
254 considering PHI nodes. PHI arguments that are undefined do not | |
255 change the constant value of the PHI node, which allows for more | |
256 constants to be propagated. | |
257 | |
258 3- Variables defined by statements other than assignments and PHI | |
259 nodes are considered VARYING. | |
260 | |
261 4- Initial values of variables that are not GIMPLE registers are | |
262 considered VARYING. */ | |
263 | |
111 | 264 static ccp_prop_value_t |
0 | 265 get_default_value (tree var) |
266 { | |
111 | 267 ccp_prop_value_t val = { UNINITIALIZED, NULL_TREE, 0 }; |
268 gimple *stmt; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
269 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
270 stmt = SSA_NAME_DEF_STMT (var); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
271 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
272 if (gimple_nop_p (stmt)) |
0 | 273 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
274 /* Variables defined by an empty statement are those used |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
275 before being initialized. If VAR is a local variable, we |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
276 can assume initially that it is UNDEFINED, otherwise we must |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
277 consider it VARYING. */ |
111 | 278 if (!virtual_operand_p (var) |
279 && SSA_NAME_VAR (var) | |
280 && TREE_CODE (SSA_NAME_VAR (var)) == VAR_DECL) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
281 val.lattice_val = UNDEFINED; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
282 else |
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
|
283 { |
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
|
284 val.lattice_val = VARYING; |
111 | 285 val.mask = -1; |
286 if (flag_tree_bit_ccp) | |
287 { | |
288 wide_int nonzero_bits = get_nonzero_bits (var); | |
289 if (nonzero_bits != -1) | |
290 { | |
291 val.lattice_val = CONSTANT; | |
292 val.value = build_zero_cst (TREE_TYPE (var)); | |
293 val.mask = extend_mask (nonzero_bits, TYPE_SIGN (TREE_TYPE (var))); | |
294 } | |
295 } | |
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
|
296 } |
0 | 297 } |
111 | 298 else if (is_gimple_assign (stmt)) |
0 | 299 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
300 tree cst; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
301 if (gimple_assign_single_p (stmt) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
302 && DECL_P (gimple_assign_rhs1 (stmt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
303 && (cst = get_symbol_constant_value (gimple_assign_rhs1 (stmt)))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
304 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
305 val.lattice_val = CONSTANT; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
306 val.value = cst; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
307 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
308 else |
111 | 309 { |
310 /* Any other variable defined by an assignment is considered | |
311 UNDEFINED. */ | |
312 val.lattice_val = UNDEFINED; | |
313 } | |
314 } | |
315 else if ((is_gimple_call (stmt) | |
316 && gimple_call_lhs (stmt) != NULL_TREE) | |
317 || gimple_code (stmt) == GIMPLE_PHI) | |
318 { | |
319 /* A variable defined by a call or a PHI node is considered | |
320 UNDEFINED. */ | |
321 val.lattice_val = UNDEFINED; | |
0 | 322 } |
323 else | |
324 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
325 /* Otherwise, VAR will never take on a constant value. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
326 val.lattice_val = VARYING; |
111 | 327 val.mask = -1; |
0 | 328 } |
329 | |
330 return val; | |
331 } | |
332 | |
333 | |
334 /* Get the constant value associated with variable VAR. */ | |
335 | |
111 | 336 static inline ccp_prop_value_t * |
0 | 337 get_value (tree var) |
338 { | |
111 | 339 ccp_prop_value_t *val; |
340 | |
341 if (const_val == NULL | |
342 || SSA_NAME_VERSION (var) >= n_const_val) | |
0 | 343 return NULL; |
344 | |
345 val = &const_val[SSA_NAME_VERSION (var)]; | |
346 if (val->lattice_val == UNINITIALIZED) | |
347 *val = get_default_value (var); | |
348 | |
111 | 349 canonicalize_value (val); |
0 | 350 |
351 return val; | |
352 } | |
353 | |
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
|
354 /* Return the constant tree value associated with VAR. */ |
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
|
355 |
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
|
356 static inline tree |
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
|
357 get_constant_value (tree var) |
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
|
358 { |
111 | 359 ccp_prop_value_t *val; |
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
|
360 if (TREE_CODE (var) != 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
|
361 { |
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
|
362 if (is_gimple_min_invariant (var)) |
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
|
363 return var; |
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
|
364 return NULL_TREE; |
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
|
365 } |
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
|
366 val = get_value (var); |
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
|
367 if (val |
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
|
368 && val->lattice_val == CONSTANT |
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
|
369 && (TREE_CODE (val->value) != INTEGER_CST |
111 | 370 || val->mask == 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
|
371 return val->value; |
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
|
372 return NULL_TREE; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
373 } |
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
|
374 |
0 | 375 /* Sets the value associated with VAR to VARYING. */ |
376 | |
377 static inline void | |
378 set_value_varying (tree var) | |
379 { | |
111 | 380 ccp_prop_value_t *val = &const_val[SSA_NAME_VERSION (var)]; |
0 | 381 |
382 val->lattice_val = VARYING; | |
383 val->value = NULL_TREE; | |
111 | 384 val->mask = -1; |
0 | 385 } |
386 | |
111 | 387 /* For integer constants, make sure to drop TREE_OVERFLOW. */ |
0 | 388 |
389 static void | |
111 | 390 canonicalize_value (ccp_prop_value_t *val) |
0 | 391 { |
111 | 392 if (val->lattice_val != CONSTANT) |
0 | 393 return; |
394 | |
111 | 395 if (TREE_OVERFLOW_P (val->value)) |
396 val->value = drop_tree_overflow (val->value); | |
0 | 397 } |
398 | |
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
|
399 /* Return whether the lattice transition is valid. */ |
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
|
400 |
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
|
401 static bool |
111 | 402 valid_lattice_transition (ccp_prop_value_t old_val, ccp_prop_value_t new_val) |
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
|
403 { |
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
|
404 /* Lattice transitions must always be monotonically increasing in |
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
|
405 value. */ |
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
|
406 if (old_val.lattice_val < new_val.lattice_val) |
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
|
407 return true; |
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
|
408 |
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
|
409 if (old_val.lattice_val != new_val.lattice_val) |
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
|
410 return false; |
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
|
411 |
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
|
412 if (!old_val.value && !new_val.value) |
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
|
413 return true; |
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
|
414 |
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
|
415 /* Now both lattice values are CONSTANT. */ |
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
|
416 |
111 | 417 /* Allow arbitrary copy changes as we might look through PHI <a_1, ...> |
418 when only a single copy edge is executable. */ | |
419 if (TREE_CODE (old_val.value) == SSA_NAME | |
420 && TREE_CODE (new_val.value) == SSA_NAME) | |
421 return true; | |
422 | |
423 /* Allow transitioning from a constant to a copy. */ | |
424 if (is_gimple_min_invariant (old_val.value) | |
425 && TREE_CODE (new_val.value) == SSA_NAME) | |
426 return true; | |
427 | |
428 /* Allow transitioning from PHI <&x, not executable> == &x | |
429 to PHI <&x, &y> == common alignment. */ | |
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
|
430 if (TREE_CODE (old_val.value) != INTEGER_CST |
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
|
431 && TREE_CODE (new_val.value) == INTEGER_CST) |
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
|
432 return true; |
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
|
433 |
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
|
434 /* Bit-lattices have to agree in the still valid bits. */ |
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
|
435 if (TREE_CODE (old_val.value) == INTEGER_CST |
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
|
436 && TREE_CODE (new_val.value) == INTEGER_CST) |
111 | 437 return (wi::bit_and_not (wi::to_widest (old_val.value), new_val.mask) |
438 == wi::bit_and_not (wi::to_widest (new_val.value), new_val.mask)); | |
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
|
439 |
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
|
440 /* Otherwise constant values have to agree. */ |
111 | 441 if (operand_equal_p (old_val.value, new_val.value, 0)) |
442 return true; | |
443 | |
444 /* At least the kinds and types should agree now. */ | |
445 if (TREE_CODE (old_val.value) != TREE_CODE (new_val.value) | |
446 || !types_compatible_p (TREE_TYPE (old_val.value), | |
447 TREE_TYPE (new_val.value))) | |
448 return false; | |
449 | |
450 /* For floats and !HONOR_NANS allow transitions from (partial) NaN | |
451 to non-NaN. */ | |
452 tree type = TREE_TYPE (new_val.value); | |
453 if (SCALAR_FLOAT_TYPE_P (type) | |
454 && !HONOR_NANS (type)) | |
455 { | |
456 if (REAL_VALUE_ISNAN (TREE_REAL_CST (old_val.value))) | |
457 return true; | |
458 } | |
459 else if (VECTOR_FLOAT_TYPE_P (type) | |
460 && !HONOR_NANS (type)) | |
461 { | |
462 for (unsigned i = 0; i < VECTOR_CST_NELTS (old_val.value); ++i) | |
463 if (!REAL_VALUE_ISNAN | |
464 (TREE_REAL_CST (VECTOR_CST_ELT (old_val.value, i))) | |
465 && !operand_equal_p (VECTOR_CST_ELT (old_val.value, i), | |
466 VECTOR_CST_ELT (new_val.value, i), 0)) | |
467 return false; | |
468 return true; | |
469 } | |
470 else if (COMPLEX_FLOAT_TYPE_P (type) | |
471 && !HONOR_NANS (type)) | |
472 { | |
473 if (!REAL_VALUE_ISNAN (TREE_REAL_CST (TREE_REALPART (old_val.value))) | |
474 && !operand_equal_p (TREE_REALPART (old_val.value), | |
475 TREE_REALPART (new_val.value), 0)) | |
476 return false; | |
477 if (!REAL_VALUE_ISNAN (TREE_REAL_CST (TREE_IMAGPART (old_val.value))) | |
478 && !operand_equal_p (TREE_IMAGPART (old_val.value), | |
479 TREE_IMAGPART (new_val.value), 0)) | |
480 return false; | |
481 return true; | |
482 } | |
483 return false; | |
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
|
484 } |
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
|
485 |
0 | 486 /* Set the value for variable VAR to NEW_VAL. Return true if the new |
487 value is different from VAR's previous value. */ | |
488 | |
489 static bool | |
111 | 490 set_lattice_value (tree var, ccp_prop_value_t *new_val) |
0 | 491 { |
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
|
492 /* We can deal with old UNINITIALIZED values just fine here. */ |
111 | 493 ccp_prop_value_t *old_val = &const_val[SSA_NAME_VERSION (var)]; |
494 | |
495 canonicalize_value (new_val); | |
0 | 496 |
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
|
497 /* We have to be careful to not go up the bitwise lattice |
111 | 498 represented by the mask. Instead of dropping to VARYING |
499 use the meet operator to retain a conservative value. | |
500 Missed optimizations like PR65851 makes this necessary. | |
501 It also ensures we converge to a stable lattice solution. */ | |
502 if (old_val->lattice_val != UNINITIALIZED) | |
503 ccp_lattice_meet (new_val, old_val); | |
504 | |
505 gcc_checking_assert (valid_lattice_transition (*old_val, *new_val)); | |
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
|
506 |
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
|
507 /* If *OLD_VAL and NEW_VAL are the same, return false to inform the |
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
|
508 caller that this was a non-transition. */ |
111 | 509 if (old_val->lattice_val != new_val->lattice_val |
510 || (new_val->lattice_val == CONSTANT | |
511 && (TREE_CODE (new_val->value) != TREE_CODE (old_val->value) | |
512 || (TREE_CODE (new_val->value) == INTEGER_CST | |
513 && (new_val->mask != old_val->mask | |
514 || (wi::bit_and_not (wi::to_widest (old_val->value), | |
515 new_val->mask) | |
516 != wi::bit_and_not (wi::to_widest (new_val->value), | |
517 new_val->mask)))) | |
518 || (TREE_CODE (new_val->value) != INTEGER_CST | |
519 && !operand_equal_p (new_val->value, old_val->value, 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
|
520 { |
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
|
521 /* ??? We would like to delay creation of INTEGER_CSTs from |
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
|
522 partially constants here. */ |
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
|
523 |
0 | 524 if (dump_file && (dump_flags & TDF_DETAILS)) |
525 { | |
111 | 526 dump_lattice_value (dump_file, "Lattice value changed to ", *new_val); |
0 | 527 fprintf (dump_file, ". Adding SSA edges to worklist.\n"); |
528 } | |
529 | |
111 | 530 *old_val = *new_val; |
531 | |
532 gcc_assert (new_val->lattice_val != UNINITIALIZED); | |
0 | 533 return true; |
534 } | |
535 | |
536 return false; | |
537 } | |
538 | |
111 | 539 static ccp_prop_value_t get_value_for_expr (tree, bool); |
540 static ccp_prop_value_t bit_value_binop (enum tree_code, tree, tree, tree); | |
541 void bit_value_binop (enum tree_code, signop, int, widest_int *, widest_int *, | |
542 signop, int, const widest_int &, const widest_int &, | |
543 signop, int, const widest_int &, const widest_int &); | |
544 | |
545 /* Return a widest_int that can be used for bitwise simplifications | |
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
|
546 from VAL. */ |
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
|
547 |
111 | 548 static widest_int |
549 value_to_wide_int (ccp_prop_value_t val) | |
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
|
550 { |
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
|
551 if (val.value |
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
|
552 && TREE_CODE (val.value) == INTEGER_CST) |
111 | 553 return wi::to_widest (val.value); |
554 | |
555 return 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
|
556 } |
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
|
557 |
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
|
558 /* Return the value for the address expression EXPR based on alignment |
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
|
559 information. */ |
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
|
560 |
111 | 561 static ccp_prop_value_t |
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
|
562 get_value_from_alignment (tree expr) |
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
|
563 { |
111 | 564 tree type = TREE_TYPE (expr); |
565 ccp_prop_value_t val; | |
566 unsigned HOST_WIDE_INT bitpos; | |
567 unsigned int align; | |
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
|
568 |
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
|
569 gcc_assert (TREE_CODE (expr) == ADDR_EXPR); |
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
|
570 |
111 | 571 get_pointer_alignment_1 (expr, &align, &bitpos); |
572 val.mask = wi::bit_and_not | |
573 (POINTER_TYPE_P (type) || TYPE_UNSIGNED (type) | |
574 ? wi::mask <widest_int> (TYPE_PRECISION (type), false) | |
575 : -1, | |
576 align / BITS_PER_UNIT - 1); | |
577 val.lattice_val | |
578 = wi::sext (val.mask, TYPE_PRECISION (type)) == -1 ? VARYING : CONSTANT; | |
579 if (val.lattice_val == CONSTANT) | |
580 val.value = build_int_cstu (type, bitpos / BITS_PER_UNIT); | |
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
|
581 else |
111 | 582 val.value = NULL_TREE; |
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
|
583 |
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
|
584 return val; |
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
|
585 } |
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
|
586 |
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
|
587 /* Return the value for the tree operand EXPR. If FOR_BITS_P is true |
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
|
588 return constant bits extracted from alignment information for |
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
|
589 invariant addresses. */ |
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
|
590 |
111 | 591 static ccp_prop_value_t |
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
|
592 get_value_for_expr (tree expr, bool for_bits_p) |
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
|
593 { |
111 | 594 ccp_prop_value_t val; |
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
|
595 |
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
|
596 if (TREE_CODE (expr) == 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
|
597 { |
111 | 598 ccp_prop_value_t *val_ = get_value (expr); |
599 if (val_) | |
600 val = *val_; | |
601 else | |
602 { | |
603 val.lattice_val = VARYING; | |
604 val.value = NULL_TREE; | |
605 val.mask = -1; | |
606 } | |
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
|
607 if (for_bits_p |
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
|
608 && val.lattice_val == CONSTANT |
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
|
609 && TREE_CODE (val.value) == ADDR_EXPR) |
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
|
610 val = get_value_from_alignment (val.value); |
111 | 611 /* Fall back to a copy value. */ |
612 if (!for_bits_p | |
613 && val.lattice_val == VARYING | |
614 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (expr)) | |
615 { | |
616 val.lattice_val = CONSTANT; | |
617 val.value = expr; | |
618 val.mask = -1; | |
619 } | |
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
|
620 } |
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
|
621 else if (is_gimple_min_invariant (expr) |
111 | 622 && (!for_bits_p || TREE_CODE (expr) == INTEGER_CST)) |
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
|
623 { |
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
|
624 val.lattice_val = CONSTANT; |
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
|
625 val.value = expr; |
111 | 626 val.mask = 0; |
627 canonicalize_value (&val); | |
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
|
628 } |
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
|
629 else if (TREE_CODE (expr) == ADDR_EXPR) |
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
|
630 val = get_value_from_alignment (expr); |
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
|
631 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
|
632 { |
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
|
633 val.lattice_val = VARYING; |
111 | 634 val.mask = -1; |
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
|
635 val.value = NULL_TREE; |
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
|
636 } |
111 | 637 |
638 if (val.lattice_val == VARYING | |
639 && TYPE_UNSIGNED (TREE_TYPE (expr))) | |
640 val.mask = wi::zext (val.mask, TYPE_PRECISION (TREE_TYPE (expr))); | |
641 | |
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
|
642 return val; |
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
|
643 } |
0 | 644 |
645 /* Return the likely CCP lattice value for STMT. | |
646 | |
647 If STMT has no operands, then return CONSTANT. | |
648 | |
649 Else if undefinedness of operands of STMT cause its value to be | |
650 undefined, then return UNDEFINED. | |
651 | |
652 Else if any operands of STMT are constants, then return CONSTANT. | |
653 | |
654 Else return VARYING. */ | |
655 | |
656 static ccp_lattice_t | |
111 | 657 likely_value (gimple *stmt) |
0 | 658 { |
659 bool has_constant_operand, has_undefined_operand, all_undefined_operands; | |
111 | 660 bool has_nsa_operand; |
0 | 661 tree use; |
662 ssa_op_iter iter; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
663 unsigned i; |
0 | 664 |
665 enum gimple_code code = gimple_code (stmt); | |
666 | |
667 /* This function appears to be called only for assignments, calls, | |
668 conditionals, and switches, due to the logic in visit_stmt. */ | |
669 gcc_assert (code == GIMPLE_ASSIGN | |
670 || code == GIMPLE_CALL | |
671 || code == GIMPLE_COND | |
672 || code == GIMPLE_SWITCH); | |
673 | |
674 /* If the statement has volatile operands, it won't fold to a | |
675 constant value. */ | |
676 if (gimple_has_volatile_ops (stmt)) | |
677 return VARYING; | |
678 | |
679 /* Arrive here for more complex cases. */ | |
680 has_constant_operand = false; | |
681 has_undefined_operand = false; | |
682 all_undefined_operands = true; | |
111 | 683 has_nsa_operand = false; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
684 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) |
0 | 685 { |
111 | 686 ccp_prop_value_t *val = get_value (use); |
687 | |
688 if (val && val->lattice_val == UNDEFINED) | |
0 | 689 has_undefined_operand = true; |
690 else | |
691 all_undefined_operands = false; | |
692 | |
111 | 693 if (val && val->lattice_val == CONSTANT) |
0 | 694 has_constant_operand = true; |
111 | 695 |
696 if (SSA_NAME_IS_DEFAULT_DEF (use) | |
697 || !prop_simulate_again_p (SSA_NAME_DEF_STMT (use))) | |
698 has_nsa_operand = true; | |
0 | 699 } |
700 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
701 /* There may be constants in regular rhs operands. For calls we |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
702 have to ignore lhs, fndecl and static chain, otherwise only |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
703 the lhs. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
704 for (i = (is_gimple_call (stmt) ? 2 : 0) + gimple_has_lhs (stmt); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
705 i < gimple_num_ops (stmt); ++i) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
706 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
707 tree op = gimple_op (stmt, i); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
708 if (!op || TREE_CODE (op) == SSA_NAME) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
709 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
710 if (is_gimple_min_invariant (op)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
711 has_constant_operand = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
712 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
713 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
714 if (has_constant_operand) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
715 all_undefined_operands = false; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
716 |
111 | 717 if (has_undefined_operand |
718 && code == GIMPLE_CALL | |
719 && gimple_call_internal_p (stmt)) | |
720 switch (gimple_call_internal_fn (stmt)) | |
721 { | |
722 /* These 3 builtins use the first argument just as a magic | |
723 way how to find out a decl uid. */ | |
724 case IFN_GOMP_SIMD_LANE: | |
725 case IFN_GOMP_SIMD_VF: | |
726 case IFN_GOMP_SIMD_LAST_LANE: | |
727 has_undefined_operand = false; | |
728 break; | |
729 default: | |
730 break; | |
731 } | |
732 | |
0 | 733 /* If the operation combines operands like COMPLEX_EXPR make sure to |
734 not mark the result UNDEFINED if only one part of the result is | |
735 undefined. */ | |
736 if (has_undefined_operand && all_undefined_operands) | |
737 return UNDEFINED; | |
738 else if (code == GIMPLE_ASSIGN && has_undefined_operand) | |
739 { | |
740 switch (gimple_assign_rhs_code (stmt)) | |
741 { | |
742 /* Unary operators are handled with all_undefined_operands. */ | |
743 case PLUS_EXPR: | |
744 case MINUS_EXPR: | |
745 case POINTER_PLUS_EXPR: | |
111 | 746 case BIT_XOR_EXPR: |
0 | 747 /* Not MIN_EXPR, MAX_EXPR. One VARYING operand may be selected. |
748 Not bitwise operators, one VARYING operand may specify the | |
111 | 749 result completely. |
750 Not logical operators for the same reason, apart from XOR. | |
0 | 751 Not COMPLEX_EXPR as one VARYING operand makes the result partly |
752 not UNDEFINED. Not *DIV_EXPR, comparisons and shifts because | |
753 the undefined operand may be promoted. */ | |
754 return UNDEFINED; | |
755 | |
111 | 756 case ADDR_EXPR: |
757 /* If any part of an address is UNDEFINED, like the index | |
758 of an ARRAY_EXPR, then treat the result as UNDEFINED. */ | |
759 return UNDEFINED; | |
760 | |
0 | 761 default: |
762 ; | |
763 } | |
764 } | |
765 /* If there was an UNDEFINED operand but the result may be not UNDEFINED | |
111 | 766 fall back to CONSTANT. During iteration UNDEFINED may still drop |
767 to CONSTANT. */ | |
0 | 768 if (has_undefined_operand) |
111 | 769 return CONSTANT; |
0 | 770 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
771 /* We do not consider virtual operands here -- load from read-only |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
772 memory may have only VARYING virtual operands, but still be |
111 | 773 constant. Also we can combine the stmt with definitions from |
774 operands whose definitions are not simulated again. */ | |
0 | 775 if (has_constant_operand |
111 | 776 || has_nsa_operand |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
777 || gimple_references_memory_p (stmt)) |
0 | 778 return CONSTANT; |
779 | |
780 return VARYING; | |
781 } | |
782 | |
783 /* Returns true if STMT cannot be constant. */ | |
784 | |
785 static bool | |
111 | 786 surely_varying_stmt_p (gimple *stmt) |
0 | 787 { |
788 /* If the statement has operands that we cannot handle, it cannot be | |
789 constant. */ | |
790 if (gimple_has_volatile_ops (stmt)) | |
791 return true; | |
792 | |
793 /* If it is a call and does not return a value or is not a | |
111 | 794 builtin and not an indirect call or a call to function with |
795 assume_aligned/alloc_align attribute, it is varying. */ | |
0 | 796 if (is_gimple_call (stmt)) |
797 { | |
111 | 798 tree fndecl, fntype = gimple_call_fntype (stmt); |
0 | 799 if (!gimple_call_lhs (stmt) |
800 || ((fndecl = gimple_call_fndecl (stmt)) != NULL_TREE | |
111 | 801 && !DECL_BUILT_IN (fndecl) |
802 && !lookup_attribute ("assume_aligned", | |
803 TYPE_ATTRIBUTES (fntype)) | |
804 && !lookup_attribute ("alloc_align", | |
805 TYPE_ATTRIBUTES (fntype)))) | |
0 | 806 return true; |
807 } | |
808 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
809 /* Any other store operation is not interesting. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
810 else if (gimple_vdef (stmt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
811 return true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
812 |
0 | 813 /* Anything other than assignments and conditional jumps are not |
814 interesting for CCP. */ | |
815 if (gimple_code (stmt) != GIMPLE_ASSIGN | |
816 && gimple_code (stmt) != GIMPLE_COND | |
817 && gimple_code (stmt) != GIMPLE_SWITCH | |
818 && gimple_code (stmt) != GIMPLE_CALL) | |
819 return true; | |
820 | |
821 return false; | |
822 } | |
823 | |
824 /* Initialize local data structures for CCP. */ | |
825 | |
826 static void | |
827 ccp_initialize (void) | |
828 { | |
829 basic_block bb; | |
830 | |
111 | 831 n_const_val = num_ssa_names; |
832 const_val = XCNEWVEC (ccp_prop_value_t, n_const_val); | |
0 | 833 |
834 /* Initialize simulation flags for PHI nodes and statements. */ | |
111 | 835 FOR_EACH_BB_FN (bb, cfun) |
0 | 836 { |
837 gimple_stmt_iterator i; | |
838 | |
839 for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i)) | |
840 { | |
111 | 841 gimple *stmt = gsi_stmt (i); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
842 bool is_varying; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
843 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
844 /* If the statement is a control insn, then we do not |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
845 want to avoid simulating the statement once. Failure |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
846 to do so means that those edges will never get added. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
847 if (stmt_ends_bb_p (stmt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
848 is_varying = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
849 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
850 is_varying = surely_varying_stmt_p (stmt); |
0 | 851 |
852 if (is_varying) | |
853 { | |
854 tree def; | |
855 ssa_op_iter iter; | |
856 | |
857 /* If the statement will not produce a constant, mark | |
858 all its outputs VARYING. */ | |
859 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
860 set_value_varying (def); |
0 | 861 } |
862 prop_set_simulate_again (stmt, !is_varying); | |
863 } | |
864 } | |
865 | |
866 /* Now process PHI nodes. We never clear the simulate_again flag on | |
867 phi nodes, since we do not know which edges are executable yet, | |
868 except for phi nodes for virtual operands when we do not do store ccp. */ | |
111 | 869 FOR_EACH_BB_FN (bb, cfun) |
0 | 870 { |
111 | 871 gphi_iterator i; |
0 | 872 |
873 for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i)) | |
874 { | |
111 | 875 gphi *phi = i.phi (); |
876 | |
877 if (virtual_operand_p (gimple_phi_result (phi))) | |
0 | 878 prop_set_simulate_again (phi, false); |
879 else | |
880 prop_set_simulate_again (phi, true); | |
881 } | |
882 } | |
883 } | |
884 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
885 /* Debug count support. Reset the values of ssa names |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
886 VARYING when the total number ssa names analyzed is |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
887 beyond the debug count specified. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
888 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
889 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
890 do_dbg_cnt (void) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
891 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
892 unsigned i; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
893 for (i = 0; i < num_ssa_names; i++) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
894 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
895 if (!dbg_cnt (ccp)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
896 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
897 const_val[i].lattice_val = VARYING; |
111 | 898 const_val[i].mask = -1; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
899 const_val[i].value = NULL_TREE; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
900 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
901 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
902 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
903 |
0 | 904 |
905 /* Do final substitution of propagated values, cleanup the flowgraph and | |
111 | 906 free allocated storage. If NONZERO_P, record nonzero bits. |
0 | 907 |
908 Return TRUE when something was optimized. */ | |
909 | |
910 static bool | |
111 | 911 ccp_finalize (bool nonzero_p) |
0 | 912 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
913 bool something_changed; |
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
|
914 unsigned i; |
111 | 915 tree name; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
916 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
917 do_dbg_cnt (); |
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
|
918 |
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
|
919 /* Derive alignment and misalignment information from partially |
111 | 920 constant pointers in the lattice or nonzero bits from partially |
921 constant integers. */ | |
922 FOR_EACH_SSA_NAME (i, name, cfun) | |
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
|
923 { |
111 | 924 ccp_prop_value_t *val; |
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
|
925 unsigned int tem, align; |
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
|
926 |
111 | 927 if (!POINTER_TYPE_P (TREE_TYPE (name)) |
928 && (!INTEGRAL_TYPE_P (TREE_TYPE (name)) | |
929 /* Don't record nonzero bits before IPA to avoid | |
930 using too much memory. */ | |
931 || !nonzero_p)) | |
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
|
932 continue; |
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
|
933 |
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
|
934 val = get_value (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
|
935 if (val->lattice_val != CONSTANT |
111 | 936 || TREE_CODE (val->value) != INTEGER_CST |
937 || val->mask == 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
|
938 continue; |
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
|
939 |
111 | 940 if (POINTER_TYPE_P (TREE_TYPE (name))) |
941 { | |
942 /* Trailing mask bits specify the alignment, trailing value | |
943 bits the misalignment. */ | |
944 tem = val->mask.to_uhwi (); | |
945 align = least_bit_hwi (tem); | |
946 if (align > 1) | |
947 set_ptr_info_alignment (get_ptr_info (name), align, | |
948 (TREE_INT_CST_LOW (val->value) | |
949 & (align - 1))); | |
950 } | |
951 else | |
952 { | |
953 unsigned int precision = TYPE_PRECISION (TREE_TYPE (val->value)); | |
954 wide_int nonzero_bits | |
955 = (wide_int::from (val->mask, precision, UNSIGNED) | |
956 | wi::to_wide (val->value)); | |
957 nonzero_bits &= get_nonzero_bits (name); | |
958 set_nonzero_bits (name, nonzero_bits); | |
959 } | |
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
|
960 } |
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
|
961 |
0 | 962 /* Perform substitutions based on the known constant values. */ |
111 | 963 something_changed = substitute_and_fold (get_constant_value, ccp_fold_stmt); |
0 | 964 |
965 free (const_val); | |
966 const_val = NULL; | |
967 return something_changed;; | |
968 } | |
969 | |
970 | |
971 /* Compute the meet operator between *VAL1 and *VAL2. Store the result | |
972 in VAL1. | |
973 | |
974 any M UNDEFINED = any | |
975 any M VARYING = VARYING | |
976 Ci M Cj = Ci if (i == j) | |
977 Ci M Cj = VARYING if (i != j) | |
978 */ | |
979 | |
980 static void | |
111 | 981 ccp_lattice_meet (ccp_prop_value_t *val1, ccp_prop_value_t *val2) |
0 | 982 { |
111 | 983 if (val1->lattice_val == UNDEFINED |
984 /* For UNDEFINED M SSA we can't always SSA because its definition | |
985 may not dominate the PHI node. Doing optimistic copy propagation | |
986 also causes a lot of gcc.dg/uninit-pred*.c FAILs. */ | |
987 && (val2->lattice_val != CONSTANT | |
988 || TREE_CODE (val2->value) != SSA_NAME)) | |
0 | 989 { |
990 /* UNDEFINED M any = any */ | |
991 *val1 = *val2; | |
992 } | |
111 | 993 else if (val2->lattice_val == UNDEFINED |
994 /* See above. */ | |
995 && (val1->lattice_val != CONSTANT | |
996 || TREE_CODE (val1->value) != SSA_NAME)) | |
0 | 997 { |
998 /* any M UNDEFINED = any | |
999 Nothing to do. VAL1 already contains the value we want. */ | |
1000 ; | |
1001 } | |
1002 else if (val1->lattice_val == VARYING | |
1003 || val2->lattice_val == VARYING) | |
1004 { | |
1005 /* any M VARYING = VARYING. */ | |
1006 val1->lattice_val = VARYING; | |
111 | 1007 val1->mask = -1; |
0 | 1008 val1->value = NULL_TREE; |
1009 } | |
1010 else if (val1->lattice_val == CONSTANT | |
1011 && val2->lattice_val == CONSTANT | |
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
|
1012 && TREE_CODE (val1->value) == INTEGER_CST |
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
|
1013 && TREE_CODE (val2->value) == INTEGER_CST) |
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
|
1014 { |
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
|
1015 /* Ci M Cj = Ci if (i == j) |
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
|
1016 Ci M Cj = VARYING if (i != j) |
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
|
1017 |
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
|
1018 For INTEGER_CSTs mask unequal bits. If no equal bits remain, |
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
|
1019 drop to varying. */ |
111 | 1020 val1->mask = (val1->mask | val2->mask |
1021 | (wi::to_widest (val1->value) | |
1022 ^ wi::to_widest (val2->value))); | |
1023 if (wi::sext (val1->mask, TYPE_PRECISION (TREE_TYPE (val1->value))) == -1) | |
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
|
1024 { |
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
|
1025 val1->lattice_val = VARYING; |
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
|
1026 val1->value = NULL_TREE; |
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
|
1027 } |
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
|
1028 } |
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
|
1029 else if (val1->lattice_val == CONSTANT |
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
|
1030 && val2->lattice_val == CONSTANT |
111 | 1031 && operand_equal_p (val1->value, val2->value, 0)) |
0 | 1032 { |
1033 /* Ci M Cj = Ci if (i == j) | |
1034 Ci M Cj = VARYING if (i != j) | |
1035 | |
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
|
1036 VAL1 already contains the value we want for equivalent values. */ |
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
|
1037 } |
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
|
1038 else if (val1->lattice_val == CONSTANT |
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
|
1039 && val2->lattice_val == CONSTANT |
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
|
1040 && (TREE_CODE (val1->value) == ADDR_EXPR |
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
|
1041 || TREE_CODE (val2->value) == ADDR_EXPR)) |
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
|
1042 { |
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
|
1043 /* When not equal addresses are involved try meeting for |
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
|
1044 alignment. */ |
111 | 1045 ccp_prop_value_t tem = *val2; |
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
|
1046 if (TREE_CODE (val1->value) == ADDR_EXPR) |
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
|
1047 *val1 = get_value_for_expr (val1->value, true); |
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
|
1048 if (TREE_CODE (val2->value) == ADDR_EXPR) |
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
|
1049 tem = get_value_for_expr (val2->value, true); |
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
|
1050 ccp_lattice_meet (val1, &tem); |
0 | 1051 } |
1052 else | |
1053 { | |
1054 /* Any other combination is VARYING. */ | |
1055 val1->lattice_val = VARYING; | |
111 | 1056 val1->mask = -1; |
0 | 1057 val1->value = NULL_TREE; |
1058 } | |
1059 } | |
1060 | |
1061 | |
1062 /* Loop through the PHI_NODE's parameters for BLOCK and compare their | |
1063 lattice values to determine PHI_NODE's lattice value. The value of a | |
1064 PHI node is determined calling ccp_lattice_meet with all the arguments | |
1065 of the PHI node that are incoming via executable edges. */ | |
1066 | |
1067 static enum ssa_prop_result | |
111 | 1068 ccp_visit_phi_node (gphi *phi) |
0 | 1069 { |
1070 unsigned i; | |
111 | 1071 ccp_prop_value_t new_val; |
0 | 1072 |
1073 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1074 { | |
1075 fprintf (dump_file, "\nVisiting PHI node: "); | |
1076 print_gimple_stmt (dump_file, phi, 0, dump_flags); | |
1077 } | |
1078 | |
111 | 1079 new_val.lattice_val = UNDEFINED; |
1080 new_val.value = NULL_TREE; | |
1081 new_val.mask = 0; | |
1082 | |
1083 bool first = true; | |
1084 bool non_exec_edge = false; | |
0 | 1085 for (i = 0; i < gimple_phi_num_args (phi); i++) |
1086 { | |
1087 /* Compute the meet operator over all the PHI arguments flowing | |
1088 through executable edges. */ | |
1089 edge e = gimple_phi_arg_edge (phi, i); | |
1090 | |
1091 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1092 { | |
1093 fprintf (dump_file, | |
1094 "\n Argument #%d (%d -> %d %sexecutable)\n", | |
1095 i, e->src->index, e->dest->index, | |
1096 (e->flags & EDGE_EXECUTABLE) ? "" : "not "); | |
1097 } | |
1098 | |
1099 /* If the incoming edge is executable, Compute the meet operator for | |
1100 the existing value of the PHI node and the current PHI argument. */ | |
1101 if (e->flags & EDGE_EXECUTABLE) | |
1102 { | |
1103 tree arg = gimple_phi_arg (phi, i)->def; | |
111 | 1104 ccp_prop_value_t arg_val = get_value_for_expr (arg, false); |
1105 | |
1106 if (first) | |
1107 { | |
1108 new_val = arg_val; | |
1109 first = false; | |
1110 } | |
1111 else | |
1112 ccp_lattice_meet (&new_val, &arg_val); | |
0 | 1113 |
1114 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1115 { | |
1116 fprintf (dump_file, "\t"); | |
1117 print_generic_expr (dump_file, arg, dump_flags); | |
1118 dump_lattice_value (dump_file, "\tValue: ", arg_val); | |
1119 fprintf (dump_file, "\n"); | |
1120 } | |
1121 | |
1122 if (new_val.lattice_val == VARYING) | |
1123 break; | |
1124 } | |
111 | 1125 else |
1126 non_exec_edge = true; | |
1127 } | |
1128 | |
1129 /* In case there were non-executable edges and the value is a copy | |
1130 make sure its definition dominates the PHI node. */ | |
1131 if (non_exec_edge | |
1132 && new_val.lattice_val == CONSTANT | |
1133 && TREE_CODE (new_val.value) == SSA_NAME | |
1134 && ! SSA_NAME_IS_DEFAULT_DEF (new_val.value) | |
1135 && ! dominated_by_p (CDI_DOMINATORS, gimple_bb (phi), | |
1136 gimple_bb (SSA_NAME_DEF_STMT (new_val.value)))) | |
1137 { | |
1138 new_val.lattice_val = VARYING; | |
1139 new_val.value = NULL_TREE; | |
1140 new_val.mask = -1; | |
0 | 1141 } |
1142 | |
1143 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1144 { | |
1145 dump_lattice_value (dump_file, "\n PHI node value: ", new_val); | |
1146 fprintf (dump_file, "\n\n"); | |
1147 } | |
1148 | |
1149 /* Make the transition to the new value. */ | |
111 | 1150 if (set_lattice_value (gimple_phi_result (phi), &new_val)) |
0 | 1151 { |
1152 if (new_val.lattice_val == VARYING) | |
1153 return SSA_PROP_VARYING; | |
1154 else | |
1155 return SSA_PROP_INTERESTING; | |
1156 } | |
1157 else | |
1158 return SSA_PROP_NOT_INTERESTING; | |
1159 } | |
1160 | |
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
|
1161 /* Return the constant value for OP or OP otherwise. */ |
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
|
1162 |
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
|
1163 static tree |
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
|
1164 valueize_op (tree op) |
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
|
1165 { |
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
|
1166 if (TREE_CODE (op) == 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
|
1167 { |
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
|
1168 tree tem = get_constant_value (op); |
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
|
1169 if (tem) |
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
|
1170 return tem; |
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
|
1171 } |
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
|
1172 return op; |
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
|
1173 } |
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
|
1174 |
111 | 1175 /* Return the constant value for OP, but signal to not follow SSA |
1176 edges if the definition may be simulated again. */ | |
1177 | |
1178 static tree | |
1179 valueize_op_1 (tree op) | |
1180 { | |
1181 if (TREE_CODE (op) == SSA_NAME) | |
1182 { | |
1183 /* If the definition may be simulated again we cannot follow | |
1184 this SSA edge as the SSA propagator does not necessarily | |
1185 re-visit the use. */ | |
1186 gimple *def_stmt = SSA_NAME_DEF_STMT (op); | |
1187 if (!gimple_nop_p (def_stmt) | |
1188 && prop_simulate_again_p (def_stmt)) | |
1189 return NULL_TREE; | |
1190 tree tem = get_constant_value (op); | |
1191 if (tem) | |
1192 return tem; | |
1193 } | |
1194 return op; | |
1195 } | |
1196 | |
0 | 1197 /* CCP specific front-end to the non-destructive constant folding |
1198 routines. | |
1199 | |
1200 Attempt to simplify the RHS of STMT knowing that one or more | |
1201 operands are constants. | |
1202 | |
1203 If simplification is possible, return the simplified RHS, | |
1204 otherwise return the original RHS or NULL_TREE. */ | |
1205 | |
1206 static tree | |
111 | 1207 ccp_fold (gimple *stmt) |
0 | 1208 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1209 location_t loc = gimple_location (stmt); |
0 | 1210 switch (gimple_code (stmt)) |
1211 { | |
1212 case GIMPLE_COND: | |
1213 { | |
1214 /* Handle comparison operators that can appear in GIMPLE form. */ | |
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
|
1215 tree op0 = valueize_op (gimple_cond_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
|
1216 tree op1 = valueize_op (gimple_cond_rhs (stmt)); |
0 | 1217 enum tree_code code = gimple_cond_code (stmt); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1218 return fold_binary_loc (loc, code, boolean_type_node, op0, op1); |
0 | 1219 } |
1220 | |
1221 case GIMPLE_SWITCH: | |
1222 { | |
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
|
1223 /* Return the constant switch index. */ |
111 | 1224 return valueize_op (gimple_switch_index (as_a <gswitch *> (stmt))); |
0 | 1225 } |
1226 | |
111 | 1227 case GIMPLE_ASSIGN: |
1228 case GIMPLE_CALL: | |
1229 return gimple_fold_stmt_to_constant_1 (stmt, | |
1230 valueize_op, valueize_op_1); | |
1231 | |
0 | 1232 default: |
1233 gcc_unreachable (); | |
1234 } | |
1235 } | |
1236 | |
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
|
1237 /* Apply the operation CODE in type TYPE to the value, mask pair |
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
|
1238 RVAL and RMASK representing a value of type RTYPE and set |
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
|
1239 the value, mask pair *VAL and *MASK to the result. */ |
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
|
1240 |
111 | 1241 void |
1242 bit_value_unop (enum tree_code code, signop type_sgn, int type_precision, | |
1243 widest_int *val, widest_int *mask, | |
1244 signop rtype_sgn, int rtype_precision, | |
1245 const widest_int &rval, const widest_int &rmask) | |
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
|
1246 { |
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
|
1247 switch (code) |
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
|
1248 { |
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
|
1249 case BIT_NOT_EXPR: |
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
|
1250 *mask = rmask; |
111 | 1251 *val = ~rval; |
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
|
1252 break; |
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
|
1253 |
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
|
1254 case NEGATE_EXPR: |
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
|
1255 { |
111 | 1256 widest_int temv, temm; |
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
|
1257 /* Return ~rval + 1. */ |
111 | 1258 bit_value_unop (BIT_NOT_EXPR, type_sgn, type_precision, &temv, &temm, |
1259 type_sgn, type_precision, rval, rmask); | |
1260 bit_value_binop (PLUS_EXPR, type_sgn, type_precision, val, mask, | |
1261 type_sgn, type_precision, temv, temm, | |
1262 type_sgn, type_precision, 1, 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
|
1263 break; |
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
|
1264 } |
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
|
1265 |
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
|
1266 CASE_CONVERT: |
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
|
1267 { |
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
|
1268 /* First extend mask and value according to the original type. */ |
111 | 1269 *mask = wi::ext (rmask, rtype_precision, rtype_sgn); |
1270 *val = wi::ext (rval, rtype_precision, rtype_sgn); | |
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
|
1271 |
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
|
1272 /* Then extend mask and value according to the target type. */ |
111 | 1273 *mask = wi::ext (*mask, type_precision, type_sgn); |
1274 *val = wi::ext (*val, type_precision, type_sgn); | |
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
|
1275 break; |
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
|
1276 } |
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
|
1277 |
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
|
1278 default: |
111 | 1279 *mask = -1; |
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
|
1280 break; |
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
|
1281 } |
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
|
1282 } |
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
|
1283 |
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
|
1284 /* Apply the operation CODE in type TYPE to the value, mask pairs |
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
|
1285 R1VAL, R1MASK and R2VAL, R2MASK representing a values of type R1TYPE |
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
|
1286 and R2TYPE and set the value, mask pair *VAL and *MASK to the result. */ |
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
|
1287 |
111 | 1288 void |
1289 bit_value_binop (enum tree_code code, signop sgn, int width, | |
1290 widest_int *val, widest_int *mask, | |
1291 signop r1type_sgn, int r1type_precision, | |
1292 const widest_int &r1val, const widest_int &r1mask, | |
1293 signop r2type_sgn, int r2type_precision, | |
1294 const widest_int &r2val, const widest_int &r2mask) | |
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
|
1295 { |
111 | 1296 bool swap_p = false; |
1297 | |
1298 /* Assume we'll get a constant result. Use an initial non varying | |
1299 value, we fall back to varying in the end if necessary. */ | |
1300 *mask = -1; | |
1301 | |
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
|
1302 switch (code) |
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
|
1303 { |
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
|
1304 case BIT_AND_EXPR: |
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
|
1305 /* The mask is constant where there is a known not |
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
|
1306 set bit, (m1 | m2) & ((v1 | m1) & (v2 | m2)) */ |
111 | 1307 *mask = (r1mask | r2mask) & (r1val | r1mask) & (r2val | r2mask); |
1308 *val = r1val & r2val; | |
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
|
1309 break; |
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
|
1310 |
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
|
1311 case BIT_IOR_EXPR: |
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
|
1312 /* The mask is constant where there is a known |
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
|
1313 set bit, (m1 | m2) & ~((v1 & ~m1) | (v2 & ~m2)). */ |
111 | 1314 *mask = wi::bit_and_not (r1mask | r2mask, |
1315 wi::bit_and_not (r1val, r1mask) | |
1316 | wi::bit_and_not (r2val, r2mask)); | |
1317 *val = r1val | r2val; | |
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
|
1318 break; |
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
|
1319 |
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
|
1320 case BIT_XOR_EXPR: |
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
|
1321 /* m1 | m2 */ |
111 | 1322 *mask = r1mask | r2mask; |
1323 *val = r1val ^ r2val; | |
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
|
1324 break; |
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
|
1325 |
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
|
1326 case LROTATE_EXPR: |
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
|
1327 case RROTATE_EXPR: |
111 | 1328 if (r2mask == 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
|
1329 { |
111 | 1330 widest_int shift = r2val; |
1331 if (shift == 0) | |
1332 { | |
1333 *mask = r1mask; | |
1334 *val = r1val; | |
1335 } | |
1336 else | |
1337 { | |
1338 if (wi::neg_p (shift)) | |
1339 { | |
1340 shift = -shift; | |
1341 if (code == RROTATE_EXPR) | |
1342 code = LROTATE_EXPR; | |
1343 else | |
1344 code = RROTATE_EXPR; | |
1345 } | |
1346 if (code == RROTATE_EXPR) | |
1347 { | |
1348 *mask = wi::rrotate (r1mask, shift, width); | |
1349 *val = wi::rrotate (r1val, shift, width); | |
1350 } | |
1351 else | |
1352 { | |
1353 *mask = wi::lrotate (r1mask, shift, width); | |
1354 *val = wi::lrotate (r1val, shift, width); | |
1355 } | |
1356 } | |
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
|
1357 } |
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
|
1358 break; |
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
|
1359 |
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
|
1360 case LSHIFT_EXPR: |
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
|
1361 case RSHIFT_EXPR: |
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
|
1362 /* ??? We can handle partially known shift counts if we know |
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
|
1363 its sign. That way we can tell that (x << (y | 8)) & 255 |
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
|
1364 is zero. */ |
111 | 1365 if (r2mask == 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
|
1366 { |
111 | 1367 widest_int shift = r2val; |
1368 if (shift == 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
|
1369 { |
111 | 1370 *mask = r1mask; |
1371 *val = r1val; | |
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
|
1372 } |
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
|
1373 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
|
1374 { |
111 | 1375 if (wi::neg_p (shift)) |
1376 { | |
1377 shift = -shift; | |
1378 if (code == RSHIFT_EXPR) | |
1379 code = LSHIFT_EXPR; | |
1380 else | |
1381 code = RSHIFT_EXPR; | |
1382 } | |
1383 if (code == RSHIFT_EXPR) | |
1384 { | |
1385 *mask = wi::rshift (wi::ext (r1mask, width, sgn), shift, sgn); | |
1386 *val = wi::rshift (wi::ext (r1val, width, sgn), shift, sgn); | |
1387 } | |
1388 else | |
1389 { | |
1390 *mask = wi::ext (r1mask << shift, width, sgn); | |
1391 *val = wi::ext (r1val << shift, width, sgn); | |
1392 } | |
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
|
1393 } |
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
|
1394 } |
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
|
1395 break; |
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
|
1396 |
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
|
1397 case PLUS_EXPR: |
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
|
1398 case POINTER_PLUS_EXPR: |
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
|
1399 { |
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
|
1400 /* Do the addition with unknown bits set to zero, to give carry-ins of |
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
|
1401 zero wherever possible. */ |
111 | 1402 widest_int lo = (wi::bit_and_not (r1val, r1mask) |
1403 + wi::bit_and_not (r2val, r2mask)); | |
1404 lo = wi::ext (lo, width, sgn); | |
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
|
1405 /* Do the addition with unknown bits set to one, to give carry-ins of |
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
|
1406 one wherever possible. */ |
111 | 1407 widest_int hi = (r1val | r1mask) + (r2val | r2mask); |
1408 hi = wi::ext (hi, width, sgn); | |
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
|
1409 /* Each bit in the result is known if (a) the corresponding bits in |
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
|
1410 both inputs are known, and (b) the carry-in to that bit position |
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
|
1411 is known. We can check condition (b) by seeing if we got the same |
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
|
1412 result with minimised carries as with maximised carries. */ |
111 | 1413 *mask = r1mask | r2mask | (lo ^ hi); |
1414 *mask = wi::ext (*mask, width, sgn); | |
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
|
1415 /* It shouldn't matter whether we choose lo or hi here. */ |
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
|
1416 *val = lo; |
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
|
1417 break; |
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
|
1418 } |
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
|
1419 |
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
|
1420 case MINUS_EXPR: |
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
|
1421 { |
111 | 1422 widest_int temv, temm; |
1423 bit_value_unop (NEGATE_EXPR, r2type_sgn, r2type_precision, &temv, &temm, | |
1424 r2type_sgn, r2type_precision, r2val, r2mask); | |
1425 bit_value_binop (PLUS_EXPR, sgn, width, val, mask, | |
1426 r1type_sgn, r1type_precision, r1val, r1mask, | |
1427 r2type_sgn, r2type_precision, temv, temm); | |
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
|
1428 break; |
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
|
1429 } |
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
|
1430 |
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
|
1431 case MULT_EXPR: |
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
|
1432 { |
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
|
1433 /* Just track trailing zeros in both operands and transfer |
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
|
1434 them to the other. */ |
111 | 1435 int r1tz = wi::ctz (r1val | r1mask); |
1436 int r2tz = wi::ctz (r2val | r2mask); | |
1437 if (r1tz + r2tz >= width) | |
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
|
1438 { |
111 | 1439 *mask = 0; |
1440 *val = 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
|
1441 } |
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
|
1442 else if (r1tz + r2tz > 0) |
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
|
1443 { |
111 | 1444 *mask = wi::ext (wi::mask <widest_int> (r1tz + r2tz, true), |
1445 width, sgn); | |
1446 *val = 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
|
1447 } |
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
|
1448 break; |
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
|
1449 } |
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
|
1450 |
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
|
1451 case EQ_EXPR: |
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
|
1452 case NE_EXPR: |
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
|
1453 { |
111 | 1454 widest_int m = r1mask | r2mask; |
1455 if (wi::bit_and_not (r1val, m) != wi::bit_and_not (r2val, m)) | |
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
|
1456 { |
111 | 1457 *mask = 0; |
1458 *val = ((code == EQ_EXPR) ? 0 : 1); | |
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
|
1459 } |
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
|
1460 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
|
1461 { |
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
|
1462 /* We know the result of a comparison is always one or zero. */ |
111 | 1463 *mask = 1; |
1464 *val = 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
|
1465 } |
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
|
1466 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1467 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1468 |
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
|
1469 case GE_EXPR: |
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
|
1470 case GT_EXPR: |
111 | 1471 swap_p = true; |
1472 code = swap_tree_comparison (code); | |
1473 /* Fall through. */ | |
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
|
1474 case LT_EXPR: |
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
|
1475 case LE_EXPR: |
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
|
1476 { |
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
|
1477 int minmax, maxmin; |
111 | 1478 |
1479 const widest_int &o1val = swap_p ? r2val : r1val; | |
1480 const widest_int &o1mask = swap_p ? r2mask : r1mask; | |
1481 const widest_int &o2val = swap_p ? r1val : r2val; | |
1482 const widest_int &o2mask = swap_p ? r1mask : r2mask; | |
1483 | |
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
|
1484 /* If the most significant bits are not known we know nothing. */ |
111 | 1485 if (wi::neg_p (o1mask) || wi::neg_p (o2mask)) |
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
|
1486 break; |
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
|
1487 |
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
|
1488 /* For comparisons the signedness is in the comparison operands. */ |
111 | 1489 sgn = r1type_sgn; |
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
|
1490 |
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
|
1491 /* If we know the most significant bits we know the values |
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
|
1492 value ranges by means of treating varying bits as zero |
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
|
1493 or one. Do a cross comparison of the max/min pairs. */ |
111 | 1494 maxmin = wi::cmp (o1val | o1mask, |
1495 wi::bit_and_not (o2val, o2mask), sgn); | |
1496 minmax = wi::cmp (wi::bit_and_not (o1val, o1mask), | |
1497 o2val | o2mask, sgn); | |
1498 if (maxmin < 0) /* o1 is less than o2. */ | |
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
|
1499 { |
111 | 1500 *mask = 0; |
1501 *val = 1; | |
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
|
1502 } |
111 | 1503 else if (minmax > 0) /* o1 is not less or equal to o2. */ |
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
|
1504 { |
111 | 1505 *mask = 0; |
1506 *val = 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
|
1507 } |
111 | 1508 else if (maxmin == minmax) /* o1 and o2 are equal. */ |
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
|
1509 { |
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
|
1510 /* This probably should never happen as we'd have |
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
|
1511 folded the thing during fully constant value folding. */ |
111 | 1512 *mask = 0; |
1513 *val = (code == LE_EXPR ? 1 : 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
|
1514 } |
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
|
1515 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
|
1516 { |
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
|
1517 /* We know the result of a comparison is always one or zero. */ |
111 | 1518 *mask = 1; |
1519 *val = 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
|
1520 } |
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
|
1521 break; |
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
|
1522 } |
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
|
1523 |
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
|
1524 default:; |
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
|
1525 } |
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
|
1526 } |
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
|
1527 |
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
|
1528 /* Return the propagation value when applying the operation CODE to |
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
|
1529 the value RHS yielding type TYPE. */ |
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
|
1530 |
111 | 1531 static ccp_prop_value_t |
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
|
1532 bit_value_unop (enum tree_code code, tree type, tree rhs) |
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
|
1533 { |
111 | 1534 ccp_prop_value_t rval = get_value_for_expr (rhs, true); |
1535 widest_int value, mask; | |
1536 ccp_prop_value_t val; | |
1537 | |
1538 if (rval.lattice_val == UNDEFINED) | |
1539 return rval; | |
1540 | |
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
|
1541 gcc_assert ((rval.lattice_val == CONSTANT |
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
|
1542 && TREE_CODE (rval.value) == INTEGER_CST) |
111 | 1543 || wi::sext (rval.mask, TYPE_PRECISION (TREE_TYPE (rhs))) == -1); |
1544 bit_value_unop (code, TYPE_SIGN (type), TYPE_PRECISION (type), &value, &mask, | |
1545 TYPE_SIGN (TREE_TYPE (rhs)), TYPE_PRECISION (TREE_TYPE (rhs)), | |
1546 value_to_wide_int (rval), rval.mask); | |
1547 if (wi::sext (mask, TYPE_PRECISION (type)) != -1) | |
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
|
1548 { |
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
|
1549 val.lattice_val = CONSTANT; |
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
|
1550 val.mask = mask; |
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
|
1551 /* ??? Delay building trees here. */ |
111 | 1552 val.value = wide_int_to_tree (type, value); |
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
|
1553 } |
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
|
1554 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
|
1555 { |
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
|
1556 val.lattice_val = VARYING; |
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
|
1557 val.value = NULL_TREE; |
111 | 1558 val.mask = -1; |
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
|
1559 } |
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
|
1560 return val; |
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
|
1561 } |
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
|
1562 |
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
|
1563 /* Return the propagation value when applying the operation CODE to |
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
|
1564 the values RHS1 and RHS2 yielding type TYPE. */ |
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
|
1565 |
111 | 1566 static ccp_prop_value_t |
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
|
1567 bit_value_binop (enum tree_code code, tree type, tree rhs1, tree rhs2) |
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
|
1568 { |
111 | 1569 ccp_prop_value_t r1val = get_value_for_expr (rhs1, true); |
1570 ccp_prop_value_t r2val = get_value_for_expr (rhs2, true); | |
1571 widest_int value, mask; | |
1572 ccp_prop_value_t val; | |
1573 | |
1574 if (r1val.lattice_val == UNDEFINED | |
1575 || r2val.lattice_val == UNDEFINED) | |
1576 { | |
1577 val.lattice_val = VARYING; | |
1578 val.value = NULL_TREE; | |
1579 val.mask = -1; | |
1580 return val; | |
1581 } | |
1582 | |
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
|
1583 gcc_assert ((r1val.lattice_val == CONSTANT |
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
|
1584 && TREE_CODE (r1val.value) == INTEGER_CST) |
111 | 1585 || wi::sext (r1val.mask, |
1586 TYPE_PRECISION (TREE_TYPE (rhs1))) == -1); | |
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
|
1587 gcc_assert ((r2val.lattice_val == CONSTANT |
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
|
1588 && TREE_CODE (r2val.value) == INTEGER_CST) |
111 | 1589 || wi::sext (r2val.mask, |
1590 TYPE_PRECISION (TREE_TYPE (rhs2))) == -1); | |
1591 bit_value_binop (code, TYPE_SIGN (type), TYPE_PRECISION (type), &value, &mask, | |
1592 TYPE_SIGN (TREE_TYPE (rhs1)), TYPE_PRECISION (TREE_TYPE (rhs1)), | |
1593 value_to_wide_int (r1val), r1val.mask, | |
1594 TYPE_SIGN (TREE_TYPE (rhs2)), TYPE_PRECISION (TREE_TYPE (rhs2)), | |
1595 value_to_wide_int (r2val), r2val.mask); | |
1596 | |
1597 if (wi::sext (mask, TYPE_PRECISION (type)) != -1) | |
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
|
1598 { |
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
|
1599 val.lattice_val = CONSTANT; |
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
|
1600 val.mask = mask; |
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
|
1601 /* ??? Delay building trees here. */ |
111 | 1602 val.value = wide_int_to_tree (type, value); |
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
|
1603 } |
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
|
1604 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
|
1605 { |
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
|
1606 val.lattice_val = VARYING; |
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
|
1607 val.value = NULL_TREE; |
111 | 1608 val.mask = -1; |
1609 } | |
1610 return val; | |
1611 } | |
1612 | |
1613 /* Return the propagation value for __builtin_assume_aligned | |
1614 and functions with assume_aligned or alloc_aligned attribute. | |
1615 For __builtin_assume_aligned, ATTR is NULL_TREE, | |
1616 for assume_aligned attribute ATTR is non-NULL and ALLOC_ALIGNED | |
1617 is false, for alloc_aligned attribute ATTR is non-NULL and | |
1618 ALLOC_ALIGNED is true. */ | |
1619 | |
1620 static ccp_prop_value_t | |
1621 bit_value_assume_aligned (gimple *stmt, tree attr, ccp_prop_value_t ptrval, | |
1622 bool alloc_aligned) | |
1623 { | |
1624 tree align, misalign = NULL_TREE, type; | |
1625 unsigned HOST_WIDE_INT aligni, misaligni = 0; | |
1626 ccp_prop_value_t alignval; | |
1627 widest_int value, mask; | |
1628 ccp_prop_value_t val; | |
1629 | |
1630 if (attr == NULL_TREE) | |
1631 { | |
1632 tree ptr = gimple_call_arg (stmt, 0); | |
1633 type = TREE_TYPE (ptr); | |
1634 ptrval = get_value_for_expr (ptr, true); | |
1635 } | |
1636 else | |
1637 { | |
1638 tree lhs = gimple_call_lhs (stmt); | |
1639 type = TREE_TYPE (lhs); | |
1640 } | |
1641 | |
1642 if (ptrval.lattice_val == UNDEFINED) | |
1643 return ptrval; | |
1644 gcc_assert ((ptrval.lattice_val == CONSTANT | |
1645 && TREE_CODE (ptrval.value) == INTEGER_CST) | |
1646 || wi::sext (ptrval.mask, TYPE_PRECISION (type)) == -1); | |
1647 if (attr == NULL_TREE) | |
1648 { | |
1649 /* Get aligni and misaligni from __builtin_assume_aligned. */ | |
1650 align = gimple_call_arg (stmt, 1); | |
1651 if (!tree_fits_uhwi_p (align)) | |
1652 return ptrval; | |
1653 aligni = tree_to_uhwi (align); | |
1654 if (gimple_call_num_args (stmt) > 2) | |
1655 { | |
1656 misalign = gimple_call_arg (stmt, 2); | |
1657 if (!tree_fits_uhwi_p (misalign)) | |
1658 return ptrval; | |
1659 misaligni = tree_to_uhwi (misalign); | |
1660 } | |
1661 } | |
1662 else | |
1663 { | |
1664 /* Get aligni and misaligni from assume_aligned or | |
1665 alloc_align attributes. */ | |
1666 if (TREE_VALUE (attr) == NULL_TREE) | |
1667 return ptrval; | |
1668 attr = TREE_VALUE (attr); | |
1669 align = TREE_VALUE (attr); | |
1670 if (!tree_fits_uhwi_p (align)) | |
1671 return ptrval; | |
1672 aligni = tree_to_uhwi (align); | |
1673 if (alloc_aligned) | |
1674 { | |
1675 if (aligni == 0 || aligni > gimple_call_num_args (stmt)) | |
1676 return ptrval; | |
1677 align = gimple_call_arg (stmt, aligni - 1); | |
1678 if (!tree_fits_uhwi_p (align)) | |
1679 return ptrval; | |
1680 aligni = tree_to_uhwi (align); | |
1681 } | |
1682 else if (TREE_CHAIN (attr) && TREE_VALUE (TREE_CHAIN (attr))) | |
1683 { | |
1684 misalign = TREE_VALUE (TREE_CHAIN (attr)); | |
1685 if (!tree_fits_uhwi_p (misalign)) | |
1686 return ptrval; | |
1687 misaligni = tree_to_uhwi (misalign); | |
1688 } | |
1689 } | |
1690 if (aligni <= 1 || (aligni & (aligni - 1)) != 0 || misaligni >= aligni) | |
1691 return ptrval; | |
1692 | |
1693 align = build_int_cst_type (type, -aligni); | |
1694 alignval = get_value_for_expr (align, true); | |
1695 bit_value_binop (BIT_AND_EXPR, TYPE_SIGN (type), TYPE_PRECISION (type), &value, &mask, | |
1696 TYPE_SIGN (type), TYPE_PRECISION (type), value_to_wide_int (ptrval), ptrval.mask, | |
1697 TYPE_SIGN (type), TYPE_PRECISION (type), value_to_wide_int (alignval), alignval.mask); | |
1698 | |
1699 if (wi::sext (mask, TYPE_PRECISION (type)) != -1) | |
1700 { | |
1701 val.lattice_val = CONSTANT; | |
1702 val.mask = mask; | |
1703 gcc_assert ((mask.to_uhwi () & (aligni - 1)) == 0); | |
1704 gcc_assert ((value.to_uhwi () & (aligni - 1)) == 0); | |
1705 value |= misaligni; | |
1706 /* ??? Delay building trees here. */ | |
1707 val.value = wide_int_to_tree (type, value); | |
1708 } | |
1709 else | |
1710 { | |
1711 val.lattice_val = VARYING; | |
1712 val.value = NULL_TREE; | |
1713 val.mask = -1; | |
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
|
1714 } |
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
|
1715 return val; |
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
|
1716 } |
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
|
1717 |
0 | 1718 /* Evaluate statement STMT. |
1719 Valid only for assignments, calls, conditionals, and switches. */ | |
1720 | |
111 | 1721 static ccp_prop_value_t |
1722 evaluate_stmt (gimple *stmt) | |
0 | 1723 { |
111 | 1724 ccp_prop_value_t val; |
0 | 1725 tree simplified = NULL_TREE; |
1726 ccp_lattice_t likelyvalue = likely_value (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
|
1727 bool is_constant = false; |
111 | 1728 unsigned int align; |
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
|
1729 |
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
|
1730 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
|
1731 { |
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
|
1732 fprintf (dump_file, "which is likely "); |
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
|
1733 switch (likelyvalue) |
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
|
1734 { |
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
|
1735 case CONSTANT: |
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
|
1736 fprintf (dump_file, "CONSTANT"); |
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
|
1737 break; |
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
|
1738 case UNDEFINED: |
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
|
1739 fprintf (dump_file, "UNDEFINED"); |
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
|
1740 break; |
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
|
1741 case VARYING: |
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
|
1742 fprintf (dump_file, "VARYING"); |
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
|
1743 break; |
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
|
1744 default:; |
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
|
1745 } |
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
|
1746 fprintf (dump_file, "\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
|
1747 } |
0 | 1748 |
1749 /* If the statement is likely to have a CONSTANT result, then try | |
1750 to fold the statement to determine the constant value. */ | |
1751 /* FIXME. This is the only place that we call ccp_fold. | |
1752 Since likely_value never returns CONSTANT for calls, we will | |
1753 not attempt to fold them, including builtins that may profit. */ | |
1754 if (likelyvalue == CONSTANT) | |
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
|
1755 { |
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
|
1756 fold_defer_overflow_warnings (); |
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
|
1757 simplified = ccp_fold (stmt); |
111 | 1758 if (simplified |
1759 && TREE_CODE (simplified) == SSA_NAME) | |
1760 { | |
1761 /* We may not use values of something that may be simulated again, | |
1762 see valueize_op_1. */ | |
1763 if (SSA_NAME_IS_DEFAULT_DEF (simplified) | |
1764 || ! prop_simulate_again_p (SSA_NAME_DEF_STMT (simplified))) | |
1765 { | |
1766 ccp_prop_value_t *val = get_value (simplified); | |
1767 if (val && val->lattice_val != VARYING) | |
1768 { | |
1769 fold_undefer_overflow_warnings (true, stmt, 0); | |
1770 return *val; | |
1771 } | |
1772 } | |
1773 else | |
1774 /* We may also not place a non-valueized copy in the lattice | |
1775 as that might become stale if we never re-visit this stmt. */ | |
1776 simplified = NULL_TREE; | |
1777 } | |
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
|
1778 is_constant = simplified && is_gimple_min_invariant (simplified); |
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
|
1779 fold_undefer_overflow_warnings (is_constant, stmt, 0); |
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
|
1780 if (is_constant) |
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
|
1781 { |
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
|
1782 /* The statement produced a constant value. */ |
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
|
1783 val.lattice_val = CONSTANT; |
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
|
1784 val.value = simplified; |
111 | 1785 val.mask = 0; |
1786 return val; | |
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
|
1787 } |
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
|
1788 } |
0 | 1789 /* If the statement is likely to have a VARYING result, then do not |
1790 bother folding the statement. */ | |
1791 else if (likelyvalue == VARYING) | |
1792 { | |
1793 enum gimple_code code = gimple_code (stmt); | |
1794 if (code == GIMPLE_ASSIGN) | |
1795 { | |
1796 enum tree_code subcode = gimple_assign_rhs_code (stmt); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1797 |
0 | 1798 /* Other cases cannot satisfy is_gimple_min_invariant |
1799 without folding. */ | |
1800 if (get_gimple_rhs_class (subcode) == GIMPLE_SINGLE_RHS) | |
1801 simplified = gimple_assign_rhs1 (stmt); | |
1802 } | |
1803 else if (code == GIMPLE_SWITCH) | |
111 | 1804 simplified = gimple_switch_index (as_a <gswitch *> (stmt)); |
0 | 1805 else |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1806 /* These cannot satisfy is_gimple_min_invariant without folding. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1807 gcc_assert (code == GIMPLE_CALL || code == GIMPLE_COND); |
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
|
1808 is_constant = simplified && is_gimple_min_invariant (simplified); |
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
|
1809 if (is_constant) |
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
|
1810 { |
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
|
1811 /* The statement produced a constant value. */ |
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
|
1812 val.lattice_val = CONSTANT; |
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
|
1813 val.value = simplified; |
111 | 1814 val.mask = 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
|
1815 } |
0 | 1816 } |
111 | 1817 /* If the statement result is likely UNDEFINED, make it so. */ |
1818 else if (likelyvalue == UNDEFINED) | |
1819 { | |
1820 val.lattice_val = UNDEFINED; | |
1821 val.value = NULL_TREE; | |
1822 val.mask = 0; | |
1823 return val; | |
1824 } | |
0 | 1825 |
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
|
1826 /* Resort to simplification for bitwise tracking. */ |
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
|
1827 if (flag_tree_bit_ccp |
111 | 1828 && (likelyvalue == CONSTANT || is_gimple_call (stmt) |
1829 || (gimple_assign_single_p (stmt) | |
1830 && gimple_assign_rhs_code (stmt) == ADDR_EXPR)) | |
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
|
1831 && !is_constant) |
0 | 1832 { |
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
|
1833 enum gimple_code code = gimple_code (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
|
1834 val.lattice_val = VARYING; |
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
|
1835 val.value = NULL_TREE; |
111 | 1836 val.mask = -1; |
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
|
1837 if (code == GIMPLE_ASSIGN) |
0 | 1838 { |
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
|
1839 enum tree_code subcode = gimple_assign_rhs_code (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
|
1840 tree rhs1 = gimple_assign_rhs1 (stmt); |
111 | 1841 tree lhs = gimple_assign_lhs (stmt); |
1842 if ((INTEGRAL_TYPE_P (TREE_TYPE (lhs)) | |
1843 || POINTER_TYPE_P (TREE_TYPE (lhs))) | |
1844 && (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)) | |
1845 || POINTER_TYPE_P (TREE_TYPE (rhs1)))) | |
1846 switch (get_gimple_rhs_class (subcode)) | |
1847 { | |
1848 case GIMPLE_SINGLE_RHS: | |
1849 val = get_value_for_expr (rhs1, true); | |
1850 break; | |
1851 | |
1852 case GIMPLE_UNARY_RHS: | |
1853 val = bit_value_unop (subcode, TREE_TYPE (lhs), rhs1); | |
1854 break; | |
1855 | |
1856 case GIMPLE_BINARY_RHS: | |
1857 val = bit_value_binop (subcode, TREE_TYPE (lhs), rhs1, | |
1858 gimple_assign_rhs2 (stmt)); | |
1859 break; | |
1860 | |
1861 default:; | |
1862 } | |
0 | 1863 } |
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
|
1864 else if (code == GIMPLE_COND) |
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
|
1865 { |
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
|
1866 enum tree_code code = gimple_cond_code (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
|
1867 tree rhs1 = gimple_cond_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
|
1868 tree rhs2 = gimple_cond_rhs (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
|
1869 if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)) |
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
|
1870 || POINTER_TYPE_P (TREE_TYPE (rhs1))) |
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
|
1871 val = bit_value_binop (code, TREE_TYPE (rhs1), rhs1, rhs2); |
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
|
1872 } |
111 | 1873 else if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) |
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
|
1874 { |
111 | 1875 tree fndecl = gimple_call_fndecl (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
|
1876 switch (DECL_FUNCTION_CODE (fndecl)) |
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
|
1877 { |
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
|
1878 case BUILT_IN_MALLOC: |
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
|
1879 case BUILT_IN_REALLOC: |
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
|
1880 case BUILT_IN_CALLOC: |
111 | 1881 case BUILT_IN_STRDUP: |
1882 case BUILT_IN_STRNDUP: | |
1883 val.lattice_val = CONSTANT; | |
1884 val.value = build_int_cst (TREE_TYPE (gimple_get_lhs (stmt)), 0); | |
1885 val.mask = ~((HOST_WIDE_INT) MALLOC_ABI_ALIGNMENT | |
1886 / BITS_PER_UNIT - 1); | |
1887 break; | |
1888 | |
1889 CASE_BUILT_IN_ALLOCA: | |
1890 align = (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA | |
1891 ? BIGGEST_ALIGNMENT | |
1892 : TREE_INT_CST_LOW (gimple_call_arg (stmt, 1))); | |
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
|
1893 val.lattice_val = CONSTANT; |
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
|
1894 val.value = build_int_cst (TREE_TYPE (gimple_get_lhs (stmt)), 0); |
111 | 1895 val.mask = ~((HOST_WIDE_INT) align / BITS_PER_UNIT - 1); |
1896 break; | |
1897 | |
1898 /* These builtins return their first argument, unmodified. */ | |
1899 case BUILT_IN_MEMCPY: | |
1900 case BUILT_IN_MEMMOVE: | |
1901 case BUILT_IN_MEMSET: | |
1902 case BUILT_IN_STRCPY: | |
1903 case BUILT_IN_STRNCPY: | |
1904 case BUILT_IN_MEMCPY_CHK: | |
1905 case BUILT_IN_MEMMOVE_CHK: | |
1906 case BUILT_IN_MEMSET_CHK: | |
1907 case BUILT_IN_STRCPY_CHK: | |
1908 case BUILT_IN_STRNCPY_CHK: | |
1909 val = get_value_for_expr (gimple_call_arg (stmt, 0), true); | |
1910 break; | |
1911 | |
1912 case BUILT_IN_ASSUME_ALIGNED: | |
1913 val = bit_value_assume_aligned (stmt, NULL_TREE, val, false); | |
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
|
1914 break; |
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
|
1915 |
111 | 1916 case BUILT_IN_ALIGNED_ALLOC: |
1917 { | |
1918 tree align = get_constant_value (gimple_call_arg (stmt, 0)); | |
1919 if (align | |
1920 && tree_fits_uhwi_p (align)) | |
1921 { | |
1922 unsigned HOST_WIDE_INT aligni = tree_to_uhwi (align); | |
1923 if (aligni > 1 | |
1924 /* align must be power-of-two */ | |
1925 && (aligni & (aligni - 1)) == 0) | |
1926 { | |
1927 val.lattice_val = CONSTANT; | |
1928 val.value = build_int_cst (ptr_type_node, 0); | |
1929 val.mask = -aligni; | |
1930 } | |
1931 } | |
1932 break; | |
1933 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1934 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1935 default:; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1936 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1937 } |
111 | 1938 if (is_gimple_call (stmt) && gimple_call_lhs (stmt)) |
1939 { | |
1940 tree fntype = gimple_call_fntype (stmt); | |
1941 if (fntype) | |
1942 { | |
1943 tree attrs = lookup_attribute ("assume_aligned", | |
1944 TYPE_ATTRIBUTES (fntype)); | |
1945 if (attrs) | |
1946 val = bit_value_assume_aligned (stmt, attrs, val, false); | |
1947 attrs = lookup_attribute ("alloc_align", | |
1948 TYPE_ATTRIBUTES (fntype)); | |
1949 if (attrs) | |
1950 val = bit_value_assume_aligned (stmt, attrs, val, true); | |
1951 } | |
1952 } | |
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
|
1953 is_constant = (val.lattice_val == CONSTANT); |
0 | 1954 } |
1955 | |
111 | 1956 if (flag_tree_bit_ccp |
1957 && ((is_constant && TREE_CODE (val.value) == INTEGER_CST) | |
1958 || !is_constant) | |
1959 && gimple_get_lhs (stmt) | |
1960 && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME) | |
1961 { | |
1962 tree lhs = gimple_get_lhs (stmt); | |
1963 wide_int nonzero_bits = get_nonzero_bits (lhs); | |
1964 if (nonzero_bits != -1) | |
1965 { | |
1966 if (!is_constant) | |
1967 { | |
1968 val.lattice_val = CONSTANT; | |
1969 val.value = build_zero_cst (TREE_TYPE (lhs)); | |
1970 val.mask = extend_mask (nonzero_bits, TYPE_SIGN (TREE_TYPE (lhs))); | |
1971 is_constant = true; | |
1972 } | |
1973 else | |
1974 { | |
1975 if (wi::bit_and_not (wi::to_wide (val.value), nonzero_bits) != 0) | |
1976 val.value = wide_int_to_tree (TREE_TYPE (lhs), | |
1977 nonzero_bits | |
1978 & wi::to_wide (val.value)); | |
1979 if (nonzero_bits == 0) | |
1980 val.mask = 0; | |
1981 else | |
1982 val.mask = val.mask & extend_mask (nonzero_bits, | |
1983 TYPE_SIGN (TREE_TYPE (lhs))); | |
1984 } | |
1985 } | |
1986 } | |
1987 | |
1988 /* The statement produced a nonconstant value. */ | |
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
|
1989 if (!is_constant) |
0 | 1990 { |
111 | 1991 /* The statement produced a copy. */ |
1992 if (simplified && TREE_CODE (simplified) == SSA_NAME | |
1993 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (simplified)) | |
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
|
1994 { |
111 | 1995 val.lattice_val = CONSTANT; |
1996 val.value = simplified; | |
1997 val.mask = -1; | |
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
|
1998 } |
111 | 1999 /* The statement is VARYING. */ |
0 | 2000 else |
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
|
2001 { |
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
|
2002 val.lattice_val = VARYING; |
111 | 2003 val.value = NULL_TREE; |
2004 val.mask = -1; | |
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
|
2005 } |
0 | 2006 } |
2007 | |
2008 return val; | |
2009 } | |
2010 | |
111 | 2011 typedef hash_table<nofree_ptr_hash<gimple> > gimple_htab; |
2012 | |
2013 /* Given a BUILT_IN_STACK_SAVE value SAVED_VAL, insert a clobber of VAR before | |
2014 each matching BUILT_IN_STACK_RESTORE. Mark visited phis in VISITED. */ | |
2015 | |
2016 static void | |
2017 insert_clobber_before_stack_restore (tree saved_val, tree var, | |
2018 gimple_htab **visited) | |
2019 { | |
2020 gimple *stmt; | |
2021 gassign *clobber_stmt; | |
2022 tree clobber; | |
2023 imm_use_iterator iter; | |
2024 gimple_stmt_iterator i; | |
2025 gimple **slot; | |
2026 | |
2027 FOR_EACH_IMM_USE_STMT (stmt, iter, saved_val) | |
2028 if (gimple_call_builtin_p (stmt, BUILT_IN_STACK_RESTORE)) | |
2029 { | |
2030 clobber = build_constructor (TREE_TYPE (var), | |
2031 NULL); | |
2032 TREE_THIS_VOLATILE (clobber) = 1; | |
2033 clobber_stmt = gimple_build_assign (var, clobber); | |
2034 | |
2035 i = gsi_for_stmt (stmt); | |
2036 gsi_insert_before (&i, clobber_stmt, GSI_SAME_STMT); | |
2037 } | |
2038 else if (gimple_code (stmt) == GIMPLE_PHI) | |
2039 { | |
2040 if (!*visited) | |
2041 *visited = new gimple_htab (10); | |
2042 | |
2043 slot = (*visited)->find_slot (stmt, INSERT); | |
2044 if (*slot != NULL) | |
2045 continue; | |
2046 | |
2047 *slot = stmt; | |
2048 insert_clobber_before_stack_restore (gimple_phi_result (stmt), var, | |
2049 visited); | |
2050 } | |
2051 else if (gimple_assign_ssa_name_copy_p (stmt)) | |
2052 insert_clobber_before_stack_restore (gimple_assign_lhs (stmt), var, | |
2053 visited); | |
2054 else if (chkp_gimple_call_builtin_p (stmt, BUILT_IN_CHKP_BNDRET)) | |
2055 continue; | |
2056 else | |
2057 gcc_assert (is_gimple_debug (stmt)); | |
2058 } | |
2059 | |
2060 /* Advance the iterator to the previous non-debug gimple statement in the same | |
2061 or dominating basic block. */ | |
2062 | |
2063 static inline void | |
2064 gsi_prev_dom_bb_nondebug (gimple_stmt_iterator *i) | |
2065 { | |
2066 basic_block dom; | |
2067 | |
2068 gsi_prev_nondebug (i); | |
2069 while (gsi_end_p (*i)) | |
2070 { | |
2071 dom = get_immediate_dominator (CDI_DOMINATORS, i->bb); | |
2072 if (dom == NULL || dom == ENTRY_BLOCK_PTR_FOR_FN (cfun)) | |
2073 return; | |
2074 | |
2075 *i = gsi_last_bb (dom); | |
2076 } | |
2077 } | |
2078 | |
2079 /* Find a BUILT_IN_STACK_SAVE dominating gsi_stmt (I), and insert | |
2080 a clobber of VAR before each matching BUILT_IN_STACK_RESTORE. | |
2081 | |
2082 It is possible that BUILT_IN_STACK_SAVE cannot be find in a dominator when a | |
2083 previous pass (such as DOM) duplicated it along multiple paths to a BB. In | |
2084 that case the function gives up without inserting the clobbers. */ | |
2085 | |
2086 static void | |
2087 insert_clobbers_for_var (gimple_stmt_iterator i, tree var) | |
2088 { | |
2089 gimple *stmt; | |
2090 tree saved_val; | |
2091 gimple_htab *visited = NULL; | |
2092 | |
2093 for (; !gsi_end_p (i); gsi_prev_dom_bb_nondebug (&i)) | |
2094 { | |
2095 stmt = gsi_stmt (i); | |
2096 | |
2097 if (!gimple_call_builtin_p (stmt, BUILT_IN_STACK_SAVE)) | |
2098 continue; | |
2099 | |
2100 saved_val = gimple_call_lhs (stmt); | |
2101 if (saved_val == NULL_TREE) | |
2102 continue; | |
2103 | |
2104 insert_clobber_before_stack_restore (saved_val, var, &visited); | |
2105 break; | |
2106 } | |
2107 | |
2108 delete visited; | |
2109 } | |
2110 | |
2111 /* Detects a __builtin_alloca_with_align with constant size argument. Declares | |
2112 fixed-size array and returns the address, if found, otherwise returns | |
2113 NULL_TREE. */ | |
2114 | |
2115 static tree | |
2116 fold_builtin_alloca_with_align (gimple *stmt) | |
2117 { | |
2118 unsigned HOST_WIDE_INT size, threshold, n_elem; | |
2119 tree lhs, arg, block, var, elem_type, array_type; | |
2120 | |
2121 /* Get lhs. */ | |
2122 lhs = gimple_call_lhs (stmt); | |
2123 if (lhs == NULL_TREE) | |
2124 return NULL_TREE; | |
2125 | |
2126 /* Detect constant argument. */ | |
2127 arg = get_constant_value (gimple_call_arg (stmt, 0)); | |
2128 if (arg == NULL_TREE | |
2129 || TREE_CODE (arg) != INTEGER_CST | |
2130 || !tree_fits_uhwi_p (arg)) | |
2131 return NULL_TREE; | |
2132 | |
2133 size = tree_to_uhwi (arg); | |
2134 | |
2135 /* Heuristic: don't fold large allocas. */ | |
2136 threshold = (unsigned HOST_WIDE_INT)PARAM_VALUE (PARAM_LARGE_STACK_FRAME); | |
2137 /* In case the alloca is located at function entry, it has the same lifetime | |
2138 as a declared array, so we allow a larger size. */ | |
2139 block = gimple_block (stmt); | |
2140 if (!(cfun->after_inlining | |
2141 && block | |
2142 && TREE_CODE (BLOCK_SUPERCONTEXT (block)) == FUNCTION_DECL)) | |
2143 threshold /= 10; | |
2144 if (size > threshold) | |
2145 return NULL_TREE; | |
2146 | |
2147 /* Declare array. */ | |
2148 elem_type = build_nonstandard_integer_type (BITS_PER_UNIT, 1); | |
2149 n_elem = size * 8 / BITS_PER_UNIT; | |
2150 array_type = build_array_type_nelts (elem_type, n_elem); | |
2151 var = create_tmp_var (array_type); | |
2152 SET_DECL_ALIGN (var, TREE_INT_CST_LOW (gimple_call_arg (stmt, 1))); | |
2153 { | |
2154 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs); | |
2155 if (pi != NULL && !pi->pt.anything) | |
2156 { | |
2157 bool singleton_p; | |
2158 unsigned uid; | |
2159 singleton_p = pt_solution_singleton_or_null_p (&pi->pt, &uid); | |
2160 gcc_assert (singleton_p); | |
2161 SET_DECL_PT_UID (var, uid); | |
2162 } | |
2163 } | |
2164 | |
2165 /* Fold alloca to the address of the array. */ | |
2166 return fold_convert (TREE_TYPE (lhs), build_fold_addr_expr (var)); | |
2167 } | |
2168 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2169 /* Fold the stmt at *GSI with CCP specific information that propagating |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2170 and regular folding does not catch. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2171 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2172 static bool |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2173 ccp_fold_stmt (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
|
2174 { |
111 | 2175 gimple *stmt = gsi_stmt (*gsi); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2176 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2177 switch (gimple_code (stmt)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2178 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2179 case GIMPLE_COND: |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2180 { |
111 | 2181 gcond *cond_stmt = as_a <gcond *> (stmt); |
2182 ccp_prop_value_t val; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2183 /* Statement evaluation will handle type mismatches in constants |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2184 more gracefully than the final propagation. This allows us to |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2185 fold more conditionals here. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2186 val = evaluate_stmt (stmt); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2187 if (val.lattice_val != CONSTANT |
111 | 2188 || val.mask != 0) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2189 return false; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2190 |
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
|
2191 if (dump_file) |
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
|
2192 { |
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
|
2193 fprintf (dump_file, "Folding predicate "); |
111 | 2194 print_gimple_expr (dump_file, stmt, 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
|
2195 fprintf (dump_file, " to "); |
111 | 2196 print_generic_expr (dump_file, val.value); |
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
|
2197 fprintf (dump_file, "\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
|
2198 } |
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
|
2199 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2200 if (integer_zerop (val.value)) |
111 | 2201 gimple_cond_make_false (cond_stmt); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2202 else |
111 | 2203 gimple_cond_make_true (cond_stmt); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2204 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2205 return true; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2206 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2207 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2208 case GIMPLE_CALL: |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2209 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2210 tree lhs = gimple_call_lhs (stmt); |
111 | 2211 int flags = gimple_call_flags (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
|
2212 tree val; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2213 tree argt; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2214 bool changed = false; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2215 unsigned i; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2216 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2217 /* If the call was folded into a constant make sure it goes |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2218 away even if we cannot propagate into all uses because of |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2219 type issues. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2220 if (lhs |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2221 && TREE_CODE (lhs) == SSA_NAME |
111 | 2222 && (val = get_constant_value (lhs)) |
2223 /* Don't optimize away calls that have side-effects. */ | |
2224 && (flags & (ECF_CONST|ECF_PURE)) != 0 | |
2225 && (flags & ECF_LOOPING_CONST_OR_PURE) == 0) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2226 { |
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
|
2227 tree new_rhs = unshare_expr (val); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2228 bool res; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2229 if (!useless_type_conversion_p (TREE_TYPE (lhs), |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2230 TREE_TYPE (new_rhs))) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2231 new_rhs = fold_convert (TREE_TYPE (lhs), new_rhs); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2232 res = update_call_from_tree (gsi, new_rhs); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2233 gcc_assert (res); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2234 return true; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2235 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2236 |
111 | 2237 /* Internal calls provide no argument types, so the extra laxity |
2238 for normal calls does not apply. */ | |
2239 if (gimple_call_internal_p (stmt)) | |
2240 return false; | |
2241 | |
2242 /* The heuristic of fold_builtin_alloca_with_align differs before and | |
2243 after inlining, so we don't require the arg to be changed into a | |
2244 constant for folding, but just to be constant. */ | |
2245 if (gimple_call_builtin_p (stmt, BUILT_IN_ALLOCA_WITH_ALIGN) | |
2246 || gimple_call_builtin_p (stmt, BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX)) | |
2247 { | |
2248 tree new_rhs = fold_builtin_alloca_with_align (stmt); | |
2249 if (new_rhs) | |
2250 { | |
2251 bool res = update_call_from_tree (gsi, new_rhs); | |
2252 tree var = TREE_OPERAND (TREE_OPERAND (new_rhs, 0),0); | |
2253 gcc_assert (res); | |
2254 insert_clobbers_for_var (*gsi, var); | |
2255 return true; | |
2256 } | |
2257 } | |
2258 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2259 /* Propagate into the call arguments. Compared to replace_uses_in |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2260 this can use the argument slot types for type verification |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2261 instead of the current argument type. We also can safely |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2262 drop qualifiers here as we are dealing with constants anyway. */ |
111 | 2263 argt = TYPE_ARG_TYPES (gimple_call_fntype (stmt)); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2264 for (i = 0; i < gimple_call_num_args (stmt) && argt; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2265 ++i, argt = TREE_CHAIN (argt)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2266 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2267 tree arg = gimple_call_arg (stmt, i); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2268 if (TREE_CODE (arg) == SSA_NAME |
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
|
2269 && (val = get_constant_value (arg)) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2270 && useless_type_conversion_p |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2271 (TYPE_MAIN_VARIANT (TREE_VALUE (argt)), |
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
|
2272 TYPE_MAIN_VARIANT (TREE_TYPE (val)))) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2273 { |
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
|
2274 gimple_call_set_arg (stmt, i, unshare_expr (val)); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2275 changed = true; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2276 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2277 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2278 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2279 return changed; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2280 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2281 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2282 case GIMPLE_ASSIGN: |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2283 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2284 tree lhs = gimple_assign_lhs (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
|
2285 tree val; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2286 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2287 /* If we have a load that turned out to be constant replace it |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2288 as we cannot propagate into all uses in all cases. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2289 if (gimple_assign_single_p (stmt) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2290 && TREE_CODE (lhs) == SSA_NAME |
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
|
2291 && (val = get_constant_value (lhs))) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2292 { |
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
|
2293 tree rhs = unshare_expr (val); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2294 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (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
|
2295 rhs = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2296 gimple_assign_set_rhs_from_tree (gsi, rhs); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2297 return true; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2298 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2299 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2300 return false; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2301 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2302 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2303 default: |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2304 return false; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2305 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2306 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2307 |
0 | 2308 /* Visit the assignment statement STMT. Set the value of its LHS to the |
2309 value computed by the RHS and store LHS in *OUTPUT_P. If STMT | |
2310 creates virtual definitions, set the value of each new name to that | |
2311 of the RHS (if we can derive a constant out of the RHS). | |
2312 Value-returning call statements also perform an assignment, and | |
2313 are handled here. */ | |
2314 | |
2315 static enum ssa_prop_result | |
111 | 2316 visit_assignment (gimple *stmt, tree *output_p) |
0 | 2317 { |
111 | 2318 ccp_prop_value_t val; |
2319 enum ssa_prop_result retval = SSA_PROP_NOT_INTERESTING; | |
0 | 2320 |
2321 tree lhs = gimple_get_lhs (stmt); | |
2322 if (TREE_CODE (lhs) == SSA_NAME) | |
2323 { | |
111 | 2324 /* Evaluate the statement, which could be |
2325 either a GIMPLE_ASSIGN or a GIMPLE_CALL. */ | |
2326 val = evaluate_stmt (stmt); | |
2327 | |
0 | 2328 /* If STMT is an assignment to an SSA_NAME, we only have one |
2329 value to set. */ | |
111 | 2330 if (set_lattice_value (lhs, &val)) |
0 | 2331 { |
2332 *output_p = lhs; | |
2333 if (val.lattice_val == VARYING) | |
2334 retval = SSA_PROP_VARYING; | |
2335 else | |
2336 retval = SSA_PROP_INTERESTING; | |
2337 } | |
2338 } | |
2339 | |
2340 return retval; | |
2341 } | |
2342 | |
2343 | |
2344 /* Visit the conditional statement STMT. Return SSA_PROP_INTERESTING | |
2345 if it can determine which edge will be taken. Otherwise, return | |
2346 SSA_PROP_VARYING. */ | |
2347 | |
2348 static enum ssa_prop_result | |
111 | 2349 visit_cond_stmt (gimple *stmt, edge *taken_edge_p) |
0 | 2350 { |
111 | 2351 ccp_prop_value_t val; |
0 | 2352 basic_block block; |
2353 | |
2354 block = gimple_bb (stmt); | |
2355 val = evaluate_stmt (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
|
2356 if (val.lattice_val != CONSTANT |
111 | 2357 || val.mask != 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
|
2358 return SSA_PROP_VARYING; |
0 | 2359 |
2360 /* Find which edge out of the conditional block will be taken and add it | |
2361 to the worklist. If no single edge can be determined statically, | |
2362 return SSA_PROP_VARYING to feed all the outgoing edges to the | |
2363 propagation engine. */ | |
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
|
2364 *taken_edge_p = find_taken_edge (block, val.value); |
0 | 2365 if (*taken_edge_p) |
2366 return SSA_PROP_INTERESTING; | |
2367 else | |
2368 return SSA_PROP_VARYING; | |
2369 } | |
2370 | |
2371 | |
2372 /* Evaluate statement STMT. If the statement produces an output value and | |
2373 its evaluation changes the lattice value of its output, return | |
2374 SSA_PROP_INTERESTING and set *OUTPUT_P to the SSA_NAME holding the | |
2375 output value. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2376 |
0 | 2377 If STMT is a conditional branch and we can determine its truth |
2378 value, set *TAKEN_EDGE_P accordingly. If STMT produces a varying | |
2379 value, return SSA_PROP_VARYING. */ | |
2380 | |
2381 static enum ssa_prop_result | |
111 | 2382 ccp_visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p) |
0 | 2383 { |
2384 tree def; | |
2385 ssa_op_iter iter; | |
2386 | |
2387 if (dump_file && (dump_flags & TDF_DETAILS)) | |
2388 { | |
2389 fprintf (dump_file, "\nVisiting statement:\n"); | |
2390 print_gimple_stmt (dump_file, stmt, 0, dump_flags); | |
2391 } | |
2392 | |
2393 switch (gimple_code (stmt)) | |
2394 { | |
2395 case GIMPLE_ASSIGN: | |
2396 /* If the statement is an assignment that produces a single | |
2397 output value, evaluate its RHS to see if the lattice value of | |
2398 its output has changed. */ | |
2399 return visit_assignment (stmt, output_p); | |
2400 | |
2401 case GIMPLE_CALL: | |
2402 /* A value-returning call also performs an assignment. */ | |
2403 if (gimple_call_lhs (stmt) != NULL_TREE) | |
2404 return visit_assignment (stmt, output_p); | |
2405 break; | |
2406 | |
2407 case GIMPLE_COND: | |
2408 case GIMPLE_SWITCH: | |
2409 /* If STMT is a conditional branch, see if we can determine | |
2410 which branch will be taken. */ | |
2411 /* FIXME. It appears that we should be able to optimize | |
2412 computed GOTOs here as well. */ | |
2413 return visit_cond_stmt (stmt, taken_edge_p); | |
2414 | |
2415 default: | |
2416 break; | |
2417 } | |
2418 | |
2419 /* Any other kind of statement is not interesting for constant | |
2420 propagation and, therefore, not worth simulating. */ | |
2421 if (dump_file && (dump_flags & TDF_DETAILS)) | |
2422 fprintf (dump_file, "No interesting values produced. Marked VARYING.\n"); | |
2423 | |
2424 /* Definitions made by statements other than assignments to | |
2425 SSA_NAMEs represent unknown modifications to their outputs. | |
2426 Mark them VARYING. */ | |
2427 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS) | |
111 | 2428 set_value_varying (def); |
0 | 2429 |
2430 return SSA_PROP_VARYING; | |
2431 } | |
2432 | |
2433 | |
111 | 2434 /* Main entry point for SSA Conditional Constant Propagation. If NONZERO_P, |
2435 record nonzero bits. */ | |
0 | 2436 |
2437 static unsigned int | |
111 | 2438 do_ssa_ccp (bool nonzero_p) |
0 | 2439 { |
111 | 2440 unsigned int todo = 0; |
2441 calculate_dominance_info (CDI_DOMINATORS); | |
2442 | |
0 | 2443 ccp_initialize (); |
2444 ssa_propagate (ccp_visit_stmt, ccp_visit_phi_node); | |
111 | 2445 if (ccp_finalize (nonzero_p || flag_ipa_bit_cp)) |
2446 { | |
2447 todo = (TODO_cleanup_cfg | TODO_update_ssa); | |
2448 | |
2449 /* ccp_finalize does not preserve loop-closed ssa. */ | |
2450 loops_state_clear (LOOP_CLOSED_SSA); | |
2451 } | |
2452 | |
2453 free_dominance_info (CDI_DOMINATORS); | |
2454 return todo; | |
0 | 2455 } |
2456 | |
2457 | |
111 | 2458 namespace { |
2459 | |
2460 const pass_data pass_data_ccp = | |
0 | 2461 { |
111 | 2462 GIMPLE_PASS, /* type */ |
2463 "ccp", /* name */ | |
2464 OPTGROUP_NONE, /* optinfo_flags */ | |
2465 TV_TREE_CCP, /* tv_id */ | |
2466 ( PROP_cfg | PROP_ssa ), /* properties_required */ | |
2467 0, /* properties_provided */ | |
2468 0, /* properties_destroyed */ | |
2469 0, /* todo_flags_start */ | |
2470 TODO_update_address_taken, /* todo_flags_finish */ | |
0 | 2471 }; |
2472 | |
111 | 2473 class pass_ccp : public gimple_opt_pass |
2474 { | |
2475 public: | |
2476 pass_ccp (gcc::context *ctxt) | |
2477 : gimple_opt_pass (pass_data_ccp, ctxt), nonzero_p (false) | |
2478 {} | |
2479 | |
2480 /* opt_pass methods: */ | |
2481 opt_pass * clone () { return new pass_ccp (m_ctxt); } | |
2482 void set_pass_param (unsigned int n, bool param) | |
2483 { | |
2484 gcc_assert (n == 0); | |
2485 nonzero_p = param; | |
2486 } | |
2487 virtual bool gate (function *) { return flag_tree_ccp != 0; } | |
2488 virtual unsigned int execute (function *) { return do_ssa_ccp (nonzero_p); } | |
2489 | |
2490 private: | |
2491 /* Determines whether the pass instance records nonzero bits. */ | |
2492 bool nonzero_p; | |
2493 }; // class pass_ccp | |
2494 | |
2495 } // anon namespace | |
2496 | |
2497 gimple_opt_pass * | |
2498 make_pass_ccp (gcc::context *ctxt) | |
2499 { | |
2500 return new pass_ccp (ctxt); | |
2501 } | |
2502 | |
0 | 2503 |
2504 | |
2505 /* Try to optimize out __builtin_stack_restore. Optimize it out | |
2506 if there is another __builtin_stack_restore in the same basic | |
2507 block and no calls or ASM_EXPRs are in between, or if this block's | |
2508 only outgoing edge is to EXIT_BLOCK and there are no calls or | |
2509 ASM_EXPRs after this __builtin_stack_restore. */ | |
2510 | |
2511 static tree | |
2512 optimize_stack_restore (gimple_stmt_iterator i) | |
2513 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2514 tree callee; |
111 | 2515 gimple *stmt; |
0 | 2516 |
2517 basic_block bb = gsi_bb (i); | |
111 | 2518 gimple *call = gsi_stmt (i); |
0 | 2519 |
2520 if (gimple_code (call) != GIMPLE_CALL | |
2521 || gimple_call_num_args (call) != 1 | |
2522 || TREE_CODE (gimple_call_arg (call, 0)) != SSA_NAME | |
2523 || !POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, 0)))) | |
2524 return NULL_TREE; | |
2525 | |
2526 for (gsi_next (&i); !gsi_end_p (i); gsi_next (&i)) | |
2527 { | |
2528 stmt = gsi_stmt (i); | |
2529 if (gimple_code (stmt) == GIMPLE_ASM) | |
2530 return NULL_TREE; | |
2531 if (gimple_code (stmt) != GIMPLE_CALL) | |
2532 continue; | |
2533 | |
2534 callee = gimple_call_fndecl (stmt); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2535 if (!callee |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2536 || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2537 /* All regular builtins are ok, just obviously not alloca. */ |
111 | 2538 || ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callee))) |
0 | 2539 return NULL_TREE; |
2540 | |
2541 if (DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2542 goto second_stack_restore; |
0 | 2543 } |
2544 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2545 if (!gsi_end_p (i)) |
0 | 2546 return NULL_TREE; |
2547 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2548 /* Allow one successor of the exit block, or zero successors. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2549 switch (EDGE_COUNT (bb->succs)) |
0 | 2550 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2551 case 0: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2552 break; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2553 case 1: |
111 | 2554 if (single_succ_edge (bb)->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2555 return NULL_TREE; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2556 break; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2557 default: |
0 | 2558 return NULL_TREE; |
2559 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2560 second_stack_restore: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2561 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2562 /* If there's exactly one use, then zap the call to __builtin_stack_save. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2563 If there are multiple uses, then the last one should remove the call. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2564 In any case, whether the call to __builtin_stack_save can be removed |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2565 or not is irrelevant to removing the call to __builtin_stack_restore. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2566 if (has_single_use (gimple_call_arg (call, 0))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2567 { |
111 | 2568 gimple *stack_save = SSA_NAME_DEF_STMT (gimple_call_arg (call, 0)); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2569 if (is_gimple_call (stack_save)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2570 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2571 callee = gimple_call_fndecl (stack_save); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2572 if (callee |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2573 && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2574 && DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2575 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2576 gimple_stmt_iterator stack_save_gsi; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2577 tree rhs; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2578 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2579 stack_save_gsi = gsi_for_stmt (stack_save); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2580 rhs = build_int_cst (TREE_TYPE (gimple_call_arg (call, 0)), 0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2581 update_call_from_tree (&stack_save_gsi, rhs); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2582 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2583 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2584 } |
0 | 2585 |
2586 /* No effect, so the statement will be deleted. */ | |
2587 return integer_zero_node; | |
2588 } | |
2589 | |
2590 /* If va_list type is a simple pointer and nothing special is needed, | |
2591 optimize __builtin_va_start (&ap, 0) into ap = __builtin_next_arg (0), | |
2592 __builtin_va_end (&ap) out as NOP and __builtin_va_copy into a simple | |
2593 pointer assignment. */ | |
2594 | |
2595 static tree | |
111 | 2596 optimize_stdarg_builtin (gimple *call) |
0 | 2597 { |
2598 tree callee, lhs, rhs, cfun_va_list; | |
2599 bool va_list_simple_ptr; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2600 location_t loc = gimple_location (call); |
0 | 2601 |
2602 if (gimple_code (call) != GIMPLE_CALL) | |
2603 return NULL_TREE; | |
2604 | |
2605 callee = gimple_call_fndecl (call); | |
2606 | |
2607 cfun_va_list = targetm.fn_abi_va_list (callee); | |
2608 va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list) | |
2609 && (TREE_TYPE (cfun_va_list) == void_type_node | |
2610 || TREE_TYPE (cfun_va_list) == char_type_node); | |
2611 | |
2612 switch (DECL_FUNCTION_CODE (callee)) | |
2613 { | |
2614 case BUILT_IN_VA_START: | |
2615 if (!va_list_simple_ptr | |
2616 || targetm.expand_builtin_va_start != NULL | |
111 | 2617 || !builtin_decl_explicit_p (BUILT_IN_NEXT_ARG)) |
0 | 2618 return NULL_TREE; |
2619 | |
2620 if (gimple_call_num_args (call) != 2) | |
2621 return NULL_TREE; | |
2622 | |
2623 lhs = gimple_call_arg (call, 0); | |
2624 if (!POINTER_TYPE_P (TREE_TYPE (lhs)) | |
2625 || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs))) | |
2626 != TYPE_MAIN_VARIANT (cfun_va_list)) | |
2627 return NULL_TREE; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2628 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2629 lhs = build_fold_indirect_ref_loc (loc, lhs); |
111 | 2630 rhs = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_NEXT_ARG), |
0 | 2631 1, integer_zero_node); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2632 rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs); |
0 | 2633 return build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs); |
2634 | |
2635 case BUILT_IN_VA_COPY: | |
2636 if (!va_list_simple_ptr) | |
2637 return NULL_TREE; | |
2638 | |
2639 if (gimple_call_num_args (call) != 2) | |
2640 return NULL_TREE; | |
2641 | |
2642 lhs = gimple_call_arg (call, 0); | |
2643 if (!POINTER_TYPE_P (TREE_TYPE (lhs)) | |
2644 || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs))) | |
2645 != TYPE_MAIN_VARIANT (cfun_va_list)) | |
2646 return NULL_TREE; | |
2647 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2648 lhs = build_fold_indirect_ref_loc (loc, lhs); |
0 | 2649 rhs = gimple_call_arg (call, 1); |
2650 if (TYPE_MAIN_VARIANT (TREE_TYPE (rhs)) | |
2651 != TYPE_MAIN_VARIANT (cfun_va_list)) | |
2652 return NULL_TREE; | |
2653 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
2654 rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs); |
0 | 2655 return build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs); |
2656 | |
2657 case BUILT_IN_VA_END: | |
2658 /* No effect, so the statement will be deleted. */ | |
2659 return integer_zero_node; | |
2660 | |
2661 default: | |
2662 gcc_unreachable (); | |
2663 } | |
2664 } | |
2665 | |
111 | 2666 /* Attemp to make the block of __builtin_unreachable I unreachable by changing |
2667 the incoming jumps. Return true if at least one jump was changed. */ | |
2668 | |
2669 static bool | |
2670 optimize_unreachable (gimple_stmt_iterator i) | |
2671 { | |
2672 basic_block bb = gsi_bb (i); | |
2673 gimple_stmt_iterator gsi; | |
2674 gimple *stmt; | |
2675 edge_iterator ei; | |
2676 edge e; | |
2677 bool ret; | |
2678 | |
2679 if (flag_sanitize & SANITIZE_UNREACHABLE) | |
2680 return false; | |
2681 | |
2682 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
2683 { | |
2684 stmt = gsi_stmt (gsi); | |
2685 | |
2686 if (is_gimple_debug (stmt)) | |
2687 continue; | |
2688 | |
2689 if (glabel *label_stmt = dyn_cast <glabel *> (stmt)) | |
2690 { | |
2691 /* Verify we do not need to preserve the label. */ | |
2692 if (FORCED_LABEL (gimple_label_label (label_stmt))) | |
2693 return false; | |
2694 | |
2695 continue; | |
2696 } | |
2697 | |
2698 /* Only handle the case that __builtin_unreachable is the first statement | |
2699 in the block. We rely on DCE to remove stmts without side-effects | |
2700 before __builtin_unreachable. */ | |
2701 if (gsi_stmt (gsi) != gsi_stmt (i)) | |
2702 return false; | |
2703 } | |
2704 | |
2705 ret = false; | |
2706 FOR_EACH_EDGE (e, ei, bb->preds) | |
2707 { | |
2708 gsi = gsi_last_bb (e->src); | |
2709 if (gsi_end_p (gsi)) | |
2710 continue; | |
2711 | |
2712 stmt = gsi_stmt (gsi); | |
2713 if (gcond *cond_stmt = dyn_cast <gcond *> (stmt)) | |
2714 { | |
2715 if (e->flags & EDGE_TRUE_VALUE) | |
2716 gimple_cond_make_false (cond_stmt); | |
2717 else if (e->flags & EDGE_FALSE_VALUE) | |
2718 gimple_cond_make_true (cond_stmt); | |
2719 else | |
2720 gcc_unreachable (); | |
2721 update_stmt (cond_stmt); | |
2722 } | |
2723 else | |
2724 { | |
2725 /* Todo: handle other cases. Note that unreachable switch case | |
2726 statements have already been removed. */ | |
2727 continue; | |
2728 } | |
2729 | |
2730 ret = true; | |
2731 } | |
2732 | |
2733 return ret; | |
2734 } | |
2735 | |
2736 /* Optimize | |
2737 mask_2 = 1 << cnt_1; | |
2738 _4 = __atomic_fetch_or_* (ptr_6, mask_2, _3); | |
2739 _5 = _4 & mask_2; | |
2740 to | |
2741 _4 = ATOMIC_BIT_TEST_AND_SET (ptr_6, cnt_1, 0, _3); | |
2742 _5 = _4; | |
2743 If _5 is only used in _5 != 0 or _5 == 0 comparisons, 1 | |
2744 is passed instead of 0, and the builtin just returns a zero | |
2745 or 1 value instead of the actual bit. | |
2746 Similarly for __sync_fetch_and_or_* (without the ", _3" part | |
2747 in there), and/or if mask_2 is a power of 2 constant. | |
2748 Similarly for xor instead of or, use ATOMIC_BIT_TEST_AND_COMPLEMENT | |
2749 in that case. And similarly for and instead of or, except that | |
2750 the second argument to the builtin needs to be one's complement | |
2751 of the mask instead of mask. */ | |
2752 | |
2753 static void | |
2754 optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip, | |
2755 enum internal_fn fn, bool has_model_arg, | |
2756 bool after) | |
2757 { | |
2758 gimple *call = gsi_stmt (*gsip); | |
2759 tree lhs = gimple_call_lhs (call); | |
2760 use_operand_p use_p; | |
2761 gimple *use_stmt; | |
2762 tree mask, bit; | |
2763 optab optab; | |
2764 | |
2765 if (!flag_inline_atomics | |
2766 || optimize_debug | |
2767 || !gimple_call_builtin_p (call, BUILT_IN_NORMAL) | |
2768 || !lhs | |
2769 || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs) | |
2770 || !single_imm_use (lhs, &use_p, &use_stmt) | |
2771 || !is_gimple_assign (use_stmt) | |
2772 || gimple_assign_rhs_code (use_stmt) != BIT_AND_EXPR | |
2773 || !gimple_vdef (call)) | |
2774 return; | |
2775 | |
2776 switch (fn) | |
2777 { | |
2778 case IFN_ATOMIC_BIT_TEST_AND_SET: | |
2779 optab = atomic_bit_test_and_set_optab; | |
2780 break; | |
2781 case IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT: | |
2782 optab = atomic_bit_test_and_complement_optab; | |
2783 break; | |
2784 case IFN_ATOMIC_BIT_TEST_AND_RESET: | |
2785 optab = atomic_bit_test_and_reset_optab; | |
2786 break; | |
2787 default: | |
2788 return; | |
2789 } | |
2790 | |
2791 if (optab_handler (optab, TYPE_MODE (TREE_TYPE (lhs))) == CODE_FOR_nothing) | |
2792 return; | |
2793 | |
2794 mask = gimple_call_arg (call, 1); | |
2795 tree use_lhs = gimple_assign_lhs (use_stmt); | |
2796 if (!use_lhs) | |
2797 return; | |
2798 | |
2799 if (TREE_CODE (mask) == INTEGER_CST) | |
2800 { | |
2801 if (fn == IFN_ATOMIC_BIT_TEST_AND_RESET) | |
2802 mask = const_unop (BIT_NOT_EXPR, TREE_TYPE (mask), mask); | |
2803 mask = fold_convert (TREE_TYPE (lhs), mask); | |
2804 int ibit = tree_log2 (mask); | |
2805 if (ibit < 0) | |
2806 return; | |
2807 bit = build_int_cst (TREE_TYPE (lhs), ibit); | |
2808 } | |
2809 else if (TREE_CODE (mask) == SSA_NAME) | |
2810 { | |
2811 gimple *g = SSA_NAME_DEF_STMT (mask); | |
2812 if (fn == IFN_ATOMIC_BIT_TEST_AND_RESET) | |
2813 { | |
2814 if (!is_gimple_assign (g) | |
2815 || gimple_assign_rhs_code (g) != BIT_NOT_EXPR) | |
2816 return; | |
2817 mask = gimple_assign_rhs1 (g); | |
2818 if (TREE_CODE (mask) != SSA_NAME) | |
2819 return; | |
2820 g = SSA_NAME_DEF_STMT (mask); | |
2821 } | |
2822 if (!is_gimple_assign (g) | |
2823 || gimple_assign_rhs_code (g) != LSHIFT_EXPR | |
2824 || !integer_onep (gimple_assign_rhs1 (g))) | |
2825 return; | |
2826 bit = gimple_assign_rhs2 (g); | |
2827 } | |
2828 else | |
2829 return; | |
2830 | |
2831 if (gimple_assign_rhs1 (use_stmt) == lhs) | |
2832 { | |
2833 if (!operand_equal_p (gimple_assign_rhs2 (use_stmt), mask, 0)) | |
2834 return; | |
2835 } | |
2836 else if (gimple_assign_rhs2 (use_stmt) != lhs | |
2837 || !operand_equal_p (gimple_assign_rhs1 (use_stmt), mask, 0)) | |
2838 return; | |
2839 | |
2840 bool use_bool = true; | |
2841 bool has_debug_uses = false; | |
2842 imm_use_iterator iter; | |
2843 gimple *g; | |
2844 | |
2845 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use_lhs)) | |
2846 use_bool = false; | |
2847 FOR_EACH_IMM_USE_STMT (g, iter, use_lhs) | |
2848 { | |
2849 enum tree_code code = ERROR_MARK; | |
2850 tree op0 = NULL_TREE, op1 = NULL_TREE; | |
2851 if (is_gimple_debug (g)) | |
2852 { | |
2853 has_debug_uses = true; | |
2854 continue; | |
2855 } | |
2856 else if (is_gimple_assign (g)) | |
2857 switch (gimple_assign_rhs_code (g)) | |
2858 { | |
2859 case COND_EXPR: | |
2860 op1 = gimple_assign_rhs1 (g); | |
2861 code = TREE_CODE (op1); | |
2862 op0 = TREE_OPERAND (op1, 0); | |
2863 op1 = TREE_OPERAND (op1, 1); | |
2864 break; | |
2865 case EQ_EXPR: | |
2866 case NE_EXPR: | |
2867 code = gimple_assign_rhs_code (g); | |
2868 op0 = gimple_assign_rhs1 (g); | |
2869 op1 = gimple_assign_rhs2 (g); | |
2870 break; | |
2871 default: | |
2872 break; | |
2873 } | |
2874 else if (gimple_code (g) == GIMPLE_COND) | |
2875 { | |
2876 code = gimple_cond_code (g); | |
2877 op0 = gimple_cond_lhs (g); | |
2878 op1 = gimple_cond_rhs (g); | |
2879 } | |
2880 | |
2881 if ((code == EQ_EXPR || code == NE_EXPR) | |
2882 && op0 == use_lhs | |
2883 && integer_zerop (op1)) | |
2884 { | |
2885 use_operand_p use_p; | |
2886 int n = 0; | |
2887 FOR_EACH_IMM_USE_ON_STMT (use_p, iter) | |
2888 n++; | |
2889 if (n == 1) | |
2890 continue; | |
2891 } | |
2892 | |
2893 use_bool = false; | |
2894 BREAK_FROM_IMM_USE_STMT (iter); | |
2895 } | |
2896 | |
2897 tree new_lhs = make_ssa_name (TREE_TYPE (lhs)); | |
2898 tree flag = build_int_cst (TREE_TYPE (lhs), use_bool); | |
2899 if (has_model_arg) | |
2900 g = gimple_build_call_internal (fn, 4, gimple_call_arg (call, 0), | |
2901 bit, flag, gimple_call_arg (call, 2)); | |
2902 else | |
2903 g = gimple_build_call_internal (fn, 3, gimple_call_arg (call, 0), | |
2904 bit, flag); | |
2905 gimple_call_set_lhs (g, new_lhs); | |
2906 gimple_set_location (g, gimple_location (call)); | |
2907 gimple_set_vuse (g, gimple_vuse (call)); | |
2908 gimple_set_vdef (g, gimple_vdef (call)); | |
2909 bool throws = stmt_can_throw_internal (call); | |
2910 gimple_call_set_nothrow (as_a <gcall *> (g), | |
2911 gimple_call_nothrow_p (as_a <gcall *> (call))); | |
2912 SSA_NAME_DEF_STMT (gimple_vdef (call)) = g; | |
2913 gimple_stmt_iterator gsi = *gsip; | |
2914 gsi_insert_after (&gsi, g, GSI_NEW_STMT); | |
2915 edge e = NULL; | |
2916 if (throws) | |
2917 { | |
2918 maybe_clean_or_replace_eh_stmt (call, g); | |
2919 if (after || (use_bool && has_debug_uses)) | |
2920 e = find_fallthru_edge (gsi_bb (gsi)->succs); | |
2921 } | |
2922 if (after) | |
2923 { | |
2924 /* The internal function returns the value of the specified bit | |
2925 before the atomic operation. If we are interested in the value | |
2926 of the specified bit after the atomic operation (makes only sense | |
2927 for xor, otherwise the bit content is compile time known), | |
2928 we need to invert the bit. */ | |
2929 g = gimple_build_assign (make_ssa_name (TREE_TYPE (lhs)), | |
2930 BIT_XOR_EXPR, new_lhs, | |
2931 use_bool ? build_int_cst (TREE_TYPE (lhs), 1) | |
2932 : mask); | |
2933 new_lhs = gimple_assign_lhs (g); | |
2934 if (throws) | |
2935 { | |
2936 gsi_insert_on_edge_immediate (e, g); | |
2937 gsi = gsi_for_stmt (g); | |
2938 } | |
2939 else | |
2940 gsi_insert_after (&gsi, g, GSI_NEW_STMT); | |
2941 } | |
2942 if (use_bool && has_debug_uses) | |
2943 { | |
2944 tree temp = NULL_TREE; | |
2945 if (!throws || after || single_pred_p (e->dest)) | |
2946 { | |
2947 temp = make_node (DEBUG_EXPR_DECL); | |
2948 DECL_ARTIFICIAL (temp) = 1; | |
2949 TREE_TYPE (temp) = TREE_TYPE (lhs); | |
2950 SET_DECL_MODE (temp, TYPE_MODE (TREE_TYPE (lhs))); | |
2951 tree t = build2 (LSHIFT_EXPR, TREE_TYPE (lhs), new_lhs, bit); | |
2952 g = gimple_build_debug_bind (temp, t, g); | |
2953 if (throws && !after) | |
2954 { | |
2955 gsi = gsi_after_labels (e->dest); | |
2956 gsi_insert_before (&gsi, g, GSI_SAME_STMT); | |
2957 } | |
2958 else | |
2959 gsi_insert_after (&gsi, g, GSI_NEW_STMT); | |
2960 } | |
2961 FOR_EACH_IMM_USE_STMT (g, iter, use_lhs) | |
2962 if (is_gimple_debug (g)) | |
2963 { | |
2964 use_operand_p use_p; | |
2965 if (temp == NULL_TREE) | |
2966 gimple_debug_bind_reset_value (g); | |
2967 else | |
2968 FOR_EACH_IMM_USE_ON_STMT (use_p, iter) | |
2969 SET_USE (use_p, temp); | |
2970 update_stmt (g); | |
2971 } | |
2972 } | |
2973 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_lhs) | |
2974 = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use_lhs); | |
2975 replace_uses_by (use_lhs, new_lhs); | |
2976 gsi = gsi_for_stmt (use_stmt); | |
2977 gsi_remove (&gsi, true); | |
2978 release_defs (use_stmt); | |
2979 gsi_remove (gsip, true); | |
2980 release_ssa_name (lhs); | |
2981 } | |
2982 | |
2983 /* Optimize | |
2984 a = {}; | |
2985 b = a; | |
2986 into | |
2987 a = {}; | |
2988 b = {}; | |
2989 Similarly for memset (&a, ..., sizeof (a)); instead of a = {}; | |
2990 and/or memcpy (&b, &a, sizeof (a)); instead of b = a; */ | |
2991 | |
2992 static void | |
2993 optimize_memcpy (gimple_stmt_iterator *gsip, tree dest, tree src, tree len) | |
2994 { | |
2995 gimple *stmt = gsi_stmt (*gsip); | |
2996 if (gimple_has_volatile_ops (stmt)) | |
2997 return; | |
2998 | |
2999 tree vuse = gimple_vuse (stmt); | |
3000 if (vuse == NULL) | |
3001 return; | |
3002 | |
3003 gimple *defstmt = SSA_NAME_DEF_STMT (vuse); | |
3004 tree src2 = NULL_TREE, len2 = NULL_TREE; | |
3005 HOST_WIDE_INT offset, offset2; | |
3006 tree val = integer_zero_node; | |
3007 if (gimple_store_p (defstmt) | |
3008 && gimple_assign_single_p (defstmt) | |
3009 && TREE_CODE (gimple_assign_rhs1 (defstmt)) == CONSTRUCTOR | |
3010 && !gimple_clobber_p (defstmt)) | |
3011 src2 = gimple_assign_lhs (defstmt); | |
3012 else if (gimple_call_builtin_p (defstmt, BUILT_IN_MEMSET) | |
3013 && TREE_CODE (gimple_call_arg (defstmt, 0)) == ADDR_EXPR | |
3014 && TREE_CODE (gimple_call_arg (defstmt, 1)) == INTEGER_CST) | |
3015 { | |
3016 src2 = TREE_OPERAND (gimple_call_arg (defstmt, 0), 0); | |
3017 len2 = gimple_call_arg (defstmt, 2); | |
3018 val = gimple_call_arg (defstmt, 1); | |
3019 /* For non-0 val, we'd have to transform stmt from assignment | |
3020 into memset (only if dest is addressable). */ | |
3021 if (!integer_zerop (val) && is_gimple_assign (stmt)) | |
3022 src2 = NULL_TREE; | |
3023 } | |
3024 | |
3025 if (src2 == NULL_TREE) | |
3026 return; | |
3027 | |
3028 if (len == NULL_TREE) | |
3029 len = (TREE_CODE (src) == COMPONENT_REF | |
3030 ? DECL_SIZE_UNIT (TREE_OPERAND (src, 1)) | |
3031 : TYPE_SIZE_UNIT (TREE_TYPE (src))); | |
3032 if (len2 == NULL_TREE) | |
3033 len2 = (TREE_CODE (src2) == COMPONENT_REF | |
3034 ? DECL_SIZE_UNIT (TREE_OPERAND (src2, 1)) | |
3035 : TYPE_SIZE_UNIT (TREE_TYPE (src2))); | |
3036 if (len == NULL_TREE | |
3037 || TREE_CODE (len) != INTEGER_CST | |
3038 || len2 == NULL_TREE | |
3039 || TREE_CODE (len2) != INTEGER_CST) | |
3040 return; | |
3041 | |
3042 src = get_addr_base_and_unit_offset (src, &offset); | |
3043 src2 = get_addr_base_and_unit_offset (src2, &offset2); | |
3044 if (src == NULL_TREE | |
3045 || src2 == NULL_TREE | |
3046 || offset < offset2) | |
3047 return; | |
3048 | |
3049 if (!operand_equal_p (src, src2, 0)) | |
3050 return; | |
3051 | |
3052 /* [ src + offset2, src + offset2 + len2 - 1 ] is set to val. | |
3053 Make sure that | |
3054 [ src + offset, src + offset + len - 1 ] is a subset of that. */ | |
3055 if (wi::to_offset (len) + (offset - offset2) > wi::to_offset (len2)) | |
3056 return; | |
3057 | |
3058 if (dump_file && (dump_flags & TDF_DETAILS)) | |
3059 { | |
3060 fprintf (dump_file, "Simplified\n "); | |
3061 print_gimple_stmt (dump_file, stmt, 0, dump_flags); | |
3062 fprintf (dump_file, "after previous\n "); | |
3063 print_gimple_stmt (dump_file, defstmt, 0, dump_flags); | |
3064 } | |
3065 | |
3066 /* For simplicity, don't change the kind of the stmt, | |
3067 turn dest = src; into dest = {}; and memcpy (&dest, &src, len); | |
3068 into memset (&dest, val, len); | |
3069 In theory we could change dest = src into memset if dest | |
3070 is addressable (maybe beneficial if val is not 0), or | |
3071 memcpy (&dest, &src, len) into dest = {} if len is the size | |
3072 of dest, dest isn't volatile. */ | |
3073 if (is_gimple_assign (stmt)) | |
3074 { | |
3075 tree ctor = build_constructor (TREE_TYPE (dest), NULL); | |
3076 gimple_assign_set_rhs_from_tree (gsip, ctor); | |
3077 update_stmt (stmt); | |
3078 } | |
3079 else /* If stmt is memcpy, transform it into memset. */ | |
3080 { | |
3081 gcall *call = as_a <gcall *> (stmt); | |
3082 tree fndecl = builtin_decl_implicit (BUILT_IN_MEMSET); | |
3083 gimple_call_set_fndecl (call, fndecl); | |
3084 gimple_call_set_fntype (call, TREE_TYPE (fndecl)); | |
3085 gimple_call_set_arg (call, 1, val); | |
3086 update_stmt (stmt); | |
3087 } | |
3088 | |
3089 if (dump_file && (dump_flags & TDF_DETAILS)) | |
3090 { | |
3091 fprintf (dump_file, "into\n "); | |
3092 print_gimple_stmt (dump_file, stmt, 0, dump_flags); | |
3093 } | |
3094 } | |
3095 | |
0 | 3096 /* A simple pass that attempts to fold all builtin functions. This pass |
3097 is run after we've propagated as many constants as we can. */ | |
3098 | |
111 | 3099 namespace { |
3100 | |
3101 const pass_data pass_data_fold_builtins = | |
3102 { | |
3103 GIMPLE_PASS, /* type */ | |
3104 "fab", /* name */ | |
3105 OPTGROUP_NONE, /* optinfo_flags */ | |
3106 TV_NONE, /* tv_id */ | |
3107 ( PROP_cfg | PROP_ssa ), /* properties_required */ | |
3108 0, /* properties_provided */ | |
3109 0, /* properties_destroyed */ | |
3110 0, /* todo_flags_start */ | |
3111 TODO_update_ssa, /* todo_flags_finish */ | |
3112 }; | |
3113 | |
3114 class pass_fold_builtins : public gimple_opt_pass | |
3115 { | |
3116 public: | |
3117 pass_fold_builtins (gcc::context *ctxt) | |
3118 : gimple_opt_pass (pass_data_fold_builtins, ctxt) | |
3119 {} | |
3120 | |
3121 /* opt_pass methods: */ | |
3122 opt_pass * clone () { return new pass_fold_builtins (m_ctxt); } | |
3123 virtual unsigned int execute (function *); | |
3124 | |
3125 }; // class pass_fold_builtins | |
3126 | |
3127 unsigned int | |
3128 pass_fold_builtins::execute (function *fun) | |
0 | 3129 { |
3130 bool cfg_changed = false; | |
3131 basic_block bb; | |
3132 unsigned int todoflags = 0; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
3133 |
111 | 3134 FOR_EACH_BB_FN (bb, fun) |
0 | 3135 { |
3136 gimple_stmt_iterator i; | |
3137 for (i = gsi_start_bb (bb); !gsi_end_p (i); ) | |
3138 { | |
111 | 3139 gimple *stmt, *old_stmt; |
3140 tree callee; | |
0 | 3141 enum built_in_function fcode; |
3142 | |
3143 stmt = gsi_stmt (i); | |
3144 | |
3145 if (gimple_code (stmt) != GIMPLE_CALL) | |
3146 { | |
111 | 3147 /* Remove all *ssaname_N ={v} {CLOBBER}; stmts, |
3148 after the last GIMPLE DSE they aren't needed and might | |
3149 unnecessarily keep the SSA_NAMEs live. */ | |
3150 if (gimple_clobber_p (stmt)) | |
3151 { | |
3152 tree lhs = gimple_assign_lhs (stmt); | |
3153 if (TREE_CODE (lhs) == MEM_REF | |
3154 && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME) | |
3155 { | |
3156 unlink_stmt_vdef (stmt); | |
3157 gsi_remove (&i, true); | |
3158 release_defs (stmt); | |
3159 continue; | |
3160 } | |
3161 } | |
3162 else if (gimple_assign_load_p (stmt) && gimple_store_p (stmt)) | |
3163 optimize_memcpy (&i, gimple_assign_lhs (stmt), | |
3164 gimple_assign_rhs1 (stmt), NULL_TREE); | |
0 | 3165 gsi_next (&i); |
3166 continue; | |
3167 } | |
111 | 3168 |
0 | 3169 callee = gimple_call_fndecl (stmt); |
3170 if (!callee || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL) | |
3171 { | |
3172 gsi_next (&i); | |
3173 continue; | |
3174 } | |
111 | 3175 |
0 | 3176 fcode = DECL_FUNCTION_CODE (callee); |
111 | 3177 if (fold_stmt (&i)) |
3178 ; | |
3179 else | |
3180 { | |
3181 tree result = NULL_TREE; | |
3182 switch (DECL_FUNCTION_CODE (callee)) | |
3183 { | |
3184 case BUILT_IN_CONSTANT_P: | |
3185 /* Resolve __builtin_constant_p. If it hasn't been | |
3186 folded to integer_one_node by now, it's fairly | |
3187 certain that the value simply isn't constant. */ | |
3188 result = integer_zero_node; | |
3189 break; | |
3190 | |
3191 case BUILT_IN_ASSUME_ALIGNED: | |
3192 /* Remove __builtin_assume_aligned. */ | |
3193 result = gimple_call_arg (stmt, 0); | |
3194 break; | |
3195 | |
3196 case BUILT_IN_STACK_RESTORE: | |
3197 result = optimize_stack_restore (i); | |
3198 if (result) | |
3199 break; | |
3200 gsi_next (&i); | |
3201 continue; | |
3202 | |
3203 case BUILT_IN_UNREACHABLE: | |
3204 if (optimize_unreachable (i)) | |
3205 cfg_changed = true; | |
3206 break; | |
3207 | |
3208 case BUILT_IN_ATOMIC_FETCH_OR_1: | |
3209 case BUILT_IN_ATOMIC_FETCH_OR_2: | |
3210 case BUILT_IN_ATOMIC_FETCH_OR_4: | |
3211 case BUILT_IN_ATOMIC_FETCH_OR_8: | |
3212 case BUILT_IN_ATOMIC_FETCH_OR_16: | |
3213 optimize_atomic_bit_test_and (&i, | |
3214 IFN_ATOMIC_BIT_TEST_AND_SET, | |
3215 true, false); | |
3216 break; | |
3217 case BUILT_IN_SYNC_FETCH_AND_OR_1: | |
3218 case BUILT_IN_SYNC_FETCH_AND_OR_2: | |
3219 case BUILT_IN_SYNC_FETCH_AND_OR_4: | |
3220 case BUILT_IN_SYNC_FETCH_AND_OR_8: | |
3221 case BUILT_IN_SYNC_FETCH_AND_OR_16: | |
3222 optimize_atomic_bit_test_and (&i, | |
3223 IFN_ATOMIC_BIT_TEST_AND_SET, | |
3224 false, false); | |
3225 break; | |
3226 | |
3227 case BUILT_IN_ATOMIC_FETCH_XOR_1: | |
3228 case BUILT_IN_ATOMIC_FETCH_XOR_2: | |
3229 case BUILT_IN_ATOMIC_FETCH_XOR_4: | |
3230 case BUILT_IN_ATOMIC_FETCH_XOR_8: | |
3231 case BUILT_IN_ATOMIC_FETCH_XOR_16: | |
3232 optimize_atomic_bit_test_and | |
3233 (&i, IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT, true, false); | |
3234 break; | |
3235 case BUILT_IN_SYNC_FETCH_AND_XOR_1: | |
3236 case BUILT_IN_SYNC_FETCH_AND_XOR_2: | |
3237 case BUILT_IN_SYNC_FETCH_AND_XOR_4: | |
3238 case BUILT_IN_SYNC_FETCH_AND_XOR_8: | |
3239 case BUILT_IN_SYNC_FETCH_AND_XOR_16: | |
3240 optimize_atomic_bit_test_and | |
3241 (&i, IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT, false, false); | |
0 | 3242 break; |
111 | 3243 |
3244 case BUILT_IN_ATOMIC_XOR_FETCH_1: | |
3245 case BUILT_IN_ATOMIC_XOR_FETCH_2: | |
3246 case BUILT_IN_ATOMIC_XOR_FETCH_4: | |
3247 case BUILT_IN_ATOMIC_XOR_FETCH_8: | |
3248 case BUILT_IN_ATOMIC_XOR_FETCH_16: | |
3249 optimize_atomic_bit_test_and | |
3250 (&i, IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT, true, true); | |
3251 break; | |
3252 case BUILT_IN_SYNC_XOR_AND_FETCH_1: | |
3253 case BUILT_IN_SYNC_XOR_AND_FETCH_2: | |
3254 case BUILT_IN_SYNC_XOR_AND_FETCH_4: | |
3255 case BUILT_IN_SYNC_XOR_AND_FETCH_8: | |
3256 case BUILT_IN_SYNC_XOR_AND_FETCH_16: | |
3257 optimize_atomic_bit_test_and | |
3258 (&i, IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT, false, true); | |
3259 break; | |
3260 | |
3261 case BUILT_IN_ATOMIC_FETCH_AND_1: | |
3262 case BUILT_IN_ATOMIC_FETCH_AND_2: | |
3263 case BUILT_IN_ATOMIC_FETCH_AND_4: | |
3264 case BUILT_IN_ATOMIC_FETCH_AND_8: | |
3265 case BUILT_IN_ATOMIC_FETCH_AND_16: | |
3266 optimize_atomic_bit_test_and (&i, | |
3267 IFN_ATOMIC_BIT_TEST_AND_RESET, | |
3268 true, false); | |
3269 break; | |
3270 case BUILT_IN_SYNC_FETCH_AND_AND_1: | |
3271 case BUILT_IN_SYNC_FETCH_AND_AND_2: | |
3272 case BUILT_IN_SYNC_FETCH_AND_AND_4: | |
3273 case BUILT_IN_SYNC_FETCH_AND_AND_8: | |
3274 case BUILT_IN_SYNC_FETCH_AND_AND_16: | |
3275 optimize_atomic_bit_test_and (&i, | |
3276 IFN_ATOMIC_BIT_TEST_AND_RESET, | |
3277 false, false); | |
0 | 3278 break; |
111 | 3279 |
3280 case BUILT_IN_MEMCPY: | |
3281 if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL) | |
3282 && TREE_CODE (gimple_call_arg (stmt, 0)) == ADDR_EXPR | |
3283 && TREE_CODE (gimple_call_arg (stmt, 1)) == ADDR_EXPR | |
3284 && TREE_CODE (gimple_call_arg (stmt, 2)) == INTEGER_CST) | |
3285 { | |
3286 tree dest = TREE_OPERAND (gimple_call_arg (stmt, 0), 0); | |
3287 tree src = TREE_OPERAND (gimple_call_arg (stmt, 1), 0); | |
3288 tree len = gimple_call_arg (stmt, 2); | |
3289 optimize_memcpy (&i, dest, src, len); | |
3290 } | |
3291 break; | |
3292 | |
3293 case BUILT_IN_VA_START: | |
3294 case BUILT_IN_VA_END: | |
3295 case BUILT_IN_VA_COPY: | |
3296 /* These shouldn't be folded before pass_stdarg. */ | |
3297 result = optimize_stdarg_builtin (stmt); | |
3298 break; | |
3299 | |
3300 default:; | |
3301 } | |
3302 | |
3303 if (!result) | |
3304 { | |
3305 gsi_next (&i); | |
3306 continue; | |
3307 } | |
3308 | |
3309 if (!update_call_from_tree (&i, result)) | |
3310 gimplify_and_update_call_from_tree (&i, result); | |
3311 } | |
3312 | |
3313 todoflags |= TODO_update_address_taken; | |
0 | 3314 |
3315 if (dump_file && (dump_flags & TDF_DETAILS)) | |
3316 { | |
3317 fprintf (dump_file, "Simplified\n "); | |
3318 print_gimple_stmt (dump_file, stmt, 0, dump_flags); | |
3319 } | |
3320 | |
3321 old_stmt = stmt; | |
3322 stmt = gsi_stmt (i); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
3323 update_stmt (stmt); |
0 | 3324 |
3325 if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt) | |
3326 && gimple_purge_dead_eh_edges (bb)) | |
3327 cfg_changed = true; | |
3328 | |
3329 if (dump_file && (dump_flags & TDF_DETAILS)) | |
3330 { | |
3331 fprintf (dump_file, "to\n "); | |
3332 print_gimple_stmt (dump_file, stmt, 0, dump_flags); | |
3333 fprintf (dump_file, "\n"); | |
3334 } | |
3335 | |
3336 /* Retry the same statement if it changed into another | |
3337 builtin, there might be new opportunities now. */ | |
3338 if (gimple_code (stmt) != GIMPLE_CALL) | |
3339 { | |
3340 gsi_next (&i); | |
3341 continue; | |
3342 } | |
3343 callee = gimple_call_fndecl (stmt); | |
3344 if (!callee | |
3345 || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL | |
3346 || DECL_FUNCTION_CODE (callee) == fcode) | |
3347 gsi_next (&i); | |
3348 } | |
3349 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
3350 |
0 | 3351 /* Delete unreachable blocks. */ |
3352 if (cfg_changed) | |
3353 todoflags |= TODO_cleanup_cfg; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
3354 |
0 | 3355 return todoflags; |
3356 } | |
3357 | |
111 | 3358 } // anon namespace |
3359 | |
3360 gimple_opt_pass * | |
3361 make_pass_fold_builtins (gcc::context *ctxt) | |
3362 { | |
3363 return new pass_fold_builtins (ctxt); | |
3364 } | |
3365 | |
3366 /* A simple pass that emits some warnings post IPA. */ | |
3367 | |
3368 namespace { | |
3369 | |
3370 const pass_data pass_data_post_ipa_warn = | |
3371 { | |
3372 GIMPLE_PASS, /* type */ | |
3373 "post_ipa_warn", /* name */ | |
3374 OPTGROUP_NONE, /* optinfo_flags */ | |
3375 TV_NONE, /* tv_id */ | |
3376 ( PROP_cfg | PROP_ssa ), /* properties_required */ | |
3377 0, /* properties_provided */ | |
3378 0, /* properties_destroyed */ | |
3379 0, /* todo_flags_start */ | |
3380 0, /* todo_flags_finish */ | |
3381 }; | |
3382 | |
3383 class pass_post_ipa_warn : public gimple_opt_pass | |
3384 { | |
3385 public: | |
3386 pass_post_ipa_warn (gcc::context *ctxt) | |
3387 : gimple_opt_pass (pass_data_post_ipa_warn, ctxt) | |
3388 {} | |
3389 | |
3390 /* opt_pass methods: */ | |
3391 opt_pass * clone () { return new pass_post_ipa_warn (m_ctxt); } | |
3392 virtual bool gate (function *) { return warn_nonnull != 0; } | |
3393 virtual unsigned int execute (function *); | |
3394 | |
3395 }; // class pass_fold_builtins | |
3396 | |
3397 unsigned int | |
3398 pass_post_ipa_warn::execute (function *fun) | |
0 | 3399 { |
111 | 3400 basic_block bb; |
3401 | |
3402 FOR_EACH_BB_FN (bb, fun) | |
3403 { | |
3404 gimple_stmt_iterator gsi; | |
3405 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
3406 { | |
3407 gimple *stmt = gsi_stmt (gsi); | |
3408 if (!is_gimple_call (stmt) || gimple_no_warning_p (stmt)) | |
3409 continue; | |
3410 | |
3411 if (warn_nonnull) | |
3412 { | |
3413 bitmap nonnullargs | |
3414 = get_nonnull_args (gimple_call_fntype (stmt)); | |
3415 if (nonnullargs) | |
3416 { | |
3417 for (unsigned i = 0; i < gimple_call_num_args (stmt); i++) | |
3418 { | |
3419 tree arg = gimple_call_arg (stmt, i); | |
3420 if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE) | |
3421 continue; | |
3422 if (!integer_zerop (arg)) | |
3423 continue; | |
3424 if (!bitmap_empty_p (nonnullargs) | |
3425 && !bitmap_bit_p (nonnullargs, i)) | |
3426 continue; | |
3427 | |
3428 location_t loc = gimple_location (stmt); | |
3429 if (warning_at (loc, OPT_Wnonnull, | |
3430 "argument %u null where non-null " | |
3431 "expected", i + 1)) | |
3432 { | |
3433 tree fndecl = gimple_call_fndecl (stmt); | |
3434 if (fndecl && DECL_IS_BUILTIN (fndecl)) | |
3435 inform (loc, "in a call to built-in function %qD", | |
3436 fndecl); | |
3437 else if (fndecl) | |
3438 inform (DECL_SOURCE_LOCATION (fndecl), | |
3439 "in a call to function %qD declared here", | |
3440 fndecl); | |
3441 | |
3442 } | |
3443 } | |
3444 BITMAP_FREE (nonnullargs); | |
3445 } | |
3446 } | |
3447 } | |
3448 } | |
3449 return 0; | |
3450 } | |
3451 | |
3452 } // anon namespace | |
3453 | |
3454 gimple_opt_pass * | |
3455 make_pass_post_ipa_warn (gcc::context *ctxt) | |
3456 { | |
3457 return new pass_post_ipa_warn (ctxt); | |
3458 } |