1169689Skan/* Forward propagation of expressions for single use variables.
2169689Skan   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3169689Skan
4169689SkanThis file is part of GCC.
5169689Skan
6169689SkanGCC is free software; you can redistribute it and/or modify
7169689Skanit under the terms of the GNU General Public License as published by
8169689Skanthe Free Software Foundation; either version 2, or (at your option)
9169689Skanany later version.
10169689Skan
11169689SkanGCC is distributed in the hope that it will be useful,
12169689Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of
13169689SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14169689SkanGNU General Public License for more details.
15169689Skan
16169689SkanYou should have received a copy of the GNU General Public License
17169689Skanalong with GCC; see the file COPYING.  If not, write to
18169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor,
19169689SkanBoston, MA 02110-1301, USA.  */
20169689Skan
21169689Skan#include "config.h"
22169689Skan#include "system.h"
23169689Skan#include "coretypes.h"
24169689Skan#include "tm.h"
25169689Skan#include "ggc.h"
26169689Skan#include "tree.h"
27169689Skan#include "rtl.h"
28169689Skan#include "tm_p.h"
29169689Skan#include "basic-block.h"
30169689Skan#include "timevar.h"
31169689Skan#include "diagnostic.h"
32169689Skan#include "tree-flow.h"
33169689Skan#include "tree-pass.h"
34169689Skan#include "tree-dump.h"
35169689Skan#include "langhooks.h"
36169689Skan
37169689Skan/* This pass propagates the RHS of assignment statements into use
38169689Skan   sites of the LHS of the assignment.  It's basically a specialized
39169689Skan   form of tree combination.   It is hoped all of this can disappear
40169689Skan   when we have a generalized tree combiner.
41169689Skan
42169689Skan   Note carefully that after propagation the resulting statement
43169689Skan   must still be a proper gimple statement.  Right now we simply
44169689Skan   only perform propagations we know will result in valid gimple
45169689Skan   code.  One day we'll want to generalize this code.
46169689Skan
47169689Skan   One class of common cases we handle is forward propagating a single use
48169689Skan   variable into a COND_EXPR.
49169689Skan
50169689Skan     bb0:
51169689Skan       x = a COND b;
52169689Skan       if (x) goto ... else goto ...
53169689Skan
54169689Skan   Will be transformed into:
55169689Skan
56169689Skan     bb0:
57169689Skan       if (a COND b) goto ... else goto ...
58169689Skan
59169689Skan   Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
60169689Skan
61169689Skan   Or (assuming c1 and c2 are constants):
62169689Skan
63169689Skan     bb0:
64169689Skan       x = a + c1;
65169689Skan       if (x EQ/NEQ c2) goto ... else goto ...
66169689Skan
67169689Skan   Will be transformed into:
68169689Skan
69169689Skan     bb0:
70169689Skan        if (a EQ/NEQ (c2 - c1)) goto ... else goto ...
71169689Skan
72169689Skan   Similarly for x = a - c1.
73169689Skan
74169689Skan   Or
75169689Skan
76169689Skan     bb0:
77169689Skan       x = !a
78169689Skan       if (x) goto ... else goto ...
79169689Skan
80169689Skan   Will be transformed into:
81169689Skan
82169689Skan     bb0:
83169689Skan        if (a == 0) goto ... else goto ...
84169689Skan
85169689Skan   Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
86169689Skan   For these cases, we propagate A into all, possibly more than one,
87169689Skan   COND_EXPRs that use X.
88169689Skan
89169689Skan   Or
90169689Skan
91169689Skan     bb0:
92169689Skan       x = (typecast) a
93169689Skan       if (x) goto ... else goto ...
94169689Skan
95169689Skan   Will be transformed into:
96169689Skan
97169689Skan     bb0:
98169689Skan        if (a != 0) goto ... else goto ...
99169689Skan
100169689Skan   (Assuming a is an integral type and x is a boolean or x is an
101169689Skan    integral and a is a boolean.)
102169689Skan
103169689Skan   Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
104169689Skan   For these cases, we propagate A into all, possibly more than one,
105169689Skan   COND_EXPRs that use X.
106169689Skan
107169689Skan   In addition to eliminating the variable and the statement which assigns
108169689Skan   a value to the variable, we may be able to later thread the jump without
109169689Skan   adding insane complexity in the dominator optimizer.
110169689Skan
111169689Skan   Also note these transformations can cascade.  We handle this by having
112169689Skan   a worklist of COND_EXPR statements to examine.  As we make a change to
113169689Skan   a statement, we put it back on the worklist to examine on the next
114169689Skan   iteration of the main loop.
115169689Skan
116169689Skan   A second class of propagation opportunities arises for ADDR_EXPR
117169689Skan   nodes.
118169689Skan
119169689Skan     ptr = &x->y->z;
120169689Skan     res = *ptr;
121169689Skan
122169689Skan   Will get turned into
123169689Skan
124169689Skan     res = x->y->z;
125169689Skan
126169689Skan   Or
127169689Skan
128169689Skan     ptr = &x[0];
129169689Skan     ptr2 = ptr + <constant>;
130169689Skan
131169689Skan   Will get turned into
132169689Skan
133169689Skan     ptr2 = &x[constant/elementsize];
134169689Skan
135169689Skan  Or
136169689Skan
137169689Skan     ptr = &x[0];
138169689Skan     offset = index * element_size;
139169689Skan     offset_p = (pointer) offset;
140169689Skan     ptr2 = ptr + offset_p
141169689Skan
142169689Skan  Will get turned into:
143169689Skan
144169689Skan     ptr2 = &x[index];
145169689Skan
146169689Skan  We also propagate casts into SWITCH_EXPR and COND_EXPR conditions to
147169689Skan  allow us to remove the cast and {NOT_EXPR,NEG_EXPR} into a subsequent
148169689Skan  {NOT_EXPR,NEG_EXPR}.
149169689Skan
150169689Skan   This will (of course) be extended as other needs arise.  */
151169689Skan
152169689Skan
153169689Skan/* Set to true if we delete EH edges during the optimization.  */
154169689Skanstatic bool cfg_changed;
155169689Skan
156169689Skan
157169689Skan/* Given an SSA_NAME VAR, return true if and only if VAR is defined by
158169689Skan   a comparison.  */
159169689Skan
160169689Skanstatic bool
161169689Skanssa_name_defined_by_comparison_p (tree var)
162169689Skan{
163169689Skan  tree def = SSA_NAME_DEF_STMT (var);
164169689Skan
165169689Skan  if (TREE_CODE (def) == MODIFY_EXPR)
166169689Skan    {
167169689Skan      tree rhs = TREE_OPERAND (def, 1);
168169689Skan      return COMPARISON_CLASS_P (rhs);
169169689Skan    }
170169689Skan
171169689Skan  return 0;
172169689Skan}
173169689Skan
174169689Skan/* Forward propagate a single-use variable into COND once.  Return a
175169689Skan   new condition if successful.  Return NULL_TREE otherwise.  */
176169689Skan
177169689Skanstatic tree
178169689Skanforward_propagate_into_cond_1 (tree cond, tree *test_var_p)
179169689Skan{
180169689Skan  tree new_cond = NULL_TREE;
181169689Skan  enum tree_code cond_code = TREE_CODE (cond);
182169689Skan  tree test_var = NULL_TREE;
183169689Skan  tree def;
184169689Skan  tree def_rhs;
185169689Skan
186169689Skan  /* If the condition is not a lone variable or an equality test of an
187169689Skan     SSA_NAME against an integral constant, then we do not have an
188169689Skan     optimizable case.
189169689Skan
190169689Skan     Note these conditions also ensure the COND_EXPR has no
191169689Skan     virtual operands or other side effects.  */
192169689Skan  if (cond_code != SSA_NAME
193169689Skan      && !((cond_code == EQ_EXPR || cond_code == NE_EXPR)
194169689Skan	   && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
195169689Skan	   && CONSTANT_CLASS_P (TREE_OPERAND (cond, 1))
196169689Skan	   && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))))
197169689Skan    return NULL_TREE;
198169689Skan
199169689Skan  /* Extract the single variable used in the test into TEST_VAR.  */
200169689Skan  if (cond_code == SSA_NAME)
201169689Skan    test_var = cond;
202169689Skan  else
203169689Skan    test_var = TREE_OPERAND (cond, 0);
204169689Skan
205169689Skan  /* Now get the defining statement for TEST_VAR.  Skip this case if
206169689Skan     it's not defined by some MODIFY_EXPR.  */
207169689Skan  def = SSA_NAME_DEF_STMT (test_var);
208169689Skan  if (TREE_CODE (def) != MODIFY_EXPR)
209169689Skan    return NULL_TREE;
210169689Skan
211169689Skan  def_rhs = TREE_OPERAND (def, 1);
212169689Skan
213169689Skan  /* If TEST_VAR is set by adding or subtracting a constant
214169689Skan     from an SSA_NAME, then it is interesting to us as we
215169689Skan     can adjust the constant in the conditional and thus
216169689Skan     eliminate the arithmetic operation.  */
217169689Skan  if (TREE_CODE (def_rhs) == PLUS_EXPR
218169689Skan      || TREE_CODE (def_rhs) == MINUS_EXPR)
219169689Skan    {
220169689Skan      tree op0 = TREE_OPERAND (def_rhs, 0);
221169689Skan      tree op1 = TREE_OPERAND (def_rhs, 1);
222169689Skan
223169689Skan      /* The first operand must be an SSA_NAME and the second
224169689Skan	 operand must be a constant.  */
225169689Skan      if (TREE_CODE (op0) != SSA_NAME
226169689Skan	  || !CONSTANT_CLASS_P (op1)
227169689Skan	  || !INTEGRAL_TYPE_P (TREE_TYPE (op1)))
228169689Skan	return NULL_TREE;
229169689Skan
230169689Skan      /* Don't propagate if the first operand occurs in
231169689Skan	 an abnormal PHI.  */
232169689Skan      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0))
233169689Skan	return NULL_TREE;
234169689Skan
235169689Skan      if (has_single_use (test_var))
236169689Skan	{
237169689Skan	  enum tree_code new_code;
238169689Skan	  tree t;
239169689Skan
240169689Skan	  /* If the variable was defined via X + C, then we must
241169689Skan	     subtract C from the constant in the conditional.
242169689Skan	     Otherwise we add C to the constant in the
243169689Skan	     conditional.  The result must fold into a valid
244169689Skan	     gimple operand to be optimizable.  */
245169689Skan	  new_code = (TREE_CODE (def_rhs) == PLUS_EXPR
246169689Skan		      ? MINUS_EXPR : PLUS_EXPR);
247169689Skan	  t = int_const_binop (new_code, TREE_OPERAND (cond, 1), op1, 0);
248169689Skan	  if (!is_gimple_val (t))
249169689Skan	    return NULL_TREE;
250169689Skan
251169689Skan	  new_cond = build2 (cond_code, boolean_type_node, op0, t);
252169689Skan	}
253169689Skan    }
254169689Skan
255169689Skan  /* These cases require comparisons of a naked SSA_NAME or
256169689Skan     comparison of an SSA_NAME against zero or one.  */
257169689Skan  else if (TREE_CODE (cond) == SSA_NAME
258169689Skan	   || integer_zerop (TREE_OPERAND (cond, 1))
259169689Skan	   || integer_onep (TREE_OPERAND (cond, 1)))
260169689Skan    {
261169689Skan      /* If TEST_VAR is set from a relational operation
262169689Skan	 between two SSA_NAMEs or a combination of an SSA_NAME
263169689Skan	 and a constant, then it is interesting.  */
264169689Skan      if (COMPARISON_CLASS_P (def_rhs))
265169689Skan	{
266169689Skan	  tree op0 = TREE_OPERAND (def_rhs, 0);
267169689Skan	  tree op1 = TREE_OPERAND (def_rhs, 1);
268169689Skan
269169689Skan	  /* Both operands of DEF_RHS must be SSA_NAMEs or
270169689Skan	     constants.  */
271169689Skan	  if ((TREE_CODE (op0) != SSA_NAME
272169689Skan	       && !is_gimple_min_invariant (op0))
273169689Skan	      || (TREE_CODE (op1) != SSA_NAME
274169689Skan		  && !is_gimple_min_invariant (op1)))
275169689Skan	    return NULL_TREE;
276169689Skan
277169689Skan	  /* Don't propagate if the first operand occurs in
278169689Skan	     an abnormal PHI.  */
279169689Skan	  if (TREE_CODE (op0) == SSA_NAME
280169689Skan	      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0))
281169689Skan	    return NULL_TREE;
282169689Skan
283169689Skan	  /* Don't propagate if the second operand occurs in
284169689Skan	     an abnormal PHI.  */
285169689Skan	  if (TREE_CODE (op1) == SSA_NAME
286169689Skan	      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op1))
287169689Skan	    return NULL_TREE;
288169689Skan
289169689Skan	  if (has_single_use (test_var))
290169689Skan	    {
291169689Skan	      /* TEST_VAR was set from a relational operator.  */
292169689Skan	      new_cond = build2 (TREE_CODE (def_rhs),
293169689Skan				 boolean_type_node, op0, op1);
294169689Skan
295169689Skan	      /* Invert the conditional if necessary.  */
296169689Skan	      if ((cond_code == EQ_EXPR
297169689Skan		   && integer_zerop (TREE_OPERAND (cond, 1)))
298169689Skan		  || (cond_code == NE_EXPR
299169689Skan		      && integer_onep (TREE_OPERAND (cond, 1))))
300169689Skan		{
301169689Skan		  new_cond = invert_truthvalue (new_cond);
302169689Skan
303169689Skan		  /* If we did not get a simple relational
304169689Skan		     expression or bare SSA_NAME, then we can
305169689Skan		     not optimize this case.  */
306169689Skan		  if (!COMPARISON_CLASS_P (new_cond)
307169689Skan		      && TREE_CODE (new_cond) != SSA_NAME)
308169689Skan		    new_cond = NULL_TREE;
309169689Skan		}
310169689Skan	    }
311169689Skan	}
312169689Skan
313169689Skan      /* If TEST_VAR is set from a TRUTH_NOT_EXPR, then it
314169689Skan	 is interesting.  */
315169689Skan      else if (TREE_CODE (def_rhs) == TRUTH_NOT_EXPR)
316169689Skan	{
317169689Skan	  enum tree_code new_code;
318169689Skan
319169689Skan	  def_rhs = TREE_OPERAND (def_rhs, 0);
320169689Skan
321169689Skan	  /* DEF_RHS must be an SSA_NAME or constant.  */
322169689Skan	  if (TREE_CODE (def_rhs) != SSA_NAME
323169689Skan	      && !is_gimple_min_invariant (def_rhs))
324169689Skan	    return NULL_TREE;
325169689Skan
326169689Skan	  /* Don't propagate if the operand occurs in
327169689Skan	     an abnormal PHI.  */
328169689Skan	  if (TREE_CODE (def_rhs) == SSA_NAME
329169689Skan	      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def_rhs))
330169689Skan	    return NULL_TREE;
331169689Skan
332169689Skan	  if (cond_code == SSA_NAME
333169689Skan	      || (cond_code == NE_EXPR
334169689Skan		  && integer_zerop (TREE_OPERAND (cond, 1)))
335169689Skan	      || (cond_code == EQ_EXPR
336169689Skan		  && integer_onep (TREE_OPERAND (cond, 1))))
337169689Skan	    new_code = EQ_EXPR;
338169689Skan	  else
339169689Skan	    new_code = NE_EXPR;
340169689Skan
341169689Skan	  new_cond = build2 (new_code, boolean_type_node, def_rhs,
342169689Skan			     fold_convert (TREE_TYPE (def_rhs),
343169689Skan					   integer_zero_node));
344169689Skan	}
345169689Skan
346169689Skan      /* If TEST_VAR was set from a cast of an integer type
347169689Skan	 to a boolean type or a cast of a boolean to an
348169689Skan	 integral, then it is interesting.  */
349169689Skan      else if (TREE_CODE (def_rhs) == NOP_EXPR
350169689Skan	       || TREE_CODE (def_rhs) == CONVERT_EXPR)
351169689Skan	{
352169689Skan	  tree outer_type;
353169689Skan	  tree inner_type;
354169689Skan
355169689Skan	  outer_type = TREE_TYPE (def_rhs);
356169689Skan	  inner_type = TREE_TYPE (TREE_OPERAND (def_rhs, 0));
357169689Skan
358169689Skan	  if ((TREE_CODE (outer_type) == BOOLEAN_TYPE
359169689Skan	       && INTEGRAL_TYPE_P (inner_type))
360169689Skan	      || (TREE_CODE (inner_type) == BOOLEAN_TYPE
361169689Skan		  && INTEGRAL_TYPE_P (outer_type)))
362169689Skan	    ;
363169689Skan	  else if (INTEGRAL_TYPE_P (outer_type)
364169689Skan		   && INTEGRAL_TYPE_P (inner_type)
365169689Skan		   && TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME
366169689Skan		   && ssa_name_defined_by_comparison_p (TREE_OPERAND (def_rhs,
367169689Skan								      0)))
368169689Skan	    ;
369169689Skan	  else
370169689Skan	    return NULL_TREE;
371169689Skan
372169689Skan	  /* Don't propagate if the operand occurs in
373169689Skan	     an abnormal PHI.  */
374169689Skan	  if (TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME
375169689Skan	      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND
376169689Skan						  (def_rhs, 0)))
377169689Skan	    return NULL_TREE;
378169689Skan
379169689Skan	  if (has_single_use (test_var))
380169689Skan	    {
381169689Skan	      enum tree_code new_code;
382169689Skan	      tree new_arg;
383169689Skan
384169689Skan	      if (cond_code == SSA_NAME
385169689Skan		  || (cond_code == NE_EXPR
386169689Skan		      && integer_zerop (TREE_OPERAND (cond, 1)))
387169689Skan		  || (cond_code == EQ_EXPR
388169689Skan		      && integer_onep (TREE_OPERAND (cond, 1))))
389169689Skan		new_code = NE_EXPR;
390169689Skan	      else
391169689Skan		new_code = EQ_EXPR;
392169689Skan
393169689Skan	      new_arg = TREE_OPERAND (def_rhs, 0);
394169689Skan	      new_cond = build2 (new_code, boolean_type_node, new_arg,
395169689Skan				 fold_convert (TREE_TYPE (new_arg),
396169689Skan					       integer_zero_node));
397169689Skan	    }
398169689Skan	}
399169689Skan    }
400169689Skan
401169689Skan  *test_var_p = test_var;
402169689Skan  return new_cond;
403169689Skan}
404169689Skan
405169689Skan/* COND is a condition of the form:
406169689Skan
407169689Skan     x == const or x != const
408169689Skan
409169689Skan   Look back to x's defining statement and see if x is defined as
410169689Skan
411169689Skan     x = (type) y;
412169689Skan
413169689Skan   If const is unchanged if we convert it to type, then we can build
414169689Skan   the equivalent expression:
415169689Skan
416169689Skan
417169689Skan      y == const or y != const
418169689Skan
419169689Skan   Which may allow further optimizations.
420169689Skan
421169689Skan   Return the equivalent comparison or NULL if no such equivalent comparison
422169689Skan   was found.  */
423169689Skan
424169689Skanstatic tree
425169689Skanfind_equivalent_equality_comparison (tree cond)
426169689Skan{
427169689Skan  tree op0 = TREE_OPERAND (cond, 0);
428169689Skan  tree op1 = TREE_OPERAND (cond, 1);
429169689Skan  tree def_stmt = SSA_NAME_DEF_STMT (op0);
430169689Skan
431169689Skan  while (def_stmt
432169689Skan	 && TREE_CODE (def_stmt) == MODIFY_EXPR
433169689Skan	 && TREE_CODE (TREE_OPERAND (def_stmt, 1)) == SSA_NAME)
434169689Skan    def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (def_stmt, 1));
435169689Skan
436169689Skan  /* OP0 might have been a parameter, so first make sure it
437169689Skan     was defined by a MODIFY_EXPR.  */
438169689Skan  if (def_stmt && TREE_CODE (def_stmt) == MODIFY_EXPR)
439169689Skan    {
440169689Skan      tree def_rhs = TREE_OPERAND (def_stmt, 1);
441169689Skan
442169689Skan      /* If either operand to the comparison is a pointer to
443169689Skan	 a function, then we can not apply this optimization
444169689Skan	 as some targets require function pointers to be
445169689Skan	 canonicalized and in this case this optimization would
446169689Skan	 eliminate a necessary canonicalization.  */
447169689Skan      if ((POINTER_TYPE_P (TREE_TYPE (op0))
448169689Skan	   && TREE_CODE (TREE_TYPE (TREE_TYPE (op0))) == FUNCTION_TYPE)
449169689Skan	  || (POINTER_TYPE_P (TREE_TYPE (op1))
450169689Skan	      && TREE_CODE (TREE_TYPE (TREE_TYPE (op1))) == FUNCTION_TYPE))
451169689Skan	return NULL;
452169689Skan
453169689Skan      /* Now make sure the RHS of the MODIFY_EXPR is a typecast.  */
454169689Skan      if ((TREE_CODE (def_rhs) == NOP_EXPR
455169689Skan	   || TREE_CODE (def_rhs) == CONVERT_EXPR)
456169689Skan	  && TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME)
457169689Skan	{
458169689Skan	  tree def_rhs_inner = TREE_OPERAND (def_rhs, 0);
459169689Skan	  tree def_rhs_inner_type = TREE_TYPE (def_rhs_inner);
460169689Skan	  tree new;
461169689Skan
462169689Skan	  if (TYPE_PRECISION (def_rhs_inner_type)
463169689Skan	      > TYPE_PRECISION (TREE_TYPE (def_rhs)))
464169689Skan	    return NULL;
465169689Skan
466169689Skan	  /* If the inner type of the conversion is a pointer to
467169689Skan	     a function, then we can not apply this optimization
468169689Skan	     as some targets require function pointers to be
469169689Skan	     canonicalized.  This optimization would result in
470169689Skan	     canonicalization of the pointer when it was not originally
471169689Skan	     needed/intended.  */
472169689Skan	  if (POINTER_TYPE_P (def_rhs_inner_type)
473169689Skan	      && TREE_CODE (TREE_TYPE (def_rhs_inner_type)) == FUNCTION_TYPE)
474169689Skan	    return NULL;
475169689Skan
476169689Skan	  /* What we want to prove is that if we convert OP1 to
477169689Skan	     the type of the object inside the NOP_EXPR that the
478169689Skan	     result is still equivalent to SRC.
479169689Skan
480169689Skan	     If that is true, the build and return new equivalent
481169689Skan	     condition which uses the source of the typecast and the
482169689Skan	     new constant (which has only changed its type).  */
483169689Skan	  new = fold_build1 (TREE_CODE (def_rhs), def_rhs_inner_type, op1);
484169689Skan	  STRIP_USELESS_TYPE_CONVERSION (new);
485169689Skan	  if (is_gimple_val (new) && tree_int_cst_equal (new, op1))
486169689Skan	    return build2 (TREE_CODE (cond), TREE_TYPE (cond),
487169689Skan			   def_rhs_inner, new);
488169689Skan	}
489169689Skan    }
490169689Skan  return NULL;
491169689Skan}
492169689Skan
493169689Skan/* STMT is a COND_EXPR
494169689Skan
495169689Skan   This routine attempts to find equivalent forms of the condition
496169689Skan   which we may be able to optimize better.  */
497169689Skan
498169689Skanstatic void
499169689Skansimplify_cond (tree stmt)
500169689Skan{
501169689Skan  tree cond = COND_EXPR_COND (stmt);
502169689Skan
503169689Skan  if (COMPARISON_CLASS_P (cond))
504169689Skan    {
505169689Skan      tree op0 = TREE_OPERAND (cond, 0);
506169689Skan      tree op1 = TREE_OPERAND (cond, 1);
507169689Skan
508169689Skan      if (TREE_CODE (op0) == SSA_NAME && is_gimple_min_invariant (op1))
509169689Skan	{
510169689Skan	  /* First see if we have test of an SSA_NAME against a constant
511169689Skan	     where the SSA_NAME is defined by an earlier typecast which
512169689Skan	     is irrelevant when performing tests against the given
513169689Skan	     constant.  */
514169689Skan	  if (TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR)
515169689Skan	    {
516169689Skan	      tree new_cond = find_equivalent_equality_comparison (cond);
517169689Skan
518169689Skan	      if (new_cond)
519169689Skan		{
520169689Skan		  COND_EXPR_COND (stmt) = new_cond;
521169689Skan		  update_stmt (stmt);
522169689Skan		}
523169689Skan	    }
524169689Skan	}
525169689Skan    }
526169689Skan}
527169689Skan
528169689Skan/* Forward propagate a single-use variable into COND_EXPR as many
529169689Skan   times as possible.  */
530169689Skan
531169689Skanstatic void
532169689Skanforward_propagate_into_cond (tree cond_expr)
533169689Skan{
534169689Skan  gcc_assert (TREE_CODE (cond_expr) == COND_EXPR);
535169689Skan
536169689Skan  while (1)
537169689Skan    {
538169689Skan      tree test_var = NULL_TREE;
539169689Skan      tree cond = COND_EXPR_COND (cond_expr);
540169689Skan      tree new_cond = forward_propagate_into_cond_1 (cond, &test_var);
541169689Skan
542169689Skan      /* Return if unsuccessful.  */
543169689Skan      if (new_cond == NULL_TREE)
544169689Skan	break;
545169689Skan
546169689Skan      /* Dump details.  */
547169689Skan      if (dump_file && (dump_flags & TDF_DETAILS))
548169689Skan	{
549169689Skan	  fprintf (dump_file, "  Replaced '");
550169689Skan	  print_generic_expr (dump_file, cond, dump_flags);
551169689Skan	  fprintf (dump_file, "' with '");
552169689Skan	  print_generic_expr (dump_file, new_cond, dump_flags);
553169689Skan	  fprintf (dump_file, "'\n");
554169689Skan	}
555169689Skan
556169689Skan      COND_EXPR_COND (cond_expr) = new_cond;
557169689Skan      update_stmt (cond_expr);
558169689Skan
559169689Skan      if (has_zero_uses (test_var))
560169689Skan	{
561169689Skan	  tree def = SSA_NAME_DEF_STMT (test_var);
562169689Skan	  block_stmt_iterator bsi = bsi_for_stmt (def);
563169689Skan	  bsi_remove (&bsi, true);
564169689Skan	}
565169689Skan    }
566169689Skan
567169689Skan  /* There are further simplifications that can be performed
568169689Skan     on COND_EXPRs.  Specifically, when comparing an SSA_NAME
569169689Skan     against a constant where the SSA_NAME is the result of a
570169689Skan     conversion.  Perhaps this should be folded into the rest
571169689Skan     of the COND_EXPR simplification code.  */
572169689Skan  simplify_cond (cond_expr);
573169689Skan}
574169689Skan
575169689Skan/* We've just substituted an ADDR_EXPR into stmt.  Update all the
576169689Skan   relevant data structures to match.  */
577169689Skan
578169689Skanstatic void
579169689Skantidy_after_forward_propagate_addr (tree stmt)
580169689Skan{
581169689Skan  /* We may have turned a trapping insn into a non-trapping insn.  */
582169689Skan  if (maybe_clean_or_replace_eh_stmt (stmt, stmt)
583169689Skan      && tree_purge_dead_eh_edges (bb_for_stmt (stmt)))
584169689Skan    cfg_changed = true;
585169689Skan
586169689Skan  if (TREE_CODE (TREE_OPERAND (stmt, 1)) == ADDR_EXPR)
587169689Skan     recompute_tree_invariant_for_addr_expr (TREE_OPERAND (stmt, 1));
588169689Skan
589169689Skan  mark_new_vars_to_rename (stmt);
590169689Skan}
591169689Skan
592169689Skan/* STMT defines LHS which is contains the address of the 0th element
593169689Skan   in an array.  USE_STMT uses LHS to compute the address of an
594169689Skan   arbitrary element within the array.  The (variable) byte offset
595169689Skan   of the element is contained in OFFSET.
596169689Skan
597169689Skan   We walk back through the use-def chains of OFFSET to verify that
598169689Skan   it is indeed computing the offset of an element within the array
599169689Skan   and extract the index corresponding to the given byte offset.
600169689Skan
601169689Skan   We then try to fold the entire address expression into a form
602169689Skan   &array[index].
603169689Skan
604169689Skan   If we are successful, we replace the right hand side of USE_STMT
605169689Skan   with the new address computation.  */
606169689Skan
607169689Skanstatic bool
608169689Skanforward_propagate_addr_into_variable_array_index (tree offset, tree lhs,
609169689Skan						  tree stmt, tree use_stmt)
610169689Skan{
611169689Skan  tree index;
612169689Skan
613169689Skan  /* The offset must be defined by a simple MODIFY_EXPR statement.  */
614169689Skan  if (TREE_CODE (offset) != MODIFY_EXPR)
615169689Skan    return false;
616169689Skan
617169689Skan  /* The RHS of the statement which defines OFFSET must be a gimple
618169689Skan     cast of another SSA_NAME.  */
619169689Skan  offset = TREE_OPERAND (offset, 1);
620169689Skan  if (!is_gimple_cast (offset))
621169689Skan    return false;
622169689Skan
623169689Skan  offset = TREE_OPERAND (offset, 0);
624169689Skan  if (TREE_CODE (offset) != SSA_NAME)
625169689Skan    return false;
626169689Skan
627169689Skan  /* Get the defining statement of the offset before type
628169689Skan     conversion.  */
629169689Skan  offset = SSA_NAME_DEF_STMT (offset);
630169689Skan
631169689Skan  /* The statement which defines OFFSET before type conversion
632169689Skan     must be a simple MODIFY_EXPR.  */
633169689Skan  if (TREE_CODE (offset) != MODIFY_EXPR)
634169689Skan    return false;
635169689Skan
636169689Skan  /* The RHS of the statement which defines OFFSET must be a
637169689Skan     multiplication of an object by the size of the array elements.
638169689Skan     This implicitly verifies that the size of the array elements
639169689Skan     is constant.  */
640169689Skan  offset = TREE_OPERAND (offset, 1);
641169689Skan  if (TREE_CODE (offset) != MULT_EXPR
642169689Skan      || TREE_CODE (TREE_OPERAND (offset, 1)) != INTEGER_CST
643169689Skan      || !simple_cst_equal (TREE_OPERAND (offset, 1),
644169689Skan			    TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (lhs)))))
645169689Skan    return false;
646169689Skan
647169689Skan  /* The first operand to the MULT_EXPR is the desired index.  */
648169689Skan  index = TREE_OPERAND (offset, 0);
649169689Skan
650169689Skan  /* Replace the pointer addition with array indexing.  */
651169689Skan  TREE_OPERAND (use_stmt, 1) = unshare_expr (TREE_OPERAND (stmt, 1));
652169689Skan  TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (use_stmt, 1), 0), 1) = index;
653169689Skan
654169689Skan  /* That should have created gimple, so there is no need to
655169689Skan     record information to undo the propagation.  */
656169689Skan  fold_stmt_inplace (use_stmt);
657169689Skan  tidy_after_forward_propagate_addr (use_stmt);
658169689Skan  return true;
659169689Skan}
660169689Skan
661169689Skan/* STMT is a statement of the form SSA_NAME = ADDR_EXPR <whatever>.
662169689Skan
663169689Skan   Try to forward propagate the ADDR_EXPR into the use USE_STMT.
664169689Skan   Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
665169689Skan   node or for recovery of array indexing from pointer arithmetic.
666169689Skan
667169689Skan   CHANGED is an optional pointer to a boolean variable set to true if
668169689Skan   either the LHS or RHS was changed in the USE_STMT.
669169689Skan
670169689Skan   Return true if the propagation was successful (the propagation can
671169689Skan   be not totally successful, yet things may have been changed).  */
672169689Skan
673169689Skanstatic bool
674169689Skanforward_propagate_addr_expr_1 (tree stmt, tree use_stmt, bool *changed)
675169689Skan{
676169689Skan  tree name = TREE_OPERAND (stmt, 0);
677169689Skan  tree lhs, rhs, array_ref;
678169689Skan
679169689Skan  /* Strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS.
680169689Skan     ADDR_EXPR will not appear on the LHS.  */
681169689Skan  lhs = TREE_OPERAND (use_stmt, 0);
682169689Skan  while (TREE_CODE (lhs) == COMPONENT_REF || TREE_CODE (lhs) == ARRAY_REF)
683169689Skan    lhs = TREE_OPERAND (lhs, 0);
684169689Skan
685169689Skan  /* Now see if the LHS node is an INDIRECT_REF using NAME.  If so,
686169689Skan     propagate the ADDR_EXPR into the use of NAME and fold the result.  */
687169689Skan  if (TREE_CODE (lhs) == INDIRECT_REF && TREE_OPERAND (lhs, 0) == name)
688169689Skan    {
689169689Skan      /* This should always succeed in creating gimple, so there is
690169689Skan	 no need to save enough state to undo this propagation.  */
691169689Skan      TREE_OPERAND (lhs, 0) = unshare_expr (TREE_OPERAND (stmt, 1));
692169689Skan      fold_stmt_inplace (use_stmt);
693169689Skan      tidy_after_forward_propagate_addr (use_stmt);
694169689Skan      if (changed)
695169689Skan	*changed = true;
696169689Skan    }
697169689Skan
698169689Skan  /* Trivial case.  The use statement could be a trivial copy.  We
699169689Skan     go ahead and handle that case here since it's trivial and
700169689Skan     removes the need to run copy-prop before this pass to get
701169689Skan     the best results.  Also note that by handling this case here
702169689Skan     we can catch some cascading effects, ie the single use is
703169689Skan     in a copy, and the copy is used later by a single INDIRECT_REF
704169689Skan     for example.  */
705169689Skan  else if (TREE_CODE (lhs) == SSA_NAME && TREE_OPERAND (use_stmt, 1) == name)
706169689Skan    {
707169689Skan      TREE_OPERAND (use_stmt, 1) = unshare_expr (TREE_OPERAND (stmt, 1));
708169689Skan      tidy_after_forward_propagate_addr (use_stmt);
709169689Skan      if (changed)
710169689Skan	*changed = true;
711169689Skan      return true;
712169689Skan    }
713169689Skan
714169689Skan  /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
715169689Skan     nodes from the RHS.  */
716169689Skan  rhs = TREE_OPERAND (use_stmt, 1);
717169689Skan  while (TREE_CODE (rhs) == COMPONENT_REF
718169689Skan	 || TREE_CODE (rhs) == ARRAY_REF
719169689Skan	 || TREE_CODE (rhs) == ADDR_EXPR)
720169689Skan    rhs = TREE_OPERAND (rhs, 0);
721169689Skan
722169689Skan  /* Now see if the RHS node is an INDIRECT_REF using NAME.  If so,
723169689Skan     propagate the ADDR_EXPR into the use of NAME and fold the result.  */
724169689Skan  if (TREE_CODE (rhs) == INDIRECT_REF && TREE_OPERAND (rhs, 0) == name)
725169689Skan    {
726169689Skan      /* This should always succeed in creating gimple, so there is
727169689Skan         no need to save enough state to undo this propagation.  */
728169689Skan      TREE_OPERAND (rhs, 0) = unshare_expr (TREE_OPERAND (stmt, 1));
729169689Skan      fold_stmt_inplace (use_stmt);
730169689Skan      tidy_after_forward_propagate_addr (use_stmt);
731169689Skan      if (changed)
732169689Skan	*changed = true;
733169689Skan      return true;
734169689Skan    }
735169689Skan
736169689Skan  /* The remaining cases are all for turning pointer arithmetic into
737169689Skan     array indexing.  They only apply when we have the address of
738169689Skan     element zero in an array.  If that is not the case then there
739169689Skan     is nothing to do.  */
740169689Skan  array_ref = TREE_OPERAND (TREE_OPERAND (stmt, 1), 0);
741169689Skan  if (TREE_CODE (array_ref) != ARRAY_REF
742169689Skan      || TREE_CODE (TREE_TYPE (TREE_OPERAND (array_ref, 0))) != ARRAY_TYPE
743169689Skan      || !integer_zerop (TREE_OPERAND (array_ref, 1)))
744169689Skan    return false;
745169689Skan
746169689Skan  /* If the use of the ADDR_EXPR must be a PLUS_EXPR, or else there
747169689Skan     is nothing to do. */
748169689Skan  if (TREE_CODE (rhs) != PLUS_EXPR)
749169689Skan    return false;
750169689Skan
751169689Skan  /* Try to optimize &x[0] + C where C is a multiple of the size
752169689Skan     of the elements in X into &x[C/element size].  */
753169689Skan  if (TREE_OPERAND (rhs, 0) == name
754169689Skan      && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
755169689Skan    {
756169689Skan      tree orig = unshare_expr (rhs);
757169689Skan      TREE_OPERAND (rhs, 0) = unshare_expr (TREE_OPERAND (stmt, 1));
758169689Skan
759169689Skan      /* If folding succeeds, then we have just exposed new variables
760169689Skan	 in USE_STMT which will need to be renamed.  If folding fails,
761169689Skan	 then we need to put everything back the way it was.  */
762169689Skan      if (fold_stmt_inplace (use_stmt))
763169689Skan	{
764169689Skan	  tidy_after_forward_propagate_addr (use_stmt);
765169689Skan	  if (changed)
766169689Skan	    *changed = true;
767169689Skan	  return true;
768169689Skan	}
769169689Skan      else
770169689Skan	{
771169689Skan	  TREE_OPERAND (use_stmt, 1) = orig;
772169689Skan	  update_stmt (use_stmt);
773169689Skan	  return false;
774169689Skan	}
775169689Skan    }
776169689Skan
777169689Skan  /* Try to optimize &x[0] + OFFSET where OFFSET is defined by
778169689Skan     converting a multiplication of an index by the size of the
779169689Skan     array elements, then the result is converted into the proper
780169689Skan     type for the arithmetic.  */
781169689Skan  if (TREE_OPERAND (rhs, 0) == name
782169689Skan      && TREE_CODE (TREE_OPERAND (rhs, 1)) == SSA_NAME
783169689Skan      /* Avoid problems with IVopts creating PLUS_EXPRs with a
784169689Skan	 different type than their operands.  */
785169689Skan      && lang_hooks.types_compatible_p (TREE_TYPE (name), TREE_TYPE (rhs)))
786169689Skan    {
787169689Skan      bool res;
788169689Skan      tree offset_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 1));
789169689Skan
790169689Skan      res = forward_propagate_addr_into_variable_array_index (offset_stmt, lhs,
791169689Skan							      stmt, use_stmt);
792169689Skan      if (res && changed)
793169689Skan	*changed = true;
794169689Skan      return res;
795169689Skan    }
796169689Skan
797169689Skan  /* Same as the previous case, except the operands of the PLUS_EXPR
798169689Skan     were reversed.  */
799169689Skan  if (TREE_OPERAND (rhs, 1) == name
800169689Skan      && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
801169689Skan      /* Avoid problems with IVopts creating PLUS_EXPRs with a
802169689Skan	 different type than their operands.  */
803169689Skan      && lang_hooks.types_compatible_p (TREE_TYPE (name), TREE_TYPE (rhs)))
804169689Skan    {
805169689Skan      bool res;
806169689Skan      tree offset_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
807169689Skan      res = forward_propagate_addr_into_variable_array_index (offset_stmt, lhs,
808169689Skan							      stmt, use_stmt);
809169689Skan      if (res && changed)
810169689Skan	*changed = true;
811169689Skan      return res;
812169689Skan    }
813169689Skan  return false;
814169689Skan}
815169689Skan
816169689Skan/* STMT is a statement of the form SSA_NAME = ADDR_EXPR <whatever>.
817169689Skan   SOME is a pointer to a boolean value indicating whether we
818169689Skan   propagated the address expression anywhere.
819169689Skan
820169689Skan   Try to forward propagate the ADDR_EXPR into all uses of the SSA_NAME.
821169689Skan   Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
822169689Skan   node or for recovery of array indexing from pointer arithmetic.
823169689Skan   Returns true, if all uses have been propagated into.  */
824169689Skan
825169689Skanstatic bool
826169689Skanforward_propagate_addr_expr (tree stmt, bool *some)
827169689Skan{
828169689Skan  int stmt_loop_depth = bb_for_stmt (stmt)->loop_depth;
829169689Skan  tree name = TREE_OPERAND (stmt, 0);
830169689Skan  imm_use_iterator iter;
831169689Skan  tree use_stmt;
832169689Skan  bool all = true;
833169689Skan
834169689Skan  FOR_EACH_IMM_USE_STMT (use_stmt, iter, name)
835169689Skan    {
836169689Skan      bool result;
837169689Skan
838169689Skan      /* If the use is not in a simple assignment statement, then
839169689Skan	 there is nothing we can do.  */
840169689Skan      if (TREE_CODE (use_stmt) != MODIFY_EXPR)
841169689Skan	{
842169689Skan	  all = false;
843169689Skan	  continue;
844169689Skan	}
845169689Skan
846169689Skan      /* If the use is in a deeper loop nest, then we do not want
847169689Skan	 to propagate the ADDR_EXPR into the loop as that is likely
848169689Skan	 adding expression evaluations into the loop.  */
849169689Skan      if (bb_for_stmt (use_stmt)->loop_depth > stmt_loop_depth)
850169689Skan	{
851169689Skan	  all = false;
852169689Skan	  continue;
853169689Skan	}
854169689Skan
855169689Skan      /* If the use_stmt has side-effects, don't propagate into it.  */
856169689Skan      if (stmt_ann (use_stmt)->has_volatile_ops)
857169689Skan        {
858169689Skan	  all = false;
859169689Skan	  continue;
860169689Skan	}
861169689Skan
862169689Skan      result = forward_propagate_addr_expr_1 (stmt, use_stmt, some);
863169689Skan      *some |= result;
864169689Skan      all &= result;
865169689Skan    }
866169689Skan
867169689Skan  return all;
868169689Skan}
869169689Skan
870169689Skan/* If we have lhs = ~x (STMT), look and see if earlier we had x = ~y.
871169689Skan   If so, we can change STMT into lhs = y which can later be copy
872169689Skan   propagated.  Similarly for negation.
873169689Skan
874169689Skan   This could trivially be formulated as a forward propagation
875169689Skan   to immediate uses.  However, we already had an implementation
876169689Skan   from DOM which used backward propagation via the use-def links.
877169689Skan
878169689Skan   It turns out that backward propagation is actually faster as
879169689Skan   there's less work to do for each NOT/NEG expression we find.
880169689Skan   Backwards propagation needs to look at the statement in a single
881169689Skan   backlink.  Forward propagation needs to look at potentially more
882169689Skan   than one forward link.  */
883169689Skan
884169689Skanstatic void
885169689Skansimplify_not_neg_expr (tree stmt)
886169689Skan{
887169689Skan  tree rhs = TREE_OPERAND (stmt, 1);
888169689Skan  tree rhs_def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
889169689Skan
890169689Skan  /* See if the RHS_DEF_STMT has the same form as our statement.  */
891169689Skan  if (TREE_CODE (rhs_def_stmt) == MODIFY_EXPR
892169689Skan      && TREE_CODE (TREE_OPERAND (rhs_def_stmt, 1)) == TREE_CODE (rhs))
893169689Skan    {
894169689Skan      tree rhs_def_operand = TREE_OPERAND (TREE_OPERAND (rhs_def_stmt, 1), 0);
895169689Skan
896169689Skan      /* Verify that RHS_DEF_OPERAND is a suitable SSA_NAME.  */
897169689Skan      if (TREE_CODE (rhs_def_operand) == SSA_NAME
898169689Skan	  && ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs_def_operand))
899169689Skan	{
900169689Skan	  TREE_OPERAND (stmt, 1) = rhs_def_operand;
901169689Skan	  update_stmt (stmt);
902169689Skan	}
903169689Skan    }
904169689Skan}
905169689Skan
906169689Skan/* STMT is a SWITCH_EXPR for which we attempt to find equivalent forms of
907169689Skan   the condition which we may be able to optimize better.  */
908169689Skan
909169689Skanstatic void
910169689Skansimplify_switch_expr (tree stmt)
911169689Skan{
912169689Skan  tree cond = SWITCH_COND (stmt);
913169689Skan  tree def, to, ti;
914169689Skan
915169689Skan  /* The optimization that we really care about is removing unnecessary
916169689Skan     casts.  That will let us do much better in propagating the inferred
917169689Skan     constant at the switch target.  */
918169689Skan  if (TREE_CODE (cond) == SSA_NAME)
919169689Skan    {
920169689Skan      def = SSA_NAME_DEF_STMT (cond);
921169689Skan      if (TREE_CODE (def) == MODIFY_EXPR)
922169689Skan	{
923169689Skan	  def = TREE_OPERAND (def, 1);
924169689Skan	  if (TREE_CODE (def) == NOP_EXPR)
925169689Skan	    {
926169689Skan	      int need_precision;
927169689Skan	      bool fail;
928169689Skan
929169689Skan	      def = TREE_OPERAND (def, 0);
930169689Skan
931169689Skan#ifdef ENABLE_CHECKING
932169689Skan	      /* ??? Why was Jeff testing this?  We are gimple...  */
933169689Skan	      gcc_assert (is_gimple_val (def));
934169689Skan#endif
935169689Skan
936169689Skan	      to = TREE_TYPE (cond);
937169689Skan	      ti = TREE_TYPE (def);
938169689Skan
939169689Skan	      /* If we have an extension that preserves value, then we
940169689Skan		 can copy the source value into the switch.  */
941169689Skan
942169689Skan	      need_precision = TYPE_PRECISION (ti);
943169689Skan	      fail = false;
944169689Skan	      if (! INTEGRAL_TYPE_P (ti))
945169689Skan		fail = true;
946169689Skan	      else if (TYPE_UNSIGNED (to) && !TYPE_UNSIGNED (ti))
947169689Skan		fail = true;
948169689Skan	      else if (!TYPE_UNSIGNED (to) && TYPE_UNSIGNED (ti))
949169689Skan		need_precision += 1;
950169689Skan	      if (TYPE_PRECISION (to) < need_precision)
951169689Skan		fail = true;
952169689Skan
953169689Skan	      if (!fail)
954169689Skan		{
955169689Skan		  SWITCH_COND (stmt) = def;
956169689Skan		  update_stmt (stmt);
957169689Skan		}
958169689Skan	    }
959169689Skan	}
960169689Skan    }
961169689Skan}
962169689Skan
963169689Skan/* Main entry point for the forward propagation optimizer.  */
964169689Skan
965169689Skanstatic unsigned int
966169689Skantree_ssa_forward_propagate_single_use_vars (void)
967169689Skan{
968169689Skan  basic_block bb;
969169689Skan  unsigned int todoflags = 0;
970169689Skan
971169689Skan  cfg_changed = false;
972169689Skan
973169689Skan  FOR_EACH_BB (bb)
974169689Skan    {
975169689Skan      block_stmt_iterator bsi;
976169689Skan
977169689Skan      /* Note we update BSI within the loop as necessary.  */
978169689Skan      for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
979169689Skan	{
980169689Skan	  tree stmt = bsi_stmt (bsi);
981169689Skan
982169689Skan	  /* If this statement sets an SSA_NAME to an address,
983169689Skan	     try to propagate the address into the uses of the SSA_NAME.  */
984169689Skan	  if (TREE_CODE (stmt) == MODIFY_EXPR)
985169689Skan	    {
986169689Skan	      tree lhs = TREE_OPERAND (stmt, 0);
987169689Skan	      tree rhs = TREE_OPERAND (stmt, 1);
988169689Skan
989169689Skan
990169689Skan	      if (TREE_CODE (lhs) != SSA_NAME)
991169689Skan		{
992169689Skan		  bsi_next (&bsi);
993169689Skan		  continue;
994169689Skan		}
995169689Skan
996169689Skan	      if (TREE_CODE (rhs) == ADDR_EXPR)
997169689Skan		{
998169689Skan		  bool some = false;
999169689Skan		  if (forward_propagate_addr_expr (stmt, &some))
1000169689Skan		    bsi_remove (&bsi, true);
1001169689Skan		  else
1002169689Skan		    bsi_next (&bsi);
1003169689Skan		  if (some)
1004169689Skan		    todoflags |= TODO_update_smt_usage;
1005169689Skan		}
1006169689Skan	      else if ((TREE_CODE (rhs) == BIT_NOT_EXPR
1007169689Skan		        || TREE_CODE (rhs) == NEGATE_EXPR)
1008169689Skan		       && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
1009169689Skan		{
1010169689Skan		  simplify_not_neg_expr (stmt);
1011169689Skan		  bsi_next (&bsi);
1012169689Skan		}
1013169689Skan	      else
1014169689Skan		bsi_next (&bsi);
1015169689Skan	    }
1016169689Skan	  else if (TREE_CODE (stmt) == SWITCH_EXPR)
1017169689Skan	    {
1018169689Skan	      simplify_switch_expr (stmt);
1019169689Skan	      bsi_next (&bsi);
1020169689Skan	    }
1021169689Skan	  else if (TREE_CODE (stmt) == COND_EXPR)
1022169689Skan	    {
1023169689Skan	      forward_propagate_into_cond (stmt);
1024169689Skan	      bsi_next (&bsi);
1025169689Skan	    }
1026169689Skan	  else
1027169689Skan	    bsi_next (&bsi);
1028169689Skan	}
1029169689Skan    }
1030169689Skan
1031169689Skan  if (cfg_changed)
1032169689Skan    cleanup_tree_cfg ();
1033169689Skan  return todoflags;
1034169689Skan}
1035169689Skan
1036169689Skan
1037169689Skanstatic bool
1038169689Skangate_forwprop (void)
1039169689Skan{
1040169689Skan  return 1;
1041169689Skan}
1042169689Skan
1043169689Skanstruct tree_opt_pass pass_forwprop = {
1044169689Skan  "forwprop",			/* name */
1045169689Skan  gate_forwprop,		/* gate */
1046169689Skan  tree_ssa_forward_propagate_single_use_vars,	/* execute */
1047169689Skan  NULL,				/* sub */
1048169689Skan  NULL,				/* next */
1049169689Skan  0,				/* static_pass_number */
1050169689Skan  TV_TREE_FORWPROP,		/* tv_id */
1051169689Skan  PROP_cfg | PROP_ssa
1052169689Skan    | PROP_alias,		/* properties_required */
1053169689Skan  0,				/* properties_provided */
1054169689Skan  PROP_smt_usage,		/* properties_destroyed */
1055169689Skan  0,				/* todo_flags_start */
1056169689Skan  TODO_dump_func /* todo_flags_finish */
1057169689Skan  | TODO_ggc_collect
1058169689Skan  | TODO_update_ssa | TODO_verify_ssa,
1059169689Skan  0					/* letter */
1060169689Skan};
1061