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