GNU Info

Info Node: (gcc-295.info)Peephole Definitions

(gcc-295.info)Peephole Definitions


Next: Expander Definitions Prev: Insn Canonicalizations Up: Machine Desc
Enter node , (file) or (file)node

Machine-Specific Peephole Optimizers
====================================

   In addition to instruction patterns the `md' file may contain
definitions of machine-specific peephole optimizations.

   The combiner does not notice certain peephole optimizations when the
data flow in the program does not suggest that it should try them.  For
example, sometimes two consecutive insns related in purpose can be
combined even though the second one does not appear to use a register
computed in the first one.  A machine-specific peephole optimizer can
detect such opportunities.

   A definition looks like this:

     (define_peephole
       [INSN-PATTERN-1
        INSN-PATTERN-2
        ...]
       "CONDITION"
       "TEMPLATE"
       "OPTIONAL INSN-ATTRIBUTES")

The last string operand may be omitted if you are not using any
machine-specific information in this machine description.  If present,
it must obey the same rules as in a `define_insn'.

   In this skeleton, INSN-PATTERN-1 and so on are patterns to match
consecutive insns.  The optimization applies to a sequence of insns when
INSN-PATTERN-1 matches the first one, INSN-PATTERN-2 matches the next,
and so on.

   Each of the insns matched by a peephole must also match a
`define_insn'.  Peepholes are checked only at the last stage just
before code generation, and only optionally.  Therefore, any insn which
would match a peephole but no `define_insn' will cause a crash in code
generation in an unoptimized compilation, or at various optimization
stages.

   The operands of the insns are matched with `match_operands',
`match_operator', and `match_dup', as usual.  What is not usual is that
the operand numbers apply to all the insn patterns in the definition.
So, you can check for identical operands in two insns by using
`match_operand' in one insn and `match_dup' in the other.

   The operand constraints used in `match_operand' patterns do not have
any direct effect on the applicability of the peephole, but they will
be validated afterward, so make sure your constraints are general enough
to apply whenever the peephole matches.  If the peephole matches but
the constraints are not satisfied, the compiler will crash.

   It is safe to omit constraints in all the operands of the peephole;
or you can write constraints which serve as a double-check on the
criteria previously tested.

   Once a sequence of insns matches the patterns, the CONDITION is
checked.  This is a C expression which makes the final decision whether
to perform the optimization (we do so if the expression is nonzero).  If
CONDITION is omitted (in other words, the string is empty) then the
optimization is applied to every sequence of insns that matches the
patterns.

   The defined peephole optimizations are applied after register
allocation is complete.  Therefore, the peephole definition can check
which operands have ended up in which kinds of registers, just by
looking at the operands.

   The way to refer to the operands in CONDITION is to write
`operands[I]' for operand number I (as matched by `(match_operand I
...)').  Use the variable `insn' to refer to the last of the insns
being matched; use `prev_active_insn' to find the preceding insns.

   When optimizing computations with intermediate results, you can use
CONDITION to match only when the intermediate results are not used
elsewhere.  Use the C expression `dead_or_set_p (INSN, OP)', where INSN
is the insn in which you expect the value to be used for the last time
(from the value of `insn', together with use of `prev_nonnote_insn'),
and OP is the intermediate value (from `operands[I]').

   Applying the optimization means replacing the sequence of insns with
one new insn.  The TEMPLATE controls ultimate output of assembler code
for this combined insn.  It works exactly like the template of a
`define_insn'.  Operand numbers in this template are the same ones used
in matching the original sequence of insns.

   The result of a defined peephole optimizer does not need to match
any of the insn patterns in the machine description; it does not even
have an opportunity to match them.  The peephole optimizer definition
itself serves as the insn pattern to control how the insn is output.

   Defined peephole optimizers are run as assembler code is being
output, so the insns they produce are never combined or rearranged in
any way.

   Here is an example, taken from the 68000 machine description:

     (define_peephole
       [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4)))
        (set (match_operand:DF 0 "register_operand" "=f")
             (match_operand:DF 1 "register_operand" "ad"))]
       "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
       "*
     {
       rtx xoperands[2];
       xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
     #ifdef MOTOROLA
       output_asm_insn (\"move.l %1,(sp)\", xoperands);
       output_asm_insn (\"move.l %1,-(sp)\", operands);
       return \"fmove.d (sp)+,%0\";
     #else
       output_asm_insn (\"movel %1,sp@\", xoperands);
       output_asm_insn (\"movel %1,sp@-\", operands);
       return \"fmoved sp@+,%0\";
     #endif
     }
     ")

   The effect of this optimization is to change

     jbsr _foobar
     addql #4,sp
     movel d1,sp@-
     movel d0,sp@-
     fmoved sp@+,fp0

into

     jbsr _foobar
     movel d1,sp@
     movel d0,sp@-
     fmoved sp@+,fp0

   INSN-PATTERN-1 and so on look *almost* like the second operand of
`define_insn'.  There is one important difference: the second operand
of `define_insn' consists of one or more RTX's enclosed in square
brackets.  Usually, there is only one: then the same action can be
written as an element of a `define_peephole'.  But when there are
multiple actions in a `define_insn', they are implicitly enclosed in a
`parallel'.  Then you must explicitly write the `parallel', and the
square brackets within it, in the `define_peephole'.  Thus, if an insn
pattern looks like this,

     (define_insn "divmodsi4"
       [(set (match_operand:SI 0 "general_operand" "=d")
             (div:SI (match_operand:SI 1 "general_operand" "0")
                     (match_operand:SI 2 "general_operand" "dmsK")))
        (set (match_operand:SI 3 "general_operand" "=d")
             (mod:SI (match_dup 1) (match_dup 2)))]
       "TARGET_68020"
       "divsl%.l %2,%3:%0")

then the way to mention this insn in a peephole is as follows:

     (define_peephole
       [...
        (parallel
         [(set (match_operand:SI 0 "general_operand" "=d")
               (div:SI (match_operand:SI 1 "general_operand" "0")
                       (match_operand:SI 2 "general_operand" "dmsK")))
          (set (match_operand:SI 3 "general_operand" "=d")
               (mod:SI (match_dup 1) (match_dup 2)))])
        ...]
       ...)


automatically generated by info2www version 1.2.2.9