| 
							- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 - <html>
 - <!-- Copyright (C) 1988-2020 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.5, http://www.gnu.org/software/texinfo/ -->
 - <head>
 - <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 - <title>Insn Splitting (GNU Compiler Collection (GCC) Internals)</title>
 - 
 - <meta name="description" content="Insn Splitting (GNU Compiler Collection (GCC) Internals)">
 - <meta name="keywords" content="Insn Splitting (GNU Compiler Collection (GCC) Internals)">
 - <meta name="resource-type" content="document">
 - <meta name="distribution" content="global">
 - <meta name="Generator" content="makeinfo">
 - <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="Machine-Desc.html#Machine-Desc" rel="up" title="Machine Desc">
 - <link href="Including-Patterns.html#Including-Patterns" rel="next" title="Including Patterns">
 - <link href="Expander-Definitions.html#Expander-Definitions" rel="prev" title="Expander Definitions">
 - <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="Insn-Splitting"></a>
 - <div class="header">
 - <p>
 - Next: <a href="Including-Patterns.html#Including-Patterns" accesskey="n" rel="next">Including Patterns</a>, Previous: <a href="Expander-Definitions.html#Expander-Definitions" accesskey="p" rel="prev">Expander Definitions</a>, Up: <a href="Machine-Desc.html#Machine-Desc" accesskey="u" rel="up">Machine Desc</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="Defining-How-to-Split-Instructions"></a>
 - <h3 class="section">17.16 Defining How to Split Instructions</h3>
 - <a name="index-insn-splitting"></a>
 - <a name="index-instruction-splitting"></a>
 - <a name="index-splitting-instructions"></a>
 - 
 - <p>There are two cases where you should specify how to split a pattern
 - into multiple insns.  On machines that have instructions requiring
 - delay slots (see <a href="Delay-Slots.html#Delay-Slots">Delay Slots</a>) or that have instructions whose
 - output is not available for multiple cycles (see <a href="Processor-pipeline-description.html#Processor-pipeline-description">Processor pipeline description</a>), the compiler phases that optimize these cases need to
 - be able to move insns into one-instruction delay slots.  However, some
 - insns may generate more than one machine instruction.  These insns
 - cannot be placed into a delay slot.
 - </p>
 - <p>Often you can rewrite the single insn as a list of individual insns,
 - each corresponding to one machine instruction.  The disadvantage of
 - doing so is that it will cause the compilation to be slower and require
 - more space.  If the resulting insns are too complex, it may also
 - suppress some optimizations.  The compiler splits the insn if there is a
 - reason to believe that it might improve instruction or delay slot
 - scheduling.
 - </p>
 - <p>The insn combiner phase also splits putative insns.  If three insns are
 - merged into one insn with a complex expression that cannot be matched by
 - some <code>define_insn</code> pattern, the combiner phase attempts to split
 - the complex pattern into two insns that are recognized.  Usually it can
 - break the complex pattern into two patterns by splitting out some
 - subexpression.  However, in some other cases, such as performing an
 - addition of a large constant in two insns on a RISC machine, the way to
 - split the addition into two insns is machine-dependent.
 - </p>
 - <a name="index-define_005fsplit"></a>
 - <p>The <code>define_split</code> definition tells the compiler how to split a
 - complex insn into several simpler insns.  It looks like this:
 - </p>
 - <div class="smallexample">
 - <pre class="smallexample">(define_split
 -   [<var>insn-pattern</var>]
 -   "<var>condition</var>"
 -   [<var>new-insn-pattern-1</var>
 -    <var>new-insn-pattern-2</var>
 -    …]
 -   "<var>preparation-statements</var>")
 - </pre></div>
 - 
 - <p><var>insn-pattern</var> is a pattern that needs to be split and
 - <var>condition</var> is the final condition to be tested, as in a
 - <code>define_insn</code>.  When an insn matching <var>insn-pattern</var> and
 - satisfying <var>condition</var> is found, it is replaced in the insn list
 - with the insns given by <var>new-insn-pattern-1</var>,
 - <var>new-insn-pattern-2</var>, etc.
 - </p>
 - <p>The <var>preparation-statements</var> are similar to those statements that
 - are specified for <code>define_expand</code> (see <a href="Expander-Definitions.html#Expander-Definitions">Expander Definitions</a>)
 - and are executed before the new RTL is generated to prepare for the
 - generated code or emit some insns whose pattern is not fixed.  Unlike
 - those in <code>define_expand</code>, however, these statements must not
 - generate any new pseudo-registers.  Once reload has completed, they also
 - must not allocate any space in the stack frame.
 - </p>
 - <p>There are two special macros defined for use in the preparation statements:
 - <code>DONE</code> and <code>FAIL</code>.  Use them with a following semicolon,
 - as a statement.
 - </p>
 - <dl compact="compact">
 - <dd>
 - <a name="index-DONE-1"></a>
 - </dd>
 - <dt><code>DONE</code></dt>
 - <dd><p>Use the <code>DONE</code> macro to end RTL generation for the splitter.  The
 - only RTL insns generated as replacement for the matched input insn will
 - be those already emitted by explicit calls to <code>emit_insn</code> within
 - the preparation statements; the replacement pattern is not used.
 - </p>
 - <a name="index-FAIL-1"></a>
 - </dd>
 - <dt><code>FAIL</code></dt>
 - <dd><p>Make the <code>define_split</code> fail on this occasion.  When a <code>define_split</code>
 - fails, it means that the splitter was not truly available for the inputs
 - it was given, and the input insn will not be split.
 - </p></dd>
 - </dl>
 - 
 - <p>If the preparation falls through (invokes neither <code>DONE</code> nor
 - <code>FAIL</code>), then the <code>define_split</code> uses the replacement
 - template.
 - </p>
 - <p>Patterns are matched against <var>insn-pattern</var> in two different
 - circumstances.  If an insn needs to be split for delay slot scheduling
 - or insn scheduling, the insn is already known to be valid, which means
 - that it must have been matched by some <code>define_insn</code> and, if
 - <code>reload_completed</code> is nonzero, is known to satisfy the constraints
 - of that <code>define_insn</code>.  In that case, the new insn patterns must
 - also be insns that are matched by some <code>define_insn</code> and, if
 - <code>reload_completed</code> is nonzero, must also satisfy the constraints
 - of those definitions.
 - </p>
 - <p>As an example of this usage of <code>define_split</code>, consider the following
 - example from <samp>a29k.md</samp>, which splits a <code>sign_extend</code> from
 - <code>HImode</code> to <code>SImode</code> into a pair of shift insns:
 - </p>
 - <div class="smallexample">
 - <pre class="smallexample">(define_split
 -   [(set (match_operand:SI 0 "gen_reg_operand" "")
 -         (sign_extend:SI (match_operand:HI 1 "gen_reg_operand" "")))]
 -   ""
 -   [(set (match_dup 0)
 -         (ashift:SI (match_dup 1)
 -                    (const_int 16)))
 -    (set (match_dup 0)
 -         (ashiftrt:SI (match_dup 0)
 -                      (const_int 16)))]
 -   "
 - { operands[1] = gen_lowpart (SImode, operands[1]); }")
 - </pre></div>
 - 
 - <p>When the combiner phase tries to split an insn pattern, it is always the
 - case that the pattern is <em>not</em> matched by any <code>define_insn</code>.
 - The combiner pass first tries to split a single <code>set</code> expression
 - and then the same <code>set</code> expression inside a <code>parallel</code>, but
 - followed by a <code>clobber</code> of a pseudo-reg to use as a scratch
 - register.  In these cases, the combiner expects exactly one or two new insn
 - patterns to be generated.  It will verify that these patterns match some
 - <code>define_insn</code> definitions, so you need not do this test in the
 - <code>define_split</code> (of course, there is no point in writing a
 - <code>define_split</code> that will never produce insns that match).
 - </p>
 - <p>Here is an example of this use of <code>define_split</code>, taken from
 - <samp>rs6000.md</samp>:
 - </p>
 - <div class="smallexample">
 - <pre class="smallexample">(define_split
 -   [(set (match_operand:SI 0 "gen_reg_operand" "")
 -         (plus:SI (match_operand:SI 1 "gen_reg_operand" "")
 -                  (match_operand:SI 2 "non_add_cint_operand" "")))]
 -   ""
 -   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
 -    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
 - "
 - {
 -   int low = INTVAL (operands[2]) & 0xffff;
 -   int high = (unsigned) INTVAL (operands[2]) >> 16;
 - 
 -   if (low & 0x8000)
 -     high++, low |= 0xffff0000;
 - 
 -   operands[3] = GEN_INT (high << 16);
 -   operands[4] = GEN_INT (low);
 - }")
 - </pre></div>
 - 
 - <p>Here the predicate <code>non_add_cint_operand</code> matches any
 - <code>const_int</code> that is <em>not</em> a valid operand of a single add
 - insn.  The add with the smaller displacement is written so that it
 - can be substituted into the address of a subsequent operation.
 - </p>
 - <p>An example that uses a scratch register, from the same file, generates
 - an equality comparison of a register and a large constant:
 - </p>
 - <div class="smallexample">
 - <pre class="smallexample">(define_split
 -   [(set (match_operand:CC 0 "cc_reg_operand" "")
 -         (compare:CC (match_operand:SI 1 "gen_reg_operand" "")
 -                     (match_operand:SI 2 "non_short_cint_operand" "")))
 -    (clobber (match_operand:SI 3 "gen_reg_operand" ""))]
 -   "find_single_use (operands[0], insn, 0)
 -    && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
 -        || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
 -   [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
 -    (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
 -   "
 - {
 -   /* <span class="roman">Get the constant we are comparing against, C, and see what it
 -      looks like sign-extended to 16 bits.  Then see what constant
 -      could be XOR’ed with C to get the sign-extended value.</span>  */
 - 
 -   int c = INTVAL (operands[2]);
 -   int sextc = (c << 16) >> 16;
 -   int xorv = c ^ sextc;
 - 
 -   operands[4] = GEN_INT (xorv);
 -   operands[5] = GEN_INT (sextc);
 - }")
 - </pre></div>
 - 
 - <p>To avoid confusion, don’t write a single <code>define_split</code> that
 - accepts some insns that match some <code>define_insn</code> as well as some
 - insns that don’t.  Instead, write two separate <code>define_split</code>
 - definitions, one for the insns that are valid and one for the insns that
 - are not valid.
 - </p>
 - <p>The splitter is allowed to split jump instructions into sequence of
 - jumps or create new jumps in while splitting non-jump instructions.  As
 - the control flow graph and branch prediction information needs to be updated,
 - several restriction apply.
 - </p>
 - <p>Splitting of jump instruction into sequence that over by another jump
 - instruction is always valid, as compiler expect identical behavior of new
 - jump.  When new sequence contains multiple jump instructions or new labels,
 - more assistance is needed.  Splitter is required to create only unconditional
 - jumps, or simple conditional jump instructions.  Additionally it must attach a
 - <code>REG_BR_PROB</code> note to each conditional jump.  A global variable
 - <code>split_branch_probability</code> holds the probability of the original branch in case
 - it was a simple conditional jump, -1 otherwise.  To simplify
 - recomputing of edge frequencies, the new sequence is required to have only
 - forward jumps to the newly created labels.
 - </p>
 - <a name="index-define_005finsn_005fand_005fsplit"></a>
 - <p>For the common case where the pattern of a define_split exactly matches the
 - pattern of a define_insn, use <code>define_insn_and_split</code>.  It looks like
 - this:
 - </p>
 - <div class="smallexample">
 - <pre class="smallexample">(define_insn_and_split
 -   [<var>insn-pattern</var>]
 -   "<var>condition</var>"
 -   "<var>output-template</var>"
 -   "<var>split-condition</var>"
 -   [<var>new-insn-pattern-1</var>
 -    <var>new-insn-pattern-2</var>
 -    …]
 -   "<var>preparation-statements</var>"
 -   [<var>insn-attributes</var>])
 - 
 - </pre></div>
 - 
 - <p><var>insn-pattern</var>, <var>condition</var>, <var>output-template</var>, and
 - <var>insn-attributes</var> are used as in <code>define_insn</code>.  The
 - <var>new-insn-pattern</var> vector and the <var>preparation-statements</var> are used as
 - in a <code>define_split</code>.  The <var>split-condition</var> is also used as in
 - <code>define_split</code>, with the additional behavior that if the condition starts
 - with ‘<samp>&&</samp>’, the condition used for the split will be the constructed as a
 - logical “and” of the split condition with the insn condition.  For example,
 - from i386.md:
 - </p>
 - <div class="smallexample">
 - <pre class="smallexample">(define_insn_and_split "zero_extendhisi2_and"
 -   [(set (match_operand:SI 0 "register_operand" "=r")
 -      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
 -    (clobber (reg:CC 17))]
 -   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
 -   "#"
 -   "&& reload_completed"
 -   [(parallel [(set (match_dup 0)
 -                    (and:SI (match_dup 0) (const_int 65535)))
 -               (clobber (reg:CC 17))])]
 -   ""
 -   [(set_attr "type" "alu1")])
 - 
 - </pre></div>
 - 
 - <p>In this case, the actual split condition will be
 - ‘<samp>TARGET_ZERO_EXTEND_WITH_AND && !optimize_size && reload_completed</samp>’.
 - </p>
 - <p>The <code>define_insn_and_split</code> construction provides exactly the same
 - functionality as two separate <code>define_insn</code> and <code>define_split</code>
 - patterns.  It exists for compactness, and as a maintenance tool to prevent
 - having to ensure the two patterns’ templates match.
 - </p>
 - <a name="index-define_005finsn_005fand_005frewrite"></a>
 - <p>It is sometimes useful to have a <code>define_insn_and_split</code>
 - that replaces specific operands of an instruction but leaves the
 - rest of the instruction pattern unchanged.  You can do this directly
 - with a <code>define_insn_and_split</code>, but it requires a
 - <var>new-insn-pattern-1</var> that repeats most of the original <var>insn-pattern</var>.
 - There is also the complication that an implicit <code>parallel</code> in
 - <var>insn-pattern</var> must become an explicit <code>parallel</code> in
 - <var>new-insn-pattern-1</var>, which is easy to overlook.
 - A simpler alternative is to use <code>define_insn_and_rewrite</code>, which
 - is a form of <code>define_insn_and_split</code> that automatically generates
 - <var>new-insn-pattern-1</var> by replacing each <code>match_operand</code>
 - in <var>insn-pattern</var> with a corresponding <code>match_dup</code>, and each
 - <code>match_operator</code> in the pattern with a corresponding <code>match_op_dup</code>.
 - The arguments are otherwise identical to <code>define_insn_and_split</code>:
 - </p>
 - <div class="smallexample">
 - <pre class="smallexample">(define_insn_and_rewrite
 -   [<var>insn-pattern</var>]
 -   "<var>condition</var>"
 -   "<var>output-template</var>"
 -   "<var>split-condition</var>"
 -   "<var>preparation-statements</var>"
 -   [<var>insn-attributes</var>])
 - </pre></div>
 - 
 - <p>The <code>match_dup</code>s and <code>match_op_dup</code>s in the new
 - instruction pattern use any new operand values that the
 - <var>preparation-statements</var> store in the <code>operands</code> array,
 - as for a normal <code>define_insn_and_split</code>.  <var>preparation-statements</var>
 - can also emit additional instructions before the new instruction.
 - They can even emit an entirely different sequence of instructions and
 - use <code>DONE</code> to avoid emitting a new form of the original
 - instruction.
 - </p>
 - <p>The split in a <code>define_insn_and_rewrite</code> is only intended
 - to apply to existing instructions that match <var>insn-pattern</var>.
 - <var>split-condition</var> must therefore start with <code>&&</code>,
 - so that the split condition applies on top of <var>condition</var>.
 - </p>
 - <p>Here is an example from the AArch64 SVE port, in which operand 1 is
 - known to be equivalent to an all-true constant and isn’t used by the
 - output template:
 - </p>
 - <div class="smallexample">
 - <pre class="smallexample">(define_insn_and_rewrite "*while_ult<GPI:mode><PRED_ALL:mode>_cc"
 -   [(set (reg:CC CC_REGNUM)
 -         (compare:CC
 -           (unspec:SI [(match_operand:PRED_ALL 1)
 -                       (unspec:PRED_ALL
 -                         [(match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")
 -                          (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")]
 -                         UNSPEC_WHILE_LO)]
 -                      UNSPEC_PTEST_PTRUE)
 -           (const_int 0)))
 -    (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
 -         (unspec:PRED_ALL [(match_dup 2)
 -                           (match_dup 3)]
 -                          UNSPEC_WHILE_LO))]
 -   "TARGET_SVE"
 -   "whilelo\t%0.<PRED_ALL:Vetype>, %<w>2, %<w>3"
 -   ;; Force the compiler to drop the unused predicate operand, so that we
 -   ;; don't have an unnecessary PTRUE.
 -   "&& !CONSTANT_P (operands[1])"
 -   {
 -     operands[1] = CONSTM1_RTX (<MODE>mode);
 -   }
 - )
 - </pre></div>
 - 
 - <p>The splitter in this case simply replaces operand 1 with the constant
 - value that it is known to have.  The equivalent <code>define_insn_and_split</code>
 - would be:
 - </p>
 - <div class="smallexample">
 - <pre class="smallexample">(define_insn_and_split "*while_ult<GPI:mode><PRED_ALL:mode>_cc"
 -   [(set (reg:CC CC_REGNUM)
 -         (compare:CC
 -           (unspec:SI [(match_operand:PRED_ALL 1)
 -                       (unspec:PRED_ALL
 -                         [(match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")
 -                          (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")]
 -                         UNSPEC_WHILE_LO)]
 -                      UNSPEC_PTEST_PTRUE)
 -           (const_int 0)))
 -    (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
 -         (unspec:PRED_ALL [(match_dup 2)
 -                           (match_dup 3)]
 -                          UNSPEC_WHILE_LO))]
 -   "TARGET_SVE"
 -   "whilelo\t%0.<PRED_ALL:Vetype>, %<w>2, %<w>3"
 -   ;; Force the compiler to drop the unused predicate operand, so that we
 -   ;; don't have an unnecessary PTRUE.
 -   "&& !CONSTANT_P (operands[1])"
 -   [(parallel
 -      [(set (reg:CC CC_REGNUM)
 -            (compare:CC
 -              (unspec:SI [(match_dup 1)
 -                          (unspec:PRED_ALL [(match_dup 2)
 -                                            (match_dup 3)]
 -                                           UNSPEC_WHILE_LO)]
 -                         UNSPEC_PTEST_PTRUE)
 -              (const_int 0)))
 -       (set (match_dup 0)
 -            (unspec:PRED_ALL [(match_dup 2)
 -                              (match_dup 3)]
 -                             UNSPEC_WHILE_LO))])]
 -   {
 -     operands[1] = CONSTM1_RTX (<MODE>mode);
 -   }
 - )
 - </pre></div>
 - 
 - <hr>
 - <div class="header">
 - <p>
 - Next: <a href="Including-Patterns.html#Including-Patterns" accesskey="n" rel="next">Including Patterns</a>, Previous: <a href="Expander-Definitions.html#Expander-Definitions" accesskey="p" rel="prev">Expander Definitions</a>, Up: <a href="Machine-Desc.html#Machine-Desc" accesskey="u" rel="up">Machine Desc</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>
 
 
  |