Branch data Line data Source code
1 : : /* Preamble and helpers for the autogenerated generic-match.cc file.
2 : : Copyright (C) 2014-2024 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify it under
7 : : the terms of the GNU General Public License as published by the Free
8 : : Software Foundation; either version 3, or (at your option) any later
9 : : version.
10 : :
11 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : #include "config.h"
21 : : #include "system.h"
22 : : #include "coretypes.h"
23 : : #include "backend.h"
24 : : #include "target.h"
25 : : #include "rtl.h"
26 : : #include "tree.h"
27 : : #include "gimple.h"
28 : : #include "ssa.h"
29 : : #include "cgraph.h"
30 : : #include "vec-perm-indices.h"
31 : : #include "fold-const.h"
32 : : #include "fold-const-call.h"
33 : : #include "stor-layout.h"
34 : : #include "tree-dfa.h"
35 : : #include "builtins.h"
36 : : #include "case-cfn-macros.h"
37 : : #include "gimplify.h"
38 : : #include "optabs-tree.h"
39 : : #include "dbgcnt.h"
40 : : #include "tm.h"
41 : : #include "tree-eh.h"
42 : : #include "langhooks.h"
43 : : #include "tree-pass.h"
44 : : #include "attribs.h"
45 : : #include "asan.h"
46 : :
47 : : /* Routine to determine if the types T1 and T2 are effectively
48 : : the same for GENERIC. If T1 or T2 is not a type, the test
49 : : applies to their TREE_TYPE. */
50 : :
51 : : static inline bool
52 : 28673877 : types_match (tree t1, tree t2)
53 : : {
54 : 28673877 : if (!TYPE_P (t1))
55 : 5374303 : t1 = TREE_TYPE (t1);
56 : 28673877 : if (!TYPE_P (t2))
57 : 5112207 : t2 = TREE_TYPE (t2);
58 : :
59 : 28673877 : return TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2);
60 : : }
61 : :
62 : : /* Return if T has a single use. For GENERIC, we assume this is
63 : : always true. */
64 : :
65 : : static inline bool
66 : : single_use (tree t ATTRIBUTE_UNUSED)
67 : : {
68 : : return true;
69 : : }
70 : :
71 : : /* Return true if math operations should be canonicalized,
72 : : e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
73 : :
74 : : static inline bool
75 : 1938 : canonicalize_math_p ()
76 : : {
77 : 1938 : return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
78 : : }
79 : :
80 : : /* Return true if math operations that are beneficial only after
81 : : vectorization should be canonicalized. */
82 : :
83 : : static inline bool
84 : : canonicalize_math_after_vectorization_p ()
85 : : {
86 : : return false;
87 : : }
88 : :
89 : : /* Return true if we can still perform transformations that may introduce
90 : : vector operations that are not supported by the target. Vector lowering
91 : : normally handles those, but after that pass, it becomes unsafe. */
92 : :
93 : : static inline bool
94 : 13199 : optimize_vectors_before_lowering_p ()
95 : : {
96 : 13199 : return !cfun || (cfun->curr_properties & PROP_gimple_lvec) == 0;
97 : : }
98 : :
99 : : /* Return true if successive divisions can be optimized.
100 : : Defer to GIMPLE opts. */
101 : :
102 : : static inline bool
103 : : optimize_successive_divisions_p (tree, tree)
104 : : {
105 : : return false;
106 : : }
107 : :
108 : : /* Return true if EXPR1 and EXPR2 have the same value, but not necessarily
109 : : same type. The types can differ through nop conversions. */
110 : :
111 : : static inline bool
112 : 356961 : bitwise_equal_p (tree expr1, tree expr2)
113 : : {
114 : 356961 : STRIP_NOPS (expr1);
115 : 356961 : STRIP_NOPS (expr2);
116 : 356961 : if (expr1 == expr2)
117 : : return true;
118 : 330635 : if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2)))
119 : : return false;
120 : 170467 : if (TREE_CODE (expr1) == INTEGER_CST && TREE_CODE (expr2) == INTEGER_CST)
121 : 0 : return wi::to_wide (expr1) == wi::to_wide (expr2);
122 : 170467 : return operand_equal_p (expr1, expr2, 0);
123 : : }
124 : :
125 : : /* Return true if EXPR1 and EXPR2 have the bitwise opposite value,
126 : : but not necessarily same type.
127 : : The types can differ through nop conversions. */
128 : :
129 : : static inline bool
130 : 10094560 : bitwise_inverted_equal_p (tree expr1, tree expr2, bool &wascmp)
131 : : {
132 : 10094560 : STRIP_NOPS (expr1);
133 : 10094560 : STRIP_NOPS (expr2);
134 : 10094560 : wascmp = false;
135 : 10094560 : if (expr1 == expr2)
136 : : return false;
137 : 10093968 : if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2)))
138 : : return false;
139 : 10093968 : if (TREE_CODE (expr1) == INTEGER_CST && TREE_CODE (expr2) == INTEGER_CST)
140 : 79582 : return wi::to_wide (expr1) == ~wi::to_wide (expr2);
141 : 10014386 : if (operand_equal_p (expr1, expr2, 0))
142 : : return false;
143 : 10014210 : if (TREE_CODE (expr1) == BIT_NOT_EXPR
144 : 10014210 : && bitwise_equal_p (TREE_OPERAND (expr1, 0), expr2))
145 : : return true;
146 : 10013985 : if (TREE_CODE (expr2) == BIT_NOT_EXPR
147 : 10013985 : && bitwise_equal_p (expr1, TREE_OPERAND (expr2, 0)))
148 : : return true;
149 : 10013713 : if (COMPARISON_CLASS_P (expr1)
150 : 5048 : && COMPARISON_CLASS_P (expr2))
151 : : {
152 : 1503 : tree op10 = TREE_OPERAND (expr1, 0);
153 : 1503 : tree op20 = TREE_OPERAND (expr2, 0);
154 : 1503 : wascmp = true;
155 : 1503 : if (!operand_equal_p (op10, op20))
156 : : return false;
157 : 581 : tree op11 = TREE_OPERAND (expr1, 1);
158 : 581 : tree op21 = TREE_OPERAND (expr2, 1);
159 : 581 : if (!operand_equal_p (op11, op21))
160 : : return false;
161 : 28 : if (invert_tree_comparison (TREE_CODE (expr1),
162 : 28 : HONOR_NANS (op10))
163 : 28 : == TREE_CODE (expr2))
164 : : return true;
165 : : }
166 : : return false;
167 : : }
|