libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / generic-match-head.cc
blob7d7e2a9f792daeeda30e6c7ba35d5542a79d1760
1 /* Preamble and helpers for the autogenerated generic-match.cc file.
2 Copyright (C) 2014-2024 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
9 version.
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.
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/>. */
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"
49 /* Routine to determine if the types T1 and T2 are effectively
50 the same for GENERIC. If T1 or T2 is not a type, the test
51 applies to their TREE_TYPE. */
53 static inline bool
54 types_match (tree t1, tree t2)
56 if (!TYPE_P (t1))
57 t1 = TREE_TYPE (t1);
58 if (!TYPE_P (t2))
59 t2 = TREE_TYPE (t2);
61 return TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2);
64 /* Routine to determine if the types T1, T2 and T3 are effectively
65 the same for GENERIC. If T1, T2 or T2 is not a type, the test
66 applies to their TREE_TYPE. */
68 static inline bool
69 types_match (tree t1, tree t2, tree t3)
71 return types_match (t1, t2) && types_match (t2, t3);
74 /* Return if T has a single use. For GENERIC, we assume this is
75 always true. */
77 static inline bool
78 single_use (tree t ATTRIBUTE_UNUSED)
80 return true;
83 /* Return true if math operations should be canonicalized,
84 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
86 static inline bool
87 canonicalize_math_p ()
89 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
92 /* Return true if math operations that are beneficial only after
93 vectorization should be canonicalized. */
95 static inline bool
96 canonicalize_math_after_vectorization_p ()
98 return false;
101 /* Return true if we can still perform transformations that may introduce
102 vector operations that are not supported by the target. Vector lowering
103 normally handles those, but after that pass, it becomes unsafe. */
105 static inline bool
106 optimize_vectors_before_lowering_p ()
108 return !cfun || (cfun->curr_properties & PROP_gimple_lvec) == 0;
111 /* Return true if successive divisions can be optimized.
112 Defer to GIMPLE opts. */
114 static inline bool
115 optimize_successive_divisions_p (tree, tree)
117 return false;
120 /* Returns true if the expression T has no side effects
121 including not trapping. */
122 static inline bool
123 expr_no_side_effects_p (tree t)
125 if (TREE_SIDE_EFFECTS (t))
126 return false;
127 if (generic_expr_could_trap_p (t))
128 return false;
129 return true;
132 /* Return true if EXPR1 and EXPR2 have the same value, but not necessarily
133 same type. The types can differ through nop conversions. */
135 static inline bool
136 bitwise_equal_p (tree expr1, tree expr2)
138 STRIP_NOPS (expr1);
139 STRIP_NOPS (expr2);
140 if (expr1 == expr2)
141 return true;
142 if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2)))
143 return false;
144 if (TREE_CODE (expr1) == INTEGER_CST && TREE_CODE (expr2) == INTEGER_CST)
145 return wi::to_wide (expr1) == wi::to_wide (expr2);
146 return operand_equal_p (expr1, expr2, 0);
149 /* Return true if EXPR1 and EXPR2 have the bitwise opposite value,
150 but not necessarily same type.
151 The types can differ through nop conversions. */
153 static inline bool
154 bitwise_inverted_equal_p (tree expr1, tree expr2, bool &wascmp)
156 STRIP_NOPS (expr1);
157 STRIP_NOPS (expr2);
158 wascmp = false;
159 if (expr1 == expr2)
160 return false;
161 if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2)))
162 return false;
163 tree cst1 = uniform_integer_cst_p (expr1);
164 tree cst2 = uniform_integer_cst_p (expr2);
165 if (cst1 && cst2)
166 return wi::to_wide (cst1) == ~wi::to_wide (cst2);
167 if (operand_equal_p (expr1, expr2, 0))
168 return false;
169 if (TREE_CODE (expr1) == BIT_NOT_EXPR
170 && bitwise_equal_p (TREE_OPERAND (expr1, 0), expr2))
171 return true;
172 if (TREE_CODE (expr2) == BIT_NOT_EXPR
173 && bitwise_equal_p (expr1, TREE_OPERAND (expr2, 0)))
174 return true;
176 /* `X ^ CST` and `X ^ ~CST` match for ~. */
177 if (TREE_CODE (expr1) == BIT_XOR_EXPR && TREE_CODE (expr2) == BIT_XOR_EXPR
178 && bitwise_equal_p (TREE_OPERAND (expr1, 0), TREE_OPERAND (expr2, 0)))
180 tree cst1 = uniform_integer_cst_p (TREE_OPERAND (expr1, 1));
181 tree cst2 = uniform_integer_cst_p (TREE_OPERAND (expr2, 1));
182 if (cst1 && cst2 && wi::to_wide (cst1) == ~wi::to_wide (cst2))
183 return true;
185 if (COMPARISON_CLASS_P (expr1)
186 && COMPARISON_CLASS_P (expr2))
188 tree op10 = TREE_OPERAND (expr1, 0);
189 tree op20 = TREE_OPERAND (expr2, 0);
190 wascmp = true;
191 if (!operand_equal_p (op10, op20))
192 return false;
193 tree op11 = TREE_OPERAND (expr1, 1);
194 tree op21 = TREE_OPERAND (expr2, 1);
195 if (!operand_equal_p (op11, op21))
196 return false;
197 if (invert_tree_comparison (TREE_CODE (expr1),
198 HONOR_NANS (op10))
199 == TREE_CODE (expr2))
200 return true;
202 return false;