annotate gcc/doc/match-and-simplify.texi @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1 @c Copyright (C) 2014-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
2 @c Free Software Foundation, Inc.
kono
parents:
diff changeset
3 @c This is part of the GCC manual.
kono
parents:
diff changeset
4 @c For copying conditions, see the file gcc.texi.
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 @node Match and Simplify
kono
parents:
diff changeset
7 @chapter Match and Simplify
kono
parents:
diff changeset
8 @cindex Match and Simplify
kono
parents:
diff changeset
9
kono
parents:
diff changeset
10 The GIMPLE and GENERIC pattern matching project match-and-simplify
kono
parents:
diff changeset
11 tries to address several issues.
kono
parents:
diff changeset
12
kono
parents:
diff changeset
13 @enumerate
kono
parents:
diff changeset
14 @item unify expression simplifications currently spread and duplicated
kono
parents:
diff changeset
15 over separate files like fold-const.c, gimple-fold.c and builtins.c
kono
parents:
diff changeset
16 @item allow for a cheap way to implement building and simplifying
kono
parents:
diff changeset
17 non-trivial GIMPLE expressions, avoiding the need to go through
kono
parents:
diff changeset
18 building and simplifying GENERIC via fold_buildN and then
kono
parents:
diff changeset
19 gimplifying via force_gimple_operand
kono
parents:
diff changeset
20 @end enumerate
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 To address these the project introduces a simple domain specific language
kono
parents:
diff changeset
23 to write expression simplifications from which code targeting GIMPLE
kono
parents:
diff changeset
24 and GENERIC is auto-generated. The GENERIC variant follows the
kono
parents:
diff changeset
25 fold_buildN API while for the GIMPLE variant and to address 2) new
kono
parents:
diff changeset
26 APIs are introduced.
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 @menu
kono
parents:
diff changeset
29 * GIMPLE API::
kono
parents:
diff changeset
30 * The Language::
kono
parents:
diff changeset
31 @end menu
kono
parents:
diff changeset
32
kono
parents:
diff changeset
33 @node GIMPLE API
kono
parents:
diff changeset
34 @section GIMPLE API
kono
parents:
diff changeset
35 @cindex GIMPLE API
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 @deftypefn {GIMPLE function} tree gimple_simplify (enum tree_code, tree, tree, gimple_seq *, tree (*)(tree))
kono
parents:
diff changeset
38 @deftypefnx {GIMPLE function} tree gimple_simplify (enum tree_code, tree, tree, tree, gimple_seq *, tree (*)(tree))
kono
parents:
diff changeset
39 @deftypefnx {GIMPLE function} tree gimple_simplify (enum tree_code, tree, tree, tree, tree, gimple_seq *, tree (*)(tree))
kono
parents:
diff changeset
40 @deftypefnx {GIMPLE function} tree gimple_simplify (enum built_in_function, tree, tree, gimple_seq *, tree (*)(tree))
kono
parents:
diff changeset
41 @deftypefnx {GIMPLE function} tree gimple_simplify (enum built_in_function, tree, tree, tree, gimple_seq *, tree (*)(tree))
kono
parents:
diff changeset
42 @deftypefnx {GIMPLE function} tree gimple_simplify (enum built_in_function, tree, tree, tree, tree, gimple_seq *, tree (*)(tree))
kono
parents:
diff changeset
43 The main GIMPLE API entry to the expression simplifications mimicing
kono
parents:
diff changeset
44 that of the GENERIC fold_@{unary,binary,ternary@} functions.
kono
parents:
diff changeset
45 @end deftypefn
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 thus providing n-ary overloads for operation or function. The
kono
parents:
diff changeset
48 additional arguments are a gimple_seq where built statements are
kono
parents:
diff changeset
49 inserted on (if @code{NULL} then simplifications requiring new statements
kono
parents:
diff changeset
50 are not performed) and a valueization hook that can be used to
kono
parents:
diff changeset
51 tie simplifications to a SSA lattice.
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 In addition to those APIs @code{fold_stmt} is overloaded with
kono
parents:
diff changeset
54 a valueization hook:
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 @deftypefn bool fold_stmt (gimple_stmt_iterator *, tree (*)(tree));
kono
parents:
diff changeset
57 @end deftypefn
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 Ontop of these a @code{fold_buildN}-like API for GIMPLE is introduced:
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 @deftypefn {GIMPLE function} tree gimple_build (gimple_seq *, location_t, enum tree_code, tree, tree, tree (*valueize) (tree) = NULL);
kono
parents:
diff changeset
63 @deftypefnx {GIMPLE function} tree gimple_build (gimple_seq *, location_t, enum tree_code, tree, tree, tree, tree (*valueize) (tree) = NULL);
kono
parents:
diff changeset
64 @deftypefnx {GIMPLE function} tree gimple_build (gimple_seq *, location_t, enum tree_code, tree, tree, tree, tree, tree (*valueize) (tree) = NULL);
kono
parents:
diff changeset
65 @deftypefnx {GIMPLE function} tree gimple_build (gimple_seq *, location_t, enum built_in_function, tree, tree, tree (*valueize) (tree) = NULL);
kono
parents:
diff changeset
66 @deftypefnx {GIMPLE function} tree gimple_build (gimple_seq *, location_t, enum built_in_function, tree, tree, tree, tree (*valueize) (tree) = NULL);
kono
parents:
diff changeset
67 @deftypefnx {GIMPLE function} tree gimple_build (gimple_seq *, location_t, enum built_in_function, tree, tree, tree, tree, tree (*valueize) (tree) = NULL);
kono
parents:
diff changeset
68 @deftypefnx {GIMPLE function} tree gimple_convert (gimple_seq *, location_t, tree, tree);
kono
parents:
diff changeset
69 @end deftypefn
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 which is supposed to replace @code{force_gimple_operand (fold_buildN (...), ...)}
kono
parents:
diff changeset
72 and calls to @code{fold_convert}. Overloads without the @code{location_t}
kono
parents:
diff changeset
73 argument exist. Built statements are inserted on the provided sequence
kono
parents:
diff changeset
74 and simplification is performed using the optional valueization hook.
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 @node The Language
kono
parents:
diff changeset
78 @section The Language
kono
parents:
diff changeset
79 @cindex The Language
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 The language to write expression simplifications in resembles other
kono
parents:
diff changeset
82 domain-specific languages GCC uses. Thus it is lispy. Lets start
kono
parents:
diff changeset
83 with an example from the match.pd file:
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 @smallexample
kono
parents:
diff changeset
86 (simplify
kono
parents:
diff changeset
87 (bit_and @@0 integer_all_onesp)
kono
parents:
diff changeset
88 @@0)
kono
parents:
diff changeset
89 @end smallexample
kono
parents:
diff changeset
90
kono
parents:
diff changeset
91 This example contains all required parts of an expression simplification.
kono
parents:
diff changeset
92 A simplification is wrapped inside a @code{(simplify ...)} expression.
kono
parents:
diff changeset
93 That contains at least two operands - an expression that is matched
kono
parents:
diff changeset
94 with the GIMPLE or GENERIC IL and a replacement expression that is
kono
parents:
diff changeset
95 returned if the match was successful.
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 Expressions have an operator ID, @code{bit_and} in this case. Expressions can
kono
parents:
diff changeset
98 be lower-case tree codes with @code{_expr} stripped off or builtin
kono
parents:
diff changeset
99 function code names in all-caps, like @code{BUILT_IN_SQRT}.
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 @code{@@n} denotes a so-called capture. It captures the operand and lets
kono
parents:
diff changeset
102 you refer to it in other places of the match-and-simplify. In the
kono
parents:
diff changeset
103 above example it is refered to in the replacement expression. Captures
kono
parents:
diff changeset
104 are @code{@@} followed by a number or an identifier.
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 @smallexample
kono
parents:
diff changeset
107 (simplify
kono
parents:
diff changeset
108 (bit_xor @@0 @@0)
kono
parents:
diff changeset
109 @{ build_zero_cst (type); @})
kono
parents:
diff changeset
110 @end smallexample
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 In this example @code{@@0} is mentioned twice which constrains the matched
kono
parents:
diff changeset
113 expression to have two equal operands. Usually matches are constraint
kono
parents:
diff changeset
114 to equal types. If operands may be constants and conversions are involved
kono
parents:
diff changeset
115 matching by value might be preferred in which case use @code{@@@@0} to
kono
parents:
diff changeset
116 denote a by value match and the specific operand you want to refer to
kono
parents:
diff changeset
117 in the result part. This example also introduces
kono
parents:
diff changeset
118 operands written in C code. These can be used in the expression
kono
parents:
diff changeset
119 replacements and are supposed to evaluate to a tree node which has to
kono
parents:
diff changeset
120 be a valid GIMPLE operand (so you cannot generate expressions in C code).
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122 @smallexample
kono
parents:
diff changeset
123 (simplify
kono
parents:
diff changeset
124 (trunc_mod integer_zerop@@0 @@1)
kono
parents:
diff changeset
125 (if (!integer_zerop (@@1))
kono
parents:
diff changeset
126 @@0))
kono
parents:
diff changeset
127 @end smallexample
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 Here @code{@@0} captures the first operand of the trunc_mod expression
kono
parents:
diff changeset
130 which is also predicated with @code{integer_zerop}. Expression operands
kono
parents:
diff changeset
131 may be either expressions, predicates or captures. Captures
kono
parents:
diff changeset
132 can be unconstrained or capture expresions or predicates.
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 This example introduces an optional operand of simplify,
kono
parents:
diff changeset
135 the if-expression. This condition is evaluated after the
kono
parents:
diff changeset
136 expression matched in the IL and is required to evaluate to true
kono
parents:
diff changeset
137 to enable the replacement expression in the second operand
kono
parents:
diff changeset
138 position. The expression operand of the @code{if} is a standard C
kono
parents:
diff changeset
139 expression which may contain references to captures. The @code{if}
kono
parents:
diff changeset
140 has an optional third operand which may contain the replacement
kono
parents:
diff changeset
141 expression that is enabled when the condition evaluates to false.
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 A @code{if} expression can be used to specify a common condition
kono
parents:
diff changeset
144 for multiple simplify patterns, avoiding the need
kono
parents:
diff changeset
145 to repeat that multiple times:
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 @smallexample
kono
parents:
diff changeset
148 (if (!TYPE_SATURATING (type)
kono
parents:
diff changeset
149 && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type))
kono
parents:
diff changeset
150 (simplify
kono
parents:
diff changeset
151 (minus (plus @@0 @@1) @@0)
kono
parents:
diff changeset
152 @@1)
kono
parents:
diff changeset
153 (simplify
kono
parents:
diff changeset
154 (minus (minus @@0 @@1) @@0)
kono
parents:
diff changeset
155 (negate @@1)))
kono
parents:
diff changeset
156 @end smallexample
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 Note that @code{if}s in outer position do not have the optional
kono
parents:
diff changeset
159 else clause but instead have multiple then clauses.
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 Ifs can be nested.
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 There exists a @code{switch} expression which can be used to
kono
parents:
diff changeset
164 chain conditions avoiding nesting @code{if}s too much:
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 @smallexample
kono
parents:
diff changeset
167 (simplify
kono
parents:
diff changeset
168 (simple_comparison @@0 REAL_CST@@1)
kono
parents:
diff changeset
169 (switch
kono
parents:
diff changeset
170 /* a CMP (-0) -> a CMP 0 */
kono
parents:
diff changeset
171 (if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@@1)))
kono
parents:
diff changeset
172 (cmp @@0 @{ build_real (TREE_TYPE (@@1), dconst0); @}))
kono
parents:
diff changeset
173 /* x != NaN is always true, other ops are always false. */
kono
parents:
diff changeset
174 (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@@1))
kono
parents:
diff changeset
175 && ! HONOR_SNANS (@@1))
kono
parents:
diff changeset
176 @{ constant_boolean_node (cmp == NE_EXPR, type); @})))
kono
parents:
diff changeset
177 @end smallexample
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 Is equal to
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 @smallexample
kono
parents:
diff changeset
182 (simplify
kono
parents:
diff changeset
183 (simple_comparison @@0 REAL_CST@@1)
kono
parents:
diff changeset
184 (switch
kono
parents:
diff changeset
185 /* a CMP (-0) -> a CMP 0 */
kono
parents:
diff changeset
186 (if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@@1)))
kono
parents:
diff changeset
187 (cmp @@0 @{ build_real (TREE_TYPE (@@1), dconst0); @})
kono
parents:
diff changeset
188 /* x != NaN is always true, other ops are always false. */
kono
parents:
diff changeset
189 (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@@1))
kono
parents:
diff changeset
190 && ! HONOR_SNANS (@@1))
kono
parents:
diff changeset
191 @{ constant_boolean_node (cmp == NE_EXPR, type); @}))))
kono
parents:
diff changeset
192 @end smallexample
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 which has the second @code{if} in the else operand of the first.
kono
parents:
diff changeset
195 The @code{switch} expression takes @code{if} expressions as
kono
parents:
diff changeset
196 operands (which may not have else clauses) and as a last operand
kono
parents:
diff changeset
197 a replacement expression which should be enabled by default if
kono
parents:
diff changeset
198 no other condition evaluated to true.
kono
parents:
diff changeset
199
kono
parents:
diff changeset
200 Captures can also be used for capturing results of sub-expressions.
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 @smallexample
kono
parents:
diff changeset
203 #if GIMPLE
kono
parents:
diff changeset
204 (simplify
kono
parents:
diff changeset
205 (pointer_plus (addr@@2 @@0) INTEGER_CST_P@@1)
kono
parents:
diff changeset
206 (if (is_gimple_min_invariant (@@2)))
kono
parents:
diff changeset
207 @{
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
208 poly_int64 off;
111
kono
parents:
diff changeset
209 tree base = get_addr_base_and_unit_offset (@@0, &off);
kono
parents:
diff changeset
210 off += tree_to_uhwi (@@1);
kono
parents:
diff changeset
211 /* Now with that we should be able to simply write
kono
parents:
diff changeset
212 (addr (mem_ref (addr @@base) (plus @@off @@1))) */
kono
parents:
diff changeset
213 build1 (ADDR_EXPR, type,
kono
parents:
diff changeset
214 build2 (MEM_REF, TREE_TYPE (TREE_TYPE (@@2)),
kono
parents:
diff changeset
215 build_fold_addr_expr (base),
kono
parents:
diff changeset
216 build_int_cst (ptr_type_node, off)));
kono
parents:
diff changeset
217 @})
kono
parents:
diff changeset
218 #endif
kono
parents:
diff changeset
219 @end smallexample
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221 In the above example, @code{@@2} captures the result of the expression
kono
parents:
diff changeset
222 @code{(addr @@0)}. For outermost expression only its type can be captured,
kono
parents:
diff changeset
223 and the keyword @code{type} is reserved for this purpose. The above
kono
parents:
diff changeset
224 example also gives a way to conditionalize patterns to only apply
kono
parents:
diff changeset
225 to @code{GIMPLE} or @code{GENERIC} by means of using the pre-defined
kono
parents:
diff changeset
226 preprocessor macros @code{GIMPLE} and @code{GENERIC} and using
kono
parents:
diff changeset
227 preprocessor directives.
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 @smallexample
kono
parents:
diff changeset
230 (simplify
kono
parents:
diff changeset
231 (bit_and:c integral_op_p@@0 (bit_ior:c (bit_not @@0) @@1))
kono
parents:
diff changeset
232 (bit_and @@1 @@0))
kono
parents:
diff changeset
233 @end smallexample
kono
parents:
diff changeset
234
kono
parents:
diff changeset
235 Here we introduce flags on match expressions. The flag used
kono
parents:
diff changeset
236 above, @code{c}, denotes that the expression should
kono
parents:
diff changeset
237 be also matched commutated. Thus the above match expression
kono
parents:
diff changeset
238 is really the following four match expressions:
kono
parents:
diff changeset
239
kono
parents:
diff changeset
240 @smallexample
kono
parents:
diff changeset
241 (bit_and integral_op_p@@0 (bit_ior (bit_not @@0) @@1))
kono
parents:
diff changeset
242 (bit_and (bit_ior (bit_not @@0) @@1) integral_op_p@@0)
kono
parents:
diff changeset
243 (bit_and integral_op_p@@0 (bit_ior @@1 (bit_not @@0)))
kono
parents:
diff changeset
244 (bit_and (bit_ior @@1 (bit_not @@0)) integral_op_p@@0)
kono
parents:
diff changeset
245 @end smallexample
kono
parents:
diff changeset
246
kono
parents:
diff changeset
247 Usual canonicalizations you know from GENERIC expressions are
kono
parents:
diff changeset
248 applied before matching, so for example constant operands always
kono
parents:
diff changeset
249 come second in commutative expressions.
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 The second supported flag is @code{s} which tells the code
kono
parents:
diff changeset
252 generator to fail the pattern if the expression marked with
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
253 @code{s} does have more than one use and the simplification
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
254 results in an expression with more than one operator.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
255 For example in
111
kono
parents:
diff changeset
256
kono
parents:
diff changeset
257 @smallexample
kono
parents:
diff changeset
258 (simplify
kono
parents:
diff changeset
259 (pointer_plus (pointer_plus:s @@0 @@1) @@3)
kono
parents:
diff changeset
260 (pointer_plus @@0 (plus @@1 @@3)))
kono
parents:
diff changeset
261 @end smallexample
kono
parents:
diff changeset
262
kono
parents:
diff changeset
263 this avoids the association if @code{(pointer_plus @@0 @@1)} is
kono
parents:
diff changeset
264 used outside of the matched expression and thus it would stay
kono
parents:
diff changeset
265 live and not trivially removed by dead code elimination.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
266 Now consider @code{((x + 3) + -3)} with the temporary
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
267 holding @code{(x + 3)} used elsewhere. This simplifies down
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
268 to @code{x} which is desirable and thus flagging with @code{s}
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
269 does not prevent the transform. Now consider @code{((x + 3) + 1)}
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
270 which simplifies to @code{(x + 4)}. Despite being flagged with
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
271 @code{s} the simplification will be performed. The
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
272 simplification of @code{((x + a) + 1)} to @code{(x + (a + 1))} will
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
273 not performed in this case though.
111
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 More features exist to avoid too much repetition.
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 @smallexample
kono
parents:
diff changeset
278 (for op (plus pointer_plus minus bit_ior bit_xor)
kono
parents:
diff changeset
279 (simplify
kono
parents:
diff changeset
280 (op @@0 integer_zerop)
kono
parents:
diff changeset
281 @@0))
kono
parents:
diff changeset
282 @end smallexample
kono
parents:
diff changeset
283
kono
parents:
diff changeset
284 A @code{for} expression can be used to repeat a pattern for each
kono
parents:
diff changeset
285 operator specified, substituting @code{op}. @code{for} can be
kono
parents:
diff changeset
286 nested and a @code{for} can have multiple operators to iterate.
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288 @smallexample
kono
parents:
diff changeset
289 (for opa (plus minus)
kono
parents:
diff changeset
290 opb (minus plus)
kono
parents:
diff changeset
291 (for opc (plus minus)
kono
parents:
diff changeset
292 (simplify...
kono
parents:
diff changeset
293 @end smallexample
kono
parents:
diff changeset
294
kono
parents:
diff changeset
295 In this example the pattern will be repeated four times with
kono
parents:
diff changeset
296 @code{opa, opb, opc} being @code{plus, minus, plus},
kono
parents:
diff changeset
297 @code{plus, minus, minus}, @code{minus, plus, plus},
kono
parents:
diff changeset
298 @code{minus, plus, minus}.
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 To avoid repeating operator lists in @code{for} you can name
kono
parents:
diff changeset
301 them via
kono
parents:
diff changeset
302
kono
parents:
diff changeset
303 @smallexample
kono
parents:
diff changeset
304 (define_operator_list pmm plus minus mult)
kono
parents:
diff changeset
305 @end smallexample
kono
parents:
diff changeset
306
kono
parents:
diff changeset
307 and use them in @code{for} operator lists where they get expanded.
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 @smallexample
kono
parents:
diff changeset
310 (for opa (pmm trunc_div)
kono
parents:
diff changeset
311 (simplify...
kono
parents:
diff changeset
312 @end smallexample
kono
parents:
diff changeset
313
kono
parents:
diff changeset
314 So this example iterates over @code{plus}, @code{minus}, @code{mult}
kono
parents:
diff changeset
315 and @code{trunc_div}.
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 Using operator lists can also remove the need to explicitely write
kono
parents:
diff changeset
318 a @code{for}. All operator list uses that appear in a @code{simplify}
kono
parents:
diff changeset
319 or @code{match} pattern in operator positions will implicitely
kono
parents:
diff changeset
320 be added to a new @code{for}. For example
kono
parents:
diff changeset
321
kono
parents:
diff changeset
322 @smallexample
kono
parents:
diff changeset
323 (define_operator_list SQRT BUILT_IN_SQRTF BUILT_IN_SQRT BUILT_IN_SQRTL)
kono
parents:
diff changeset
324 (define_operator_list POW BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL)
kono
parents:
diff changeset
325 (simplify
kono
parents:
diff changeset
326 (SQRT (POW @@0 @@1))
kono
parents:
diff changeset
327 (POW (abs @@0) (mult @@1 @{ built_real (TREE_TYPE (@@1), dconsthalf); @})))
kono
parents:
diff changeset
328 @end smallexample
kono
parents:
diff changeset
329
kono
parents:
diff changeset
330 is the same as
kono
parents:
diff changeset
331
kono
parents:
diff changeset
332 @smallexample
kono
parents:
diff changeset
333 (for SQRT (BUILT_IN_SQRTF BUILT_IN_SQRT BUILT_IN_SQRTL)
kono
parents:
diff changeset
334 POW (BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL)
kono
parents:
diff changeset
335 (simplify
kono
parents:
diff changeset
336 (SQRT (POW @@0 @@1))
kono
parents:
diff changeset
337 (POW (abs @@0) (mult @@1 @{ built_real (TREE_TYPE (@@1), dconsthalf); @}))))
kono
parents:
diff changeset
338 @end smallexample
kono
parents:
diff changeset
339
kono
parents:
diff changeset
340 @code{for}s and operator lists can include the special identifier
kono
parents:
diff changeset
341 @code{null} that matches nothing and can never be generated. This can
kono
parents:
diff changeset
342 be used to pad an operator list so that it has a standard form,
kono
parents:
diff changeset
343 even if there isn't a suitable operator for every form.
kono
parents:
diff changeset
344
kono
parents:
diff changeset
345 Another building block are @code{with} expressions in the
kono
parents:
diff changeset
346 result expression which nest the generated code in a new C block
kono
parents:
diff changeset
347 followed by its argument:
kono
parents:
diff changeset
348
kono
parents:
diff changeset
349 @smallexample
kono
parents:
diff changeset
350 (simplify
kono
parents:
diff changeset
351 (convert (mult @@0 @@1))
kono
parents:
diff changeset
352 (with @{ tree utype = unsigned_type_for (type); @}
kono
parents:
diff changeset
353 (convert (mult (convert:utype @@0) (convert:utype @@1)))))
kono
parents:
diff changeset
354 @end smallexample
kono
parents:
diff changeset
355
kono
parents:
diff changeset
356 This allows code nested in the @code{with} to refer to the declared
kono
parents:
diff changeset
357 variables. In the above case we use the feature to specify the
kono
parents:
diff changeset
358 type of a generated expression with the @code{:type} syntax where
kono
parents:
diff changeset
359 @code{type} needs to be an identifier that refers to the desired type.
kono
parents:
diff changeset
360 Usually the types of the generated result expressions are
kono
parents:
diff changeset
361 determined from the context, but sometimes like in the above case
kono
parents:
diff changeset
362 it is required that you specify them explicitely.
kono
parents:
diff changeset
363
kono
parents:
diff changeset
364 As intermediate conversions are often optional there is a way to
kono
parents:
diff changeset
365 avoid the need to repeat patterns both with and without such
kono
parents:
diff changeset
366 conversions. Namely you can mark a conversion as being optional
kono
parents:
diff changeset
367 with a @code{?}:
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 @smallexample
kono
parents:
diff changeset
370 (simplify
kono
parents:
diff changeset
371 (eq (convert@@0 @@1) (convert@? @@2))
kono
parents:
diff changeset
372 (eq @@1 (convert @@2)))
kono
parents:
diff changeset
373 @end smallexample
kono
parents:
diff changeset
374
kono
parents:
diff changeset
375 which will match both @code{(eq (convert @@1) (convert @@2))} and
kono
parents:
diff changeset
376 @code{(eq (convert @@1) @@2)}. The optional converts are supposed
kono
parents:
diff changeset
377 to be all either present or not, thus
kono
parents:
diff changeset
378 @code{(eq (convert@? @@1) (convert@? @@2))} will result in two
kono
parents:
diff changeset
379 patterns only. If you want to match all four combinations you
kono
parents:
diff changeset
380 have access to two additional conditional converts as in
kono
parents:
diff changeset
381 @code{(eq (convert1@? @@1) (convert2@? @@2))}.
kono
parents:
diff changeset
382
kono
parents:
diff changeset
383 Predicates available from the GCC middle-end need to be made
kono
parents:
diff changeset
384 available explicitely via @code{define_predicates}:
kono
parents:
diff changeset
385
kono
parents:
diff changeset
386 @smallexample
kono
parents:
diff changeset
387 (define_predicates
kono
parents:
diff changeset
388 integer_onep integer_zerop integer_all_onesp)
kono
parents:
diff changeset
389 @end smallexample
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 You can also define predicates using the pattern matching language
kono
parents:
diff changeset
392 and the @code{match} form:
kono
parents:
diff changeset
393
kono
parents:
diff changeset
394 @smallexample
kono
parents:
diff changeset
395 (match negate_expr_p
kono
parents:
diff changeset
396 INTEGER_CST
kono
parents:
diff changeset
397 (if (TYPE_OVERFLOW_WRAPS (type)
kono
parents:
diff changeset
398 || may_negate_without_overflow_p (t))))
kono
parents:
diff changeset
399 (match negate_expr_p
kono
parents:
diff changeset
400 (negate @@0))
kono
parents:
diff changeset
401 @end smallexample
kono
parents:
diff changeset
402
kono
parents:
diff changeset
403 This shows that for @code{match} expressions there is @code{t}
kono
parents:
diff changeset
404 available which captures the outermost expression (something
kono
parents:
diff changeset
405 not possible in the @code{simplify} context). As you can see
kono
parents:
diff changeset
406 @code{match} has an identifier as first operand which is how
kono
parents:
diff changeset
407 you refer to the predicate in patterns. Multiple @code{match}
kono
parents:
diff changeset
408 for the same identifier add additional cases where the predicate
kono
parents:
diff changeset
409 matches.
kono
parents:
diff changeset
410
kono
parents:
diff changeset
411 Predicates can also match an expression in which case you need
kono
parents:
diff changeset
412 to provide a template specifying the identifier and where to
kono
parents:
diff changeset
413 get its operands from:
kono
parents:
diff changeset
414
kono
parents:
diff changeset
415 @smallexample
kono
parents:
diff changeset
416 (match (logical_inverted_value @@0)
kono
parents:
diff changeset
417 (eq @@0 integer_zerop))
kono
parents:
diff changeset
418 (match (logical_inverted_value @@0)
kono
parents:
diff changeset
419 (bit_not truth_valued_p@@0))
kono
parents:
diff changeset
420 @end smallexample
kono
parents:
diff changeset
421
kono
parents:
diff changeset
422 You can use the above predicate like
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 @smallexample
kono
parents:
diff changeset
425 (simplify
kono
parents:
diff changeset
426 (bit_and @@0 (logical_inverted_value @@0))
kono
parents:
diff changeset
427 @{ build_zero_cst (type); @})
kono
parents:
diff changeset
428 @end smallexample
kono
parents:
diff changeset
429
kono
parents:
diff changeset
430 Which will match a bitwise and of an operand with its logical
kono
parents:
diff changeset
431 inverted value.
kono
parents:
diff changeset
432