define_subst
Example
To illustrate how define_subst
works, let us examine a simple
template transformation.
Suppose there are two kinds of instructions: one that touches flags and
the other that does not. The instructions of the second type could be
generated with the following define_subst
:
(define_subst "add_clobber_subst" [(set (match_operand:SI 0 "" "") (match_operand:SI 1 "" ""))] "" [(set (match_dup 0) (match_dup 1)) (clobber (reg:CC FLAGS_REG))]
This define_subst
can be applied to any RTL pattern containing
set
of mode SI and generates a copy with clobber when it is
applied.
Assume there is an RTL template for a max
instruction to be used
in define_subst
mentioned above:
(define_insn "maxsi" [(set (match_operand:SI 0 "register_operand" "=r") (max:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "register_operand" "r")))] "" "max\t{%2, %1, %0|%0, %1, %2}" [...])
To mark the RTL template for define_subst
application,
subst-attributes are used. They should be declared in advance:
(define_subst_attr "add_clobber_name" "add_clobber_subst" "_noclobber" "_clobber")
Here ‘add_clobber_name’ is the attribute name,
‘add_clobber_subst’ is the name of the corresponding
define_subst
, the third argument (‘_noclobber’) is the
attribute value that would be substituted into the unchanged version of
the source RTL template, and the last argument (‘_clobber’) is the
value that would be substituted into the second, transformed,
version of the RTL template.
Once the subst-attribute has been defined, it should be used in RTL
templates which need to be processed by the define_subst
. So,
the original RTL template should be changed:
(define_insn "maxsi<add_clobber_name>" [(set (match_operand:SI 0 "register_operand" "=r") (max:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "register_operand" "r")))] "" "max\t{%2, %1, %0|%0, %1, %2}" [...])
The result of the define_subst
usage would look like the following:
(define_insn "maxsi_noclobber" [(set (match_operand:SI 0 "register_operand" "=r") (max:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "register_operand" "r")))] "" "max\t{%2, %1, %0|%0, %1, %2}" [...]) (define_insn "maxsi_clobber" [(set (match_operand:SI 0 "register_operand" "=r") (max:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "register_operand" "r"))) (clobber (reg:CC FLAGS_REG))] "" "max\t{%2, %1, %0|%0, %1, %2}" [...])