Line data Source code
1 : /* Preamble and helpers for the autogenerated generic-match.cc file.
2 : Copyright (C) 2014-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 "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 "memmodel.h"
39 : #include "optabs.h"
40 : #include "optabs-tree.h"
41 : #include "dbgcnt.h"
42 : #include "tm.h"
43 : #include "tree-eh.h"
44 : #include "langhooks.h"
45 : #include "tree-pass.h"
46 : #include "attribs.h"
47 : #include "asan.h"
48 : #include "gimple-iterator.h"
49 : #include "gimple-fold.h"
50 :
51 : /* Routine to determine if the types T1 and T2 are effectively
52 : the same for GENERIC. If T1 or T2 is not a type, the test
53 : applies to their TREE_TYPE. */
54 :
55 : static inline bool
56 89568366 : types_match (tree t1, tree t2)
57 : {
58 89568366 : if (!TYPE_P (t1))
59 6656691 : t1 = TREE_TYPE (t1);
60 89568366 : if (!TYPE_P (t2))
61 6295175 : t2 = TREE_TYPE (t2);
62 :
63 89568366 : return TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2);
64 : }
65 :
66 : /* Routine to determine if the types T1, T2 and T3 are effectively
67 : the same for GENERIC. If T1, T2 or T2 is not a type, the test
68 : applies to their TREE_TYPE. */
69 :
70 : static inline bool
71 : types_match (tree t1, tree t2, tree t3)
72 : {
73 : return types_match (t1, t2) && types_match (t2, t3);
74 : }
75 :
76 : /* Return if T has a single use. For GENERIC, we assume this is
77 : always true. */
78 :
79 : static inline bool
80 : single_use (tree t ATTRIBUTE_UNUSED)
81 : {
82 : return true;
83 : }
84 :
85 : /* Return true if math operations should be canonicalized,
86 : e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
87 :
88 : static inline bool
89 100 : canonicalize_math_p ()
90 : {
91 100 : return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
92 : }
93 :
94 : /* Return true if math operations that are beneficial only after
95 : vectorization should be canonicalized. */
96 :
97 : static inline bool
98 : canonicalize_math_after_vectorization_p ()
99 : {
100 : return false;
101 : }
102 :
103 : /* Return true if we can still perform transformations that may introduce
104 : vector operations that are not supported by the target. Vector lowering
105 : normally handles those, but after that pass, it becomes unsafe. */
106 :
107 : static inline bool
108 2472 : optimize_vectors_before_lowering_p ()
109 : {
110 2472 : return !cfun || (cfun->curr_properties & PROP_gimple_lvec) == 0;
111 : }
112 :
113 : /* Return true if successive divisions can be optimized.
114 : Defer to GIMPLE opts. */
115 :
116 : static inline bool
117 : optimize_successive_divisions_p (tree, tree)
118 : {
119 : return false;
120 : }
121 :
122 : /* Returns true if the expression T has no side effects
123 : including not trapping. */
124 : static inline bool
125 141 : expr_no_side_effects_p (tree t)
126 : {
127 141 : if (TREE_SIDE_EFFECTS (t))
128 : return false;
129 141 : if (generic_expr_could_trap_p (t))
130 : return false;
131 : return true;
132 : }
133 :
134 : /* Return true if EXPR1 and EXPR2 have the same value, but not necessarily
135 : same type. The types can differ through nop conversions. */
136 :
137 : static inline bool
138 553645 : bitwise_equal_p (tree expr1, tree expr2)
139 : {
140 553645 : STRIP_NOPS (expr1);
141 553645 : STRIP_NOPS (expr2);
142 553645 : if (expr1 == expr2)
143 : return true;
144 522428 : if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2)))
145 : return false;
146 300200 : if (TREE_CODE (expr1) == INTEGER_CST && TREE_CODE (expr2) == INTEGER_CST)
147 0 : return wi::to_wide (expr1) == wi::to_wide (expr2);
148 300200 : return operand_equal_p (expr1, expr2, 0);
149 : }
150 :
151 : /* Return true if EXPR1 and EXPR2 have the bitwise opposite value,
152 : but not necessarily same type.
153 : The types can differ through nop conversions. */
154 :
155 : static inline bool
156 62569354 : bitwise_inverted_equal_p (tree expr1, tree expr2, bool &wascmp)
157 : {
158 62569354 : STRIP_NOPS (expr1);
159 62569354 : STRIP_NOPS (expr2);
160 62569354 : wascmp = false;
161 62569354 : if (expr1 == expr2)
162 : return false;
163 62568915 : if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2)))
164 : return false;
165 62568915 : tree cst1 = uniform_integer_cst_p (expr1);
166 62568915 : tree cst2 = uniform_integer_cst_p (expr2);
167 62568915 : if (cst1 && cst2)
168 277225 : return wi::to_wide (cst1) == ~wi::to_wide (cst2);
169 62291690 : if (operand_equal_p (expr1, expr2, 0))
170 : return false;
171 62291523 : if (TREE_CODE (expr1) == BIT_NOT_EXPR
172 62291523 : && bitwise_equal_p (TREE_OPERAND (expr1, 0), expr2))
173 : return true;
174 62291431 : if (TREE_CODE (expr2) == BIT_NOT_EXPR
175 62291431 : && bitwise_equal_p (expr1, TREE_OPERAND (expr2, 0)))
176 : return true;
177 :
178 : /* `X ^ CST` and `X ^ ~CST` match for ~. */
179 98535 : if (TREE_CODE (expr1) == BIT_XOR_EXPR && TREE_CODE (expr2) == BIT_XOR_EXPR
180 62291877 : && bitwise_equal_p (TREE_OPERAND (expr1, 0), TREE_OPERAND (expr2, 0)))
181 : {
182 9 : tree cst1 = uniform_integer_cst_p (TREE_OPERAND (expr1, 1));
183 9 : tree cst2 = uniform_integer_cst_p (TREE_OPERAND (expr2, 1));
184 16 : if (cst1 && cst2 && wi::to_wide (cst1) == ~wi::to_wide (cst2))
185 : return true;
186 : }
187 62291009 : if (COMPARISON_CLASS_P (expr1)
188 394360 : && COMPARISON_CLASS_P (expr2))
189 : {
190 149606 : tree op10 = TREE_OPERAND (expr1, 0);
191 149606 : tree op20 = TREE_OPERAND (expr2, 0);
192 149606 : wascmp = true;
193 149606 : if (!operand_equal_p (op10, op20))
194 : return false;
195 3944 : tree op11 = TREE_OPERAND (expr1, 1);
196 3944 : tree op21 = TREE_OPERAND (expr2, 1);
197 3944 : if (!operand_equal_p (op11, op21))
198 : return false;
199 1152 : if (invert_tree_comparison (TREE_CODE (expr1),
200 1152 : HONOR_NANS (op10))
201 1152 : == TREE_CODE (expr2))
202 : return true;
203 : }
204 : return false;
205 : }
206 :
207 : static inline gimple *
208 : gimple_match_ctx (tree)
209 : {
210 : return NULL;
211 : }
|