Line data Source code
1 : /* Header file for SSA dominator optimizations.
2 : Copyright (C) 2013-2026 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 63772624 : avail_exprs_stack::pop_to_marker ()
50 : {
51 : /* Remove all the expressions made available in this block. */
52 181094515 : while (m_stack.length () > 0)
53 : {
54 181094515 : std::pair<expr_hash_elt_t, expr_hash_elt_t> victim = m_stack.pop ();
55 181094515 : expr_hash_elt **slot;
56 :
57 181094515 : 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 117321891 : if (dump_file && (dump_flags & TDF_DETAILS))
64 : {
65 3368 : fprintf (dump_file, "<<<< ");
66 3368 : victim.first->print (dump_file);
67 : }
68 :
69 117321891 : slot = m_avail_exprs->find_slot (victim.first, NO_INSERT);
70 117321891 : gcc_assert (slot && *slot == victim.first);
71 117321891 : if (victim.second != NULL)
72 : {
73 4975128 : delete *slot;
74 4975128 : *slot = victim.second;
75 : }
76 : else
77 112346763 : m_avail_exprs->clear_slot (slot);
78 : }
79 63772624 : }
80 :
81 : /* Add <ELT1,ELT2> to the unwinding stack so they can be later removed
82 : from the hash table. */
83 :
84 : void
85 181094515 : avail_exprs_stack::record_expr (class expr_hash_elt *elt1,
86 : class expr_hash_elt *elt2,
87 : char type)
88 : {
89 181094515 : if (elt1 && dump_file && (dump_flags & TDF_DETAILS))
90 : {
91 3368 : fprintf (dump_file, "%c>>> ", type);
92 3368 : elt1->print (dump_file);
93 : }
94 :
95 181094515 : m_stack.safe_push (std::pair<expr_hash_elt_t, expr_hash_elt_t> (elt1, elt2));
96 181094515 : }
97 :
98 : /* Helper for walk_non_aliased_vuses. Determine if we arrived at
99 : the desired memory state. */
100 :
101 : static void *
102 18883909 : vuse_eq (ao_ref *, tree vuse1, void *data)
103 : {
104 18883909 : tree vuse2 = (tree) data;
105 18883909 : if (vuse1 == vuse2)
106 528518 : 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 45098523 : avail_exprs_stack::simplify_binary_operation (gimple *stmt,
119 : class expr_hash_elt element)
120 : {
121 45098523 : if (is_gimple_assign (stmt))
122 : {
123 35199654 : struct hashable_expr *expr = element.expr ();
124 35199654 : if (expr->kind == EXPR_BINARY)
125 : {
126 10337077 : enum tree_code code = expr->ops.binary.op;
127 :
128 10337077 : switch (code)
129 : {
130 : /* For these cases, if we know some relationships
131 : between the operands, then we can simplify. */
132 175936 : case MIN_EXPR:
133 175936 : case MAX_EXPR:
134 175936 : {
135 : /* Build a simple equality expr and query the hash table
136 : for it. */
137 175936 : struct hashable_expr expr;
138 175936 : expr.type = boolean_type_node;
139 175936 : expr.kind = EXPR_BINARY;
140 175936 : expr.ops.binary.op = LE_EXPR;
141 175936 : tree rhs1 = gimple_assign_rhs1 (stmt);
142 175936 : tree rhs2 = gimple_assign_rhs2 (stmt);
143 175936 : if (tree_swap_operands_p (rhs1, rhs2))
144 1219 : std::swap (rhs1, rhs2);
145 175936 : expr.ops.binary.opnd0 = rhs1;
146 175936 : expr.ops.binary.opnd1 = rhs2;
147 175936 : class expr_hash_elt element2 (&expr, NULL_TREE);
148 175936 : expr_hash_elt **slot
149 175936 : = 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 175936 : if (slot && *slot && integer_onep ((*slot)->lhs ()))
155 195 : return code == MIN_EXPR ? rhs1 : rhs2;
156 :
157 : /* Try again, this time with GE_EXPR. */
158 175798 : expr.ops.binary.op = GE_EXPR;
159 175798 : class expr_hash_elt element3 (&expr, NULL_TREE);
160 175798 : 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 175798 : if (slot && *slot && integer_onep ((*slot)->lhs ()))
166 494 : return code == MIN_EXPR ? rhs2 : rhs1;
167 :
168 175304 : break;
169 175936 : }
170 :
171 : /* For these cases, if we know the operands
172 : are equal, then we know the result. */
173 2012896 : case BIT_IOR_EXPR:
174 2012896 : case BIT_AND_EXPR:
175 2012896 : case BIT_XOR_EXPR:
176 2012896 : case MINUS_EXPR:
177 2012896 : case TRUNC_DIV_EXPR:
178 2012896 : case CEIL_DIV_EXPR:
179 2012896 : case FLOOR_DIV_EXPR:
180 2012896 : case ROUND_DIV_EXPR:
181 2012896 : case EXACT_DIV_EXPR:
182 2012896 : case TRUNC_MOD_EXPR:
183 2012896 : case CEIL_MOD_EXPR:
184 2012896 : case FLOOR_MOD_EXPR:
185 2012896 : case ROUND_MOD_EXPR:
186 2012896 : {
187 : /* Build a simple equality expr and query the hash table
188 : for it. */
189 2012896 : struct hashable_expr expr;
190 2012896 : expr.type = boolean_type_node;
191 2012896 : expr.kind = EXPR_BINARY;
192 2012896 : expr.ops.binary.op = EQ_EXPR;
193 2012896 : tree rhs1 = gimple_assign_rhs1 (stmt);
194 2012896 : tree rhs2 = gimple_assign_rhs2 (stmt);
195 2012896 : if (tree_swap_operands_p (rhs1, rhs2))
196 369203 : std::swap (rhs1, rhs2);
197 2012896 : expr.ops.binary.opnd0 = rhs1;
198 2012896 : expr.ops.binary.opnd1 = rhs2;
199 2012896 : class expr_hash_elt element2 (&expr, NULL_TREE);
200 2012896 : expr_hash_elt **slot
201 2012896 : = m_avail_exprs->find_slot (&element2, NO_INSERT);
202 2012896 : 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 2012896 : if (slot && *slot && integer_onep ((*slot)->lhs ()))
211 : {
212 176 : switch (code)
213 : {
214 3 : case BIT_IOR_EXPR:
215 3 : case BIT_AND_EXPR:
216 3 : return gimple_assign_rhs1 (stmt);
217 :
218 157 : 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 127 : if (FLOAT_TYPE_P (result_type)
223 157 : && HONOR_NANS (result_type))
224 : break;
225 : /* FALLTHRU */
226 142 : case BIT_XOR_EXPR:
227 142 : case TRUNC_MOD_EXPR:
228 142 : case CEIL_MOD_EXPR:
229 142 : case FLOOR_MOD_EXPR:
230 142 : case ROUND_MOD_EXPR:
231 142 : 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 2012750 : break;
248 2012896 : }
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 119828952 : avail_exprs_stack::lookup_avail_expr (gimple *stmt, bool insert, bool tbaa_p,
268 : expr_hash_elt **elt)
269 : {
270 119828952 : expr_hash_elt **slot;
271 119828952 : tree lhs;
272 :
273 : /* Get LHS of phi, assignment, or call; else NULL_TREE. */
274 119828952 : if (gimple_code (stmt) == GIMPLE_PHI)
275 8826166 : lhs = gimple_phi_result (stmt);
276 : else
277 111002786 : lhs = gimple_get_lhs (stmt);
278 :
279 119828952 : class expr_hash_elt element (stmt, lhs);
280 :
281 119828952 : if (dump_file && (dump_flags & TDF_DETAILS))
282 : {
283 2911 : fprintf (dump_file, "LKUP ");
284 2911 : 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 119828952 : if (element.expr()->kind == EXPR_SINGLE
291 119828952 : && (TREE_CODE (element.expr()->ops.single.rhs) == SSA_NAME
292 54179371 : || is_gimple_min_invariant (element.expr()->ops.single.rhs)))
293 13079361 : return NULL_TREE;
294 :
295 : /* Finally try to find the expression in the main expression hash table. */
296 163497485 : slot = m_avail_exprs->find_slot (&element, (insert ? INSERT : NO_INSERT));
297 106749591 : if (slot == NULL)
298 : {
299 : return NULL_TREE;
300 : }
301 54811972 : 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 45098523 : class expr_hash_elt *element2 = new expr_hash_elt (element);
314 45098523 : *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 45098523 : tree retval = avail_exprs_stack::simplify_binary_operation (stmt,
319 : element);
320 :
321 45098523 : record_expr (element2, NULL, '2');
322 45098523 : 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 19238529 : if (gimple_vuse (stmt) != (*slot)->vop ())
328 : {
329 8177535 : tree vuse1 = (*slot)->vop ();
330 8177535 : 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 8177535 : ao_ref ref;
336 8177535 : unsigned limit = param_sccvn_max_alias_queries_per_access;
337 15436350 : if (!(vuse1 && vuse2
338 8177535 : && gimple_assign_single_p (stmt)
339 8060290 : && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
340 7258815 : && (ao_ref_init (&ref, gimple_assign_rhs1 (stmt)),
341 7258815 : ref.base_alias_set = ref.ref_alias_set = tbaa_p ? -1 : 0, true)
342 7258815 : && walk_non_aliased_vuses (&ref, vuse2, true, vuse_eq, NULL, NULL,
343 : NULL, limit, vuse1) != NULL))
344 : {
345 7649017 : if (insert)
346 : {
347 4498685 : 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 4498685 : record_expr (element2, *slot, '2');
353 4498685 : *slot = element2;
354 : }
355 7649017 : 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 2064432 : lhs = (*slot)->lhs ();
362 2064432 : if (elt)
363 826522 : *elt = *slot;
364 :
365 : /* Valueize the result. */
366 2064432 : if (TREE_CODE (lhs) == SSA_NAME)
367 : {
368 1767237 : tree tem = SSA_NAME_VALUE (lhs);
369 1486756 : if (tem)
370 2064432 : lhs = tem;
371 : }
372 :
373 2064432 : if (dump_file && (dump_flags & TDF_DETAILS))
374 : {
375 177 : fprintf (dump_file, "FIND: ");
376 177 : print_generic_expr (dump_file, lhs);
377 177 : fprintf (dump_file, "\n");
378 : }
379 :
380 : return lhs;
381 119828952 : }
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 67724683 : avail_exprs_stack::record_cond (cond_equivalence *p)
390 : {
391 67724683 : class expr_hash_elt *element = new expr_hash_elt (&p->cond, p->value);
392 67724683 : expr_hash_elt **slot;
393 :
394 67724683 : slot = m_avail_exprs->find_slot_with_hash (element, element->hash (), INSERT);
395 :
396 : /* We will always get back a valid slot in the hash table. Go ahead and
397 : record the new equivalence. While it may be overwriting something older,
398 : the belief is that the newer equivalence is more likely to be useful as
399 : it was derived using more information/context. */
400 67724683 : record_expr (element, *slot, '1');
401 67724683 : *slot = element;
402 67724683 : }
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 66220882 : add_expr_commutative (const_tree t1, const_tree t2, hash &hstate)
416 : {
417 66220882 : hash one, two;
418 :
419 66220882 : inchash::add_expr (t1, one);
420 66220882 : inchash::add_expr (t2, two);
421 66220882 : hstate.add_commutative (one, two);
422 66220882 : }
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 150828328 : add_hashable_expr (const struct hashable_expr *expr, hash &hstate)
432 : {
433 150828328 : switch (expr->kind)
434 : {
435 21430148 : case EXPR_SINGLE:
436 21430148 : inchash::add_expr (expr->ops.single.rhs, hstate);
437 21430148 : break;
438 :
439 8004250 : case EXPR_UNARY:
440 8004250 : 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 8004250 : if (CONVERT_EXPR_CODE_P (expr->ops.unary.op)
447 931604 : || expr->ops.unary.op == NON_LVALUE_EXPR)
448 7072646 : hstate.add_int (TYPE_UNSIGNED (expr->type));
449 :
450 8004250 : inchash::add_expr (expr->ops.unary.opnd, hstate);
451 8004250 : break;
452 :
453 109395052 : case EXPR_BINARY:
454 109395052 : hstate.add_object (expr->ops.binary.op);
455 109395052 : if (commutative_tree_code (expr->ops.binary.op))
456 66220193 : inchash::add_expr_commutative (expr->ops.binary.opnd0,
457 66220193 : expr->ops.binary.opnd1, hstate);
458 : else
459 : {
460 43174859 : inchash::add_expr (expr->ops.binary.opnd0, hstate);
461 43174859 : inchash::add_expr (expr->ops.binary.opnd1, hstate);
462 : }
463 : break;
464 :
465 210089 : case EXPR_TERNARY:
466 210089 : hstate.add_object (expr->ops.ternary.op);
467 210089 : if (commutative_ternary_tree_code (expr->ops.ternary.op))
468 689 : inchash::add_expr_commutative (expr->ops.ternary.opnd0,
469 689 : expr->ops.ternary.opnd1, hstate);
470 : else
471 : {
472 209400 : inchash::add_expr (expr->ops.ternary.opnd0, hstate);
473 209400 : inchash::add_expr (expr->ops.ternary.opnd1, hstate);
474 : }
475 210089 : inchash::add_expr (expr->ops.ternary.opnd2, hstate);
476 210089 : break;
477 :
478 2962623 : case EXPR_CALL:
479 2962623 : {
480 2962623 : size_t i;
481 2962623 : enum tree_code code = CALL_EXPR;
482 2962623 : gcall *fn_from;
483 :
484 2962623 : hstate.add_object (code);
485 2962623 : fn_from = expr->ops.call.fn_from;
486 2962623 : if (gimple_call_internal_p (fn_from))
487 248809 : hstate.merge_hash ((hashval_t) gimple_call_internal_fn (fn_from));
488 : else
489 2713814 : inchash::add_expr (gimple_call_fn (fn_from), hstate);
490 8666900 : for (i = 0; i < expr->ops.call.nargs; i++)
491 5704277 : inchash::add_expr (expr->ops.call.args[i], hstate);
492 : }
493 2962623 : break;
494 :
495 : case EXPR_PHI:
496 : {
497 : size_t i;
498 :
499 31650826 : for (i = 0; i < expr->ops.phi.nargs; i++)
500 22824660 : inchash::add_expr (expr->ops.phi.args[i], hstate);
501 : }
502 : break;
503 :
504 0 : default:
505 0 : gcc_unreachable ();
506 : }
507 150828328 : }
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 189918265 : avail_expr_hash (class expr_hash_elt *p)
516 : {
517 189918265 : const struct hashable_expr *expr = p->expr ();
518 189918265 : inchash::hash hstate;
519 :
520 189918265 : if (expr->kind == EXPR_SINGLE)
521 : {
522 : /* T could potentially be a switch index or a goto dest. */
523 60520085 : tree t = expr->ops.single.rhs;
524 60520085 : 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 40402541 : bool reverse;
530 40402541 : poly_int64 offset, size, max_size;
531 40402541 : 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 40402541 : if (known_size_p (max_size)
536 40402541 : && known_eq (size, max_size))
537 : {
538 39089937 : enum tree_code code = MEM_REF;
539 39089937 : hstate.add_object (code);
540 39089937 : inchash::add_expr (base, hstate,
541 39089937 : TREE_CODE (base) == MEM_REF
542 : ? OEP_ADDRESS_OF : 0);
543 39089937 : hstate.add_object (offset);
544 39089937 : hstate.add_object (size);
545 39089937 : return hstate.end ();
546 : }
547 : }
548 : }
549 :
550 150828328 : inchash::add_hashable_expr (expr, hstate);
551 :
552 150828328 : 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 8995292 : equal_mem_array_ref_p (tree t0, tree t1)
563 : {
564 8995292 : if (TREE_CODE (t0) != MEM_REF && ! handled_component_p (t0))
565 : return false;
566 9131522 : if (TREE_CODE (t1) != MEM_REF && ! handled_component_p (t1))
567 : return false;
568 :
569 7773104 : if (!types_compatible_p (TREE_TYPE (t0), TREE_TYPE (t1)))
570 : return false;
571 7769083 : bool rev0;
572 7769083 : poly_int64 off0, sz0, max0;
573 7769083 : tree base0 = get_ref_base_and_extent (t0, &off0, &sz0, &max0, &rev0);
574 7769083 : if (!known_size_p (max0)
575 7769083 : || maybe_ne (sz0, max0))
576 : return false;
577 :
578 7636874 : bool rev1;
579 7636874 : poly_int64 off1, sz1, max1;
580 7636874 : tree base1 = get_ref_base_and_extent (t1, &off1, &sz1, &max1, &rev1);
581 7636874 : if (!known_size_p (max1)
582 7636874 : || maybe_ne (sz1, max1))
583 : return false;
584 :
585 7636874 : if (rev0 != rev1 || maybe_ne (sz0, sz1) || maybe_ne (off0, off1))
586 : return false;
587 :
588 7636874 : return operand_equal_p (base0, base1,
589 7636874 : (TREE_CODE (base0) == MEM_REF
590 7636874 : || TREE_CODE (base0) == TARGET_MEM_REF)
591 2705214 : && (TREE_CODE (base1) == MEM_REF
592 2705214 : || TREE_CODE (base1) == TARGET_MEM_REF)
593 7636874 : ? 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 10494608 : hashable_expr_equal_p (const struct hashable_expr *expr0,
603 : const struct hashable_expr *expr1)
604 : {
605 10494608 : tree type0 = expr0->type;
606 10494608 : tree type1 = expr1->type;
607 :
608 : /* If either type is NULL, there is nothing to check. */
609 10494608 : 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 10494608 : if (type0 != type1
615 10494608 : && (TREE_CODE (type0) == ERROR_MARK
616 1415234 : || TREE_CODE (type1) == ERROR_MARK
617 1415234 : || TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)
618 1352153 : || element_precision (type0) != element_precision (type1)
619 1248279 : || TYPE_MODE (type0) != TYPE_MODE (type1)))
620 243182 : return false;
621 :
622 10251426 : if (expr0->kind != expr1->kind)
623 : return false;
624 :
625 10251426 : switch (expr0->kind)
626 : {
627 8995292 : case EXPR_SINGLE:
628 8995292 : return equal_mem_array_ref_p (expr0->ops.single.rhs,
629 8995292 : expr1->ops.single.rhs)
630 10355625 : || operand_equal_p (expr0->ops.single.rhs,
631 1360333 : expr1->ops.single.rhs, 0);
632 186342 : case EXPR_UNARY:
633 186342 : if (expr0->ops.unary.op != expr1->ops.unary.op)
634 : return false;
635 :
636 15968 : if ((CONVERT_EXPR_CODE_P (expr0->ops.unary.op)
637 15968 : || expr0->ops.unary.op == NON_LVALUE_EXPR)
638 186342 : && TYPE_UNSIGNED (expr0->type) != TYPE_UNSIGNED (expr1->type))
639 : return false;
640 :
641 186342 : return operand_equal_p (expr0->ops.unary.opnd,
642 186342 : expr1->ops.unary.opnd, 0);
643 :
644 920678 : case EXPR_BINARY:
645 920678 : if (expr0->ops.binary.op != expr1->ops.binary.op)
646 : return false;
647 :
648 920678 : if (operand_equal_p (expr0->ops.binary.opnd0,
649 920678 : expr1->ops.binary.opnd0, 0)
650 1826139 : && operand_equal_p (expr0->ops.binary.opnd1,
651 905461 : expr1->ops.binary.opnd1, 0))
652 : return true;
653 :
654 : /* For commutative ops, allow the other order. */
655 17263 : return (commutative_tree_code (expr0->ops.binary.op)
656 15641 : && operand_equal_p (expr0->ops.binary.opnd0,
657 15641 : expr1->ops.binary.opnd1, 0)
658 23801 : && operand_equal_p (expr0->ops.binary.opnd1,
659 6538 : expr1->ops.binary.opnd0, 0));
660 :
661 231 : case EXPR_TERNARY:
662 231 : if (expr0->ops.ternary.op != expr1->ops.ternary.op
663 462 : || !operand_equal_p (expr0->ops.ternary.opnd2,
664 231 : 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 231 : 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 231 : && TYPE_PRECISION (TREE_TYPE (expr0->ops.ternary.opnd1))
673 0 : != TYPE_PRECISION (TREE_TYPE (expr1->ops.ternary.opnd1)))
674 : return false;
675 :
676 231 : if (operand_equal_p (expr0->ops.ternary.opnd0,
677 231 : expr1->ops.ternary.opnd0, 0)
678 462 : && operand_equal_p (expr0->ops.ternary.opnd1,
679 231 : 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 124026 : case EXPR_CALL:
690 124026 : {
691 124026 : size_t i;
692 :
693 : /* If the calls are to different functions, then they
694 : clearly cannot be equal. */
695 124026 : if (!gimple_call_same_target_p (expr0->ops.call.fn_from,
696 124026 : expr1->ops.call.fn_from))
697 : return false;
698 :
699 123402 : if (! expr0->ops.call.pure)
700 : return false;
701 :
702 123402 : if (expr0->ops.call.nargs != expr1->ops.call.nargs)
703 : return false;
704 :
705 351710 : for (i = 0; i < expr0->ops.call.nargs; i++)
706 228350 : if (! operand_equal_p (expr0->ops.call.args[i],
707 228350 : expr1->ops.call.args[i], 0))
708 : return false;
709 :
710 123360 : if (stmt_could_throw_p (cfun, expr0->ops.call.fn_from))
711 : {
712 22 : int lp0 = lookup_stmt_eh_lp (expr0->ops.call.fn_from);
713 22 : int lp1 = lookup_stmt_eh_lp (expr1->ops.call.fn_from);
714 22 : if ((lp0 > 0 || lp1 > 0) && lp0 != lp1)
715 : return false;
716 : }
717 :
718 : return true;
719 : }
720 :
721 24857 : case EXPR_PHI:
722 24857 : {
723 24857 : size_t i;
724 :
725 24857 : if (expr0->ops.phi.nargs != expr1->ops.phi.nargs)
726 : return false;
727 :
728 60156 : for (i = 0; i < expr0->ops.phi.nargs; i++)
729 35357 : if (! operand_equal_p (expr0->ops.phi.args[i],
730 35357 : 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 119828952 : expr_hash_elt::expr_hash_elt (gimple *stmt, tree orig_lhs)
744 : {
745 119828952 : enum gimple_code code = gimple_code (stmt);
746 119828952 : struct hashable_expr *expr = this->expr ();
747 :
748 119828952 : if (code == GIMPLE_ASSIGN)
749 : {
750 88582752 : enum tree_code subcode = gimple_assign_rhs_code (stmt);
751 :
752 88582752 : switch (get_gimple_rhs_class (subcode))
753 : {
754 60455233 : case GIMPLE_SINGLE_RHS:
755 60455233 : expr->kind = EXPR_SINGLE;
756 60455233 : expr->type = TREE_TYPE (gimple_assign_rhs1 (stmt));
757 60455233 : expr->ops.single.rhs = gimple_assign_rhs1 (stmt);
758 60455233 : break;
759 7882896 : case GIMPLE_UNARY_RHS:
760 7882896 : expr->kind = EXPR_UNARY;
761 7882896 : expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
762 7882896 : if (CONVERT_EXPR_CODE_P (subcode))
763 7072646 : subcode = NOP_EXPR;
764 7882896 : expr->ops.unary.op = subcode;
765 7882896 : expr->ops.unary.opnd = gimple_assign_rhs1 (stmt);
766 7882896 : break;
767 20034534 : case GIMPLE_BINARY_RHS:
768 20034534 : expr->kind = EXPR_BINARY;
769 20034534 : expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
770 20034534 : expr->ops.binary.op = subcode;
771 20034534 : expr->ops.binary.opnd0 = gimple_assign_rhs1 (stmt);
772 20034534 : expr->ops.binary.opnd1 = gimple_assign_rhs2 (stmt);
773 20034534 : break;
774 210089 : case GIMPLE_TERNARY_RHS:
775 210089 : expr->kind = EXPR_TERNARY;
776 210089 : expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
777 210089 : expr->ops.ternary.op = subcode;
778 210089 : expr->ops.ternary.opnd0 = gimple_assign_rhs1 (stmt);
779 210089 : expr->ops.ternary.opnd1 = gimple_assign_rhs2 (stmt);
780 210089 : expr->ops.ternary.opnd2 = gimple_assign_rhs3 (stmt);
781 210089 : break;
782 0 : default:
783 0 : gcc_unreachable ();
784 : }
785 : }
786 : else if (code == GIMPLE_COND)
787 : {
788 19392559 : expr->type = boolean_type_node;
789 19392559 : expr->kind = EXPR_BINARY;
790 19392559 : expr->ops.binary.op = gimple_cond_code (stmt);
791 19392559 : expr->ops.binary.opnd0 = gimple_cond_lhs (stmt);
792 19392559 : expr->ops.binary.opnd1 = gimple_cond_rhs (stmt);
793 : }
794 2962623 : else if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
795 : {
796 2962623 : size_t nargs = gimple_call_num_args (call_stmt);
797 2962623 : size_t i;
798 :
799 2962623 : gcc_assert (gimple_call_lhs (call_stmt));
800 :
801 2962623 : expr->type = TREE_TYPE (gimple_call_lhs (call_stmt));
802 2962623 : expr->kind = EXPR_CALL;
803 2962623 : expr->ops.call.fn_from = call_stmt;
804 :
805 2962623 : if (gimple_call_flags (call_stmt) & (ECF_CONST | ECF_PURE))
806 1525484 : expr->ops.call.pure = true;
807 : else
808 1437139 : expr->ops.call.pure = false;
809 :
810 2962623 : expr->ops.call.nargs = nargs;
811 2962623 : expr->ops.call.args = XCNEWVEC (tree, nargs);
812 8666900 : for (i = 0; i < nargs; i++)
813 5704277 : expr->ops.call.args[i] = gimple_call_arg (call_stmt, i);
814 : }
815 64632 : else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
816 : {
817 64632 : expr->type = TREE_TYPE (gimple_switch_index (swtch_stmt));
818 64632 : expr->kind = EXPR_SINGLE;
819 64632 : 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 8826166 : size_t nargs = gimple_phi_num_args (stmt);
830 8826166 : size_t i;
831 :
832 8826166 : expr->type = TREE_TYPE (gimple_phi_result (stmt));
833 8826166 : expr->kind = EXPR_PHI;
834 8826166 : expr->ops.phi.nargs = nargs;
835 8826166 : expr->ops.phi.args = XCNEWVEC (tree, nargs);
836 31650826 : for (i = 0; i < nargs; i++)
837 22824660 : expr->ops.phi.args[i] = gimple_phi_arg_def (stmt, i);
838 : }
839 : else
840 0 : gcc_unreachable ();
841 :
842 119828952 : m_lhs = orig_lhs;
843 119828952 : m_vop = gimple_vuse (stmt);
844 119828952 : m_hash = avail_expr_hash (this);
845 119828952 : m_stamp = this;
846 119828952 : }
847 :
848 : /* Given a hashable_expr expression ORIG and an ORIG_LHS,
849 : construct a hash table element. */
850 :
851 70089313 : expr_hash_elt::expr_hash_elt (struct hashable_expr *orig, tree orig_lhs)
852 : {
853 70089313 : m_expr = *orig;
854 70089313 : m_lhs = orig_lhs;
855 70089313 : m_vop = NULL_TREE;
856 70089313 : m_hash = avail_expr_hash (this);
857 70089313 : m_stamp = this;
858 70089313 : }
859 :
860 : /* Copy constructor for a hash table element. */
861 :
862 94695731 : expr_hash_elt::expr_hash_elt (class expr_hash_elt &old_elt)
863 : {
864 94695731 : m_expr = old_elt.m_expr;
865 94695731 : m_lhs = old_elt.m_lhs;
866 94695731 : m_vop = old_elt.m_vop;
867 94695731 : m_hash = old_elt.m_hash;
868 94695731 : m_stamp = this;
869 :
870 : /* Now deep copy the malloc'd space for CALL and PHI args. */
871 94695731 : if (old_elt.m_expr.kind == EXPR_CALL)
872 : {
873 2296704 : size_t nargs = old_elt.m_expr.ops.call.nargs;
874 2296704 : size_t i;
875 :
876 2296704 : m_expr.ops.call.args = XCNEWVEC (tree, nargs);
877 7179617 : for (i = 0; i < nargs; i++)
878 4882913 : m_expr.ops.call.args[i] = old_elt.m_expr.ops.call.args[i];
879 : }
880 92399027 : else if (old_elt.m_expr.kind == EXPR_PHI)
881 : {
882 17589536 : size_t nargs = old_elt.m_expr.ops.phi.nargs;
883 17589536 : size_t i;
884 :
885 17589536 : m_expr.ops.phi.args = XCNEWVEC (tree, nargs);
886 63125298 : for (i = 0; i < nargs; i++)
887 45535762 : m_expr.ops.phi.args[i] = old_elt.m_expr.ops.phi.args[i];
888 : }
889 94695731 : }
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 284613996 : expr_hash_elt::~expr_hash_elt ()
895 : {
896 284613996 : if (m_expr.kind == EXPR_CALL)
897 5259327 : free (m_expr.ops.call.args);
898 279354669 : else if (m_expr.kind == EXPR_PHI)
899 26415702 : free (m_expr.ops.phi.args);
900 284613996 : }
901 :
902 : /* Print a diagnostic dump of an expression hash table entry. */
903 :
904 : void
905 9647 : expr_hash_elt::print (FILE *stream)
906 : {
907 9647 : fprintf (stream, "STMT ");
908 :
909 9647 : if (m_lhs)
910 : {
911 9071 : print_generic_expr (stream, m_lhs);
912 9071 : fprintf (stream, " = ");
913 : }
914 :
915 9647 : switch (m_expr.kind)
916 : {
917 2605 : case EXPR_SINGLE:
918 2605 : print_generic_expr (stream, m_expr.ops.single.rhs);
919 2605 : 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 6045 : case EXPR_BINARY:
927 6045 : print_generic_expr (stream, m_expr.ops.binary.opnd0);
928 6045 : fprintf (stream, " %s ", get_tree_code_name (m_expr.ops.binary.op));
929 6045 : print_generic_expr (stream, m_expr.ops.binary.opnd1);
930 6045 : 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 6 : case EXPR_CALL:
943 6 : {
944 6 : size_t i;
945 6 : size_t nargs = m_expr.ops.call.nargs;
946 6 : gcall *fn_from;
947 :
948 6 : fn_from = m_expr.ops.call.fn_from;
949 6 : 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 6 : print_generic_expr (stream, gimple_call_fn (fn_from));
954 6 : fprintf (stream, " (");
955 24 : for (i = 0; i < nargs; i++)
956 : {
957 12 : print_generic_expr (stream, m_expr.ops.call.args[i]);
958 12 : if (i + 1 < nargs)
959 6 : fprintf (stream, ", ");
960 : }
961 6 : fprintf (stream, ")");
962 : }
963 6 : break;
964 :
965 715 : case EXPR_PHI:
966 715 : {
967 715 : size_t i;
968 715 : size_t nargs = m_expr.ops.phi.nargs;
969 :
970 715 : fprintf (stream, "PHI <");
971 3058 : for (i = 0; i < nargs; i++)
972 : {
973 1628 : print_generic_expr (stream, m_expr.ops.phi.args[i]);
974 1628 : if (i + 1 < nargs)
975 913 : fprintf (stream, ", ");
976 : }
977 715 : fprintf (stream, ">");
978 : }
979 715 : break;
980 : }
981 :
982 9647 : if (m_vop)
983 : {
984 2361 : fprintf (stream, " with ");
985 2361 : print_generic_expr (stream, m_vop);
986 : }
987 :
988 9647 : fprintf (stream, "\n");
989 9647 : }
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 53610237 : const_and_copies::pop_to_marker (void)
997 : {
998 91517179 : while (m_stack.length () > 0)
999 : {
1000 91517179 : tree prev_value, dest;
1001 :
1002 91517179 : 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 91517179 : if (dest == NULL)
1007 : break;
1008 :
1009 37906942 : if (dump_file && (dump_flags & TDF_DETAILS))
1010 : {
1011 1241 : fprintf (dump_file, "<<<< COPY ");
1012 1241 : print_generic_expr (dump_file, dest);
1013 1241 : fprintf (dump_file, " = ");
1014 1241 : print_generic_expr (dump_file, SSA_NAME_VALUE (dest));
1015 1241 : fprintf (dump_file, "\n");
1016 : }
1017 :
1018 37906942 : prev_value = m_stack.pop ();
1019 37906942 : set_ssa_name_value (dest, prev_value);
1020 : }
1021 53610237 : }
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 37906942 : const_and_copies::record_const_or_copy_raw (tree x, tree y, tree prev_x)
1029 : {
1030 37906942 : if (dump_file && (dump_flags & TDF_DETAILS))
1031 : {
1032 1241 : fprintf (dump_file, "0>>> COPY ");
1033 1241 : print_generic_expr (dump_file, x);
1034 1241 : fprintf (dump_file, " = ");
1035 1241 : print_generic_expr (dump_file, y);
1036 1241 : fprintf (dump_file, "\n");
1037 : }
1038 :
1039 37906942 : set_ssa_name_value (x, y);
1040 37906942 : m_stack.reserve (2);
1041 37906942 : m_stack.quick_push (prev_x);
1042 37906942 : m_stack.quick_push (x);
1043 37906942 : }
1044 :
1045 : /* Record that X has the value Y. */
1046 :
1047 : void
1048 24629101 : const_and_copies::record_const_or_copy (tree x, tree y)
1049 : {
1050 24629101 : record_const_or_copy (x, y, SSA_NAME_VALUE (x));
1051 24629101 : }
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 37906942 : 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 37906942 : if (y && TREE_CODE (y) == SSA_NAME)
1062 : {
1063 16847961 : tree tmp = SSA_NAME_VALUE (y);
1064 15261463 : y = tmp ? tmp : y;
1065 : }
1066 :
1067 37906942 : record_const_or_copy_raw (x, y, prev_x);
1068 37906942 : }
1069 :
1070 : bool
1071 259070962 : expr_elt_hasher::equal (const value_type &p1, const compare_type &p2)
1072 : {
1073 259070962 : const struct hashable_expr *expr1 = p1->expr ();
1074 259070962 : const class expr_hash_elt *stamp1 = p1->stamp ();
1075 259070962 : const struct hashable_expr *expr2 = p2->expr ();
1076 259070962 : const class expr_hash_elt *stamp2 = p2->stamp ();
1077 :
1078 : /* This case should apply only when removing entries from the table. */
1079 259070962 : if (stamp1 == stamp2)
1080 : return true;
1081 :
1082 141749071 : 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 10494608 : if (hashable_expr_equal_p (expr1, expr2)
1088 10494608 : && 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 65326664 : initialize_expr_from_cond (tree cond, struct hashable_expr *expr)
1101 : {
1102 65326664 : expr->type = boolean_type_node;
1103 :
1104 65326664 : if (COMPARISON_CLASS_P (cond))
1105 : {
1106 65122770 : expr->kind = EXPR_BINARY;
1107 65122770 : expr->ops.binary.op = TREE_CODE (cond);
1108 65122770 : expr->ops.binary.opnd0 = TREE_OPERAND (cond, 0);
1109 65122770 : expr->ops.binary.opnd1 = TREE_OPERAND (cond, 1);
1110 : }
1111 203894 : else if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
1112 : {
1113 203894 : expr->kind = EXPR_UNARY;
1114 203894 : expr->ops.unary.op = TRUTH_NOT_EXPR;
1115 203894 : expr->ops.unary.opnd = TREE_OPERAND (cond, 0);
1116 : }
1117 : else
1118 0 : gcc_unreachable ();
1119 65326664 : }
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 37455465 : 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 37455465 : cond_equivalence c;
1131 37455465 : struct hashable_expr *cond = &c.cond;
1132 :
1133 37455465 : gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
1134 :
1135 37455465 : cond->type = boolean_type_node;
1136 37455465 : cond->kind = EXPR_BINARY;
1137 37455465 : cond->ops.binary.op = code;
1138 37455465 : cond->ops.binary.opnd0 = op0;
1139 37455465 : cond->ops.binary.opnd1 = op1;
1140 :
1141 37455465 : c.value = val ? boolean_true_node : boolean_false_node;
1142 37455465 : p->safe_push (c);
1143 37455465 : }
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 32913171 : record_conditions (vec<cond_equivalence> *p, tree cond, tree inverted)
1153 : {
1154 32913171 : tree op0, op1;
1155 32913171 : cond_equivalence c;
1156 :
1157 32913171 : if (!COMPARISON_CLASS_P (cond))
1158 249839 : return;
1159 :
1160 32663332 : op0 = TREE_OPERAND (cond, 0);
1161 32663332 : op1 = TREE_OPERAND (cond, 1);
1162 :
1163 32663332 : switch (TREE_CODE (cond))
1164 : {
1165 4307736 : case LT_EXPR:
1166 4307736 : case GT_EXPR:
1167 4307736 : if (FLOAT_TYPE_P (TREE_TYPE (op0)))
1168 : {
1169 111349 : build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
1170 111349 : build_and_record_new_cond (LTGT_EXPR, op0, op1, p);
1171 : }
1172 :
1173 7380605 : build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR
1174 : ? LE_EXPR : GE_EXPR),
1175 : op0, op1, p);
1176 4307736 : build_and_record_new_cond (NE_EXPR, op0, op1, p);
1177 4307736 : build_and_record_new_cond (EQ_EXPR, op0, op1, p, false);
1178 4307736 : break;
1179 :
1180 4394403 : case GE_EXPR:
1181 4394403 : case LE_EXPR:
1182 4394403 : if (FLOAT_TYPE_P (TREE_TYPE (op0)))
1183 : {
1184 55509 : build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
1185 : }
1186 : break;
1187 :
1188 11802839 : case EQ_EXPR:
1189 11802839 : if (FLOAT_TYPE_P (TREE_TYPE (op0)))
1190 : {
1191 486112 : build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
1192 : }
1193 11802839 : build_and_record_new_cond (LE_EXPR, op0, op1, p);
1194 11802839 : build_and_record_new_cond (GE_EXPR, op0, op1, p);
1195 11802839 : break;
1196 :
1197 21217 : case UNORDERED_EXPR:
1198 21217 : build_and_record_new_cond (NE_EXPR, op0, op1, p);
1199 21217 : build_and_record_new_cond (UNLE_EXPR, op0, op1, p);
1200 21217 : build_and_record_new_cond (UNGE_EXPR, op0, op1, p);
1201 21217 : build_and_record_new_cond (UNEQ_EXPR, op0, op1, p);
1202 21217 : build_and_record_new_cond (UNLT_EXPR, op0, op1, p);
1203 21217 : build_and_record_new_cond (UNGT_EXPR, op0, op1, p);
1204 21217 : break;
1205 :
1206 16377 : case UNLT_EXPR:
1207 16377 : case UNGT_EXPR:
1208 28865 : build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR
1209 : ? UNLE_EXPR : UNGE_EXPR),
1210 : op0, op1, p);
1211 16377 : build_and_record_new_cond (NE_EXPR, op0, op1, p);
1212 16377 : break;
1213 :
1214 1094 : case UNEQ_EXPR:
1215 1094 : build_and_record_new_cond (UNLE_EXPR, op0, op1, p);
1216 1094 : build_and_record_new_cond (UNGE_EXPR, op0, op1, p);
1217 1094 : 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 32663332 : initialize_expr_from_cond (cond, &c.cond);
1231 32663332 : c.value = boolean_true_node;
1232 32663332 : 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 32663332 : initialize_expr_from_cond (inverted, &c.cond);
1240 32663332 : c.value = boolean_false_node;
1241 32663332 : p->safe_push (c);
1242 : }
|