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 63308401 : avail_exprs_stack::pop_to_marker ()
50 : {
51 : /* Remove all the expressions made available in this block. */
52 179124853 : while (m_stack.length () > 0)
53 : {
54 179124853 : std::pair<expr_hash_elt_t, expr_hash_elt_t> victim = m_stack.pop ();
55 179124853 : expr_hash_elt **slot;
56 :
57 179124853 : 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 115816452 : if (dump_file && (dump_flags & TDF_DETAILS))
64 : {
65 3325 : fprintf (dump_file, "<<<< ");
66 3325 : victim.first->print (dump_file);
67 : }
68 :
69 115816452 : slot = m_avail_exprs->find_slot (victim.first, NO_INSERT);
70 115816452 : gcc_assert (slot && *slot == victim.first);
71 115816452 : if (victim.second != NULL)
72 : {
73 4467378 : delete *slot;
74 4467378 : *slot = victim.second;
75 : }
76 : else
77 111349074 : m_avail_exprs->clear_slot (slot);
78 : }
79 63308401 : }
80 :
81 : /* Add <ELT1,ELT2> to the unwinding stack so they can be later removed
82 : from the hash table. */
83 :
84 : void
85 179124853 : avail_exprs_stack::record_expr (class expr_hash_elt *elt1,
86 : class expr_hash_elt *elt2,
87 : char type)
88 : {
89 179124853 : if (elt1 && dump_file && (dump_flags & TDF_DETAILS))
90 : {
91 3325 : fprintf (dump_file, "%c>>> ", type);
92 3325 : elt1->print (dump_file);
93 : }
94 :
95 179124853 : m_stack.safe_push (std::pair<expr_hash_elt_t, expr_hash_elt_t> (elt1, elt2));
96 179124853 : }
97 :
98 : /* Helper for walk_non_aliased_vuses. Determine if we arrived at
99 : the desired memory state. */
100 :
101 : static void *
102 18830986 : vuse_eq (ao_ref *, tree vuse1, void *data)
103 : {
104 18830986 : tree vuse2 = (tree) data;
105 18830986 : if (vuse1 == vuse2)
106 527530 : 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 44864182 : avail_exprs_stack::simplify_binary_operation (gimple *stmt,
119 : class expr_hash_elt element)
120 : {
121 44864182 : if (is_gimple_assign (stmt))
122 : {
123 35104248 : struct hashable_expr *expr = element.expr ();
124 35104248 : if (expr->kind == EXPR_BINARY)
125 : {
126 10237429 : enum tree_code code = expr->ops.binary.op;
127 :
128 10237429 : switch (code)
129 : {
130 : /* For these cases, if we know some relationships
131 : between the operands, then we can simplify. */
132 177265 : case MIN_EXPR:
133 177265 : case MAX_EXPR:
134 177265 : {
135 : /* Build a simple equality expr and query the hash table
136 : for it. */
137 177265 : struct hashable_expr expr;
138 177265 : expr.type = boolean_type_node;
139 177265 : expr.kind = EXPR_BINARY;
140 177265 : expr.ops.binary.op = LE_EXPR;
141 177265 : tree rhs1 = gimple_assign_rhs1 (stmt);
142 177265 : tree rhs2 = gimple_assign_rhs2 (stmt);
143 177265 : if (tree_swap_operands_p (rhs1, rhs2))
144 1243 : std::swap (rhs1, rhs2);
145 177265 : expr.ops.binary.opnd0 = rhs1;
146 177265 : expr.ops.binary.opnd1 = rhs2;
147 177265 : class expr_hash_elt element2 (&expr, NULL_TREE);
148 177265 : expr_hash_elt **slot
149 177265 : = 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 177265 : 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 177127 : expr.ops.binary.op = GE_EXPR;
159 177127 : class expr_hash_elt element3 (&expr, NULL_TREE);
160 177127 : 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 177127 : if (slot && *slot && integer_onep ((*slot)->lhs ()))
166 499 : return code == MIN_EXPR ? rhs2 : rhs1;
167 :
168 176628 : break;
169 177265 : }
170 :
171 : /* For these cases, if we know the operands
172 : are equal, then we know the result. */
173 1972985 : case BIT_IOR_EXPR:
174 1972985 : case BIT_AND_EXPR:
175 1972985 : case BIT_XOR_EXPR:
176 1972985 : case MINUS_EXPR:
177 1972985 : case TRUNC_DIV_EXPR:
178 1972985 : case CEIL_DIV_EXPR:
179 1972985 : case FLOOR_DIV_EXPR:
180 1972985 : case ROUND_DIV_EXPR:
181 1972985 : case EXACT_DIV_EXPR:
182 1972985 : case TRUNC_MOD_EXPR:
183 1972985 : case CEIL_MOD_EXPR:
184 1972985 : case FLOOR_MOD_EXPR:
185 1972985 : case ROUND_MOD_EXPR:
186 1972985 : {
187 : /* Build a simple equality expr and query the hash table
188 : for it. */
189 1972985 : struct hashable_expr expr;
190 1972985 : expr.type = boolean_type_node;
191 1972985 : expr.kind = EXPR_BINARY;
192 1972985 : expr.ops.binary.op = EQ_EXPR;
193 1972985 : tree rhs1 = gimple_assign_rhs1 (stmt);
194 1972985 : tree rhs2 = gimple_assign_rhs2 (stmt);
195 1972985 : if (tree_swap_operands_p (rhs1, rhs2))
196 359028 : std::swap (rhs1, rhs2);
197 1972985 : expr.ops.binary.opnd0 = rhs1;
198 1972985 : expr.ops.binary.opnd1 = rhs2;
199 1972985 : class expr_hash_elt element2 (&expr, NULL_TREE);
200 1972985 : expr_hash_elt **slot
201 1972985 : = m_avail_exprs->find_slot (&element2, NO_INSERT);
202 1972985 : 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 1972985 : if (slot && *slot && integer_onep ((*slot)->lhs ()))
211 : {
212 175 : switch (code)
213 : {
214 3 : case BIT_IOR_EXPR:
215 3 : case BIT_AND_EXPR:
216 3 : return gimple_assign_rhs1 (stmt);
217 :
218 156 : 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 126 : if (FLOAT_TYPE_P (result_type)
223 156 : && HONOR_NANS (result_type))
224 : break;
225 : /* FALLTHRU */
226 141 : case BIT_XOR_EXPR:
227 141 : case TRUNC_MOD_EXPR:
228 141 : case CEIL_MOD_EXPR:
229 141 : case FLOOR_MOD_EXPR:
230 141 : case ROUND_MOD_EXPR:
231 141 : 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 1972840 : break;
248 1972985 : }
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 118963757 : avail_exprs_stack::lookup_avail_expr (gimple *stmt, bool insert, bool tbaa_p,
268 : expr_hash_elt **elt)
269 : {
270 118963757 : expr_hash_elt **slot;
271 118963757 : tree lhs;
272 :
273 : /* Get LHS of phi, assignment, or call; else NULL_TREE. */
274 118963757 : if (gimple_code (stmt) == GIMPLE_PHI)
275 8682758 : lhs = gimple_phi_result (stmt);
276 : else
277 110280999 : lhs = gimple_get_lhs (stmt);
278 :
279 118963757 : class expr_hash_elt element (stmt, lhs);
280 :
281 118963757 : 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 118963757 : if (element.expr()->kind == EXPR_SINGLE
291 118963757 : && (TREE_CODE (element.expr()->ops.single.rhs) == SSA_NAME
292 54088253 : || is_gimple_min_invariant (element.expr()->ops.single.rhs)))
293 13074171 : return NULL_TREE;
294 :
295 : /* Finally try to find the expression in the main expression hash table. */
296 162036755 : slot = m_avail_exprs->find_slot (&element, (insert ? INSERT : NO_INSERT));
297 105889586 : if (slot == NULL)
298 : {
299 : return NULL_TREE;
300 : }
301 54504841 : 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 44864182 : class expr_hash_elt *element2 = new expr_hash_elt (element);
314 44864182 : *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 44864182 : tree retval = avail_exprs_stack::simplify_binary_operation (stmt,
319 : element);
320 :
321 44864182 : record_expr (element2, NULL, '2');
322 44864182 : 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 19096780 : if (gimple_vuse (stmt) != (*slot)->vop ())
328 : {
329 8105313 : tree vuse1 = (*slot)->vop ();
330 8105313 : 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 8105313 : ao_ref ref;
336 8105313 : unsigned limit = param_sccvn_max_alias_queries_per_access;
337 15295026 : if (!(vuse1 && vuse2
338 8105313 : && gimple_assign_single_p (stmt)
339 7988145 : && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
340 7189713 : && (ao_ref_init (&ref, gimple_assign_rhs1 (stmt)),
341 7189713 : ref.base_alias_set = ref.ref_alias_set = tbaa_p ? -1 : 0, true)
342 7189713 : && walk_non_aliased_vuses (&ref, vuse2, true, vuse_eq, NULL, NULL,
343 : NULL, limit, vuse1) != NULL))
344 : {
345 7577783 : if (insert)
346 : {
347 4467378 : 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 4467378 : record_expr (element2, *slot, '2');
353 4467378 : *slot = element2;
354 : }
355 7577783 : 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 2062876 : lhs = (*slot)->lhs ();
362 2062876 : if (elt)
363 821840 : *elt = *slot;
364 :
365 : /* Valueize the result. */
366 2062876 : if (TREE_CODE (lhs) == SSA_NAME)
367 : {
368 1772787 : tree tem = SSA_NAME_VALUE (lhs);
369 1490841 : if (tem)
370 2062876 : lhs = tem;
371 : }
372 :
373 2062876 : 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 118963757 : }
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 66960545 : avail_exprs_stack::record_cond (cond_equivalence *p)
390 : {
391 66960545 : class expr_hash_elt *element = new expr_hash_elt (&p->cond, p->value);
392 66960545 : expr_hash_elt **slot;
393 :
394 66960545 : slot = m_avail_exprs->find_slot_with_hash (element, element->hash (), INSERT);
395 66960545 : if (*slot == NULL)
396 : {
397 66484892 : *slot = element;
398 66484892 : record_expr (element, NULL, '1');
399 : }
400 : else
401 475653 : delete element;
402 66960545 : }
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 65453137 : add_expr_commutative (const_tree t1, const_tree t2, hash &hstate)
416 : {
417 65453137 : hash one, two;
418 :
419 65453137 : inchash::add_expr (t1, one);
420 65453137 : inchash::add_expr (t2, two);
421 65453137 : hstate.add_commutative (one, two);
422 65453137 : }
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 149263139 : add_hashable_expr (const struct hashable_expr *expr, hash &hstate)
432 : {
433 149263139 : switch (expr->kind)
434 : {
435 21427081 : case EXPR_SINGLE:
436 21427081 : inchash::add_expr (expr->ops.single.rhs, hstate);
437 21427081 : break;
438 :
439 7900192 : case EXPR_UNARY:
440 7900192 : 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 7900192 : if (CONVERT_EXPR_CODE_P (expr->ops.unary.op)
447 928076 : || expr->ops.unary.op == NON_LVALUE_EXPR)
448 6972116 : hstate.add_int (TYPE_UNSIGNED (expr->type));
449 :
450 7900192 : inchash::add_expr (expr->ops.unary.opnd, hstate);
451 7900192 : break;
452 :
453 108068722 : case EXPR_BINARY:
454 108068722 : hstate.add_object (expr->ops.binary.op);
455 108068722 : if (commutative_tree_code (expr->ops.binary.op))
456 65452448 : inchash::add_expr_commutative (expr->ops.binary.opnd0,
457 65452448 : expr->ops.binary.opnd1, hstate);
458 : else
459 : {
460 42616274 : inchash::add_expr (expr->ops.binary.opnd0, hstate);
461 42616274 : inchash::add_expr (expr->ops.binary.opnd1, hstate);
462 : }
463 : break;
464 :
465 217866 : case EXPR_TERNARY:
466 217866 : hstate.add_object (expr->ops.ternary.op);
467 217866 : 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 217177 : inchash::add_expr (expr->ops.ternary.opnd0, hstate);
473 217177 : inchash::add_expr (expr->ops.ternary.opnd1, hstate);
474 : }
475 217866 : inchash::add_expr (expr->ops.ternary.opnd2, hstate);
476 217866 : break;
477 :
478 2966520 : case EXPR_CALL:
479 2966520 : {
480 2966520 : size_t i;
481 2966520 : enum tree_code code = CALL_EXPR;
482 2966520 : gcall *fn_from;
483 :
484 2966520 : hstate.add_object (code);
485 2966520 : fn_from = expr->ops.call.fn_from;
486 2966520 : if (gimple_call_internal_p (fn_from))
487 252926 : hstate.merge_hash ((hashval_t) gimple_call_internal_fn (fn_from));
488 : else
489 2713594 : inchash::add_expr (gimple_call_fn (fn_from), hstate);
490 8686573 : for (i = 0; i < expr->ops.call.nargs; i++)
491 5720053 : inchash::add_expr (expr->ops.call.args[i], hstate);
492 : }
493 2966520 : break;
494 :
495 : case EXPR_PHI:
496 : {
497 : size_t i;
498 :
499 31241233 : for (i = 0; i < expr->ops.phi.nargs; i++)
500 22558475 : inchash::add_expr (expr->ops.phi.args[i], hstate);
501 : }
502 : break;
503 :
504 0 : default:
505 0 : gcc_unreachable ();
506 : }
507 149263139 : }
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 188251679 : avail_expr_hash (class expr_hash_elt *p)
516 : {
517 188251679 : const struct hashable_expr *expr = p->expr ();
518 188251679 : inchash::hash hstate;
519 :
520 188251679 : if (expr->kind == EXPR_SINGLE)
521 : {
522 : /* T could potentially be a switch index or a goto dest. */
523 60415621 : tree t = expr->ops.single.rhs;
524 60415621 : 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 40281876 : bool reverse;
530 40281876 : poly_int64 offset, size, max_size;
531 40281876 : 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 40281876 : if (known_size_p (max_size)
536 40281876 : && known_eq (size, max_size))
537 : {
538 38988540 : enum tree_code code = MEM_REF;
539 38988540 : hstate.add_object (code);
540 38988540 : inchash::add_expr (base, hstate,
541 38988540 : TREE_CODE (base) == MEM_REF
542 : ? OEP_ADDRESS_OF : 0);
543 38988540 : hstate.add_object (offset);
544 38988540 : hstate.add_object (size);
545 38988540 : return hstate.end ();
546 : }
547 : }
548 : }
549 :
550 149263139 : inchash::add_hashable_expr (expr, hstate);
551 :
552 149263139 : 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 8926344 : equal_mem_array_ref_p (tree t0, tree t1)
563 : {
564 8926344 : if (TREE_CODE (t0) != MEM_REF && ! handled_component_p (t0))
565 : return false;
566 9062394 : if (TREE_CODE (t1) != MEM_REF && ! handled_component_p (t1))
567 : return false;
568 :
569 7695941 : if (!types_compatible_p (TREE_TYPE (t0), TREE_TYPE (t1)))
570 : return false;
571 7691934 : bool rev0;
572 7691934 : poly_int64 off0, sz0, max0;
573 7691934 : tree base0 = get_ref_base_and_extent (t0, &off0, &sz0, &max0, &rev0);
574 7691934 : if (!known_size_p (max0)
575 7691934 : || maybe_ne (sz0, max0))
576 : return false;
577 :
578 7559891 : bool rev1;
579 7559891 : poly_int64 off1, sz1, max1;
580 7559891 : tree base1 = get_ref_base_and_extent (t1, &off1, &sz1, &max1, &rev1);
581 7559891 : if (!known_size_p (max1)
582 7559891 : || maybe_ne (sz1, max1))
583 : return false;
584 :
585 7559891 : if (rev0 != rev1 || maybe_ne (sz0, sz1) || maybe_ne (off0, off1))
586 : return false;
587 :
588 7559891 : return operand_equal_p (base0, base1,
589 7559891 : (TREE_CODE (base0) == MEM_REF
590 7559891 : || TREE_CODE (base0) == TARGET_MEM_REF)
591 2653967 : && (TREE_CODE (base1) == MEM_REF
592 2653967 : || TREE_CODE (base1) == TARGET_MEM_REF)
593 7559891 : ? 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 10418544 : hashable_expr_equal_p (const struct hashable_expr *expr0,
603 : const struct hashable_expr *expr1)
604 : {
605 10418544 : tree type0 = expr0->type;
606 10418544 : tree type1 = expr1->type;
607 :
608 : /* If either type is NULL, there is nothing to check. */
609 10418544 : 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 10418544 : if (type0 != type1
615 10418544 : && (TREE_CODE (type0) == ERROR_MARK
616 1397347 : || TREE_CODE (type1) == ERROR_MARK
617 1397347 : || TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)
618 1335413 : || element_precision (type0) != element_precision (type1)
619 1234221 : || TYPE_MODE (type0) != TYPE_MODE (type1)))
620 240919 : return false;
621 :
622 10177625 : if (expr0->kind != expr1->kind)
623 : return false;
624 :
625 10177625 : switch (expr0->kind)
626 : {
627 8926344 : case EXPR_SINGLE:
628 8926344 : return equal_mem_array_ref_p (expr0->ops.single.rhs,
629 8926344 : expr1->ops.single.rhs)
630 10295747 : || operand_equal_p (expr0->ops.single.rhs,
631 1369403 : expr1->ops.single.rhs, 0);
632 187277 : case EXPR_UNARY:
633 187277 : if (expr0->ops.unary.op != expr1->ops.unary.op)
634 : return false;
635 :
636 14796 : if ((CONVERT_EXPR_CODE_P (expr0->ops.unary.op)
637 14796 : || expr0->ops.unary.op == NON_LVALUE_EXPR)
638 187277 : && TYPE_UNSIGNED (expr0->type) != TYPE_UNSIGNED (expr1->type))
639 : return false;
640 :
641 187277 : return operand_equal_p (expr0->ops.unary.opnd,
642 187277 : expr1->ops.unary.opnd, 0);
643 :
644 915578 : case EXPR_BINARY:
645 915578 : if (expr0->ops.binary.op != expr1->ops.binary.op)
646 : return false;
647 :
648 915578 : if (operand_equal_p (expr0->ops.binary.opnd0,
649 915578 : expr1->ops.binary.opnd0, 0)
650 1816138 : && operand_equal_p (expr0->ops.binary.opnd1,
651 900560 : expr1->ops.binary.opnd1, 0))
652 : return true;
653 :
654 : /* For commutative ops, allow the other order. */
655 18017 : return (commutative_tree_code (expr0->ops.binary.op)
656 15664 : && operand_equal_p (expr0->ops.binary.opnd0,
657 15664 : expr1->ops.binary.opnd1, 0)
658 24406 : && operand_equal_p (expr0->ops.binary.opnd1,
659 6389 : expr1->ops.binary.opnd0, 0));
660 :
661 462 : case EXPR_TERNARY:
662 462 : if (expr0->ops.ternary.op != expr1->ops.ternary.op
663 924 : || !operand_equal_p (expr0->ops.ternary.opnd2,
664 462 : 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 462 : 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 462 : && TYPE_PRECISION (TREE_TYPE (expr0->ops.ternary.opnd1))
673 0 : != TYPE_PRECISION (TREE_TYPE (expr1->ops.ternary.opnd1)))
674 : return false;
675 :
676 462 : if (operand_equal_p (expr0->ops.ternary.opnd0,
677 462 : expr1->ops.ternary.opnd0, 0)
678 924 : && operand_equal_p (expr0->ops.ternary.opnd1,
679 462 : 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 124308 : case EXPR_CALL:
690 124308 : {
691 124308 : size_t i;
692 :
693 : /* If the calls are to different functions, then they
694 : clearly cannot be equal. */
695 124308 : if (!gimple_call_same_target_p (expr0->ops.call.fn_from,
696 124308 : expr1->ops.call.fn_from))
697 : return false;
698 :
699 123684 : if (! expr0->ops.call.pure)
700 : return false;
701 :
702 123684 : if (expr0->ops.call.nargs != expr1->ops.call.nargs)
703 : return false;
704 :
705 352764 : for (i = 0; i < expr0->ops.call.nargs; i++)
706 229124 : if (! operand_equal_p (expr0->ops.call.args[i],
707 229124 : expr1->ops.call.args[i], 0))
708 : return false;
709 :
710 123640 : 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 23656 : case EXPR_PHI:
722 23656 : {
723 23656 : size_t i;
724 :
725 23656 : if (expr0->ops.phi.nargs != expr1->ops.phi.nargs)
726 : return false;
727 :
728 57996 : for (i = 0; i < expr0->ops.phi.nargs; i++)
729 34398 : if (! operand_equal_p (expr0->ops.phi.args[i],
730 34398 : 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 118963757 : expr_hash_elt::expr_hash_elt (gimple *stmt, tree orig_lhs)
744 : {
745 118963757 : enum gimple_code code = gimple_code (stmt);
746 118963757 : struct hashable_expr *expr = this->expr ();
747 :
748 118963757 : if (code == GIMPLE_ASSIGN)
749 : {
750 88110881 : enum tree_code subcode = gimple_assign_rhs_code (stmt);
751 :
752 88110881 : switch (get_gimple_rhs_class (subcode))
753 : {
754 60357111 : case GIMPLE_SINGLE_RHS:
755 60357111 : expr->kind = EXPR_SINGLE;
756 60357111 : expr->type = TREE_TYPE (gimple_assign_rhs1 (stmt));
757 60357111 : expr->ops.single.rhs = gimple_assign_rhs1 (stmt);
758 60357111 : break;
759 7779809 : case GIMPLE_UNARY_RHS:
760 7779809 : expr->kind = EXPR_UNARY;
761 7779809 : expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
762 7779809 : if (CONVERT_EXPR_CODE_P (subcode))
763 6972116 : subcode = NOP_EXPR;
764 7779809 : expr->ops.unary.op = subcode;
765 7779809 : expr->ops.unary.opnd = gimple_assign_rhs1 (stmt);
766 7779809 : break;
767 19756095 : case GIMPLE_BINARY_RHS:
768 19756095 : expr->kind = EXPR_BINARY;
769 19756095 : expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
770 19756095 : expr->ops.binary.op = subcode;
771 19756095 : expr->ops.binary.opnd0 = gimple_assign_rhs1 (stmt);
772 19756095 : expr->ops.binary.opnd1 = gimple_assign_rhs2 (stmt);
773 19756095 : break;
774 217866 : case GIMPLE_TERNARY_RHS:
775 217866 : expr->kind = EXPR_TERNARY;
776 217866 : expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
777 217866 : expr->ops.ternary.op = subcode;
778 217866 : expr->ops.ternary.opnd0 = gimple_assign_rhs1 (stmt);
779 217866 : expr->ops.ternary.opnd1 = gimple_assign_rhs2 (stmt);
780 217866 : expr->ops.ternary.opnd2 = gimple_assign_rhs3 (stmt);
781 217866 : break;
782 0 : default:
783 0 : gcc_unreachable ();
784 : }
785 : }
786 : else if (code == GIMPLE_COND)
787 : {
788 19145088 : expr->type = boolean_type_node;
789 19145088 : expr->kind = EXPR_BINARY;
790 19145088 : expr->ops.binary.op = gimple_cond_code (stmt);
791 19145088 : expr->ops.binary.opnd0 = gimple_cond_lhs (stmt);
792 19145088 : expr->ops.binary.opnd1 = gimple_cond_rhs (stmt);
793 : }
794 2966520 : else if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
795 : {
796 2966520 : size_t nargs = gimple_call_num_args (call_stmt);
797 2966520 : size_t i;
798 :
799 2966520 : gcc_assert (gimple_call_lhs (call_stmt));
800 :
801 2966520 : expr->type = TREE_TYPE (gimple_call_lhs (call_stmt));
802 2966520 : expr->kind = EXPR_CALL;
803 2966520 : expr->ops.call.fn_from = call_stmt;
804 :
805 2966520 : if (gimple_call_flags (call_stmt) & (ECF_CONST | ECF_PURE))
806 1527858 : expr->ops.call.pure = true;
807 : else
808 1438662 : expr->ops.call.pure = false;
809 :
810 2966520 : expr->ops.call.nargs = nargs;
811 2966520 : expr->ops.call.args = XCNEWVEC (tree, nargs);
812 8686573 : for (i = 0; i < nargs; i++)
813 5720053 : expr->ops.call.args[i] = gimple_call_arg (call_stmt, i);
814 : }
815 58288 : else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
816 : {
817 58288 : expr->type = TREE_TYPE (gimple_switch_index (swtch_stmt));
818 58288 : expr->kind = EXPR_SINGLE;
819 58288 : expr->ops.single.rhs = gimple_switch_index (swtch_stmt);
820 : }
821 : else if (code == GIMPLE_GOTO)
822 : {
823 222 : expr->type = TREE_TYPE (gimple_goto_dest (stmt));
824 222 : expr->kind = EXPR_SINGLE;
825 222 : expr->ops.single.rhs = gimple_goto_dest (stmt);
826 : }
827 : else if (code == GIMPLE_PHI)
828 : {
829 8682758 : size_t nargs = gimple_phi_num_args (stmt);
830 8682758 : size_t i;
831 :
832 8682758 : expr->type = TREE_TYPE (gimple_phi_result (stmt));
833 8682758 : expr->kind = EXPR_PHI;
834 8682758 : expr->ops.phi.nargs = nargs;
835 8682758 : expr->ops.phi.args = XCNEWVEC (tree, nargs);
836 31241233 : for (i = 0; i < nargs; i++)
837 22558475 : expr->ops.phi.args[i] = gimple_phi_arg_def (stmt, i);
838 : }
839 : else
840 0 : gcc_unreachable ();
841 :
842 118963757 : m_lhs = orig_lhs;
843 118963757 : m_vop = gimple_vuse (stmt);
844 118963757 : m_hash = avail_expr_hash (this);
845 118963757 : m_stamp = this;
846 118963757 : }
847 :
848 : /* Given a hashable_expr expression ORIG and an ORIG_LHS,
849 : construct a hash table element. */
850 :
851 69287922 : expr_hash_elt::expr_hash_elt (struct hashable_expr *orig, tree orig_lhs)
852 : {
853 69287922 : m_expr = *orig;
854 69287922 : m_lhs = orig_lhs;
855 69287922 : m_vop = NULL_TREE;
856 69287922 : m_hash = avail_expr_hash (this);
857 69287922 : m_stamp = this;
858 69287922 : }
859 :
860 : /* Copy constructor for a hash table element. */
861 :
862 94195742 : expr_hash_elt::expr_hash_elt (class expr_hash_elt &old_elt)
863 : {
864 94195742 : m_expr = old_elt.m_expr;
865 94195742 : m_lhs = old_elt.m_lhs;
866 94195742 : m_vop = old_elt.m_vop;
867 94195742 : m_hash = old_elt.m_hash;
868 94195742 : m_stamp = this;
869 :
870 : /* Now deep copy the malloc'd space for CALL and PHI args. */
871 94195742 : if (old_elt.m_expr.kind == EXPR_CALL)
872 : {
873 2303888 : size_t nargs = old_elt.m_expr.ops.call.nargs;
874 2303888 : size_t i;
875 :
876 2303888 : m_expr.ops.call.args = XCNEWVEC (tree, nargs);
877 7198711 : for (i = 0; i < nargs; i++)
878 4894823 : m_expr.ops.call.args[i] = old_elt.m_expr.ops.call.args[i];
879 : }
880 91891854 : else if (old_elt.m_expr.kind == EXPR_PHI)
881 : {
882 17304492 : size_t nargs = old_elt.m_expr.ops.phi.nargs;
883 17304492 : size_t i;
884 :
885 17304492 : m_expr.ops.phi.args = XCNEWVEC (tree, nargs);
886 62309166 : for (i = 0; i < nargs; i++)
887 45004674 : m_expr.ops.phi.args[i] = old_elt.m_expr.ops.phi.args[i];
888 : }
889 94195742 : }
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 282447421 : expr_hash_elt::~expr_hash_elt ()
895 : {
896 282447421 : if (m_expr.kind == EXPR_CALL)
897 5270408 : free (m_expr.ops.call.args);
898 277177013 : else if (m_expr.kind == EXPR_PHI)
899 25987250 : free (m_expr.ops.phi.args);
900 282447421 : }
901 :
902 : /* Print a diagnostic dump of an expression hash table entry. */
903 :
904 : void
905 9561 : expr_hash_elt::print (FILE *stream)
906 : {
907 9561 : fprintf (stream, "STMT ");
908 :
909 9561 : if (m_lhs)
910 : {
911 8985 : print_generic_expr (stream, m_lhs);
912 8985 : fprintf (stream, " = ");
913 : }
914 :
915 9561 : 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 5959 : case EXPR_BINARY:
927 5959 : print_generic_expr (stream, m_expr.ops.binary.opnd0);
928 5959 : fprintf (stream, " %s ", get_tree_code_name (m_expr.ops.binary.op));
929 5959 : print_generic_expr (stream, m_expr.ops.binary.opnd1);
930 5959 : 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 9561 : if (m_vop)
983 : {
984 2361 : fprintf (stream, " with ");
985 2361 : print_generic_expr (stream, m_vop);
986 : }
987 :
988 9561 : fprintf (stream, "\n");
989 9561 : }
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 53121776 : const_and_copies::pop_to_marker (void)
997 : {
998 90298063 : while (m_stack.length () > 0)
999 : {
1000 90298063 : tree prev_value, dest;
1001 :
1002 90298063 : 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 90298063 : if (dest == NULL)
1007 : break;
1008 :
1009 37176287 : 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 37176287 : prev_value = m_stack.pop ();
1019 37176287 : set_ssa_name_value (dest, prev_value);
1020 : }
1021 53121776 : }
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 37176287 : const_and_copies::record_const_or_copy_raw (tree x, tree y, tree prev_x)
1029 : {
1030 37176287 : 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 37176287 : set_ssa_name_value (x, y);
1040 37176287 : m_stack.reserve (2);
1041 37176287 : m_stack.quick_push (prev_x);
1042 37176287 : m_stack.quick_push (x);
1043 37176287 : }
1044 :
1045 : /* Record that X has the value Y. */
1046 :
1047 : void
1048 24034960 : const_and_copies::record_const_or_copy (tree x, tree y)
1049 : {
1050 24034960 : record_const_or_copy (x, y, SSA_NAME_VALUE (x));
1051 24034960 : }
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 37176287 : 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 37176287 : if (y && TREE_CODE (y) == SSA_NAME)
1062 : {
1063 16416272 : tree tmp = SSA_NAME_VALUE (y);
1064 14861769 : y = tmp ? tmp : y;
1065 : }
1066 :
1067 37176287 : record_const_or_copy_raw (x, y, prev_x);
1068 37176287 : }
1069 :
1070 : bool
1071 258440018 : expr_elt_hasher::equal (const value_type &p1, const compare_type &p2)
1072 : {
1073 258440018 : const struct hashable_expr *expr1 = p1->expr ();
1074 258440018 : const class expr_hash_elt *stamp1 = p1->stamp ();
1075 258440018 : const struct hashable_expr *expr2 = p2->expr ();
1076 258440018 : const class expr_hash_elt *stamp2 = p2->stamp ();
1077 :
1078 : /* This case should apply only when removing entries from the table. */
1079 258440018 : if (stamp1 == stamp2)
1080 : return true;
1081 :
1082 142623566 : 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 10418544 : if (hashable_expr_equal_p (expr1, expr2)
1088 10418544 : && 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 64889884 : initialize_expr_from_cond (tree cond, struct hashable_expr *expr)
1101 : {
1102 64889884 : expr->type = boolean_type_node;
1103 :
1104 64889884 : if (COMPARISON_CLASS_P (cond))
1105 : {
1106 64688656 : expr->kind = EXPR_BINARY;
1107 64688656 : expr->ops.binary.op = TREE_CODE (cond);
1108 64688656 : expr->ops.binary.opnd0 = TREE_OPERAND (cond, 0);
1109 64688656 : expr->ops.binary.opnd1 = TREE_OPERAND (cond, 1);
1110 : }
1111 201228 : else if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
1112 : {
1113 201228 : expr->kind = EXPR_UNARY;
1114 201228 : expr->ops.unary.op = TRUTH_NOT_EXPR;
1115 201228 : expr->ops.unary.opnd = TREE_OPERAND (cond, 0);
1116 : }
1117 : else
1118 0 : gcc_unreachable ();
1119 64889884 : }
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 37207953 : 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 37207953 : cond_equivalence c;
1131 37207953 : struct hashable_expr *cond = &c.cond;
1132 :
1133 37207953 : gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
1134 :
1135 37207953 : cond->type = boolean_type_node;
1136 37207953 : cond->kind = EXPR_BINARY;
1137 37207953 : cond->ops.binary.op = code;
1138 37207953 : cond->ops.binary.opnd0 = op0;
1139 37207953 : cond->ops.binary.opnd1 = op1;
1140 :
1141 37207953 : c.value = val ? boolean_true_node : boolean_false_node;
1142 37207953 : p->safe_push (c);
1143 37207953 : }
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 32692115 : record_conditions (vec<cond_equivalence> *p, tree cond, tree inverted)
1153 : {
1154 32692115 : tree op0, op1;
1155 32692115 : cond_equivalence c;
1156 :
1157 32692115 : if (!COMPARISON_CLASS_P (cond))
1158 247173 : return;
1159 :
1160 32444942 : op0 = TREE_OPERAND (cond, 0);
1161 32444942 : op1 = TREE_OPERAND (cond, 1);
1162 :
1163 32444942 : switch (TREE_CODE (cond))
1164 : {
1165 4281663 : case LT_EXPR:
1166 4281663 : case GT_EXPR:
1167 4281663 : if (FLOAT_TYPE_P (TREE_TYPE (op0)))
1168 : {
1169 111755 : build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
1170 111755 : build_and_record_new_cond (LTGT_EXPR, op0, op1, p);
1171 : }
1172 :
1173 7334528 : build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR
1174 : ? LE_EXPR : GE_EXPR),
1175 : op0, op1, p);
1176 4281663 : build_and_record_new_cond (NE_EXPR, op0, op1, p);
1177 4281663 : build_and_record_new_cond (EQ_EXPR, op0, op1, p, false);
1178 4281663 : break;
1179 :
1180 4367810 : case GE_EXPR:
1181 4367810 : case LE_EXPR:
1182 4367810 : 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 11720563 : case EQ_EXPR:
1189 11720563 : if (FLOAT_TYPE_P (TREE_TYPE (op0)))
1190 : {
1191 486127 : build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
1192 : }
1193 11720563 : build_and_record_new_cond (LE_EXPR, op0, op1, p);
1194 11720563 : build_and_record_new_cond (GE_EXPR, op0, op1, p);
1195 11720563 : break;
1196 :
1197 21313 : case UNORDERED_EXPR:
1198 21313 : build_and_record_new_cond (NE_EXPR, op0, op1, p);
1199 21313 : build_and_record_new_cond (UNLE_EXPR, op0, op1, p);
1200 21313 : build_and_record_new_cond (UNGE_EXPR, op0, op1, p);
1201 21313 : build_and_record_new_cond (UNEQ_EXPR, op0, op1, p);
1202 21313 : build_and_record_new_cond (UNLT_EXPR, op0, op1, p);
1203 21313 : build_and_record_new_cond (UNGT_EXPR, op0, op1, p);
1204 21313 : break;
1205 :
1206 13305 : case UNLT_EXPR:
1207 13305 : case UNGT_EXPR:
1208 22721 : build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR
1209 : ? UNLE_EXPR : UNGE_EXPR),
1210 : op0, op1, p);
1211 13305 : build_and_record_new_cond (NE_EXPR, op0, op1, p);
1212 13305 : 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 32444942 : initialize_expr_from_cond (cond, &c.cond);
1231 32444942 : c.value = boolean_true_node;
1232 32444942 : 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 32444942 : initialize_expr_from_cond (inverted, &c.cond);
1240 32444942 : c.value = boolean_false_node;
1241 32444942 : p->safe_push (c);
1242 : }
|