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