1 /* Header file for SSA dominator optimizations.
2 Copyright (C) 2013-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
22 #include "coretypes.h"
24 #include "basic-block.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"
34 #include "internal-fn.h"
38 static bool hashable_expr_equal_p (const struct hashable_expr
*,
39 const struct hashable_expr
*);
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. */
45 /* Pop items off the unwinding stack, removing each from the hash table
46 until a marker is encountered. */
49 avail_exprs_stack::pop_to_marker ()
51 /* Remove all the expressions made available in this block. */
52 while (m_stack
.length () > 0)
54 std::pair
<expr_hash_elt_t
, expr_hash_elt_t
> victim
= m_stack
.pop ();
57 if (victim
.first
== NULL
)
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 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
65 fprintf (dump_file
, "<<<< ");
66 victim
.first
->print (dump_file
);
69 slot
= m_avail_exprs
->find_slot (victim
.first
, NO_INSERT
);
70 gcc_assert (slot
&& *slot
== victim
.first
);
71 if (victim
.second
!= NULL
)
74 *slot
= victim
.second
;
77 m_avail_exprs
->clear_slot (slot
);
81 /* Add <ELT1,ELT2> to the unwinding stack so they can be later removed
82 from the hash table. */
85 avail_exprs_stack::record_expr (class expr_hash_elt
*elt1
,
86 class expr_hash_elt
*elt2
,
89 if (elt1
&& dump_file
&& (dump_flags
& TDF_DETAILS
))
91 fprintf (dump_file
, "%c>>> ", type
);
92 elt1
->print (dump_file
);
95 m_stack
.safe_push (std::pair
<expr_hash_elt_t
, expr_hash_elt_t
> (elt1
, elt2
));
98 /* Helper for walk_non_aliased_vuses. Determine if we arrived at
99 the desired memory state. */
102 vuse_eq (ao_ref
*, tree vuse1
, void *data
)
104 tree vuse2
= (tree
) data
;
111 /* We looked for STMT in the hash table, but did not find it.
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. */
118 avail_exprs_stack::simplify_binary_operation (gimple
*stmt
,
119 class expr_hash_elt element
)
121 if (is_gimple_assign (stmt
))
123 struct hashable_expr
*expr
= element
.expr ();
124 if (expr
->kind
== EXPR_BINARY
)
126 enum tree_code code
= expr
->ops
.binary
.op
;
130 /* For these cases, if we know the operands
131 are equal, then we know the result. */
148 /* Build a simple equality expr and query the hash table
150 struct hashable_expr expr
;
151 expr
.type
= boolean_type_node
;
152 expr
.kind
= EXPR_BINARY
;
153 expr
.ops
.binary
.op
= EQ_EXPR
;
154 expr
.ops
.binary
.opnd0
= gimple_assign_rhs1 (stmt
);
155 expr
.ops
.binary
.opnd1
= gimple_assign_rhs2 (stmt
);
156 class expr_hash_elt
element2 (&expr
, NULL_TREE
);
158 = m_avail_exprs
->find_slot (&element2
, NO_INSERT
);
159 tree result_type
= TREE_TYPE (gimple_assign_lhs (stmt
));
161 /* If the query was successful and returned a nonzero
162 result, then we know that the operands of the binary
163 expression are the same. In many cases this allows
164 us to compute a constant result of the expression
165 at compile time, even if we do not know the exact
166 values of the operands. */
167 if (slot
&& *slot
&& integer_onep ((*slot
)->lhs ()))
175 return gimple_assign_rhs1 (stmt
);
178 /* This is unsafe for certain floats even in non-IEEE
179 formats. In IEEE, it is unsafe because it does
181 if (FLOAT_TYPE_P (result_type
)
182 && HONOR_NANS (result_type
))
190 return build_zero_cst (result_type
);
197 /* Avoid _Fract types where we can't build 1. */
198 if (ALL_FRACT_MODE_P (TYPE_MODE (result_type
)))
200 return build_one_cst (result_type
);
217 /* Search for an existing instance of STMT in the AVAIL_EXPRS_STACK table.
218 If found, return its LHS. Otherwise insert STMT in the table and
221 Also, when an expression is first inserted in the table, it is also
222 is also added to AVAIL_EXPRS_STACK, so that it can be removed when
223 we finish processing this block and its children. */
226 avail_exprs_stack::lookup_avail_expr (gimple
*stmt
, bool insert
, bool tbaa_p
,
229 expr_hash_elt
**slot
;
232 /* Get LHS of phi, assignment, or call; else NULL_TREE. */
233 if (gimple_code (stmt
) == GIMPLE_PHI
)
234 lhs
= gimple_phi_result (stmt
);
236 lhs
= gimple_get_lhs (stmt
);
238 class expr_hash_elt
element (stmt
, lhs
);
240 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
242 fprintf (dump_file
, "LKUP ");
243 element
.print (dump_file
);
246 /* Don't bother remembering constant assignments and copy operations.
247 Constants and copy operations are handled by the constant/copy propagator
249 if (element
.expr()->kind
== EXPR_SINGLE
250 && (TREE_CODE (element
.expr()->ops
.single
.rhs
) == SSA_NAME
251 || is_gimple_min_invariant (element
.expr()->ops
.single
.rhs
)))
254 /* Finally try to find the expression in the main expression hash table. */
255 slot
= m_avail_exprs
->find_slot (&element
, (insert
? INSERT
: NO_INSERT
));
260 else if (*slot
== NULL
)
262 /* We have, in effect, allocated *SLOT for ELEMENT at this point.
263 We must initialize *SLOT to a real entry, even if we found a
264 way to prove ELEMENT was a constant after not finding ELEMENT
267 An uninitialized or empty slot is an indication no prior objects
268 entered into the hash table had a hash collection with ELEMENT.
270 If we fail to do so and had such entries in the table, they
271 would become unreachable. */
272 class expr_hash_elt
*element2
= new expr_hash_elt (element
);
275 /* If we did not find the expression in the hash table, we may still
276 be able to produce a result for some expressions. */
277 tree retval
= avail_exprs_stack::simplify_binary_operation (stmt
,
280 record_expr (element2
, NULL
, '2');
284 /* If we found a redundant memory operation do an alias walk to
285 check if we can re-use it. */
286 if (gimple_vuse (stmt
) != (*slot
)->vop ())
288 tree vuse1
= (*slot
)->vop ();
289 tree vuse2
= gimple_vuse (stmt
);
290 /* If we have a load of a register and a candidate in the
291 hash with vuse1 then try to reach its stmt by walking
292 up the virtual use-def chain using walk_non_aliased_vuses.
293 But don't do this when removing expressions from the hash. */
295 unsigned limit
= param_sccvn_max_alias_queries_per_access
;
297 && gimple_assign_single_p (stmt
)
298 && TREE_CODE (gimple_assign_lhs (stmt
)) == SSA_NAME
299 && (ao_ref_init (&ref
, gimple_assign_rhs1 (stmt
)),
300 ref
.base_alias_set
= ref
.ref_alias_set
= tbaa_p
? -1 : 0, true)
301 && walk_non_aliased_vuses (&ref
, vuse2
, true, vuse_eq
, NULL
, NULL
,
302 limit
, vuse1
) != NULL
))
306 class expr_hash_elt
*element2
= new expr_hash_elt (element
);
308 /* Insert the expr into the hash by replacing the current
309 entry and recording the value to restore in the
310 avail_exprs_stack. */
311 record_expr (element2
, *slot
, '2');
318 /* Extract the LHS of the assignment so that it can be used as the current
319 definition of another variable. */
320 lhs
= (*slot
)->lhs ();
324 /* Valueize the result. */
325 if (TREE_CODE (lhs
) == SSA_NAME
)
327 tree tem
= SSA_NAME_VALUE (lhs
);
332 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
334 fprintf (dump_file
, "FIND: ");
335 print_generic_expr (dump_file
, lhs
);
336 fprintf (dump_file
, "\n");
342 /* Enter condition equivalence P into the hash table.
344 This indicates that a conditional expression has a known
348 avail_exprs_stack::record_cond (cond_equivalence
*p
)
350 class expr_hash_elt
*element
= new expr_hash_elt (&p
->cond
, p
->value
);
351 expr_hash_elt
**slot
;
353 slot
= m_avail_exprs
->find_slot_with_hash (element
, element
->hash (), INSERT
);
357 record_expr (element
, NULL
, '1');
363 /* Generate a hash value for a pair of expressions. This can be used
364 iteratively by passing a previous result in HSTATE.
366 The same hash value is always returned for a given pair of expressions,
367 regardless of the order in which they are presented. This is useful in
368 hashing the operands of commutative functions. */
374 add_expr_commutative (const_tree t1
, const_tree t2
, hash
&hstate
)
378 inchash::add_expr (t1
, one
);
379 inchash::add_expr (t2
, two
);
380 hstate
.add_commutative (one
, two
);
383 /* Compute a hash value for a hashable_expr value EXPR and a
384 previously accumulated hash value VAL. If two hashable_expr
385 values compare equal with hashable_expr_equal_p, they must
386 hash to the same value, given an identical value of VAL.
387 The logic is intended to follow inchash::add_expr in tree.cc. */
390 add_hashable_expr (const struct hashable_expr
*expr
, hash
&hstate
)
395 inchash::add_expr (expr
->ops
.single
.rhs
, hstate
);
399 hstate
.add_object (expr
->ops
.unary
.op
);
401 /* Make sure to include signedness in the hash computation.
402 Don't hash the type, that can lead to having nodes which
403 compare equal according to operand_equal_p, but which
404 have different hash codes. */
405 if (CONVERT_EXPR_CODE_P (expr
->ops
.unary
.op
)
406 || expr
->ops
.unary
.op
== NON_LVALUE_EXPR
)
407 hstate
.add_int (TYPE_UNSIGNED (expr
->type
));
409 inchash::add_expr (expr
->ops
.unary
.opnd
, hstate
);
413 hstate
.add_object (expr
->ops
.binary
.op
);
414 if (commutative_tree_code (expr
->ops
.binary
.op
))
415 inchash::add_expr_commutative (expr
->ops
.binary
.opnd0
,
416 expr
->ops
.binary
.opnd1
, hstate
);
419 inchash::add_expr (expr
->ops
.binary
.opnd0
, hstate
);
420 inchash::add_expr (expr
->ops
.binary
.opnd1
, hstate
);
425 hstate
.add_object (expr
->ops
.ternary
.op
);
426 if (commutative_ternary_tree_code (expr
->ops
.ternary
.op
))
427 inchash::add_expr_commutative (expr
->ops
.ternary
.opnd0
,
428 expr
->ops
.ternary
.opnd1
, hstate
);
431 inchash::add_expr (expr
->ops
.ternary
.opnd0
, hstate
);
432 inchash::add_expr (expr
->ops
.ternary
.opnd1
, hstate
);
434 inchash::add_expr (expr
->ops
.ternary
.opnd2
, hstate
);
440 enum tree_code code
= CALL_EXPR
;
443 hstate
.add_object (code
);
444 fn_from
= expr
->ops
.call
.fn_from
;
445 if (gimple_call_internal_p (fn_from
))
446 hstate
.merge_hash ((hashval_t
) gimple_call_internal_fn (fn_from
));
448 inchash::add_expr (gimple_call_fn (fn_from
), hstate
);
449 for (i
= 0; i
< expr
->ops
.call
.nargs
; i
++)
450 inchash::add_expr (expr
->ops
.call
.args
[i
], hstate
);
458 for (i
= 0; i
< expr
->ops
.phi
.nargs
; i
++)
459 inchash::add_expr (expr
->ops
.phi
.args
[i
], hstate
);
470 /* Hashing and equality functions. We compute a value number for expressions
471 using the code of the expression and the SSA numbers of its operands. */
474 avail_expr_hash (class expr_hash_elt
*p
)
476 const struct hashable_expr
*expr
= p
->expr ();
477 inchash::hash hstate
;
479 if (expr
->kind
== EXPR_SINGLE
)
481 /* T could potentially be a switch index or a goto dest. */
482 tree t
= expr
->ops
.single
.rhs
;
483 if (TREE_CODE (t
) == MEM_REF
|| handled_component_p (t
))
485 /* Make equivalent statements of both these kinds hash together.
486 Dealing with both MEM_REF and ARRAY_REF allows us not to care
487 about equivalence with other statements not considered here. */
489 poly_int64 offset
, size
, max_size
;
490 tree base
= get_ref_base_and_extent (t
, &offset
, &size
, &max_size
,
492 /* Strictly, we could try to normalize variable-sized accesses too,
493 but here we just deal with the common case. */
494 if (known_size_p (max_size
)
495 && known_eq (size
, max_size
))
497 enum tree_code code
= MEM_REF
;
498 hstate
.add_object (code
);
499 inchash::add_expr (base
, hstate
,
500 TREE_CODE (base
) == MEM_REF
501 ? OEP_ADDRESS_OF
: 0);
502 hstate
.add_object (offset
);
503 hstate
.add_object (size
);
504 return hstate
.end ();
509 inchash::add_hashable_expr (expr
, hstate
);
511 return hstate
.end ();
514 /* Compares trees T0 and T1 to see if they are MEM_REF or ARRAY_REFs equivalent
515 to each other. (That is, they return the value of the same bit of memory.)
517 Return TRUE if the two are so equivalent; FALSE if not (which could still
518 mean the two are equivalent by other means). */
521 equal_mem_array_ref_p (tree t0
, tree t1
)
523 if (TREE_CODE (t0
) != MEM_REF
&& ! handled_component_p (t0
))
525 if (TREE_CODE (t1
) != MEM_REF
&& ! handled_component_p (t1
))
528 if (!types_compatible_p (TREE_TYPE (t0
), TREE_TYPE (t1
)))
531 poly_int64 off0
, sz0
, max0
;
532 tree base0
= get_ref_base_and_extent (t0
, &off0
, &sz0
, &max0
, &rev0
);
533 if (!known_size_p (max0
)
534 || maybe_ne (sz0
, max0
))
538 poly_int64 off1
, sz1
, max1
;
539 tree base1
= get_ref_base_and_extent (t1
, &off1
, &sz1
, &max1
, &rev1
);
540 if (!known_size_p (max1
)
541 || maybe_ne (sz1
, max1
))
544 if (rev0
!= rev1
|| maybe_ne (sz0
, sz1
) || maybe_ne (off0
, off1
))
547 return operand_equal_p (base0
, base1
,
548 (TREE_CODE (base0
) == MEM_REF
549 || TREE_CODE (base0
) == TARGET_MEM_REF
)
550 && (TREE_CODE (base1
) == MEM_REF
551 || TREE_CODE (base1
) == TARGET_MEM_REF
)
552 ? OEP_ADDRESS_OF
: 0);
555 /* Compare two hashable_expr structures for equivalence. They are
556 considered equivalent when the expressions they denote must
557 necessarily be equal. The logic is intended to follow that of
558 operand_equal_p in fold-const.cc */
561 hashable_expr_equal_p (const struct hashable_expr
*expr0
,
562 const struct hashable_expr
*expr1
)
564 tree type0
= expr0
->type
;
565 tree type1
= expr1
->type
;
567 /* If either type is NULL, there is nothing to check. */
568 if ((type0
== NULL_TREE
) ^ (type1
== NULL_TREE
))
571 /* If both types don't have the same signedness, precision, and mode,
572 then we can't consider them equal. */
574 && (TREE_CODE (type0
) == ERROR_MARK
575 || TREE_CODE (type1
) == ERROR_MARK
576 || TYPE_UNSIGNED (type0
) != TYPE_UNSIGNED (type1
)
577 || TYPE_PRECISION (type0
) != TYPE_PRECISION (type1
)
578 || TYPE_MODE (type0
) != TYPE_MODE (type1
)))
581 if (expr0
->kind
!= expr1
->kind
)
587 return equal_mem_array_ref_p (expr0
->ops
.single
.rhs
,
588 expr1
->ops
.single
.rhs
)
589 || operand_equal_p (expr0
->ops
.single
.rhs
,
590 expr1
->ops
.single
.rhs
, 0);
592 if (expr0
->ops
.unary
.op
!= expr1
->ops
.unary
.op
)
595 if ((CONVERT_EXPR_CODE_P (expr0
->ops
.unary
.op
)
596 || expr0
->ops
.unary
.op
== NON_LVALUE_EXPR
)
597 && TYPE_UNSIGNED (expr0
->type
) != TYPE_UNSIGNED (expr1
->type
))
600 return operand_equal_p (expr0
->ops
.unary
.opnd
,
601 expr1
->ops
.unary
.opnd
, 0);
604 if (expr0
->ops
.binary
.op
!= expr1
->ops
.binary
.op
)
607 if (operand_equal_p (expr0
->ops
.binary
.opnd0
,
608 expr1
->ops
.binary
.opnd0
, 0)
609 && operand_equal_p (expr0
->ops
.binary
.opnd1
,
610 expr1
->ops
.binary
.opnd1
, 0))
613 /* For commutative ops, allow the other order. */
614 return (commutative_tree_code (expr0
->ops
.binary
.op
)
615 && operand_equal_p (expr0
->ops
.binary
.opnd0
,
616 expr1
->ops
.binary
.opnd1
, 0)
617 && operand_equal_p (expr0
->ops
.binary
.opnd1
,
618 expr1
->ops
.binary
.opnd0
, 0));
621 if (expr0
->ops
.ternary
.op
!= expr1
->ops
.ternary
.op
622 || !operand_equal_p (expr0
->ops
.ternary
.opnd2
,
623 expr1
->ops
.ternary
.opnd2
, 0))
626 /* BIT_INSERT_EXPR has an implict operand as the type precision
627 of op1. Need to check to make sure they are the same. */
628 if (expr0
->ops
.ternary
.op
== BIT_INSERT_EXPR
629 && TREE_CODE (expr0
->ops
.ternary
.opnd1
) == INTEGER_CST
630 && TREE_CODE (expr1
->ops
.ternary
.opnd1
) == INTEGER_CST
631 && TYPE_PRECISION (TREE_TYPE (expr0
->ops
.ternary
.opnd1
))
632 != TYPE_PRECISION (TREE_TYPE (expr1
->ops
.ternary
.opnd1
)))
635 if (operand_equal_p (expr0
->ops
.ternary
.opnd0
,
636 expr1
->ops
.ternary
.opnd0
, 0)
637 && operand_equal_p (expr0
->ops
.ternary
.opnd1
,
638 expr1
->ops
.ternary
.opnd1
, 0))
641 /* For commutative ops, allow the other order. */
642 return (commutative_ternary_tree_code (expr0
->ops
.ternary
.op
)
643 && operand_equal_p (expr0
->ops
.ternary
.opnd0
,
644 expr1
->ops
.ternary
.opnd1
, 0)
645 && operand_equal_p (expr0
->ops
.ternary
.opnd1
,
646 expr1
->ops
.ternary
.opnd0
, 0));
652 /* If the calls are to different functions, then they
653 clearly cannot be equal. */
654 if (!gimple_call_same_target_p (expr0
->ops
.call
.fn_from
,
655 expr1
->ops
.call
.fn_from
))
658 if (! expr0
->ops
.call
.pure
)
661 if (expr0
->ops
.call
.nargs
!= expr1
->ops
.call
.nargs
)
664 for (i
= 0; i
< expr0
->ops
.call
.nargs
; i
++)
665 if (! operand_equal_p (expr0
->ops
.call
.args
[i
],
666 expr1
->ops
.call
.args
[i
], 0))
669 if (stmt_could_throw_p (cfun
, expr0
->ops
.call
.fn_from
))
671 int lp0
= lookup_stmt_eh_lp (expr0
->ops
.call
.fn_from
);
672 int lp1
= lookup_stmt_eh_lp (expr1
->ops
.call
.fn_from
);
673 if ((lp0
> 0 || lp1
> 0) && lp0
!= lp1
)
684 if (expr0
->ops
.phi
.nargs
!= expr1
->ops
.phi
.nargs
)
687 for (i
= 0; i
< expr0
->ops
.phi
.nargs
; i
++)
688 if (! operand_equal_p (expr0
->ops
.phi
.args
[i
],
689 expr1
->ops
.phi
.args
[i
], 0))
700 /* Given a statement STMT, construct a hash table element. */
702 expr_hash_elt::expr_hash_elt (gimple
*stmt
, tree orig_lhs
)
704 enum gimple_code code
= gimple_code (stmt
);
705 struct hashable_expr
*expr
= this->expr ();
707 if (code
== GIMPLE_ASSIGN
)
709 enum tree_code subcode
= gimple_assign_rhs_code (stmt
);
711 switch (get_gimple_rhs_class (subcode
))
713 case GIMPLE_SINGLE_RHS
:
714 expr
->kind
= EXPR_SINGLE
;
715 expr
->type
= TREE_TYPE (gimple_assign_rhs1 (stmt
));
716 expr
->ops
.single
.rhs
= gimple_assign_rhs1 (stmt
);
718 case GIMPLE_UNARY_RHS
:
719 expr
->kind
= EXPR_UNARY
;
720 expr
->type
= TREE_TYPE (gimple_assign_lhs (stmt
));
721 if (CONVERT_EXPR_CODE_P (subcode
))
723 expr
->ops
.unary
.op
= subcode
;
724 expr
->ops
.unary
.opnd
= gimple_assign_rhs1 (stmt
);
726 case GIMPLE_BINARY_RHS
:
727 expr
->kind
= EXPR_BINARY
;
728 expr
->type
= TREE_TYPE (gimple_assign_lhs (stmt
));
729 expr
->ops
.binary
.op
= subcode
;
730 expr
->ops
.binary
.opnd0
= gimple_assign_rhs1 (stmt
);
731 expr
->ops
.binary
.opnd1
= gimple_assign_rhs2 (stmt
);
733 case GIMPLE_TERNARY_RHS
:
734 expr
->kind
= EXPR_TERNARY
;
735 expr
->type
= TREE_TYPE (gimple_assign_lhs (stmt
));
736 expr
->ops
.ternary
.op
= subcode
;
737 expr
->ops
.ternary
.opnd0
= gimple_assign_rhs1 (stmt
);
738 expr
->ops
.ternary
.opnd1
= gimple_assign_rhs2 (stmt
);
739 expr
->ops
.ternary
.opnd2
= gimple_assign_rhs3 (stmt
);
745 else if (code
== GIMPLE_COND
)
747 expr
->type
= boolean_type_node
;
748 expr
->kind
= EXPR_BINARY
;
749 expr
->ops
.binary
.op
= gimple_cond_code (stmt
);
750 expr
->ops
.binary
.opnd0
= gimple_cond_lhs (stmt
);
751 expr
->ops
.binary
.opnd1
= gimple_cond_rhs (stmt
);
753 else if (gcall
*call_stmt
= dyn_cast
<gcall
*> (stmt
))
755 size_t nargs
= gimple_call_num_args (call_stmt
);
758 gcc_assert (gimple_call_lhs (call_stmt
));
760 expr
->type
= TREE_TYPE (gimple_call_lhs (call_stmt
));
761 expr
->kind
= EXPR_CALL
;
762 expr
->ops
.call
.fn_from
= call_stmt
;
764 if (gimple_call_flags (call_stmt
) & (ECF_CONST
| ECF_PURE
))
765 expr
->ops
.call
.pure
= true;
767 expr
->ops
.call
.pure
= false;
769 expr
->ops
.call
.nargs
= nargs
;
770 expr
->ops
.call
.args
= XCNEWVEC (tree
, nargs
);
771 for (i
= 0; i
< nargs
; i
++)
772 expr
->ops
.call
.args
[i
] = gimple_call_arg (call_stmt
, i
);
774 else if (gswitch
*swtch_stmt
= dyn_cast
<gswitch
*> (stmt
))
776 expr
->type
= TREE_TYPE (gimple_switch_index (swtch_stmt
));
777 expr
->kind
= EXPR_SINGLE
;
778 expr
->ops
.single
.rhs
= gimple_switch_index (swtch_stmt
);
780 else if (code
== GIMPLE_GOTO
)
782 expr
->type
= TREE_TYPE (gimple_goto_dest (stmt
));
783 expr
->kind
= EXPR_SINGLE
;
784 expr
->ops
.single
.rhs
= gimple_goto_dest (stmt
);
786 else if (code
== GIMPLE_PHI
)
788 size_t nargs
= gimple_phi_num_args (stmt
);
791 expr
->type
= TREE_TYPE (gimple_phi_result (stmt
));
792 expr
->kind
= EXPR_PHI
;
793 expr
->ops
.phi
.nargs
= nargs
;
794 expr
->ops
.phi
.args
= XCNEWVEC (tree
, nargs
);
795 for (i
= 0; i
< nargs
; i
++)
796 expr
->ops
.phi
.args
[i
] = gimple_phi_arg_def (stmt
, i
);
802 m_vop
= gimple_vuse (stmt
);
803 m_hash
= avail_expr_hash (this);
807 /* Given a hashable_expr expression ORIG and an ORIG_LHS,
808 construct a hash table element. */
810 expr_hash_elt::expr_hash_elt (struct hashable_expr
*orig
, tree orig_lhs
)
815 m_hash
= avail_expr_hash (this);
819 /* Copy constructor for a hash table element. */
821 expr_hash_elt::expr_hash_elt (class expr_hash_elt
&old_elt
)
823 m_expr
= old_elt
.m_expr
;
824 m_lhs
= old_elt
.m_lhs
;
825 m_vop
= old_elt
.m_vop
;
826 m_hash
= old_elt
.m_hash
;
829 /* Now deep copy the malloc'd space for CALL and PHI args. */
830 if (old_elt
.m_expr
.kind
== EXPR_CALL
)
832 size_t nargs
= old_elt
.m_expr
.ops
.call
.nargs
;
835 m_expr
.ops
.call
.args
= XCNEWVEC (tree
, nargs
);
836 for (i
= 0; i
< nargs
; i
++)
837 m_expr
.ops
.call
.args
[i
] = old_elt
.m_expr
.ops
.call
.args
[i
];
839 else if (old_elt
.m_expr
.kind
== EXPR_PHI
)
841 size_t nargs
= old_elt
.m_expr
.ops
.phi
.nargs
;
844 m_expr
.ops
.phi
.args
= XCNEWVEC (tree
, nargs
);
845 for (i
= 0; i
< nargs
; i
++)
846 m_expr
.ops
.phi
.args
[i
] = old_elt
.m_expr
.ops
.phi
.args
[i
];
850 /* Calls and PHIs have a variable number of arguments that are allocated
851 on the heap. Thus we have to have a special dtor to release them. */
853 expr_hash_elt::~expr_hash_elt ()
855 if (m_expr
.kind
== EXPR_CALL
)
856 free (m_expr
.ops
.call
.args
);
857 else if (m_expr
.kind
== EXPR_PHI
)
858 free (m_expr
.ops
.phi
.args
);
861 /* Print a diagnostic dump of an expression hash table entry. */
864 expr_hash_elt::print (FILE *stream
)
866 fprintf (stream
, "STMT ");
870 print_generic_expr (stream
, m_lhs
);
871 fprintf (stream
, " = ");
877 print_generic_expr (stream
, m_expr
.ops
.single
.rhs
);
881 fprintf (stream
, "%s ", get_tree_code_name (m_expr
.ops
.unary
.op
));
882 print_generic_expr (stream
, m_expr
.ops
.unary
.opnd
);
886 print_generic_expr (stream
, m_expr
.ops
.binary
.opnd0
);
887 fprintf (stream
, " %s ", get_tree_code_name (m_expr
.ops
.binary
.op
));
888 print_generic_expr (stream
, m_expr
.ops
.binary
.opnd1
);
892 fprintf (stream
, " %s <", get_tree_code_name (m_expr
.ops
.ternary
.op
));
893 print_generic_expr (stream
, m_expr
.ops
.ternary
.opnd0
);
894 fputs (", ", stream
);
895 print_generic_expr (stream
, m_expr
.ops
.ternary
.opnd1
);
896 fputs (", ", stream
);
897 print_generic_expr (stream
, m_expr
.ops
.ternary
.opnd2
);
904 size_t nargs
= m_expr
.ops
.call
.nargs
;
907 fn_from
= m_expr
.ops
.call
.fn_from
;
908 if (gimple_call_internal_p (fn_from
))
909 fprintf (stream
, ".%s",
910 internal_fn_name (gimple_call_internal_fn (fn_from
)));
912 print_generic_expr (stream
, gimple_call_fn (fn_from
));
913 fprintf (stream
, " (");
914 for (i
= 0; i
< nargs
; i
++)
916 print_generic_expr (stream
, m_expr
.ops
.call
.args
[i
]);
918 fprintf (stream
, ", ");
920 fprintf (stream
, ")");
927 size_t nargs
= m_expr
.ops
.phi
.nargs
;
929 fprintf (stream
, "PHI <");
930 for (i
= 0; i
< nargs
; i
++)
932 print_generic_expr (stream
, m_expr
.ops
.phi
.args
[i
]);
934 fprintf (stream
, ", ");
936 fprintf (stream
, ">");
943 fprintf (stream
, " with ");
944 print_generic_expr (stream
, m_vop
);
947 fprintf (stream
, "\n");
950 /* Pop entries off the stack until we hit the NULL marker.
951 For each entry popped, use the SRC/DEST pair to restore
952 SRC to its prior value. */
955 const_and_copies::pop_to_marker (void)
957 while (m_stack
.length () > 0)
959 tree prev_value
, dest
;
961 dest
= m_stack
.pop ();
963 /* A NULL value indicates we should stop unwinding, otherwise
964 pop off the next entry as they're recorded in pairs. */
968 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
970 fprintf (dump_file
, "<<<< COPY ");
971 print_generic_expr (dump_file
, dest
);
972 fprintf (dump_file
, " = ");
973 print_generic_expr (dump_file
, SSA_NAME_VALUE (dest
));
974 fprintf (dump_file
, "\n");
977 prev_value
= m_stack
.pop ();
978 set_ssa_name_value (dest
, prev_value
);
982 /* Record that X has the value Y and that X's previous value is PREV_X.
984 This variant does not follow the value chain for Y. */
987 const_and_copies::record_const_or_copy_raw (tree x
, tree y
, tree prev_x
)
989 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
991 fprintf (dump_file
, "0>>> COPY ");
992 print_generic_expr (dump_file
, x
);
993 fprintf (dump_file
, " = ");
994 print_generic_expr (dump_file
, y
);
995 fprintf (dump_file
, "\n");
998 set_ssa_name_value (x
, y
);
1000 m_stack
.quick_push (prev_x
);
1001 m_stack
.quick_push (x
);
1004 /* Record that X has the value Y. */
1007 const_and_copies::record_const_or_copy (tree x
, tree y
)
1009 record_const_or_copy (x
, y
, SSA_NAME_VALUE (x
));
1012 /* Record that X has the value Y and that X's previous value is PREV_X.
1014 This variant follow's Y value chain. */
1017 const_and_copies::record_const_or_copy (tree x
, tree y
, tree prev_x
)
1019 /* Y may be NULL if we are invalidating entries in the table. */
1020 if (y
&& TREE_CODE (y
) == SSA_NAME
)
1022 tree tmp
= SSA_NAME_VALUE (y
);
1026 record_const_or_copy_raw (x
, y
, prev_x
);
1030 expr_elt_hasher::equal (const value_type
&p1
, const compare_type
&p2
)
1032 const struct hashable_expr
*expr1
= p1
->expr ();
1033 const class expr_hash_elt
*stamp1
= p1
->stamp ();
1034 const struct hashable_expr
*expr2
= p2
->expr ();
1035 const class expr_hash_elt
*stamp2
= p2
->stamp ();
1037 /* This case should apply only when removing entries from the table. */
1038 if (stamp1
== stamp2
)
1041 if (p1
->hash () != p2
->hash ())
1044 /* In case of a collision, both RHS have to be identical and have the
1045 same VUSE operands. */
1046 if (hashable_expr_equal_p (expr1
, expr2
)
1047 && types_compatible_p (expr1
->type
, expr2
->type
))
1053 /* Given a conditional expression COND as a tree, initialize
1054 a hashable_expr expression EXPR. The conditional must be a
1055 comparison or logical negation. A constant or a variable is
1059 initialize_expr_from_cond (tree cond
, struct hashable_expr
*expr
)
1061 expr
->type
= boolean_type_node
;
1063 if (COMPARISON_CLASS_P (cond
))
1065 expr
->kind
= EXPR_BINARY
;
1066 expr
->ops
.binary
.op
= TREE_CODE (cond
);
1067 expr
->ops
.binary
.opnd0
= TREE_OPERAND (cond
, 0);
1068 expr
->ops
.binary
.opnd1
= TREE_OPERAND (cond
, 1);
1070 else if (TREE_CODE (cond
) == TRUTH_NOT_EXPR
)
1072 expr
->kind
= EXPR_UNARY
;
1073 expr
->ops
.unary
.op
= TRUTH_NOT_EXPR
;
1074 expr
->ops
.unary
.opnd
= TREE_OPERAND (cond
, 0);
1080 /* Build a cond_equivalence record indicating that the comparison
1081 CODE holds between operands OP0 and OP1 and push it to **P. */
1084 build_and_record_new_cond (enum tree_code code
,
1086 vec
<cond_equivalence
> *p
,
1090 struct hashable_expr
*cond
= &c
.cond
;
1092 gcc_assert (TREE_CODE_CLASS (code
) == tcc_comparison
);
1094 cond
->type
= boolean_type_node
;
1095 cond
->kind
= EXPR_BINARY
;
1096 cond
->ops
.binary
.op
= code
;
1097 cond
->ops
.binary
.opnd0
= op0
;
1098 cond
->ops
.binary
.opnd1
= op1
;
1100 c
.value
= val
? boolean_true_node
: boolean_false_node
;
1104 /* Record that COND is true and INVERTED is false into the edge information
1105 structure. Also record that any conditions dominated by COND are true
1108 For example, if a < b is true, then a <= b must also be true. */
1111 record_conditions (vec
<cond_equivalence
> *p
, tree cond
, tree inverted
)
1116 if (!COMPARISON_CLASS_P (cond
))
1119 op0
= TREE_OPERAND (cond
, 0);
1120 op1
= TREE_OPERAND (cond
, 1);
1122 switch (TREE_CODE (cond
))
1126 if (FLOAT_TYPE_P (TREE_TYPE (op0
)))
1128 build_and_record_new_cond (ORDERED_EXPR
, op0
, op1
, p
);
1129 build_and_record_new_cond (LTGT_EXPR
, op0
, op1
, p
);
1132 build_and_record_new_cond ((TREE_CODE (cond
) == LT_EXPR
1133 ? LE_EXPR
: GE_EXPR
),
1135 build_and_record_new_cond (NE_EXPR
, op0
, op1
, p
);
1136 build_and_record_new_cond (EQ_EXPR
, op0
, op1
, p
, false);
1141 if (FLOAT_TYPE_P (TREE_TYPE (op0
)))
1143 build_and_record_new_cond (ORDERED_EXPR
, op0
, op1
, p
);
1148 if (FLOAT_TYPE_P (TREE_TYPE (op0
)))
1150 build_and_record_new_cond (ORDERED_EXPR
, op0
, op1
, p
);
1152 build_and_record_new_cond (LE_EXPR
, op0
, op1
, p
);
1153 build_and_record_new_cond (GE_EXPR
, op0
, op1
, p
);
1156 case UNORDERED_EXPR
:
1157 build_and_record_new_cond (NE_EXPR
, op0
, op1
, p
);
1158 build_and_record_new_cond (UNLE_EXPR
, op0
, op1
, p
);
1159 build_and_record_new_cond (UNGE_EXPR
, op0
, op1
, p
);
1160 build_and_record_new_cond (UNEQ_EXPR
, op0
, op1
, p
);
1161 build_and_record_new_cond (UNLT_EXPR
, op0
, op1
, p
);
1162 build_and_record_new_cond (UNGT_EXPR
, op0
, op1
, p
);
1167 build_and_record_new_cond ((TREE_CODE (cond
) == UNLT_EXPR
1168 ? UNLE_EXPR
: UNGE_EXPR
),
1170 build_and_record_new_cond (NE_EXPR
, op0
, op1
, p
);
1174 build_and_record_new_cond (UNLE_EXPR
, op0
, op1
, p
);
1175 build_and_record_new_cond (UNGE_EXPR
, op0
, op1
, p
);
1179 build_and_record_new_cond (NE_EXPR
, op0
, op1
, p
);
1180 build_and_record_new_cond (ORDERED_EXPR
, op0
, op1
, p
);
1187 /* Now store the original true and false conditions into the first
1189 initialize_expr_from_cond (cond
, &c
.cond
);
1190 c
.value
= boolean_true_node
;
1193 /* It is possible for INVERTED to be the negation of a comparison,
1194 and not a valid RHS or GIMPLE_COND condition. This happens because
1195 invert_truthvalue may return such an expression when asked to invert
1196 a floating-point comparison. These comparisons are not assumed to
1197 obey the trichotomy law. */
1198 initialize_expr_from_cond (inverted
, &c
.cond
);
1199 c
.value
= boolean_false_node
;