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