]>
Commit | Line | Data |
---|---|---|
c63539ff ML |
1 | .. |
2 | Copyright 1988-2022 Free Software Foundation, Inc. | |
3 | This is part of the GCC manual. | |
4 | For copying conditions, see the copyright.rst file. | |
5 | ||
6 | .. index:: define_subst | |
7 | ||
8 | .. _define-subst: | |
9 | ||
10 | RTL Templates Transformations | |
11 | ***************************** | |
12 | ||
13 | For some hardware architectures there are common cases when the RTL | |
14 | templates for the instructions can be derived from the other RTL | |
15 | templates using simple transformations. E.g., :samp:`i386.md` contains | |
16 | an RTL template for the ordinary ``sub`` instruction--- | |
17 | ``*subsi_1``, and for the ``sub`` instruction with subsequent | |
18 | zero-extension--- ``*subsi_1_zext``. Such cases can be easily | |
19 | implemented by a single meta-template capable of generating a modified | |
20 | case based on the initial one: | |
21 | ||
22 | .. index:: define_subst | |
23 | ||
24 | .. code-block:: | |
25 | ||
26 | (define_subst "name" | |
27 | [input-template] | |
28 | "condition" | |
29 | [output-template]) | |
30 | ||
31 | :samp:`{input-template}` is a pattern describing the source RTL template, | |
32 | which will be transformed. | |
33 | ||
34 | :samp:`{condition}` is a C expression that is conjunct with the condition | |
35 | from the input-template to generate a condition to be used in the | |
36 | output-template. | |
37 | ||
38 | :samp:`{output-template}` is a pattern that will be used in the resulting | |
39 | template. | |
40 | ||
41 | ``define_subst`` mechanism is tightly coupled with the notion of the | |
42 | subst attribute (see :ref:`subst-iterators`). The use of | |
43 | ``define_subst`` is triggered by a reference to a subst attribute in | |
44 | the transforming RTL template. This reference initiates duplication of | |
45 | the source RTL template and substitution of the attributes with their | |
46 | values. The source RTL template is left unchanged, while the copy is | |
47 | transformed by ``define_subst``. This transformation can fail in the | |
48 | case when the source RTL template is not matched against the | |
49 | input-template of the ``define_subst``. In such case the copy is | |
50 | deleted. | |
51 | ||
52 | ``define_subst`` can be used only in ``define_insn`` and | |
53 | ``define_expand``, it cannot be used in other expressions (e.g. in | |
54 | ``define_insn_and_split``). | |
55 | ||
56 | .. toctree:: | |
57 | :maxdepth: 2 | |
58 | ||
59 | ||
60 | .. index:: define_subst | |
61 | ||
62 | .. _define-subst-example: | |
63 | ||
64 | define_subst Example | |
65 | ^^^^^^^^^^^^^^^^^^^^ | |
66 | ||
67 | To illustrate how ``define_subst`` works, let us examine a simple | |
68 | template transformation. | |
69 | ||
70 | Suppose there are two kinds of instructions: one that touches flags and | |
71 | the other that does not. The instructions of the second type could be | |
72 | generated with the following ``define_subst`` : | |
73 | ||
74 | .. code-block:: | |
75 | ||
76 | (define_subst "add_clobber_subst" | |
77 | [(set (match_operand:SI 0 "" "") | |
78 | (match_operand:SI 1 "" ""))] | |
79 | "" | |
80 | [(set (match_dup 0) | |
81 | (match_dup 1)) | |
82 | (clobber (reg:CC FLAGS_REG))]) | |
83 | ||
84 | This ``define_subst`` can be applied to any RTL pattern containing | |
85 | ``set`` of mode SI and generates a copy with clobber when it is | |
86 | applied. | |
87 | ||
88 | Assume there is an RTL template for a ``max`` instruction to be used | |
89 | in ``define_subst`` mentioned above: | |
90 | ||
91 | .. code-block:: | |
92 | ||
93 | (define_insn "maxsi" | |
94 | [(set (match_operand:SI 0 "register_operand" "=r") | |
95 | (max:SI | |
96 | (match_operand:SI 1 "register_operand" "r") | |
97 | (match_operand:SI 2 "register_operand" "r")))] | |
98 | "" | |
99 | "max\t{%2, %1, %0|%0, %1, %2}" | |
100 | [...]) | |
101 | ||
102 | To mark the RTL template for ``define_subst`` application, | |
103 | subst-attributes are used. They should be declared in advance: | |
104 | ||
105 | .. code-block:: | |
106 | ||
107 | (define_subst_attr "add_clobber_name" "add_clobber_subst" "_noclobber" "_clobber") | |
108 | ||
109 | Here :samp:`add_clobber_name` is the attribute name, | |
110 | :samp:`add_clobber_subst` is the name of the corresponding | |
111 | ``define_subst``, the third argument (:samp:`_noclobber`) is the | |
112 | attribute value that would be substituted into the unchanged version of | |
113 | the source RTL template, and the last argument (:samp:`_clobber`) is the | |
114 | value that would be substituted into the second, transformed, | |
115 | version of the RTL template. | |
116 | ||
117 | Once the subst-attribute has been defined, it should be used in RTL | |
118 | templates which need to be processed by the ``define_subst``. So, | |
119 | the original RTL template should be changed: | |
120 | ||
121 | .. code-block:: | |
122 | ||
123 | (define_insn "maxsi<add_clobber_name>" | |
124 | [(set (match_operand:SI 0 "register_operand" "=r") | |
125 | (max:SI | |
126 | (match_operand:SI 1 "register_operand" "r") | |
127 | (match_operand:SI 2 "register_operand" "r")))] | |
128 | "" | |
129 | "max\t{%2, %1, %0|%0, %1, %2}" | |
130 | [...]) | |
131 | ||
132 | The result of the ``define_subst`` usage would look like the following: | |
133 | ||
134 | .. code-block:: | |
135 | ||
136 | (define_insn "maxsi_noclobber" | |
137 | [(set (match_operand:SI 0 "register_operand" "=r") | |
138 | (max:SI | |
139 | (match_operand:SI 1 "register_operand" "r") | |
140 | (match_operand:SI 2 "register_operand" "r")))] | |
141 | "" | |
142 | "max\t{%2, %1, %0|%0, %1, %2}" | |
143 | [...]) | |
144 | (define_insn "maxsi_clobber" | |
145 | [(set (match_operand:SI 0 "register_operand" "=r") | |
146 | (max:SI | |
147 | (match_operand:SI 1 "register_operand" "r") | |
148 | (match_operand:SI 2 "register_operand" "r"))) | |
149 | (clobber (reg:CC FLAGS_REG))] | |
150 | "" | |
151 | "max\t{%2, %1, %0|%0, %1, %2}" | |
152 | [...]) | |
153 | ||
154 | .. index:: define_subst | |
155 | ||
156 | .. _define-subst-pattern-matching: | |
157 | ||
158 | Pattern Matching in define_subst | |
159 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
160 | ||
161 | All expressions, allowed in ``define_insn`` or ``define_expand``, | |
162 | are allowed in the input-template of ``define_subst``, except | |
163 | ``match_par_dup``, ``match_scratch``, ``match_parallel``. The | |
164 | meanings of expressions in the input-template were changed: | |
165 | ||
166 | ``match_operand`` matches any expression (possibly, a subtree in | |
167 | RTL-template), if modes of the ``match_operand`` and this expression | |
168 | are the same, or mode of the ``match_operand`` is ``VOIDmode``, or | |
169 | this expression is ``match_dup``, ``match_op_dup``. If the | |
170 | expression is ``match_operand`` too, and predicate of | |
171 | ``match_operand`` from the input pattern is not empty, then the | |
172 | predicates are compared. That can be used for more accurate filtering | |
173 | of accepted RTL-templates. | |
174 | ||
175 | ``match_operator`` matches common operators (like ``plus``, | |
176 | ``minus``), ``unspec``, ``unspec_volatile`` operators and | |
177 | ``match_operator`` s from the original pattern if the modes match and | |
178 | ``match_operator`` from the input pattern has the same number of | |
179 | operands as the operator from the original pattern. | |
180 | ||
181 | .. index:: define_subst | |
182 | ||
183 | .. _define-subst-output-template: | |
184 | ||
185 | Generation of output template in define_subst | |
186 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
187 | ||
188 | If all necessary checks for ``define_subst`` application pass, a new | |
189 | RTL-pattern, based on the output-template, is created to replace the old | |
190 | template. Like in input-patterns, meanings of some RTL expressions are | |
191 | changed when they are used in output-patterns of a ``define_subst``. | |
192 | Thus, ``match_dup`` is used for copying the whole expression from the | |
193 | original pattern, which matched corresponding ``match_operand`` from | |
194 | the input pattern. | |
195 | ||
196 | ``match_dup N`` is used in the output template to be replaced with | |
197 | the expression from the original pattern, which matched | |
198 | ``match_operand N`` from the input pattern. As a consequence, | |
199 | ``match_dup`` cannot be used to point to ``match_operand`` s from | |
200 | the output pattern, it should always refer to a ``match_operand`` | |
201 | from the input pattern. If a ``match_dup N`` occurs more than once | |
202 | in the output template, its first occurrence is replaced with the | |
203 | expression from the original pattern, and the subsequent expressions | |
204 | are replaced with ``match_dup N``, i.e., a reference to the first | |
205 | expression. | |
206 | ||
207 | In the output template one can refer to the expressions from the | |
208 | original pattern and create new ones. For instance, some operands could | |
209 | be added by means of standard ``match_operand``. | |
210 | ||
211 | After replacing ``match_dup`` with some RTL-subtree from the original | |
212 | pattern, it could happen that several ``match_operand`` s in the | |
213 | output pattern have the same indexes. It is unknown, how many and what | |
214 | indexes would be used in the expression which would replace | |
215 | ``match_dup``, so such conflicts in indexes are inevitable. To | |
216 | overcome this issue, ``match_operands`` and ``match_operators``, | |
217 | which were introduced into the output pattern, are renumerated when all | |
218 | ``match_dup`` s are replaced. | |
219 | ||
220 | Number of alternatives in ``match_operand`` s introduced into the | |
221 | output template ``M`` could differ from the number of alternatives in | |
222 | the original pattern ``N``, so in the resultant pattern there would | |
223 | be ``N*M`` alternatives. Thus, constraints from the original pattern | |
224 | would be duplicated ``N`` times, constraints from the output pattern | |
3ed1b4ce | 225 | would be duplicated ``M`` times, producing all possible combinations. |