You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
433 lines
17 KiB
HTML
433 lines
17 KiB
HTML
4 years ago
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
|
<html>
|
||
|
<!-- Copyright (C) 1988-2018 Free Software Foundation, Inc.
|
||
|
|
||
|
Permission is granted to copy, distribute and/or modify this document
|
||
|
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||
|
any later version published by the Free Software Foundation; with the
|
||
|
Invariant Sections being "Funding Free Software", the Front-Cover
|
||
|
Texts being (a) (see below), and with the Back-Cover Texts being (b)
|
||
|
(see below). A copy of the license is included in the section entitled
|
||
|
"GNU Free Documentation License".
|
||
|
|
||
|
(a) The FSF's Front-Cover Text is:
|
||
|
|
||
|
A GNU Manual
|
||
|
|
||
|
(b) The FSF's Back-Cover Text is:
|
||
|
|
||
|
You have freedom to copy and modify this GNU Manual, like GNU
|
||
|
software. Copies published by the Free Software Foundation raise
|
||
|
funds for GNU development. -->
|
||
|
<!-- Created by GNU Texinfo 6.4, http://www.gnu.org/software/texinfo/ -->
|
||
|
<head>
|
||
|
<title>The Language (GNU Compiler Collection (GCC) Internals)</title>
|
||
|
|
||
|
<meta name="description" content="The Language (GNU Compiler Collection (GCC) Internals)">
|
||
|
<meta name="keywords" content="The Language (GNU Compiler Collection (GCC) Internals)">
|
||
|
<meta name="resource-type" content="document">
|
||
|
<meta name="distribution" content="global">
|
||
|
<meta name="Generator" content="makeinfo">
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||
|
<link href="index.html#Top" rel="start" title="Top">
|
||
|
<link href="Option-Index.html#Option-Index" rel="index" title="Option Index">
|
||
|
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
|
||
|
<link href="Match-and-Simplify.html#Match-and-Simplify" rel="up" title="Match and Simplify">
|
||
|
<link href="Funding.html#Funding" rel="next" title="Funding">
|
||
|
<link href="GIMPLE-API.html#GIMPLE-API" rel="prev" title="GIMPLE API">
|
||
|
<style type="text/css">
|
||
|
<!--
|
||
|
a.summary-letter {text-decoration: none}
|
||
|
blockquote.indentedblock {margin-right: 0em}
|
||
|
blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
|
||
|
blockquote.smallquotation {font-size: smaller}
|
||
|
div.display {margin-left: 3.2em}
|
||
|
div.example {margin-left: 3.2em}
|
||
|
div.lisp {margin-left: 3.2em}
|
||
|
div.smalldisplay {margin-left: 3.2em}
|
||
|
div.smallexample {margin-left: 3.2em}
|
||
|
div.smalllisp {margin-left: 3.2em}
|
||
|
kbd {font-style: oblique}
|
||
|
pre.display {font-family: inherit}
|
||
|
pre.format {font-family: inherit}
|
||
|
pre.menu-comment {font-family: serif}
|
||
|
pre.menu-preformatted {font-family: serif}
|
||
|
pre.smalldisplay {font-family: inherit; font-size: smaller}
|
||
|
pre.smallexample {font-size: smaller}
|
||
|
pre.smallformat {font-family: inherit; font-size: smaller}
|
||
|
pre.smalllisp {font-size: smaller}
|
||
|
span.nolinebreak {white-space: nowrap}
|
||
|
span.roman {font-family: initial; font-weight: normal}
|
||
|
span.sansserif {font-family: sans-serif; font-weight: normal}
|
||
|
ul.no-bullet {list-style: none}
|
||
|
-->
|
||
|
</style>
|
||
|
|
||
|
|
||
|
</head>
|
||
|
|
||
|
<body lang="en">
|
||
|
<a name="The-Language"></a>
|
||
|
<div class="header">
|
||
|
<p>
|
||
|
Previous: <a href="GIMPLE-API.html#GIMPLE-API" accesskey="p" rel="prev">GIMPLE API</a>, Up: <a href="Match-and-Simplify.html#Match-and-Simplify" accesskey="u" rel="up">Match and Simplify</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<hr>
|
||
|
<a name="The-Language-1"></a>
|
||
|
<h3 class="section">26.2 The Language</h3>
|
||
|
<a name="index-The-Language"></a>
|
||
|
|
||
|
<p>The language to write expression simplifications in resembles other
|
||
|
domain-specific languages GCC uses. Thus it is lispy. Lets start
|
||
|
with an example from the match.pd file:
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(simplify
|
||
|
(bit_and @0 integer_all_onesp)
|
||
|
@0)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>This example contains all required parts of an expression simplification.
|
||
|
A simplification is wrapped inside a <code>(simplify ...)</code> expression.
|
||
|
That contains at least two operands - an expression that is matched
|
||
|
with the GIMPLE or GENERIC IL and a replacement expression that is
|
||
|
returned if the match was successful.
|
||
|
</p>
|
||
|
<p>Expressions have an operator ID, <code>bit_and</code> in this case. Expressions can
|
||
|
be lower-case tree codes with <code>_expr</code> stripped off or builtin
|
||
|
function code names in all-caps, like <code>BUILT_IN_SQRT</code>.
|
||
|
</p>
|
||
|
<p><code>@n</code> denotes a so-called capture. It captures the operand and lets
|
||
|
you refer to it in other places of the match-and-simplify. In the
|
||
|
above example it is refered to in the replacement expression. Captures
|
||
|
are <code>@</code> followed by a number or an identifier.
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(simplify
|
||
|
(bit_xor @0 @0)
|
||
|
{ build_zero_cst (type); })
|
||
|
</pre></div>
|
||
|
|
||
|
<p>In this example <code>@0</code> is mentioned twice which constrains the matched
|
||
|
expression to have two equal operands. Usually matches are constraint
|
||
|
to equal types. If operands may be constants and conversions are involved
|
||
|
matching by value might be preferred in which case use <code>@@0</code> to
|
||
|
denote a by value match and the specific operand you want to refer to
|
||
|
in the result part. This example also introduces
|
||
|
operands written in C code. These can be used in the expression
|
||
|
replacements and are supposed to evaluate to a tree node which has to
|
||
|
be a valid GIMPLE operand (so you cannot generate expressions in C code).
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(simplify
|
||
|
(trunc_mod integer_zerop@0 @1)
|
||
|
(if (!integer_zerop (@1))
|
||
|
@0))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Here <code>@0</code> captures the first operand of the trunc_mod expression
|
||
|
which is also predicated with <code>integer_zerop</code>. Expression operands
|
||
|
may be either expressions, predicates or captures. Captures
|
||
|
can be unconstrained or capture expresions or predicates.
|
||
|
</p>
|
||
|
<p>This example introduces an optional operand of simplify,
|
||
|
the if-expression. This condition is evaluated after the
|
||
|
expression matched in the IL and is required to evaluate to true
|
||
|
to enable the replacement expression in the second operand
|
||
|
position. The expression operand of the <code>if</code> is a standard C
|
||
|
expression which may contain references to captures. The <code>if</code>
|
||
|
has an optional third operand which may contain the replacement
|
||
|
expression that is enabled when the condition evaluates to false.
|
||
|
</p>
|
||
|
<p>A <code>if</code> expression can be used to specify a common condition
|
||
|
for multiple simplify patterns, avoiding the need
|
||
|
to repeat that multiple times:
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(if (!TYPE_SATURATING (type)
|
||
|
&& !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type))
|
||
|
(simplify
|
||
|
(minus (plus @0 @1) @0)
|
||
|
@1)
|
||
|
(simplify
|
||
|
(minus (minus @0 @1) @0)
|
||
|
(negate @1)))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Note that <code>if</code>s in outer position do not have the optional
|
||
|
else clause but instead have multiple then clauses.
|
||
|
</p>
|
||
|
<p>Ifs can be nested.
|
||
|
</p>
|
||
|
<p>There exists a <code>switch</code> expression which can be used to
|
||
|
chain conditions avoiding nesting <code>if</code>s too much:
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(simplify
|
||
|
(simple_comparison @0 REAL_CST@1)
|
||
|
(switch
|
||
|
/* a CMP (-0) -> a CMP 0 */
|
||
|
(if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@1)))
|
||
|
(cmp @0 { build_real (TREE_TYPE (@1), dconst0); }))
|
||
|
/* x != NaN is always true, other ops are always false. */
|
||
|
(if (REAL_VALUE_ISNAN (TREE_REAL_CST (@1))
|
||
|
&& ! HONOR_SNANS (@1))
|
||
|
{ constant_boolean_node (cmp == NE_EXPR, type); })))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Is equal to
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(simplify
|
||
|
(simple_comparison @0 REAL_CST@1)
|
||
|
(switch
|
||
|
/* a CMP (-0) -> a CMP 0 */
|
||
|
(if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@1)))
|
||
|
(cmp @0 { build_real (TREE_TYPE (@1), dconst0); })
|
||
|
/* x != NaN is always true, other ops are always false. */
|
||
|
(if (REAL_VALUE_ISNAN (TREE_REAL_CST (@1))
|
||
|
&& ! HONOR_SNANS (@1))
|
||
|
{ constant_boolean_node (cmp == NE_EXPR, type); }))))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>which has the second <code>if</code> in the else operand of the first.
|
||
|
The <code>switch</code> expression takes <code>if</code> expressions as
|
||
|
operands (which may not have else clauses) and as a last operand
|
||
|
a replacement expression which should be enabled by default if
|
||
|
no other condition evaluated to true.
|
||
|
</p>
|
||
|
<p>Captures can also be used for capturing results of sub-expressions.
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">#if GIMPLE
|
||
|
(simplify
|
||
|
(pointer_plus (addr@2 @0) INTEGER_CST_P@1)
|
||
|
(if (is_gimple_min_invariant (@2)))
|
||
|
{
|
||
|
poly_int64 off;
|
||
|
tree base = get_addr_base_and_unit_offset (@0, &off);
|
||
|
off += tree_to_uhwi (@1);
|
||
|
/* Now with that we should be able to simply write
|
||
|
(addr (mem_ref (addr @base) (plus @off @1))) */
|
||
|
build1 (ADDR_EXPR, type,
|
||
|
build2 (MEM_REF, TREE_TYPE (TREE_TYPE (@2)),
|
||
|
build_fold_addr_expr (base),
|
||
|
build_int_cst (ptr_type_node, off)));
|
||
|
})
|
||
|
#endif
|
||
|
</pre></div>
|
||
|
|
||
|
<p>In the above example, <code>@2</code> captures the result of the expression
|
||
|
<code>(addr @0)</code>. For outermost expression only its type can be captured,
|
||
|
and the keyword <code>type</code> is reserved for this purpose. The above
|
||
|
example also gives a way to conditionalize patterns to only apply
|
||
|
to <code>GIMPLE</code> or <code>GENERIC</code> by means of using the pre-defined
|
||
|
preprocessor macros <code>GIMPLE</code> and <code>GENERIC</code> and using
|
||
|
preprocessor directives.
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(simplify
|
||
|
(bit_and:c integral_op_p@0 (bit_ior:c (bit_not @0) @1))
|
||
|
(bit_and @1 @0))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Here we introduce flags on match expressions. The flag used
|
||
|
above, <code>c</code>, denotes that the expression should
|
||
|
be also matched commutated. Thus the above match expression
|
||
|
is really the following four match expressions:
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample"> (bit_and integral_op_p@0 (bit_ior (bit_not @0) @1))
|
||
|
(bit_and (bit_ior (bit_not @0) @1) integral_op_p@0)
|
||
|
(bit_and integral_op_p@0 (bit_ior @1 (bit_not @0)))
|
||
|
(bit_and (bit_ior @1 (bit_not @0)) integral_op_p@0)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Usual canonicalizations you know from GENERIC expressions are
|
||
|
applied before matching, so for example constant operands always
|
||
|
come second in commutative expressions.
|
||
|
</p>
|
||
|
<p>The second supported flag is <code>s</code> which tells the code
|
||
|
generator to fail the pattern if the expression marked with
|
||
|
<code>s</code> does have more than one use. For example in
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(simplify
|
||
|
(pointer_plus (pointer_plus:s @0 @1) @3)
|
||
|
(pointer_plus @0 (plus @1 @3)))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>this avoids the association if <code>(pointer_plus @0 @1)</code> is
|
||
|
used outside of the matched expression and thus it would stay
|
||
|
live and not trivially removed by dead code elimination.
|
||
|
</p>
|
||
|
<p>More features exist to avoid too much repetition.
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(for op (plus pointer_plus minus bit_ior bit_xor)
|
||
|
(simplify
|
||
|
(op @0 integer_zerop)
|
||
|
@0))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>A <code>for</code> expression can be used to repeat a pattern for each
|
||
|
operator specified, substituting <code>op</code>. <code>for</code> can be
|
||
|
nested and a <code>for</code> can have multiple operators to iterate.
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(for opa (plus minus)
|
||
|
opb (minus plus)
|
||
|
(for opc (plus minus)
|
||
|
(simplify...
|
||
|
</pre></div>
|
||
|
|
||
|
<p>In this example the pattern will be repeated four times with
|
||
|
<code>opa, opb, opc</code> being <code>plus, minus, plus</code>,
|
||
|
<code>plus, minus, minus</code>, <code>minus, plus, plus</code>,
|
||
|
<code>minus, plus, minus</code>.
|
||
|
</p>
|
||
|
<p>To avoid repeating operator lists in <code>for</code> you can name
|
||
|
them via
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(define_operator_list pmm plus minus mult)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>and use them in <code>for</code> operator lists where they get expanded.
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(for opa (pmm trunc_div)
|
||
|
(simplify...
|
||
|
</pre></div>
|
||
|
|
||
|
<p>So this example iterates over <code>plus</code>, <code>minus</code>, <code>mult</code>
|
||
|
and <code>trunc_div</code>.
|
||
|
</p>
|
||
|
<p>Using operator lists can also remove the need to explicitely write
|
||
|
a <code>for</code>. All operator list uses that appear in a <code>simplify</code>
|
||
|
or <code>match</code> pattern in operator positions will implicitely
|
||
|
be added to a new <code>for</code>. For example
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(define_operator_list SQRT BUILT_IN_SQRTF BUILT_IN_SQRT BUILT_IN_SQRTL)
|
||
|
(define_operator_list POW BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL)
|
||
|
(simplify
|
||
|
(SQRT (POW @0 @1))
|
||
|
(POW (abs @0) (mult @1 { built_real (TREE_TYPE (@1), dconsthalf); })))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>is the same as
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(for SQRT (BUILT_IN_SQRTF BUILT_IN_SQRT BUILT_IN_SQRTL)
|
||
|
POW (BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL)
|
||
|
(simplify
|
||
|
(SQRT (POW @0 @1))
|
||
|
(POW (abs @0) (mult @1 { built_real (TREE_TYPE (@1), dconsthalf); }))))
|
||
|
</pre></div>
|
||
|
|
||
|
<p><code>for</code>s and operator lists can include the special identifier
|
||
|
<code>null</code> that matches nothing and can never be generated. This can
|
||
|
be used to pad an operator list so that it has a standard form,
|
||
|
even if there isn’t a suitable operator for every form.
|
||
|
</p>
|
||
|
<p>Another building block are <code>with</code> expressions in the
|
||
|
result expression which nest the generated code in a new C block
|
||
|
followed by its argument:
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(simplify
|
||
|
(convert (mult @0 @1))
|
||
|
(with { tree utype = unsigned_type_for (type); }
|
||
|
(convert (mult (convert:utype @0) (convert:utype @1)))))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>This allows code nested in the <code>with</code> to refer to the declared
|
||
|
variables. In the above case we use the feature to specify the
|
||
|
type of a generated expression with the <code>:type</code> syntax where
|
||
|
<code>type</code> needs to be an identifier that refers to the desired type.
|
||
|
Usually the types of the generated result expressions are
|
||
|
determined from the context, but sometimes like in the above case
|
||
|
it is required that you specify them explicitely.
|
||
|
</p>
|
||
|
<p>As intermediate conversions are often optional there is a way to
|
||
|
avoid the need to repeat patterns both with and without such
|
||
|
conversions. Namely you can mark a conversion as being optional
|
||
|
with a <code>?</code>:
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(simplify
|
||
|
(eq (convert@0 @1) (convert? @2))
|
||
|
(eq @1 (convert @2)))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>which will match both <code>(eq (convert @1) (convert @2))</code> and
|
||
|
<code>(eq (convert @1) @2)</code>. The optional converts are supposed
|
||
|
to be all either present or not, thus
|
||
|
<code>(eq (convert? @1) (convert? @2))</code> will result in two
|
||
|
patterns only. If you want to match all four combinations you
|
||
|
have access to two additional conditional converts as in
|
||
|
<code>(eq (convert1? @1) (convert2? @2))</code>.
|
||
|
</p>
|
||
|
<p>Predicates available from the GCC middle-end need to be made
|
||
|
available explicitely via <code>define_predicates</code>:
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(define_predicates
|
||
|
integer_onep integer_zerop integer_all_onesp)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>You can also define predicates using the pattern matching language
|
||
|
and the <code>match</code> form:
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(match negate_expr_p
|
||
|
INTEGER_CST
|
||
|
(if (TYPE_OVERFLOW_WRAPS (type)
|
||
|
|| may_negate_without_overflow_p (t))))
|
||
|
(match negate_expr_p
|
||
|
(negate @0))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>This shows that for <code>match</code> expressions there is <code>t</code>
|
||
|
available which captures the outermost expression (something
|
||
|
not possible in the <code>simplify</code> context). As you can see
|
||
|
<code>match</code> has an identifier as first operand which is how
|
||
|
you refer to the predicate in patterns. Multiple <code>match</code>
|
||
|
for the same identifier add additional cases where the predicate
|
||
|
matches.
|
||
|
</p>
|
||
|
<p>Predicates can also match an expression in which case you need
|
||
|
to provide a template specifying the identifier and where to
|
||
|
get its operands from:
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(match (logical_inverted_value @0)
|
||
|
(eq @0 integer_zerop))
|
||
|
(match (logical_inverted_value @0)
|
||
|
(bit_not truth_valued_p@0))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>You can use the above predicate like
|
||
|
</p>
|
||
|
<div class="smallexample">
|
||
|
<pre class="smallexample">(simplify
|
||
|
(bit_and @0 (logical_inverted_value @0))
|
||
|
{ build_zero_cst (type); })
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Which will match a bitwise and of an operand with its logical
|
||
|
inverted value.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<div class="header">
|
||
|
<p>
|
||
|
Previous: <a href="GIMPLE-API.html#GIMPLE-API" accesskey="p" rel="prev">GIMPLE API</a>, Up: <a href="Match-and-Simplify.html#Match-and-Simplify" accesskey="u" rel="up">Match and Simplify</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
</body>
|
||
|
</html>
|