2005-05-11 Kenneth Zadeck <zadeck@naturalbridge.com>
[official-gcc.git] / gcc / tree-ssa-forwprop.c
blob746812ac30db636b8d4526d5b9b352dafc91acc1
1 /* Forward propagation of single use variables.
2 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "errors.h"
26 #include "ggc.h"
27 #include "tree.h"
28 #include "rtl.h"
29 #include "tm_p.h"
30 #include "basic-block.h"
31 #include "timevar.h"
32 #include "diagnostic.h"
33 #include "tree-flow.h"
34 #include "tree-pass.h"
35 #include "tree-dump.h"
37 /* This pass performs simple forward propagation of single use variables
38 from their definition site into their single use site.
40 Right now we only bother forward propagating into COND_EXPRs since those
41 are relatively common cases where forward propagation creates valid
42 gimple code without the expression needing to fold. i.e.
44 bb0:
45 x = a COND b;
46 if (x) goto ... else goto ...
48 Will be transformed into:
50 bb0:
51 if (a COND b) goto ... else goto ...
53 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
55 Or (assuming c1 and c2 are constants):
57 bb0:
58 x = a + c1;
59 if (x EQ/NEQ c2) goto ... else goto ...
61 Will be transformed into:
63 bb0:
64 if (a EQ/NEQ (c2 - c1)) goto ... else goto ...
66 Similarly for x = a - c1.
70 bb0:
71 x = !a
72 if (x) goto ... else goto ...
74 Will be transformed into:
76 bb0:
77 if (a == 0) goto ... else goto ...
79 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
80 For these cases, we propagate A into all, possibly more than one,
81 COND_EXPRs that use X.
85 bb0:
86 x = (typecast) a
87 if (x) goto ... else goto ...
89 Will be transformed into:
91 bb0:
92 if (a != 0) goto ... else goto ...
94 (Assuming a is an integral type and x is a boolean or x is an
95 integral and a is a boolean.)
97 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
98 For these cases, we propagate A into all, possibly more than one,
99 COND_EXPRs that use X.
101 In addition to eliminating the variable and the statement which assigns
102 a value to the variable, we may be able to later thread the jump without
103 adding insane complexity in the dominator optimizer.
105 Also note these transformations can cascade. We handle this by having
106 a worklist of COND_EXPR statements to examine. As we make a change to
107 a statement, we put it back on the worklist to examine on the next
108 iteration of the main loop.
110 This will (of course) be extended as other needs arise. */
112 /* Given an SSA_NAME VAR, return true if and only if VAR is defined by
113 a comparison. */
115 static bool
116 ssa_name_defined_by_comparison_p (tree var)
118 tree def = SSA_NAME_DEF_STMT (var);
120 if (TREE_CODE (def) == MODIFY_EXPR)
122 tree rhs = TREE_OPERAND (def, 1);
123 return COMPARISON_CLASS_P (rhs);
126 return 0;
129 /* Forward propagate a single-use variable into COND once. Return a
130 new condition if successful. Return NULL_TREE otherwise. */
132 static tree
133 forward_propagate_into_cond_1 (tree cond, tree *test_var_p)
135 tree new_cond = NULL_TREE;
136 enum tree_code cond_code = TREE_CODE (cond);
137 tree test_var = NULL_TREE;
138 tree def;
139 tree def_rhs;
141 /* If the condition is not a lone variable or an equality test of an
142 SSA_NAME against an integral constant, then we do not have an
143 optimizable case.
145 Note these conditions also ensure the COND_EXPR has no
146 virtual operands or other side effects. */
147 if (cond_code != SSA_NAME
148 && !((cond_code == EQ_EXPR || cond_code == NE_EXPR)
149 && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
150 && CONSTANT_CLASS_P (TREE_OPERAND (cond, 1))
151 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))))
152 return NULL_TREE;
154 /* Extract the single variable used in the test into TEST_VAR. */
155 if (cond_code == SSA_NAME)
156 test_var = cond;
157 else
158 test_var = TREE_OPERAND (cond, 0);
160 /* Now get the defining statement for TEST_VAR. Skip this case if
161 it's not defined by some MODIFY_EXPR. */
162 def = SSA_NAME_DEF_STMT (test_var);
163 if (TREE_CODE (def) != MODIFY_EXPR)
164 return NULL_TREE;
166 def_rhs = TREE_OPERAND (def, 1);
168 /* If TEST_VAR is set by adding or subtracting a constant
169 from an SSA_NAME, then it is interesting to us as we
170 can adjust the constant in the conditional and thus
171 eliminate the arithmetic operation. */
172 if (TREE_CODE (def_rhs) == PLUS_EXPR
173 || TREE_CODE (def_rhs) == MINUS_EXPR)
175 tree op0 = TREE_OPERAND (def_rhs, 0);
176 tree op1 = TREE_OPERAND (def_rhs, 1);
178 /* The first operand must be an SSA_NAME and the second
179 operand must be a constant. */
180 if (TREE_CODE (op0) != SSA_NAME
181 || !CONSTANT_CLASS_P (op1)
182 || !INTEGRAL_TYPE_P (TREE_TYPE (op1)))
183 return NULL_TREE;
185 /* Don't propagate if the first operand occurs in
186 an abnormal PHI. */
187 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0))
188 return NULL_TREE;
190 if (has_single_use (test_var))
192 enum tree_code new_code;
193 tree t;
195 /* If the variable was defined via X + C, then we must
196 subtract C from the constant in the conditional.
197 Otherwise we add C to the constant in the
198 conditional. The result must fold into a valid
199 gimple operand to be optimizable. */
200 new_code = (TREE_CODE (def_rhs) == PLUS_EXPR
201 ? MINUS_EXPR : PLUS_EXPR);
202 t = int_const_binop (new_code, TREE_OPERAND (cond, 1), op1, 0);
203 if (!is_gimple_val (t))
204 return NULL_TREE;
206 new_cond = build (cond_code, boolean_type_node, op0, t);
210 /* These cases require comparisons of a naked SSA_NAME or
211 comparison of an SSA_NAME against zero or one. */
212 else if (TREE_CODE (cond) == SSA_NAME
213 || integer_zerop (TREE_OPERAND (cond, 1))
214 || integer_onep (TREE_OPERAND (cond, 1)))
216 /* If TEST_VAR is set from a relational operation
217 between two SSA_NAMEs or a combination of an SSA_NAME
218 and a constant, then it is interesting. */
219 if (COMPARISON_CLASS_P (def_rhs))
221 tree op0 = TREE_OPERAND (def_rhs, 0);
222 tree op1 = TREE_OPERAND (def_rhs, 1);
224 /* Both operands of DEF_RHS must be SSA_NAMEs or
225 constants. */
226 if ((TREE_CODE (op0) != SSA_NAME
227 && !is_gimple_min_invariant (op0))
228 || (TREE_CODE (op1) != SSA_NAME
229 && !is_gimple_min_invariant (op1)))
230 return NULL_TREE;
232 /* Don't propagate if the first operand occurs in
233 an abnormal PHI. */
234 if (TREE_CODE (op0) == SSA_NAME
235 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0))
236 return NULL_TREE;
238 /* Don't propagate if the second operand occurs in
239 an abnormal PHI. */
240 if (TREE_CODE (op1) == SSA_NAME
241 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op1))
242 return NULL_TREE;
244 if (has_single_use (test_var))
246 /* TEST_VAR was set from a relational operator. */
247 new_cond = build (TREE_CODE (def_rhs),
248 boolean_type_node, op0, op1);
250 /* Invert the conditional if necessary. */
251 if ((cond_code == EQ_EXPR
252 && integer_zerop (TREE_OPERAND (cond, 1)))
253 || (cond_code == NE_EXPR
254 && integer_onep (TREE_OPERAND (cond, 1))))
256 new_cond = invert_truthvalue (new_cond);
258 /* If we did not get a simple relational
259 expression or bare SSA_NAME, then we can
260 not optimize this case. */
261 if (!COMPARISON_CLASS_P (new_cond)
262 && TREE_CODE (new_cond) != SSA_NAME)
263 new_cond = NULL_TREE;
268 /* If TEST_VAR is set from a TRUTH_NOT_EXPR, then it
269 is interesting. */
270 else if (TREE_CODE (def_rhs) == TRUTH_NOT_EXPR)
272 enum tree_code new_code;
274 def_rhs = TREE_OPERAND (def_rhs, 0);
276 /* DEF_RHS must be an SSA_NAME or constant. */
277 if (TREE_CODE (def_rhs) != SSA_NAME
278 && !is_gimple_min_invariant (def_rhs))
279 return NULL_TREE;
281 /* Don't propagate if the operand occurs in
282 an abnormal PHI. */
283 if (TREE_CODE (def_rhs) == SSA_NAME
284 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def_rhs))
285 return NULL_TREE;
287 if (cond_code == SSA_NAME
288 || (cond_code == NE_EXPR
289 && integer_zerop (TREE_OPERAND (cond, 1)))
290 || (cond_code == EQ_EXPR
291 && integer_onep (TREE_OPERAND (cond, 1))))
292 new_code = EQ_EXPR;
293 else
294 new_code = NE_EXPR;
296 new_cond = build2 (new_code, boolean_type_node, def_rhs,
297 fold_convert (TREE_TYPE (def_rhs),
298 integer_zero_node));
301 /* If TEST_VAR was set from a cast of an integer type
302 to a boolean type or a cast of a boolean to an
303 integral, then it is interesting. */
304 else if (TREE_CODE (def_rhs) == NOP_EXPR
305 || TREE_CODE (def_rhs) == CONVERT_EXPR)
307 tree outer_type;
308 tree inner_type;
310 outer_type = TREE_TYPE (def_rhs);
311 inner_type = TREE_TYPE (TREE_OPERAND (def_rhs, 0));
313 if ((TREE_CODE (outer_type) == BOOLEAN_TYPE
314 && INTEGRAL_TYPE_P (inner_type))
315 || (TREE_CODE (inner_type) == BOOLEAN_TYPE
316 && INTEGRAL_TYPE_P (outer_type)))
318 else if (INTEGRAL_TYPE_P (outer_type)
319 && INTEGRAL_TYPE_P (inner_type)
320 && TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME
321 && ssa_name_defined_by_comparison_p (TREE_OPERAND (def_rhs,
322 0)))
324 else
325 return NULL_TREE;
327 /* Don't propagate if the operand occurs in
328 an abnormal PHI. */
329 if (TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME
330 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND
331 (def_rhs, 0)))
332 return NULL_TREE;
334 if (has_single_use (test_var))
336 enum tree_code new_code;
337 tree new_arg;
339 if (cond_code == SSA_NAME
340 || (cond_code == NE_EXPR
341 && integer_zerop (TREE_OPERAND (cond, 1)))
342 || (cond_code == EQ_EXPR
343 && integer_onep (TREE_OPERAND (cond, 1))))
344 new_code = NE_EXPR;
345 else
346 new_code = EQ_EXPR;
348 new_arg = TREE_OPERAND (def_rhs, 0);
349 new_cond = build2 (new_code, boolean_type_node, new_arg,
350 fold_convert (TREE_TYPE (new_arg),
351 integer_zero_node));
356 *test_var_p = test_var;
357 return new_cond;
360 /* Forward propagate a single-use variable into COND_EXPR as many
361 times as possible. */
363 static void
364 forward_propagate_into_cond (tree cond_expr)
366 gcc_assert (TREE_CODE (cond_expr) == COND_EXPR);
368 while (1)
370 tree test_var = NULL_TREE;
371 tree cond = COND_EXPR_COND (cond_expr);
372 tree new_cond = forward_propagate_into_cond_1 (cond, &test_var);
374 /* Return if unsuccessful. */
375 if (new_cond == NULL_TREE)
376 break;
378 /* Dump details. */
379 if (dump_file && (dump_flags & TDF_DETAILS))
381 fprintf (dump_file, " Replaced '");
382 print_generic_expr (dump_file, cond, dump_flags);
383 fprintf (dump_file, "' with '");
384 print_generic_expr (dump_file, new_cond, dump_flags);
385 fprintf (dump_file, "'\n");
388 COND_EXPR_COND (cond_expr) = new_cond;
389 update_stmt (cond_expr);
391 if (has_zero_uses (test_var))
393 tree def = SSA_NAME_DEF_STMT (test_var);
394 block_stmt_iterator bsi = bsi_for_stmt (def);
395 bsi_remove (&bsi);
400 /* Main entry point for the forward propagation optimizer. */
402 static void
403 tree_ssa_forward_propagate_single_use_vars (void)
405 basic_block bb;
407 FOR_EACH_BB (bb)
409 tree last = last_stmt (bb);
410 if (last && TREE_CODE (last) == COND_EXPR)
411 forward_propagate_into_cond (last);
416 static bool
417 gate_forwprop (void)
419 return 1;
422 struct tree_opt_pass pass_forwprop = {
423 "forwprop", /* name */
424 gate_forwprop, /* gate */
425 tree_ssa_forward_propagate_single_use_vars, /* execute */
426 NULL, /* sub */
427 NULL, /* next */
428 0, /* static_pass_number */
429 TV_TREE_FORWPROP, /* tv_id */
430 PROP_cfg | PROP_ssa
431 | PROP_alias, /* properties_required */
432 0, /* properties_provided */
433 0, /* properties_destroyed */
434 0, /* todo_flags_start */
435 TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
436 | TODO_verify_ssa,
437 0 /* letter */