]>
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:: canonicalization of instructions, insn canonicalization | |
7 | ||
8 | .. _insn-canonicalizations: | |
9 | ||
10 | Canonicalization of Instructions | |
11 | ******************************** | |
12 | ||
13 | There are often cases where multiple RTL expressions could represent an | |
14 | operation performed by a single machine instruction. This situation is | |
15 | most commonly encountered with logical, branch, and multiply-accumulate | |
16 | instructions. In such cases, the compiler attempts to convert these | |
17 | multiple RTL expressions into a single canonical form to reduce the | |
18 | number of insn patterns required. | |
19 | ||
20 | In addition to algebraic simplifications, following canonicalizations | |
21 | are performed: | |
22 | ||
23 | * For commutative and comparison operators, a constant is always made the | |
24 | second operand. If a machine only supports a constant as the second | |
25 | operand, only patterns that match a constant in the second operand need | |
26 | be supplied. | |
27 | ||
28 | * For associative operators, a sequence of operators will always chain | |
29 | to the left; for instance, only the left operand of an integer ``plus`` | |
30 | can itself be a ``plus``. ``and``, ``ior``, ``xor``, | |
31 | ``plus``, ``mult``, ``smin``, ``smax``, ``umin``, and | |
32 | ``umax`` are associative when applied to integers, and sometimes to | |
33 | floating-point. | |
34 | ||
35 | .. index:: neg, canonicalization of, not, canonicalization of, mult, canonicalization of, plus, canonicalization of, minus, canonicalization of | |
36 | ||
37 | * For these operators, if only one operand is a ``neg``, ``not``, | |
38 | ``mult``, ``plus``, or ``minus`` expression, it will be the | |
39 | first operand. | |
40 | ||
41 | * In combinations of ``neg``, ``mult``, ``plus``, and | |
42 | ``minus``, the ``neg`` operations (if any) will be moved inside | |
43 | the operations as far as possible. For instance, | |
44 | ``(neg (mult A B))`` is canonicalized as ``(mult (neg A) B)``, but | |
45 | ``(plus (mult (neg B) C) A)`` is canonicalized as | |
46 | ``(minus A (mult B C))``. | |
47 | ||
48 | .. index:: compare, canonicalization of | |
49 | ||
50 | * For the ``compare`` operator, a constant is always the second operand | |
51 | if the first argument is a condition code register. | |
52 | ||
53 | * For instructions that inherently set a condition code register, the | |
54 | ``compare`` operator is always written as the first RTL expression of | |
55 | the ``parallel`` instruction pattern. For example, | |
56 | ||
57 | .. code-block:: | |
58 | ||
59 | (define_insn "" | |
60 | [(set (reg:CCZ FLAGS_REG) | |
61 | (compare:CCZ | |
62 | (plus:SI | |
63 | (match_operand:SI 1 "register_operand" "%r") | |
64 | (match_operand:SI 2 "register_operand" "r")) | |
65 | (const_int 0))) | |
66 | (set (match_operand:SI 0 "register_operand" "=r") | |
67 | (plus:SI (match_dup 1) (match_dup 2)))] | |
68 | "" | |
69 | "addl %0, %1, %2") | |
70 | ||
71 | * An operand of ``neg``, ``not``, ``mult``, ``plus``, or | |
72 | ``minus`` is made the first operand under the same conditions as | |
73 | above. | |
74 | ||
75 | * ``(ltu (plus ab) b)`` is converted to | |
76 | ``(ltu (plus ab) a)``. Likewise with ``geu`` instead | |
77 | of ``ltu``. | |
78 | ||
79 | * ``(minus x (const_int n))`` is converted to | |
80 | ``(plus x (const_int -n))``. | |
81 | ||
82 | * Within address computations (i.e., inside ``mem``), a left shift is | |
83 | converted into the appropriate multiplication by a power of two. | |
84 | ||
85 | .. index:: ior, canonicalization of, and, canonicalization of, De Morgan's law | |
86 | ||
87 | * De Morgan's Law is used to move bitwise negation inside a bitwise | |
88 | logical-and or logical-or operation. If this results in only one | |
89 | operand being a ``not`` expression, it will be the first one. | |
90 | ||
91 | A machine that has an instruction that performs a bitwise logical-and of one | |
92 | operand with the bitwise negation of the other should specify the pattern | |
93 | for that instruction as | |
94 | ||
95 | .. code-block:: | |
96 | ||
97 | (define_insn "" | |
98 | [(set (match_operand:m 0 ...) | |
99 | (and:m (not:m (match_operand:m 1 ...)) | |
100 | (match_operand:m 2 ...)))] | |
101 | "..." | |
102 | "...") | |
103 | ||
104 | Similarly, a pattern for a 'NAND' instruction should be written | |
105 | ||
106 | .. code-block:: | |
107 | ||
108 | (define_insn "" | |
109 | [(set (match_operand:m 0 ...) | |
110 | (ior:m (not:m (match_operand:m 1 ...)) | |
111 | (not:m (match_operand:m 2 ...))))] | |
112 | "..." | |
113 | "...") | |
114 | ||
115 | In both cases, it is not necessary to include patterns for the many | |
116 | logically equivalent RTL expressions. | |
117 | ||
118 | .. index:: xor, canonicalization of | |
119 | ||
120 | * The only possible RTL expressions involving both bitwise exclusive-or | |
121 | and bitwise negation are ``(xor:mxy)`` | |
122 | and ``(not:m (xor:mxy))``. | |
123 | ||
124 | * The sum of three items, one of which is a constant, will only appear in | |
125 | the form | |
126 | ||
127 | .. code-block:: c++ | |
128 | ||
129 | (plus:m (plus:m x y) constant) | |
130 | ||
131 | .. index:: zero_extract, canonicalization of, sign_extract, canonicalization of | |
132 | ||
133 | * Equality comparisons of a group of bits (usually a single bit) with zero | |
134 | will be written using ``zero_extract`` rather than the equivalent | |
135 | ``and`` or ``sign_extract`` operations. | |
136 | ||
137 | .. index:: mult, canonicalization of | |
138 | ||
139 | * ``(sign_extend:m1 (mult:m2 (sign_extend:m2x) | |
140 | (sign_extend:m2y)))`` is converted to ``(mult:m1 | |
141 | (sign_extend:m1x) (sign_extend:m1y))``, and likewise | |
142 | for ``zero_extend``. | |
143 | ||
144 | * ``(sign_extend:m1 (mult:m2 (ashiftrt:m2xs) (sign_extend:m2y)))`` is converted | |
145 | to ``(mult:m1 (sign_extend:m1 (ashiftrt:m2xs)) (sign_extend:m1y))``, and likewise for | |
146 | patterns using ``zero_extend`` and ``lshiftrt``. If the second | |
147 | operand of ``mult`` is also a shift, then that is extended also. | |
148 | This transformation is only applied when it can be proven that the | |
149 | original operation had sufficient precision to prevent overflow. | |
150 | ||
151 | Further canonicalization rules are defined in the function | |
3ed1b4ce | 152 | ``commutative_operand_precedence`` in :samp:`gcc/rtlanal.cc`. |