xref: /dflybsd-src/contrib/gcc-8.0/gcc/tree-ssa-scopedtables.c (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj /* Header file for SSA dominator optimizations.
2*38fd1498Szrj    Copyright (C) 2013-2018 Free Software Foundation, Inc.
3*38fd1498Szrj 
4*38fd1498Szrj This file is part of GCC.
5*38fd1498Szrj 
6*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
7*38fd1498Szrj the terms of the GNU General Public License as published by the Free
8*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
9*38fd1498Szrj version.
10*38fd1498Szrj 
11*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*38fd1498Szrj  for more details.
15*38fd1498Szrj 
16*38fd1498Szrj You should have received a copy of the GNU General Public License
17*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
18*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
19*38fd1498Szrj 
20*38fd1498Szrj #include "config.h"
21*38fd1498Szrj #include "system.h"
22*38fd1498Szrj #include "coretypes.h"
23*38fd1498Szrj #include "function.h"
24*38fd1498Szrj #include "basic-block.h"
25*38fd1498Szrj #include "tree.h"
26*38fd1498Szrj #include "gimple.h"
27*38fd1498Szrj #include "tree-pass.h"
28*38fd1498Szrj #include "tree-pretty-print.h"
29*38fd1498Szrj #include "tree-ssa-scopedtables.h"
30*38fd1498Szrj #include "tree-ssa-threadedge.h"
31*38fd1498Szrj #include "stor-layout.h"
32*38fd1498Szrj #include "fold-const.h"
33*38fd1498Szrj #include "tree-eh.h"
34*38fd1498Szrj #include "internal-fn.h"
35*38fd1498Szrj #include "tree-dfa.h"
36*38fd1498Szrj #include "options.h"
37*38fd1498Szrj #include "params.h"
38*38fd1498Szrj 
39*38fd1498Szrj static bool hashable_expr_equal_p (const struct hashable_expr *,
40*38fd1498Szrj 				   const struct hashable_expr *);
41*38fd1498Szrj 
42*38fd1498Szrj /* Initialize local stacks for this optimizer and record equivalences
43*38fd1498Szrj    upon entry to BB.  Equivalences can come from the edge traversed to
44*38fd1498Szrj    reach BB or they may come from PHI nodes at the start of BB.  */
45*38fd1498Szrj 
46*38fd1498Szrj /* Pop items off the unwinding stack, removing each from the hash table
47*38fd1498Szrj    until a marker is encountered.  */
48*38fd1498Szrj 
49*38fd1498Szrj void
pop_to_marker()50*38fd1498Szrj avail_exprs_stack::pop_to_marker ()
51*38fd1498Szrj {
52*38fd1498Szrj   /* Remove all the expressions made available in this block.  */
53*38fd1498Szrj   while (m_stack.length () > 0)
54*38fd1498Szrj     {
55*38fd1498Szrj       std::pair<expr_hash_elt_t, expr_hash_elt_t> victim = m_stack.pop ();
56*38fd1498Szrj       expr_hash_elt **slot;
57*38fd1498Szrj 
58*38fd1498Szrj       if (victim.first == NULL)
59*38fd1498Szrj 	break;
60*38fd1498Szrj 
61*38fd1498Szrj       /* This must precede the actual removal from the hash table,
62*38fd1498Szrj          as ELEMENT and the table entry may share a call argument
63*38fd1498Szrj          vector which will be freed during removal.  */
64*38fd1498Szrj       if (dump_file && (dump_flags & TDF_DETAILS))
65*38fd1498Szrj         {
66*38fd1498Szrj           fprintf (dump_file, "<<<< ");
67*38fd1498Szrj 	  victim.first->print (dump_file);
68*38fd1498Szrj         }
69*38fd1498Szrj 
70*38fd1498Szrj       slot = m_avail_exprs->find_slot (victim.first, NO_INSERT);
71*38fd1498Szrj       gcc_assert (slot && *slot == victim.first);
72*38fd1498Szrj       if (victim.second != NULL)
73*38fd1498Szrj 	{
74*38fd1498Szrj 	  delete *slot;
75*38fd1498Szrj 	  *slot = victim.second;
76*38fd1498Szrj 	}
77*38fd1498Szrj       else
78*38fd1498Szrj 	m_avail_exprs->clear_slot (slot);
79*38fd1498Szrj     }
80*38fd1498Szrj }
81*38fd1498Szrj 
82*38fd1498Szrj /* Add <ELT1,ELT2> to the unwinding stack so they can be later removed
83*38fd1498Szrj    from the hash table.  */
84*38fd1498Szrj 
85*38fd1498Szrj void
record_expr(class expr_hash_elt * elt1,class expr_hash_elt * elt2,char type)86*38fd1498Szrj avail_exprs_stack::record_expr (class expr_hash_elt *elt1,
87*38fd1498Szrj 				class expr_hash_elt *elt2,
88*38fd1498Szrj 				char type)
89*38fd1498Szrj {
90*38fd1498Szrj   if (elt1 && dump_file && (dump_flags & TDF_DETAILS))
91*38fd1498Szrj     {
92*38fd1498Szrj       fprintf (dump_file, "%c>>> ", type);
93*38fd1498Szrj       elt1->print (dump_file);
94*38fd1498Szrj     }
95*38fd1498Szrj 
96*38fd1498Szrj   m_stack.safe_push (std::pair<expr_hash_elt_t, expr_hash_elt_t> (elt1, elt2));
97*38fd1498Szrj }
98*38fd1498Szrj 
99*38fd1498Szrj /* Helper for walk_non_aliased_vuses.  Determine if we arrived at
100*38fd1498Szrj    the desired memory state.  */
101*38fd1498Szrj 
102*38fd1498Szrj static void *
vuse_eq(ao_ref *,tree vuse1,unsigned int cnt,void * data)103*38fd1498Szrj vuse_eq (ao_ref *, tree vuse1, unsigned int cnt, void *data)
104*38fd1498Szrj {
105*38fd1498Szrj   tree vuse2 = (tree) data;
106*38fd1498Szrj   if (vuse1 == vuse2)
107*38fd1498Szrj     return data;
108*38fd1498Szrj 
109*38fd1498Szrj   /* This bounds the stmt walks we perform on reference lookups
110*38fd1498Szrj      to O(1) instead of O(N) where N is the number of dominating
111*38fd1498Szrj      stores leading to a candidate.  We re-use the SCCVN param
112*38fd1498Szrj      for this as it is basically the same complexity.  */
113*38fd1498Szrj   if (cnt > (unsigned) PARAM_VALUE (PARAM_SCCVN_MAX_ALIAS_QUERIES_PER_ACCESS))
114*38fd1498Szrj     return (void *)-1;
115*38fd1498Szrj 
116*38fd1498Szrj   return NULL;
117*38fd1498Szrj }
118*38fd1498Szrj 
119*38fd1498Szrj /* We looked for STMT in the hash table, but did not find it.
120*38fd1498Szrj 
121*38fd1498Szrj    If STMT is an assignment from a binary operator, we may know something
122*38fd1498Szrj    about the operands relationship to each other which would allow
123*38fd1498Szrj    us to derive a constant value for the RHS of STMT.  */
124*38fd1498Szrj 
125*38fd1498Szrj tree
simplify_binary_operation(gimple * stmt,class expr_hash_elt element)126*38fd1498Szrj avail_exprs_stack::simplify_binary_operation (gimple *stmt,
127*38fd1498Szrj 					      class expr_hash_elt element)
128*38fd1498Szrj {
129*38fd1498Szrj   if (is_gimple_assign (stmt))
130*38fd1498Szrj     {
131*38fd1498Szrj       struct hashable_expr *expr = element.expr ();
132*38fd1498Szrj       if (expr->kind == EXPR_BINARY)
133*38fd1498Szrj 	{
134*38fd1498Szrj 	  enum tree_code code = expr->ops.binary.op;
135*38fd1498Szrj 
136*38fd1498Szrj 	  switch (code)
137*38fd1498Szrj 	    {
138*38fd1498Szrj 	    /* For these cases, if we know the operands
139*38fd1498Szrj 	       are equal, then we know the result.  */
140*38fd1498Szrj 	    case MIN_EXPR:
141*38fd1498Szrj 	    case MAX_EXPR:
142*38fd1498Szrj 	    case BIT_IOR_EXPR:
143*38fd1498Szrj 	    case BIT_AND_EXPR:
144*38fd1498Szrj 	    case BIT_XOR_EXPR:
145*38fd1498Szrj 	    case MINUS_EXPR:
146*38fd1498Szrj 	    case TRUNC_DIV_EXPR:
147*38fd1498Szrj 	    case CEIL_DIV_EXPR:
148*38fd1498Szrj 	    case FLOOR_DIV_EXPR:
149*38fd1498Szrj 	    case ROUND_DIV_EXPR:
150*38fd1498Szrj 	    case EXACT_DIV_EXPR:
151*38fd1498Szrj 	    case TRUNC_MOD_EXPR:
152*38fd1498Szrj 	    case CEIL_MOD_EXPR:
153*38fd1498Szrj 	    case FLOOR_MOD_EXPR:
154*38fd1498Szrj 	    case ROUND_MOD_EXPR:
155*38fd1498Szrj 	      {
156*38fd1498Szrj 		/* Build a simple equality expr and query the hash table
157*38fd1498Szrj 		   for it.  */
158*38fd1498Szrj 		struct hashable_expr expr;
159*38fd1498Szrj 		expr.type = boolean_type_node;
160*38fd1498Szrj 		expr.kind = EXPR_BINARY;
161*38fd1498Szrj 		expr.ops.binary.op = EQ_EXPR;
162*38fd1498Szrj 		expr.ops.binary.opnd0 = gimple_assign_rhs1 (stmt);
163*38fd1498Szrj 		expr.ops.binary.opnd1 = gimple_assign_rhs2 (stmt);
164*38fd1498Szrj 		class expr_hash_elt element2 (&expr, NULL_TREE);
165*38fd1498Szrj 		expr_hash_elt **slot
166*38fd1498Szrj 		  = m_avail_exprs->find_slot (&element2, NO_INSERT);
167*38fd1498Szrj 		tree result_type = TREE_TYPE (gimple_assign_lhs (stmt));
168*38fd1498Szrj 
169*38fd1498Szrj 		/* If the query was successful and returned a nonzero
170*38fd1498Szrj 		   result, then we know that the operands of the binary
171*38fd1498Szrj 		   expression are the same.  In many cases this allows
172*38fd1498Szrj 		   us to compute a constant result of the expression
173*38fd1498Szrj 		   at compile time, even if we do not know the exact
174*38fd1498Szrj 		   values of the operands.  */
175*38fd1498Szrj 		if (slot && *slot && integer_onep ((*slot)->lhs ()))
176*38fd1498Szrj 		  {
177*38fd1498Szrj 		    switch (code)
178*38fd1498Szrj 		      {
179*38fd1498Szrj 		      case MIN_EXPR:
180*38fd1498Szrj 		      case MAX_EXPR:
181*38fd1498Szrj 		      case BIT_IOR_EXPR:
182*38fd1498Szrj 		      case BIT_AND_EXPR:
183*38fd1498Szrj 			return gimple_assign_rhs1 (stmt);
184*38fd1498Szrj 
185*38fd1498Szrj 		      case MINUS_EXPR:
186*38fd1498Szrj 			/* This is unsafe for certain floats even in non-IEEE
187*38fd1498Szrj 			   formats.  In IEEE, it is unsafe because it does
188*38fd1498Szrj 			   wrong for NaNs.  */
189*38fd1498Szrj 			if (FLOAT_TYPE_P (result_type)
190*38fd1498Szrj 			    && HONOR_NANS (result_type))
191*38fd1498Szrj 			  break;
192*38fd1498Szrj 			/* FALLTHRU */
193*38fd1498Szrj 		      case BIT_XOR_EXPR:
194*38fd1498Szrj 		      case TRUNC_MOD_EXPR:
195*38fd1498Szrj 		      case CEIL_MOD_EXPR:
196*38fd1498Szrj 		      case FLOOR_MOD_EXPR:
197*38fd1498Szrj 		      case ROUND_MOD_EXPR:
198*38fd1498Szrj 			return build_zero_cst (result_type);
199*38fd1498Szrj 
200*38fd1498Szrj 		      case TRUNC_DIV_EXPR:
201*38fd1498Szrj 		      case CEIL_DIV_EXPR:
202*38fd1498Szrj 		      case FLOOR_DIV_EXPR:
203*38fd1498Szrj 		      case ROUND_DIV_EXPR:
204*38fd1498Szrj 		      case EXACT_DIV_EXPR:
205*38fd1498Szrj 			/* Avoid _Fract types where we can't build 1.  */
206*38fd1498Szrj 			if (ALL_FRACT_MODE_P (TYPE_MODE (result_type)))
207*38fd1498Szrj 			  break;
208*38fd1498Szrj 			return build_one_cst (result_type);
209*38fd1498Szrj 
210*38fd1498Szrj 		      default:
211*38fd1498Szrj 			gcc_unreachable ();
212*38fd1498Szrj 		      }
213*38fd1498Szrj 		  }
214*38fd1498Szrj 		break;
215*38fd1498Szrj 	      }
216*38fd1498Szrj 
217*38fd1498Szrj 	    default:
218*38fd1498Szrj 	      break;
219*38fd1498Szrj 	    }
220*38fd1498Szrj 	}
221*38fd1498Szrj     }
222*38fd1498Szrj   return NULL_TREE;
223*38fd1498Szrj }
224*38fd1498Szrj 
225*38fd1498Szrj /* Search for an existing instance of STMT in the AVAIL_EXPRS_STACK table.
226*38fd1498Szrj    If found, return its LHS. Otherwise insert STMT in the table and
227*38fd1498Szrj    return NULL_TREE.
228*38fd1498Szrj 
229*38fd1498Szrj    Also, when an expression is first inserted in the  table, it is also
230*38fd1498Szrj    is also added to AVAIL_EXPRS_STACK, so that it can be removed when
231*38fd1498Szrj    we finish processing this block and its children.  */
232*38fd1498Szrj 
233*38fd1498Szrj tree
lookup_avail_expr(gimple * stmt,bool insert,bool tbaa_p)234*38fd1498Szrj avail_exprs_stack::lookup_avail_expr (gimple *stmt, bool insert, bool tbaa_p)
235*38fd1498Szrj {
236*38fd1498Szrj   expr_hash_elt **slot;
237*38fd1498Szrj   tree lhs;
238*38fd1498Szrj 
239*38fd1498Szrj   /* Get LHS of phi, assignment, or call; else NULL_TREE.  */
240*38fd1498Szrj   if (gimple_code (stmt) == GIMPLE_PHI)
241*38fd1498Szrj     lhs = gimple_phi_result (stmt);
242*38fd1498Szrj   else
243*38fd1498Szrj     lhs = gimple_get_lhs (stmt);
244*38fd1498Szrj 
245*38fd1498Szrj   class expr_hash_elt element (stmt, lhs);
246*38fd1498Szrj 
247*38fd1498Szrj   if (dump_file && (dump_flags & TDF_DETAILS))
248*38fd1498Szrj     {
249*38fd1498Szrj       fprintf (dump_file, "LKUP ");
250*38fd1498Szrj       element.print (dump_file);
251*38fd1498Szrj     }
252*38fd1498Szrj 
253*38fd1498Szrj   /* Don't bother remembering constant assignments and copy operations.
254*38fd1498Szrj      Constants and copy operations are handled by the constant/copy propagator
255*38fd1498Szrj      in optimize_stmt.  */
256*38fd1498Szrj   if (element.expr()->kind == EXPR_SINGLE
257*38fd1498Szrj       && (TREE_CODE (element.expr()->ops.single.rhs) == SSA_NAME
258*38fd1498Szrj           || is_gimple_min_invariant (element.expr()->ops.single.rhs)))
259*38fd1498Szrj     return NULL_TREE;
260*38fd1498Szrj 
261*38fd1498Szrj   /* Finally try to find the expression in the main expression hash table.  */
262*38fd1498Szrj   slot = m_avail_exprs->find_slot (&element, (insert ? INSERT : NO_INSERT));
263*38fd1498Szrj   if (slot == NULL)
264*38fd1498Szrj     {
265*38fd1498Szrj       return NULL_TREE;
266*38fd1498Szrj     }
267*38fd1498Szrj   else if (*slot == NULL)
268*38fd1498Szrj     {
269*38fd1498Szrj       /* If we did not find the expression in the hash table, we may still
270*38fd1498Szrj 	 be able to produce a result for some expressions.  */
271*38fd1498Szrj       tree retval = avail_exprs_stack::simplify_binary_operation (stmt,
272*38fd1498Szrj 								  element);
273*38fd1498Szrj 
274*38fd1498Szrj       /* We have, in effect, allocated *SLOT for ELEMENT at this point.
275*38fd1498Szrj 	 We must initialize *SLOT to a real entry, even if we found a
276*38fd1498Szrj 	 way to prove ELEMENT was a constant after not finding ELEMENT
277*38fd1498Szrj 	 in the hash table.
278*38fd1498Szrj 
279*38fd1498Szrj 	 An uninitialized or empty slot is an indication no prior objects
280*38fd1498Szrj 	 entered into the hash table had a hash collection with ELEMENT.
281*38fd1498Szrj 
282*38fd1498Szrj 	 If we fail to do so and had such entries in the table, they
283*38fd1498Szrj 	 would become unreachable.  */
284*38fd1498Szrj       class expr_hash_elt *element2 = new expr_hash_elt (element);
285*38fd1498Szrj       *slot = element2;
286*38fd1498Szrj 
287*38fd1498Szrj       record_expr (element2, NULL, '2');
288*38fd1498Szrj       return retval;
289*38fd1498Szrj     }
290*38fd1498Szrj 
291*38fd1498Szrj   /* If we found a redundant memory operation do an alias walk to
292*38fd1498Szrj      check if we can re-use it.  */
293*38fd1498Szrj   if (gimple_vuse (stmt) != (*slot)->vop ())
294*38fd1498Szrj     {
295*38fd1498Szrj       tree vuse1 = (*slot)->vop ();
296*38fd1498Szrj       tree vuse2 = gimple_vuse (stmt);
297*38fd1498Szrj       /* If we have a load of a register and a candidate in the
298*38fd1498Szrj 	 hash with vuse1 then try to reach its stmt by walking
299*38fd1498Szrj 	 up the virtual use-def chain using walk_non_aliased_vuses.
300*38fd1498Szrj 	 But don't do this when removing expressions from the hash.  */
301*38fd1498Szrj       ao_ref ref;
302*38fd1498Szrj       if (!(vuse1 && vuse2
303*38fd1498Szrj 	    && gimple_assign_single_p (stmt)
304*38fd1498Szrj 	    && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
305*38fd1498Szrj 	    && (ao_ref_init (&ref, gimple_assign_rhs1 (stmt)),
306*38fd1498Szrj 		ref.base_alias_set = ref.ref_alias_set = tbaa_p ? -1 : 0, true)
307*38fd1498Szrj 	    && walk_non_aliased_vuses (&ref, vuse2,
308*38fd1498Szrj 				       vuse_eq, NULL, NULL, vuse1) != NULL))
309*38fd1498Szrj 	{
310*38fd1498Szrj 	  if (insert)
311*38fd1498Szrj 	    {
312*38fd1498Szrj 	      class expr_hash_elt *element2 = new expr_hash_elt (element);
313*38fd1498Szrj 
314*38fd1498Szrj 	      /* Insert the expr into the hash by replacing the current
315*38fd1498Szrj 		 entry and recording the value to restore in the
316*38fd1498Szrj 		 avail_exprs_stack.  */
317*38fd1498Szrj 	      record_expr (element2, *slot, '2');
318*38fd1498Szrj 	      *slot = element2;
319*38fd1498Szrj 	    }
320*38fd1498Szrj 	  return NULL_TREE;
321*38fd1498Szrj 	}
322*38fd1498Szrj     }
323*38fd1498Szrj 
324*38fd1498Szrj   /* Extract the LHS of the assignment so that it can be used as the current
325*38fd1498Szrj      definition of another variable.  */
326*38fd1498Szrj   lhs = (*slot)->lhs ();
327*38fd1498Szrj 
328*38fd1498Szrj   /* Valueize the result.  */
329*38fd1498Szrj   if (TREE_CODE (lhs) == SSA_NAME)
330*38fd1498Szrj     {
331*38fd1498Szrj       tree tem = SSA_NAME_VALUE (lhs);
332*38fd1498Szrj       if (tem)
333*38fd1498Szrj 	lhs = tem;
334*38fd1498Szrj     }
335*38fd1498Szrj 
336*38fd1498Szrj   if (dump_file && (dump_flags & TDF_DETAILS))
337*38fd1498Szrj     {
338*38fd1498Szrj       fprintf (dump_file, "FIND: ");
339*38fd1498Szrj       print_generic_expr (dump_file, lhs);
340*38fd1498Szrj       fprintf (dump_file, "\n");
341*38fd1498Szrj     }
342*38fd1498Szrj 
343*38fd1498Szrj   return lhs;
344*38fd1498Szrj }
345*38fd1498Szrj 
346*38fd1498Szrj /* Enter condition equivalence P into the hash table.
347*38fd1498Szrj 
348*38fd1498Szrj    This indicates that a conditional expression has a known
349*38fd1498Szrj    boolean value.  */
350*38fd1498Szrj 
351*38fd1498Szrj void
record_cond(cond_equivalence * p)352*38fd1498Szrj avail_exprs_stack::record_cond (cond_equivalence *p)
353*38fd1498Szrj {
354*38fd1498Szrj   class expr_hash_elt *element = new expr_hash_elt (&p->cond, p->value);
355*38fd1498Szrj   expr_hash_elt **slot;
356*38fd1498Szrj 
357*38fd1498Szrj   slot = m_avail_exprs->find_slot_with_hash (element, element->hash (), INSERT);
358*38fd1498Szrj   if (*slot == NULL)
359*38fd1498Szrj     {
360*38fd1498Szrj       *slot = element;
361*38fd1498Szrj       record_expr (element, NULL, '1');
362*38fd1498Szrj     }
363*38fd1498Szrj   else
364*38fd1498Szrj     delete element;
365*38fd1498Szrj }
366*38fd1498Szrj 
367*38fd1498Szrj /* Generate a hash value for a pair of expressions.  This can be used
368*38fd1498Szrj    iteratively by passing a previous result in HSTATE.
369*38fd1498Szrj 
370*38fd1498Szrj    The same hash value is always returned for a given pair of expressions,
371*38fd1498Szrj    regardless of the order in which they are presented.  This is useful in
372*38fd1498Szrj    hashing the operands of commutative functions.  */
373*38fd1498Szrj 
374*38fd1498Szrj namespace inchash
375*38fd1498Szrj {
376*38fd1498Szrj 
377*38fd1498Szrj static void
add_expr_commutative(const_tree t1,const_tree t2,hash & hstate)378*38fd1498Szrj add_expr_commutative (const_tree t1, const_tree t2, hash &hstate)
379*38fd1498Szrj {
380*38fd1498Szrj   hash one, two;
381*38fd1498Szrj 
382*38fd1498Szrj   inchash::add_expr (t1, one);
383*38fd1498Szrj   inchash::add_expr (t2, two);
384*38fd1498Szrj   hstate.add_commutative (one, two);
385*38fd1498Szrj }
386*38fd1498Szrj 
387*38fd1498Szrj /* Compute a hash value for a hashable_expr value EXPR and a
388*38fd1498Szrj    previously accumulated hash value VAL.  If two hashable_expr
389*38fd1498Szrj    values compare equal with hashable_expr_equal_p, they must
390*38fd1498Szrj    hash to the same value, given an identical value of VAL.
391*38fd1498Szrj    The logic is intended to follow inchash::add_expr in tree.c.  */
392*38fd1498Szrj 
393*38fd1498Szrj static void
add_hashable_expr(const struct hashable_expr * expr,hash & hstate)394*38fd1498Szrj add_hashable_expr (const struct hashable_expr *expr, hash &hstate)
395*38fd1498Szrj {
396*38fd1498Szrj   switch (expr->kind)
397*38fd1498Szrj     {
398*38fd1498Szrj     case EXPR_SINGLE:
399*38fd1498Szrj       inchash::add_expr (expr->ops.single.rhs, hstate);
400*38fd1498Szrj       break;
401*38fd1498Szrj 
402*38fd1498Szrj     case EXPR_UNARY:
403*38fd1498Szrj       hstate.add_object (expr->ops.unary.op);
404*38fd1498Szrj 
405*38fd1498Szrj       /* Make sure to include signedness in the hash computation.
406*38fd1498Szrj          Don't hash the type, that can lead to having nodes which
407*38fd1498Szrj          compare equal according to operand_equal_p, but which
408*38fd1498Szrj          have different hash codes.  */
409*38fd1498Szrj       if (CONVERT_EXPR_CODE_P (expr->ops.unary.op)
410*38fd1498Szrj           || expr->ops.unary.op == NON_LVALUE_EXPR)
411*38fd1498Szrj         hstate.add_int (TYPE_UNSIGNED (expr->type));
412*38fd1498Szrj 
413*38fd1498Szrj       inchash::add_expr (expr->ops.unary.opnd, hstate);
414*38fd1498Szrj       break;
415*38fd1498Szrj 
416*38fd1498Szrj     case EXPR_BINARY:
417*38fd1498Szrj       hstate.add_object (expr->ops.binary.op);
418*38fd1498Szrj       if (commutative_tree_code (expr->ops.binary.op))
419*38fd1498Szrj 	inchash::add_expr_commutative (expr->ops.binary.opnd0,
420*38fd1498Szrj 					  expr->ops.binary.opnd1, hstate);
421*38fd1498Szrj       else
422*38fd1498Szrj         {
423*38fd1498Szrj           inchash::add_expr (expr->ops.binary.opnd0, hstate);
424*38fd1498Szrj           inchash::add_expr (expr->ops.binary.opnd1, hstate);
425*38fd1498Szrj         }
426*38fd1498Szrj       break;
427*38fd1498Szrj 
428*38fd1498Szrj     case EXPR_TERNARY:
429*38fd1498Szrj       hstate.add_object (expr->ops.ternary.op);
430*38fd1498Szrj       if (commutative_ternary_tree_code (expr->ops.ternary.op))
431*38fd1498Szrj 	inchash::add_expr_commutative (expr->ops.ternary.opnd0,
432*38fd1498Szrj 					  expr->ops.ternary.opnd1, hstate);
433*38fd1498Szrj       else
434*38fd1498Szrj         {
435*38fd1498Szrj           inchash::add_expr (expr->ops.ternary.opnd0, hstate);
436*38fd1498Szrj           inchash::add_expr (expr->ops.ternary.opnd1, hstate);
437*38fd1498Szrj         }
438*38fd1498Szrj       inchash::add_expr (expr->ops.ternary.opnd2, hstate);
439*38fd1498Szrj       break;
440*38fd1498Szrj 
441*38fd1498Szrj     case EXPR_CALL:
442*38fd1498Szrj       {
443*38fd1498Szrj         size_t i;
444*38fd1498Szrj         enum tree_code code = CALL_EXPR;
445*38fd1498Szrj         gcall *fn_from;
446*38fd1498Szrj 
447*38fd1498Szrj         hstate.add_object (code);
448*38fd1498Szrj         fn_from = expr->ops.call.fn_from;
449*38fd1498Szrj         if (gimple_call_internal_p (fn_from))
450*38fd1498Szrj           hstate.merge_hash ((hashval_t) gimple_call_internal_fn (fn_from));
451*38fd1498Szrj         else
452*38fd1498Szrj           inchash::add_expr (gimple_call_fn (fn_from), hstate);
453*38fd1498Szrj         for (i = 0; i < expr->ops.call.nargs; i++)
454*38fd1498Szrj           inchash::add_expr (expr->ops.call.args[i], hstate);
455*38fd1498Szrj       }
456*38fd1498Szrj       break;
457*38fd1498Szrj 
458*38fd1498Szrj     case EXPR_PHI:
459*38fd1498Szrj       {
460*38fd1498Szrj         size_t i;
461*38fd1498Szrj 
462*38fd1498Szrj         for (i = 0; i < expr->ops.phi.nargs; i++)
463*38fd1498Szrj           inchash::add_expr (expr->ops.phi.args[i], hstate);
464*38fd1498Szrj       }
465*38fd1498Szrj       break;
466*38fd1498Szrj 
467*38fd1498Szrj     default:
468*38fd1498Szrj       gcc_unreachable ();
469*38fd1498Szrj     }
470*38fd1498Szrj }
471*38fd1498Szrj 
472*38fd1498Szrj }
473*38fd1498Szrj 
474*38fd1498Szrj /* Hashing and equality functions.  We compute a value number for expressions
475*38fd1498Szrj    using the code of the expression and the SSA numbers of its operands.  */
476*38fd1498Szrj 
477*38fd1498Szrj static hashval_t
avail_expr_hash(class expr_hash_elt * p)478*38fd1498Szrj avail_expr_hash (class expr_hash_elt *p)
479*38fd1498Szrj {
480*38fd1498Szrj   const struct hashable_expr *expr = p->expr ();
481*38fd1498Szrj   inchash::hash hstate;
482*38fd1498Szrj 
483*38fd1498Szrj   if (expr->kind == EXPR_SINGLE)
484*38fd1498Szrj     {
485*38fd1498Szrj       /* T could potentially be a switch index or a goto dest.  */
486*38fd1498Szrj       tree t = expr->ops.single.rhs;
487*38fd1498Szrj       if (TREE_CODE (t) == MEM_REF || handled_component_p (t))
488*38fd1498Szrj 	{
489*38fd1498Szrj 	  /* Make equivalent statements of both these kinds hash together.
490*38fd1498Szrj 	     Dealing with both MEM_REF and ARRAY_REF allows us not to care
491*38fd1498Szrj 	     about equivalence with other statements not considered here.  */
492*38fd1498Szrj 	  bool reverse;
493*38fd1498Szrj 	  poly_int64 offset, size, max_size;
494*38fd1498Szrj 	  tree base = get_ref_base_and_extent (t, &offset, &size, &max_size,
495*38fd1498Szrj 					       &reverse);
496*38fd1498Szrj 	  /* Strictly, we could try to normalize variable-sized accesses too,
497*38fd1498Szrj 	    but here we just deal with the common case.  */
498*38fd1498Szrj 	  if (known_size_p (max_size)
499*38fd1498Szrj 	      && known_eq (size, max_size))
500*38fd1498Szrj 	    {
501*38fd1498Szrj 	      enum tree_code code = MEM_REF;
502*38fd1498Szrj 	      hstate.add_object (code);
503*38fd1498Szrj 	      inchash::add_expr (base, hstate);
504*38fd1498Szrj 	      hstate.add_object (offset);
505*38fd1498Szrj 	      hstate.add_object (size);
506*38fd1498Szrj 	      return hstate.end ();
507*38fd1498Szrj 	    }
508*38fd1498Szrj 	}
509*38fd1498Szrj     }
510*38fd1498Szrj 
511*38fd1498Szrj   inchash::add_hashable_expr (expr, hstate);
512*38fd1498Szrj 
513*38fd1498Szrj   return hstate.end ();
514*38fd1498Szrj }
515*38fd1498Szrj 
516*38fd1498Szrj /* Compares trees T0 and T1 to see if they are MEM_REF or ARRAY_REFs equivalent
517*38fd1498Szrj    to each other.  (That is, they return the value of the same bit of memory.)
518*38fd1498Szrj 
519*38fd1498Szrj    Return TRUE if the two are so equivalent; FALSE if not (which could still
520*38fd1498Szrj    mean the two are equivalent by other means).  */
521*38fd1498Szrj 
522*38fd1498Szrj static bool
equal_mem_array_ref_p(tree t0,tree t1)523*38fd1498Szrj equal_mem_array_ref_p (tree t0, tree t1)
524*38fd1498Szrj {
525*38fd1498Szrj   if (TREE_CODE (t0) != MEM_REF && ! handled_component_p (t0))
526*38fd1498Szrj     return false;
527*38fd1498Szrj   if (TREE_CODE (t1) != MEM_REF && ! handled_component_p (t1))
528*38fd1498Szrj     return false;
529*38fd1498Szrj 
530*38fd1498Szrj   if (!types_compatible_p (TREE_TYPE (t0), TREE_TYPE (t1)))
531*38fd1498Szrj     return false;
532*38fd1498Szrj   bool rev0;
533*38fd1498Szrj   poly_int64 off0, sz0, max0;
534*38fd1498Szrj   tree base0 = get_ref_base_and_extent (t0, &off0, &sz0, &max0, &rev0);
535*38fd1498Szrj   if (!known_size_p (max0)
536*38fd1498Szrj       || maybe_ne (sz0, max0))
537*38fd1498Szrj     return false;
538*38fd1498Szrj 
539*38fd1498Szrj   bool rev1;
540*38fd1498Szrj   poly_int64 off1, sz1, max1;
541*38fd1498Szrj   tree base1 = get_ref_base_and_extent (t1, &off1, &sz1, &max1, &rev1);
542*38fd1498Szrj   if (!known_size_p (max1)
543*38fd1498Szrj       || maybe_ne (sz1, max1))
544*38fd1498Szrj     return false;
545*38fd1498Szrj 
546*38fd1498Szrj   if (rev0 != rev1)
547*38fd1498Szrj     return false;
548*38fd1498Szrj 
549*38fd1498Szrj   /* Types were compatible, so this is a sanity check.  */
550*38fd1498Szrj   gcc_assert (known_eq (sz0, sz1));
551*38fd1498Szrj 
552*38fd1498Szrj   return known_eq (off0, off1) && operand_equal_p (base0, base1, 0);
553*38fd1498Szrj }
554*38fd1498Szrj 
555*38fd1498Szrj /* Compare two hashable_expr structures for equivalence.  They are
556*38fd1498Szrj    considered equivalent when the expressions they denote must
557*38fd1498Szrj    necessarily be equal.  The logic is intended to follow that of
558*38fd1498Szrj    operand_equal_p in fold-const.c */
559*38fd1498Szrj 
560*38fd1498Szrj static bool
hashable_expr_equal_p(const struct hashable_expr * expr0,const struct hashable_expr * expr1)561*38fd1498Szrj hashable_expr_equal_p (const struct hashable_expr *expr0,
562*38fd1498Szrj 		       const struct hashable_expr *expr1)
563*38fd1498Szrj {
564*38fd1498Szrj   tree type0 = expr0->type;
565*38fd1498Szrj   tree type1 = expr1->type;
566*38fd1498Szrj 
567*38fd1498Szrj   /* If either type is NULL, there is nothing to check.  */
568*38fd1498Szrj   if ((type0 == NULL_TREE) ^ (type1 == NULL_TREE))
569*38fd1498Szrj     return false;
570*38fd1498Szrj 
571*38fd1498Szrj   /* If both types don't have the same signedness, precision, and mode,
572*38fd1498Szrj      then we can't consider  them equal.  */
573*38fd1498Szrj   if (type0 != type1
574*38fd1498Szrj       && (TREE_CODE (type0) == ERROR_MARK
575*38fd1498Szrj 	  || TREE_CODE (type1) == ERROR_MARK
576*38fd1498Szrj 	  || TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)
577*38fd1498Szrj 	  || TYPE_PRECISION (type0) != TYPE_PRECISION (type1)
578*38fd1498Szrj 	  || TYPE_MODE (type0) != TYPE_MODE (type1)))
579*38fd1498Szrj     return false;
580*38fd1498Szrj 
581*38fd1498Szrj   if (expr0->kind != expr1->kind)
582*38fd1498Szrj     return false;
583*38fd1498Szrj 
584*38fd1498Szrj   switch (expr0->kind)
585*38fd1498Szrj     {
586*38fd1498Szrj     case EXPR_SINGLE:
587*38fd1498Szrj       return equal_mem_array_ref_p (expr0->ops.single.rhs,
588*38fd1498Szrj 				    expr1->ops.single.rhs)
589*38fd1498Szrj 	     || operand_equal_p (expr0->ops.single.rhs,
590*38fd1498Szrj 				 expr1->ops.single.rhs, 0);
591*38fd1498Szrj     case EXPR_UNARY:
592*38fd1498Szrj       if (expr0->ops.unary.op != expr1->ops.unary.op)
593*38fd1498Szrj         return false;
594*38fd1498Szrj 
595*38fd1498Szrj       if ((CONVERT_EXPR_CODE_P (expr0->ops.unary.op)
596*38fd1498Szrj            || expr0->ops.unary.op == NON_LVALUE_EXPR)
597*38fd1498Szrj           && TYPE_UNSIGNED (expr0->type) != TYPE_UNSIGNED (expr1->type))
598*38fd1498Szrj         return false;
599*38fd1498Szrj 
600*38fd1498Szrj       return operand_equal_p (expr0->ops.unary.opnd,
601*38fd1498Szrj                               expr1->ops.unary.opnd, 0);
602*38fd1498Szrj 
603*38fd1498Szrj     case EXPR_BINARY:
604*38fd1498Szrj       if (expr0->ops.binary.op != expr1->ops.binary.op)
605*38fd1498Szrj 	return false;
606*38fd1498Szrj 
607*38fd1498Szrj       if (operand_equal_p (expr0->ops.binary.opnd0,
608*38fd1498Szrj 			   expr1->ops.binary.opnd0, 0)
609*38fd1498Szrj 	  && operand_equal_p (expr0->ops.binary.opnd1,
610*38fd1498Szrj 			      expr1->ops.binary.opnd1, 0))
611*38fd1498Szrj 	return true;
612*38fd1498Szrj 
613*38fd1498Szrj       /* For commutative ops, allow the other order.  */
614*38fd1498Szrj       return (commutative_tree_code (expr0->ops.binary.op)
615*38fd1498Szrj 	      && operand_equal_p (expr0->ops.binary.opnd0,
616*38fd1498Szrj 				  expr1->ops.binary.opnd1, 0)
617*38fd1498Szrj 	      && operand_equal_p (expr0->ops.binary.opnd1,
618*38fd1498Szrj 				  expr1->ops.binary.opnd0, 0));
619*38fd1498Szrj 
620*38fd1498Szrj     case EXPR_TERNARY:
621*38fd1498Szrj       if (expr0->ops.ternary.op != expr1->ops.ternary.op
622*38fd1498Szrj 	  || !operand_equal_p (expr0->ops.ternary.opnd2,
623*38fd1498Szrj 			       expr1->ops.ternary.opnd2, 0))
624*38fd1498Szrj 	return false;
625*38fd1498Szrj 
626*38fd1498Szrj       /* BIT_INSERT_EXPR has an implict operand as the type precision
627*38fd1498Szrj          of op1.  Need to check to make sure they are the same.  */
628*38fd1498Szrj       if (expr0->ops.ternary.op == BIT_INSERT_EXPR
629*38fd1498Szrj 	  && TREE_CODE (expr0->ops.ternary.opnd1) == INTEGER_CST
630*38fd1498Szrj           && TREE_CODE (expr1->ops.ternary.opnd1) == INTEGER_CST
631*38fd1498Szrj           && TYPE_PRECISION (TREE_TYPE (expr0->ops.ternary.opnd1))
632*38fd1498Szrj               != TYPE_PRECISION (TREE_TYPE (expr1->ops.ternary.opnd1)))
633*38fd1498Szrj         return false;
634*38fd1498Szrj 
635*38fd1498Szrj       if (operand_equal_p (expr0->ops.ternary.opnd0,
636*38fd1498Szrj 			   expr1->ops.ternary.opnd0, 0)
637*38fd1498Szrj 	  && operand_equal_p (expr0->ops.ternary.opnd1,
638*38fd1498Szrj 			      expr1->ops.ternary.opnd1, 0))
639*38fd1498Szrj 	return true;
640*38fd1498Szrj 
641*38fd1498Szrj       /* For commutative ops, allow the other order.  */
642*38fd1498Szrj       return (commutative_ternary_tree_code (expr0->ops.ternary.op)
643*38fd1498Szrj 	      && operand_equal_p (expr0->ops.ternary.opnd0,
644*38fd1498Szrj 				  expr1->ops.ternary.opnd1, 0)
645*38fd1498Szrj 	      && operand_equal_p (expr0->ops.ternary.opnd1,
646*38fd1498Szrj 				  expr1->ops.ternary.opnd0, 0));
647*38fd1498Szrj 
648*38fd1498Szrj     case EXPR_CALL:
649*38fd1498Szrj       {
650*38fd1498Szrj         size_t i;
651*38fd1498Szrj 
652*38fd1498Szrj         /* If the calls are to different functions, then they
653*38fd1498Szrj            clearly cannot be equal.  */
654*38fd1498Szrj         if (!gimple_call_same_target_p (expr0->ops.call.fn_from,
655*38fd1498Szrj                                         expr1->ops.call.fn_from))
656*38fd1498Szrj           return false;
657*38fd1498Szrj 
658*38fd1498Szrj         if (! expr0->ops.call.pure)
659*38fd1498Szrj           return false;
660*38fd1498Szrj 
661*38fd1498Szrj         if (expr0->ops.call.nargs !=  expr1->ops.call.nargs)
662*38fd1498Szrj           return false;
663*38fd1498Szrj 
664*38fd1498Szrj         for (i = 0; i < expr0->ops.call.nargs; i++)
665*38fd1498Szrj           if (! operand_equal_p (expr0->ops.call.args[i],
666*38fd1498Szrj                                  expr1->ops.call.args[i], 0))
667*38fd1498Szrj             return false;
668*38fd1498Szrj 
669*38fd1498Szrj 	if (stmt_could_throw_p (expr0->ops.call.fn_from))
670*38fd1498Szrj 	  {
671*38fd1498Szrj 	    int lp0 = lookup_stmt_eh_lp (expr0->ops.call.fn_from);
672*38fd1498Szrj 	    int lp1 = lookup_stmt_eh_lp (expr1->ops.call.fn_from);
673*38fd1498Szrj 	    if ((lp0 > 0 || lp1 > 0) && lp0 != lp1)
674*38fd1498Szrj 	      return false;
675*38fd1498Szrj 	  }
676*38fd1498Szrj 
677*38fd1498Szrj         return true;
678*38fd1498Szrj       }
679*38fd1498Szrj 
680*38fd1498Szrj     case EXPR_PHI:
681*38fd1498Szrj       {
682*38fd1498Szrj         size_t i;
683*38fd1498Szrj 
684*38fd1498Szrj         if (expr0->ops.phi.nargs !=  expr1->ops.phi.nargs)
685*38fd1498Szrj           return false;
686*38fd1498Szrj 
687*38fd1498Szrj         for (i = 0; i < expr0->ops.phi.nargs; i++)
688*38fd1498Szrj           if (! operand_equal_p (expr0->ops.phi.args[i],
689*38fd1498Szrj                                  expr1->ops.phi.args[i], 0))
690*38fd1498Szrj             return false;
691*38fd1498Szrj 
692*38fd1498Szrj         return true;
693*38fd1498Szrj       }
694*38fd1498Szrj 
695*38fd1498Szrj     default:
696*38fd1498Szrj       gcc_unreachable ();
697*38fd1498Szrj     }
698*38fd1498Szrj }
699*38fd1498Szrj 
700*38fd1498Szrj /* Given a statement STMT, construct a hash table element.  */
701*38fd1498Szrj 
expr_hash_elt(gimple * stmt,tree orig_lhs)702*38fd1498Szrj expr_hash_elt::expr_hash_elt (gimple *stmt, tree orig_lhs)
703*38fd1498Szrj {
704*38fd1498Szrj   enum gimple_code code = gimple_code (stmt);
705*38fd1498Szrj   struct hashable_expr *expr = this->expr ();
706*38fd1498Szrj 
707*38fd1498Szrj   if (code == GIMPLE_ASSIGN)
708*38fd1498Szrj     {
709*38fd1498Szrj       enum tree_code subcode = gimple_assign_rhs_code (stmt);
710*38fd1498Szrj 
711*38fd1498Szrj       switch (get_gimple_rhs_class (subcode))
712*38fd1498Szrj         {
713*38fd1498Szrj         case GIMPLE_SINGLE_RHS:
714*38fd1498Szrj 	  expr->kind = EXPR_SINGLE;
715*38fd1498Szrj 	  expr->type = TREE_TYPE (gimple_assign_rhs1 (stmt));
716*38fd1498Szrj 	  expr->ops.single.rhs = gimple_assign_rhs1 (stmt);
717*38fd1498Szrj 	  break;
718*38fd1498Szrj         case GIMPLE_UNARY_RHS:
719*38fd1498Szrj 	  expr->kind = EXPR_UNARY;
720*38fd1498Szrj 	  expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
721*38fd1498Szrj 	  if (CONVERT_EXPR_CODE_P (subcode))
722*38fd1498Szrj 	    subcode = NOP_EXPR;
723*38fd1498Szrj 	  expr->ops.unary.op = subcode;
724*38fd1498Szrj 	  expr->ops.unary.opnd = gimple_assign_rhs1 (stmt);
725*38fd1498Szrj 	  break;
726*38fd1498Szrj         case GIMPLE_BINARY_RHS:
727*38fd1498Szrj 	  expr->kind = EXPR_BINARY;
728*38fd1498Szrj 	  expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
729*38fd1498Szrj 	  expr->ops.binary.op = subcode;
730*38fd1498Szrj 	  expr->ops.binary.opnd0 = gimple_assign_rhs1 (stmt);
731*38fd1498Szrj 	  expr->ops.binary.opnd1 = gimple_assign_rhs2 (stmt);
732*38fd1498Szrj 	  break;
733*38fd1498Szrj         case GIMPLE_TERNARY_RHS:
734*38fd1498Szrj 	  expr->kind = EXPR_TERNARY;
735*38fd1498Szrj 	  expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
736*38fd1498Szrj 	  expr->ops.ternary.op = subcode;
737*38fd1498Szrj 	  expr->ops.ternary.opnd0 = gimple_assign_rhs1 (stmt);
738*38fd1498Szrj 	  expr->ops.ternary.opnd1 = gimple_assign_rhs2 (stmt);
739*38fd1498Szrj 	  expr->ops.ternary.opnd2 = gimple_assign_rhs3 (stmt);
740*38fd1498Szrj 	  break;
741*38fd1498Szrj         default:
742*38fd1498Szrj           gcc_unreachable ();
743*38fd1498Szrj         }
744*38fd1498Szrj     }
745*38fd1498Szrj   else if (code == GIMPLE_COND)
746*38fd1498Szrj     {
747*38fd1498Szrj       expr->type = boolean_type_node;
748*38fd1498Szrj       expr->kind = EXPR_BINARY;
749*38fd1498Szrj       expr->ops.binary.op = gimple_cond_code (stmt);
750*38fd1498Szrj       expr->ops.binary.opnd0 = gimple_cond_lhs (stmt);
751*38fd1498Szrj       expr->ops.binary.opnd1 = gimple_cond_rhs (stmt);
752*38fd1498Szrj     }
753*38fd1498Szrj   else if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
754*38fd1498Szrj     {
755*38fd1498Szrj       size_t nargs = gimple_call_num_args (call_stmt);
756*38fd1498Szrj       size_t i;
757*38fd1498Szrj 
758*38fd1498Szrj       gcc_assert (gimple_call_lhs (call_stmt));
759*38fd1498Szrj 
760*38fd1498Szrj       expr->type = TREE_TYPE (gimple_call_lhs (call_stmt));
761*38fd1498Szrj       expr->kind = EXPR_CALL;
762*38fd1498Szrj       expr->ops.call.fn_from = call_stmt;
763*38fd1498Szrj 
764*38fd1498Szrj       if (gimple_call_flags (call_stmt) & (ECF_CONST | ECF_PURE))
765*38fd1498Szrj         expr->ops.call.pure = true;
766*38fd1498Szrj       else
767*38fd1498Szrj         expr->ops.call.pure = false;
768*38fd1498Szrj 
769*38fd1498Szrj       expr->ops.call.nargs = nargs;
770*38fd1498Szrj       expr->ops.call.args = XCNEWVEC (tree, nargs);
771*38fd1498Szrj       for (i = 0; i < nargs; i++)
772*38fd1498Szrj         expr->ops.call.args[i] = gimple_call_arg (call_stmt, i);
773*38fd1498Szrj     }
774*38fd1498Szrj   else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
775*38fd1498Szrj     {
776*38fd1498Szrj       expr->type = TREE_TYPE (gimple_switch_index (swtch_stmt));
777*38fd1498Szrj       expr->kind = EXPR_SINGLE;
778*38fd1498Szrj       expr->ops.single.rhs = gimple_switch_index (swtch_stmt);
779*38fd1498Szrj     }
780*38fd1498Szrj   else if (code == GIMPLE_GOTO)
781*38fd1498Szrj     {
782*38fd1498Szrj       expr->type = TREE_TYPE (gimple_goto_dest (stmt));
783*38fd1498Szrj       expr->kind = EXPR_SINGLE;
784*38fd1498Szrj       expr->ops.single.rhs = gimple_goto_dest (stmt);
785*38fd1498Szrj     }
786*38fd1498Szrj   else if (code == GIMPLE_PHI)
787*38fd1498Szrj     {
788*38fd1498Szrj       size_t nargs = gimple_phi_num_args (stmt);
789*38fd1498Szrj       size_t i;
790*38fd1498Szrj 
791*38fd1498Szrj       expr->type = TREE_TYPE (gimple_phi_result (stmt));
792*38fd1498Szrj       expr->kind = EXPR_PHI;
793*38fd1498Szrj       expr->ops.phi.nargs = nargs;
794*38fd1498Szrj       expr->ops.phi.args = XCNEWVEC (tree, nargs);
795*38fd1498Szrj       for (i = 0; i < nargs; i++)
796*38fd1498Szrj         expr->ops.phi.args[i] = gimple_phi_arg_def (stmt, i);
797*38fd1498Szrj     }
798*38fd1498Szrj   else
799*38fd1498Szrj     gcc_unreachable ();
800*38fd1498Szrj 
801*38fd1498Szrj   m_lhs = orig_lhs;
802*38fd1498Szrj   m_vop = gimple_vuse (stmt);
803*38fd1498Szrj   m_hash = avail_expr_hash (this);
804*38fd1498Szrj   m_stamp = this;
805*38fd1498Szrj }
806*38fd1498Szrj 
807*38fd1498Szrj /* Given a hashable_expr expression ORIG and an ORIG_LHS,
808*38fd1498Szrj    construct a hash table element.  */
809*38fd1498Szrj 
expr_hash_elt(struct hashable_expr * orig,tree orig_lhs)810*38fd1498Szrj expr_hash_elt::expr_hash_elt (struct hashable_expr *orig, tree orig_lhs)
811*38fd1498Szrj {
812*38fd1498Szrj   m_expr = *orig;
813*38fd1498Szrj   m_lhs = orig_lhs;
814*38fd1498Szrj   m_vop = NULL_TREE;
815*38fd1498Szrj   m_hash = avail_expr_hash (this);
816*38fd1498Szrj   m_stamp = this;
817*38fd1498Szrj }
818*38fd1498Szrj 
819*38fd1498Szrj /* Copy constructor for a hash table element.  */
820*38fd1498Szrj 
expr_hash_elt(class expr_hash_elt & old_elt)821*38fd1498Szrj expr_hash_elt::expr_hash_elt (class expr_hash_elt &old_elt)
822*38fd1498Szrj {
823*38fd1498Szrj   m_expr = old_elt.m_expr;
824*38fd1498Szrj   m_lhs = old_elt.m_lhs;
825*38fd1498Szrj   m_vop = old_elt.m_vop;
826*38fd1498Szrj   m_hash = old_elt.m_hash;
827*38fd1498Szrj   m_stamp = this;
828*38fd1498Szrj 
829*38fd1498Szrj   /* Now deep copy the malloc'd space for CALL and PHI args.  */
830*38fd1498Szrj   if (old_elt.m_expr.kind == EXPR_CALL)
831*38fd1498Szrj     {
832*38fd1498Szrj       size_t nargs = old_elt.m_expr.ops.call.nargs;
833*38fd1498Szrj       size_t i;
834*38fd1498Szrj 
835*38fd1498Szrj       m_expr.ops.call.args = XCNEWVEC (tree, nargs);
836*38fd1498Szrj       for (i = 0; i < nargs; i++)
837*38fd1498Szrj         m_expr.ops.call.args[i] = old_elt.m_expr.ops.call.args[i];
838*38fd1498Szrj     }
839*38fd1498Szrj   else if (old_elt.m_expr.kind == EXPR_PHI)
840*38fd1498Szrj     {
841*38fd1498Szrj       size_t nargs = old_elt.m_expr.ops.phi.nargs;
842*38fd1498Szrj       size_t i;
843*38fd1498Szrj 
844*38fd1498Szrj       m_expr.ops.phi.args = XCNEWVEC (tree, nargs);
845*38fd1498Szrj       for (i = 0; i < nargs; i++)
846*38fd1498Szrj         m_expr.ops.phi.args[i] = old_elt.m_expr.ops.phi.args[i];
847*38fd1498Szrj     }
848*38fd1498Szrj }
849*38fd1498Szrj 
850*38fd1498Szrj /* Calls and PHIs have a variable number of arguments that are allocated
851*38fd1498Szrj    on the heap.  Thus we have to have a special dtor to release them.  */
852*38fd1498Szrj 
~expr_hash_elt()853*38fd1498Szrj expr_hash_elt::~expr_hash_elt ()
854*38fd1498Szrj {
855*38fd1498Szrj   if (m_expr.kind == EXPR_CALL)
856*38fd1498Szrj     free (m_expr.ops.call.args);
857*38fd1498Szrj   else if (m_expr.kind == EXPR_PHI)
858*38fd1498Szrj     free (m_expr.ops.phi.args);
859*38fd1498Szrj }
860*38fd1498Szrj 
861*38fd1498Szrj /* Print a diagnostic dump of an expression hash table entry.  */
862*38fd1498Szrj 
863*38fd1498Szrj void
print(FILE * stream)864*38fd1498Szrj expr_hash_elt::print (FILE *stream)
865*38fd1498Szrj {
866*38fd1498Szrj   fprintf (stream, "STMT ");
867*38fd1498Szrj 
868*38fd1498Szrj   if (m_lhs)
869*38fd1498Szrj     {
870*38fd1498Szrj       print_generic_expr (stream, m_lhs);
871*38fd1498Szrj       fprintf (stream, " = ");
872*38fd1498Szrj     }
873*38fd1498Szrj 
874*38fd1498Szrj   switch (m_expr.kind)
875*38fd1498Szrj     {
876*38fd1498Szrj       case EXPR_SINGLE:
877*38fd1498Szrj 	print_generic_expr (stream, m_expr.ops.single.rhs);
878*38fd1498Szrj 	break;
879*38fd1498Szrj 
880*38fd1498Szrj       case EXPR_UNARY:
881*38fd1498Szrj 	fprintf (stream, "%s ", get_tree_code_name (m_expr.ops.unary.op));
882*38fd1498Szrj 	print_generic_expr (stream, m_expr.ops.unary.opnd);
883*38fd1498Szrj 	break;
884*38fd1498Szrj 
885*38fd1498Szrj       case EXPR_BINARY:
886*38fd1498Szrj 	print_generic_expr (stream, m_expr.ops.binary.opnd0);
887*38fd1498Szrj 	fprintf (stream, " %s ", get_tree_code_name (m_expr.ops.binary.op));
888*38fd1498Szrj 	print_generic_expr (stream, m_expr.ops.binary.opnd1);
889*38fd1498Szrj 	break;
890*38fd1498Szrj 
891*38fd1498Szrj       case EXPR_TERNARY:
892*38fd1498Szrj 	fprintf (stream, " %s <", get_tree_code_name (m_expr.ops.ternary.op));
893*38fd1498Szrj 	print_generic_expr (stream, m_expr.ops.ternary.opnd0);
894*38fd1498Szrj 	fputs (", ", stream);
895*38fd1498Szrj 	print_generic_expr (stream, m_expr.ops.ternary.opnd1);
896*38fd1498Szrj 	fputs (", ", stream);
897*38fd1498Szrj 	print_generic_expr (stream, m_expr.ops.ternary.opnd2);
898*38fd1498Szrj 	fputs (">", stream);
899*38fd1498Szrj 	break;
900*38fd1498Szrj 
901*38fd1498Szrj       case EXPR_CALL:
902*38fd1498Szrj         {
903*38fd1498Szrj           size_t i;
904*38fd1498Szrj           size_t nargs = m_expr.ops.call.nargs;
905*38fd1498Szrj           gcall *fn_from;
906*38fd1498Szrj 
907*38fd1498Szrj           fn_from = m_expr.ops.call.fn_from;
908*38fd1498Szrj           if (gimple_call_internal_p (fn_from))
909*38fd1498Szrj             fputs (internal_fn_name (gimple_call_internal_fn (fn_from)),
910*38fd1498Szrj                    stream);
911*38fd1498Szrj           else
912*38fd1498Szrj 	    print_generic_expr (stream, gimple_call_fn (fn_from));
913*38fd1498Szrj           fprintf (stream, " (");
914*38fd1498Szrj           for (i = 0; i < nargs; i++)
915*38fd1498Szrj             {
916*38fd1498Szrj 	      print_generic_expr (stream, m_expr.ops.call.args[i]);
917*38fd1498Szrj               if (i + 1 < nargs)
918*38fd1498Szrj                 fprintf (stream, ", ");
919*38fd1498Szrj             }
920*38fd1498Szrj           fprintf (stream, ")");
921*38fd1498Szrj         }
922*38fd1498Szrj         break;
923*38fd1498Szrj 
924*38fd1498Szrj       case EXPR_PHI:
925*38fd1498Szrj         {
926*38fd1498Szrj           size_t i;
927*38fd1498Szrj           size_t nargs = m_expr.ops.phi.nargs;
928*38fd1498Szrj 
929*38fd1498Szrj           fprintf (stream, "PHI <");
930*38fd1498Szrj           for (i = 0; i < nargs; i++)
931*38fd1498Szrj             {
932*38fd1498Szrj 	      print_generic_expr (stream, m_expr.ops.phi.args[i]);
933*38fd1498Szrj               if (i + 1 < nargs)
934*38fd1498Szrj                 fprintf (stream, ", ");
935*38fd1498Szrj             }
936*38fd1498Szrj           fprintf (stream, ">");
937*38fd1498Szrj         }
938*38fd1498Szrj         break;
939*38fd1498Szrj     }
940*38fd1498Szrj 
941*38fd1498Szrj   if (m_vop)
942*38fd1498Szrj     {
943*38fd1498Szrj       fprintf (stream, " with ");
944*38fd1498Szrj       print_generic_expr (stream, m_vop);
945*38fd1498Szrj     }
946*38fd1498Szrj 
947*38fd1498Szrj   fprintf (stream, "\n");
948*38fd1498Szrj }
949*38fd1498Szrj 
950*38fd1498Szrj /* Pop entries off the stack until we hit the NULL marker.
951*38fd1498Szrj    For each entry popped, use the SRC/DEST pair to restore
952*38fd1498Szrj    SRC to its prior value.  */
953*38fd1498Szrj 
954*38fd1498Szrj void
pop_to_marker(void)955*38fd1498Szrj const_and_copies::pop_to_marker (void)
956*38fd1498Szrj {
957*38fd1498Szrj   while (m_stack.length () > 0)
958*38fd1498Szrj     {
959*38fd1498Szrj       tree prev_value, dest;
960*38fd1498Szrj 
961*38fd1498Szrj       dest = m_stack.pop ();
962*38fd1498Szrj 
963*38fd1498Szrj       /* A NULL value indicates we should stop unwinding, otherwise
964*38fd1498Szrj 	 pop off the next entry as they're recorded in pairs.  */
965*38fd1498Szrj       if (dest == NULL)
966*38fd1498Szrj 	break;
967*38fd1498Szrj 
968*38fd1498Szrj       if (dump_file && (dump_flags & TDF_DETAILS))
969*38fd1498Szrj 	{
970*38fd1498Szrj 	  fprintf (dump_file, "<<<< COPY ");
971*38fd1498Szrj 	  print_generic_expr (dump_file, dest);
972*38fd1498Szrj 	  fprintf (dump_file, " = ");
973*38fd1498Szrj 	  print_generic_expr (dump_file, SSA_NAME_VALUE (dest));
974*38fd1498Szrj 	  fprintf (dump_file, "\n");
975*38fd1498Szrj 	}
976*38fd1498Szrj 
977*38fd1498Szrj       prev_value = m_stack.pop ();
978*38fd1498Szrj       set_ssa_name_value (dest, prev_value);
979*38fd1498Szrj     }
980*38fd1498Szrj }
981*38fd1498Szrj 
982*38fd1498Szrj /* Record that X has the value Y and that X's previous value is PREV_X.
983*38fd1498Szrj 
984*38fd1498Szrj    This variant does not follow the value chain for Y.  */
985*38fd1498Szrj 
986*38fd1498Szrj void
record_const_or_copy_raw(tree x,tree y,tree prev_x)987*38fd1498Szrj const_and_copies::record_const_or_copy_raw (tree x, tree y, tree prev_x)
988*38fd1498Szrj {
989*38fd1498Szrj   if (dump_file && (dump_flags & TDF_DETAILS))
990*38fd1498Szrj     {
991*38fd1498Szrj       fprintf (dump_file, "0>>> COPY ");
992*38fd1498Szrj       print_generic_expr (dump_file, x);
993*38fd1498Szrj       fprintf (dump_file, " = ");
994*38fd1498Szrj       print_generic_expr (dump_file, y);
995*38fd1498Szrj       fprintf (dump_file, "\n");
996*38fd1498Szrj     }
997*38fd1498Szrj 
998*38fd1498Szrj   set_ssa_name_value (x, y);
999*38fd1498Szrj   m_stack.reserve (2);
1000*38fd1498Szrj   m_stack.quick_push (prev_x);
1001*38fd1498Szrj   m_stack.quick_push (x);
1002*38fd1498Szrj }
1003*38fd1498Szrj 
1004*38fd1498Szrj /* Record that X has the value Y.  */
1005*38fd1498Szrj 
1006*38fd1498Szrj void
record_const_or_copy(tree x,tree y)1007*38fd1498Szrj const_and_copies::record_const_or_copy (tree x, tree y)
1008*38fd1498Szrj {
1009*38fd1498Szrj   record_const_or_copy (x, y, SSA_NAME_VALUE (x));
1010*38fd1498Szrj }
1011*38fd1498Szrj 
1012*38fd1498Szrj /* Record that X has the value Y and that X's previous value is PREV_X.
1013*38fd1498Szrj 
1014*38fd1498Szrj    This variant follow's Y value chain.  */
1015*38fd1498Szrj 
1016*38fd1498Szrj void
record_const_or_copy(tree x,tree y,tree prev_x)1017*38fd1498Szrj const_and_copies::record_const_or_copy (tree x, tree y, tree prev_x)
1018*38fd1498Szrj {
1019*38fd1498Szrj   /* Y may be NULL if we are invalidating entries in the table.  */
1020*38fd1498Szrj   if (y && TREE_CODE (y) == SSA_NAME)
1021*38fd1498Szrj     {
1022*38fd1498Szrj       tree tmp = SSA_NAME_VALUE (y);
1023*38fd1498Szrj       y = tmp ? tmp : y;
1024*38fd1498Szrj     }
1025*38fd1498Szrj 
1026*38fd1498Szrj   record_const_or_copy_raw (x, y, prev_x);
1027*38fd1498Szrj }
1028*38fd1498Szrj 
1029*38fd1498Szrj bool
equal(const value_type & p1,const compare_type & p2)1030*38fd1498Szrj expr_elt_hasher::equal (const value_type &p1, const compare_type &p2)
1031*38fd1498Szrj {
1032*38fd1498Szrj   const struct hashable_expr *expr1 = p1->expr ();
1033*38fd1498Szrj   const struct expr_hash_elt *stamp1 = p1->stamp ();
1034*38fd1498Szrj   const struct hashable_expr *expr2 = p2->expr ();
1035*38fd1498Szrj   const struct expr_hash_elt *stamp2 = p2->stamp ();
1036*38fd1498Szrj 
1037*38fd1498Szrj   /* This case should apply only when removing entries from the table.  */
1038*38fd1498Szrj   if (stamp1 == stamp2)
1039*38fd1498Szrj     return true;
1040*38fd1498Szrj 
1041*38fd1498Szrj   if (p1->hash () != p2->hash ())
1042*38fd1498Szrj     return false;
1043*38fd1498Szrj 
1044*38fd1498Szrj   /* In case of a collision, both RHS have to be identical and have the
1045*38fd1498Szrj      same VUSE operands.  */
1046*38fd1498Szrj   if (hashable_expr_equal_p (expr1, expr2)
1047*38fd1498Szrj       && types_compatible_p (expr1->type, expr2->type))
1048*38fd1498Szrj     return true;
1049*38fd1498Szrj 
1050*38fd1498Szrj   return false;
1051*38fd1498Szrj }
1052*38fd1498Szrj 
1053*38fd1498Szrj /* Given a conditional expression COND as a tree, initialize
1054*38fd1498Szrj    a hashable_expr expression EXPR.  The conditional must be a
1055*38fd1498Szrj    comparison or logical negation.  A constant or a variable is
1056*38fd1498Szrj    not permitted.  */
1057*38fd1498Szrj 
1058*38fd1498Szrj void
initialize_expr_from_cond(tree cond,struct hashable_expr * expr)1059*38fd1498Szrj initialize_expr_from_cond (tree cond, struct hashable_expr *expr)
1060*38fd1498Szrj {
1061*38fd1498Szrj   expr->type = boolean_type_node;
1062*38fd1498Szrj 
1063*38fd1498Szrj   if (COMPARISON_CLASS_P (cond))
1064*38fd1498Szrj     {
1065*38fd1498Szrj       expr->kind = EXPR_BINARY;
1066*38fd1498Szrj       expr->ops.binary.op = TREE_CODE (cond);
1067*38fd1498Szrj       expr->ops.binary.opnd0 = TREE_OPERAND (cond, 0);
1068*38fd1498Szrj       expr->ops.binary.opnd1 = TREE_OPERAND (cond, 1);
1069*38fd1498Szrj     }
1070*38fd1498Szrj   else if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
1071*38fd1498Szrj     {
1072*38fd1498Szrj       expr->kind = EXPR_UNARY;
1073*38fd1498Szrj       expr->ops.unary.op = TRUTH_NOT_EXPR;
1074*38fd1498Szrj       expr->ops.unary.opnd = TREE_OPERAND (cond, 0);
1075*38fd1498Szrj     }
1076*38fd1498Szrj   else
1077*38fd1498Szrj     gcc_unreachable ();
1078*38fd1498Szrj }
1079*38fd1498Szrj 
1080*38fd1498Szrj /* Build a cond_equivalence record indicating that the comparison
1081*38fd1498Szrj    CODE holds between operands OP0 and OP1 and push it to **P.  */
1082*38fd1498Szrj 
1083*38fd1498Szrj static void
1084*38fd1498Szrj build_and_record_new_cond (enum tree_code code,
1085*38fd1498Szrj                            tree op0, tree op1,
1086*38fd1498Szrj                            vec<cond_equivalence> *p,
1087*38fd1498Szrj 			   bool val = true)
1088*38fd1498Szrj {
1089*38fd1498Szrj   cond_equivalence c;
1090*38fd1498Szrj   struct hashable_expr *cond = &c.cond;
1091*38fd1498Szrj 
1092*38fd1498Szrj   gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
1093*38fd1498Szrj 
1094*38fd1498Szrj   cond->type = boolean_type_node;
1095*38fd1498Szrj   cond->kind = EXPR_BINARY;
1096*38fd1498Szrj   cond->ops.binary.op = code;
1097*38fd1498Szrj   cond->ops.binary.opnd0 = op0;
1098*38fd1498Szrj   cond->ops.binary.opnd1 = op1;
1099*38fd1498Szrj 
1100*38fd1498Szrj   c.value = val ? boolean_true_node : boolean_false_node;
1101*38fd1498Szrj   p->safe_push (c);
1102*38fd1498Szrj }
1103*38fd1498Szrj 
1104*38fd1498Szrj /* Record that COND is true and INVERTED is false into the edge information
1105*38fd1498Szrj    structure.  Also record that any conditions dominated by COND are true
1106*38fd1498Szrj    as well.
1107*38fd1498Szrj 
1108*38fd1498Szrj    For example, if a < b is true, then a <= b must also be true.  */
1109*38fd1498Szrj 
1110*38fd1498Szrj void
record_conditions(vec<cond_equivalence> * p,tree cond,tree inverted)1111*38fd1498Szrj record_conditions (vec<cond_equivalence> *p, tree cond, tree inverted)
1112*38fd1498Szrj {
1113*38fd1498Szrj   tree op0, op1;
1114*38fd1498Szrj   cond_equivalence c;
1115*38fd1498Szrj 
1116*38fd1498Szrj   if (!COMPARISON_CLASS_P (cond))
1117*38fd1498Szrj     return;
1118*38fd1498Szrj 
1119*38fd1498Szrj   op0 = TREE_OPERAND (cond, 0);
1120*38fd1498Szrj   op1 = TREE_OPERAND (cond, 1);
1121*38fd1498Szrj 
1122*38fd1498Szrj   switch (TREE_CODE (cond))
1123*38fd1498Szrj     {
1124*38fd1498Szrj     case LT_EXPR:
1125*38fd1498Szrj     case GT_EXPR:
1126*38fd1498Szrj       if (FLOAT_TYPE_P (TREE_TYPE (op0)))
1127*38fd1498Szrj 	{
1128*38fd1498Szrj 	  build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
1129*38fd1498Szrj 	  build_and_record_new_cond (LTGT_EXPR, op0, op1, p);
1130*38fd1498Szrj 	}
1131*38fd1498Szrj 
1132*38fd1498Szrj       build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR
1133*38fd1498Szrj 				  ? LE_EXPR : GE_EXPR),
1134*38fd1498Szrj 				 op0, op1, p);
1135*38fd1498Szrj       build_and_record_new_cond (NE_EXPR, op0, op1, p);
1136*38fd1498Szrj       build_and_record_new_cond (EQ_EXPR, op0, op1, p, false);
1137*38fd1498Szrj       break;
1138*38fd1498Szrj 
1139*38fd1498Szrj     case GE_EXPR:
1140*38fd1498Szrj     case LE_EXPR:
1141*38fd1498Szrj       if (FLOAT_TYPE_P (TREE_TYPE (op0)))
1142*38fd1498Szrj 	{
1143*38fd1498Szrj 	  build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
1144*38fd1498Szrj 	}
1145*38fd1498Szrj       break;
1146*38fd1498Szrj 
1147*38fd1498Szrj     case EQ_EXPR:
1148*38fd1498Szrj       if (FLOAT_TYPE_P (TREE_TYPE (op0)))
1149*38fd1498Szrj 	{
1150*38fd1498Szrj 	  build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
1151*38fd1498Szrj 	}
1152*38fd1498Szrj       build_and_record_new_cond (LE_EXPR, op0, op1, p);
1153*38fd1498Szrj       build_and_record_new_cond (GE_EXPR, op0, op1, p);
1154*38fd1498Szrj       break;
1155*38fd1498Szrj 
1156*38fd1498Szrj     case UNORDERED_EXPR:
1157*38fd1498Szrj       build_and_record_new_cond (NE_EXPR, op0, op1, p);
1158*38fd1498Szrj       build_and_record_new_cond (UNLE_EXPR, op0, op1, p);
1159*38fd1498Szrj       build_and_record_new_cond (UNGE_EXPR, op0, op1, p);
1160*38fd1498Szrj       build_and_record_new_cond (UNEQ_EXPR, op0, op1, p);
1161*38fd1498Szrj       build_and_record_new_cond (UNLT_EXPR, op0, op1, p);
1162*38fd1498Szrj       build_and_record_new_cond (UNGT_EXPR, op0, op1, p);
1163*38fd1498Szrj       break;
1164*38fd1498Szrj 
1165*38fd1498Szrj     case UNLT_EXPR:
1166*38fd1498Szrj     case UNGT_EXPR:
1167*38fd1498Szrj       build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR
1168*38fd1498Szrj 				  ? UNLE_EXPR : UNGE_EXPR),
1169*38fd1498Szrj 				 op0, op1, p);
1170*38fd1498Szrj       build_and_record_new_cond (NE_EXPR, op0, op1, p);
1171*38fd1498Szrj       break;
1172*38fd1498Szrj 
1173*38fd1498Szrj     case UNEQ_EXPR:
1174*38fd1498Szrj       build_and_record_new_cond (UNLE_EXPR, op0, op1, p);
1175*38fd1498Szrj       build_and_record_new_cond (UNGE_EXPR, op0, op1, p);
1176*38fd1498Szrj       break;
1177*38fd1498Szrj 
1178*38fd1498Szrj     case LTGT_EXPR:
1179*38fd1498Szrj       build_and_record_new_cond (NE_EXPR, op0, op1, p);
1180*38fd1498Szrj       build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
1181*38fd1498Szrj       break;
1182*38fd1498Szrj 
1183*38fd1498Szrj     default:
1184*38fd1498Szrj       break;
1185*38fd1498Szrj     }
1186*38fd1498Szrj 
1187*38fd1498Szrj   /* Now store the original true and false conditions into the first
1188*38fd1498Szrj      two slots.  */
1189*38fd1498Szrj   initialize_expr_from_cond (cond, &c.cond);
1190*38fd1498Szrj   c.value = boolean_true_node;
1191*38fd1498Szrj   p->safe_push (c);
1192*38fd1498Szrj 
1193*38fd1498Szrj   /* It is possible for INVERTED to be the negation of a comparison,
1194*38fd1498Szrj      and not a valid RHS or GIMPLE_COND condition.  This happens because
1195*38fd1498Szrj      invert_truthvalue may return such an expression when asked to invert
1196*38fd1498Szrj      a floating-point comparison.  These comparisons are not assumed to
1197*38fd1498Szrj      obey the trichotomy law.  */
1198*38fd1498Szrj   initialize_expr_from_cond (inverted, &c.cond);
1199*38fd1498Szrj   c.value = boolean_false_node;
1200*38fd1498Szrj   p->safe_push (c);
1201*38fd1498Szrj }
1202