1*38fd1498Szrj /* Generate code from machine description to recognize rtl as insns.
2*38fd1498Szrj Copyright (C) 1987-2018 Free Software Foundation, Inc.
3*38fd1498Szrj
4*38fd1498Szrj This file is part of GCC.
5*38fd1498Szrj
6*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it
7*38fd1498Szrj under the terms of the GNU General Public License as published by
8*38fd1498Szrj the Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj any later version.
10*38fd1498Szrj
11*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT
12*38fd1498Szrj ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13*38fd1498Szrj or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14*38fd1498Szrj License for more details.
15*38fd1498Szrj
16*38fd1498Szrj You should have received a copy of the GNU General Public License
17*38fd1498Szrj along with GCC; see the file COPYING3. If not see
18*38fd1498Szrj <http://www.gnu.org/licenses/>. */
19*38fd1498Szrj
20*38fd1498Szrj
21*38fd1498Szrj /* This program is used to produce insn-recog.c, which contains a
22*38fd1498Szrj function called `recog' plus its subroutines. These functions
23*38fd1498Szrj contain a decision tree that recognizes whether an rtx, the
24*38fd1498Szrj argument given to recog, is a valid instruction.
25*38fd1498Szrj
26*38fd1498Szrj recog returns -1 if the rtx is not valid. If the rtx is valid,
27*38fd1498Szrj recog returns a nonnegative number which is the insn code number
28*38fd1498Szrj for the pattern that matched. This is the same as the order in the
29*38fd1498Szrj machine description of the entry that matched. This number can be
30*38fd1498Szrj used as an index into various insn_* tables, such as insn_template,
31*38fd1498Szrj insn_outfun, and insn_n_operands (found in insn-output.c).
32*38fd1498Szrj
33*38fd1498Szrj The third argument to recog is an optional pointer to an int. If
34*38fd1498Szrj present, recog will accept a pattern if it matches except for
35*38fd1498Szrj missing CLOBBER expressions at the end. In that case, the value
36*38fd1498Szrj pointed to by the optional pointer will be set to the number of
37*38fd1498Szrj CLOBBERs that need to be added (it should be initialized to zero by
38*38fd1498Szrj the caller). If it is set nonzero, the caller should allocate a
39*38fd1498Szrj PARALLEL of the appropriate size, copy the initial entries, and
40*38fd1498Szrj call add_clobbers (found in insn-emit.c) to fill in the CLOBBERs.
41*38fd1498Szrj
42*38fd1498Szrj This program also generates the function `split_insns', which
43*38fd1498Szrj returns 0 if the rtl could not be split, or it returns the split
44*38fd1498Szrj rtl as an INSN list.
45*38fd1498Szrj
46*38fd1498Szrj This program also generates the function `peephole2_insns', which
47*38fd1498Szrj returns 0 if the rtl could not be matched. If there was a match,
48*38fd1498Szrj the new rtl is returned in an INSN list, and LAST_INSN will point
49*38fd1498Szrj to the last recognized insn in the old sequence.
50*38fd1498Szrj
51*38fd1498Szrj
52*38fd1498Szrj At a high level, the algorithm used in this file is as follows:
53*38fd1498Szrj
54*38fd1498Szrj 1. Build up a decision tree for each routine, using the following
55*38fd1498Szrj approach to matching an rtx:
56*38fd1498Szrj
57*38fd1498Szrj - First determine the "shape" of the rtx, based on GET_CODE,
58*38fd1498Szrj XVECLEN and XINT. This phase examines SET_SRCs before SET_DESTs
59*38fd1498Szrj since SET_SRCs tend to be more distinctive. It examines other
60*38fd1498Szrj operands in numerical order, since the canonicalization rules
61*38fd1498Szrj prefer putting complex operands of commutative operators first.
62*38fd1498Szrj
63*38fd1498Szrj - Next check modes and predicates. This phase examines all
64*38fd1498Szrj operands in numerical order, even for SETs, since the mode of a
65*38fd1498Szrj SET_DEST is exact while the mode of a SET_SRC can be VOIDmode
66*38fd1498Szrj for constant integers.
67*38fd1498Szrj
68*38fd1498Szrj - Next check match_dups.
69*38fd1498Szrj
70*38fd1498Szrj - Finally check the C condition and (where appropriate) pnum_clobbers.
71*38fd1498Szrj
72*38fd1498Szrj 2. Try to optimize the tree by removing redundant tests, CSEing tests,
73*38fd1498Szrj folding tests together, etc.
74*38fd1498Szrj
75*38fd1498Szrj 3. Look for common subtrees and split them out into "pattern" routines.
76*38fd1498Szrj These common subtrees can be identical or they can differ in mode,
77*38fd1498Szrj code, or integer (usually an UNSPEC or UNSPEC_VOLATILE code).
78*38fd1498Szrj In the latter case the users of the pattern routine pass the
79*38fd1498Szrj appropriate mode, etc., as argument. For example, if two patterns
80*38fd1498Szrj contain:
81*38fd1498Szrj
82*38fd1498Szrj (plus:SI (match_operand:SI 1 "register_operand")
83*38fd1498Szrj (match_operand:SI 2 "register_operand"))
84*38fd1498Szrj
85*38fd1498Szrj we can split the associated matching code out into a subroutine.
86*38fd1498Szrj If a pattern contains:
87*38fd1498Szrj
88*38fd1498Szrj (minus:DI (match_operand:DI 1 "register_operand")
89*38fd1498Szrj (match_operand:DI 2 "register_operand"))
90*38fd1498Szrj
91*38fd1498Szrj then we can consider using the same matching routine for both
92*38fd1498Szrj the plus and minus expressions, passing PLUS and SImode in the
93*38fd1498Szrj former case and MINUS and DImode in the latter case.
94*38fd1498Szrj
95*38fd1498Szrj The main aim of this phase is to reduce the compile time of the
96*38fd1498Szrj insn-recog.c code and to reduce the amount of object code in
97*38fd1498Szrj insn-recog.o.
98*38fd1498Szrj
99*38fd1498Szrj 4. Split the matching trees into functions, trying to limit the
100*38fd1498Szrj size of each function to a sensible amount.
101*38fd1498Szrj
102*38fd1498Szrj Again, the main aim of this phase is to reduce the compile time
103*38fd1498Szrj of insn-recog.c. (It doesn't help with the size of insn-recog.o.)
104*38fd1498Szrj
105*38fd1498Szrj 5. Write out C++ code for each function. */
106*38fd1498Szrj
107*38fd1498Szrj #include "bconfig.h"
108*38fd1498Szrj #define INCLUDE_ALGORITHM
109*38fd1498Szrj #include "system.h"
110*38fd1498Szrj #include "coretypes.h"
111*38fd1498Szrj #include "tm.h"
112*38fd1498Szrj #include "rtl.h"
113*38fd1498Szrj #include "errors.h"
114*38fd1498Szrj #include "read-md.h"
115*38fd1498Szrj #include "gensupport.h"
116*38fd1498Szrj
117*38fd1498Szrj #undef GENERATOR_FILE
118*38fd1498Szrj enum true_rtx_doe {
119*38fd1498Szrj #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) TRUE_##ENUM,
120*38fd1498Szrj #include "rtl.def"
121*38fd1498Szrj #undef DEF_RTL_EXPR
122*38fd1498Szrj FIRST_GENERATOR_RTX_CODE
123*38fd1498Szrj };
124*38fd1498Szrj #define NUM_TRUE_RTX_CODE ((int) FIRST_GENERATOR_RTX_CODE)
125*38fd1498Szrj #define GENERATOR_FILE 1
126*38fd1498Szrj
127*38fd1498Szrj /* Debugging variables to control which optimizations are performed.
128*38fd1498Szrj Note that disabling merge_states_p leads to very large output. */
129*38fd1498Szrj static const bool merge_states_p = true;
130*38fd1498Szrj static const bool collapse_optional_decisions_p = true;
131*38fd1498Szrj static const bool cse_tests_p = true;
132*38fd1498Szrj static const bool simplify_tests_p = true;
133*38fd1498Szrj static const bool use_operand_variables_p = true;
134*38fd1498Szrj static const bool use_subroutines_p = true;
135*38fd1498Szrj static const bool use_pattern_routines_p = true;
136*38fd1498Szrj
137*38fd1498Szrj /* Whether to add comments for optional tests that we decided to keep.
138*38fd1498Szrj Can be useful when debugging the generator itself but is noise when
139*38fd1498Szrj debugging the generated code. */
140*38fd1498Szrj static const bool mark_optional_transitions_p = false;
141*38fd1498Szrj
142*38fd1498Szrj /* Whether pattern routines should calculate positions relative to their
143*38fd1498Szrj rtx parameter rather than use absolute positions. This e.g. allows
144*38fd1498Szrj a pattern routine to be shared between a plain SET and a PARALLEL
145*38fd1498Szrj that includes a SET.
146*38fd1498Szrj
147*38fd1498Szrj In principle it sounds like this should be useful, especially for
148*38fd1498Szrj recog_for_combine, where the plain SET form is generated automatically
149*38fd1498Szrj from a PARALLEL of a single SET and some CLOBBERs. In practice it doesn't
150*38fd1498Szrj seem to help much and leads to slightly bigger object files. */
151*38fd1498Szrj static const bool relative_patterns_p = false;
152*38fd1498Szrj
153*38fd1498Szrj /* Whether pattern routines should be allowed to test whether pnum_clobbers
154*38fd1498Szrj is null. This requires passing pnum_clobbers around as a parameter. */
155*38fd1498Szrj static const bool pattern_have_num_clobbers_p = true;
156*38fd1498Szrj
157*38fd1498Szrj /* Whether pattern routines should be allowed to test .md file C conditions.
158*38fd1498Szrj This requires passing insn around as a parameter, in case the C
159*38fd1498Szrj condition refers to it. In practice this tends to lead to bigger
160*38fd1498Szrj object files. */
161*38fd1498Szrj static const bool pattern_c_test_p = false;
162*38fd1498Szrj
163*38fd1498Szrj /* Whether to require each parameter passed to a pattern routine to be
164*38fd1498Szrj unique. Disabling this check for example allows unary operators with
165*38fd1498Szrj matching modes (like NEG) and unary operators with mismatched modes
166*38fd1498Szrj (like ZERO_EXTEND) to be matched by a single pattern. However, we then
167*38fd1498Szrj often have cases where the same value is passed too many times. */
168*38fd1498Szrj static const bool force_unique_params_p = true;
169*38fd1498Szrj
170*38fd1498Szrj /* The maximum (approximate) depth of block nesting that an individual
171*38fd1498Szrj routine or subroutine should have. This limit is about keeping the
172*38fd1498Szrj output readable rather than reducing compile time. */
173*38fd1498Szrj static const unsigned int MAX_DEPTH = 6;
174*38fd1498Szrj
175*38fd1498Szrj /* The minimum number of pseudo-statements that a state must have before
176*38fd1498Szrj we split it out into a subroutine. */
177*38fd1498Szrj static const unsigned int MIN_NUM_STATEMENTS = 5;
178*38fd1498Szrj
179*38fd1498Szrj /* The number of pseudo-statements a state can have before we consider
180*38fd1498Szrj splitting out substates into subroutines. This limit is about avoiding
181*38fd1498Szrj compile-time problems with very big functions (and also about keeping
182*38fd1498Szrj functions within --param optimization limits, etc.). */
183*38fd1498Szrj static const unsigned int MAX_NUM_STATEMENTS = 200;
184*38fd1498Szrj
185*38fd1498Szrj /* The minimum number of pseudo-statements that can be used in a pattern
186*38fd1498Szrj routine. */
187*38fd1498Szrj static const unsigned int MIN_COMBINE_COST = 4;
188*38fd1498Szrj
189*38fd1498Szrj /* The maximum number of arguments that a pattern routine can have.
190*38fd1498Szrj The idea is to prevent one pattern getting a ridiculous number of
191*38fd1498Szrj arguments when it would be more beneficial to have a separate pattern
192*38fd1498Szrj routine instead. */
193*38fd1498Szrj static const unsigned int MAX_PATTERN_PARAMS = 5;
194*38fd1498Szrj
195*38fd1498Szrj /* The maximum operand number plus one. */
196*38fd1498Szrj int num_operands;
197*38fd1498Szrj
198*38fd1498Szrj /* Ways of obtaining an rtx to be tested. */
199*38fd1498Szrj enum position_type {
200*38fd1498Szrj /* PATTERN (peep2_next_insn (ARG)). */
201*38fd1498Szrj POS_PEEP2_INSN,
202*38fd1498Szrj
203*38fd1498Szrj /* XEXP (BASE, ARG). */
204*38fd1498Szrj POS_XEXP,
205*38fd1498Szrj
206*38fd1498Szrj /* XVECEXP (BASE, 0, ARG). */
207*38fd1498Szrj POS_XVECEXP0
208*38fd1498Szrj };
209*38fd1498Szrj
210*38fd1498Szrj /* The position of an rtx relative to X0. Each useful position is
211*38fd1498Szrj represented by exactly one instance of this structure. */
212*38fd1498Szrj struct position
213*38fd1498Szrj {
214*38fd1498Szrj /* The parent rtx. This is the root position for POS_PEEP2_INSNs. */
215*38fd1498Szrj struct position *base;
216*38fd1498Szrj
217*38fd1498Szrj /* A position with the same BASE and TYPE, but with the next value
218*38fd1498Szrj of ARG. */
219*38fd1498Szrj struct position *next;
220*38fd1498Szrj
221*38fd1498Szrj /* A list of all POS_XEXP positions that use this one as their base,
222*38fd1498Szrj chained by NEXT fields. The first entry represents XEXP (this, 0),
223*38fd1498Szrj the second represents XEXP (this, 1), and so on. */
224*38fd1498Szrj struct position *xexps;
225*38fd1498Szrj
226*38fd1498Szrj /* A list of POS_XVECEXP0 positions that use this one as their base,
227*38fd1498Szrj chained by NEXT fields. The first entry represents XVECEXP (this, 0, 0),
228*38fd1498Szrj the second represents XVECEXP (this, 0, 1), and so on. */
229*38fd1498Szrj struct position *xvecexp0s;
230*38fd1498Szrj
231*38fd1498Szrj /* The type of position. */
232*38fd1498Szrj enum position_type type;
233*38fd1498Szrj
234*38fd1498Szrj /* The argument to TYPE (shown as ARG in the position_type comments). */
235*38fd1498Szrj int arg;
236*38fd1498Szrj
237*38fd1498Szrj /* The instruction to which the position belongs. */
238*38fd1498Szrj unsigned int insn_id;
239*38fd1498Szrj
240*38fd1498Szrj /* The depth of this position relative to the instruction pattern.
241*38fd1498Szrj E.g. if the instruction pattern is a SET, the SET itself has a
242*38fd1498Szrj depth of 0 while the SET_DEST and SET_SRC have depths of 1. */
243*38fd1498Szrj unsigned int depth;
244*38fd1498Szrj
245*38fd1498Szrj /* A unique identifier for this position. */
246*38fd1498Szrj unsigned int id;
247*38fd1498Szrj };
248*38fd1498Szrj
249*38fd1498Szrj enum routine_type {
250*38fd1498Szrj SUBPATTERN, RECOG, SPLIT, PEEPHOLE2
251*38fd1498Szrj };
252*38fd1498Szrj
253*38fd1498Szrj /* The root position (x0). */
254*38fd1498Szrj static struct position root_pos;
255*38fd1498Szrj
256*38fd1498Szrj /* The number of positions created. Also one higher than the maximum
257*38fd1498Szrj position id. */
258*38fd1498Szrj static unsigned int num_positions = 1;
259*38fd1498Szrj
260*38fd1498Szrj /* A list of all POS_PEEP2_INSNs. The entry for insn 0 is the root position,
261*38fd1498Szrj since we are given that instruction's pattern as x0. */
262*38fd1498Szrj static struct position *peep2_insn_pos_list = &root_pos;
263*38fd1498Szrj
264*38fd1498Szrj /* Return a position with the given BASE, TYPE and ARG. NEXT_PTR
265*38fd1498Szrj points to where the unique object that represents the position
266*38fd1498Szrj should be stored. Create the object if it doesn't already exist,
267*38fd1498Szrj otherwise reuse the object that is already there. */
268*38fd1498Szrj
269*38fd1498Szrj static struct position *
next_position(struct position ** next_ptr,struct position * base,enum position_type type,int arg)270*38fd1498Szrj next_position (struct position **next_ptr, struct position *base,
271*38fd1498Szrj enum position_type type, int arg)
272*38fd1498Szrj {
273*38fd1498Szrj struct position *pos;
274*38fd1498Szrj
275*38fd1498Szrj pos = *next_ptr;
276*38fd1498Szrj if (!pos)
277*38fd1498Szrj {
278*38fd1498Szrj pos = XCNEW (struct position);
279*38fd1498Szrj pos->type = type;
280*38fd1498Szrj pos->arg = arg;
281*38fd1498Szrj if (type == POS_PEEP2_INSN)
282*38fd1498Szrj {
283*38fd1498Szrj pos->base = 0;
284*38fd1498Szrj pos->insn_id = arg;
285*38fd1498Szrj pos->depth = base->depth;
286*38fd1498Szrj }
287*38fd1498Szrj else
288*38fd1498Szrj {
289*38fd1498Szrj pos->base = base;
290*38fd1498Szrj pos->insn_id = base->insn_id;
291*38fd1498Szrj pos->depth = base->depth + 1;
292*38fd1498Szrj }
293*38fd1498Szrj pos->id = num_positions++;
294*38fd1498Szrj *next_ptr = pos;
295*38fd1498Szrj }
296*38fd1498Szrj return pos;
297*38fd1498Szrj }
298*38fd1498Szrj
299*38fd1498Szrj /* Compare positions POS1 and POS2 lexicographically. */
300*38fd1498Szrj
301*38fd1498Szrj static int
compare_positions(struct position * pos1,struct position * pos2)302*38fd1498Szrj compare_positions (struct position *pos1, struct position *pos2)
303*38fd1498Szrj {
304*38fd1498Szrj int diff;
305*38fd1498Szrj
306*38fd1498Szrj diff = pos1->depth - pos2->depth;
307*38fd1498Szrj if (diff < 0)
308*38fd1498Szrj do
309*38fd1498Szrj pos2 = pos2->base;
310*38fd1498Szrj while (pos1->depth != pos2->depth);
311*38fd1498Szrj else if (diff > 0)
312*38fd1498Szrj do
313*38fd1498Szrj pos1 = pos1->base;
314*38fd1498Szrj while (pos1->depth != pos2->depth);
315*38fd1498Szrj while (pos1 != pos2)
316*38fd1498Szrj {
317*38fd1498Szrj diff = (int) pos1->type - (int) pos2->type;
318*38fd1498Szrj if (diff == 0)
319*38fd1498Szrj diff = pos1->arg - pos2->arg;
320*38fd1498Szrj pos1 = pos1->base;
321*38fd1498Szrj pos2 = pos2->base;
322*38fd1498Szrj }
323*38fd1498Szrj return diff;
324*38fd1498Szrj }
325*38fd1498Szrj
326*38fd1498Szrj /* Return the most deeply-nested position that is common to both
327*38fd1498Szrj POS1 and POS2. If the positions are from different instructions,
328*38fd1498Szrj return the one with the lowest insn_id. */
329*38fd1498Szrj
330*38fd1498Szrj static struct position *
common_position(struct position * pos1,struct position * pos2)331*38fd1498Szrj common_position (struct position *pos1, struct position *pos2)
332*38fd1498Szrj {
333*38fd1498Szrj if (pos1->insn_id != pos2->insn_id)
334*38fd1498Szrj return pos1->insn_id < pos2->insn_id ? pos1 : pos2;
335*38fd1498Szrj if (pos1->depth > pos2->depth)
336*38fd1498Szrj std::swap (pos1, pos2);
337*38fd1498Szrj while (pos1->depth != pos2->depth)
338*38fd1498Szrj pos2 = pos2->base;
339*38fd1498Szrj while (pos1 != pos2)
340*38fd1498Szrj {
341*38fd1498Szrj pos1 = pos1->base;
342*38fd1498Szrj pos2 = pos2->base;
343*38fd1498Szrj }
344*38fd1498Szrj return pos1;
345*38fd1498Szrj }
346*38fd1498Szrj
347*38fd1498Szrj /* Search for and return operand N, stop when reaching node STOP. */
348*38fd1498Szrj
349*38fd1498Szrj static rtx
find_operand(rtx pattern,int n,rtx stop)350*38fd1498Szrj find_operand (rtx pattern, int n, rtx stop)
351*38fd1498Szrj {
352*38fd1498Szrj const char *fmt;
353*38fd1498Szrj RTX_CODE code;
354*38fd1498Szrj int i, j, len;
355*38fd1498Szrj rtx r;
356*38fd1498Szrj
357*38fd1498Szrj if (pattern == stop)
358*38fd1498Szrj return stop;
359*38fd1498Szrj
360*38fd1498Szrj code = GET_CODE (pattern);
361*38fd1498Szrj if ((code == MATCH_SCRATCH
362*38fd1498Szrj || code == MATCH_OPERAND
363*38fd1498Szrj || code == MATCH_OPERATOR
364*38fd1498Szrj || code == MATCH_PARALLEL)
365*38fd1498Szrj && XINT (pattern, 0) == n)
366*38fd1498Szrj return pattern;
367*38fd1498Szrj
368*38fd1498Szrj fmt = GET_RTX_FORMAT (code);
369*38fd1498Szrj len = GET_RTX_LENGTH (code);
370*38fd1498Szrj for (i = 0; i < len; i++)
371*38fd1498Szrj {
372*38fd1498Szrj switch (fmt[i])
373*38fd1498Szrj {
374*38fd1498Szrj case 'e': case 'u':
375*38fd1498Szrj if ((r = find_operand (XEXP (pattern, i), n, stop)) != NULL_RTX)
376*38fd1498Szrj return r;
377*38fd1498Szrj break;
378*38fd1498Szrj
379*38fd1498Szrj case 'V':
380*38fd1498Szrj if (! XVEC (pattern, i))
381*38fd1498Szrj break;
382*38fd1498Szrj /* Fall through. */
383*38fd1498Szrj
384*38fd1498Szrj case 'E':
385*38fd1498Szrj for (j = 0; j < XVECLEN (pattern, i); j++)
386*38fd1498Szrj if ((r = find_operand (XVECEXP (pattern, i, j), n, stop))
387*38fd1498Szrj != NULL_RTX)
388*38fd1498Szrj return r;
389*38fd1498Szrj break;
390*38fd1498Szrj
391*38fd1498Szrj case 'r': case 'p': case 'i': case 'w': case '0': case 's':
392*38fd1498Szrj break;
393*38fd1498Szrj
394*38fd1498Szrj default:
395*38fd1498Szrj gcc_unreachable ();
396*38fd1498Szrj }
397*38fd1498Szrj }
398*38fd1498Szrj
399*38fd1498Szrj return NULL;
400*38fd1498Szrj }
401*38fd1498Szrj
402*38fd1498Szrj /* Search for and return operand M, such that it has a matching
403*38fd1498Szrj constraint for operand N. */
404*38fd1498Szrj
405*38fd1498Szrj static rtx
find_matching_operand(rtx pattern,int n)406*38fd1498Szrj find_matching_operand (rtx pattern, int n)
407*38fd1498Szrj {
408*38fd1498Szrj const char *fmt;
409*38fd1498Szrj RTX_CODE code;
410*38fd1498Szrj int i, j, len;
411*38fd1498Szrj rtx r;
412*38fd1498Szrj
413*38fd1498Szrj code = GET_CODE (pattern);
414*38fd1498Szrj if (code == MATCH_OPERAND
415*38fd1498Szrj && (XSTR (pattern, 2)[0] == '0' + n
416*38fd1498Szrj || (XSTR (pattern, 2)[0] == '%'
417*38fd1498Szrj && XSTR (pattern, 2)[1] == '0' + n)))
418*38fd1498Szrj return pattern;
419*38fd1498Szrj
420*38fd1498Szrj fmt = GET_RTX_FORMAT (code);
421*38fd1498Szrj len = GET_RTX_LENGTH (code);
422*38fd1498Szrj for (i = 0; i < len; i++)
423*38fd1498Szrj {
424*38fd1498Szrj switch (fmt[i])
425*38fd1498Szrj {
426*38fd1498Szrj case 'e': case 'u':
427*38fd1498Szrj if ((r = find_matching_operand (XEXP (pattern, i), n)))
428*38fd1498Szrj return r;
429*38fd1498Szrj break;
430*38fd1498Szrj
431*38fd1498Szrj case 'V':
432*38fd1498Szrj if (! XVEC (pattern, i))
433*38fd1498Szrj break;
434*38fd1498Szrj /* Fall through. */
435*38fd1498Szrj
436*38fd1498Szrj case 'E':
437*38fd1498Szrj for (j = 0; j < XVECLEN (pattern, i); j++)
438*38fd1498Szrj if ((r = find_matching_operand (XVECEXP (pattern, i, j), n)))
439*38fd1498Szrj return r;
440*38fd1498Szrj break;
441*38fd1498Szrj
442*38fd1498Szrj case 'r': case 'p': case 'i': case 'w': case '0': case 's':
443*38fd1498Szrj break;
444*38fd1498Szrj
445*38fd1498Szrj default:
446*38fd1498Szrj gcc_unreachable ();
447*38fd1498Szrj }
448*38fd1498Szrj }
449*38fd1498Szrj
450*38fd1498Szrj return NULL;
451*38fd1498Szrj }
452*38fd1498Szrj
453*38fd1498Szrj /* In DEFINE_EXPAND, DEFINE_SPLIT, and DEFINE_PEEPHOLE2, we
454*38fd1498Szrj don't use the MATCH_OPERAND constraint, only the predicate.
455*38fd1498Szrj This is confusing to folks doing new ports, so help them
456*38fd1498Szrj not make the mistake. */
457*38fd1498Szrj
458*38fd1498Szrj static bool
constraints_supported_in_insn_p(rtx insn)459*38fd1498Szrj constraints_supported_in_insn_p (rtx insn)
460*38fd1498Szrj {
461*38fd1498Szrj return !(GET_CODE (insn) == DEFINE_EXPAND
462*38fd1498Szrj || GET_CODE (insn) == DEFINE_SPLIT
463*38fd1498Szrj || GET_CODE (insn) == DEFINE_PEEPHOLE2);
464*38fd1498Szrj }
465*38fd1498Szrj
466*38fd1498Szrj /* Return the name of the predicate matched by MATCH_RTX. */
467*38fd1498Szrj
468*38fd1498Szrj static const char *
predicate_name(rtx match_rtx)469*38fd1498Szrj predicate_name (rtx match_rtx)
470*38fd1498Szrj {
471*38fd1498Szrj if (GET_CODE (match_rtx) == MATCH_SCRATCH)
472*38fd1498Szrj return "scratch_operand";
473*38fd1498Szrj else
474*38fd1498Szrj return XSTR (match_rtx, 1);
475*38fd1498Szrj }
476*38fd1498Szrj
477*38fd1498Szrj /* Return true if OPERAND is a MATCH_OPERAND using a special predicate
478*38fd1498Szrj function. */
479*38fd1498Szrj
480*38fd1498Szrj static bool
special_predicate_operand_p(rtx operand)481*38fd1498Szrj special_predicate_operand_p (rtx operand)
482*38fd1498Szrj {
483*38fd1498Szrj if (GET_CODE (operand) == MATCH_OPERAND)
484*38fd1498Szrj {
485*38fd1498Szrj const char *pred_name = predicate_name (operand);
486*38fd1498Szrj if (pred_name[0] != 0)
487*38fd1498Szrj {
488*38fd1498Szrj const struct pred_data *pred;
489*38fd1498Szrj
490*38fd1498Szrj pred = lookup_predicate (pred_name);
491*38fd1498Szrj return pred != NULL && pred->special;
492*38fd1498Szrj }
493*38fd1498Szrj }
494*38fd1498Szrj
495*38fd1498Szrj return false;
496*38fd1498Szrj }
497*38fd1498Szrj
498*38fd1498Szrj /* Check for various errors in PATTERN, which is part of INFO.
499*38fd1498Szrj SET is nonnull for a destination, and is the complete set pattern.
500*38fd1498Szrj SET_CODE is '=' for normal sets, and '+' within a context that
501*38fd1498Szrj requires in-out constraints. */
502*38fd1498Szrj
503*38fd1498Szrj static void
validate_pattern(rtx pattern,md_rtx_info * info,rtx set,int set_code)504*38fd1498Szrj validate_pattern (rtx pattern, md_rtx_info *info, rtx set, int set_code)
505*38fd1498Szrj {
506*38fd1498Szrj const char *fmt;
507*38fd1498Szrj RTX_CODE code;
508*38fd1498Szrj size_t i, len;
509*38fd1498Szrj int j;
510*38fd1498Szrj
511*38fd1498Szrj code = GET_CODE (pattern);
512*38fd1498Szrj switch (code)
513*38fd1498Szrj {
514*38fd1498Szrj case MATCH_SCRATCH:
515*38fd1498Szrj {
516*38fd1498Szrj const char constraints0 = XSTR (pattern, 1)[0];
517*38fd1498Szrj
518*38fd1498Szrj if (!constraints_supported_in_insn_p (info->def))
519*38fd1498Szrj {
520*38fd1498Szrj if (constraints0)
521*38fd1498Szrj {
522*38fd1498Szrj error_at (info->loc, "constraints not supported in %s",
523*38fd1498Szrj GET_RTX_NAME (GET_CODE (info->def)));
524*38fd1498Szrj }
525*38fd1498Szrj return;
526*38fd1498Szrj }
527*38fd1498Szrj
528*38fd1498Szrj /* If a MATCH_SCRATCH is used in a context requiring an write-only
529*38fd1498Szrj or read/write register, validate that. */
530*38fd1498Szrj if (set_code == '='
531*38fd1498Szrj && constraints0
532*38fd1498Szrj && constraints0 != '='
533*38fd1498Szrj && constraints0 != '+')
534*38fd1498Szrj {
535*38fd1498Szrj error_at (info->loc, "operand %d missing output reload",
536*38fd1498Szrj XINT (pattern, 0));
537*38fd1498Szrj }
538*38fd1498Szrj return;
539*38fd1498Szrj }
540*38fd1498Szrj case MATCH_DUP:
541*38fd1498Szrj case MATCH_OP_DUP:
542*38fd1498Szrj case MATCH_PAR_DUP:
543*38fd1498Szrj if (find_operand (info->def, XINT (pattern, 0), pattern) == pattern)
544*38fd1498Szrj error_at (info->loc, "operand %i duplicated before defined",
545*38fd1498Szrj XINT (pattern, 0));
546*38fd1498Szrj break;
547*38fd1498Szrj case MATCH_OPERAND:
548*38fd1498Szrj case MATCH_OPERATOR:
549*38fd1498Szrj {
550*38fd1498Szrj const char *pred_name = XSTR (pattern, 1);
551*38fd1498Szrj const struct pred_data *pred;
552*38fd1498Szrj const char *c_test;
553*38fd1498Szrj
554*38fd1498Szrj c_test = get_c_test (info->def);
555*38fd1498Szrj
556*38fd1498Szrj if (pred_name[0] != 0)
557*38fd1498Szrj {
558*38fd1498Szrj pred = lookup_predicate (pred_name);
559*38fd1498Szrj if (!pred)
560*38fd1498Szrj error_at (info->loc, "unknown predicate '%s'", pred_name);
561*38fd1498Szrj }
562*38fd1498Szrj else
563*38fd1498Szrj pred = 0;
564*38fd1498Szrj
565*38fd1498Szrj if (code == MATCH_OPERAND)
566*38fd1498Szrj {
567*38fd1498Szrj const char *constraints = XSTR (pattern, 2);
568*38fd1498Szrj const char constraints0 = constraints[0];
569*38fd1498Szrj
570*38fd1498Szrj if (!constraints_supported_in_insn_p (info->def))
571*38fd1498Szrj {
572*38fd1498Szrj if (constraints0)
573*38fd1498Szrj {
574*38fd1498Szrj error_at (info->loc, "constraints not supported in %s",
575*38fd1498Szrj GET_RTX_NAME (GET_CODE (info->def)));
576*38fd1498Szrj }
577*38fd1498Szrj }
578*38fd1498Szrj
579*38fd1498Szrj /* A MATCH_OPERAND that is a SET should have an output reload. */
580*38fd1498Szrj else if (set && constraints0)
581*38fd1498Szrj {
582*38fd1498Szrj if (set_code == '+')
583*38fd1498Szrj {
584*38fd1498Szrj if (constraints0 == '+')
585*38fd1498Szrj ;
586*38fd1498Szrj /* If we've only got an output reload for this operand,
587*38fd1498Szrj we'd better have a matching input operand. */
588*38fd1498Szrj else if (constraints0 == '='
589*38fd1498Szrj && find_matching_operand (info->def,
590*38fd1498Szrj XINT (pattern, 0)))
591*38fd1498Szrj ;
592*38fd1498Szrj else
593*38fd1498Szrj error_at (info->loc, "operand %d missing in-out reload",
594*38fd1498Szrj XINT (pattern, 0));
595*38fd1498Szrj }
596*38fd1498Szrj else if (constraints0 != '=' && constraints0 != '+')
597*38fd1498Szrj error_at (info->loc, "operand %d missing output reload",
598*38fd1498Szrj XINT (pattern, 0));
599*38fd1498Szrj }
600*38fd1498Szrj
601*38fd1498Szrj /* For matching constraint in MATCH_OPERAND, the digit must be a
602*38fd1498Szrj smaller number than the number of the operand that uses it in the
603*38fd1498Szrj constraint. */
604*38fd1498Szrj while (1)
605*38fd1498Szrj {
606*38fd1498Szrj while (constraints[0]
607*38fd1498Szrj && (constraints[0] == ' ' || constraints[0] == ','))
608*38fd1498Szrj constraints++;
609*38fd1498Szrj if (!constraints[0])
610*38fd1498Szrj break;
611*38fd1498Szrj
612*38fd1498Szrj if (constraints[0] >= '0' && constraints[0] <= '9')
613*38fd1498Szrj {
614*38fd1498Szrj int val;
615*38fd1498Szrj
616*38fd1498Szrj sscanf (constraints, "%d", &val);
617*38fd1498Szrj if (val >= XINT (pattern, 0))
618*38fd1498Szrj error_at (info->loc, "constraint digit %d is not"
619*38fd1498Szrj " smaller than operand %d",
620*38fd1498Szrj val, XINT (pattern, 0));
621*38fd1498Szrj }
622*38fd1498Szrj
623*38fd1498Szrj while (constraints[0] && constraints[0] != ',')
624*38fd1498Szrj constraints++;
625*38fd1498Szrj }
626*38fd1498Szrj }
627*38fd1498Szrj
628*38fd1498Szrj /* Allowing non-lvalues in destinations -- particularly CONST_INT --
629*38fd1498Szrj while not likely to occur at runtime, results in less efficient
630*38fd1498Szrj code from insn-recog.c. */
631*38fd1498Szrj if (set && pred && pred->allows_non_lvalue)
632*38fd1498Szrj error_at (info->loc, "destination operand %d allows non-lvalue",
633*38fd1498Szrj XINT (pattern, 0));
634*38fd1498Szrj
635*38fd1498Szrj /* A modeless MATCH_OPERAND can be handy when we can check for
636*38fd1498Szrj multiple modes in the c_test. In most other cases, it is a
637*38fd1498Szrj mistake. Only DEFINE_INSN is eligible, since SPLIT and
638*38fd1498Szrj PEEP2 can FAIL within the output pattern. Exclude special
639*38fd1498Szrj predicates, which check the mode themselves. Also exclude
640*38fd1498Szrj predicates that allow only constants. Exclude the SET_DEST
641*38fd1498Szrj of a call instruction, as that is a common idiom. */
642*38fd1498Szrj
643*38fd1498Szrj if (GET_MODE (pattern) == VOIDmode
644*38fd1498Szrj && code == MATCH_OPERAND
645*38fd1498Szrj && GET_CODE (info->def) == DEFINE_INSN
646*38fd1498Szrj && pred
647*38fd1498Szrj && !pred->special
648*38fd1498Szrj && pred->allows_non_const
649*38fd1498Szrj && strstr (c_test, "operands") == NULL
650*38fd1498Szrj && ! (set
651*38fd1498Szrj && GET_CODE (set) == SET
652*38fd1498Szrj && GET_CODE (SET_SRC (set)) == CALL))
653*38fd1498Szrj message_at (info->loc, "warning: operand %d missing mode?",
654*38fd1498Szrj XINT (pattern, 0));
655*38fd1498Szrj return;
656*38fd1498Szrj }
657*38fd1498Szrj
658*38fd1498Szrj case SET:
659*38fd1498Szrj {
660*38fd1498Szrj machine_mode dmode, smode;
661*38fd1498Szrj rtx dest, src;
662*38fd1498Szrj
663*38fd1498Szrj dest = SET_DEST (pattern);
664*38fd1498Szrj src = SET_SRC (pattern);
665*38fd1498Szrj
666*38fd1498Szrj /* STRICT_LOW_PART is a wrapper. Its argument is the real
667*38fd1498Szrj destination, and it's mode should match the source. */
668*38fd1498Szrj if (GET_CODE (dest) == STRICT_LOW_PART)
669*38fd1498Szrj dest = XEXP (dest, 0);
670*38fd1498Szrj
671*38fd1498Szrj /* Find the referent for a DUP. */
672*38fd1498Szrj
673*38fd1498Szrj if (GET_CODE (dest) == MATCH_DUP
674*38fd1498Szrj || GET_CODE (dest) == MATCH_OP_DUP
675*38fd1498Szrj || GET_CODE (dest) == MATCH_PAR_DUP)
676*38fd1498Szrj dest = find_operand (info->def, XINT (dest, 0), NULL);
677*38fd1498Szrj
678*38fd1498Szrj if (GET_CODE (src) == MATCH_DUP
679*38fd1498Szrj || GET_CODE (src) == MATCH_OP_DUP
680*38fd1498Szrj || GET_CODE (src) == MATCH_PAR_DUP)
681*38fd1498Szrj src = find_operand (info->def, XINT (src, 0), NULL);
682*38fd1498Szrj
683*38fd1498Szrj dmode = GET_MODE (dest);
684*38fd1498Szrj smode = GET_MODE (src);
685*38fd1498Szrj
686*38fd1498Szrj /* Mode checking is not performed for special predicates. */
687*38fd1498Szrj if (special_predicate_operand_p (src)
688*38fd1498Szrj || special_predicate_operand_p (dest))
689*38fd1498Szrj ;
690*38fd1498Szrj
691*38fd1498Szrj /* The operands of a SET must have the same mode unless one
692*38fd1498Szrj is VOIDmode. */
693*38fd1498Szrj else if (dmode != VOIDmode && smode != VOIDmode && dmode != smode)
694*38fd1498Szrj error_at (info->loc, "mode mismatch in set: %smode vs %smode",
695*38fd1498Szrj GET_MODE_NAME (dmode), GET_MODE_NAME (smode));
696*38fd1498Szrj
697*38fd1498Szrj /* If only one of the operands is VOIDmode, and PC or CC0 is
698*38fd1498Szrj not involved, it's probably a mistake. */
699*38fd1498Szrj else if (dmode != smode
700*38fd1498Szrj && GET_CODE (dest) != PC
701*38fd1498Szrj && GET_CODE (dest) != CC0
702*38fd1498Szrj && GET_CODE (src) != PC
703*38fd1498Szrj && GET_CODE (src) != CC0
704*38fd1498Szrj && !CONST_INT_P (src)
705*38fd1498Szrj && !CONST_WIDE_INT_P (src)
706*38fd1498Szrj && GET_CODE (src) != CALL)
707*38fd1498Szrj {
708*38fd1498Szrj const char *which;
709*38fd1498Szrj which = (dmode == VOIDmode ? "destination" : "source");
710*38fd1498Szrj message_at (info->loc, "warning: %s missing a mode?", which);
711*38fd1498Szrj }
712*38fd1498Szrj
713*38fd1498Szrj if (dest != SET_DEST (pattern))
714*38fd1498Szrj validate_pattern (dest, info, pattern, '=');
715*38fd1498Szrj validate_pattern (SET_DEST (pattern), info, pattern, '=');
716*38fd1498Szrj validate_pattern (SET_SRC (pattern), info, NULL_RTX, 0);
717*38fd1498Szrj return;
718*38fd1498Szrj }
719*38fd1498Szrj
720*38fd1498Szrj case CLOBBER:
721*38fd1498Szrj validate_pattern (SET_DEST (pattern), info, pattern, '=');
722*38fd1498Szrj return;
723*38fd1498Szrj
724*38fd1498Szrj case ZERO_EXTRACT:
725*38fd1498Szrj validate_pattern (XEXP (pattern, 0), info, set, set ? '+' : 0);
726*38fd1498Szrj validate_pattern (XEXP (pattern, 1), info, NULL_RTX, 0);
727*38fd1498Szrj validate_pattern (XEXP (pattern, 2), info, NULL_RTX, 0);
728*38fd1498Szrj return;
729*38fd1498Szrj
730*38fd1498Szrj case STRICT_LOW_PART:
731*38fd1498Szrj validate_pattern (XEXP (pattern, 0), info, set, set ? '+' : 0);
732*38fd1498Szrj return;
733*38fd1498Szrj
734*38fd1498Szrj case LABEL_REF:
735*38fd1498Szrj if (GET_MODE (XEXP (pattern, 0)) != VOIDmode)
736*38fd1498Szrj error_at (info->loc, "operand to label_ref %smode not VOIDmode",
737*38fd1498Szrj GET_MODE_NAME (GET_MODE (XEXP (pattern, 0))));
738*38fd1498Szrj break;
739*38fd1498Szrj
740*38fd1498Szrj case VEC_SELECT:
741*38fd1498Szrj if (GET_MODE (pattern) != VOIDmode)
742*38fd1498Szrj {
743*38fd1498Szrj machine_mode mode = GET_MODE (pattern);
744*38fd1498Szrj machine_mode imode = GET_MODE (XEXP (pattern, 0));
745*38fd1498Szrj machine_mode emode
746*38fd1498Szrj = VECTOR_MODE_P (mode) ? GET_MODE_INNER (mode) : mode;
747*38fd1498Szrj if (GET_CODE (XEXP (pattern, 1)) == PARALLEL)
748*38fd1498Szrj {
749*38fd1498Szrj int expected = 1;
750*38fd1498Szrj unsigned int nelems;
751*38fd1498Szrj if (VECTOR_MODE_P (mode)
752*38fd1498Szrj && !GET_MODE_NUNITS (mode).is_constant (&expected))
753*38fd1498Szrj error_at (info->loc,
754*38fd1498Szrj "vec_select with variable-sized mode %s",
755*38fd1498Szrj GET_MODE_NAME (mode));
756*38fd1498Szrj else if (XVECLEN (XEXP (pattern, 1), 0) != expected)
757*38fd1498Szrj error_at (info->loc,
758*38fd1498Szrj "vec_select parallel with %d elements, expected %d",
759*38fd1498Szrj XVECLEN (XEXP (pattern, 1), 0), expected);
760*38fd1498Szrj else if (VECTOR_MODE_P (imode)
761*38fd1498Szrj && GET_MODE_NUNITS (imode).is_constant (&nelems))
762*38fd1498Szrj {
763*38fd1498Szrj int i;
764*38fd1498Szrj for (i = 0; i < expected; ++i)
765*38fd1498Szrj if (CONST_INT_P (XVECEXP (XEXP (pattern, 1), 0, i))
766*38fd1498Szrj && (UINTVAL (XVECEXP (XEXP (pattern, 1), 0, i))
767*38fd1498Szrj >= nelems))
768*38fd1498Szrj error_at (info->loc,
769*38fd1498Szrj "out of bounds selector %u in vec_select, "
770*38fd1498Szrj "expected at most %u",
771*38fd1498Szrj (unsigned)
772*38fd1498Szrj UINTVAL (XVECEXP (XEXP (pattern, 1), 0, i)),
773*38fd1498Szrj nelems - 1);
774*38fd1498Szrj }
775*38fd1498Szrj }
776*38fd1498Szrj if (imode != VOIDmode && !VECTOR_MODE_P (imode))
777*38fd1498Szrj error_at (info->loc, "%smode of first vec_select operand is not a "
778*38fd1498Szrj "vector mode", GET_MODE_NAME (imode));
779*38fd1498Szrj else if (imode != VOIDmode && GET_MODE_INNER (imode) != emode)
780*38fd1498Szrj error_at (info->loc, "element mode mismatch between vec_select "
781*38fd1498Szrj "%smode and its operand %smode",
782*38fd1498Szrj GET_MODE_NAME (emode),
783*38fd1498Szrj GET_MODE_NAME (GET_MODE_INNER (imode)));
784*38fd1498Szrj }
785*38fd1498Szrj break;
786*38fd1498Szrj
787*38fd1498Szrj default:
788*38fd1498Szrj break;
789*38fd1498Szrj }
790*38fd1498Szrj
791*38fd1498Szrj fmt = GET_RTX_FORMAT (code);
792*38fd1498Szrj len = GET_RTX_LENGTH (code);
793*38fd1498Szrj for (i = 0; i < len; i++)
794*38fd1498Szrj {
795*38fd1498Szrj switch (fmt[i])
796*38fd1498Szrj {
797*38fd1498Szrj case 'e': case 'u':
798*38fd1498Szrj validate_pattern (XEXP (pattern, i), info, NULL_RTX, 0);
799*38fd1498Szrj break;
800*38fd1498Szrj
801*38fd1498Szrj case 'E':
802*38fd1498Szrj for (j = 0; j < XVECLEN (pattern, i); j++)
803*38fd1498Szrj validate_pattern (XVECEXP (pattern, i, j), info, NULL_RTX, 0);
804*38fd1498Szrj break;
805*38fd1498Szrj
806*38fd1498Szrj case 'r': case 'p': case 'i': case 'w': case '0': case 's':
807*38fd1498Szrj break;
808*38fd1498Szrj
809*38fd1498Szrj default:
810*38fd1498Szrj gcc_unreachable ();
811*38fd1498Szrj }
812*38fd1498Szrj }
813*38fd1498Szrj }
814*38fd1498Szrj
815*38fd1498Szrj /* Simple list structure for items of type T, for use when being part
816*38fd1498Szrj of a list is an inherent property of T. T must have members equivalent
817*38fd1498Szrj to "T *prev, *next;" and a function "void set_parent (list_head <T> *)"
818*38fd1498Szrj to set the parent list. */
819*38fd1498Szrj template <typename T>
820*38fd1498Szrj struct list_head
821*38fd1498Szrj {
822*38fd1498Szrj /* A range of linked items. */
823*38fd1498Szrj struct range
824*38fd1498Szrj {
825*38fd1498Szrj range (T *);
826*38fd1498Szrj range (T *, T *);
827*38fd1498Szrj
828*38fd1498Szrj T *start, *end;
829*38fd1498Szrj void set_parent (list_head *);
830*38fd1498Szrj };
831*38fd1498Szrj
832*38fd1498Szrj list_head ();
833*38fd1498Szrj range release ();
834*38fd1498Szrj void push_back (range);
835*38fd1498Szrj range remove (range);
836*38fd1498Szrj void replace (range, range);
837*38fd1498Szrj T *singleton () const;
838*38fd1498Szrj
839*38fd1498Szrj T *first, *last;
840*38fd1498Szrj };
841*38fd1498Szrj
842*38fd1498Szrj /* Create a range [START_IN, START_IN]. */
843*38fd1498Szrj
844*38fd1498Szrj template <typename T>
range(T * start_in)845*38fd1498Szrj list_head <T>::range::range (T *start_in) : start (start_in), end (start_in) {}
846*38fd1498Szrj
847*38fd1498Szrj /* Create a range [START_IN, END_IN], linked by next and prev fields. */
848*38fd1498Szrj
849*38fd1498Szrj template <typename T>
range(T * start_in,T * end_in)850*38fd1498Szrj list_head <T>::range::range (T *start_in, T *end_in)
851*38fd1498Szrj : start (start_in), end (end_in) {}
852*38fd1498Szrj
853*38fd1498Szrj template <typename T>
854*38fd1498Szrj void
set_parent(list_head<T> * owner)855*38fd1498Szrj list_head <T>::range::set_parent (list_head <T> *owner)
856*38fd1498Szrj {
857*38fd1498Szrj for (T *item = start; item != end; item = item->next)
858*38fd1498Szrj item->set_parent (owner);
859*38fd1498Szrj end->set_parent (owner);
860*38fd1498Szrj }
861*38fd1498Szrj
862*38fd1498Szrj template <typename T>
list_head()863*38fd1498Szrj list_head <T>::list_head () : first (0), last (0) {}
864*38fd1498Szrj
865*38fd1498Szrj /* Add R to the end of the list. */
866*38fd1498Szrj
867*38fd1498Szrj template <typename T>
868*38fd1498Szrj void
push_back(range r)869*38fd1498Szrj list_head <T>::push_back (range r)
870*38fd1498Szrj {
871*38fd1498Szrj if (last)
872*38fd1498Szrj last->next = r.start;
873*38fd1498Szrj else
874*38fd1498Szrj first = r.start;
875*38fd1498Szrj r.start->prev = last;
876*38fd1498Szrj last = r.end;
877*38fd1498Szrj r.set_parent (this);
878*38fd1498Szrj }
879*38fd1498Szrj
880*38fd1498Szrj /* Remove R from the list. R remains valid and can be inserted into
881*38fd1498Szrj other lists. */
882*38fd1498Szrj
883*38fd1498Szrj template <typename T>
884*38fd1498Szrj typename list_head <T>::range
remove(range r)885*38fd1498Szrj list_head <T>::remove (range r)
886*38fd1498Szrj {
887*38fd1498Szrj if (r.start->prev)
888*38fd1498Szrj r.start->prev->next = r.end->next;
889*38fd1498Szrj else
890*38fd1498Szrj first = r.end->next;
891*38fd1498Szrj if (r.end->next)
892*38fd1498Szrj r.end->next->prev = r.start->prev;
893*38fd1498Szrj else
894*38fd1498Szrj last = r.start->prev;
895*38fd1498Szrj r.start->prev = 0;
896*38fd1498Szrj r.end->next = 0;
897*38fd1498Szrj r.set_parent (0);
898*38fd1498Szrj return r;
899*38fd1498Szrj }
900*38fd1498Szrj
901*38fd1498Szrj /* Replace OLDR with NEWR. OLDR remains valid and can be inserted into
902*38fd1498Szrj other lists. */
903*38fd1498Szrj
904*38fd1498Szrj template <typename T>
905*38fd1498Szrj void
replace(range oldr,range newr)906*38fd1498Szrj list_head <T>::replace (range oldr, range newr)
907*38fd1498Szrj {
908*38fd1498Szrj newr.start->prev = oldr.start->prev;
909*38fd1498Szrj newr.end->next = oldr.end->next;
910*38fd1498Szrj
911*38fd1498Szrj oldr.start->prev = 0;
912*38fd1498Szrj oldr.end->next = 0;
913*38fd1498Szrj oldr.set_parent (0);
914*38fd1498Szrj
915*38fd1498Szrj if (newr.start->prev)
916*38fd1498Szrj newr.start->prev->next = newr.start;
917*38fd1498Szrj else
918*38fd1498Szrj first = newr.start;
919*38fd1498Szrj if (newr.end->next)
920*38fd1498Szrj newr.end->next->prev = newr.end;
921*38fd1498Szrj else
922*38fd1498Szrj last = newr.end;
923*38fd1498Szrj newr.set_parent (this);
924*38fd1498Szrj }
925*38fd1498Szrj
926*38fd1498Szrj /* Empty the list and return the previous contents as a range that can
927*38fd1498Szrj be inserted into other lists. */
928*38fd1498Szrj
929*38fd1498Szrj template <typename T>
930*38fd1498Szrj typename list_head <T>::range
release()931*38fd1498Szrj list_head <T>::release ()
932*38fd1498Szrj {
933*38fd1498Szrj range r (first, last);
934*38fd1498Szrj first = 0;
935*38fd1498Szrj last = 0;
936*38fd1498Szrj r.set_parent (0);
937*38fd1498Szrj return r;
938*38fd1498Szrj }
939*38fd1498Szrj
940*38fd1498Szrj /* If the list contains a single item, return that item, otherwise return
941*38fd1498Szrj null. */
942*38fd1498Szrj
943*38fd1498Szrj template <typename T>
944*38fd1498Szrj T *
singleton()945*38fd1498Szrj list_head <T>::singleton () const
946*38fd1498Szrj {
947*38fd1498Szrj return first == last ? first : 0;
948*38fd1498Szrj }
949*38fd1498Szrj
950*38fd1498Szrj struct state;
951*38fd1498Szrj
952*38fd1498Szrj /* Describes a possible successful return from a routine. */
953*38fd1498Szrj struct acceptance_type
954*38fd1498Szrj {
955*38fd1498Szrj /* The type of routine we're returning from. */
956*38fd1498Szrj routine_type type : 16;
957*38fd1498Szrj
958*38fd1498Szrj /* True if this structure only really represents a partial match,
959*38fd1498Szrj and if we must call a subroutine of type TYPE to complete the match.
960*38fd1498Szrj In this case we'll call the subroutine and, if it succeeds, return
961*38fd1498Szrj whatever the subroutine returned.
962*38fd1498Szrj
963*38fd1498Szrj False if this structure presents a full match. */
964*38fd1498Szrj unsigned int partial_p : 1;
965*38fd1498Szrj
966*38fd1498Szrj union
967*38fd1498Szrj {
968*38fd1498Szrj /* If PARTIAL_P, this is the number of the subroutine to call. */
969*38fd1498Szrj int subroutine_id;
970*38fd1498Szrj
971*38fd1498Szrj /* Valid if !PARTIAL_P. */
972*38fd1498Szrj struct
973*38fd1498Szrj {
974*38fd1498Szrj /* The identifier of the matching pattern. For SUBPATTERNs this
975*38fd1498Szrj value belongs to an ad-hoc routine-specific enum. For the
976*38fd1498Szrj others it's the number of an .md file pattern. */
977*38fd1498Szrj int code;
978*38fd1498Szrj union
979*38fd1498Szrj {
980*38fd1498Szrj /* For RECOG, the number of clobbers that must be added to the
981*38fd1498Szrj pattern in order for it to match CODE. */
982*38fd1498Szrj int num_clobbers;
983*38fd1498Szrj
984*38fd1498Szrj /* For PEEPHOLE2, the number of additional instructions that were
985*38fd1498Szrj included in the optimization. */
986*38fd1498Szrj int match_len;
987*38fd1498Szrj } u;
988*38fd1498Szrj } full;
989*38fd1498Szrj } u;
990*38fd1498Szrj };
991*38fd1498Szrj
992*38fd1498Szrj bool
993*38fd1498Szrj operator == (const acceptance_type &a, const acceptance_type &b)
994*38fd1498Szrj {
995*38fd1498Szrj if (a.partial_p != b.partial_p)
996*38fd1498Szrj return false;
997*38fd1498Szrj if (a.partial_p)
998*38fd1498Szrj return a.u.subroutine_id == b.u.subroutine_id;
999*38fd1498Szrj else
1000*38fd1498Szrj return a.u.full.code == b.u.full.code;
1001*38fd1498Szrj }
1002*38fd1498Szrj
1003*38fd1498Szrj bool
1004*38fd1498Szrj operator != (const acceptance_type &a, const acceptance_type &b)
1005*38fd1498Szrj {
1006*38fd1498Szrj return !operator == (a, b);
1007*38fd1498Szrj }
1008*38fd1498Szrj
1009*38fd1498Szrj /* Represents a parameter to a pattern routine. */
1010*38fd1498Szrj struct parameter
1011*38fd1498Szrj {
1012*38fd1498Szrj /* The C type of parameter. */
1013*38fd1498Szrj enum type_enum {
1014*38fd1498Szrj /* Represents an invalid parameter. */
1015*38fd1498Szrj UNSET,
1016*38fd1498Szrj
1017*38fd1498Szrj /* A machine_mode parameter. */
1018*38fd1498Szrj MODE,
1019*38fd1498Szrj
1020*38fd1498Szrj /* An rtx_code parameter. */
1021*38fd1498Szrj CODE,
1022*38fd1498Szrj
1023*38fd1498Szrj /* An int parameter. */
1024*38fd1498Szrj INT,
1025*38fd1498Szrj
1026*38fd1498Szrj /* An unsigned int parameter. */
1027*38fd1498Szrj UINT,
1028*38fd1498Szrj
1029*38fd1498Szrj /* A HOST_WIDE_INT parameter. */
1030*38fd1498Szrj WIDE_INT
1031*38fd1498Szrj };
1032*38fd1498Szrj
1033*38fd1498Szrj parameter ();
1034*38fd1498Szrj parameter (type_enum, bool, uint64_t);
1035*38fd1498Szrj
1036*38fd1498Szrj /* The type of the parameter. */
1037*38fd1498Szrj type_enum type;
1038*38fd1498Szrj
1039*38fd1498Szrj /* True if the value passed is variable, false if it is constant. */
1040*38fd1498Szrj bool is_param;
1041*38fd1498Szrj
1042*38fd1498Szrj /* If IS_PARAM, this is the number of the variable passed, for an "i%d"
1043*38fd1498Szrj format string. If !IS_PARAM, this is the constant value passed. */
1044*38fd1498Szrj uint64_t value;
1045*38fd1498Szrj };
1046*38fd1498Szrj
parameter()1047*38fd1498Szrj parameter::parameter ()
1048*38fd1498Szrj : type (UNSET), is_param (false), value (0) {}
1049*38fd1498Szrj
parameter(type_enum type_in,bool is_param_in,uint64_t value_in)1050*38fd1498Szrj parameter::parameter (type_enum type_in, bool is_param_in, uint64_t value_in)
1051*38fd1498Szrj : type (type_in), is_param (is_param_in), value (value_in) {}
1052*38fd1498Szrj
1053*38fd1498Szrj bool
1054*38fd1498Szrj operator == (const parameter ¶m1, const parameter ¶m2)
1055*38fd1498Szrj {
1056*38fd1498Szrj return (param1.type == param2.type
1057*38fd1498Szrj && param1.is_param == param2.is_param
1058*38fd1498Szrj && param1.value == param2.value);
1059*38fd1498Szrj }
1060*38fd1498Szrj
1061*38fd1498Szrj bool
1062*38fd1498Szrj operator != (const parameter ¶m1, const parameter ¶m2)
1063*38fd1498Szrj {
1064*38fd1498Szrj return !operator == (param1, param2);
1065*38fd1498Szrj }
1066*38fd1498Szrj
1067*38fd1498Szrj /* Represents a routine that matches a partial rtx pattern, returning
1068*38fd1498Szrj an ad-hoc enum value on success and -1 on failure. The routine can
1069*38fd1498Szrj be used by any subroutine type. The match can be parameterized by
1070*38fd1498Szrj things like mode, code and UNSPEC number. */
1071*38fd1498Szrj struct pattern_routine
1072*38fd1498Szrj {
1073*38fd1498Szrj /* The state that implements the pattern. */
1074*38fd1498Szrj state *s;
1075*38fd1498Szrj
1076*38fd1498Szrj /* The deepest root position from which S can access all the rtxes it needs.
1077*38fd1498Szrj This is NULL if the pattern doesn't need an rtx input, usually because
1078*38fd1498Szrj all matching is done on operands[] instead. */
1079*38fd1498Szrj position *pos;
1080*38fd1498Szrj
1081*38fd1498Szrj /* A unique identifier for the routine. */
1082*38fd1498Szrj unsigned int pattern_id;
1083*38fd1498Szrj
1084*38fd1498Szrj /* True if the routine takes pnum_clobbers as argument. */
1085*38fd1498Szrj bool pnum_clobbers_p;
1086*38fd1498Szrj
1087*38fd1498Szrj /* True if the routine takes the enclosing instruction as argument. */
1088*38fd1498Szrj bool insn_p;
1089*38fd1498Szrj
1090*38fd1498Szrj /* The types of the other parameters to the routine, if any. */
1091*38fd1498Szrj auto_vec <parameter::type_enum, MAX_PATTERN_PARAMS> param_types;
1092*38fd1498Szrj };
1093*38fd1498Szrj
1094*38fd1498Szrj /* All defined patterns. */
1095*38fd1498Szrj static vec <pattern_routine *> patterns;
1096*38fd1498Szrj
1097*38fd1498Szrj /* Represents one use of a pattern routine. */
1098*38fd1498Szrj struct pattern_use
1099*38fd1498Szrj {
1100*38fd1498Szrj /* The pattern routine to use. */
1101*38fd1498Szrj pattern_routine *routine;
1102*38fd1498Szrj
1103*38fd1498Szrj /* The values to pass as parameters. This vector has the same length
1104*38fd1498Szrj as ROUTINE->PARAM_TYPES. */
1105*38fd1498Szrj auto_vec <parameter, MAX_PATTERN_PARAMS> params;
1106*38fd1498Szrj };
1107*38fd1498Szrj
1108*38fd1498Szrj /* Represents a test performed by a decision. */
1109*38fd1498Szrj struct rtx_test
1110*38fd1498Szrj {
1111*38fd1498Szrj rtx_test ();
1112*38fd1498Szrj
1113*38fd1498Szrj /* The types of test that can be performed. Most of them take as input
1114*38fd1498Szrj an rtx X. Some also take as input a transition label LABEL; the others
1115*38fd1498Szrj are booleans for which the transition label is always "true".
1116*38fd1498Szrj
1117*38fd1498Szrj The order of the enum isn't important. */
1118*38fd1498Szrj enum kind_enum {
1119*38fd1498Szrj /* Check GET_CODE (X) == LABEL. */
1120*38fd1498Szrj CODE,
1121*38fd1498Szrj
1122*38fd1498Szrj /* Check GET_MODE (X) == LABEL. */
1123*38fd1498Szrj MODE,
1124*38fd1498Szrj
1125*38fd1498Szrj /* Check REGNO (X) == LABEL. */
1126*38fd1498Szrj REGNO_FIELD,
1127*38fd1498Szrj
1128*38fd1498Szrj /* Check known_eq (SUBREG_BYTE (X), LABEL). */
1129*38fd1498Szrj SUBREG_FIELD,
1130*38fd1498Szrj
1131*38fd1498Szrj /* Check XINT (X, u.opno) == LABEL. */
1132*38fd1498Szrj INT_FIELD,
1133*38fd1498Szrj
1134*38fd1498Szrj /* Check XWINT (X, u.opno) == LABEL. */
1135*38fd1498Szrj WIDE_INT_FIELD,
1136*38fd1498Szrj
1137*38fd1498Szrj /* Check XVECLEN (X, 0) == LABEL. */
1138*38fd1498Szrj VECLEN,
1139*38fd1498Szrj
1140*38fd1498Szrj /* Check peep2_current_count >= u.min_len. */
1141*38fd1498Szrj PEEP2_COUNT,
1142*38fd1498Szrj
1143*38fd1498Szrj /* Check XVECLEN (X, 0) >= u.min_len. */
1144*38fd1498Szrj VECLEN_GE,
1145*38fd1498Szrj
1146*38fd1498Szrj /* Check whether X is a cached const_int with value u.integer. */
1147*38fd1498Szrj SAVED_CONST_INT,
1148*38fd1498Szrj
1149*38fd1498Szrj /* Check u.predicate.data (X, u.predicate.mode). */
1150*38fd1498Szrj PREDICATE,
1151*38fd1498Szrj
1152*38fd1498Szrj /* Check rtx_equal_p (X, operands[u.opno]). */
1153*38fd1498Szrj DUPLICATE,
1154*38fd1498Szrj
1155*38fd1498Szrj /* Check whether X matches pattern u.pattern. */
1156*38fd1498Szrj PATTERN,
1157*38fd1498Szrj
1158*38fd1498Szrj /* Check whether pnum_clobbers is nonnull (RECOG only). */
1159*38fd1498Szrj HAVE_NUM_CLOBBERS,
1160*38fd1498Szrj
1161*38fd1498Szrj /* Check whether general C test u.string holds. In general the condition
1162*38fd1498Szrj needs access to "insn" and the full operand list. */
1163*38fd1498Szrj C_TEST,
1164*38fd1498Szrj
1165*38fd1498Szrj /* Execute operands[u.opno] = X. (Always succeeds.) */
1166*38fd1498Szrj SET_OP,
1167*38fd1498Szrj
1168*38fd1498Szrj /* Accept u.acceptance. Always succeeds for SUBPATTERN, RECOG and SPLIT.
1169*38fd1498Szrj May fail for PEEPHOLE2 if the define_peephole2 C code executes FAIL. */
1170*38fd1498Szrj ACCEPT
1171*38fd1498Szrj };
1172*38fd1498Szrj
1173*38fd1498Szrj /* The position of rtx X in the above description, relative to the
1174*38fd1498Szrj incoming instruction "insn". The position is null if the test
1175*38fd1498Szrj doesn't take an X as input. */
1176*38fd1498Szrj position *pos;
1177*38fd1498Szrj
1178*38fd1498Szrj /* Which element of operands[] already contains POS, or -1 if no element
1179*38fd1498Szrj is known to hold POS. */
1180*38fd1498Szrj int pos_operand;
1181*38fd1498Szrj
1182*38fd1498Szrj /* The type of test and its parameters, as described above. */
1183*38fd1498Szrj kind_enum kind;
1184*38fd1498Szrj union
1185*38fd1498Szrj {
1186*38fd1498Szrj int opno;
1187*38fd1498Szrj int min_len;
1188*38fd1498Szrj struct
1189*38fd1498Szrj {
1190*38fd1498Szrj bool is_param;
1191*38fd1498Szrj int value;
1192*38fd1498Szrj } integer;
1193*38fd1498Szrj struct
1194*38fd1498Szrj {
1195*38fd1498Szrj const struct pred_data *data;
1196*38fd1498Szrj /* True if the mode is taken from a machine_mode parameter
1197*38fd1498Szrj to the routine rather than a constant machine_mode. If true,
1198*38fd1498Szrj MODE is the number of the parameter (for an "i%d" format string),
1199*38fd1498Szrj otherwise it is the mode itself. */
1200*38fd1498Szrj bool mode_is_param;
1201*38fd1498Szrj unsigned int mode;
1202*38fd1498Szrj } predicate;
1203*38fd1498Szrj pattern_use *pattern;
1204*38fd1498Szrj const char *string;
1205*38fd1498Szrj acceptance_type acceptance;
1206*38fd1498Szrj } u;
1207*38fd1498Szrj
1208*38fd1498Szrj static rtx_test code (position *);
1209*38fd1498Szrj static rtx_test mode (position *);
1210*38fd1498Szrj static rtx_test regno_field (position *);
1211*38fd1498Szrj static rtx_test subreg_field (position *);
1212*38fd1498Szrj static rtx_test int_field (position *, int);
1213*38fd1498Szrj static rtx_test wide_int_field (position *, int);
1214*38fd1498Szrj static rtx_test veclen (position *);
1215*38fd1498Szrj static rtx_test peep2_count (int);
1216*38fd1498Szrj static rtx_test veclen_ge (position *, int);
1217*38fd1498Szrj static rtx_test predicate (position *, const pred_data *, machine_mode);
1218*38fd1498Szrj static rtx_test duplicate (position *, int);
1219*38fd1498Szrj static rtx_test pattern (position *, pattern_use *);
1220*38fd1498Szrj static rtx_test have_num_clobbers ();
1221*38fd1498Szrj static rtx_test c_test (const char *);
1222*38fd1498Szrj static rtx_test set_op (position *, int);
1223*38fd1498Szrj static rtx_test accept (const acceptance_type &);
1224*38fd1498Szrj
1225*38fd1498Szrj bool terminal_p () const;
1226*38fd1498Szrj bool single_outcome_p () const;
1227*38fd1498Szrj
1228*38fd1498Szrj private:
1229*38fd1498Szrj rtx_test (position *, kind_enum);
1230*38fd1498Szrj };
1231*38fd1498Szrj
rtx_test()1232*38fd1498Szrj rtx_test::rtx_test () {}
1233*38fd1498Szrj
rtx_test(position * pos_in,kind_enum kind_in)1234*38fd1498Szrj rtx_test::rtx_test (position *pos_in, kind_enum kind_in)
1235*38fd1498Szrj : pos (pos_in), pos_operand (-1), kind (kind_in) {}
1236*38fd1498Szrj
1237*38fd1498Szrj rtx_test
code(position * pos)1238*38fd1498Szrj rtx_test::code (position *pos)
1239*38fd1498Szrj {
1240*38fd1498Szrj return rtx_test (pos, rtx_test::CODE);
1241*38fd1498Szrj }
1242*38fd1498Szrj
1243*38fd1498Szrj rtx_test
mode(position * pos)1244*38fd1498Szrj rtx_test::mode (position *pos)
1245*38fd1498Szrj {
1246*38fd1498Szrj return rtx_test (pos, rtx_test::MODE);
1247*38fd1498Szrj }
1248*38fd1498Szrj
1249*38fd1498Szrj rtx_test
regno_field(position * pos)1250*38fd1498Szrj rtx_test::regno_field (position *pos)
1251*38fd1498Szrj {
1252*38fd1498Szrj rtx_test res (pos, rtx_test::REGNO_FIELD);
1253*38fd1498Szrj return res;
1254*38fd1498Szrj }
1255*38fd1498Szrj
1256*38fd1498Szrj rtx_test
subreg_field(position * pos)1257*38fd1498Szrj rtx_test::subreg_field (position *pos)
1258*38fd1498Szrj {
1259*38fd1498Szrj rtx_test res (pos, rtx_test::SUBREG_FIELD);
1260*38fd1498Szrj return res;
1261*38fd1498Szrj }
1262*38fd1498Szrj
1263*38fd1498Szrj rtx_test
int_field(position * pos,int opno)1264*38fd1498Szrj rtx_test::int_field (position *pos, int opno)
1265*38fd1498Szrj {
1266*38fd1498Szrj rtx_test res (pos, rtx_test::INT_FIELD);
1267*38fd1498Szrj res.u.opno = opno;
1268*38fd1498Szrj return res;
1269*38fd1498Szrj }
1270*38fd1498Szrj
1271*38fd1498Szrj rtx_test
wide_int_field(position * pos,int opno)1272*38fd1498Szrj rtx_test::wide_int_field (position *pos, int opno)
1273*38fd1498Szrj {
1274*38fd1498Szrj rtx_test res (pos, rtx_test::WIDE_INT_FIELD);
1275*38fd1498Szrj res.u.opno = opno;
1276*38fd1498Szrj return res;
1277*38fd1498Szrj }
1278*38fd1498Szrj
1279*38fd1498Szrj rtx_test
veclen(position * pos)1280*38fd1498Szrj rtx_test::veclen (position *pos)
1281*38fd1498Szrj {
1282*38fd1498Szrj return rtx_test (pos, rtx_test::VECLEN);
1283*38fd1498Szrj }
1284*38fd1498Szrj
1285*38fd1498Szrj rtx_test
peep2_count(int min_len)1286*38fd1498Szrj rtx_test::peep2_count (int min_len)
1287*38fd1498Szrj {
1288*38fd1498Szrj rtx_test res (0, rtx_test::PEEP2_COUNT);
1289*38fd1498Szrj res.u.min_len = min_len;
1290*38fd1498Szrj return res;
1291*38fd1498Szrj }
1292*38fd1498Szrj
1293*38fd1498Szrj rtx_test
veclen_ge(position * pos,int min_len)1294*38fd1498Szrj rtx_test::veclen_ge (position *pos, int min_len)
1295*38fd1498Szrj {
1296*38fd1498Szrj rtx_test res (pos, rtx_test::VECLEN_GE);
1297*38fd1498Szrj res.u.min_len = min_len;
1298*38fd1498Szrj return res;
1299*38fd1498Szrj }
1300*38fd1498Szrj
1301*38fd1498Szrj rtx_test
predicate(position * pos,const struct pred_data * data,machine_mode mode)1302*38fd1498Szrj rtx_test::predicate (position *pos, const struct pred_data *data,
1303*38fd1498Szrj machine_mode mode)
1304*38fd1498Szrj {
1305*38fd1498Szrj rtx_test res (pos, rtx_test::PREDICATE);
1306*38fd1498Szrj res.u.predicate.data = data;
1307*38fd1498Szrj res.u.predicate.mode_is_param = false;
1308*38fd1498Szrj res.u.predicate.mode = mode;
1309*38fd1498Szrj return res;
1310*38fd1498Szrj }
1311*38fd1498Szrj
1312*38fd1498Szrj rtx_test
duplicate(position * pos,int opno)1313*38fd1498Szrj rtx_test::duplicate (position *pos, int opno)
1314*38fd1498Szrj {
1315*38fd1498Szrj rtx_test res (pos, rtx_test::DUPLICATE);
1316*38fd1498Szrj res.u.opno = opno;
1317*38fd1498Szrj return res;
1318*38fd1498Szrj }
1319*38fd1498Szrj
1320*38fd1498Szrj rtx_test
pattern(position * pos,pattern_use * pattern)1321*38fd1498Szrj rtx_test::pattern (position *pos, pattern_use *pattern)
1322*38fd1498Szrj {
1323*38fd1498Szrj rtx_test res (pos, rtx_test::PATTERN);
1324*38fd1498Szrj res.u.pattern = pattern;
1325*38fd1498Szrj return res;
1326*38fd1498Szrj }
1327*38fd1498Szrj
1328*38fd1498Szrj rtx_test
have_num_clobbers()1329*38fd1498Szrj rtx_test::have_num_clobbers ()
1330*38fd1498Szrj {
1331*38fd1498Szrj return rtx_test (0, rtx_test::HAVE_NUM_CLOBBERS);
1332*38fd1498Szrj }
1333*38fd1498Szrj
1334*38fd1498Szrj rtx_test
c_test(const char * string)1335*38fd1498Szrj rtx_test::c_test (const char *string)
1336*38fd1498Szrj {
1337*38fd1498Szrj rtx_test res (0, rtx_test::C_TEST);
1338*38fd1498Szrj res.u.string = string;
1339*38fd1498Szrj return res;
1340*38fd1498Szrj }
1341*38fd1498Szrj
1342*38fd1498Szrj rtx_test
set_op(position * pos,int opno)1343*38fd1498Szrj rtx_test::set_op (position *pos, int opno)
1344*38fd1498Szrj {
1345*38fd1498Szrj rtx_test res (pos, rtx_test::SET_OP);
1346*38fd1498Szrj res.u.opno = opno;
1347*38fd1498Szrj return res;
1348*38fd1498Szrj }
1349*38fd1498Szrj
1350*38fd1498Szrj rtx_test
accept(const acceptance_type & acceptance)1351*38fd1498Szrj rtx_test::accept (const acceptance_type &acceptance)
1352*38fd1498Szrj {
1353*38fd1498Szrj rtx_test res (0, rtx_test::ACCEPT);
1354*38fd1498Szrj res.u.acceptance = acceptance;
1355*38fd1498Szrj return res;
1356*38fd1498Szrj }
1357*38fd1498Szrj
1358*38fd1498Szrj /* Return true if the test represents an unconditionally successful match. */
1359*38fd1498Szrj
1360*38fd1498Szrj bool
terminal_p()1361*38fd1498Szrj rtx_test::terminal_p () const
1362*38fd1498Szrj {
1363*38fd1498Szrj return kind == rtx_test::ACCEPT && u.acceptance.type != PEEPHOLE2;
1364*38fd1498Szrj }
1365*38fd1498Szrj
1366*38fd1498Szrj /* Return true if the test is a boolean that is always true. */
1367*38fd1498Szrj
1368*38fd1498Szrj bool
single_outcome_p()1369*38fd1498Szrj rtx_test::single_outcome_p () const
1370*38fd1498Szrj {
1371*38fd1498Szrj return terminal_p () || kind == rtx_test::SET_OP;
1372*38fd1498Szrj }
1373*38fd1498Szrj
1374*38fd1498Szrj bool
1375*38fd1498Szrj operator == (const rtx_test &a, const rtx_test &b)
1376*38fd1498Szrj {
1377*38fd1498Szrj if (a.pos != b.pos || a.kind != b.kind)
1378*38fd1498Szrj return false;
1379*38fd1498Szrj switch (a.kind)
1380*38fd1498Szrj {
1381*38fd1498Szrj case rtx_test::CODE:
1382*38fd1498Szrj case rtx_test::MODE:
1383*38fd1498Szrj case rtx_test::REGNO_FIELD:
1384*38fd1498Szrj case rtx_test::SUBREG_FIELD:
1385*38fd1498Szrj case rtx_test::VECLEN:
1386*38fd1498Szrj case rtx_test::HAVE_NUM_CLOBBERS:
1387*38fd1498Szrj return true;
1388*38fd1498Szrj
1389*38fd1498Szrj case rtx_test::PEEP2_COUNT:
1390*38fd1498Szrj case rtx_test::VECLEN_GE:
1391*38fd1498Szrj return a.u.min_len == b.u.min_len;
1392*38fd1498Szrj
1393*38fd1498Szrj case rtx_test::INT_FIELD:
1394*38fd1498Szrj case rtx_test::WIDE_INT_FIELD:
1395*38fd1498Szrj case rtx_test::DUPLICATE:
1396*38fd1498Szrj case rtx_test::SET_OP:
1397*38fd1498Szrj return a.u.opno == b.u.opno;
1398*38fd1498Szrj
1399*38fd1498Szrj case rtx_test::SAVED_CONST_INT:
1400*38fd1498Szrj return (a.u.integer.is_param == b.u.integer.is_param
1401*38fd1498Szrj && a.u.integer.value == b.u.integer.value);
1402*38fd1498Szrj
1403*38fd1498Szrj case rtx_test::PREDICATE:
1404*38fd1498Szrj return (a.u.predicate.data == b.u.predicate.data
1405*38fd1498Szrj && a.u.predicate.mode_is_param == b.u.predicate.mode_is_param
1406*38fd1498Szrj && a.u.predicate.mode == b.u.predicate.mode);
1407*38fd1498Szrj
1408*38fd1498Szrj case rtx_test::PATTERN:
1409*38fd1498Szrj return (a.u.pattern->routine == b.u.pattern->routine
1410*38fd1498Szrj && a.u.pattern->params == b.u.pattern->params);
1411*38fd1498Szrj
1412*38fd1498Szrj case rtx_test::C_TEST:
1413*38fd1498Szrj return strcmp (a.u.string, b.u.string) == 0;
1414*38fd1498Szrj
1415*38fd1498Szrj case rtx_test::ACCEPT:
1416*38fd1498Szrj return a.u.acceptance == b.u.acceptance;
1417*38fd1498Szrj }
1418*38fd1498Szrj gcc_unreachable ();
1419*38fd1498Szrj }
1420*38fd1498Szrj
1421*38fd1498Szrj bool
1422*38fd1498Szrj operator != (const rtx_test &a, const rtx_test &b)
1423*38fd1498Szrj {
1424*38fd1498Szrj return !operator == (a, b);
1425*38fd1498Szrj }
1426*38fd1498Szrj
1427*38fd1498Szrj /* A simple set of transition labels. Most transitions have a singleton
1428*38fd1498Szrj label, so try to make that case as efficient as possible. */
1429*38fd1498Szrj struct int_set : public auto_vec <uint64_t, 1>
1430*38fd1498Szrj {
1431*38fd1498Szrj typedef uint64_t *iterator;
1432*38fd1498Szrj
1433*38fd1498Szrj int_set ();
1434*38fd1498Szrj int_set (uint64_t);
1435*38fd1498Szrj int_set (const int_set &);
1436*38fd1498Szrj
1437*38fd1498Szrj int_set &operator = (const int_set &);
1438*38fd1498Szrj
1439*38fd1498Szrj iterator begin ();
1440*38fd1498Szrj iterator end ();
1441*38fd1498Szrj };
1442*38fd1498Szrj
int_set()1443*38fd1498Szrj int_set::int_set () : auto_vec<uint64_t, 1> () {}
1444*38fd1498Szrj
int_set(uint64_t label)1445*38fd1498Szrj int_set::int_set (uint64_t label) :
1446*38fd1498Szrj auto_vec<uint64_t, 1> ()
1447*38fd1498Szrj {
1448*38fd1498Szrj safe_push (label);
1449*38fd1498Szrj }
1450*38fd1498Szrj
int_set(const int_set & other)1451*38fd1498Szrj int_set::int_set (const int_set &other) :
1452*38fd1498Szrj auto_vec<uint64_t, 1> ()
1453*38fd1498Szrj {
1454*38fd1498Szrj safe_splice (other);
1455*38fd1498Szrj }
1456*38fd1498Szrj
1457*38fd1498Szrj int_set &
1458*38fd1498Szrj int_set::operator = (const int_set &other)
1459*38fd1498Szrj {
1460*38fd1498Szrj truncate (0);
1461*38fd1498Szrj safe_splice (other);
1462*38fd1498Szrj return *this;
1463*38fd1498Szrj }
1464*38fd1498Szrj
1465*38fd1498Szrj int_set::iterator
begin()1466*38fd1498Szrj int_set::begin ()
1467*38fd1498Szrj {
1468*38fd1498Szrj return address ();
1469*38fd1498Szrj }
1470*38fd1498Szrj
1471*38fd1498Szrj int_set::iterator
end()1472*38fd1498Szrj int_set::end ()
1473*38fd1498Szrj {
1474*38fd1498Szrj return address () + length ();
1475*38fd1498Szrj }
1476*38fd1498Szrj
1477*38fd1498Szrj bool
1478*38fd1498Szrj operator == (const int_set &a, const int_set &b)
1479*38fd1498Szrj {
1480*38fd1498Szrj if (a.length () != b.length ())
1481*38fd1498Szrj return false;
1482*38fd1498Szrj for (unsigned int i = 0; i < a.length (); ++i)
1483*38fd1498Szrj if (a[i] != b[i])
1484*38fd1498Szrj return false;
1485*38fd1498Szrj return true;
1486*38fd1498Szrj }
1487*38fd1498Szrj
1488*38fd1498Szrj bool
1489*38fd1498Szrj operator != (const int_set &a, const int_set &b)
1490*38fd1498Szrj {
1491*38fd1498Szrj return !operator == (a, b);
1492*38fd1498Szrj }
1493*38fd1498Szrj
1494*38fd1498Szrj struct decision;
1495*38fd1498Szrj
1496*38fd1498Szrj /* Represents a transition between states, dependent on the result of
1497*38fd1498Szrj a test T. */
1498*38fd1498Szrj struct transition
1499*38fd1498Szrj {
1500*38fd1498Szrj transition (const int_set &, state *, bool);
1501*38fd1498Szrj
1502*38fd1498Szrj void set_parent (list_head <transition> *);
1503*38fd1498Szrj
1504*38fd1498Szrj /* Links to other transitions for T. Always null for boolean tests. */
1505*38fd1498Szrj transition *prev, *next;
1506*38fd1498Szrj
1507*38fd1498Szrj /* The transition should be taken when T has one of these values.
1508*38fd1498Szrj E.g. for rtx_test::CODE this is a set of codes, while for booleans like
1509*38fd1498Szrj rtx_test::PREDICATE it is always a singleton "true". The labels are
1510*38fd1498Szrj sorted in ascending order. */
1511*38fd1498Szrj int_set labels;
1512*38fd1498Szrj
1513*38fd1498Szrj /* The source decision. */
1514*38fd1498Szrj decision *from;
1515*38fd1498Szrj
1516*38fd1498Szrj /* The target state. */
1517*38fd1498Szrj state *to;
1518*38fd1498Szrj
1519*38fd1498Szrj /* True if TO would function correctly even if TEST wasn't performed.
1520*38fd1498Szrj E.g. it isn't necessary to check whether GET_MODE (x1) is SImode
1521*38fd1498Szrj before calling register_operand (x1, SImode), since register_operand
1522*38fd1498Szrj performs its own mode check. However, checking GET_MODE can be a cheap
1523*38fd1498Szrj way of disambiguating SImode and DImode register operands. */
1524*38fd1498Szrj bool optional;
1525*38fd1498Szrj
1526*38fd1498Szrj /* True if LABELS contains parameter numbers rather than constants.
1527*38fd1498Szrj E.g. if this is true for a rtx_test::CODE, the label is the number
1528*38fd1498Szrj of an rtx_code parameter rather than an rtx_code itself.
1529*38fd1498Szrj LABELS is always a singleton when this variable is true. */
1530*38fd1498Szrj bool is_param;
1531*38fd1498Szrj };
1532*38fd1498Szrj
1533*38fd1498Szrj /* Represents a test and the action that should be taken on the result.
1534*38fd1498Szrj If a transition exists for the test outcome, the machine switches
1535*38fd1498Szrj to the transition's target state. If no suitable transition exists,
1536*38fd1498Szrj the machine either falls through to the next decision or, if there are no
1537*38fd1498Szrj more decisions to try, fails the match. */
1538*38fd1498Szrj struct decision : list_head <transition>
1539*38fd1498Szrj {
1540*38fd1498Szrj decision (const rtx_test &);
1541*38fd1498Szrj
1542*38fd1498Szrj void set_parent (list_head <decision> *s);
1543*38fd1498Szrj bool if_statement_p (uint64_t * = 0) const;
1544*38fd1498Szrj
1545*38fd1498Szrj /* The state to which this decision belongs. */
1546*38fd1498Szrj state *s;
1547*38fd1498Szrj
1548*38fd1498Szrj /* Links to other decisions in the same state. */
1549*38fd1498Szrj decision *prev, *next;
1550*38fd1498Szrj
1551*38fd1498Szrj /* The test to perform. */
1552*38fd1498Szrj rtx_test test;
1553*38fd1498Szrj };
1554*38fd1498Szrj
1555*38fd1498Szrj /* Represents one machine state. For each state the machine tries a list
1556*38fd1498Szrj of decisions, in order, and acts on the first match. It fails without
1557*38fd1498Szrj further backtracking if no decisions match. */
1558*38fd1498Szrj struct state : list_head <decision>
1559*38fd1498Szrj {
set_parentstate1560*38fd1498Szrj void set_parent (list_head <state> *) {}
1561*38fd1498Szrj };
1562*38fd1498Szrj
transition(const int_set & labels_in,state * to_in,bool optional_in)1563*38fd1498Szrj transition::transition (const int_set &labels_in, state *to_in,
1564*38fd1498Szrj bool optional_in)
1565*38fd1498Szrj : prev (0), next (0), labels (labels_in), from (0), to (to_in),
1566*38fd1498Szrj optional (optional_in), is_param (false) {}
1567*38fd1498Szrj
1568*38fd1498Szrj /* Set the source decision of the transition. */
1569*38fd1498Szrj
1570*38fd1498Szrj void
set_parent(list_head<transition> * from_in)1571*38fd1498Szrj transition::set_parent (list_head <transition> *from_in)
1572*38fd1498Szrj {
1573*38fd1498Szrj from = static_cast <decision *> (from_in);
1574*38fd1498Szrj }
1575*38fd1498Szrj
decision(const rtx_test & test_in)1576*38fd1498Szrj decision::decision (const rtx_test &test_in)
1577*38fd1498Szrj : prev (0), next (0), test (test_in) {}
1578*38fd1498Szrj
1579*38fd1498Szrj /* Set the state to which this decision belongs. */
1580*38fd1498Szrj
1581*38fd1498Szrj void
set_parent(list_head<decision> * s_in)1582*38fd1498Szrj decision::set_parent (list_head <decision> *s_in)
1583*38fd1498Szrj {
1584*38fd1498Szrj s = static_cast <state *> (s_in);
1585*38fd1498Szrj }
1586*38fd1498Szrj
1587*38fd1498Szrj /* Return true if the decision has a single transition with a single label.
1588*38fd1498Szrj If so, return the label in *LABEL if nonnull. */
1589*38fd1498Szrj
1590*38fd1498Szrj inline bool
if_statement_p(uint64_t * label)1591*38fd1498Szrj decision::if_statement_p (uint64_t *label) const
1592*38fd1498Szrj {
1593*38fd1498Szrj if (singleton () && first->labels.length () == 1)
1594*38fd1498Szrj {
1595*38fd1498Szrj if (label)
1596*38fd1498Szrj *label = first->labels[0];
1597*38fd1498Szrj return true;
1598*38fd1498Szrj }
1599*38fd1498Szrj return false;
1600*38fd1498Szrj }
1601*38fd1498Szrj
1602*38fd1498Szrj /* Add to FROM a decision that performs TEST and has a single transition
1603*38fd1498Szrj TRANS. */
1604*38fd1498Szrj
1605*38fd1498Szrj static void
add_decision(state * from,const rtx_test & test,transition * trans)1606*38fd1498Szrj add_decision (state *from, const rtx_test &test, transition *trans)
1607*38fd1498Szrj {
1608*38fd1498Szrj decision *d = new decision (test);
1609*38fd1498Szrj from->push_back (d);
1610*38fd1498Szrj d->push_back (trans);
1611*38fd1498Szrj }
1612*38fd1498Szrj
1613*38fd1498Szrj /* Add a transition from FROM to a new, empty state that is taken
1614*38fd1498Szrj when TEST == LABELS. OPTIONAL says whether the new transition
1615*38fd1498Szrj should be optional. Return the new state. */
1616*38fd1498Szrj
1617*38fd1498Szrj static state *
add_decision(state * from,const rtx_test & test,int_set labels,bool optional)1618*38fd1498Szrj add_decision (state *from, const rtx_test &test, int_set labels, bool optional)
1619*38fd1498Szrj {
1620*38fd1498Szrj state *to = new state;
1621*38fd1498Szrj add_decision (from, test, new transition (labels, to, optional));
1622*38fd1498Szrj return to;
1623*38fd1498Szrj }
1624*38fd1498Szrj
1625*38fd1498Szrj /* Insert a decision before decisions R to make them dependent on
1626*38fd1498Szrj TEST == LABELS. OPTIONAL says whether the new transition should be
1627*38fd1498Szrj optional. */
1628*38fd1498Szrj
1629*38fd1498Szrj static decision *
insert_decision_before(state::range r,const rtx_test & test,const int_set & labels,bool optional)1630*38fd1498Szrj insert_decision_before (state::range r, const rtx_test &test,
1631*38fd1498Szrj const int_set &labels, bool optional)
1632*38fd1498Szrj {
1633*38fd1498Szrj decision *newd = new decision (test);
1634*38fd1498Szrj state *news = new state;
1635*38fd1498Szrj newd->push_back (new transition (labels, news, optional));
1636*38fd1498Szrj r.start->s->replace (r, newd);
1637*38fd1498Szrj news->push_back (r);
1638*38fd1498Szrj return newd;
1639*38fd1498Szrj }
1640*38fd1498Szrj
1641*38fd1498Szrj /* Remove any optional transitions from S that turned out not to be useful. */
1642*38fd1498Szrj
1643*38fd1498Szrj static void
collapse_optional_decisions(state * s)1644*38fd1498Szrj collapse_optional_decisions (state *s)
1645*38fd1498Szrj {
1646*38fd1498Szrj decision *d = s->first;
1647*38fd1498Szrj while (d)
1648*38fd1498Szrj {
1649*38fd1498Szrj decision *next = d->next;
1650*38fd1498Szrj for (transition *trans = d->first; trans; trans = trans->next)
1651*38fd1498Szrj collapse_optional_decisions (trans->to);
1652*38fd1498Szrj /* A decision with a single optional transition doesn't help
1653*38fd1498Szrj partition the potential matches and so is unlikely to be
1654*38fd1498Szrj worthwhile. In particular, if the decision that performs the
1655*38fd1498Szrj test is the last in the state, the best it could do is reject
1656*38fd1498Szrj an invalid pattern slightly earlier. If instead the decision
1657*38fd1498Szrj is not the last in the state, the condition it tests could hold
1658*38fd1498Szrj even for the later decisions in the state. The best it can do
1659*38fd1498Szrj is save work in some cases where only the later decisions can
1660*38fd1498Szrj succeed.
1661*38fd1498Szrj
1662*38fd1498Szrj In both cases the optional transition would add extra work to
1663*38fd1498Szrj successful matches when the tested condition holds. */
1664*38fd1498Szrj if (transition *trans = d->singleton ())
1665*38fd1498Szrj if (trans->optional)
1666*38fd1498Szrj s->replace (d, trans->to->release ());
1667*38fd1498Szrj d = next;
1668*38fd1498Szrj }
1669*38fd1498Szrj }
1670*38fd1498Szrj
1671*38fd1498Szrj /* Try to squash several separate tests into simpler ones. */
1672*38fd1498Szrj
1673*38fd1498Szrj static void
simplify_tests(state * s)1674*38fd1498Szrj simplify_tests (state *s)
1675*38fd1498Szrj {
1676*38fd1498Szrj for (decision *d = s->first; d; d = d->next)
1677*38fd1498Szrj {
1678*38fd1498Szrj uint64_t label;
1679*38fd1498Szrj /* Convert checks for GET_CODE (x) == CONST_INT and XWINT (x, 0) == N
1680*38fd1498Szrj into checks for const_int_rtx[N'], if N is suitably small. */
1681*38fd1498Szrj if (d->test.kind == rtx_test::CODE
1682*38fd1498Szrj && d->if_statement_p (&label)
1683*38fd1498Szrj && label == CONST_INT)
1684*38fd1498Szrj if (decision *second = d->first->to->singleton ())
1685*38fd1498Szrj if (d->test.pos == second->test.pos
1686*38fd1498Szrj && second->test.kind == rtx_test::WIDE_INT_FIELD
1687*38fd1498Szrj && second->test.u.opno == 0
1688*38fd1498Szrj && second->if_statement_p (&label)
1689*38fd1498Szrj && IN_RANGE (int64_t (label),
1690*38fd1498Szrj -MAX_SAVED_CONST_INT, MAX_SAVED_CONST_INT))
1691*38fd1498Szrj {
1692*38fd1498Szrj d->test.kind = rtx_test::SAVED_CONST_INT;
1693*38fd1498Szrj d->test.u.integer.is_param = false;
1694*38fd1498Szrj d->test.u.integer.value = label;
1695*38fd1498Szrj d->replace (d->first, second->release ());
1696*38fd1498Szrj d->first->labels[0] = true;
1697*38fd1498Szrj }
1698*38fd1498Szrj /* If we have a CODE test followed by a PREDICATE test, rely on
1699*38fd1498Szrj the predicate to test the code.
1700*38fd1498Szrj
1701*38fd1498Szrj This case exists for match_operators. We initially treat the
1702*38fd1498Szrj CODE test for a match_operator as non-optional so that we can
1703*38fd1498Szrj safely move down to its operands. It may turn out that all
1704*38fd1498Szrj paths that reach that code test require the same predicate
1705*38fd1498Szrj to be true. cse_tests will then put the predicate test in
1706*38fd1498Szrj series with the code test. */
1707*38fd1498Szrj if (d->test.kind == rtx_test::CODE)
1708*38fd1498Szrj if (transition *trans = d->singleton ())
1709*38fd1498Szrj {
1710*38fd1498Szrj state *s = trans->to;
1711*38fd1498Szrj while (decision *d2 = s->singleton ())
1712*38fd1498Szrj {
1713*38fd1498Szrj if (d->test.pos != d2->test.pos)
1714*38fd1498Szrj break;
1715*38fd1498Szrj transition *trans2 = d2->singleton ();
1716*38fd1498Szrj if (!trans2)
1717*38fd1498Szrj break;
1718*38fd1498Szrj if (d2->test.kind == rtx_test::PREDICATE)
1719*38fd1498Szrj {
1720*38fd1498Szrj d->test = d2->test;
1721*38fd1498Szrj trans->labels = int_set (true);
1722*38fd1498Szrj s->replace (d2, trans2->to->release ());
1723*38fd1498Szrj break;
1724*38fd1498Szrj }
1725*38fd1498Szrj s = trans2->to;
1726*38fd1498Szrj }
1727*38fd1498Szrj }
1728*38fd1498Szrj for (transition *trans = d->first; trans; trans = trans->next)
1729*38fd1498Szrj simplify_tests (trans->to);
1730*38fd1498Szrj }
1731*38fd1498Szrj }
1732*38fd1498Szrj
1733*38fd1498Szrj /* Return true if all successful returns passing through D require the
1734*38fd1498Szrj condition tested by COMMON to be true.
1735*38fd1498Szrj
1736*38fd1498Szrj When returning true, add all transitions like COMMON in D to WHERE.
1737*38fd1498Szrj WHERE may contain a partial result on failure. */
1738*38fd1498Szrj
1739*38fd1498Szrj static bool
common_test_p(decision * d,transition * common,vec<transition * > * where)1740*38fd1498Szrj common_test_p (decision *d, transition *common, vec <transition *> *where)
1741*38fd1498Szrj {
1742*38fd1498Szrj if (d->test.kind == rtx_test::ACCEPT)
1743*38fd1498Szrj /* We found a successful return that didn't require COMMON. */
1744*38fd1498Szrj return false;
1745*38fd1498Szrj if (d->test == common->from->test)
1746*38fd1498Szrj {
1747*38fd1498Szrj transition *trans = d->singleton ();
1748*38fd1498Szrj if (!trans
1749*38fd1498Szrj || trans->optional != common->optional
1750*38fd1498Szrj || trans->labels != common->labels)
1751*38fd1498Szrj return false;
1752*38fd1498Szrj where->safe_push (trans);
1753*38fd1498Szrj return true;
1754*38fd1498Szrj }
1755*38fd1498Szrj for (transition *trans = d->first; trans; trans = trans->next)
1756*38fd1498Szrj for (decision *subd = trans->to->first; subd; subd = subd->next)
1757*38fd1498Szrj if (!common_test_p (subd, common, where))
1758*38fd1498Szrj return false;
1759*38fd1498Szrj return true;
1760*38fd1498Szrj }
1761*38fd1498Szrj
1762*38fd1498Szrj /* Indicates that we have tested GET_CODE (X) for a particular rtx X. */
1763*38fd1498Szrj const unsigned char TESTED_CODE = 1;
1764*38fd1498Szrj
1765*38fd1498Szrj /* Indicates that we have tested XVECLEN (X, 0) for a particular rtx X. */
1766*38fd1498Szrj const unsigned char TESTED_VECLEN = 2;
1767*38fd1498Szrj
1768*38fd1498Szrj /* Represents a set of conditions that are known to hold. */
1769*38fd1498Szrj struct known_conditions
1770*38fd1498Szrj {
1771*38fd1498Szrj /* A mask of TESTED_ values for each position, indexed by the position's
1772*38fd1498Szrj id field. */
1773*38fd1498Szrj auto_vec <unsigned char> position_tests;
1774*38fd1498Szrj
1775*38fd1498Szrj /* Index N says whether operands[N] has been set. */
1776*38fd1498Szrj auto_vec <bool> set_operands;
1777*38fd1498Szrj
1778*38fd1498Szrj /* A guranteed lower bound on the value of peep2_current_count. */
1779*38fd1498Szrj int peep2_count;
1780*38fd1498Szrj };
1781*38fd1498Szrj
1782*38fd1498Szrj /* Return true if TEST can safely be performed at D, where
1783*38fd1498Szrj the conditions in KC hold. TEST is known to occur along the
1784*38fd1498Szrj first path from D (i.e. always following the first transition
1785*38fd1498Szrj of the first decision). Any intervening tests can be used as
1786*38fd1498Szrj negative proof that hoisting isn't safe, but only KC can be used
1787*38fd1498Szrj as positive proof. */
1788*38fd1498Szrj
1789*38fd1498Szrj static bool
safe_to_hoist_p(decision * d,const rtx_test & test,known_conditions * kc)1790*38fd1498Szrj safe_to_hoist_p (decision *d, const rtx_test &test, known_conditions *kc)
1791*38fd1498Szrj {
1792*38fd1498Szrj switch (test.kind)
1793*38fd1498Szrj {
1794*38fd1498Szrj case rtx_test::C_TEST:
1795*38fd1498Szrj /* In general, C tests require everything else to have been
1796*38fd1498Szrj verified and all operands to have been set up. */
1797*38fd1498Szrj return false;
1798*38fd1498Szrj
1799*38fd1498Szrj case rtx_test::ACCEPT:
1800*38fd1498Szrj /* Don't accept something before all conditions have been tested. */
1801*38fd1498Szrj return false;
1802*38fd1498Szrj
1803*38fd1498Szrj case rtx_test::PREDICATE:
1804*38fd1498Szrj /* Don't move a predicate over a test for VECLEN_GE, since the
1805*38fd1498Szrj predicate used in a match_parallel can legitimately expect the
1806*38fd1498Szrj length to be checked first. */
1807*38fd1498Szrj for (decision *subd = d;
1808*38fd1498Szrj subd->test != test;
1809*38fd1498Szrj subd = subd->first->to->first)
1810*38fd1498Szrj if (subd->test.pos == test.pos
1811*38fd1498Szrj && subd->test.kind == rtx_test::VECLEN_GE)
1812*38fd1498Szrj return false;
1813*38fd1498Szrj goto any_rtx;
1814*38fd1498Szrj
1815*38fd1498Szrj case rtx_test::DUPLICATE:
1816*38fd1498Szrj /* Don't test for a match_dup until the associated operand has
1817*38fd1498Szrj been set. */
1818*38fd1498Szrj if (!kc->set_operands[test.u.opno])
1819*38fd1498Szrj return false;
1820*38fd1498Szrj goto any_rtx;
1821*38fd1498Szrj
1822*38fd1498Szrj case rtx_test::CODE:
1823*38fd1498Szrj case rtx_test::MODE:
1824*38fd1498Szrj case rtx_test::SAVED_CONST_INT:
1825*38fd1498Szrj case rtx_test::SET_OP:
1826*38fd1498Szrj any_rtx:
1827*38fd1498Szrj /* Check whether it is safe to access the rtx under test. */
1828*38fd1498Szrj switch (test.pos->type)
1829*38fd1498Szrj {
1830*38fd1498Szrj case POS_PEEP2_INSN:
1831*38fd1498Szrj return test.pos->arg < kc->peep2_count;
1832*38fd1498Szrj
1833*38fd1498Szrj case POS_XEXP:
1834*38fd1498Szrj return kc->position_tests[test.pos->base->id] & TESTED_CODE;
1835*38fd1498Szrj
1836*38fd1498Szrj case POS_XVECEXP0:
1837*38fd1498Szrj return kc->position_tests[test.pos->base->id] & TESTED_VECLEN;
1838*38fd1498Szrj }
1839*38fd1498Szrj gcc_unreachable ();
1840*38fd1498Szrj
1841*38fd1498Szrj case rtx_test::REGNO_FIELD:
1842*38fd1498Szrj case rtx_test::SUBREG_FIELD:
1843*38fd1498Szrj case rtx_test::INT_FIELD:
1844*38fd1498Szrj case rtx_test::WIDE_INT_FIELD:
1845*38fd1498Szrj case rtx_test::VECLEN:
1846*38fd1498Szrj case rtx_test::VECLEN_GE:
1847*38fd1498Szrj /* These tests access a specific part of an rtx, so are only safe
1848*38fd1498Szrj once we know what the rtx is. */
1849*38fd1498Szrj return kc->position_tests[test.pos->id] & TESTED_CODE;
1850*38fd1498Szrj
1851*38fd1498Szrj case rtx_test::PEEP2_COUNT:
1852*38fd1498Szrj case rtx_test::HAVE_NUM_CLOBBERS:
1853*38fd1498Szrj /* These tests can be performed anywhere. */
1854*38fd1498Szrj return true;
1855*38fd1498Szrj
1856*38fd1498Szrj case rtx_test::PATTERN:
1857*38fd1498Szrj gcc_unreachable ();
1858*38fd1498Szrj }
1859*38fd1498Szrj gcc_unreachable ();
1860*38fd1498Szrj }
1861*38fd1498Szrj
1862*38fd1498Szrj /* Look for a transition that is taken by all successful returns from a range
1863*38fd1498Szrj of decisions starting at OUTER and that would be better performed by
1864*38fd1498Szrj OUTER's state instead. On success, store all instances of that transition
1865*38fd1498Szrj in WHERE and return the last decision in the range. The range could
1866*38fd1498Szrj just be OUTER, or it could include later decisions as well.
1867*38fd1498Szrj
1868*38fd1498Szrj WITH_POSITION_P is true if only tests with position POS should be tried,
1869*38fd1498Szrj false if any test should be tried. WORTHWHILE_SINGLE_P is true if the
1870*38fd1498Szrj result is useful even when the range contains just a single decision
1871*38fd1498Szrj with a single transition. KC are the conditions that are known to
1872*38fd1498Szrj hold at OUTER. */
1873*38fd1498Szrj
1874*38fd1498Szrj static decision *
find_common_test(decision * outer,bool with_position_p,position * pos,bool worthwhile_single_p,known_conditions * kc,vec<transition * > * where)1875*38fd1498Szrj find_common_test (decision *outer, bool with_position_p,
1876*38fd1498Szrj position *pos, bool worthwhile_single_p,
1877*38fd1498Szrj known_conditions *kc, vec <transition *> *where)
1878*38fd1498Szrj {
1879*38fd1498Szrj /* After this, WORTHWHILE_SINGLE_P indicates whether a range that contains
1880*38fd1498Szrj just a single decision is useful, regardless of the number of
1881*38fd1498Szrj transitions it has. */
1882*38fd1498Szrj if (!outer->singleton ())
1883*38fd1498Szrj worthwhile_single_p = true;
1884*38fd1498Szrj /* Quick exit if we don't have enough decisions to form a worthwhile
1885*38fd1498Szrj range. */
1886*38fd1498Szrj if (!worthwhile_single_p && !outer->next)
1887*38fd1498Szrj return 0;
1888*38fd1498Szrj /* Follow the first chain down, as one example of a path that needs
1889*38fd1498Szrj to contain the common test. */
1890*38fd1498Szrj for (decision *d = outer; d; d = d->first->to->first)
1891*38fd1498Szrj {
1892*38fd1498Szrj transition *trans = d->singleton ();
1893*38fd1498Szrj if (trans
1894*38fd1498Szrj && (!with_position_p || d->test.pos == pos)
1895*38fd1498Szrj && safe_to_hoist_p (outer, d->test, kc))
1896*38fd1498Szrj {
1897*38fd1498Szrj if (common_test_p (outer, trans, where))
1898*38fd1498Szrj {
1899*38fd1498Szrj if (!outer->next)
1900*38fd1498Szrj /* We checked above whether the move is worthwhile. */
1901*38fd1498Szrj return outer;
1902*38fd1498Szrj /* See how many decisions in OUTER's chain could reuse
1903*38fd1498Szrj the same test. */
1904*38fd1498Szrj decision *outer_end = outer;
1905*38fd1498Szrj do
1906*38fd1498Szrj {
1907*38fd1498Szrj unsigned int length = where->length ();
1908*38fd1498Szrj if (!common_test_p (outer_end->next, trans, where))
1909*38fd1498Szrj {
1910*38fd1498Szrj where->truncate (length);
1911*38fd1498Szrj break;
1912*38fd1498Szrj }
1913*38fd1498Szrj outer_end = outer_end->next;
1914*38fd1498Szrj }
1915*38fd1498Szrj while (outer_end->next);
1916*38fd1498Szrj /* It is worth moving TRANS if it can be shared by more than
1917*38fd1498Szrj one decision. */
1918*38fd1498Szrj if (outer_end != outer || worthwhile_single_p)
1919*38fd1498Szrj return outer_end;
1920*38fd1498Szrj }
1921*38fd1498Szrj where->truncate (0);
1922*38fd1498Szrj }
1923*38fd1498Szrj }
1924*38fd1498Szrj return 0;
1925*38fd1498Szrj }
1926*38fd1498Szrj
1927*38fd1498Szrj /* Try to promote common subtests in S to a single, shared decision.
1928*38fd1498Szrj Also try to bunch tests for the same position together. POS is the
1929*38fd1498Szrj position of the rtx tested before reaching S. KC are the conditions
1930*38fd1498Szrj that are known to hold on entry to S. */
1931*38fd1498Szrj
1932*38fd1498Szrj static void
cse_tests(position * pos,state * s,known_conditions * kc)1933*38fd1498Szrj cse_tests (position *pos, state *s, known_conditions *kc)
1934*38fd1498Szrj {
1935*38fd1498Szrj for (decision *d = s->first; d; d = d->next)
1936*38fd1498Szrj {
1937*38fd1498Szrj auto_vec <transition *, 16> where;
1938*38fd1498Szrj if (d->test.pos)
1939*38fd1498Szrj {
1940*38fd1498Szrj /* Try to find conditions that don't depend on a particular rtx,
1941*38fd1498Szrj such as pnum_clobbers != NULL or peep2_current_count >= X.
1942*38fd1498Szrj It's usually better to check these conditions as soon as
1943*38fd1498Szrj possible, so the change is worthwhile even if there is
1944*38fd1498Szrj only one copy of the test. */
1945*38fd1498Szrj decision *endd = find_common_test (d, true, 0, true, kc, &where);
1946*38fd1498Szrj if (!endd && d->test.pos != pos)
1947*38fd1498Szrj /* Try to find other conditions related to position POS
1948*38fd1498Szrj before moving to the new position. Again, this is
1949*38fd1498Szrj worthwhile even if there is only one copy of the test,
1950*38fd1498Szrj since it means that fewer position variables are live
1951*38fd1498Szrj at a given time. */
1952*38fd1498Szrj endd = find_common_test (d, true, pos, true, kc, &where);
1953*38fd1498Szrj if (!endd)
1954*38fd1498Szrj /* Try to find any condition that is used more than once. */
1955*38fd1498Szrj endd = find_common_test (d, false, 0, false, kc, &where);
1956*38fd1498Szrj if (endd)
1957*38fd1498Szrj {
1958*38fd1498Szrj transition *common = where[0];
1959*38fd1498Szrj /* Replace [D, ENDD] with a test like COMMON. We'll recurse
1960*38fd1498Szrj on the common test and see the original D again next time. */
1961*38fd1498Szrj d = insert_decision_before (state::range (d, endd),
1962*38fd1498Szrj common->from->test,
1963*38fd1498Szrj common->labels,
1964*38fd1498Szrj common->optional);
1965*38fd1498Szrj /* Remove the old tests. */
1966*38fd1498Szrj while (!where.is_empty ())
1967*38fd1498Szrj {
1968*38fd1498Szrj transition *trans = where.pop ();
1969*38fd1498Szrj trans->from->s->replace (trans->from, trans->to->release ());
1970*38fd1498Szrj }
1971*38fd1498Szrj }
1972*38fd1498Szrj }
1973*38fd1498Szrj
1974*38fd1498Szrj /* Make sure that safe_to_hoist_p isn't being overly conservative.
1975*38fd1498Szrj It should realize that D's test is safe in the current
1976*38fd1498Szrj environment. */
1977*38fd1498Szrj gcc_assert (d->test.kind == rtx_test::C_TEST
1978*38fd1498Szrj || d->test.kind == rtx_test::ACCEPT
1979*38fd1498Szrj || safe_to_hoist_p (d, d->test, kc));
1980*38fd1498Szrj
1981*38fd1498Szrj /* D won't be changed any further by the current optimization.
1982*38fd1498Szrj Recurse with the state temporarily updated to include D. */
1983*38fd1498Szrj int prev = 0;
1984*38fd1498Szrj switch (d->test.kind)
1985*38fd1498Szrj {
1986*38fd1498Szrj case rtx_test::CODE:
1987*38fd1498Szrj prev = kc->position_tests[d->test.pos->id];
1988*38fd1498Szrj kc->position_tests[d->test.pos->id] |= TESTED_CODE;
1989*38fd1498Szrj break;
1990*38fd1498Szrj
1991*38fd1498Szrj case rtx_test::VECLEN:
1992*38fd1498Szrj case rtx_test::VECLEN_GE:
1993*38fd1498Szrj prev = kc->position_tests[d->test.pos->id];
1994*38fd1498Szrj kc->position_tests[d->test.pos->id] |= TESTED_VECLEN;
1995*38fd1498Szrj break;
1996*38fd1498Szrj
1997*38fd1498Szrj case rtx_test::SET_OP:
1998*38fd1498Szrj prev = kc->set_operands[d->test.u.opno];
1999*38fd1498Szrj gcc_assert (!prev);
2000*38fd1498Szrj kc->set_operands[d->test.u.opno] = true;
2001*38fd1498Szrj break;
2002*38fd1498Szrj
2003*38fd1498Szrj case rtx_test::PEEP2_COUNT:
2004*38fd1498Szrj prev = kc->peep2_count;
2005*38fd1498Szrj kc->peep2_count = MAX (prev, d->test.u.min_len);
2006*38fd1498Szrj break;
2007*38fd1498Szrj
2008*38fd1498Szrj default:
2009*38fd1498Szrj break;
2010*38fd1498Szrj }
2011*38fd1498Szrj for (transition *trans = d->first; trans; trans = trans->next)
2012*38fd1498Szrj cse_tests (d->test.pos ? d->test.pos : pos, trans->to, kc);
2013*38fd1498Szrj switch (d->test.kind)
2014*38fd1498Szrj {
2015*38fd1498Szrj case rtx_test::CODE:
2016*38fd1498Szrj case rtx_test::VECLEN:
2017*38fd1498Szrj case rtx_test::VECLEN_GE:
2018*38fd1498Szrj kc->position_tests[d->test.pos->id] = prev;
2019*38fd1498Szrj break;
2020*38fd1498Szrj
2021*38fd1498Szrj case rtx_test::SET_OP:
2022*38fd1498Szrj kc->set_operands[d->test.u.opno] = prev;
2023*38fd1498Szrj break;
2024*38fd1498Szrj
2025*38fd1498Szrj case rtx_test::PEEP2_COUNT:
2026*38fd1498Szrj kc->peep2_count = prev;
2027*38fd1498Szrj break;
2028*38fd1498Szrj
2029*38fd1498Szrj default:
2030*38fd1498Szrj break;
2031*38fd1498Szrj }
2032*38fd1498Szrj }
2033*38fd1498Szrj }
2034*38fd1498Szrj
2035*38fd1498Szrj /* Return the type of value that can be used to parameterize test KIND,
2036*38fd1498Szrj or parameter::UNSET if none. */
2037*38fd1498Szrj
2038*38fd1498Szrj parameter::type_enum
transition_parameter_type(rtx_test::kind_enum kind)2039*38fd1498Szrj transition_parameter_type (rtx_test::kind_enum kind)
2040*38fd1498Szrj {
2041*38fd1498Szrj switch (kind)
2042*38fd1498Szrj {
2043*38fd1498Szrj case rtx_test::CODE:
2044*38fd1498Szrj return parameter::CODE;
2045*38fd1498Szrj
2046*38fd1498Szrj case rtx_test::MODE:
2047*38fd1498Szrj return parameter::MODE;
2048*38fd1498Szrj
2049*38fd1498Szrj case rtx_test::REGNO_FIELD:
2050*38fd1498Szrj case rtx_test::SUBREG_FIELD:
2051*38fd1498Szrj return parameter::UINT;
2052*38fd1498Szrj
2053*38fd1498Szrj case rtx_test::INT_FIELD:
2054*38fd1498Szrj case rtx_test::VECLEN:
2055*38fd1498Szrj case rtx_test::PATTERN:
2056*38fd1498Szrj return parameter::INT;
2057*38fd1498Szrj
2058*38fd1498Szrj case rtx_test::WIDE_INT_FIELD:
2059*38fd1498Szrj return parameter::WIDE_INT;
2060*38fd1498Szrj
2061*38fd1498Szrj case rtx_test::PEEP2_COUNT:
2062*38fd1498Szrj case rtx_test::VECLEN_GE:
2063*38fd1498Szrj case rtx_test::SAVED_CONST_INT:
2064*38fd1498Szrj case rtx_test::PREDICATE:
2065*38fd1498Szrj case rtx_test::DUPLICATE:
2066*38fd1498Szrj case rtx_test::HAVE_NUM_CLOBBERS:
2067*38fd1498Szrj case rtx_test::C_TEST:
2068*38fd1498Szrj case rtx_test::SET_OP:
2069*38fd1498Szrj case rtx_test::ACCEPT:
2070*38fd1498Szrj return parameter::UNSET;
2071*38fd1498Szrj }
2072*38fd1498Szrj gcc_unreachable ();
2073*38fd1498Szrj }
2074*38fd1498Szrj
2075*38fd1498Szrj /* Initialize the pos_operand fields of each state reachable from S.
2076*38fd1498Szrj If OPERAND_POS[ID] >= 0, the position with id ID is stored in
2077*38fd1498Szrj operands[OPERAND_POS[ID]] on entry to S. */
2078*38fd1498Szrj
2079*38fd1498Szrj static void
find_operand_positions(state * s,vec<int> & operand_pos)2080*38fd1498Szrj find_operand_positions (state *s, vec <int> &operand_pos)
2081*38fd1498Szrj {
2082*38fd1498Szrj for (decision *d = s->first; d; d = d->next)
2083*38fd1498Szrj {
2084*38fd1498Szrj int this_operand = (d->test.pos ? operand_pos[d->test.pos->id] : -1);
2085*38fd1498Szrj if (this_operand >= 0)
2086*38fd1498Szrj d->test.pos_operand = this_operand;
2087*38fd1498Szrj if (d->test.kind == rtx_test::SET_OP)
2088*38fd1498Szrj operand_pos[d->test.pos->id] = d->test.u.opno;
2089*38fd1498Szrj for (transition *trans = d->first; trans; trans = trans->next)
2090*38fd1498Szrj find_operand_positions (trans->to, operand_pos);
2091*38fd1498Szrj if (d->test.kind == rtx_test::SET_OP)
2092*38fd1498Szrj operand_pos[d->test.pos->id] = this_operand;
2093*38fd1498Szrj }
2094*38fd1498Szrj }
2095*38fd1498Szrj
2096*38fd1498Szrj /* Statistics about a matching routine. */
2097*38fd1498Szrj struct stats
2098*38fd1498Szrj {
2099*38fd1498Szrj stats ();
2100*38fd1498Szrj
2101*38fd1498Szrj /* The total number of decisions in the routine, excluding trivial
2102*38fd1498Szrj ones that never fail. */
2103*38fd1498Szrj unsigned int num_decisions;
2104*38fd1498Szrj
2105*38fd1498Szrj /* The number of non-trivial decisions on the longest path through
2106*38fd1498Szrj the routine, and the return value that contributes most to that
2107*38fd1498Szrj long path. */
2108*38fd1498Szrj unsigned int longest_path;
2109*38fd1498Szrj int longest_path_code;
2110*38fd1498Szrj
2111*38fd1498Szrj /* The maximum number of times that a single call to the routine
2112*38fd1498Szrj can backtrack, and the value returned at the end of that path.
2113*38fd1498Szrj "Backtracking" here means failing one decision in state and
2114*38fd1498Szrj going onto to the next. */
2115*38fd1498Szrj unsigned int longest_backtrack;
2116*38fd1498Szrj int longest_backtrack_code;
2117*38fd1498Szrj };
2118*38fd1498Szrj
stats()2119*38fd1498Szrj stats::stats ()
2120*38fd1498Szrj : num_decisions (0), longest_path (0), longest_path_code (-1),
2121*38fd1498Szrj longest_backtrack (0), longest_backtrack_code (-1) {}
2122*38fd1498Szrj
2123*38fd1498Szrj /* Return statistics about S. */
2124*38fd1498Szrj
2125*38fd1498Szrj static stats
get_stats(state * s)2126*38fd1498Szrj get_stats (state *s)
2127*38fd1498Szrj {
2128*38fd1498Szrj stats for_s;
2129*38fd1498Szrj unsigned int longest_path = 0;
2130*38fd1498Szrj for (decision *d = s->first; d; d = d->next)
2131*38fd1498Szrj {
2132*38fd1498Szrj /* Work out the statistics for D. */
2133*38fd1498Szrj stats for_d;
2134*38fd1498Szrj for (transition *trans = d->first; trans; trans = trans->next)
2135*38fd1498Szrj {
2136*38fd1498Szrj stats for_trans = get_stats (trans->to);
2137*38fd1498Szrj for_d.num_decisions += for_trans.num_decisions;
2138*38fd1498Szrj /* Each transition is mutually-exclusive, so just pick the
2139*38fd1498Szrj longest of the individual paths. */
2140*38fd1498Szrj if (for_d.longest_path <= for_trans.longest_path)
2141*38fd1498Szrj {
2142*38fd1498Szrj for_d.longest_path = for_trans.longest_path;
2143*38fd1498Szrj for_d.longest_path_code = for_trans.longest_path_code;
2144*38fd1498Szrj }
2145*38fd1498Szrj /* Likewise for backtracking. */
2146*38fd1498Szrj if (for_d.longest_backtrack <= for_trans.longest_backtrack)
2147*38fd1498Szrj {
2148*38fd1498Szrj for_d.longest_backtrack = for_trans.longest_backtrack;
2149*38fd1498Szrj for_d.longest_backtrack_code = for_trans.longest_backtrack_code;
2150*38fd1498Szrj }
2151*38fd1498Szrj }
2152*38fd1498Szrj
2153*38fd1498Szrj /* Account for D's test in its statistics. */
2154*38fd1498Szrj if (!d->test.single_outcome_p ())
2155*38fd1498Szrj {
2156*38fd1498Szrj for_d.num_decisions += 1;
2157*38fd1498Szrj for_d.longest_path += 1;
2158*38fd1498Szrj }
2159*38fd1498Szrj if (d->test.kind == rtx_test::ACCEPT)
2160*38fd1498Szrj {
2161*38fd1498Szrj for_d.longest_path_code = d->test.u.acceptance.u.full.code;
2162*38fd1498Szrj for_d.longest_backtrack_code = d->test.u.acceptance.u.full.code;
2163*38fd1498Szrj }
2164*38fd1498Szrj
2165*38fd1498Szrj /* Keep a running count of the number of backtracks. */
2166*38fd1498Szrj if (d->prev)
2167*38fd1498Szrj for_s.longest_backtrack += 1;
2168*38fd1498Szrj
2169*38fd1498Szrj /* Accumulate D's statistics into S's. */
2170*38fd1498Szrj for_s.num_decisions += for_d.num_decisions;
2171*38fd1498Szrj for_s.longest_path += for_d.longest_path;
2172*38fd1498Szrj for_s.longest_backtrack += for_d.longest_backtrack;
2173*38fd1498Szrj
2174*38fd1498Szrj /* Use the code from the decision with the longest individual path,
2175*38fd1498Szrj since that's more likely to be useful if trying to make the
2176*38fd1498Szrj path shorter. In the event of a tie, pick the later decision,
2177*38fd1498Szrj since that's closer to the end of the path. */
2178*38fd1498Szrj if (longest_path <= for_d.longest_path)
2179*38fd1498Szrj {
2180*38fd1498Szrj longest_path = for_d.longest_path;
2181*38fd1498Szrj for_s.longest_path_code = for_d.longest_path_code;
2182*38fd1498Szrj }
2183*38fd1498Szrj
2184*38fd1498Szrj /* Later decisions in a state are necessarily in a longer backtrack
2185*38fd1498Szrj than earlier decisions. */
2186*38fd1498Szrj for_s.longest_backtrack_code = for_d.longest_backtrack_code;
2187*38fd1498Szrj }
2188*38fd1498Szrj return for_s;
2189*38fd1498Szrj }
2190*38fd1498Szrj
2191*38fd1498Szrj /* Optimize ROOT. Use TYPE to describe ROOT in status messages. */
2192*38fd1498Szrj
2193*38fd1498Szrj static void
optimize_subroutine_group(const char * type,state * root)2194*38fd1498Szrj optimize_subroutine_group (const char *type, state *root)
2195*38fd1498Szrj {
2196*38fd1498Szrj /* Remove optional transitions that turned out not to be worthwhile. */
2197*38fd1498Szrj if (collapse_optional_decisions_p)
2198*38fd1498Szrj collapse_optional_decisions (root);
2199*38fd1498Szrj
2200*38fd1498Szrj /* Try to remove duplicated tests and to rearrange tests into a more
2201*38fd1498Szrj logical order. */
2202*38fd1498Szrj if (cse_tests_p)
2203*38fd1498Szrj {
2204*38fd1498Szrj known_conditions kc;
2205*38fd1498Szrj kc.position_tests.safe_grow_cleared (num_positions);
2206*38fd1498Szrj kc.set_operands.safe_grow_cleared (num_operands);
2207*38fd1498Szrj kc.peep2_count = 1;
2208*38fd1498Szrj cse_tests (&root_pos, root, &kc);
2209*38fd1498Szrj }
2210*38fd1498Szrj
2211*38fd1498Szrj /* Try to simplify two or more tests into one. */
2212*38fd1498Szrj if (simplify_tests_p)
2213*38fd1498Szrj simplify_tests (root);
2214*38fd1498Szrj
2215*38fd1498Szrj /* Try to use operands[] instead of xN variables. */
2216*38fd1498Szrj if (use_operand_variables_p)
2217*38fd1498Szrj {
2218*38fd1498Szrj auto_vec <int> operand_pos (num_positions);
2219*38fd1498Szrj for (unsigned int i = 0; i < num_positions; ++i)
2220*38fd1498Szrj operand_pos.quick_push (-1);
2221*38fd1498Szrj find_operand_positions (root, operand_pos);
2222*38fd1498Szrj }
2223*38fd1498Szrj
2224*38fd1498Szrj /* Print a summary of the new state. */
2225*38fd1498Szrj stats st = get_stats (root);
2226*38fd1498Szrj fprintf (stderr, "Statistics for %s:\n", type);
2227*38fd1498Szrj fprintf (stderr, " Number of decisions: %6d\n", st.num_decisions);
2228*38fd1498Szrj fprintf (stderr, " longest path: %6d (code: %6d)\n",
2229*38fd1498Szrj st.longest_path, st.longest_path_code);
2230*38fd1498Szrj fprintf (stderr, " longest backtrack: %6d (code: %6d)\n",
2231*38fd1498Szrj st.longest_backtrack, st.longest_backtrack_code);
2232*38fd1498Szrj }
2233*38fd1498Szrj
2234*38fd1498Szrj struct merge_pattern_info;
2235*38fd1498Szrj
2236*38fd1498Szrj /* Represents a transition from one pattern to another. */
2237*38fd1498Szrj struct merge_pattern_transition
2238*38fd1498Szrj {
2239*38fd1498Szrj merge_pattern_transition (merge_pattern_info *);
2240*38fd1498Szrj
2241*38fd1498Szrj /* The target pattern. */
2242*38fd1498Szrj merge_pattern_info *to;
2243*38fd1498Szrj
2244*38fd1498Szrj /* The parameters that the source pattern passes to the target pattern.
2245*38fd1498Szrj "parameter (TYPE, true, I)" represents parameter I of the source
2246*38fd1498Szrj pattern. */
2247*38fd1498Szrj auto_vec <parameter, MAX_PATTERN_PARAMS> params;
2248*38fd1498Szrj };
2249*38fd1498Szrj
merge_pattern_transition(merge_pattern_info * to_in)2250*38fd1498Szrj merge_pattern_transition::merge_pattern_transition (merge_pattern_info *to_in)
2251*38fd1498Szrj : to (to_in)
2252*38fd1498Szrj {
2253*38fd1498Szrj }
2254*38fd1498Szrj
2255*38fd1498Szrj /* Represents a pattern that can might match several states. The pattern
2256*38fd1498Szrj may replace parts of the test with a parameter value. It may also
2257*38fd1498Szrj replace transition labels with parameters. */
2258*38fd1498Szrj struct merge_pattern_info
2259*38fd1498Szrj {
2260*38fd1498Szrj merge_pattern_info (unsigned int);
2261*38fd1498Szrj
2262*38fd1498Szrj /* If PARAM_TEST_P, the state's singleton test should be generalized
2263*38fd1498Szrj to use the runtime value of PARAMS[PARAM_TEST]. */
2264*38fd1498Szrj unsigned int param_test : 8;
2265*38fd1498Szrj
2266*38fd1498Szrj /* If PARAM_TRANSITION_P, the state's single transition label should
2267*38fd1498Szrj be replaced by the runtime value of PARAMS[PARAM_TRANSITION]. */
2268*38fd1498Szrj unsigned int param_transition : 8;
2269*38fd1498Szrj
2270*38fd1498Szrj /* True if we have decided to generalize the root decision's test,
2271*38fd1498Szrj as per PARAM_TEST. */
2272*38fd1498Szrj unsigned int param_test_p : 1;
2273*38fd1498Szrj
2274*38fd1498Szrj /* Likewise for the root decision's transition, as per PARAM_TRANSITION. */
2275*38fd1498Szrj unsigned int param_transition_p : 1;
2276*38fd1498Szrj
2277*38fd1498Szrj /* True if the contents of the structure are completely filled in. */
2278*38fd1498Szrj unsigned int complete_p : 1;
2279*38fd1498Szrj
2280*38fd1498Szrj /* The number of pseudo-statements in the pattern. Used to decide
2281*38fd1498Szrj whether it's big enough to break out into a subroutine. */
2282*38fd1498Szrj unsigned int num_statements;
2283*38fd1498Szrj
2284*38fd1498Szrj /* The number of states that use this pattern. */
2285*38fd1498Szrj unsigned int num_users;
2286*38fd1498Szrj
2287*38fd1498Szrj /* The number of distinct success values that the pattern returns. */
2288*38fd1498Szrj unsigned int num_results;
2289*38fd1498Szrj
2290*38fd1498Szrj /* This array has one element for each runtime parameter to the pattern.
2291*38fd1498Szrj PARAMS[I] gives the default value of parameter I, which is always
2292*38fd1498Szrj constant.
2293*38fd1498Szrj
2294*38fd1498Szrj These default parameters are used in cases where we match the
2295*38fd1498Szrj pattern against some state S1, then add more parameters while
2296*38fd1498Szrj matching against some state S2. S1 is then left passing fewer
2297*38fd1498Szrj parameters than S2. The array gives us enough informatino to
2298*38fd1498Szrj construct a full parameter list for S1 (see update_parameters).
2299*38fd1498Szrj
2300*38fd1498Szrj If we decide to create a subroutine for this pattern,
2301*38fd1498Szrj PARAMS[I].type determines the C type of parameter I. */
2302*38fd1498Szrj auto_vec <parameter, MAX_PATTERN_PARAMS> params;
2303*38fd1498Szrj
2304*38fd1498Szrj /* All states that match this pattern must have the same number of
2305*38fd1498Szrj transitions. TRANSITIONS[I] describes the subpattern for transition
2306*38fd1498Szrj number I; it is null if transition I represents a successful return
2307*38fd1498Szrj from the pattern. */
2308*38fd1498Szrj auto_vec <merge_pattern_transition *, 1> transitions;
2309*38fd1498Szrj
2310*38fd1498Szrj /* The routine associated with the pattern, or null if we haven't generated
2311*38fd1498Szrj one yet. */
2312*38fd1498Szrj pattern_routine *routine;
2313*38fd1498Szrj };
2314*38fd1498Szrj
merge_pattern_info(unsigned int num_transitions)2315*38fd1498Szrj merge_pattern_info::merge_pattern_info (unsigned int num_transitions)
2316*38fd1498Szrj : param_test (0),
2317*38fd1498Szrj param_transition (0),
2318*38fd1498Szrj param_test_p (false),
2319*38fd1498Szrj param_transition_p (false),
2320*38fd1498Szrj complete_p (false),
2321*38fd1498Szrj num_statements (0),
2322*38fd1498Szrj num_users (0),
2323*38fd1498Szrj num_results (0),
2324*38fd1498Szrj routine (0)
2325*38fd1498Szrj {
2326*38fd1498Szrj transitions.safe_grow_cleared (num_transitions);
2327*38fd1498Szrj }
2328*38fd1498Szrj
2329*38fd1498Szrj /* Describes one way of matching a particular state to a particular
2330*38fd1498Szrj pattern. */
2331*38fd1498Szrj struct merge_state_result
2332*38fd1498Szrj {
2333*38fd1498Szrj merge_state_result (merge_pattern_info *, position *, merge_state_result *);
2334*38fd1498Szrj
2335*38fd1498Szrj /* A pattern that matches the state. */
2336*38fd1498Szrj merge_pattern_info *pattern;
2337*38fd1498Szrj
2338*38fd1498Szrj /* If we decide to use this match and create a subroutine for PATTERN,
2339*38fd1498Szrj the state should pass the rtx at position ROOT to the pattern's
2340*38fd1498Szrj rtx parameter. A null root means that the pattern doesn't need
2341*38fd1498Szrj an rtx parameter; all the rtxes it matches come from elsewhere. */
2342*38fd1498Szrj position *root;
2343*38fd1498Szrj
2344*38fd1498Szrj /* The parameters that should be passed to PATTERN for this state.
2345*38fd1498Szrj If the array is shorter than PATTERN->params, the missing entries
2346*38fd1498Szrj should be taken from the corresponding element of PATTERN->params. */
2347*38fd1498Szrj auto_vec <parameter, MAX_PATTERN_PARAMS> params;
2348*38fd1498Szrj
2349*38fd1498Szrj /* An earlier match for the same state, or null if none. Patterns
2350*38fd1498Szrj matched by earlier entries are smaller than PATTERN. */
2351*38fd1498Szrj merge_state_result *prev;
2352*38fd1498Szrj };
2353*38fd1498Szrj
merge_state_result(merge_pattern_info * pattern_in,position * root_in,merge_state_result * prev_in)2354*38fd1498Szrj merge_state_result::merge_state_result (merge_pattern_info *pattern_in,
2355*38fd1498Szrj position *root_in,
2356*38fd1498Szrj merge_state_result *prev_in)
2357*38fd1498Szrj : pattern (pattern_in), root (root_in), prev (prev_in)
2358*38fd1498Szrj {}
2359*38fd1498Szrj
2360*38fd1498Szrj /* Information about a state, used while trying to match it against
2361*38fd1498Szrj a pattern. */
2362*38fd1498Szrj struct merge_state_info
2363*38fd1498Szrj {
2364*38fd1498Szrj merge_state_info (state *);
2365*38fd1498Szrj
2366*38fd1498Szrj /* The state itself. */
2367*38fd1498Szrj state *s;
2368*38fd1498Szrj
2369*38fd1498Szrj /* Index I gives information about the target of transition I. */
2370*38fd1498Szrj merge_state_info *to_states;
2371*38fd1498Szrj
2372*38fd1498Szrj /* The number of transitions in S. */
2373*38fd1498Szrj unsigned int num_transitions;
2374*38fd1498Szrj
2375*38fd1498Szrj /* True if the state has been deleted in favor of a call to a
2376*38fd1498Szrj pattern routine. */
2377*38fd1498Szrj bool merged_p;
2378*38fd1498Szrj
2379*38fd1498Szrj /* The previous state that might be a merge candidate for S, or null
2380*38fd1498Szrj if no previous states could be merged with S. */
2381*38fd1498Szrj merge_state_info *prev_same_test;
2382*38fd1498Szrj
2383*38fd1498Szrj /* A list of pattern matches for this state. */
2384*38fd1498Szrj merge_state_result *res;
2385*38fd1498Szrj };
2386*38fd1498Szrj
merge_state_info(state * s_in)2387*38fd1498Szrj merge_state_info::merge_state_info (state *s_in)
2388*38fd1498Szrj : s (s_in),
2389*38fd1498Szrj to_states (0),
2390*38fd1498Szrj num_transitions (0),
2391*38fd1498Szrj merged_p (false),
2392*38fd1498Szrj prev_same_test (0),
2393*38fd1498Szrj res (0) {}
2394*38fd1498Szrj
2395*38fd1498Szrj /* True if PAT would be useful as a subroutine. */
2396*38fd1498Szrj
2397*38fd1498Szrj static bool
useful_pattern_p(merge_pattern_info * pat)2398*38fd1498Szrj useful_pattern_p (merge_pattern_info *pat)
2399*38fd1498Szrj {
2400*38fd1498Szrj return pat->num_statements >= MIN_COMBINE_COST;
2401*38fd1498Szrj }
2402*38fd1498Szrj
2403*38fd1498Szrj /* PAT2 is a subpattern of PAT1. Return true if PAT2 should be inlined
2404*38fd1498Szrj into PAT1's C routine. */
2405*38fd1498Szrj
2406*38fd1498Szrj static bool
same_pattern_p(merge_pattern_info * pat1,merge_pattern_info * pat2)2407*38fd1498Szrj same_pattern_p (merge_pattern_info *pat1, merge_pattern_info *pat2)
2408*38fd1498Szrj {
2409*38fd1498Szrj return pat1->num_users == pat2->num_users || !useful_pattern_p (pat2);
2410*38fd1498Szrj }
2411*38fd1498Szrj
2412*38fd1498Szrj /* PAT was previously matched against SINFO based on tentative matches
2413*38fd1498Szrj for the target states of SINFO's state. Return true if the match
2414*38fd1498Szrj still holds; that is, if the target states of SINFO's state still
2415*38fd1498Szrj match the corresponding transitions of PAT. */
2416*38fd1498Szrj
2417*38fd1498Szrj static bool
valid_result_p(merge_pattern_info * pat,merge_state_info * sinfo)2418*38fd1498Szrj valid_result_p (merge_pattern_info *pat, merge_state_info *sinfo)
2419*38fd1498Szrj {
2420*38fd1498Szrj for (unsigned int j = 0; j < sinfo->num_transitions; ++j)
2421*38fd1498Szrj if (merge_pattern_transition *ptrans = pat->transitions[j])
2422*38fd1498Szrj {
2423*38fd1498Szrj merge_state_result *to_res = sinfo->to_states[j].res;
2424*38fd1498Szrj if (!to_res || to_res->pattern != ptrans->to)
2425*38fd1498Szrj return false;
2426*38fd1498Szrj }
2427*38fd1498Szrj return true;
2428*38fd1498Szrj }
2429*38fd1498Szrj
2430*38fd1498Szrj /* Remove any matches that are no longer valid from the head of SINFO's
2431*38fd1498Szrj list of matches. */
2432*38fd1498Szrj
2433*38fd1498Szrj static void
prune_invalid_results(merge_state_info * sinfo)2434*38fd1498Szrj prune_invalid_results (merge_state_info *sinfo)
2435*38fd1498Szrj {
2436*38fd1498Szrj while (sinfo->res && !valid_result_p (sinfo->res->pattern, sinfo))
2437*38fd1498Szrj {
2438*38fd1498Szrj sinfo->res = sinfo->res->prev;
2439*38fd1498Szrj gcc_assert (sinfo->res);
2440*38fd1498Szrj }
2441*38fd1498Szrj }
2442*38fd1498Szrj
2443*38fd1498Szrj /* Return true if PAT represents the biggest posssible match for SINFO;
2444*38fd1498Szrj that is, if the next action of SINFO's state on return from PAT will
2445*38fd1498Szrj be something that cannot be merged with any other state. */
2446*38fd1498Szrj
2447*38fd1498Szrj static bool
complete_result_p(merge_pattern_info * pat,merge_state_info * sinfo)2448*38fd1498Szrj complete_result_p (merge_pattern_info *pat, merge_state_info *sinfo)
2449*38fd1498Szrj {
2450*38fd1498Szrj for (unsigned int j = 0; j < sinfo->num_transitions; ++j)
2451*38fd1498Szrj if (sinfo->to_states[j].res && !pat->transitions[j])
2452*38fd1498Szrj return false;
2453*38fd1498Szrj return true;
2454*38fd1498Szrj }
2455*38fd1498Szrj
2456*38fd1498Szrj /* Update TO for any parameters that have been added to FROM since TO
2457*38fd1498Szrj was last set. The extra parameters in FROM will be constants or
2458*38fd1498Szrj instructions to duplicate earlier parameters. */
2459*38fd1498Szrj
2460*38fd1498Szrj static void
update_parameters(vec<parameter> & to,const vec<parameter> & from)2461*38fd1498Szrj update_parameters (vec <parameter> &to, const vec <parameter> &from)
2462*38fd1498Szrj {
2463*38fd1498Szrj for (unsigned int i = to.length (); i < from.length (); ++i)
2464*38fd1498Szrj to.quick_push (from[i]);
2465*38fd1498Szrj }
2466*38fd1498Szrj
2467*38fd1498Szrj /* Return true if A and B can be tested by a single test. If the test
2468*38fd1498Szrj can be parameterised, store the parameter value for A in *PARAMA and
2469*38fd1498Szrj the parameter value for B in *PARAMB, otherwise leave PARAMA and
2470*38fd1498Szrj PARAMB alone. */
2471*38fd1498Szrj
2472*38fd1498Szrj static bool
compatible_tests_p(const rtx_test & a,const rtx_test & b,parameter * parama,parameter * paramb)2473*38fd1498Szrj compatible_tests_p (const rtx_test &a, const rtx_test &b,
2474*38fd1498Szrj parameter *parama, parameter *paramb)
2475*38fd1498Szrj {
2476*38fd1498Szrj if (a.kind != b.kind)
2477*38fd1498Szrj return false;
2478*38fd1498Szrj switch (a.kind)
2479*38fd1498Szrj {
2480*38fd1498Szrj case rtx_test::PREDICATE:
2481*38fd1498Szrj if (a.u.predicate.data != b.u.predicate.data)
2482*38fd1498Szrj return false;
2483*38fd1498Szrj *parama = parameter (parameter::MODE, false, a.u.predicate.mode);
2484*38fd1498Szrj *paramb = parameter (parameter::MODE, false, b.u.predicate.mode);
2485*38fd1498Szrj return true;
2486*38fd1498Szrj
2487*38fd1498Szrj case rtx_test::SAVED_CONST_INT:
2488*38fd1498Szrj *parama = parameter (parameter::INT, false, a.u.integer.value);
2489*38fd1498Szrj *paramb = parameter (parameter::INT, false, b.u.integer.value);
2490*38fd1498Szrj return true;
2491*38fd1498Szrj
2492*38fd1498Szrj default:
2493*38fd1498Szrj return a == b;
2494*38fd1498Szrj }
2495*38fd1498Szrj }
2496*38fd1498Szrj
2497*38fd1498Szrj /* PARAMS is an array of the parameters that a state is going to pass
2498*38fd1498Szrj to a pattern routine. It is still incomplete; index I has a kind of
2499*38fd1498Szrj parameter::UNSET if we don't yet know what the state will pass
2500*38fd1498Szrj as parameter I. Try to make parameter ID equal VALUE, returning
2501*38fd1498Szrj true on success. */
2502*38fd1498Szrj
2503*38fd1498Szrj static bool
set_parameter(vec<parameter> & params,unsigned int id,const parameter & value)2504*38fd1498Szrj set_parameter (vec <parameter> ¶ms, unsigned int id,
2505*38fd1498Szrj const parameter &value)
2506*38fd1498Szrj {
2507*38fd1498Szrj if (params[id].type == parameter::UNSET)
2508*38fd1498Szrj {
2509*38fd1498Szrj if (force_unique_params_p)
2510*38fd1498Szrj for (unsigned int i = 0; i < params.length (); ++i)
2511*38fd1498Szrj if (params[i] == value)
2512*38fd1498Szrj return false;
2513*38fd1498Szrj params[id] = value;
2514*38fd1498Szrj return true;
2515*38fd1498Szrj }
2516*38fd1498Szrj return params[id] == value;
2517*38fd1498Szrj }
2518*38fd1498Szrj
2519*38fd1498Szrj /* PARAMS2 is the "params" array for a pattern and PARAMS1 is the
2520*38fd1498Szrj set of parameters that a particular state is going to pass to
2521*38fd1498Szrj that pattern.
2522*38fd1498Szrj
2523*38fd1498Szrj Try to extend PARAMS1 and PARAMS2 so that there is a parameter
2524*38fd1498Szrj that is equal to PARAM1 for the state and has a default value of
2525*38fd1498Szrj PARAM2. Parameters beginning at START were added as part of the
2526*38fd1498Szrj same match and so may be reused. */
2527*38fd1498Szrj
2528*38fd1498Szrj static bool
add_parameter(vec<parameter> & params1,vec<parameter> & params2,const parameter & param1,const parameter & param2,unsigned int start,unsigned int * res)2529*38fd1498Szrj add_parameter (vec <parameter> ¶ms1, vec <parameter> ¶ms2,
2530*38fd1498Szrj const parameter ¶m1, const parameter ¶m2,
2531*38fd1498Szrj unsigned int start, unsigned int *res)
2532*38fd1498Szrj {
2533*38fd1498Szrj gcc_assert (params1.length () == params2.length ());
2534*38fd1498Szrj gcc_assert (!param1.is_param && !param2.is_param);
2535*38fd1498Szrj
2536*38fd1498Szrj for (unsigned int i = start; i < params2.length (); ++i)
2537*38fd1498Szrj if (params1[i] == param1 && params2[i] == param2)
2538*38fd1498Szrj {
2539*38fd1498Szrj *res = i;
2540*38fd1498Szrj return true;
2541*38fd1498Szrj }
2542*38fd1498Szrj
2543*38fd1498Szrj if (force_unique_params_p)
2544*38fd1498Szrj for (unsigned int i = 0; i < params2.length (); ++i)
2545*38fd1498Szrj if (params1[i] == param1 || params2[i] == param2)
2546*38fd1498Szrj return false;
2547*38fd1498Szrj
2548*38fd1498Szrj if (params2.length () >= MAX_PATTERN_PARAMS)
2549*38fd1498Szrj return false;
2550*38fd1498Szrj
2551*38fd1498Szrj *res = params2.length ();
2552*38fd1498Szrj params1.quick_push (param1);
2553*38fd1498Szrj params2.quick_push (param2);
2554*38fd1498Szrj return true;
2555*38fd1498Szrj }
2556*38fd1498Szrj
2557*38fd1498Szrj /* If *ROOTA is nonnull, return true if the same sequence of steps are
2558*38fd1498Szrj required to reach A from *ROOTA as to reach B from ROOTB. If *ROOTA
2559*38fd1498Szrj is null, update it if necessary in order to make the condition hold. */
2560*38fd1498Szrj
2561*38fd1498Szrj static bool
merge_relative_positions(position ** roota,position * a,position * rootb,position * b)2562*38fd1498Szrj merge_relative_positions (position **roota, position *a,
2563*38fd1498Szrj position *rootb, position *b)
2564*38fd1498Szrj {
2565*38fd1498Szrj if (!relative_patterns_p)
2566*38fd1498Szrj {
2567*38fd1498Szrj if (a != b)
2568*38fd1498Szrj return false;
2569*38fd1498Szrj if (!*roota)
2570*38fd1498Szrj {
2571*38fd1498Szrj *roota = rootb;
2572*38fd1498Szrj return true;
2573*38fd1498Szrj }
2574*38fd1498Szrj return *roota == rootb;
2575*38fd1498Szrj }
2576*38fd1498Szrj /* If B does not belong to the same instruction as ROOTB, we don't
2577*38fd1498Szrj start with ROOTB but instead start with a call to peep2_next_insn.
2578*38fd1498Szrj In that case the sequences for B and A are identical iff B and A
2579*38fd1498Szrj are themselves identical. */
2580*38fd1498Szrj if (rootb->insn_id != b->insn_id)
2581*38fd1498Szrj return a == b;
2582*38fd1498Szrj while (rootb != b)
2583*38fd1498Szrj {
2584*38fd1498Szrj if (!a || b->type != a->type || b->arg != a->arg)
2585*38fd1498Szrj return false;
2586*38fd1498Szrj b = b->base;
2587*38fd1498Szrj a = a->base;
2588*38fd1498Szrj }
2589*38fd1498Szrj if (!*roota)
2590*38fd1498Szrj *roota = a;
2591*38fd1498Szrj return *roota == a;
2592*38fd1498Szrj }
2593*38fd1498Szrj
2594*38fd1498Szrj /* A hasher of states that treats two states as "equal" if they might be
2595*38fd1498Szrj merged (but trying to be more discriminating than "return true"). */
2596*38fd1498Szrj struct test_pattern_hasher : nofree_ptr_hash <merge_state_info>
2597*38fd1498Szrj {
2598*38fd1498Szrj static inline hashval_t hash (const value_type &);
2599*38fd1498Szrj static inline bool equal (const value_type &, const compare_type &);
2600*38fd1498Szrj };
2601*38fd1498Szrj
2602*38fd1498Szrj hashval_t
hash(merge_state_info * const & sinfo)2603*38fd1498Szrj test_pattern_hasher::hash (merge_state_info *const &sinfo)
2604*38fd1498Szrj {
2605*38fd1498Szrj inchash::hash h;
2606*38fd1498Szrj decision *d = sinfo->s->singleton ();
2607*38fd1498Szrj h.add_int (d->test.pos_operand + 1);
2608*38fd1498Szrj if (!relative_patterns_p)
2609*38fd1498Szrj h.add_int (d->test.pos ? d->test.pos->id + 1 : 0);
2610*38fd1498Szrj h.add_int (d->test.kind);
2611*38fd1498Szrj h.add_int (sinfo->num_transitions);
2612*38fd1498Szrj return h.end ();
2613*38fd1498Szrj }
2614*38fd1498Szrj
2615*38fd1498Szrj bool
equal(merge_state_info * const & sinfo1,merge_state_info * const & sinfo2)2616*38fd1498Szrj test_pattern_hasher::equal (merge_state_info *const &sinfo1,
2617*38fd1498Szrj merge_state_info *const &sinfo2)
2618*38fd1498Szrj {
2619*38fd1498Szrj decision *d1 = sinfo1->s->singleton ();
2620*38fd1498Szrj decision *d2 = sinfo2->s->singleton ();
2621*38fd1498Szrj gcc_assert (d1 && d2);
2622*38fd1498Szrj
2623*38fd1498Szrj parameter new_param1, new_param2;
2624*38fd1498Szrj return (d1->test.pos_operand == d2->test.pos_operand
2625*38fd1498Szrj && (relative_patterns_p || d1->test.pos == d2->test.pos)
2626*38fd1498Szrj && compatible_tests_p (d1->test, d2->test, &new_param1, &new_param2)
2627*38fd1498Szrj && sinfo1->num_transitions == sinfo2->num_transitions);
2628*38fd1498Szrj }
2629*38fd1498Szrj
2630*38fd1498Szrj /* Try to make the state described by SINFO1 use the same pattern as the
2631*38fd1498Szrj state described by SINFO2. Return true on success.
2632*38fd1498Szrj
2633*38fd1498Szrj SINFO1 and SINFO2 are known to have the same hash value. */
2634*38fd1498Szrj
2635*38fd1498Szrj static bool
merge_patterns(merge_state_info * sinfo1,merge_state_info * sinfo2)2636*38fd1498Szrj merge_patterns (merge_state_info *sinfo1, merge_state_info *sinfo2)
2637*38fd1498Szrj {
2638*38fd1498Szrj merge_state_result *res2 = sinfo2->res;
2639*38fd1498Szrj merge_pattern_info *pat = res2->pattern;
2640*38fd1498Szrj
2641*38fd1498Szrj /* Write to temporary arrays while matching, in case we have to abort
2642*38fd1498Szrj half way through. */
2643*38fd1498Szrj auto_vec <parameter, MAX_PATTERN_PARAMS> params1;
2644*38fd1498Szrj auto_vec <parameter, MAX_PATTERN_PARAMS> params2;
2645*38fd1498Szrj params1.quick_grow_cleared (pat->params.length ());
2646*38fd1498Szrj params2.splice (pat->params);
2647*38fd1498Szrj unsigned int start_param = params2.length ();
2648*38fd1498Szrj
2649*38fd1498Szrj /* An array for recording changes to PAT->transitions[?].params.
2650*38fd1498Szrj All changes involve replacing a constant parameter with some
2651*38fd1498Szrj PAT->params[N], where N is the second element of the pending_param. */
2652*38fd1498Szrj typedef std::pair <parameter *, unsigned int> pending_param;
2653*38fd1498Szrj auto_vec <pending_param, 32> pending_params;
2654*38fd1498Szrj
2655*38fd1498Szrj decision *d1 = sinfo1->s->singleton ();
2656*38fd1498Szrj decision *d2 = sinfo2->s->singleton ();
2657*38fd1498Szrj gcc_assert (d1 && d2);
2658*38fd1498Szrj
2659*38fd1498Szrj /* If D2 tests a position, SINFO1's root relative to D1 is the same
2660*38fd1498Szrj as SINFO2's root relative to D2. */
2661*38fd1498Szrj position *root1 = 0;
2662*38fd1498Szrj position *root2 = res2->root;
2663*38fd1498Szrj if (d2->test.pos_operand < 0
2664*38fd1498Szrj && d1->test.pos
2665*38fd1498Szrj && !merge_relative_positions (&root1, d1->test.pos,
2666*38fd1498Szrj root2, d2->test.pos))
2667*38fd1498Szrj return false;
2668*38fd1498Szrj
2669*38fd1498Szrj /* Check whether the patterns have the same shape. */
2670*38fd1498Szrj unsigned int num_transitions = sinfo1->num_transitions;
2671*38fd1498Szrj gcc_assert (num_transitions == sinfo2->num_transitions);
2672*38fd1498Szrj for (unsigned int i = 0; i < num_transitions; ++i)
2673*38fd1498Szrj if (merge_pattern_transition *ptrans = pat->transitions[i])
2674*38fd1498Szrj {
2675*38fd1498Szrj merge_state_result *to1_res = sinfo1->to_states[i].res;
2676*38fd1498Szrj merge_state_result *to2_res = sinfo2->to_states[i].res;
2677*38fd1498Szrj merge_pattern_info *to_pat = ptrans->to;
2678*38fd1498Szrj gcc_assert (to2_res && to2_res->pattern == to_pat);
2679*38fd1498Szrj if (!to1_res || to1_res->pattern != to_pat)
2680*38fd1498Szrj return false;
2681*38fd1498Szrj if (to2_res->root
2682*38fd1498Szrj && !merge_relative_positions (&root1, to1_res->root,
2683*38fd1498Szrj root2, to2_res->root))
2684*38fd1498Szrj return false;
2685*38fd1498Szrj /* Match the parameters that TO1_RES passes to TO_PAT with the
2686*38fd1498Szrj parameters that PAT passes to TO_PAT. */
2687*38fd1498Szrj update_parameters (to1_res->params, to_pat->params);
2688*38fd1498Szrj for (unsigned int j = 0; j < to1_res->params.length (); ++j)
2689*38fd1498Szrj {
2690*38fd1498Szrj const parameter ¶m1 = to1_res->params[j];
2691*38fd1498Szrj const parameter ¶m2 = ptrans->params[j];
2692*38fd1498Szrj gcc_assert (!param1.is_param);
2693*38fd1498Szrj if (param2.is_param)
2694*38fd1498Szrj {
2695*38fd1498Szrj if (!set_parameter (params1, param2.value, param1))
2696*38fd1498Szrj return false;
2697*38fd1498Szrj }
2698*38fd1498Szrj else if (param1 != param2)
2699*38fd1498Szrj {
2700*38fd1498Szrj unsigned int id;
2701*38fd1498Szrj if (!add_parameter (params1, params2,
2702*38fd1498Szrj param1, param2, start_param, &id))
2703*38fd1498Szrj return false;
2704*38fd1498Szrj /* Record that PAT should now pass parameter ID to TO_PAT,
2705*38fd1498Szrj instead of the current contents of *PARAM2. We only
2706*38fd1498Szrj make the change if the rest of the match succeeds. */
2707*38fd1498Szrj pending_params.safe_push
2708*38fd1498Szrj (pending_param (&ptrans->params[j], id));
2709*38fd1498Szrj }
2710*38fd1498Szrj }
2711*38fd1498Szrj }
2712*38fd1498Szrj
2713*38fd1498Szrj unsigned int param_test = pat->param_test;
2714*38fd1498Szrj unsigned int param_transition = pat->param_transition;
2715*38fd1498Szrj bool param_test_p = pat->param_test_p;
2716*38fd1498Szrj bool param_transition_p = pat->param_transition_p;
2717*38fd1498Szrj
2718*38fd1498Szrj /* If the tests don't match exactly, try to parameterize them. */
2719*38fd1498Szrj parameter new_param1, new_param2;
2720*38fd1498Szrj if (!compatible_tests_p (d1->test, d2->test, &new_param1, &new_param2))
2721*38fd1498Szrj gcc_unreachable ();
2722*38fd1498Szrj if (new_param1.type != parameter::UNSET)
2723*38fd1498Szrj {
2724*38fd1498Szrj /* If the test has not already been parameterized, all existing
2725*38fd1498Szrj matches use constant NEW_PARAM2. */
2726*38fd1498Szrj if (param_test_p)
2727*38fd1498Szrj {
2728*38fd1498Szrj if (!set_parameter (params1, param_test, new_param1))
2729*38fd1498Szrj return false;
2730*38fd1498Szrj }
2731*38fd1498Szrj else if (new_param1 != new_param2)
2732*38fd1498Szrj {
2733*38fd1498Szrj if (!add_parameter (params1, params2, new_param1, new_param2,
2734*38fd1498Szrj start_param, ¶m_test))
2735*38fd1498Szrj return false;
2736*38fd1498Szrj param_test_p = true;
2737*38fd1498Szrj }
2738*38fd1498Szrj }
2739*38fd1498Szrj
2740*38fd1498Szrj /* Match the transitions. */
2741*38fd1498Szrj transition *trans1 = d1->first;
2742*38fd1498Szrj transition *trans2 = d2->first;
2743*38fd1498Szrj for (unsigned int i = 0; i < num_transitions; ++i)
2744*38fd1498Szrj {
2745*38fd1498Szrj if (param_transition_p || trans1->labels != trans2->labels)
2746*38fd1498Szrj {
2747*38fd1498Szrj /* We can only generalize a single transition with a single
2748*38fd1498Szrj label. */
2749*38fd1498Szrj if (num_transitions != 1
2750*38fd1498Szrj || trans1->labels.length () != 1
2751*38fd1498Szrj || trans2->labels.length () != 1)
2752*38fd1498Szrj return false;
2753*38fd1498Szrj
2754*38fd1498Szrj /* Although we can match wide-int fields, in practice it leads
2755*38fd1498Szrj to some odd results for const_vectors. We end up
2756*38fd1498Szrj parameterizing the first N const_ints of the vector
2757*38fd1498Szrj and then (once we reach the maximum number of parameters)
2758*38fd1498Szrj we go on to match the other elements exactly. */
2759*38fd1498Szrj if (d1->test.kind == rtx_test::WIDE_INT_FIELD)
2760*38fd1498Szrj return false;
2761*38fd1498Szrj
2762*38fd1498Szrj /* See whether the label has a generalizable type. */
2763*38fd1498Szrj parameter::type_enum param_type
2764*38fd1498Szrj = transition_parameter_type (d1->test.kind);
2765*38fd1498Szrj if (param_type == parameter::UNSET)
2766*38fd1498Szrj return false;
2767*38fd1498Szrj
2768*38fd1498Szrj /* Match the labels using parameters. */
2769*38fd1498Szrj new_param1 = parameter (param_type, false, trans1->labels[0]);
2770*38fd1498Szrj if (param_transition_p)
2771*38fd1498Szrj {
2772*38fd1498Szrj if (!set_parameter (params1, param_transition, new_param1))
2773*38fd1498Szrj return false;
2774*38fd1498Szrj }
2775*38fd1498Szrj else
2776*38fd1498Szrj {
2777*38fd1498Szrj new_param2 = parameter (param_type, false, trans2->labels[0]);
2778*38fd1498Szrj if (!add_parameter (params1, params2, new_param1, new_param2,
2779*38fd1498Szrj start_param, ¶m_transition))
2780*38fd1498Szrj return false;
2781*38fd1498Szrj param_transition_p = true;
2782*38fd1498Szrj }
2783*38fd1498Szrj }
2784*38fd1498Szrj trans1 = trans1->next;
2785*38fd1498Szrj trans2 = trans2->next;
2786*38fd1498Szrj }
2787*38fd1498Szrj
2788*38fd1498Szrj /* Set any unset parameters to their default values. This occurs if some
2789*38fd1498Szrj other state needed something to be parameterized in order to match SINFO2,
2790*38fd1498Szrj but SINFO1 on its own does not. */
2791*38fd1498Szrj for (unsigned int i = 0; i < params1.length (); ++i)
2792*38fd1498Szrj if (params1[i].type == parameter::UNSET)
2793*38fd1498Szrj params1[i] = params2[i];
2794*38fd1498Szrj
2795*38fd1498Szrj /* The match was successful. Commit all pending changes to PAT. */
2796*38fd1498Szrj update_parameters (pat->params, params2);
2797*38fd1498Szrj {
2798*38fd1498Szrj pending_param *pp;
2799*38fd1498Szrj unsigned int i;
2800*38fd1498Szrj FOR_EACH_VEC_ELT (pending_params, i, pp)
2801*38fd1498Szrj *pp->first = parameter (pp->first->type, true, pp->second);
2802*38fd1498Szrj }
2803*38fd1498Szrj pat->param_test = param_test;
2804*38fd1498Szrj pat->param_transition = param_transition;
2805*38fd1498Szrj pat->param_test_p = param_test_p;
2806*38fd1498Szrj pat->param_transition_p = param_transition_p;
2807*38fd1498Szrj
2808*38fd1498Szrj /* Record the match of SINFO1. */
2809*38fd1498Szrj merge_state_result *new_res1 = new merge_state_result (pat, root1,
2810*38fd1498Szrj sinfo1->res);
2811*38fd1498Szrj new_res1->params.splice (params1);
2812*38fd1498Szrj sinfo1->res = new_res1;
2813*38fd1498Szrj return true;
2814*38fd1498Szrj }
2815*38fd1498Szrj
2816*38fd1498Szrj /* The number of states that were removed by calling pattern routines. */
2817*38fd1498Szrj static unsigned int pattern_use_states;
2818*38fd1498Szrj
2819*38fd1498Szrj /* The number of states used while defining pattern routines. */
2820*38fd1498Szrj static unsigned int pattern_def_states;
2821*38fd1498Szrj
2822*38fd1498Szrj /* Information used while constructing a use or definition of a pattern
2823*38fd1498Szrj routine. */
2824*38fd1498Szrj struct create_pattern_info
2825*38fd1498Szrj {
2826*38fd1498Szrj /* The routine itself. */
2827*38fd1498Szrj pattern_routine *routine;
2828*38fd1498Szrj
2829*38fd1498Szrj /* The first unclaimed return value for this particular use or definition.
2830*38fd1498Szrj We walk the substates of uses and definitions in the same order
2831*38fd1498Szrj so each return value always refers to the same position within
2832*38fd1498Szrj the pattern. */
2833*38fd1498Szrj unsigned int next_result;
2834*38fd1498Szrj };
2835*38fd1498Szrj
2836*38fd1498Szrj static void populate_pattern_routine (create_pattern_info *,
2837*38fd1498Szrj merge_state_info *, state *,
2838*38fd1498Szrj const vec <parameter> &);
2839*38fd1498Szrj
2840*38fd1498Szrj /* SINFO matches a pattern for which we've decided to create a C routine.
2841*38fd1498Szrj Return a decision that performs a call to the pattern routine,
2842*38fd1498Szrj but leave the caller to add the transitions to it. Initialize CPI
2843*38fd1498Szrj for this purpose. Also create a definition for the pattern routine,
2844*38fd1498Szrj if it doesn't already have one.
2845*38fd1498Szrj
2846*38fd1498Szrj PARAMS are the parameters that SINFO passes to its pattern. */
2847*38fd1498Szrj
2848*38fd1498Szrj static decision *
init_pattern_use(create_pattern_info * cpi,merge_state_info * sinfo,const vec<parameter> & params)2849*38fd1498Szrj init_pattern_use (create_pattern_info *cpi, merge_state_info *sinfo,
2850*38fd1498Szrj const vec <parameter> ¶ms)
2851*38fd1498Szrj {
2852*38fd1498Szrj state *s = sinfo->s;
2853*38fd1498Szrj merge_state_result *res = sinfo->res;
2854*38fd1498Szrj merge_pattern_info *pat = res->pattern;
2855*38fd1498Szrj cpi->routine = pat->routine;
2856*38fd1498Szrj if (!cpi->routine)
2857*38fd1498Szrj {
2858*38fd1498Szrj /* We haven't defined the pattern routine yet, so create
2859*38fd1498Szrj a definition now. */
2860*38fd1498Szrj pattern_routine *routine = new pattern_routine;
2861*38fd1498Szrj pat->routine = routine;
2862*38fd1498Szrj cpi->routine = routine;
2863*38fd1498Szrj routine->s = new state;
2864*38fd1498Szrj routine->insn_p = false;
2865*38fd1498Szrj routine->pnum_clobbers_p = false;
2866*38fd1498Szrj
2867*38fd1498Szrj /* Create an "idempotent" mapping of parameter I to parameter I.
2868*38fd1498Szrj Also record the C type of each parameter to the routine. */
2869*38fd1498Szrj auto_vec <parameter, MAX_PATTERN_PARAMS> def_params;
2870*38fd1498Szrj for (unsigned int i = 0; i < pat->params.length (); ++i)
2871*38fd1498Szrj {
2872*38fd1498Szrj def_params.quick_push (parameter (pat->params[i].type, true, i));
2873*38fd1498Szrj routine->param_types.quick_push (pat->params[i].type);
2874*38fd1498Szrj }
2875*38fd1498Szrj
2876*38fd1498Szrj /* Any of the states that match the pattern could be used to
2877*38fd1498Szrj create the routine definition. We might as well use SINFO
2878*38fd1498Szrj since it's already to hand. This means that all positions
2879*38fd1498Szrj in the definition will be relative to RES->root. */
2880*38fd1498Szrj routine->pos = res->root;
2881*38fd1498Szrj cpi->next_result = 0;
2882*38fd1498Szrj populate_pattern_routine (cpi, sinfo, routine->s, def_params);
2883*38fd1498Szrj gcc_assert (cpi->next_result == pat->num_results);
2884*38fd1498Szrj
2885*38fd1498Szrj /* Add the routine to the global list, after the subroutines
2886*38fd1498Szrj that it calls. */
2887*38fd1498Szrj routine->pattern_id = patterns.length ();
2888*38fd1498Szrj patterns.safe_push (routine);
2889*38fd1498Szrj }
2890*38fd1498Szrj
2891*38fd1498Szrj /* Create a decision to call the routine, passing PARAMS to it. */
2892*38fd1498Szrj pattern_use *use = new pattern_use;
2893*38fd1498Szrj use->routine = pat->routine;
2894*38fd1498Szrj use->params.splice (params);
2895*38fd1498Szrj decision *d = new decision (rtx_test::pattern (res->root, use));
2896*38fd1498Szrj
2897*38fd1498Szrj /* If the original decision could use an element of operands[] instead
2898*38fd1498Szrj of an rtx variable, try to transfer it to the new decision. */
2899*38fd1498Szrj if (s->first->test.pos && res->root == s->first->test.pos)
2900*38fd1498Szrj d->test.pos_operand = s->first->test.pos_operand;
2901*38fd1498Szrj
2902*38fd1498Szrj cpi->next_result = 0;
2903*38fd1498Szrj return d;
2904*38fd1498Szrj }
2905*38fd1498Szrj
2906*38fd1498Szrj /* Make S return the next unclaimed pattern routine result for CPI. */
2907*38fd1498Szrj
2908*38fd1498Szrj static void
add_pattern_acceptance(create_pattern_info * cpi,state * s)2909*38fd1498Szrj add_pattern_acceptance (create_pattern_info *cpi, state *s)
2910*38fd1498Szrj {
2911*38fd1498Szrj acceptance_type acceptance;
2912*38fd1498Szrj acceptance.type = SUBPATTERN;
2913*38fd1498Szrj acceptance.partial_p = false;
2914*38fd1498Szrj acceptance.u.full.code = cpi->next_result;
2915*38fd1498Szrj add_decision (s, rtx_test::accept (acceptance), true, false);
2916*38fd1498Szrj cpi->next_result += 1;
2917*38fd1498Szrj }
2918*38fd1498Szrj
2919*38fd1498Szrj /* Initialize new empty state NEWS so that it implements SINFO's pattern
2920*38fd1498Szrj (here referred to as "P"). P may be the top level of a pattern routine
2921*38fd1498Szrj or a subpattern that should be inlined into its parent pattern's routine
2922*38fd1498Szrj (as per same_pattern_p). The choice of SINFO for a top-level pattern is
2923*38fd1498Szrj arbitrary; it could be any of the states that use P. The choice for
2924*38fd1498Szrj subpatterns follows the choice for the parent pattern.
2925*38fd1498Szrj
2926*38fd1498Szrj PARAMS gives the value of each parameter to P in terms of the parameters
2927*38fd1498Szrj to the top-level pattern. If P itself is the top level pattern, PARAMS[I]
2928*38fd1498Szrj is always "parameter (TYPE, true, I)". */
2929*38fd1498Szrj
2930*38fd1498Szrj static void
populate_pattern_routine(create_pattern_info * cpi,merge_state_info * sinfo,state * news,const vec<parameter> & params)2931*38fd1498Szrj populate_pattern_routine (create_pattern_info *cpi, merge_state_info *sinfo,
2932*38fd1498Szrj state *news, const vec <parameter> ¶ms)
2933*38fd1498Szrj {
2934*38fd1498Szrj pattern_def_states += 1;
2935*38fd1498Szrj
2936*38fd1498Szrj decision *d = sinfo->s->singleton ();
2937*38fd1498Szrj merge_pattern_info *pat = sinfo->res->pattern;
2938*38fd1498Szrj pattern_routine *routine = cpi->routine;
2939*38fd1498Szrj
2940*38fd1498Szrj /* Create a copy of D's test for the pattern routine and generalize it
2941*38fd1498Szrj as appropriate. */
2942*38fd1498Szrj decision *newd = new decision (d->test);
2943*38fd1498Szrj gcc_assert (newd->test.pos_operand >= 0
2944*38fd1498Szrj || !newd->test.pos
2945*38fd1498Szrj || common_position (newd->test.pos,
2946*38fd1498Szrj routine->pos) == routine->pos);
2947*38fd1498Szrj if (pat->param_test_p)
2948*38fd1498Szrj {
2949*38fd1498Szrj const parameter ¶m = params[pat->param_test];
2950*38fd1498Szrj switch (newd->test.kind)
2951*38fd1498Szrj {
2952*38fd1498Szrj case rtx_test::PREDICATE:
2953*38fd1498Szrj newd->test.u.predicate.mode_is_param = param.is_param;
2954*38fd1498Szrj newd->test.u.predicate.mode = param.value;
2955*38fd1498Szrj break;
2956*38fd1498Szrj
2957*38fd1498Szrj case rtx_test::SAVED_CONST_INT:
2958*38fd1498Szrj newd->test.u.integer.is_param = param.is_param;
2959*38fd1498Szrj newd->test.u.integer.value = param.value;
2960*38fd1498Szrj break;
2961*38fd1498Szrj
2962*38fd1498Szrj default:
2963*38fd1498Szrj gcc_unreachable ();
2964*38fd1498Szrj break;
2965*38fd1498Szrj }
2966*38fd1498Szrj }
2967*38fd1498Szrj if (d->test.kind == rtx_test::C_TEST)
2968*38fd1498Szrj routine->insn_p = true;
2969*38fd1498Szrj else if (d->test.kind == rtx_test::HAVE_NUM_CLOBBERS)
2970*38fd1498Szrj routine->pnum_clobbers_p = true;
2971*38fd1498Szrj news->push_back (newd);
2972*38fd1498Szrj
2973*38fd1498Szrj /* Fill in the transitions of NEWD. */
2974*38fd1498Szrj unsigned int i = 0;
2975*38fd1498Szrj for (transition *trans = d->first; trans; trans = trans->next)
2976*38fd1498Szrj {
2977*38fd1498Szrj /* Create a new state to act as the target of the new transition. */
2978*38fd1498Szrj state *to_news = new state;
2979*38fd1498Szrj if (merge_pattern_transition *ptrans = pat->transitions[i])
2980*38fd1498Szrj {
2981*38fd1498Szrj /* The pattern hasn't finished matching yet. Get the target
2982*38fd1498Szrj pattern and the corresponding target state of SINFO. */
2983*38fd1498Szrj merge_pattern_info *to_pat = ptrans->to;
2984*38fd1498Szrj merge_state_info *to = sinfo->to_states + i;
2985*38fd1498Szrj gcc_assert (to->res->pattern == to_pat);
2986*38fd1498Szrj gcc_assert (ptrans->params.length () == to_pat->params.length ());
2987*38fd1498Szrj
2988*38fd1498Szrj /* Express the parameters to TO_PAT in terms of the parameters
2989*38fd1498Szrj to the top-level pattern. */
2990*38fd1498Szrj auto_vec <parameter, MAX_PATTERN_PARAMS> to_params;
2991*38fd1498Szrj for (unsigned int j = 0; j < ptrans->params.length (); ++j)
2992*38fd1498Szrj {
2993*38fd1498Szrj const parameter ¶m = ptrans->params[j];
2994*38fd1498Szrj to_params.quick_push (param.is_param
2995*38fd1498Szrj ? params[param.value]
2996*38fd1498Szrj : param);
2997*38fd1498Szrj }
2998*38fd1498Szrj
2999*38fd1498Szrj if (same_pattern_p (pat, to_pat))
3000*38fd1498Szrj /* TO_PAT is part of the current routine, so just recurse. */
3001*38fd1498Szrj populate_pattern_routine (cpi, to, to_news, to_params);
3002*38fd1498Szrj else
3003*38fd1498Szrj {
3004*38fd1498Szrj /* TO_PAT should be matched by calling a separate routine. */
3005*38fd1498Szrj create_pattern_info sub_cpi;
3006*38fd1498Szrj decision *subd = init_pattern_use (&sub_cpi, to, to_params);
3007*38fd1498Szrj routine->insn_p |= sub_cpi.routine->insn_p;
3008*38fd1498Szrj routine->pnum_clobbers_p |= sub_cpi.routine->pnum_clobbers_p;
3009*38fd1498Szrj
3010*38fd1498Szrj /* Add the pattern routine call to the new target state. */
3011*38fd1498Szrj to_news->push_back (subd);
3012*38fd1498Szrj
3013*38fd1498Szrj /* Add a transition for each successful call result. */
3014*38fd1498Szrj for (unsigned int j = 0; j < to_pat->num_results; ++j)
3015*38fd1498Szrj {
3016*38fd1498Szrj state *res = new state;
3017*38fd1498Szrj add_pattern_acceptance (cpi, res);
3018*38fd1498Szrj subd->push_back (new transition (j, res, false));
3019*38fd1498Szrj }
3020*38fd1498Szrj }
3021*38fd1498Szrj }
3022*38fd1498Szrj else
3023*38fd1498Szrj /* This transition corresponds to a successful match. */
3024*38fd1498Szrj add_pattern_acceptance (cpi, to_news);
3025*38fd1498Szrj
3026*38fd1498Szrj /* Create the transition itself, generalizing as necessary. */
3027*38fd1498Szrj transition *new_trans = new transition (trans->labels, to_news,
3028*38fd1498Szrj trans->optional);
3029*38fd1498Szrj if (pat->param_transition_p)
3030*38fd1498Szrj {
3031*38fd1498Szrj const parameter ¶m = params[pat->param_transition];
3032*38fd1498Szrj new_trans->is_param = param.is_param;
3033*38fd1498Szrj new_trans->labels[0] = param.value;
3034*38fd1498Szrj }
3035*38fd1498Szrj newd->push_back (new_trans);
3036*38fd1498Szrj i += 1;
3037*38fd1498Szrj }
3038*38fd1498Szrj }
3039*38fd1498Szrj
3040*38fd1498Szrj /* USE is a decision that calls a pattern routine and SINFO is part of the
3041*38fd1498Szrj original state tree that the call is supposed to replace. Add the
3042*38fd1498Szrj transitions for SINFO and its substates to USE. */
3043*38fd1498Szrj
3044*38fd1498Szrj static void
populate_pattern_use(create_pattern_info * cpi,decision * use,merge_state_info * sinfo)3045*38fd1498Szrj populate_pattern_use (create_pattern_info *cpi, decision *use,
3046*38fd1498Szrj merge_state_info *sinfo)
3047*38fd1498Szrj {
3048*38fd1498Szrj pattern_use_states += 1;
3049*38fd1498Szrj gcc_assert (!sinfo->merged_p);
3050*38fd1498Szrj sinfo->merged_p = true;
3051*38fd1498Szrj merge_state_result *res = sinfo->res;
3052*38fd1498Szrj merge_pattern_info *pat = res->pattern;
3053*38fd1498Szrj decision *d = sinfo->s->singleton ();
3054*38fd1498Szrj unsigned int i = 0;
3055*38fd1498Szrj for (transition *trans = d->first; trans; trans = trans->next)
3056*38fd1498Szrj {
3057*38fd1498Szrj if (pat->transitions[i])
3058*38fd1498Szrj /* The target state is also part of the pattern. */
3059*38fd1498Szrj populate_pattern_use (cpi, use, sinfo->to_states + i);
3060*38fd1498Szrj else
3061*38fd1498Szrj {
3062*38fd1498Szrj /* The transition corresponds to a successful return from the
3063*38fd1498Szrj pattern routine. */
3064*38fd1498Szrj use->push_back (new transition (cpi->next_result, trans->to, false));
3065*38fd1498Szrj cpi->next_result += 1;
3066*38fd1498Szrj }
3067*38fd1498Szrj i += 1;
3068*38fd1498Szrj }
3069*38fd1498Szrj }
3070*38fd1498Szrj
3071*38fd1498Szrj /* We have decided to replace SINFO's state with a call to a pattern
3072*38fd1498Szrj routine. Make the change, creating a definition of the pattern routine
3073*38fd1498Szrj if it doesn't have one already. */
3074*38fd1498Szrj
3075*38fd1498Szrj static void
use_pattern(merge_state_info * sinfo)3076*38fd1498Szrj use_pattern (merge_state_info *sinfo)
3077*38fd1498Szrj {
3078*38fd1498Szrj merge_state_result *res = sinfo->res;
3079*38fd1498Szrj merge_pattern_info *pat = res->pattern;
3080*38fd1498Szrj state *s = sinfo->s;
3081*38fd1498Szrj
3082*38fd1498Szrj /* The pattern may have acquired new parameters after it was matched
3083*38fd1498Szrj against SINFO. Update the parameters that SINFO passes accordingly. */
3084*38fd1498Szrj update_parameters (res->params, pat->params);
3085*38fd1498Szrj
3086*38fd1498Szrj create_pattern_info cpi;
3087*38fd1498Szrj decision *d = init_pattern_use (&cpi, sinfo, res->params);
3088*38fd1498Szrj populate_pattern_use (&cpi, d, sinfo);
3089*38fd1498Szrj s->release ();
3090*38fd1498Szrj s->push_back (d);
3091*38fd1498Szrj }
3092*38fd1498Szrj
3093*38fd1498Szrj /* Look through the state trees in STATES for common patterns and
3094*38fd1498Szrj split them into subroutines. */
3095*38fd1498Szrj
3096*38fd1498Szrj static void
split_out_patterns(vec<merge_state_info> & states)3097*38fd1498Szrj split_out_patterns (vec <merge_state_info> &states)
3098*38fd1498Szrj {
3099*38fd1498Szrj unsigned int first_transition = states.length ();
3100*38fd1498Szrj hash_table <test_pattern_hasher> hashtab (128);
3101*38fd1498Szrj /* Stage 1: Create an order in which parent states come before their child
3102*38fd1498Szrj states and in which sibling states are at consecutive locations.
3103*38fd1498Szrj Having consecutive sibling states allows merge_state_info to have
3104*38fd1498Szrj a single to_states pointer. */
3105*38fd1498Szrj for (unsigned int i = 0; i < states.length (); ++i)
3106*38fd1498Szrj for (decision *d = states[i].s->first; d; d = d->next)
3107*38fd1498Szrj for (transition *trans = d->first; trans; trans = trans->next)
3108*38fd1498Szrj {
3109*38fd1498Szrj states.safe_push (trans->to);
3110*38fd1498Szrj states[i].num_transitions += 1;
3111*38fd1498Szrj }
3112*38fd1498Szrj /* Stage 2: Now that the addresses are stable, set up the to_states
3113*38fd1498Szrj pointers. Look for states that might be merged and enter them
3114*38fd1498Szrj into the hash table. */
3115*38fd1498Szrj for (unsigned int i = 0; i < states.length (); ++i)
3116*38fd1498Szrj {
3117*38fd1498Szrj merge_state_info *sinfo = &states[i];
3118*38fd1498Szrj if (sinfo->num_transitions)
3119*38fd1498Szrj {
3120*38fd1498Szrj sinfo->to_states = &states[first_transition];
3121*38fd1498Szrj first_transition += sinfo->num_transitions;
3122*38fd1498Szrj }
3123*38fd1498Szrj /* For simplicity, we only try to merge states that have a single
3124*38fd1498Szrj decision. This is in any case the best we can do for peephole2,
3125*38fd1498Szrj since whether a peephole2 ACCEPT succeeds or not depends on the
3126*38fd1498Szrj specific peephole2 pattern (which is unique to each ACCEPT
3127*38fd1498Szrj and so couldn't be shared between states). */
3128*38fd1498Szrj if (decision *d = sinfo->s->singleton ())
3129*38fd1498Szrj /* ACCEPT states are unique, so don't even try to merge them. */
3130*38fd1498Szrj if (d->test.kind != rtx_test::ACCEPT
3131*38fd1498Szrj && (pattern_have_num_clobbers_p
3132*38fd1498Szrj || d->test.kind != rtx_test::HAVE_NUM_CLOBBERS)
3133*38fd1498Szrj && (pattern_c_test_p
3134*38fd1498Szrj || d->test.kind != rtx_test::C_TEST))
3135*38fd1498Szrj {
3136*38fd1498Szrj merge_state_info **slot = hashtab.find_slot (sinfo, INSERT);
3137*38fd1498Szrj sinfo->prev_same_test = *slot;
3138*38fd1498Szrj *slot = sinfo;
3139*38fd1498Szrj }
3140*38fd1498Szrj }
3141*38fd1498Szrj /* Stage 3: Walk backwards through the list of states and try to merge
3142*38fd1498Szrj them. This is a greedy, bottom-up match; parent nodes can only start
3143*38fd1498Szrj a new leaf pattern if they fail to match when combined with all child
3144*38fd1498Szrj nodes that have matching patterns.
3145*38fd1498Szrj
3146*38fd1498Szrj For each state we keep a list of potential matches, with each
3147*38fd1498Szrj potential match being larger (and deeper) than the next match in
3148*38fd1498Szrj the list. The final element in the list is a leaf pattern that
3149*38fd1498Szrj matches just a single state.
3150*38fd1498Szrj
3151*38fd1498Szrj Each candidate pattern created in this loop is unique -- it won't
3152*38fd1498Szrj have been seen by an earlier iteration. We try to match each pattern
3153*38fd1498Szrj with every state that appears earlier in STATES.
3154*38fd1498Szrj
3155*38fd1498Szrj Because the patterns created in the loop are unique, any state
3156*38fd1498Szrj that already has a match must have a final potential match that
3157*38fd1498Szrj is different from any new leaf pattern. Therefore, when matching
3158*38fd1498Szrj leaf patterns, we need only consider states whose list of matches
3159*38fd1498Szrj is empty.
3160*38fd1498Szrj
3161*38fd1498Szrj The non-leaf patterns that we try are as deep as possible
3162*38fd1498Szrj and are an extension of the state's previous best candidate match (PB).
3163*38fd1498Szrj We need only consider states whose current potential match is also PB;
3164*38fd1498Szrj any states that don't match as much as PB cannnot match the new pattern,
3165*38fd1498Szrj while any states that already match more than PB must be different from
3166*38fd1498Szrj the new pattern. */
3167*38fd1498Szrj for (unsigned int i2 = states.length (); i2-- > 0; )
3168*38fd1498Szrj {
3169*38fd1498Szrj merge_state_info *sinfo2 = &states[i2];
3170*38fd1498Szrj
3171*38fd1498Szrj /* Enforce the bottom-upness of the match: remove matches with later
3172*38fd1498Szrj states if SINFO2's child states ended up finding a better match. */
3173*38fd1498Szrj prune_invalid_results (sinfo2);
3174*38fd1498Szrj
3175*38fd1498Szrj /* Do nothing if the state doesn't match a later one and if there are
3176*38fd1498Szrj no earlier states it could match. */
3177*38fd1498Szrj if (!sinfo2->res && !sinfo2->prev_same_test)
3178*38fd1498Szrj continue;
3179*38fd1498Szrj
3180*38fd1498Szrj merge_state_result *res2 = sinfo2->res;
3181*38fd1498Szrj decision *d2 = sinfo2->s->singleton ();
3182*38fd1498Szrj position *root2 = (d2->test.pos_operand < 0 ? d2->test.pos : 0);
3183*38fd1498Szrj unsigned int num_transitions = sinfo2->num_transitions;
3184*38fd1498Szrj
3185*38fd1498Szrj /* If RES2 is null then SINFO2's test in isolation has not been seen
3186*38fd1498Szrj before. First try matching that on its own. */
3187*38fd1498Szrj if (!res2)
3188*38fd1498Szrj {
3189*38fd1498Szrj merge_pattern_info *new_pat
3190*38fd1498Szrj = new merge_pattern_info (num_transitions);
3191*38fd1498Szrj merge_state_result *new_res2
3192*38fd1498Szrj = new merge_state_result (new_pat, root2, res2);
3193*38fd1498Szrj sinfo2->res = new_res2;
3194*38fd1498Szrj
3195*38fd1498Szrj new_pat->num_statements = !d2->test.single_outcome_p ();
3196*38fd1498Szrj new_pat->num_results = num_transitions;
3197*38fd1498Szrj bool matched_p = false;
3198*38fd1498Szrj /* Look for states that don't currently match anything but
3199*38fd1498Szrj can be made to match SINFO2 on its own. */
3200*38fd1498Szrj for (merge_state_info *sinfo1 = sinfo2->prev_same_test; sinfo1;
3201*38fd1498Szrj sinfo1 = sinfo1->prev_same_test)
3202*38fd1498Szrj if (!sinfo1->res && merge_patterns (sinfo1, sinfo2))
3203*38fd1498Szrj matched_p = true;
3204*38fd1498Szrj if (!matched_p)
3205*38fd1498Szrj {
3206*38fd1498Szrj /* No other states match. */
3207*38fd1498Szrj sinfo2->res = res2;
3208*38fd1498Szrj delete new_pat;
3209*38fd1498Szrj delete new_res2;
3210*38fd1498Szrj continue;
3211*38fd1498Szrj }
3212*38fd1498Szrj else
3213*38fd1498Szrj res2 = new_res2;
3214*38fd1498Szrj }
3215*38fd1498Szrj
3216*38fd1498Szrj /* Keep the existing pattern if it's as good as anything we'd
3217*38fd1498Szrj create for SINFO2. */
3218*38fd1498Szrj if (complete_result_p (res2->pattern, sinfo2))
3219*38fd1498Szrj {
3220*38fd1498Szrj res2->pattern->num_users += 1;
3221*38fd1498Szrj continue;
3222*38fd1498Szrj }
3223*38fd1498Szrj
3224*38fd1498Szrj /* Create a new pattern for SINFO2. */
3225*38fd1498Szrj merge_pattern_info *new_pat = new merge_pattern_info (num_transitions);
3226*38fd1498Szrj merge_state_result *new_res2
3227*38fd1498Szrj = new merge_state_result (new_pat, root2, res2);
3228*38fd1498Szrj sinfo2->res = new_res2;
3229*38fd1498Szrj
3230*38fd1498Szrj /* Fill in details about the pattern. */
3231*38fd1498Szrj new_pat->num_statements = !d2->test.single_outcome_p ();
3232*38fd1498Szrj new_pat->num_results = 0;
3233*38fd1498Szrj for (unsigned int j = 0; j < num_transitions; ++j)
3234*38fd1498Szrj if (merge_state_result *to_res = sinfo2->to_states[j].res)
3235*38fd1498Szrj {
3236*38fd1498Szrj /* Count the target state as part of this pattern.
3237*38fd1498Szrj First update the root position so that it can reach
3238*38fd1498Szrj the target state's root. */
3239*38fd1498Szrj if (to_res->root)
3240*38fd1498Szrj {
3241*38fd1498Szrj if (new_res2->root)
3242*38fd1498Szrj new_res2->root = common_position (new_res2->root,
3243*38fd1498Szrj to_res->root);
3244*38fd1498Szrj else
3245*38fd1498Szrj new_res2->root = to_res->root;
3246*38fd1498Szrj }
3247*38fd1498Szrj merge_pattern_info *to_pat = to_res->pattern;
3248*38fd1498Szrj merge_pattern_transition *ptrans
3249*38fd1498Szrj = new merge_pattern_transition (to_pat);
3250*38fd1498Szrj
3251*38fd1498Szrj /* TO_PAT may have acquired more parameters when matching
3252*38fd1498Szrj states earlier in STATES than TO_RES's, but the list is
3253*38fd1498Szrj now final. Make sure that TO_RES is up to date. */
3254*38fd1498Szrj update_parameters (to_res->params, to_pat->params);
3255*38fd1498Szrj
3256*38fd1498Szrj /* Start out by assuming that every user of NEW_PAT will
3257*38fd1498Szrj want to pass the same (constant) parameters as TO_RES. */
3258*38fd1498Szrj update_parameters (ptrans->params, to_res->params);
3259*38fd1498Szrj
3260*38fd1498Szrj new_pat->transitions[j] = ptrans;
3261*38fd1498Szrj new_pat->num_statements += to_pat->num_statements;
3262*38fd1498Szrj new_pat->num_results += to_pat->num_results;
3263*38fd1498Szrj }
3264*38fd1498Szrj else
3265*38fd1498Szrj /* The target state doesn't match anything and so is not part
3266*38fd1498Szrj of the pattern. */
3267*38fd1498Szrj new_pat->num_results += 1;
3268*38fd1498Szrj
3269*38fd1498Szrj /* See if any earlier states that match RES2's pattern also match
3270*38fd1498Szrj NEW_PAT. */
3271*38fd1498Szrj bool matched_p = false;
3272*38fd1498Szrj for (merge_state_info *sinfo1 = sinfo2->prev_same_test; sinfo1;
3273*38fd1498Szrj sinfo1 = sinfo1->prev_same_test)
3274*38fd1498Szrj {
3275*38fd1498Szrj prune_invalid_results (sinfo1);
3276*38fd1498Szrj if (sinfo1->res
3277*38fd1498Szrj && sinfo1->res->pattern == res2->pattern
3278*38fd1498Szrj && merge_patterns (sinfo1, sinfo2))
3279*38fd1498Szrj matched_p = true;
3280*38fd1498Szrj }
3281*38fd1498Szrj if (!matched_p)
3282*38fd1498Szrj {
3283*38fd1498Szrj /* Nothing else matches NEW_PAT, so go back to the previous
3284*38fd1498Szrj pattern (possibly just a single-state one). */
3285*38fd1498Szrj sinfo2->res = res2;
3286*38fd1498Szrj delete new_pat;
3287*38fd1498Szrj delete new_res2;
3288*38fd1498Szrj }
3289*38fd1498Szrj /* Assume that SINFO2 will use RES. At this point we don't know
3290*38fd1498Szrj whether earlier states that match the same pattern will use
3291*38fd1498Szrj that match or a different one. */
3292*38fd1498Szrj sinfo2->res->pattern->num_users += 1;
3293*38fd1498Szrj }
3294*38fd1498Szrj /* Step 4: Finalize the choice of pattern for each state, ignoring
3295*38fd1498Szrj patterns that were only used once. Update each pattern's size
3296*38fd1498Szrj so that it doesn't include subpatterns that are going to be split
3297*38fd1498Szrj out into subroutines. */
3298*38fd1498Szrj for (unsigned int i = 0; i < states.length (); ++i)
3299*38fd1498Szrj {
3300*38fd1498Szrj merge_state_info *sinfo = &states[i];
3301*38fd1498Szrj merge_state_result *res = sinfo->res;
3302*38fd1498Szrj /* Wind past patterns that are only used by SINFO. */
3303*38fd1498Szrj while (res && res->pattern->num_users == 1)
3304*38fd1498Szrj {
3305*38fd1498Szrj res = res->prev;
3306*38fd1498Szrj sinfo->res = res;
3307*38fd1498Szrj if (res)
3308*38fd1498Szrj res->pattern->num_users += 1;
3309*38fd1498Szrj }
3310*38fd1498Szrj if (!res)
3311*38fd1498Szrj continue;
3312*38fd1498Szrj
3313*38fd1498Szrj /* We have a shared pattern and are now committed to the match. */
3314*38fd1498Szrj merge_pattern_info *pat = res->pattern;
3315*38fd1498Szrj gcc_assert (valid_result_p (pat, sinfo));
3316*38fd1498Szrj
3317*38fd1498Szrj if (!pat->complete_p)
3318*38fd1498Szrj {
3319*38fd1498Szrj /* Look for subpatterns that are going to be split out and remove
3320*38fd1498Szrj them from the number of statements. */
3321*38fd1498Szrj for (unsigned int j = 0; j < sinfo->num_transitions; ++j)
3322*38fd1498Szrj if (merge_pattern_transition *ptrans = pat->transitions[j])
3323*38fd1498Szrj {
3324*38fd1498Szrj merge_pattern_info *to_pat = ptrans->to;
3325*38fd1498Szrj if (!same_pattern_p (pat, to_pat))
3326*38fd1498Szrj pat->num_statements -= to_pat->num_statements;
3327*38fd1498Szrj }
3328*38fd1498Szrj pat->complete_p = true;
3329*38fd1498Szrj }
3330*38fd1498Szrj }
3331*38fd1498Szrj /* Step 5: Split out the patterns. */
3332*38fd1498Szrj for (unsigned int i = 0; i < states.length (); ++i)
3333*38fd1498Szrj {
3334*38fd1498Szrj merge_state_info *sinfo = &states[i];
3335*38fd1498Szrj merge_state_result *res = sinfo->res;
3336*38fd1498Szrj if (!sinfo->merged_p && res && useful_pattern_p (res->pattern))
3337*38fd1498Szrj use_pattern (sinfo);
3338*38fd1498Szrj }
3339*38fd1498Szrj fprintf (stderr, "Shared %d out of %d states by creating %d new states,"
3340*38fd1498Szrj " saving %d\n",
3341*38fd1498Szrj pattern_use_states, states.length (), pattern_def_states,
3342*38fd1498Szrj pattern_use_states - pattern_def_states);
3343*38fd1498Szrj }
3344*38fd1498Szrj
3345*38fd1498Szrj /* Information about a state tree that we're considering splitting into a
3346*38fd1498Szrj subroutine. */
3347*38fd1498Szrj struct state_size
3348*38fd1498Szrj {
3349*38fd1498Szrj /* The number of pseudo-statements in the state tree. */
3350*38fd1498Szrj unsigned int num_statements;
3351*38fd1498Szrj
3352*38fd1498Szrj /* The approximate number of nested "if" and "switch" statements that
3353*38fd1498Szrj would be required if control could fall through to a later state. */
3354*38fd1498Szrj unsigned int depth;
3355*38fd1498Szrj };
3356*38fd1498Szrj
3357*38fd1498Szrj /* Pairs a transition with information about its target state. */
3358*38fd1498Szrj typedef std::pair <transition *, state_size> subroutine_candidate;
3359*38fd1498Szrj
3360*38fd1498Szrj /* Sort two subroutine_candidates so that the one with the largest
3361*38fd1498Szrj number of statements comes last. */
3362*38fd1498Szrj
3363*38fd1498Szrj static int
subroutine_candidate_cmp(const void * a,const void * b)3364*38fd1498Szrj subroutine_candidate_cmp (const void *a, const void *b)
3365*38fd1498Szrj {
3366*38fd1498Szrj return int (((const subroutine_candidate *) a)->second.num_statements
3367*38fd1498Szrj - ((const subroutine_candidate *) b)->second.num_statements);
3368*38fd1498Szrj }
3369*38fd1498Szrj
3370*38fd1498Szrj /* Turn S into a subroutine of type TYPE and add it to PROCS. Return a new
3371*38fd1498Szrj state that performs a subroutine call to S. */
3372*38fd1498Szrj
3373*38fd1498Szrj static state *
create_subroutine(routine_type type,state * s,vec<state * > & procs)3374*38fd1498Szrj create_subroutine (routine_type type, state *s, vec <state *> &procs)
3375*38fd1498Szrj {
3376*38fd1498Szrj procs.safe_push (s);
3377*38fd1498Szrj acceptance_type acceptance;
3378*38fd1498Szrj acceptance.type = type;
3379*38fd1498Szrj acceptance.partial_p = true;
3380*38fd1498Szrj acceptance.u.subroutine_id = procs.length ();
3381*38fd1498Szrj state *news = new state;
3382*38fd1498Szrj add_decision (news, rtx_test::accept (acceptance), true, false);
3383*38fd1498Szrj return news;
3384*38fd1498Szrj }
3385*38fd1498Szrj
3386*38fd1498Szrj /* Walk state tree S, of type TYPE, and look for subtrees that would be
3387*38fd1498Szrj better split into subroutines. Accumulate all such subroutines in PROCS.
3388*38fd1498Szrj Return the size of the new state tree (excluding subroutines). */
3389*38fd1498Szrj
3390*38fd1498Szrj static state_size
find_subroutines(routine_type type,state * s,vec<state * > & procs)3391*38fd1498Szrj find_subroutines (routine_type type, state *s, vec <state *> &procs)
3392*38fd1498Szrj {
3393*38fd1498Szrj auto_vec <subroutine_candidate, 16> candidates;
3394*38fd1498Szrj state_size size;
3395*38fd1498Szrj size.num_statements = 0;
3396*38fd1498Szrj size.depth = 0;
3397*38fd1498Szrj for (decision *d = s->first; d; d = d->next)
3398*38fd1498Szrj {
3399*38fd1498Szrj if (!d->test.single_outcome_p ())
3400*38fd1498Szrj size.num_statements += 1;
3401*38fd1498Szrj for (transition *trans = d->first; trans; trans = trans->next)
3402*38fd1498Szrj {
3403*38fd1498Szrj /* Keep chains of simple decisions together if we know that no
3404*38fd1498Szrj change of position is required. We'll output this chain as a
3405*38fd1498Szrj single "if" statement, so it counts as a single nesting level. */
3406*38fd1498Szrj if (d->test.pos && d->if_statement_p ())
3407*38fd1498Szrj for (;;)
3408*38fd1498Szrj {
3409*38fd1498Szrj decision *newd = trans->to->singleton ();
3410*38fd1498Szrj if (!newd
3411*38fd1498Szrj || (newd->test.pos
3412*38fd1498Szrj && newd->test.pos_operand < 0
3413*38fd1498Szrj && newd->test.pos != d->test.pos)
3414*38fd1498Szrj || !newd->if_statement_p ())
3415*38fd1498Szrj break;
3416*38fd1498Szrj if (!newd->test.single_outcome_p ())
3417*38fd1498Szrj size.num_statements += 1;
3418*38fd1498Szrj trans = newd->singleton ();
3419*38fd1498Szrj if (newd->test.kind == rtx_test::SET_OP
3420*38fd1498Szrj || newd->test.kind == rtx_test::ACCEPT)
3421*38fd1498Szrj break;
3422*38fd1498Szrj }
3423*38fd1498Szrj /* The target of TRANS is a subroutine candidate. First recurse
3424*38fd1498Szrj on it to see how big it is after subroutines have been
3425*38fd1498Szrj split out. */
3426*38fd1498Szrj state_size to_size = find_subroutines (type, trans->to, procs);
3427*38fd1498Szrj if (d->next && to_size.depth > MAX_DEPTH)
3428*38fd1498Szrj /* Keeping the target state in the same routine would lead
3429*38fd1498Szrj to an excessive nesting of "if" and "switch" statements.
3430*38fd1498Szrj Split it out into a subroutine so that it can use
3431*38fd1498Szrj inverted tests that return early on failure. */
3432*38fd1498Szrj trans->to = create_subroutine (type, trans->to, procs);
3433*38fd1498Szrj else
3434*38fd1498Szrj {
3435*38fd1498Szrj size.num_statements += to_size.num_statements;
3436*38fd1498Szrj if (to_size.num_statements < MIN_NUM_STATEMENTS)
3437*38fd1498Szrj /* The target state is too small to be worth splitting.
3438*38fd1498Szrj Keep it in the same routine as S. */
3439*38fd1498Szrj size.depth = MAX (size.depth, to_size.depth);
3440*38fd1498Szrj else
3441*38fd1498Szrj /* Assume for now that we'll keep the target state in the
3442*38fd1498Szrj same routine as S, but record it as a subroutine candidate
3443*38fd1498Szrj if S grows too big. */
3444*38fd1498Szrj candidates.safe_push (subroutine_candidate (trans, to_size));
3445*38fd1498Szrj }
3446*38fd1498Szrj }
3447*38fd1498Szrj }
3448*38fd1498Szrj if (size.num_statements > MAX_NUM_STATEMENTS)
3449*38fd1498Szrj {
3450*38fd1498Szrj /* S is too big. Sort the subroutine candidates so that bigger ones
3451*38fd1498Szrj are nearer the end. */
3452*38fd1498Szrj candidates.qsort (subroutine_candidate_cmp);
3453*38fd1498Szrj while (!candidates.is_empty ()
3454*38fd1498Szrj && size.num_statements > MAX_NUM_STATEMENTS)
3455*38fd1498Szrj {
3456*38fd1498Szrj /* Peel off a candidate and force it into a subroutine. */
3457*38fd1498Szrj subroutine_candidate cand = candidates.pop ();
3458*38fd1498Szrj size.num_statements -= cand.second.num_statements;
3459*38fd1498Szrj cand.first->to = create_subroutine (type, cand.first->to, procs);
3460*38fd1498Szrj }
3461*38fd1498Szrj }
3462*38fd1498Szrj /* Update the depth for subroutine candidates that we decided not to
3463*38fd1498Szrj split out. */
3464*38fd1498Szrj for (unsigned int i = 0; i < candidates.length (); ++i)
3465*38fd1498Szrj size.depth = MAX (size.depth, candidates[i].second.depth);
3466*38fd1498Szrj size.depth += 1;
3467*38fd1498Szrj return size;
3468*38fd1498Szrj }
3469*38fd1498Szrj
3470*38fd1498Szrj /* Return true if, for all X, PRED (X, MODE) implies that X has mode MODE. */
3471*38fd1498Szrj
3472*38fd1498Szrj static bool
safe_predicate_mode(const struct pred_data * pred,machine_mode mode)3473*38fd1498Szrj safe_predicate_mode (const struct pred_data *pred, machine_mode mode)
3474*38fd1498Szrj {
3475*38fd1498Szrj /* Scalar integer constants have VOIDmode. */
3476*38fd1498Szrj if (GET_MODE_CLASS (mode) == MODE_INT
3477*38fd1498Szrj && (pred->codes[CONST_INT]
3478*38fd1498Szrj || pred->codes[CONST_DOUBLE]
3479*38fd1498Szrj || pred->codes[CONST_WIDE_INT]
3480*38fd1498Szrj || pred->codes[LABEL_REF]))
3481*38fd1498Szrj return false;
3482*38fd1498Szrj
3483*38fd1498Szrj return !pred->special && mode != VOIDmode;
3484*38fd1498Szrj }
3485*38fd1498Szrj
3486*38fd1498Szrj /* Fill CODES with the set of codes that could be matched by PRED. */
3487*38fd1498Szrj
3488*38fd1498Szrj static void
get_predicate_codes(const struct pred_data * pred,int_set * codes)3489*38fd1498Szrj get_predicate_codes (const struct pred_data *pred, int_set *codes)
3490*38fd1498Szrj {
3491*38fd1498Szrj for (int i = 0; i < NUM_TRUE_RTX_CODE; ++i)
3492*38fd1498Szrj if (!pred || pred->codes[i])
3493*38fd1498Szrj codes->safe_push (i);
3494*38fd1498Szrj }
3495*38fd1498Szrj
3496*38fd1498Szrj /* Return true if the first path through D1 tests the same thing as D2. */
3497*38fd1498Szrj
3498*38fd1498Szrj static bool
has_same_test_p(decision * d1,decision * d2)3499*38fd1498Szrj has_same_test_p (decision *d1, decision *d2)
3500*38fd1498Szrj {
3501*38fd1498Szrj do
3502*38fd1498Szrj {
3503*38fd1498Szrj if (d1->test == d2->test)
3504*38fd1498Szrj return true;
3505*38fd1498Szrj d1 = d1->first->to->first;
3506*38fd1498Szrj }
3507*38fd1498Szrj while (d1);
3508*38fd1498Szrj return false;
3509*38fd1498Szrj }
3510*38fd1498Szrj
3511*38fd1498Szrj /* Return true if D1 and D2 cannot match the same rtx. All states reachable
3512*38fd1498Szrj from D2 have single decisions and all those decisions have single
3513*38fd1498Szrj transitions. */
3514*38fd1498Szrj
3515*38fd1498Szrj static bool
mutually_exclusive_p(decision * d1,decision * d2)3516*38fd1498Szrj mutually_exclusive_p (decision *d1, decision *d2)
3517*38fd1498Szrj {
3518*38fd1498Szrj /* If one path through D1 fails to test the same thing as D2, assume
3519*38fd1498Szrj that D2's test could be true for D1 and look for a later, more useful,
3520*38fd1498Szrj test. This isn't as expensive as it looks in practice. */
3521*38fd1498Szrj while (!has_same_test_p (d1, d2))
3522*38fd1498Szrj {
3523*38fd1498Szrj d2 = d2->singleton ()->to->singleton ();
3524*38fd1498Szrj if (!d2)
3525*38fd1498Szrj return false;
3526*38fd1498Szrj }
3527*38fd1498Szrj if (d1->test == d2->test)
3528*38fd1498Szrj {
3529*38fd1498Szrj /* Look for any transitions from D1 that have the same labels as
3530*38fd1498Szrj the transition from D2. */
3531*38fd1498Szrj transition *trans2 = d2->singleton ();
3532*38fd1498Szrj for (transition *trans1 = d1->first; trans1; trans1 = trans1->next)
3533*38fd1498Szrj {
3534*38fd1498Szrj int_set::iterator i1 = trans1->labels.begin ();
3535*38fd1498Szrj int_set::iterator end1 = trans1->labels.end ();
3536*38fd1498Szrj int_set::iterator i2 = trans2->labels.begin ();
3537*38fd1498Szrj int_set::iterator end2 = trans2->labels.end ();
3538*38fd1498Szrj while (i1 != end1 && i2 != end2)
3539*38fd1498Szrj if (*i1 < *i2)
3540*38fd1498Szrj ++i1;
3541*38fd1498Szrj else if (*i2 < *i1)
3542*38fd1498Szrj ++i2;
3543*38fd1498Szrj else
3544*38fd1498Szrj {
3545*38fd1498Szrj /* TRANS1 has some labels in common with TRANS2. Assume
3546*38fd1498Szrj that D1 and D2 could match the same rtx if the target
3547*38fd1498Szrj of TRANS1 could match the same rtx as D2. */
3548*38fd1498Szrj for (decision *subd1 = trans1->to->first;
3549*38fd1498Szrj subd1; subd1 = subd1->next)
3550*38fd1498Szrj if (!mutually_exclusive_p (subd1, d2))
3551*38fd1498Szrj return false;
3552*38fd1498Szrj break;
3553*38fd1498Szrj }
3554*38fd1498Szrj }
3555*38fd1498Szrj return true;
3556*38fd1498Szrj }
3557*38fd1498Szrj for (transition *trans1 = d1->first; trans1; trans1 = trans1->next)
3558*38fd1498Szrj for (decision *subd1 = trans1->to->first; subd1; subd1 = subd1->next)
3559*38fd1498Szrj if (!mutually_exclusive_p (subd1, d2))
3560*38fd1498Szrj return false;
3561*38fd1498Szrj return true;
3562*38fd1498Szrj }
3563*38fd1498Szrj
3564*38fd1498Szrj /* Try to merge S2's decision into D1, given that they have the same test.
3565*38fd1498Szrj Fail only if EXCLUDE is nonnull and the new transition would have the
3566*38fd1498Szrj same labels as *EXCLUDE. When returning true, set *NEXT_S1, *NEXT_S2
3567*38fd1498Szrj and *NEXT_EXCLUDE as for merge_into_state_1, or set *NEXT_S2 to null
3568*38fd1498Szrj if the merge is complete. */
3569*38fd1498Szrj
3570*38fd1498Szrj static bool
merge_into_decision(decision * d1,state * s2,const int_set * exclude,state ** next_s1,state ** next_s2,const int_set ** next_exclude)3571*38fd1498Szrj merge_into_decision (decision *d1, state *s2, const int_set *exclude,
3572*38fd1498Szrj state **next_s1, state **next_s2,
3573*38fd1498Szrj const int_set **next_exclude)
3574*38fd1498Szrj {
3575*38fd1498Szrj decision *d2 = s2->singleton ();
3576*38fd1498Szrj transition *trans2 = d2->singleton ();
3577*38fd1498Szrj
3578*38fd1498Szrj /* Get a list of the transitions that intersect TRANS2. */
3579*38fd1498Szrj auto_vec <transition *, 32> intersecting;
3580*38fd1498Szrj for (transition *trans1 = d1->first; trans1; trans1 = trans1->next)
3581*38fd1498Szrj {
3582*38fd1498Szrj int_set::iterator i1 = trans1->labels.begin ();
3583*38fd1498Szrj int_set::iterator end1 = trans1->labels.end ();
3584*38fd1498Szrj int_set::iterator i2 = trans2->labels.begin ();
3585*38fd1498Szrj int_set::iterator end2 = trans2->labels.end ();
3586*38fd1498Szrj bool trans1_is_subset = true;
3587*38fd1498Szrj bool trans2_is_subset = true;
3588*38fd1498Szrj bool intersect_p = false;
3589*38fd1498Szrj while (i1 != end1 && i2 != end2)
3590*38fd1498Szrj if (*i1 < *i2)
3591*38fd1498Szrj {
3592*38fd1498Szrj trans1_is_subset = false;
3593*38fd1498Szrj ++i1;
3594*38fd1498Szrj }
3595*38fd1498Szrj else if (*i2 < *i1)
3596*38fd1498Szrj {
3597*38fd1498Szrj trans2_is_subset = false;
3598*38fd1498Szrj ++i2;
3599*38fd1498Szrj }
3600*38fd1498Szrj else
3601*38fd1498Szrj {
3602*38fd1498Szrj intersect_p = true;
3603*38fd1498Szrj ++i1;
3604*38fd1498Szrj ++i2;
3605*38fd1498Szrj }
3606*38fd1498Szrj if (i1 != end1)
3607*38fd1498Szrj trans1_is_subset = false;
3608*38fd1498Szrj if (i2 != end2)
3609*38fd1498Szrj trans2_is_subset = false;
3610*38fd1498Szrj if (trans1_is_subset && trans2_is_subset)
3611*38fd1498Szrj {
3612*38fd1498Szrj /* There's already a transition that matches exactly.
3613*38fd1498Szrj Merge the target states. */
3614*38fd1498Szrj trans1->optional &= trans2->optional;
3615*38fd1498Szrj *next_s1 = trans1->to;
3616*38fd1498Szrj *next_s2 = trans2->to;
3617*38fd1498Szrj *next_exclude = 0;
3618*38fd1498Szrj return true;
3619*38fd1498Szrj }
3620*38fd1498Szrj if (trans2_is_subset)
3621*38fd1498Szrj {
3622*38fd1498Szrj /* TRANS1 has all the labels that TRANS2 needs. Merge S2 into
3623*38fd1498Szrj the target of TRANS1, but (to avoid infinite recursion)
3624*38fd1498Szrj make sure that we don't end up creating another transition
3625*38fd1498Szrj like TRANS1. */
3626*38fd1498Szrj *next_s1 = trans1->to;
3627*38fd1498Szrj *next_s2 = s2;
3628*38fd1498Szrj *next_exclude = &trans1->labels;
3629*38fd1498Szrj return true;
3630*38fd1498Szrj }
3631*38fd1498Szrj if (intersect_p)
3632*38fd1498Szrj intersecting.safe_push (trans1);
3633*38fd1498Szrj }
3634*38fd1498Szrj
3635*38fd1498Szrj if (intersecting.is_empty ())
3636*38fd1498Szrj {
3637*38fd1498Szrj /* No existing labels intersect the new ones. We can just add
3638*38fd1498Szrj TRANS2 itself. */
3639*38fd1498Szrj d1->push_back (d2->release ());
3640*38fd1498Szrj *next_s1 = 0;
3641*38fd1498Szrj *next_s2 = 0;
3642*38fd1498Szrj *next_exclude = 0;
3643*38fd1498Szrj return true;
3644*38fd1498Szrj }
3645*38fd1498Szrj
3646*38fd1498Szrj /* Take the union of the labels in INTERSECTING and TRANS2. Store the
3647*38fd1498Szrj result in COMBINED and use NEXT as a temporary. */
3648*38fd1498Szrj int_set tmp1 = trans2->labels, tmp2;
3649*38fd1498Szrj int_set *combined = &tmp1, *next = &tmp2;
3650*38fd1498Szrj for (unsigned int i = 0; i < intersecting.length (); ++i)
3651*38fd1498Szrj {
3652*38fd1498Szrj transition *trans1 = intersecting[i];
3653*38fd1498Szrj next->truncate (0);
3654*38fd1498Szrj next->safe_grow (trans1->labels.length () + combined->length ());
3655*38fd1498Szrj int_set::iterator end
3656*38fd1498Szrj = std::set_union (trans1->labels.begin (), trans1->labels.end (),
3657*38fd1498Szrj combined->begin (), combined->end (),
3658*38fd1498Szrj next->begin ());
3659*38fd1498Szrj next->truncate (end - next->begin ());
3660*38fd1498Szrj std::swap (next, combined);
3661*38fd1498Szrj }
3662*38fd1498Szrj
3663*38fd1498Szrj /* Stop now if we've been told not to create a transition with these
3664*38fd1498Szrj labels. */
3665*38fd1498Szrj if (exclude && *combined == *exclude)
3666*38fd1498Szrj return false;
3667*38fd1498Szrj
3668*38fd1498Szrj /* Get the transition that should carry the new labels. */
3669*38fd1498Szrj transition *new_trans = intersecting[0];
3670*38fd1498Szrj if (intersecting.length () == 1)
3671*38fd1498Szrj {
3672*38fd1498Szrj /* We're merging with one existing transition whose labels are a
3673*38fd1498Szrj subset of those required. If both transitions are optional,
3674*38fd1498Szrj we can just expand the set of labels so that it's suitable
3675*38fd1498Szrj for both transitions. It isn't worth preserving the original
3676*38fd1498Szrj transitions since we know that they can't be merged; we would
3677*38fd1498Szrj need to backtrack to S2 if TRANS1->to fails. In contrast,
3678*38fd1498Szrj we might be able to merge the targets of the transitions
3679*38fd1498Szrj without any backtracking.
3680*38fd1498Szrj
3681*38fd1498Szrj If instead the existing transition is not optional, ensure that
3682*38fd1498Szrj all target decisions are suitably protected. Some decisions
3683*38fd1498Szrj might already have a more specific requirement than NEW_TRANS,
3684*38fd1498Szrj in which case there's no point testing NEW_TRANS as well. E.g. this
3685*38fd1498Szrj would have happened if a test for an (eq ...) rtx had been
3686*38fd1498Szrj added to a decision that tested whether the code is suitable
3687*38fd1498Szrj for comparison_operator. The original comparison_operator
3688*38fd1498Szrj transition would have been non-optional and the (eq ...) test
3689*38fd1498Szrj would be performed by a second decision in the target of that
3690*38fd1498Szrj transition.
3691*38fd1498Szrj
3692*38fd1498Szrj The remaining case -- keeping the original optional transition
3693*38fd1498Szrj when adding a non-optional TRANS2 -- is a wash. Preserving
3694*38fd1498Szrj the optional transition only helps if we later merge another
3695*38fd1498Szrj state S3 that is mutually exclusive with S2 and whose labels
3696*38fd1498Szrj belong to *COMBINED - TRANS1->labels. We can then test the
3697*38fd1498Szrj original NEW_TRANS and S3 in the same decision. We keep the
3698*38fd1498Szrj optional transition around for that case, but it occurs very
3699*38fd1498Szrj rarely. */
3700*38fd1498Szrj gcc_assert (new_trans->labels != *combined);
3701*38fd1498Szrj if (!new_trans->optional || !trans2->optional)
3702*38fd1498Szrj {
3703*38fd1498Szrj decision *start = 0;
3704*38fd1498Szrj for (decision *end = new_trans->to->first; end; end = end->next)
3705*38fd1498Szrj {
3706*38fd1498Szrj if (!start && end->test != d1->test)
3707*38fd1498Szrj /* END belongs to a range of decisions that need to be
3708*38fd1498Szrj protected by NEW_TRANS. */
3709*38fd1498Szrj start = end;
3710*38fd1498Szrj if (start && (!end->next || end->next->test == d1->test))
3711*38fd1498Szrj {
3712*38fd1498Szrj /* Protect [START, END] with NEW_TRANS. The decisions
3713*38fd1498Szrj move to NEW_S and NEW_D becomes part of NEW_TRANS->to. */
3714*38fd1498Szrj state *new_s = new state;
3715*38fd1498Szrj decision *new_d = new decision (d1->test);
3716*38fd1498Szrj new_d->push_back (new transition (new_trans->labels, new_s,
3717*38fd1498Szrj new_trans->optional));
3718*38fd1498Szrj state::range r (start, end);
3719*38fd1498Szrj new_trans->to->replace (r, new_d);
3720*38fd1498Szrj new_s->push_back (r);
3721*38fd1498Szrj
3722*38fd1498Szrj /* Continue with an empty range. */
3723*38fd1498Szrj start = 0;
3724*38fd1498Szrj
3725*38fd1498Szrj /* Continue from the decision after NEW_D. */
3726*38fd1498Szrj end = new_d;
3727*38fd1498Szrj }
3728*38fd1498Szrj }
3729*38fd1498Szrj }
3730*38fd1498Szrj new_trans->optional = true;
3731*38fd1498Szrj new_trans->labels = *combined;
3732*38fd1498Szrj }
3733*38fd1498Szrj else
3734*38fd1498Szrj {
3735*38fd1498Szrj /* We're merging more than one existing transition together.
3736*38fd1498Szrj Those transitions are successfully dividing the matching space
3737*38fd1498Szrj and so we want to preserve them, even if they're optional.
3738*38fd1498Szrj
3739*38fd1498Szrj Create a new transition with the union set of labels and make
3740*38fd1498Szrj it go to a state that has the original transitions. */
3741*38fd1498Szrj decision *new_d = new decision (d1->test);
3742*38fd1498Szrj for (unsigned int i = 0; i < intersecting.length (); ++i)
3743*38fd1498Szrj new_d->push_back (d1->remove (intersecting[i]));
3744*38fd1498Szrj
3745*38fd1498Szrj state *new_s = new state;
3746*38fd1498Szrj new_s->push_back (new_d);
3747*38fd1498Szrj
3748*38fd1498Szrj new_trans = new transition (*combined, new_s, true);
3749*38fd1498Szrj d1->push_back (new_trans);
3750*38fd1498Szrj }
3751*38fd1498Szrj
3752*38fd1498Szrj /* We now have an optional transition with labels *COMBINED. Decide
3753*38fd1498Szrj whether we can use it as TRANS2 or whether we need to merge S2
3754*38fd1498Szrj into the target of NEW_TRANS. */
3755*38fd1498Szrj gcc_assert (new_trans->optional);
3756*38fd1498Szrj if (new_trans->labels == trans2->labels)
3757*38fd1498Szrj {
3758*38fd1498Szrj /* NEW_TRANS matches TRANS2. Just merge the target states. */
3759*38fd1498Szrj new_trans->optional = trans2->optional;
3760*38fd1498Szrj *next_s1 = new_trans->to;
3761*38fd1498Szrj *next_s2 = trans2->to;
3762*38fd1498Szrj *next_exclude = 0;
3763*38fd1498Szrj }
3764*38fd1498Szrj else
3765*38fd1498Szrj {
3766*38fd1498Szrj /* Try to merge TRANS2 into the target of the overlapping transition,
3767*38fd1498Szrj but (to prevent infinite recursion or excessive redundancy) without
3768*38fd1498Szrj creating another transition of the same type. */
3769*38fd1498Szrj *next_s1 = new_trans->to;
3770*38fd1498Szrj *next_s2 = s2;
3771*38fd1498Szrj *next_exclude = &new_trans->labels;
3772*38fd1498Szrj }
3773*38fd1498Szrj return true;
3774*38fd1498Szrj }
3775*38fd1498Szrj
3776*38fd1498Szrj /* Make progress in merging S2 into S1, given that each state in S2
3777*38fd1498Szrj has a single decision. If EXCLUDE is nonnull, avoid creating a new
3778*38fd1498Szrj transition with the same test as S2's decision and with the labels
3779*38fd1498Szrj in *EXCLUDE.
3780*38fd1498Szrj
3781*38fd1498Szrj Return true if there is still work to do. When returning true,
3782*38fd1498Szrj set *NEXT_S1, *NEXT_S2 and *NEXT_EXCLUDE to the values that
3783*38fd1498Szrj S1, S2 and EXCLUDE should have next time round.
3784*38fd1498Szrj
3785*38fd1498Szrj If S1 and S2 both match a particular rtx, give priority to S1. */
3786*38fd1498Szrj
3787*38fd1498Szrj static bool
merge_into_state_1(state * s1,state * s2,const int_set * exclude,state ** next_s1,state ** next_s2,const int_set ** next_exclude)3788*38fd1498Szrj merge_into_state_1 (state *s1, state *s2, const int_set *exclude,
3789*38fd1498Szrj state **next_s1, state **next_s2,
3790*38fd1498Szrj const int_set **next_exclude)
3791*38fd1498Szrj {
3792*38fd1498Szrj decision *d2 = s2->singleton ();
3793*38fd1498Szrj if (decision *d1 = s1->last)
3794*38fd1498Szrj {
3795*38fd1498Szrj if (d1->test.terminal_p ())
3796*38fd1498Szrj /* D1 is an unconditional return, so S2 can never match. This can
3797*38fd1498Szrj sometimes be a bug in the .md description, but might also happen
3798*38fd1498Szrj if genconditions forces some conditions to true for certain
3799*38fd1498Szrj configurations. */
3800*38fd1498Szrj return false;
3801*38fd1498Szrj
3802*38fd1498Szrj /* Go backwards through the decisions in S1, stopping once we find one
3803*38fd1498Szrj that could match the same thing as S2. */
3804*38fd1498Szrj while (d1->prev && mutually_exclusive_p (d1, d2))
3805*38fd1498Szrj d1 = d1->prev;
3806*38fd1498Szrj
3807*38fd1498Szrj /* Search forwards from that point, merging D2 into the first
3808*38fd1498Szrj decision we can. */
3809*38fd1498Szrj for (; d1; d1 = d1->next)
3810*38fd1498Szrj {
3811*38fd1498Szrj /* If S2 performs some optional tests before testing the same thing
3812*38fd1498Szrj as D1, those tests do not help to distinguish D1 and S2, so it's
3813*38fd1498Szrj better to drop them. Search through such optional decisions
3814*38fd1498Szrj until we find something that tests the same thing as D1. */
3815*38fd1498Szrj state *sub_s2 = s2;
3816*38fd1498Szrj for (;;)
3817*38fd1498Szrj {
3818*38fd1498Szrj decision *sub_d2 = sub_s2->singleton ();
3819*38fd1498Szrj if (d1->test == sub_d2->test)
3820*38fd1498Szrj {
3821*38fd1498Szrj /* Only apply EXCLUDE if we're testing the same thing
3822*38fd1498Szrj as D2. */
3823*38fd1498Szrj const int_set *sub_exclude = (d2 == sub_d2 ? exclude : 0);
3824*38fd1498Szrj
3825*38fd1498Szrj /* Try to merge SUB_S2 into D1. This can only fail if
3826*38fd1498Szrj it would involve creating a new transition with
3827*38fd1498Szrj labels SUB_EXCLUDE. */
3828*38fd1498Szrj if (merge_into_decision (d1, sub_s2, sub_exclude,
3829*38fd1498Szrj next_s1, next_s2, next_exclude))
3830*38fd1498Szrj return *next_s2 != 0;
3831*38fd1498Szrj
3832*38fd1498Szrj /* Can't merge with D1; try a later decision. */
3833*38fd1498Szrj break;
3834*38fd1498Szrj }
3835*38fd1498Szrj transition *sub_trans2 = sub_d2->singleton ();
3836*38fd1498Szrj if (!sub_trans2->optional)
3837*38fd1498Szrj /* Can't merge with D1; try a later decision. */
3838*38fd1498Szrj break;
3839*38fd1498Szrj sub_s2 = sub_trans2->to;
3840*38fd1498Szrj }
3841*38fd1498Szrj }
3842*38fd1498Szrj }
3843*38fd1498Szrj
3844*38fd1498Szrj /* We can't merge D2 with any existing decision. Just add it to the end. */
3845*38fd1498Szrj s1->push_back (s2->release ());
3846*38fd1498Szrj return false;
3847*38fd1498Szrj }
3848*38fd1498Szrj
3849*38fd1498Szrj /* Merge S2 into S1. If they both match a particular rtx, give
3850*38fd1498Szrj priority to S1. Each state in S2 has a single decision. */
3851*38fd1498Szrj
3852*38fd1498Szrj static void
merge_into_state(state * s1,state * s2)3853*38fd1498Szrj merge_into_state (state *s1, state *s2)
3854*38fd1498Szrj {
3855*38fd1498Szrj const int_set *exclude = 0;
3856*38fd1498Szrj while (s2 && merge_into_state_1 (s1, s2, exclude, &s1, &s2, &exclude))
3857*38fd1498Szrj continue;
3858*38fd1498Szrj }
3859*38fd1498Szrj
3860*38fd1498Szrj /* Pairs a pattern that needs to be matched with the rtx position at
3861*38fd1498Szrj which the pattern should occur. */
3862*38fd1498Szrj struct pattern_pos {
pattern_pospattern_pos3863*38fd1498Szrj pattern_pos () {}
3864*38fd1498Szrj pattern_pos (rtx, position *);
3865*38fd1498Szrj
3866*38fd1498Szrj rtx pattern;
3867*38fd1498Szrj position *pos;
3868*38fd1498Szrj };
3869*38fd1498Szrj
pattern_pos(rtx pattern_in,position * pos_in)3870*38fd1498Szrj pattern_pos::pattern_pos (rtx pattern_in, position *pos_in)
3871*38fd1498Szrj : pattern (pattern_in), pos (pos_in)
3872*38fd1498Szrj {}
3873*38fd1498Szrj
3874*38fd1498Szrj /* Compare entries according to their depth-first order. There shouldn't
3875*38fd1498Szrj be two entries at the same position. */
3876*38fd1498Szrj
3877*38fd1498Szrj bool
3878*38fd1498Szrj operator < (const pattern_pos &e1, const pattern_pos &e2)
3879*38fd1498Szrj {
3880*38fd1498Szrj int diff = compare_positions (e1.pos, e2.pos);
3881*38fd1498Szrj gcc_assert (diff != 0 || e1.pattern == e2.pattern);
3882*38fd1498Szrj return diff < 0;
3883*38fd1498Szrj }
3884*38fd1498Szrj
3885*38fd1498Szrj /* Add new decisions to S that check whether the rtx at position POS
3886*38fd1498Szrj matches PATTERN. Return the state that is reached in that case.
3887*38fd1498Szrj TOP_PATTERN is the overall pattern, as passed to match_pattern_1. */
3888*38fd1498Szrj
3889*38fd1498Szrj static state *
match_pattern_2(state * s,md_rtx_info * info,position * pos,rtx pattern)3890*38fd1498Szrj match_pattern_2 (state *s, md_rtx_info *info, position *pos, rtx pattern)
3891*38fd1498Szrj {
3892*38fd1498Szrj auto_vec <pattern_pos, 32> worklist;
3893*38fd1498Szrj auto_vec <pattern_pos, 32> pred_and_mode_tests;
3894*38fd1498Szrj auto_vec <pattern_pos, 32> dup_tests;
3895*38fd1498Szrj
3896*38fd1498Szrj worklist.safe_push (pattern_pos (pattern, pos));
3897*38fd1498Szrj while (!worklist.is_empty ())
3898*38fd1498Szrj {
3899*38fd1498Szrj pattern_pos next = worklist.pop ();
3900*38fd1498Szrj pattern = next.pattern;
3901*38fd1498Szrj pos = next.pos;
3902*38fd1498Szrj unsigned int reverse_s = worklist.length ();
3903*38fd1498Szrj
3904*38fd1498Szrj enum rtx_code code = GET_CODE (pattern);
3905*38fd1498Szrj switch (code)
3906*38fd1498Szrj {
3907*38fd1498Szrj case MATCH_OP_DUP:
3908*38fd1498Szrj case MATCH_DUP:
3909*38fd1498Szrj case MATCH_PAR_DUP:
3910*38fd1498Szrj /* Add a test that the rtx matches the earlier one, but only
3911*38fd1498Szrj after the structure and predicates have been checked. */
3912*38fd1498Szrj dup_tests.safe_push (pattern_pos (pattern, pos));
3913*38fd1498Szrj
3914*38fd1498Szrj /* Use the same code check as the original operand. */
3915*38fd1498Szrj pattern = find_operand (info->def, XINT (pattern, 0), NULL_RTX);
3916*38fd1498Szrj /* Fall through. */
3917*38fd1498Szrj
3918*38fd1498Szrj case MATCH_PARALLEL:
3919*38fd1498Szrj case MATCH_OPERAND:
3920*38fd1498Szrj case MATCH_SCRATCH:
3921*38fd1498Szrj case MATCH_OPERATOR:
3922*38fd1498Szrj {
3923*38fd1498Szrj const char *pred_name = predicate_name (pattern);
3924*38fd1498Szrj const struct pred_data *pred = 0;
3925*38fd1498Szrj if (pred_name[0] != 0)
3926*38fd1498Szrj {
3927*38fd1498Szrj pred = lookup_predicate (pred_name);
3928*38fd1498Szrj /* Only report errors once per rtx. */
3929*38fd1498Szrj if (code == GET_CODE (pattern))
3930*38fd1498Szrj {
3931*38fd1498Szrj if (!pred)
3932*38fd1498Szrj error_at (info->loc, "unknown predicate '%s' used in %s",
3933*38fd1498Szrj pred_name, GET_RTX_NAME (code));
3934*38fd1498Szrj else if (code == MATCH_PARALLEL
3935*38fd1498Szrj && pred->singleton != PARALLEL)
3936*38fd1498Szrj error_at (info->loc, "predicate '%s' used in"
3937*38fd1498Szrj " match_parallel does not allow only PARALLEL",
3938*38fd1498Szrj pred->name);
3939*38fd1498Szrj }
3940*38fd1498Szrj }
3941*38fd1498Szrj
3942*38fd1498Szrj if (code == MATCH_PARALLEL || code == MATCH_PAR_DUP)
3943*38fd1498Szrj {
3944*38fd1498Szrj /* Check that we have a parallel with enough elements. */
3945*38fd1498Szrj s = add_decision (s, rtx_test::code (pos), PARALLEL, false);
3946*38fd1498Szrj int min_len = XVECLEN (pattern, 2);
3947*38fd1498Szrj s = add_decision (s, rtx_test::veclen_ge (pos, min_len),
3948*38fd1498Szrj true, false);
3949*38fd1498Szrj }
3950*38fd1498Szrj else
3951*38fd1498Szrj {
3952*38fd1498Szrj /* Check that the rtx has one of codes accepted by the
3953*38fd1498Szrj predicate. This is necessary when matching suboperands
3954*38fd1498Szrj of a MATCH_OPERATOR or MATCH_OP_DUP, since we can't
3955*38fd1498Szrj call XEXP (X, N) without checking that X has at least
3956*38fd1498Szrj N+1 operands. */
3957*38fd1498Szrj int_set codes;
3958*38fd1498Szrj get_predicate_codes (pred, &codes);
3959*38fd1498Szrj bool need_codes = (pred
3960*38fd1498Szrj && (code == MATCH_OPERATOR
3961*38fd1498Szrj || code == MATCH_OP_DUP));
3962*38fd1498Szrj s = add_decision (s, rtx_test::code (pos), codes, !need_codes);
3963*38fd1498Szrj }
3964*38fd1498Szrj
3965*38fd1498Szrj /* Postpone the predicate check until we've checked the rest
3966*38fd1498Szrj of the rtx structure. */
3967*38fd1498Szrj if (code == GET_CODE (pattern))
3968*38fd1498Szrj pred_and_mode_tests.safe_push (pattern_pos (pattern, pos));
3969*38fd1498Szrj
3970*38fd1498Szrj /* If we need to match suboperands, add them to the worklist. */
3971*38fd1498Szrj if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
3972*38fd1498Szrj {
3973*38fd1498Szrj position **subpos_ptr;
3974*38fd1498Szrj enum position_type pos_type;
3975*38fd1498Szrj int i;
3976*38fd1498Szrj if (code == MATCH_OPERATOR || code == MATCH_OP_DUP)
3977*38fd1498Szrj {
3978*38fd1498Szrj pos_type = POS_XEXP;
3979*38fd1498Szrj subpos_ptr = &pos->xexps;
3980*38fd1498Szrj i = (code == MATCH_OPERATOR ? 2 : 1);
3981*38fd1498Szrj }
3982*38fd1498Szrj else
3983*38fd1498Szrj {
3984*38fd1498Szrj pos_type = POS_XVECEXP0;
3985*38fd1498Szrj subpos_ptr = &pos->xvecexp0s;
3986*38fd1498Szrj i = 2;
3987*38fd1498Szrj }
3988*38fd1498Szrj for (int j = 0; j < XVECLEN (pattern, i); ++j)
3989*38fd1498Szrj {
3990*38fd1498Szrj position *subpos = next_position (subpos_ptr, pos,
3991*38fd1498Szrj pos_type, j);
3992*38fd1498Szrj worklist.safe_push (pattern_pos (XVECEXP (pattern, i, j),
3993*38fd1498Szrj subpos));
3994*38fd1498Szrj subpos_ptr = &subpos->next;
3995*38fd1498Szrj }
3996*38fd1498Szrj }
3997*38fd1498Szrj break;
3998*38fd1498Szrj }
3999*38fd1498Szrj
4000*38fd1498Szrj default:
4001*38fd1498Szrj {
4002*38fd1498Szrj /* Check that the rtx has the right code. */
4003*38fd1498Szrj s = add_decision (s, rtx_test::code (pos), code, false);
4004*38fd1498Szrj
4005*38fd1498Szrj /* Queue a test for the mode if one is specified. */
4006*38fd1498Szrj if (GET_MODE (pattern) != VOIDmode)
4007*38fd1498Szrj pred_and_mode_tests.safe_push (pattern_pos (pattern, pos));
4008*38fd1498Szrj
4009*38fd1498Szrj /* Push subrtxes onto the worklist. Match nonrtx operands now. */
4010*38fd1498Szrj const char *fmt = GET_RTX_FORMAT (code);
4011*38fd1498Szrj position **subpos_ptr = &pos->xexps;
4012*38fd1498Szrj for (size_t i = 0; fmt[i]; ++i)
4013*38fd1498Szrj {
4014*38fd1498Szrj position *subpos = next_position (subpos_ptr, pos,
4015*38fd1498Szrj POS_XEXP, i);
4016*38fd1498Szrj switch (fmt[i])
4017*38fd1498Szrj {
4018*38fd1498Szrj case 'e': case 'u':
4019*38fd1498Szrj worklist.safe_push (pattern_pos (XEXP (pattern, i),
4020*38fd1498Szrj subpos));
4021*38fd1498Szrj break;
4022*38fd1498Szrj
4023*38fd1498Szrj case 'E':
4024*38fd1498Szrj {
4025*38fd1498Szrj /* Make sure the vector has the right number of
4026*38fd1498Szrj elements. */
4027*38fd1498Szrj int length = XVECLEN (pattern, i);
4028*38fd1498Szrj s = add_decision (s, rtx_test::veclen (pos),
4029*38fd1498Szrj length, false);
4030*38fd1498Szrj
4031*38fd1498Szrj position **subpos2_ptr = &pos->xvecexp0s;
4032*38fd1498Szrj for (int j = 0; j < length; j++)
4033*38fd1498Szrj {
4034*38fd1498Szrj position *subpos2 = next_position (subpos2_ptr, pos,
4035*38fd1498Szrj POS_XVECEXP0, j);
4036*38fd1498Szrj rtx x = XVECEXP (pattern, i, j);
4037*38fd1498Szrj worklist.safe_push (pattern_pos (x, subpos2));
4038*38fd1498Szrj subpos2_ptr = &subpos2->next;
4039*38fd1498Szrj }
4040*38fd1498Szrj break;
4041*38fd1498Szrj }
4042*38fd1498Szrj
4043*38fd1498Szrj case 'i':
4044*38fd1498Szrj /* Make sure that XINT (X, I) has the right value. */
4045*38fd1498Szrj s = add_decision (s, rtx_test::int_field (pos, i),
4046*38fd1498Szrj XINT (pattern, i), false);
4047*38fd1498Szrj break;
4048*38fd1498Szrj
4049*38fd1498Szrj case 'r':
4050*38fd1498Szrj /* Make sure that REGNO (X) has the right value. */
4051*38fd1498Szrj gcc_assert (i == 0);
4052*38fd1498Szrj s = add_decision (s, rtx_test::regno_field (pos),
4053*38fd1498Szrj REGNO (pattern), false);
4054*38fd1498Szrj break;
4055*38fd1498Szrj
4056*38fd1498Szrj case 'w':
4057*38fd1498Szrj /* Make sure that XWINT (X, I) has the right value. */
4058*38fd1498Szrj s = add_decision (s, rtx_test::wide_int_field (pos, i),
4059*38fd1498Szrj XWINT (pattern, 0), false);
4060*38fd1498Szrj break;
4061*38fd1498Szrj
4062*38fd1498Szrj case 'p':
4063*38fd1498Szrj /* We don't have a way of parsing polynomial offsets yet,
4064*38fd1498Szrj and hopefully never will. */
4065*38fd1498Szrj s = add_decision (s, rtx_test::subreg_field (pos),
4066*38fd1498Szrj SUBREG_BYTE (pattern).to_constant (),
4067*38fd1498Szrj false);
4068*38fd1498Szrj break;
4069*38fd1498Szrj
4070*38fd1498Szrj case '0':
4071*38fd1498Szrj break;
4072*38fd1498Szrj
4073*38fd1498Szrj default:
4074*38fd1498Szrj gcc_unreachable ();
4075*38fd1498Szrj }
4076*38fd1498Szrj subpos_ptr = &subpos->next;
4077*38fd1498Szrj }
4078*38fd1498Szrj }
4079*38fd1498Szrj break;
4080*38fd1498Szrj }
4081*38fd1498Szrj /* Operands are pushed onto the worklist so that later indices are
4082*38fd1498Szrj nearer the top. That's what we want for SETs, since a SET_SRC
4083*38fd1498Szrj is a better discriminator than a SET_DEST. In other cases it's
4084*38fd1498Szrj usually better to match earlier indices first. This is especially
4085*38fd1498Szrj true of PARALLELs, where the first element tends to be the most
4086*38fd1498Szrj individual. It's also true for commutative operators, where the
4087*38fd1498Szrj canonicalization rules say that the more complex operand should
4088*38fd1498Szrj come first. */
4089*38fd1498Szrj if (code != SET && worklist.length () > reverse_s)
4090*38fd1498Szrj std::reverse (&worklist[0] + reverse_s,
4091*38fd1498Szrj &worklist[0] + worklist.length ());
4092*38fd1498Szrj }
4093*38fd1498Szrj
4094*38fd1498Szrj /* Sort the predicate and mode tests so that they're in depth-first order.
4095*38fd1498Szrj The main goal of this is to put SET_SRC match_operands after SET_DEST
4096*38fd1498Szrj match_operands and after mode checks for the enclosing SET_SRC operators
4097*38fd1498Szrj (such as the mode of a PLUS in an addition instruction). The latter
4098*38fd1498Szrj two types of test can determine the mode exactly, whereas a SET_SRC
4099*38fd1498Szrj match_operand often has to cope with the possibility of the operand
4100*38fd1498Szrj being a modeless constant integer. E.g. something that matches
4101*38fd1498Szrj register_operand (x, SImode) never matches register_operand (x, DImode),
4102*38fd1498Szrj but a const_int that matches immediate_operand (x, SImode) also matches
4103*38fd1498Szrj immediate_operand (x, DImode). The register_operand cases can therefore
4104*38fd1498Szrj be distinguished by a switch on the mode, but the immediate_operand
4105*38fd1498Szrj cases can't. */
4106*38fd1498Szrj if (pred_and_mode_tests.length () > 1)
4107*38fd1498Szrj std::sort (&pred_and_mode_tests[0],
4108*38fd1498Szrj &pred_and_mode_tests[0] + pred_and_mode_tests.length ());
4109*38fd1498Szrj
4110*38fd1498Szrj /* Add the mode and predicate tests. */
4111*38fd1498Szrj pattern_pos *e;
4112*38fd1498Szrj unsigned int i;
4113*38fd1498Szrj FOR_EACH_VEC_ELT (pred_and_mode_tests, i, e)
4114*38fd1498Szrj {
4115*38fd1498Szrj switch (GET_CODE (e->pattern))
4116*38fd1498Szrj {
4117*38fd1498Szrj case MATCH_PARALLEL:
4118*38fd1498Szrj case MATCH_OPERAND:
4119*38fd1498Szrj case MATCH_SCRATCH:
4120*38fd1498Szrj case MATCH_OPERATOR:
4121*38fd1498Szrj {
4122*38fd1498Szrj int opno = XINT (e->pattern, 0);
4123*38fd1498Szrj num_operands = MAX (num_operands, opno + 1);
4124*38fd1498Szrj const char *pred_name = predicate_name (e->pattern);
4125*38fd1498Szrj if (pred_name[0])
4126*38fd1498Szrj {
4127*38fd1498Szrj const struct pred_data *pred = lookup_predicate (pred_name);
4128*38fd1498Szrj /* Check the mode first, to distinguish things like SImode
4129*38fd1498Szrj and DImode register_operands, as described above. */
4130*38fd1498Szrj machine_mode mode = GET_MODE (e->pattern);
4131*38fd1498Szrj if (pred && safe_predicate_mode (pred, mode))
4132*38fd1498Szrj s = add_decision (s, rtx_test::mode (e->pos), mode, true);
4133*38fd1498Szrj
4134*38fd1498Szrj /* Assign to operands[] first, so that the rtx usually doesn't
4135*38fd1498Szrj need to be live across the call to the predicate.
4136*38fd1498Szrj
4137*38fd1498Szrj This shouldn't cause a problem with dirtying the page,
4138*38fd1498Szrj since we fully expect to assign to operands[] at some point,
4139*38fd1498Szrj and since the caller usually writes to other parts of
4140*38fd1498Szrj recog_data anyway. */
4141*38fd1498Szrj s = add_decision (s, rtx_test::set_op (e->pos, opno),
4142*38fd1498Szrj true, false);
4143*38fd1498Szrj s = add_decision (s, rtx_test::predicate (e->pos, pred, mode),
4144*38fd1498Szrj true, false);
4145*38fd1498Szrj }
4146*38fd1498Szrj else
4147*38fd1498Szrj /* Historically we've ignored the mode when there's no
4148*38fd1498Szrj predicate. Just set up operands[] unconditionally. */
4149*38fd1498Szrj s = add_decision (s, rtx_test::set_op (e->pos, opno),
4150*38fd1498Szrj true, false);
4151*38fd1498Szrj break;
4152*38fd1498Szrj }
4153*38fd1498Szrj
4154*38fd1498Szrj default:
4155*38fd1498Szrj s = add_decision (s, rtx_test::mode (e->pos),
4156*38fd1498Szrj GET_MODE (e->pattern), false);
4157*38fd1498Szrj break;
4158*38fd1498Szrj }
4159*38fd1498Szrj }
4160*38fd1498Szrj
4161*38fd1498Szrj /* Finally add rtx_equal_p checks for duplicated operands. */
4162*38fd1498Szrj FOR_EACH_VEC_ELT (dup_tests, i, e)
4163*38fd1498Szrj s = add_decision (s, rtx_test::duplicate (e->pos, XINT (e->pattern, 0)),
4164*38fd1498Szrj true, false);
4165*38fd1498Szrj return s;
4166*38fd1498Szrj }
4167*38fd1498Szrj
4168*38fd1498Szrj /* Add new decisions to S that make it return ACCEPTANCE if:
4169*38fd1498Szrj
4170*38fd1498Szrj (1) the rtx doesn't match anything already matched by S
4171*38fd1498Szrj (2) the rtx matches TOP_PATTERN and
4172*38fd1498Szrj (3) the C test required by INFO->def is true
4173*38fd1498Szrj
4174*38fd1498Szrj For peephole2, TOP_PATTERN is a SEQUENCE of the instruction patterns
4175*38fd1498Szrj to match, otherwise it is a single instruction pattern. */
4176*38fd1498Szrj
4177*38fd1498Szrj static void
match_pattern_1(state * s,md_rtx_info * info,rtx pattern,acceptance_type acceptance)4178*38fd1498Szrj match_pattern_1 (state *s, md_rtx_info *info, rtx pattern,
4179*38fd1498Szrj acceptance_type acceptance)
4180*38fd1498Szrj {
4181*38fd1498Szrj if (acceptance.type == PEEPHOLE2)
4182*38fd1498Szrj {
4183*38fd1498Szrj /* Match each individual instruction. */
4184*38fd1498Szrj position **subpos_ptr = &peep2_insn_pos_list;
4185*38fd1498Szrj int count = 0;
4186*38fd1498Szrj for (int i = 0; i < XVECLEN (pattern, 0); ++i)
4187*38fd1498Szrj {
4188*38fd1498Szrj rtx x = XVECEXP (pattern, 0, i);
4189*38fd1498Szrj position *subpos = next_position (subpos_ptr, &root_pos,
4190*38fd1498Szrj POS_PEEP2_INSN, count);
4191*38fd1498Szrj if (count > 0)
4192*38fd1498Szrj s = add_decision (s, rtx_test::peep2_count (count + 1),
4193*38fd1498Szrj true, false);
4194*38fd1498Szrj s = match_pattern_2 (s, info, subpos, x);
4195*38fd1498Szrj subpos_ptr = &subpos->next;
4196*38fd1498Szrj count += 1;
4197*38fd1498Szrj }
4198*38fd1498Szrj acceptance.u.full.u.match_len = count - 1;
4199*38fd1498Szrj }
4200*38fd1498Szrj else
4201*38fd1498Szrj {
4202*38fd1498Szrj /* Make the rtx itself. */
4203*38fd1498Szrj s = match_pattern_2 (s, info, &root_pos, pattern);
4204*38fd1498Szrj
4205*38fd1498Szrj /* If the match is only valid when extra clobbers are added,
4206*38fd1498Szrj make sure we're able to pass that information to the caller. */
4207*38fd1498Szrj if (acceptance.type == RECOG && acceptance.u.full.u.num_clobbers)
4208*38fd1498Szrj s = add_decision (s, rtx_test::have_num_clobbers (), true, false);
4209*38fd1498Szrj }
4210*38fd1498Szrj
4211*38fd1498Szrj /* Make sure that the C test is true. */
4212*38fd1498Szrj const char *c_test = get_c_test (info->def);
4213*38fd1498Szrj if (maybe_eval_c_test (c_test) != 1)
4214*38fd1498Szrj s = add_decision (s, rtx_test::c_test (c_test), true, false);
4215*38fd1498Szrj
4216*38fd1498Szrj /* Accept the pattern. */
4217*38fd1498Szrj add_decision (s, rtx_test::accept (acceptance), true, false);
4218*38fd1498Szrj }
4219*38fd1498Szrj
4220*38fd1498Szrj /* Like match_pattern_1, but (if merge_states_p) try to merge the
4221*38fd1498Szrj decisions with what's already in S, to reduce the amount of
4222*38fd1498Szrj backtracking. */
4223*38fd1498Szrj
4224*38fd1498Szrj static void
match_pattern(state * s,md_rtx_info * info,rtx pattern,acceptance_type acceptance)4225*38fd1498Szrj match_pattern (state *s, md_rtx_info *info, rtx pattern,
4226*38fd1498Szrj acceptance_type acceptance)
4227*38fd1498Szrj {
4228*38fd1498Szrj if (merge_states_p)
4229*38fd1498Szrj {
4230*38fd1498Szrj state root;
4231*38fd1498Szrj /* Add the decisions to a fresh state and then merge the full tree
4232*38fd1498Szrj into the existing one. */
4233*38fd1498Szrj match_pattern_1 (&root, info, pattern, acceptance);
4234*38fd1498Szrj merge_into_state (s, &root);
4235*38fd1498Szrj }
4236*38fd1498Szrj else
4237*38fd1498Szrj match_pattern_1 (s, info, pattern, acceptance);
4238*38fd1498Szrj }
4239*38fd1498Szrj
4240*38fd1498Szrj /* Begin the output file. */
4241*38fd1498Szrj
4242*38fd1498Szrj static void
write_header(void)4243*38fd1498Szrj write_header (void)
4244*38fd1498Szrj {
4245*38fd1498Szrj puts ("\
4246*38fd1498Szrj /* Generated automatically by the program `genrecog' from the target\n\
4247*38fd1498Szrj machine description file. */\n\
4248*38fd1498Szrj \n\
4249*38fd1498Szrj #define IN_TARGET_CODE 1\n\
4250*38fd1498Szrj \n\
4251*38fd1498Szrj #include \"config.h\"\n\
4252*38fd1498Szrj #include \"system.h\"\n\
4253*38fd1498Szrj #include \"coretypes.h\"\n\
4254*38fd1498Szrj #include \"backend.h\"\n\
4255*38fd1498Szrj #include \"predict.h\"\n\
4256*38fd1498Szrj #include \"rtl.h\"\n\
4257*38fd1498Szrj #include \"memmodel.h\"\n\
4258*38fd1498Szrj #include \"tm_p.h\"\n\
4259*38fd1498Szrj #include \"emit-rtl.h\"\n\
4260*38fd1498Szrj #include \"insn-config.h\"\n\
4261*38fd1498Szrj #include \"recog.h\"\n\
4262*38fd1498Szrj #include \"output.h\"\n\
4263*38fd1498Szrj #include \"flags.h\"\n\
4264*38fd1498Szrj #include \"df.h\"\n\
4265*38fd1498Szrj #include \"resource.h\"\n\
4266*38fd1498Szrj #include \"diagnostic-core.h\"\n\
4267*38fd1498Szrj #include \"reload.h\"\n\
4268*38fd1498Szrj #include \"regs.h\"\n\
4269*38fd1498Szrj #include \"tm-constrs.h\"\n\
4270*38fd1498Szrj \n");
4271*38fd1498Szrj
4272*38fd1498Szrj puts ("\n\
4273*38fd1498Szrj /* `recog' contains a decision tree that recognizes whether the rtx\n\
4274*38fd1498Szrj X0 is a valid instruction.\n\
4275*38fd1498Szrj \n\
4276*38fd1498Szrj recog returns -1 if the rtx is not valid. If the rtx is valid, recog\n\
4277*38fd1498Szrj returns a nonnegative number which is the insn code number for the\n\
4278*38fd1498Szrj pattern that matched. This is the same as the order in the machine\n\
4279*38fd1498Szrj description of the entry that matched. This number can be used as an\n\
4280*38fd1498Szrj index into `insn_data' and other tables.\n");
4281*38fd1498Szrj puts ("\
4282*38fd1498Szrj The third parameter to recog is an optional pointer to an int. If\n\
4283*38fd1498Szrj present, recog will accept a pattern if it matches except for missing\n\
4284*38fd1498Szrj CLOBBER expressions at the end. In that case, the value pointed to by\n\
4285*38fd1498Szrj the optional pointer will be set to the number of CLOBBERs that need\n\
4286*38fd1498Szrj to be added (it should be initialized to zero by the caller). If it");
4287*38fd1498Szrj puts ("\
4288*38fd1498Szrj is set nonzero, the caller should allocate a PARALLEL of the\n\
4289*38fd1498Szrj appropriate size, copy the initial entries, and call add_clobbers\n\
4290*38fd1498Szrj (found in insn-emit.c) to fill in the CLOBBERs.\n\
4291*38fd1498Szrj ");
4292*38fd1498Szrj
4293*38fd1498Szrj puts ("\n\
4294*38fd1498Szrj The function split_insns returns 0 if the rtl could not\n\
4295*38fd1498Szrj be split or the split rtl as an INSN list if it can be.\n\
4296*38fd1498Szrj \n\
4297*38fd1498Szrj The function peephole2_insns returns 0 if the rtl could not\n\
4298*38fd1498Szrj be matched. If there was a match, the new rtl is returned in an INSN list,\n\
4299*38fd1498Szrj and LAST_INSN will point to the last recognized insn in the old sequence.\n\
4300*38fd1498Szrj */\n\n");
4301*38fd1498Szrj }
4302*38fd1498Szrj
4303*38fd1498Szrj /* Return the C type of a parameter with type TYPE. */
4304*38fd1498Szrj
4305*38fd1498Szrj static const char *
parameter_type_string(parameter::type_enum type)4306*38fd1498Szrj parameter_type_string (parameter::type_enum type)
4307*38fd1498Szrj {
4308*38fd1498Szrj switch (type)
4309*38fd1498Szrj {
4310*38fd1498Szrj case parameter::UNSET:
4311*38fd1498Szrj break;
4312*38fd1498Szrj
4313*38fd1498Szrj case parameter::CODE:
4314*38fd1498Szrj return "rtx_code";
4315*38fd1498Szrj
4316*38fd1498Szrj case parameter::MODE:
4317*38fd1498Szrj return "machine_mode";
4318*38fd1498Szrj
4319*38fd1498Szrj case parameter::INT:
4320*38fd1498Szrj return "int";
4321*38fd1498Szrj
4322*38fd1498Szrj case parameter::UINT:
4323*38fd1498Szrj return "unsigned int";
4324*38fd1498Szrj
4325*38fd1498Szrj case parameter::WIDE_INT:
4326*38fd1498Szrj return "HOST_WIDE_INT";
4327*38fd1498Szrj }
4328*38fd1498Szrj gcc_unreachable ();
4329*38fd1498Szrj }
4330*38fd1498Szrj
4331*38fd1498Szrj /* Return true if ACCEPTANCE requires only a single C statement even in
4332*38fd1498Szrj a backtracking context. */
4333*38fd1498Szrj
4334*38fd1498Szrj static bool
single_statement_p(const acceptance_type & acceptance)4335*38fd1498Szrj single_statement_p (const acceptance_type &acceptance)
4336*38fd1498Szrj {
4337*38fd1498Szrj if (acceptance.partial_p)
4338*38fd1498Szrj /* We need to handle failures of the subroutine. */
4339*38fd1498Szrj return false;
4340*38fd1498Szrj switch (acceptance.type)
4341*38fd1498Szrj {
4342*38fd1498Szrj case SUBPATTERN:
4343*38fd1498Szrj case SPLIT:
4344*38fd1498Szrj return true;
4345*38fd1498Szrj
4346*38fd1498Szrj case RECOG:
4347*38fd1498Szrj /* False if we need to assign to pnum_clobbers. */
4348*38fd1498Szrj return acceptance.u.full.u.num_clobbers == 0;
4349*38fd1498Szrj
4350*38fd1498Szrj case PEEPHOLE2:
4351*38fd1498Szrj /* We need to assign to pmatch_len_ and handle null returns from the
4352*38fd1498Szrj peephole2 routine. */
4353*38fd1498Szrj return false;
4354*38fd1498Szrj }
4355*38fd1498Szrj gcc_unreachable ();
4356*38fd1498Szrj }
4357*38fd1498Szrj
4358*38fd1498Szrj /* Return the C failure value for a routine of type TYPE. */
4359*38fd1498Szrj
4360*38fd1498Szrj static const char *
get_failure_return(routine_type type)4361*38fd1498Szrj get_failure_return (routine_type type)
4362*38fd1498Szrj {
4363*38fd1498Szrj switch (type)
4364*38fd1498Szrj {
4365*38fd1498Szrj case SUBPATTERN:
4366*38fd1498Szrj case RECOG:
4367*38fd1498Szrj return "-1";
4368*38fd1498Szrj
4369*38fd1498Szrj case SPLIT:
4370*38fd1498Szrj case PEEPHOLE2:
4371*38fd1498Szrj return "NULL";
4372*38fd1498Szrj }
4373*38fd1498Szrj gcc_unreachable ();
4374*38fd1498Szrj }
4375*38fd1498Szrj
4376*38fd1498Szrj /* Indicates whether a block of code always returns or whether it can fall
4377*38fd1498Szrj through. */
4378*38fd1498Szrj
4379*38fd1498Szrj enum exit_state {
4380*38fd1498Szrj ES_RETURNED,
4381*38fd1498Szrj ES_FALLTHROUGH
4382*38fd1498Szrj };
4383*38fd1498Szrj
4384*38fd1498Szrj /* Information used while writing out code. */
4385*38fd1498Szrj
4386*38fd1498Szrj struct output_state
4387*38fd1498Szrj {
4388*38fd1498Szrj /* The type of routine that we're generating. */
4389*38fd1498Szrj routine_type type;
4390*38fd1498Szrj
4391*38fd1498Szrj /* Maps position ids to xN variable numbers. The entry is only valid if
4392*38fd1498Szrj it is less than the length of VAR_TO_ID, but this holds for every position
4393*38fd1498Szrj tested by a state when writing out that state. */
4394*38fd1498Szrj auto_vec <unsigned int> id_to_var;
4395*38fd1498Szrj
4396*38fd1498Szrj /* Maps xN variable numbers to position ids. */
4397*38fd1498Szrj auto_vec <unsigned int> var_to_id;
4398*38fd1498Szrj
4399*38fd1498Szrj /* Index N is true if variable xN has already been set. */
4400*38fd1498Szrj auto_vec <bool> seen_vars;
4401*38fd1498Szrj };
4402*38fd1498Szrj
4403*38fd1498Szrj /* Return true if D is a call to a pattern routine and if there is some X
4404*38fd1498Szrj such that the transition for pattern result N goes to a successful return
4405*38fd1498Szrj with code X+N. When returning true, set *BASE_OUT to this X and *COUNT_OUT
4406*38fd1498Szrj to the number of return values. (We know that every PATTERN decision has
4407*38fd1498Szrj a transition for every successful return.) */
4408*38fd1498Szrj
4409*38fd1498Szrj static bool
terminal_pattern_p(decision * d,unsigned int * base_out,unsigned int * count_out)4410*38fd1498Szrj terminal_pattern_p (decision *d, unsigned int *base_out,
4411*38fd1498Szrj unsigned int *count_out)
4412*38fd1498Szrj {
4413*38fd1498Szrj if (d->test.kind != rtx_test::PATTERN)
4414*38fd1498Szrj return false;
4415*38fd1498Szrj unsigned int base = 0;
4416*38fd1498Szrj unsigned int count = 0;
4417*38fd1498Szrj for (transition *trans = d->first; trans; trans = trans->next)
4418*38fd1498Szrj {
4419*38fd1498Szrj if (trans->is_param || trans->labels.length () != 1)
4420*38fd1498Szrj return false;
4421*38fd1498Szrj decision *subd = trans->to->singleton ();
4422*38fd1498Szrj if (!subd || subd->test.kind != rtx_test::ACCEPT)
4423*38fd1498Szrj return false;
4424*38fd1498Szrj unsigned int this_base = (subd->test.u.acceptance.u.full.code
4425*38fd1498Szrj - trans->labels[0]);
4426*38fd1498Szrj if (trans == d->first)
4427*38fd1498Szrj base = this_base;
4428*38fd1498Szrj else if (base != this_base)
4429*38fd1498Szrj return false;
4430*38fd1498Szrj count += 1;
4431*38fd1498Szrj }
4432*38fd1498Szrj *base_out = base;
4433*38fd1498Szrj *count_out = count;
4434*38fd1498Szrj return true;
4435*38fd1498Szrj }
4436*38fd1498Szrj
4437*38fd1498Szrj /* Return true if TEST doesn't test an rtx or if the rtx it tests is
4438*38fd1498Szrj already available in state OS. */
4439*38fd1498Szrj
4440*38fd1498Szrj static bool
test_position_available_p(output_state * os,const rtx_test & test)4441*38fd1498Szrj test_position_available_p (output_state *os, const rtx_test &test)
4442*38fd1498Szrj {
4443*38fd1498Szrj return (!test.pos
4444*38fd1498Szrj || test.pos_operand >= 0
4445*38fd1498Szrj || os->seen_vars[os->id_to_var[test.pos->id]]);
4446*38fd1498Szrj }
4447*38fd1498Szrj
4448*38fd1498Szrj /* Like printf, but print INDENT spaces at the beginning. */
4449*38fd1498Szrj
4450*38fd1498Szrj static void ATTRIBUTE_PRINTF_2
printf_indent(unsigned int indent,const char * format,...)4451*38fd1498Szrj printf_indent (unsigned int indent, const char *format, ...)
4452*38fd1498Szrj {
4453*38fd1498Szrj va_list ap;
4454*38fd1498Szrj va_start (ap, format);
4455*38fd1498Szrj printf ("%*s", indent, "");
4456*38fd1498Szrj vprintf (format, ap);
4457*38fd1498Szrj va_end (ap);
4458*38fd1498Szrj }
4459*38fd1498Szrj
4460*38fd1498Szrj /* Emit code to initialize the variable associated with POS, if it isn't
4461*38fd1498Szrj already valid in state OS. Indent each line by INDENT spaces. Update
4462*38fd1498Szrj OS with the new state. */
4463*38fd1498Szrj
4464*38fd1498Szrj static void
change_state(output_state * os,position * pos,unsigned int indent)4465*38fd1498Szrj change_state (output_state *os, position *pos, unsigned int indent)
4466*38fd1498Szrj {
4467*38fd1498Szrj unsigned int var = os->id_to_var[pos->id];
4468*38fd1498Szrj gcc_assert (var < os->var_to_id.length () && os->var_to_id[var] == pos->id);
4469*38fd1498Szrj if (os->seen_vars[var])
4470*38fd1498Szrj return;
4471*38fd1498Szrj switch (pos->type)
4472*38fd1498Szrj {
4473*38fd1498Szrj case POS_PEEP2_INSN:
4474*38fd1498Szrj printf_indent (indent, "x%d = PATTERN (peep2_next_insn (%d));\n",
4475*38fd1498Szrj var, pos->arg);
4476*38fd1498Szrj break;
4477*38fd1498Szrj
4478*38fd1498Szrj case POS_XEXP:
4479*38fd1498Szrj change_state (os, pos->base, indent);
4480*38fd1498Szrj printf_indent (indent, "x%d = XEXP (x%d, %d);\n",
4481*38fd1498Szrj var, os->id_to_var[pos->base->id], pos->arg);
4482*38fd1498Szrj break;
4483*38fd1498Szrj
4484*38fd1498Szrj case POS_XVECEXP0:
4485*38fd1498Szrj change_state (os, pos->base, indent);
4486*38fd1498Szrj printf_indent (indent, "x%d = XVECEXP (x%d, 0, %d);\n",
4487*38fd1498Szrj var, os->id_to_var[pos->base->id], pos->arg);
4488*38fd1498Szrj break;
4489*38fd1498Szrj }
4490*38fd1498Szrj os->seen_vars[var] = true;
4491*38fd1498Szrj }
4492*38fd1498Szrj
4493*38fd1498Szrj /* Print the enumerator constant for CODE -- the upcase version of
4494*38fd1498Szrj the name. */
4495*38fd1498Szrj
4496*38fd1498Szrj static void
print_code(enum rtx_code code)4497*38fd1498Szrj print_code (enum rtx_code code)
4498*38fd1498Szrj {
4499*38fd1498Szrj const char *p;
4500*38fd1498Szrj for (p = GET_RTX_NAME (code); *p; p++)
4501*38fd1498Szrj putchar (TOUPPER (*p));
4502*38fd1498Szrj }
4503*38fd1498Szrj
4504*38fd1498Szrj /* Emit a uint64_t as an integer constant expression. We need to take
4505*38fd1498Szrj special care to avoid "decimal constant is so large that it is unsigned"
4506*38fd1498Szrj warnings in the resulting code. */
4507*38fd1498Szrj
4508*38fd1498Szrj static void
print_host_wide_int(uint64_t val)4509*38fd1498Szrj print_host_wide_int (uint64_t val)
4510*38fd1498Szrj {
4511*38fd1498Szrj uint64_t min = uint64_t (1) << (HOST_BITS_PER_WIDE_INT - 1);
4512*38fd1498Szrj if (val == min)
4513*38fd1498Szrj printf ("(" HOST_WIDE_INT_PRINT_DEC_C " - 1)", val + 1);
4514*38fd1498Szrj else
4515*38fd1498Szrj printf (HOST_WIDE_INT_PRINT_DEC_C, val);
4516*38fd1498Szrj }
4517*38fd1498Szrj
4518*38fd1498Szrj /* Print the C expression for actual parameter PARAM. */
4519*38fd1498Szrj
4520*38fd1498Szrj static void
print_parameter_value(const parameter & param)4521*38fd1498Szrj print_parameter_value (const parameter ¶m)
4522*38fd1498Szrj {
4523*38fd1498Szrj if (param.is_param)
4524*38fd1498Szrj printf ("i%d", (int) param.value + 1);
4525*38fd1498Szrj else
4526*38fd1498Szrj switch (param.type)
4527*38fd1498Szrj {
4528*38fd1498Szrj case parameter::UNSET:
4529*38fd1498Szrj gcc_unreachable ();
4530*38fd1498Szrj break;
4531*38fd1498Szrj
4532*38fd1498Szrj case parameter::CODE:
4533*38fd1498Szrj print_code ((enum rtx_code) param.value);
4534*38fd1498Szrj break;
4535*38fd1498Szrj
4536*38fd1498Szrj case parameter::MODE:
4537*38fd1498Szrj printf ("E_%smode", GET_MODE_NAME ((machine_mode) param.value));
4538*38fd1498Szrj break;
4539*38fd1498Szrj
4540*38fd1498Szrj case parameter::INT:
4541*38fd1498Szrj printf ("%d", (int) param.value);
4542*38fd1498Szrj break;
4543*38fd1498Szrj
4544*38fd1498Szrj case parameter::UINT:
4545*38fd1498Szrj printf ("%u", (unsigned int) param.value);
4546*38fd1498Szrj break;
4547*38fd1498Szrj
4548*38fd1498Szrj case parameter::WIDE_INT:
4549*38fd1498Szrj print_host_wide_int (param.value);
4550*38fd1498Szrj break;
4551*38fd1498Szrj }
4552*38fd1498Szrj }
4553*38fd1498Szrj
4554*38fd1498Szrj /* Print the C expression for the rtx tested by TEST. */
4555*38fd1498Szrj
4556*38fd1498Szrj static void
print_test_rtx(output_state * os,const rtx_test & test)4557*38fd1498Szrj print_test_rtx (output_state *os, const rtx_test &test)
4558*38fd1498Szrj {
4559*38fd1498Szrj if (test.pos_operand >= 0)
4560*38fd1498Szrj printf ("operands[%d]", test.pos_operand);
4561*38fd1498Szrj else
4562*38fd1498Szrj printf ("x%d", os->id_to_var[test.pos->id]);
4563*38fd1498Szrj }
4564*38fd1498Szrj
4565*38fd1498Szrj /* Print the C expression for non-boolean test TEST. */
4566*38fd1498Szrj
4567*38fd1498Szrj static void
print_nonbool_test(output_state * os,const rtx_test & test)4568*38fd1498Szrj print_nonbool_test (output_state *os, const rtx_test &test)
4569*38fd1498Szrj {
4570*38fd1498Szrj switch (test.kind)
4571*38fd1498Szrj {
4572*38fd1498Szrj case rtx_test::CODE:
4573*38fd1498Szrj printf ("GET_CODE (");
4574*38fd1498Szrj print_test_rtx (os, test);
4575*38fd1498Szrj printf (")");
4576*38fd1498Szrj break;
4577*38fd1498Szrj
4578*38fd1498Szrj case rtx_test::MODE:
4579*38fd1498Szrj printf ("GET_MODE (");
4580*38fd1498Szrj print_test_rtx (os, test);
4581*38fd1498Szrj printf (")");
4582*38fd1498Szrj break;
4583*38fd1498Szrj
4584*38fd1498Szrj case rtx_test::VECLEN:
4585*38fd1498Szrj printf ("XVECLEN (");
4586*38fd1498Szrj print_test_rtx (os, test);
4587*38fd1498Szrj printf (", 0)");
4588*38fd1498Szrj break;
4589*38fd1498Szrj
4590*38fd1498Szrj case rtx_test::INT_FIELD:
4591*38fd1498Szrj printf ("XINT (");
4592*38fd1498Szrj print_test_rtx (os, test);
4593*38fd1498Szrj printf (", %d)", test.u.opno);
4594*38fd1498Szrj break;
4595*38fd1498Szrj
4596*38fd1498Szrj case rtx_test::REGNO_FIELD:
4597*38fd1498Szrj printf ("REGNO (");
4598*38fd1498Szrj print_test_rtx (os, test);
4599*38fd1498Szrj printf (")");
4600*38fd1498Szrj break;
4601*38fd1498Szrj
4602*38fd1498Szrj case rtx_test::SUBREG_FIELD:
4603*38fd1498Szrj printf ("SUBREG_BYTE (");
4604*38fd1498Szrj print_test_rtx (os, test);
4605*38fd1498Szrj printf (")");
4606*38fd1498Szrj break;
4607*38fd1498Szrj
4608*38fd1498Szrj case rtx_test::WIDE_INT_FIELD:
4609*38fd1498Szrj printf ("XWINT (");
4610*38fd1498Szrj print_test_rtx (os, test);
4611*38fd1498Szrj printf (", %d)", test.u.opno);
4612*38fd1498Szrj break;
4613*38fd1498Szrj
4614*38fd1498Szrj case rtx_test::PATTERN:
4615*38fd1498Szrj {
4616*38fd1498Szrj pattern_routine *routine = test.u.pattern->routine;
4617*38fd1498Szrj printf ("pattern%d (", routine->pattern_id);
4618*38fd1498Szrj const char *sep = "";
4619*38fd1498Szrj if (test.pos)
4620*38fd1498Szrj {
4621*38fd1498Szrj print_test_rtx (os, test);
4622*38fd1498Szrj sep = ", ";
4623*38fd1498Szrj }
4624*38fd1498Szrj if (routine->insn_p)
4625*38fd1498Szrj {
4626*38fd1498Szrj printf ("%sinsn", sep);
4627*38fd1498Szrj sep = ", ";
4628*38fd1498Szrj }
4629*38fd1498Szrj if (routine->pnum_clobbers_p)
4630*38fd1498Szrj {
4631*38fd1498Szrj printf ("%spnum_clobbers", sep);
4632*38fd1498Szrj sep = ", ";
4633*38fd1498Szrj }
4634*38fd1498Szrj for (unsigned int i = 0; i < test.u.pattern->params.length (); ++i)
4635*38fd1498Szrj {
4636*38fd1498Szrj fputs (sep, stdout);
4637*38fd1498Szrj print_parameter_value (test.u.pattern->params[i]);
4638*38fd1498Szrj sep = ", ";
4639*38fd1498Szrj }
4640*38fd1498Szrj printf (")");
4641*38fd1498Szrj break;
4642*38fd1498Szrj }
4643*38fd1498Szrj
4644*38fd1498Szrj case rtx_test::PEEP2_COUNT:
4645*38fd1498Szrj case rtx_test::VECLEN_GE:
4646*38fd1498Szrj case rtx_test::SAVED_CONST_INT:
4647*38fd1498Szrj case rtx_test::DUPLICATE:
4648*38fd1498Szrj case rtx_test::PREDICATE:
4649*38fd1498Szrj case rtx_test::SET_OP:
4650*38fd1498Szrj case rtx_test::HAVE_NUM_CLOBBERS:
4651*38fd1498Szrj case rtx_test::C_TEST:
4652*38fd1498Szrj case rtx_test::ACCEPT:
4653*38fd1498Szrj gcc_unreachable ();
4654*38fd1498Szrj }
4655*38fd1498Szrj }
4656*38fd1498Szrj
4657*38fd1498Szrj /* IS_PARAM and LABEL are taken from a transition whose source
4658*38fd1498Szrj decision performs TEST. Print the C code for the label. */
4659*38fd1498Szrj
4660*38fd1498Szrj static void
print_label_value(const rtx_test & test,bool is_param,uint64_t value)4661*38fd1498Szrj print_label_value (const rtx_test &test, bool is_param, uint64_t value)
4662*38fd1498Szrj {
4663*38fd1498Szrj print_parameter_value (parameter (transition_parameter_type (test.kind),
4664*38fd1498Szrj is_param, value));
4665*38fd1498Szrj }
4666*38fd1498Szrj
4667*38fd1498Szrj /* If IS_PARAM, print code to compare TEST with the C variable i<VALUE+1>.
4668*38fd1498Szrj If !IS_PARAM, print code to compare TEST with the C constant VALUE.
4669*38fd1498Szrj Test for inequality if INVERT_P, otherwise test for equality. */
4670*38fd1498Szrj
4671*38fd1498Szrj static void
print_test(output_state * os,const rtx_test & test,bool is_param,uint64_t value,bool invert_p)4672*38fd1498Szrj print_test (output_state *os, const rtx_test &test, bool is_param,
4673*38fd1498Szrj uint64_t value, bool invert_p)
4674*38fd1498Szrj {
4675*38fd1498Szrj switch (test.kind)
4676*38fd1498Szrj {
4677*38fd1498Szrj /* Handle the non-boolean TESTs. */
4678*38fd1498Szrj case rtx_test::CODE:
4679*38fd1498Szrj case rtx_test::MODE:
4680*38fd1498Szrj case rtx_test::VECLEN:
4681*38fd1498Szrj case rtx_test::REGNO_FIELD:
4682*38fd1498Szrj case rtx_test::INT_FIELD:
4683*38fd1498Szrj case rtx_test::WIDE_INT_FIELD:
4684*38fd1498Szrj case rtx_test::PATTERN:
4685*38fd1498Szrj print_nonbool_test (os, test);
4686*38fd1498Szrj printf (" %s ", invert_p ? "!=" : "==");
4687*38fd1498Szrj print_label_value (test, is_param, value);
4688*38fd1498Szrj break;
4689*38fd1498Szrj
4690*38fd1498Szrj case rtx_test::SUBREG_FIELD:
4691*38fd1498Szrj printf ("%s (", invert_p ? "maybe_ne" : "known_eq");
4692*38fd1498Szrj print_nonbool_test (os, test);
4693*38fd1498Szrj printf (", ");
4694*38fd1498Szrj print_label_value (test, is_param, value);
4695*38fd1498Szrj printf (")");
4696*38fd1498Szrj break;
4697*38fd1498Szrj
4698*38fd1498Szrj case rtx_test::SAVED_CONST_INT:
4699*38fd1498Szrj gcc_assert (!is_param && value == 1);
4700*38fd1498Szrj print_test_rtx (os, test);
4701*38fd1498Szrj printf (" %s const_int_rtx[MAX_SAVED_CONST_INT + ",
4702*38fd1498Szrj invert_p ? "!=" : "==");
4703*38fd1498Szrj print_parameter_value (parameter (parameter::INT,
4704*38fd1498Szrj test.u.integer.is_param,
4705*38fd1498Szrj test.u.integer.value));
4706*38fd1498Szrj printf ("]");
4707*38fd1498Szrj break;
4708*38fd1498Szrj
4709*38fd1498Szrj case rtx_test::PEEP2_COUNT:
4710*38fd1498Szrj gcc_assert (!is_param && value == 1);
4711*38fd1498Szrj printf ("peep2_current_count %s %d", invert_p ? "<" : ">=",
4712*38fd1498Szrj test.u.min_len);
4713*38fd1498Szrj break;
4714*38fd1498Szrj
4715*38fd1498Szrj case rtx_test::VECLEN_GE:
4716*38fd1498Szrj gcc_assert (!is_param && value == 1);
4717*38fd1498Szrj printf ("XVECLEN (");
4718*38fd1498Szrj print_test_rtx (os, test);
4719*38fd1498Szrj printf (", 0) %s %d", invert_p ? "<" : ">=", test.u.min_len);
4720*38fd1498Szrj break;
4721*38fd1498Szrj
4722*38fd1498Szrj case rtx_test::PREDICATE:
4723*38fd1498Szrj gcc_assert (!is_param && value == 1);
4724*38fd1498Szrj printf ("%s%s (", invert_p ? "!" : "", test.u.predicate.data->name);
4725*38fd1498Szrj print_test_rtx (os, test);
4726*38fd1498Szrj printf (", ");
4727*38fd1498Szrj print_parameter_value (parameter (parameter::MODE,
4728*38fd1498Szrj test.u.predicate.mode_is_param,
4729*38fd1498Szrj test.u.predicate.mode));
4730*38fd1498Szrj printf (")");
4731*38fd1498Szrj break;
4732*38fd1498Szrj
4733*38fd1498Szrj case rtx_test::DUPLICATE:
4734*38fd1498Szrj gcc_assert (!is_param && value == 1);
4735*38fd1498Szrj printf ("%srtx_equal_p (", invert_p ? "!" : "");
4736*38fd1498Szrj print_test_rtx (os, test);
4737*38fd1498Szrj printf (", operands[%d])", test.u.opno);
4738*38fd1498Szrj break;
4739*38fd1498Szrj
4740*38fd1498Szrj case rtx_test::HAVE_NUM_CLOBBERS:
4741*38fd1498Szrj gcc_assert (!is_param && value == 1);
4742*38fd1498Szrj printf ("pnum_clobbers %s NULL", invert_p ? "==" : "!=");
4743*38fd1498Szrj break;
4744*38fd1498Szrj
4745*38fd1498Szrj case rtx_test::C_TEST:
4746*38fd1498Szrj gcc_assert (!is_param && value == 1);
4747*38fd1498Szrj if (invert_p)
4748*38fd1498Szrj printf ("!");
4749*38fd1498Szrj rtx_reader_ptr->print_c_condition (test.u.string);
4750*38fd1498Szrj break;
4751*38fd1498Szrj
4752*38fd1498Szrj case rtx_test::ACCEPT:
4753*38fd1498Szrj case rtx_test::SET_OP:
4754*38fd1498Szrj gcc_unreachable ();
4755*38fd1498Szrj }
4756*38fd1498Szrj }
4757*38fd1498Szrj
4758*38fd1498Szrj static exit_state print_decision (output_state *, decision *,
4759*38fd1498Szrj unsigned int, bool);
4760*38fd1498Szrj
4761*38fd1498Szrj /* Print code to perform S, indent each line by INDENT spaces.
4762*38fd1498Szrj IS_FINAL is true if there are no fallback decisions to test on failure;
4763*38fd1498Szrj if the state fails then the entire routine fails. */
4764*38fd1498Szrj
4765*38fd1498Szrj static exit_state
print_state(output_state * os,state * s,unsigned int indent,bool is_final)4766*38fd1498Szrj print_state (output_state *os, state *s, unsigned int indent, bool is_final)
4767*38fd1498Szrj {
4768*38fd1498Szrj exit_state es = ES_FALLTHROUGH;
4769*38fd1498Szrj for (decision *d = s->first; d; d = d->next)
4770*38fd1498Szrj es = print_decision (os, d, indent, is_final && !d->next);
4771*38fd1498Szrj if (es != ES_RETURNED && is_final)
4772*38fd1498Szrj {
4773*38fd1498Szrj printf_indent (indent, "return %s;\n", get_failure_return (os->type));
4774*38fd1498Szrj es = ES_RETURNED;
4775*38fd1498Szrj }
4776*38fd1498Szrj return es;
4777*38fd1498Szrj }
4778*38fd1498Szrj
4779*38fd1498Szrj /* Print the code for subroutine call ACCEPTANCE (for which partial_p
4780*38fd1498Szrj is known to be true). Return the C condition that indicates a successful
4781*38fd1498Szrj match. */
4782*38fd1498Szrj
4783*38fd1498Szrj static const char *
print_subroutine_call(const acceptance_type & acceptance)4784*38fd1498Szrj print_subroutine_call (const acceptance_type &acceptance)
4785*38fd1498Szrj {
4786*38fd1498Szrj switch (acceptance.type)
4787*38fd1498Szrj {
4788*38fd1498Szrj case SUBPATTERN:
4789*38fd1498Szrj gcc_unreachable ();
4790*38fd1498Szrj
4791*38fd1498Szrj case RECOG:
4792*38fd1498Szrj printf ("recog_%d (x1, insn, pnum_clobbers)",
4793*38fd1498Szrj acceptance.u.subroutine_id);
4794*38fd1498Szrj return ">= 0";
4795*38fd1498Szrj
4796*38fd1498Szrj case SPLIT:
4797*38fd1498Szrj printf ("split_%d (x1, insn)", acceptance.u.subroutine_id);
4798*38fd1498Szrj return "!= NULL_RTX";
4799*38fd1498Szrj
4800*38fd1498Szrj case PEEPHOLE2:
4801*38fd1498Szrj printf ("peephole2_%d (x1, insn, pmatch_len_)",
4802*38fd1498Szrj acceptance.u.subroutine_id);
4803*38fd1498Szrj return "!= NULL_RTX";
4804*38fd1498Szrj }
4805*38fd1498Szrj gcc_unreachable ();
4806*38fd1498Szrj }
4807*38fd1498Szrj
4808*38fd1498Szrj /* Print code for the successful match described by ACCEPTANCE.
4809*38fd1498Szrj INDENT and IS_FINAL are as for print_state. */
4810*38fd1498Szrj
4811*38fd1498Szrj static exit_state
print_acceptance(const acceptance_type & acceptance,unsigned int indent,bool is_final)4812*38fd1498Szrj print_acceptance (const acceptance_type &acceptance, unsigned int indent,
4813*38fd1498Szrj bool is_final)
4814*38fd1498Szrj {
4815*38fd1498Szrj if (acceptance.partial_p)
4816*38fd1498Szrj {
4817*38fd1498Szrj /* Defer the rest of the match to a subroutine. */
4818*38fd1498Szrj if (is_final)
4819*38fd1498Szrj {
4820*38fd1498Szrj printf_indent (indent, "return ");
4821*38fd1498Szrj print_subroutine_call (acceptance);
4822*38fd1498Szrj printf (";\n");
4823*38fd1498Szrj return ES_RETURNED;
4824*38fd1498Szrj }
4825*38fd1498Szrj else
4826*38fd1498Szrj {
4827*38fd1498Szrj printf_indent (indent, "res = ");
4828*38fd1498Szrj const char *res_test = print_subroutine_call (acceptance);
4829*38fd1498Szrj printf (";\n");
4830*38fd1498Szrj printf_indent (indent, "if (res %s)\n", res_test);
4831*38fd1498Szrj printf_indent (indent + 2, "return res;\n");
4832*38fd1498Szrj return ES_FALLTHROUGH;
4833*38fd1498Szrj }
4834*38fd1498Szrj }
4835*38fd1498Szrj switch (acceptance.type)
4836*38fd1498Szrj {
4837*38fd1498Szrj case SUBPATTERN:
4838*38fd1498Szrj printf_indent (indent, "return %d;\n", acceptance.u.full.code);
4839*38fd1498Szrj return ES_RETURNED;
4840*38fd1498Szrj
4841*38fd1498Szrj case RECOG:
4842*38fd1498Szrj if (acceptance.u.full.u.num_clobbers != 0)
4843*38fd1498Szrj printf_indent (indent, "*pnum_clobbers = %d;\n",
4844*38fd1498Szrj acceptance.u.full.u.num_clobbers);
4845*38fd1498Szrj printf_indent (indent, "return %d; /* %s */\n", acceptance.u.full.code,
4846*38fd1498Szrj get_insn_name (acceptance.u.full.code));
4847*38fd1498Szrj return ES_RETURNED;
4848*38fd1498Szrj
4849*38fd1498Szrj case SPLIT:
4850*38fd1498Szrj printf_indent (indent, "return gen_split_%d (insn, operands);\n",
4851*38fd1498Szrj acceptance.u.full.code);
4852*38fd1498Szrj return ES_RETURNED;
4853*38fd1498Szrj
4854*38fd1498Szrj case PEEPHOLE2:
4855*38fd1498Szrj printf_indent (indent, "*pmatch_len_ = %d;\n",
4856*38fd1498Szrj acceptance.u.full.u.match_len);
4857*38fd1498Szrj if (is_final)
4858*38fd1498Szrj {
4859*38fd1498Szrj printf_indent (indent, "return gen_peephole2_%d (insn, operands);\n",
4860*38fd1498Szrj acceptance.u.full.code);
4861*38fd1498Szrj return ES_RETURNED;
4862*38fd1498Szrj }
4863*38fd1498Szrj else
4864*38fd1498Szrj {
4865*38fd1498Szrj printf_indent (indent, "res = gen_peephole2_%d (insn, operands);\n",
4866*38fd1498Szrj acceptance.u.full.code);
4867*38fd1498Szrj printf_indent (indent, "if (res != NULL_RTX)\n");
4868*38fd1498Szrj printf_indent (indent + 2, "return res;\n");
4869*38fd1498Szrj return ES_FALLTHROUGH;
4870*38fd1498Szrj }
4871*38fd1498Szrj }
4872*38fd1498Szrj gcc_unreachable ();
4873*38fd1498Szrj }
4874*38fd1498Szrj
4875*38fd1498Szrj /* Print code to perform D. INDENT and IS_FINAL are as for print_state. */
4876*38fd1498Szrj
4877*38fd1498Szrj static exit_state
print_decision(output_state * os,decision * d,unsigned int indent,bool is_final)4878*38fd1498Szrj print_decision (output_state *os, decision *d, unsigned int indent,
4879*38fd1498Szrj bool is_final)
4880*38fd1498Szrj {
4881*38fd1498Szrj uint64_t label;
4882*38fd1498Szrj unsigned int base, count;
4883*38fd1498Szrj
4884*38fd1498Szrj /* Make sure the rtx under test is available either in operands[] or
4885*38fd1498Szrj in an xN variable. */
4886*38fd1498Szrj if (d->test.pos && d->test.pos_operand < 0)
4887*38fd1498Szrj change_state (os, d->test.pos, indent);
4888*38fd1498Szrj
4889*38fd1498Szrj /* Look for cases where a pattern routine P1 calls another pattern routine
4890*38fd1498Szrj P2 and where P1 returns X + BASE whenever P2 returns X. If IS_FINAL
4891*38fd1498Szrj is true and BASE is zero we can simply use:
4892*38fd1498Szrj
4893*38fd1498Szrj return patternN (...);
4894*38fd1498Szrj
4895*38fd1498Szrj Otherwise we can use:
4896*38fd1498Szrj
4897*38fd1498Szrj res = patternN (...);
4898*38fd1498Szrj if (res >= 0)
4899*38fd1498Szrj return res + BASE;
4900*38fd1498Szrj
4901*38fd1498Szrj However, if BASE is nonzero and patternN only returns 0 or -1,
4902*38fd1498Szrj the usual "return BASE;" is better than "return res + BASE;".
4903*38fd1498Szrj If BASE is zero, "return res;" should be better than "return 0;",
4904*38fd1498Szrj since no assignment to the return register is required. */
4905*38fd1498Szrj if (os->type == SUBPATTERN
4906*38fd1498Szrj && terminal_pattern_p (d, &base, &count)
4907*38fd1498Szrj && (base == 0 || count > 1))
4908*38fd1498Szrj {
4909*38fd1498Szrj if (is_final && base == 0)
4910*38fd1498Szrj {
4911*38fd1498Szrj printf_indent (indent, "return ");
4912*38fd1498Szrj print_nonbool_test (os, d->test);
4913*38fd1498Szrj printf ("; /* [-1, %d] */\n", count - 1);
4914*38fd1498Szrj return ES_RETURNED;
4915*38fd1498Szrj }
4916*38fd1498Szrj else
4917*38fd1498Szrj {
4918*38fd1498Szrj printf_indent (indent, "res = ");
4919*38fd1498Szrj print_nonbool_test (os, d->test);
4920*38fd1498Szrj printf (";\n");
4921*38fd1498Szrj printf_indent (indent, "if (res >= 0)\n");
4922*38fd1498Szrj printf_indent (indent + 2, "return res");
4923*38fd1498Szrj if (base != 0)
4924*38fd1498Szrj printf (" + %d", base);
4925*38fd1498Szrj printf ("; /* [%d, %d] */\n", base, base + count - 1);
4926*38fd1498Szrj return ES_FALLTHROUGH;
4927*38fd1498Szrj }
4928*38fd1498Szrj }
4929*38fd1498Szrj else if (d->test.kind == rtx_test::ACCEPT)
4930*38fd1498Szrj return print_acceptance (d->test.u.acceptance, indent, is_final);
4931*38fd1498Szrj else if (d->test.kind == rtx_test::SET_OP)
4932*38fd1498Szrj {
4933*38fd1498Szrj printf_indent (indent, "operands[%d] = ", d->test.u.opno);
4934*38fd1498Szrj print_test_rtx (os, d->test);
4935*38fd1498Szrj printf (";\n");
4936*38fd1498Szrj return print_state (os, d->singleton ()->to, indent, is_final);
4937*38fd1498Szrj }
4938*38fd1498Szrj /* Handle decisions with a single transition and a single transition
4939*38fd1498Szrj label. */
4940*38fd1498Szrj else if (d->if_statement_p (&label))
4941*38fd1498Szrj {
4942*38fd1498Szrj transition *trans = d->singleton ();
4943*38fd1498Szrj if (mark_optional_transitions_p && trans->optional)
4944*38fd1498Szrj printf_indent (indent, "/* OPTIONAL IF */\n");
4945*38fd1498Szrj
4946*38fd1498Szrj /* Print the condition associated with TRANS. Invert it if IS_FINAL,
4947*38fd1498Szrj so that we return immediately on failure and fall through on
4948*38fd1498Szrj success. */
4949*38fd1498Szrj printf_indent (indent, "if (");
4950*38fd1498Szrj print_test (os, d->test, trans->is_param, label, is_final);
4951*38fd1498Szrj
4952*38fd1498Szrj /* Look for following states that would be handled by this code
4953*38fd1498Szrj on recursion. If they don't need any preparatory statements,
4954*38fd1498Szrj include them in the current "if" statement rather than creating
4955*38fd1498Szrj a new one. */
4956*38fd1498Szrj for (;;)
4957*38fd1498Szrj {
4958*38fd1498Szrj d = trans->to->singleton ();
4959*38fd1498Szrj if (!d
4960*38fd1498Szrj || d->test.kind == rtx_test::ACCEPT
4961*38fd1498Szrj || d->test.kind == rtx_test::SET_OP
4962*38fd1498Szrj || !d->if_statement_p (&label)
4963*38fd1498Szrj || !test_position_available_p (os, d->test))
4964*38fd1498Szrj break;
4965*38fd1498Szrj trans = d->first;
4966*38fd1498Szrj printf ("\n");
4967*38fd1498Szrj if (mark_optional_transitions_p && trans->optional)
4968*38fd1498Szrj printf_indent (indent + 4, "/* OPTIONAL IF */\n");
4969*38fd1498Szrj printf_indent (indent + 4, "%s ", is_final ? "||" : "&&");
4970*38fd1498Szrj print_test (os, d->test, trans->is_param, label, is_final);
4971*38fd1498Szrj }
4972*38fd1498Szrj printf (")\n");
4973*38fd1498Szrj
4974*38fd1498Szrj /* Print the conditional code with INDENT + 2 and the fallthrough
4975*38fd1498Szrj code with indent INDENT. */
4976*38fd1498Szrj state *to = trans->to;
4977*38fd1498Szrj if (is_final)
4978*38fd1498Szrj {
4979*38fd1498Szrj /* We inverted the condition above, so return failure in the
4980*38fd1498Szrj "if" body and fall through to the target of the transition. */
4981*38fd1498Szrj printf_indent (indent + 2, "return %s;\n",
4982*38fd1498Szrj get_failure_return (os->type));
4983*38fd1498Szrj return print_state (os, to, indent, is_final);
4984*38fd1498Szrj }
4985*38fd1498Szrj else if (to->singleton ()
4986*38fd1498Szrj && to->first->test.kind == rtx_test::ACCEPT
4987*38fd1498Szrj && single_statement_p (to->first->test.u.acceptance))
4988*38fd1498Szrj {
4989*38fd1498Szrj /* The target of the transition is a simple "return" statement.
4990*38fd1498Szrj It doesn't need any braces and doesn't fall through. */
4991*38fd1498Szrj if (print_acceptance (to->first->test.u.acceptance,
4992*38fd1498Szrj indent + 2, true) != ES_RETURNED)
4993*38fd1498Szrj gcc_unreachable ();
4994*38fd1498Szrj return ES_FALLTHROUGH;
4995*38fd1498Szrj }
4996*38fd1498Szrj else
4997*38fd1498Szrj {
4998*38fd1498Szrj /* The general case. Output code for the target of the transition
4999*38fd1498Szrj in braces. This will not invalidate any of the xN variables
5000*38fd1498Szrj that are already valid, but we mustn't rely on any that are
5001*38fd1498Szrj set by the "if" body. */
5002*38fd1498Szrj auto_vec <bool, 32> old_seen;
5003*38fd1498Szrj old_seen.safe_splice (os->seen_vars);
5004*38fd1498Szrj
5005*38fd1498Szrj printf_indent (indent + 2, "{\n");
5006*38fd1498Szrj print_state (os, trans->to, indent + 4, is_final);
5007*38fd1498Szrj printf_indent (indent + 2, "}\n");
5008*38fd1498Szrj
5009*38fd1498Szrj os->seen_vars.truncate (0);
5010*38fd1498Szrj os->seen_vars.splice (old_seen);
5011*38fd1498Szrj return ES_FALLTHROUGH;
5012*38fd1498Szrj }
5013*38fd1498Szrj }
5014*38fd1498Szrj else
5015*38fd1498Szrj {
5016*38fd1498Szrj /* Output the decision as a switch statement. */
5017*38fd1498Szrj printf_indent (indent, "switch (");
5018*38fd1498Szrj print_nonbool_test (os, d->test);
5019*38fd1498Szrj printf (")\n");
5020*38fd1498Szrj
5021*38fd1498Szrj /* Each case statement starts with the same set of valid variables.
5022*38fd1498Szrj These are also the only variables will be valid on fallthrough. */
5023*38fd1498Szrj auto_vec <bool, 32> old_seen;
5024*38fd1498Szrj old_seen.safe_splice (os->seen_vars);
5025*38fd1498Szrj
5026*38fd1498Szrj printf_indent (indent + 2, "{\n");
5027*38fd1498Szrj for (transition *trans = d->first; trans; trans = trans->next)
5028*38fd1498Szrj {
5029*38fd1498Szrj gcc_assert (!trans->is_param);
5030*38fd1498Szrj if (mark_optional_transitions_p && trans->optional)
5031*38fd1498Szrj printf_indent (indent + 2, "/* OPTIONAL CASE */\n");
5032*38fd1498Szrj for (int_set::iterator j = trans->labels.begin ();
5033*38fd1498Szrj j != trans->labels.end (); ++j)
5034*38fd1498Szrj {
5035*38fd1498Szrj printf_indent (indent + 2, "case ");
5036*38fd1498Szrj print_label_value (d->test, trans->is_param, *j);
5037*38fd1498Szrj printf (":\n");
5038*38fd1498Szrj }
5039*38fd1498Szrj if (print_state (os, trans->to, indent + 4, is_final))
5040*38fd1498Szrj {
5041*38fd1498Szrj /* The state can fall through. Add an explicit break. */
5042*38fd1498Szrj gcc_assert (!is_final);
5043*38fd1498Szrj printf_indent (indent + 4, "break;\n");
5044*38fd1498Szrj }
5045*38fd1498Szrj printf ("\n");
5046*38fd1498Szrj
5047*38fd1498Szrj /* Restore the original set of valid variables. */
5048*38fd1498Szrj os->seen_vars.truncate (0);
5049*38fd1498Szrj os->seen_vars.splice (old_seen);
5050*38fd1498Szrj }
5051*38fd1498Szrj /* Add a default case. */
5052*38fd1498Szrj printf_indent (indent + 2, "default:\n");
5053*38fd1498Szrj if (is_final)
5054*38fd1498Szrj printf_indent (indent + 4, "return %s;\n",
5055*38fd1498Szrj get_failure_return (os->type));
5056*38fd1498Szrj else
5057*38fd1498Szrj printf_indent (indent + 4, "break;\n");
5058*38fd1498Szrj printf_indent (indent + 2, "}\n");
5059*38fd1498Szrj return is_final ? ES_RETURNED : ES_FALLTHROUGH;
5060*38fd1498Szrj }
5061*38fd1498Szrj }
5062*38fd1498Szrj
5063*38fd1498Szrj /* Make sure that OS has a position variable for POS. ROOT_P is true if
5064*38fd1498Szrj POS is the root position for the routine. */
5065*38fd1498Szrj
5066*38fd1498Szrj static void
assign_position_var(output_state * os,position * pos,bool root_p)5067*38fd1498Szrj assign_position_var (output_state *os, position *pos, bool root_p)
5068*38fd1498Szrj {
5069*38fd1498Szrj unsigned int idx = os->id_to_var[pos->id];
5070*38fd1498Szrj if (idx < os->var_to_id.length () && os->var_to_id[idx] == pos->id)
5071*38fd1498Szrj return;
5072*38fd1498Szrj if (!root_p && pos->type != POS_PEEP2_INSN)
5073*38fd1498Szrj assign_position_var (os, pos->base, false);
5074*38fd1498Szrj os->id_to_var[pos->id] = os->var_to_id.length ();
5075*38fd1498Szrj os->var_to_id.safe_push (pos->id);
5076*38fd1498Szrj }
5077*38fd1498Szrj
5078*38fd1498Szrj /* Make sure that OS has the position variables required by S. */
5079*38fd1498Szrj
5080*38fd1498Szrj static void
assign_position_vars(output_state * os,state * s)5081*38fd1498Szrj assign_position_vars (output_state *os, state *s)
5082*38fd1498Szrj {
5083*38fd1498Szrj for (decision *d = s->first; d; d = d->next)
5084*38fd1498Szrj {
5085*38fd1498Szrj /* Positions associated with operands can be read from the
5086*38fd1498Szrj operands[] array. */
5087*38fd1498Szrj if (d->test.pos && d->test.pos_operand < 0)
5088*38fd1498Szrj assign_position_var (os, d->test.pos, false);
5089*38fd1498Szrj for (transition *trans = d->first; trans; trans = trans->next)
5090*38fd1498Szrj assign_position_vars (os, trans->to);
5091*38fd1498Szrj }
5092*38fd1498Szrj }
5093*38fd1498Szrj
5094*38fd1498Szrj /* Print the open brace and variable definitions for a routine that
5095*38fd1498Szrj implements S. ROOT is the deepest rtx from which S can access all
5096*38fd1498Szrj relevant parts of the first instruction it matches. Initialize OS
5097*38fd1498Szrj so that every relevant position has an rtx variable xN and so that
5098*38fd1498Szrj only ROOT's variable has a valid value. */
5099*38fd1498Szrj
5100*38fd1498Szrj static void
print_subroutine_start(output_state * os,state * s,position * root)5101*38fd1498Szrj print_subroutine_start (output_state *os, state *s, position *root)
5102*38fd1498Szrj {
5103*38fd1498Szrj printf ("{\n rtx * const operands ATTRIBUTE_UNUSED"
5104*38fd1498Szrj " = &recog_data.operand[0];\n");
5105*38fd1498Szrj os->var_to_id.truncate (0);
5106*38fd1498Szrj os->seen_vars.truncate (0);
5107*38fd1498Szrj if (root)
5108*38fd1498Szrj {
5109*38fd1498Szrj /* Create a fake entry for position 0 so that an id_to_var of 0
5110*38fd1498Szrj is always invalid. This also makes the xN variables naturally
5111*38fd1498Szrj 1-based rather than 0-based. */
5112*38fd1498Szrj os->var_to_id.safe_push (num_positions);
5113*38fd1498Szrj
5114*38fd1498Szrj /* Associate ROOT with x1. */
5115*38fd1498Szrj assign_position_var (os, root, true);
5116*38fd1498Szrj
5117*38fd1498Szrj /* Assign xN variables to all other relevant positions. */
5118*38fd1498Szrj assign_position_vars (os, s);
5119*38fd1498Szrj
5120*38fd1498Szrj /* Output the variable declarations (except for ROOT's, which is
5121*38fd1498Szrj passed in as a parameter). */
5122*38fd1498Szrj unsigned int num_vars = os->var_to_id.length ();
5123*38fd1498Szrj if (num_vars > 2)
5124*38fd1498Szrj {
5125*38fd1498Szrj for (unsigned int i = 2; i < num_vars; ++i)
5126*38fd1498Szrj /* Print 8 rtx variables to a line. */
5127*38fd1498Szrj printf ("%s x%d",
5128*38fd1498Szrj i == 2 ? " rtx" : (i - 2) % 8 == 0 ? ";\n rtx" : ",", i);
5129*38fd1498Szrj printf (";\n");
5130*38fd1498Szrj }
5131*38fd1498Szrj
5132*38fd1498Szrj /* Say that x1 is valid and the rest aren't. */
5133*38fd1498Szrj os->seen_vars.safe_grow_cleared (num_vars);
5134*38fd1498Szrj os->seen_vars[1] = true;
5135*38fd1498Szrj }
5136*38fd1498Szrj if (os->type == SUBPATTERN || os->type == RECOG)
5137*38fd1498Szrj printf (" int res ATTRIBUTE_UNUSED;\n");
5138*38fd1498Szrj else
5139*38fd1498Szrj printf (" rtx_insn *res ATTRIBUTE_UNUSED;\n");
5140*38fd1498Szrj }
5141*38fd1498Szrj
5142*38fd1498Szrj /* Output the definition of pattern routine ROUTINE. */
5143*38fd1498Szrj
5144*38fd1498Szrj static void
print_pattern(output_state * os,pattern_routine * routine)5145*38fd1498Szrj print_pattern (output_state *os, pattern_routine *routine)
5146*38fd1498Szrj {
5147*38fd1498Szrj printf ("\nstatic int\npattern%d (", routine->pattern_id);
5148*38fd1498Szrj const char *sep = "";
5149*38fd1498Szrj /* Add the top-level rtx parameter, if any. */
5150*38fd1498Szrj if (routine->pos)
5151*38fd1498Szrj {
5152*38fd1498Szrj printf ("%srtx x1", sep);
5153*38fd1498Szrj sep = ", ";
5154*38fd1498Szrj }
5155*38fd1498Szrj /* Add the optional parameters. */
5156*38fd1498Szrj if (routine->insn_p)
5157*38fd1498Szrj {
5158*38fd1498Szrj /* We can't easily tell whether a C condition actually reads INSN,
5159*38fd1498Szrj so add an ATTRIBUTE_UNUSED just in case. */
5160*38fd1498Szrj printf ("%srtx_insn *insn ATTRIBUTE_UNUSED", sep);
5161*38fd1498Szrj sep = ", ";
5162*38fd1498Szrj }
5163*38fd1498Szrj if (routine->pnum_clobbers_p)
5164*38fd1498Szrj {
5165*38fd1498Szrj printf ("%sint *pnum_clobbers", sep);
5166*38fd1498Szrj sep = ", ";
5167*38fd1498Szrj }
5168*38fd1498Szrj /* Add the "i" parameters. */
5169*38fd1498Szrj for (unsigned int i = 0; i < routine->param_types.length (); ++i)
5170*38fd1498Szrj {
5171*38fd1498Szrj printf ("%s%s i%d", sep,
5172*38fd1498Szrj parameter_type_string (routine->param_types[i]), i + 1);
5173*38fd1498Szrj sep = ", ";
5174*38fd1498Szrj }
5175*38fd1498Szrj printf (")\n");
5176*38fd1498Szrj os->type = SUBPATTERN;
5177*38fd1498Szrj print_subroutine_start (os, routine->s, routine->pos);
5178*38fd1498Szrj print_state (os, routine->s, 2, true);
5179*38fd1498Szrj printf ("}\n");
5180*38fd1498Szrj }
5181*38fd1498Szrj
5182*38fd1498Szrj /* Output a routine of type TYPE that implements S. PROC_ID is the
5183*38fd1498Szrj number of the subroutine associated with S, or 0 if S is the main
5184*38fd1498Szrj routine. */
5185*38fd1498Szrj
5186*38fd1498Szrj static void
print_subroutine(output_state * os,state * s,int proc_id)5187*38fd1498Szrj print_subroutine (output_state *os, state *s, int proc_id)
5188*38fd1498Szrj {
5189*38fd1498Szrj printf ("\n");
5190*38fd1498Szrj switch (os->type)
5191*38fd1498Szrj {
5192*38fd1498Szrj case SUBPATTERN:
5193*38fd1498Szrj gcc_unreachable ();
5194*38fd1498Szrj
5195*38fd1498Szrj case RECOG:
5196*38fd1498Szrj if (proc_id)
5197*38fd1498Szrj printf ("static int\nrecog_%d", proc_id);
5198*38fd1498Szrj else
5199*38fd1498Szrj printf ("int\nrecog");
5200*38fd1498Szrj printf (" (rtx x1 ATTRIBUTE_UNUSED,\n"
5201*38fd1498Szrj "\trtx_insn *insn ATTRIBUTE_UNUSED,\n"
5202*38fd1498Szrj "\tint *pnum_clobbers ATTRIBUTE_UNUSED)\n");
5203*38fd1498Szrj break;
5204*38fd1498Szrj
5205*38fd1498Szrj case SPLIT:
5206*38fd1498Szrj if (proc_id)
5207*38fd1498Szrj printf ("static rtx_insn *\nsplit_%d", proc_id);
5208*38fd1498Szrj else
5209*38fd1498Szrj printf ("rtx_insn *\nsplit_insns");
5210*38fd1498Szrj printf (" (rtx x1 ATTRIBUTE_UNUSED, rtx_insn *insn ATTRIBUTE_UNUSED)\n");
5211*38fd1498Szrj break;
5212*38fd1498Szrj
5213*38fd1498Szrj case PEEPHOLE2:
5214*38fd1498Szrj if (proc_id)
5215*38fd1498Szrj printf ("static rtx_insn *\npeephole2_%d", proc_id);
5216*38fd1498Szrj else
5217*38fd1498Szrj printf ("rtx_insn *\npeephole2_insns");
5218*38fd1498Szrj printf (" (rtx x1 ATTRIBUTE_UNUSED,\n"
5219*38fd1498Szrj "\trtx_insn *insn ATTRIBUTE_UNUSED,\n"
5220*38fd1498Szrj "\tint *pmatch_len_ ATTRIBUTE_UNUSED)\n");
5221*38fd1498Szrj break;
5222*38fd1498Szrj }
5223*38fd1498Szrj print_subroutine_start (os, s, &root_pos);
5224*38fd1498Szrj if (proc_id == 0)
5225*38fd1498Szrj {
5226*38fd1498Szrj printf (" recog_data.insn = NULL;\n");
5227*38fd1498Szrj }
5228*38fd1498Szrj print_state (os, s, 2, true);
5229*38fd1498Szrj printf ("}\n");
5230*38fd1498Szrj }
5231*38fd1498Szrj
5232*38fd1498Szrj /* Print out a routine of type TYPE that performs ROOT. */
5233*38fd1498Szrj
5234*38fd1498Szrj static void
print_subroutine_group(output_state * os,routine_type type,state * root)5235*38fd1498Szrj print_subroutine_group (output_state *os, routine_type type, state *root)
5236*38fd1498Szrj {
5237*38fd1498Szrj os->type = type;
5238*38fd1498Szrj if (use_subroutines_p)
5239*38fd1498Szrj {
5240*38fd1498Szrj /* Split ROOT up into smaller pieces, both for readability and to
5241*38fd1498Szrj help the compiler. */
5242*38fd1498Szrj auto_vec <state *> subroutines;
5243*38fd1498Szrj find_subroutines (type, root, subroutines);
5244*38fd1498Szrj
5245*38fd1498Szrj /* Output the subroutines (but not ROOT itself). */
5246*38fd1498Szrj unsigned int i;
5247*38fd1498Szrj state *s;
5248*38fd1498Szrj FOR_EACH_VEC_ELT (subroutines, i, s)
5249*38fd1498Szrj print_subroutine (os, s, i + 1);
5250*38fd1498Szrj }
5251*38fd1498Szrj /* Output the main routine. */
5252*38fd1498Szrj print_subroutine (os, root, 0);
5253*38fd1498Szrj }
5254*38fd1498Szrj
5255*38fd1498Szrj /* Return the rtx pattern for the list of rtxes in a define_peephole2. */
5256*38fd1498Szrj
5257*38fd1498Szrj static rtx
get_peephole2_pattern(md_rtx_info * info)5258*38fd1498Szrj get_peephole2_pattern (md_rtx_info *info)
5259*38fd1498Szrj {
5260*38fd1498Szrj int i, j;
5261*38fd1498Szrj rtvec vec = XVEC (info->def, 0);
5262*38fd1498Szrj rtx pattern = rtx_alloc (SEQUENCE);
5263*38fd1498Szrj XVEC (pattern, 0) = rtvec_alloc (GET_NUM_ELEM (vec));
5264*38fd1498Szrj for (i = j = 0; i < GET_NUM_ELEM (vec); i++)
5265*38fd1498Szrj {
5266*38fd1498Szrj rtx x = RTVEC_ELT (vec, i);
5267*38fd1498Szrj /* Ignore scratch register requirements. */
5268*38fd1498Szrj if (GET_CODE (x) != MATCH_SCRATCH && GET_CODE (x) != MATCH_DUP)
5269*38fd1498Szrj {
5270*38fd1498Szrj XVECEXP (pattern, 0, j) = x;
5271*38fd1498Szrj j++;
5272*38fd1498Szrj }
5273*38fd1498Szrj }
5274*38fd1498Szrj XVECLEN (pattern, 0) = j;
5275*38fd1498Szrj if (j == 0)
5276*38fd1498Szrj error_at (info->loc, "empty define_peephole2");
5277*38fd1498Szrj return pattern;
5278*38fd1498Szrj }
5279*38fd1498Szrj
5280*38fd1498Szrj /* Return true if *PATTERN_PTR is a PARALLEL in which at least one trailing
5281*38fd1498Szrj rtx can be added automatically by add_clobbers. If so, update
5282*38fd1498Szrj *ACCEPTANCE_PTR so that its num_clobbers field contains the number
5283*38fd1498Szrj of such trailing rtxes and update *PATTERN_PTR so that it contains
5284*38fd1498Szrj the pattern without those rtxes. */
5285*38fd1498Szrj
5286*38fd1498Szrj static bool
remove_clobbers(acceptance_type * acceptance_ptr,rtx * pattern_ptr)5287*38fd1498Szrj remove_clobbers (acceptance_type *acceptance_ptr, rtx *pattern_ptr)
5288*38fd1498Szrj {
5289*38fd1498Szrj int i;
5290*38fd1498Szrj rtx new_pattern;
5291*38fd1498Szrj
5292*38fd1498Szrj /* Find the last non-clobber in the parallel. */
5293*38fd1498Szrj rtx pattern = *pattern_ptr;
5294*38fd1498Szrj for (i = XVECLEN (pattern, 0); i > 0; i--)
5295*38fd1498Szrj {
5296*38fd1498Szrj rtx x = XVECEXP (pattern, 0, i - 1);
5297*38fd1498Szrj if (GET_CODE (x) != CLOBBER
5298*38fd1498Szrj || (!REG_P (XEXP (x, 0))
5299*38fd1498Szrj && GET_CODE (XEXP (x, 0)) != MATCH_SCRATCH))
5300*38fd1498Szrj break;
5301*38fd1498Szrj }
5302*38fd1498Szrj
5303*38fd1498Szrj if (i == XVECLEN (pattern, 0))
5304*38fd1498Szrj return false;
5305*38fd1498Szrj
5306*38fd1498Szrj /* Build a similar insn without the clobbers. */
5307*38fd1498Szrj if (i == 1)
5308*38fd1498Szrj new_pattern = XVECEXP (pattern, 0, 0);
5309*38fd1498Szrj else
5310*38fd1498Szrj {
5311*38fd1498Szrj new_pattern = rtx_alloc (PARALLEL);
5312*38fd1498Szrj XVEC (new_pattern, 0) = rtvec_alloc (i);
5313*38fd1498Szrj for (int j = 0; j < i; ++j)
5314*38fd1498Szrj XVECEXP (new_pattern, 0, j) = XVECEXP (pattern, 0, j);
5315*38fd1498Szrj }
5316*38fd1498Szrj
5317*38fd1498Szrj /* Recognize it. */
5318*38fd1498Szrj acceptance_ptr->u.full.u.num_clobbers = XVECLEN (pattern, 0) - i;
5319*38fd1498Szrj *pattern_ptr = new_pattern;
5320*38fd1498Szrj return true;
5321*38fd1498Szrj }
5322*38fd1498Szrj
5323*38fd1498Szrj int
main(int argc,const char ** argv)5324*38fd1498Szrj main (int argc, const char **argv)
5325*38fd1498Szrj {
5326*38fd1498Szrj state insn_root, split_root, peephole2_root;
5327*38fd1498Szrj
5328*38fd1498Szrj progname = "genrecog";
5329*38fd1498Szrj
5330*38fd1498Szrj if (!init_rtx_reader_args (argc, argv))
5331*38fd1498Szrj return (FATAL_EXIT_CODE);
5332*38fd1498Szrj
5333*38fd1498Szrj write_header ();
5334*38fd1498Szrj
5335*38fd1498Szrj /* Read the machine description. */
5336*38fd1498Szrj
5337*38fd1498Szrj md_rtx_info info;
5338*38fd1498Szrj while (read_md_rtx (&info))
5339*38fd1498Szrj {
5340*38fd1498Szrj rtx def = info.def;
5341*38fd1498Szrj
5342*38fd1498Szrj acceptance_type acceptance;
5343*38fd1498Szrj acceptance.partial_p = false;
5344*38fd1498Szrj acceptance.u.full.code = info.index;
5345*38fd1498Szrj
5346*38fd1498Szrj rtx pattern;
5347*38fd1498Szrj switch (GET_CODE (def))
5348*38fd1498Szrj {
5349*38fd1498Szrj case DEFINE_INSN:
5350*38fd1498Szrj {
5351*38fd1498Szrj /* Match the instruction in the original .md form. */
5352*38fd1498Szrj acceptance.type = RECOG;
5353*38fd1498Szrj acceptance.u.full.u.num_clobbers = 0;
5354*38fd1498Szrj pattern = add_implicit_parallel (XVEC (def, 1));
5355*38fd1498Szrj validate_pattern (pattern, &info, NULL_RTX, 0);
5356*38fd1498Szrj match_pattern (&insn_root, &info, pattern, acceptance);
5357*38fd1498Szrj
5358*38fd1498Szrj /* If the pattern is a PARALLEL with trailing CLOBBERs,
5359*38fd1498Szrj allow recog_for_combine to match without the clobbers. */
5360*38fd1498Szrj if (GET_CODE (pattern) == PARALLEL
5361*38fd1498Szrj && remove_clobbers (&acceptance, &pattern))
5362*38fd1498Szrj match_pattern (&insn_root, &info, pattern, acceptance);
5363*38fd1498Szrj break;
5364*38fd1498Szrj }
5365*38fd1498Szrj
5366*38fd1498Szrj case DEFINE_SPLIT:
5367*38fd1498Szrj acceptance.type = SPLIT;
5368*38fd1498Szrj pattern = add_implicit_parallel (XVEC (def, 0));
5369*38fd1498Szrj validate_pattern (pattern, &info, NULL_RTX, 0);
5370*38fd1498Szrj match_pattern (&split_root, &info, pattern, acceptance);
5371*38fd1498Szrj
5372*38fd1498Szrj /* Declare the gen_split routine that we'll call if the
5373*38fd1498Szrj pattern matches. The definition comes from insn-emit.c. */
5374*38fd1498Szrj printf ("extern rtx_insn *gen_split_%d (rtx_insn *, rtx *);\n",
5375*38fd1498Szrj info.index);
5376*38fd1498Szrj break;
5377*38fd1498Szrj
5378*38fd1498Szrj case DEFINE_PEEPHOLE2:
5379*38fd1498Szrj acceptance.type = PEEPHOLE2;
5380*38fd1498Szrj pattern = get_peephole2_pattern (&info);
5381*38fd1498Szrj validate_pattern (pattern, &info, NULL_RTX, 0);
5382*38fd1498Szrj match_pattern (&peephole2_root, &info, pattern, acceptance);
5383*38fd1498Szrj
5384*38fd1498Szrj /* Declare the gen_peephole2 routine that we'll call if the
5385*38fd1498Szrj pattern matches. The definition comes from insn-emit.c. */
5386*38fd1498Szrj printf ("extern rtx_insn *gen_peephole2_%d (rtx_insn *, rtx *);\n",
5387*38fd1498Szrj info.index);
5388*38fd1498Szrj break;
5389*38fd1498Szrj
5390*38fd1498Szrj default:
5391*38fd1498Szrj /* do nothing */;
5392*38fd1498Szrj }
5393*38fd1498Szrj }
5394*38fd1498Szrj
5395*38fd1498Szrj if (have_error)
5396*38fd1498Szrj return FATAL_EXIT_CODE;
5397*38fd1498Szrj
5398*38fd1498Szrj puts ("\n\n");
5399*38fd1498Szrj
5400*38fd1498Szrj /* Optimize each routine in turn. */
5401*38fd1498Szrj optimize_subroutine_group ("recog", &insn_root);
5402*38fd1498Szrj optimize_subroutine_group ("split_insns", &split_root);
5403*38fd1498Szrj optimize_subroutine_group ("peephole2_insns", &peephole2_root);
5404*38fd1498Szrj
5405*38fd1498Szrj output_state os;
5406*38fd1498Szrj os.id_to_var.safe_grow_cleared (num_positions);
5407*38fd1498Szrj
5408*38fd1498Szrj if (use_pattern_routines_p)
5409*38fd1498Szrj {
5410*38fd1498Szrj /* Look for common patterns and split them out into subroutines. */
5411*38fd1498Szrj auto_vec <merge_state_info> states;
5412*38fd1498Szrj states.safe_push (&insn_root);
5413*38fd1498Szrj states.safe_push (&split_root);
5414*38fd1498Szrj states.safe_push (&peephole2_root);
5415*38fd1498Szrj split_out_patterns (states);
5416*38fd1498Szrj
5417*38fd1498Szrj /* Print out the routines that we just created. */
5418*38fd1498Szrj unsigned int i;
5419*38fd1498Szrj pattern_routine *routine;
5420*38fd1498Szrj FOR_EACH_VEC_ELT (patterns, i, routine)
5421*38fd1498Szrj print_pattern (&os, routine);
5422*38fd1498Szrj }
5423*38fd1498Szrj
5424*38fd1498Szrj /* Print out the matching routines. */
5425*38fd1498Szrj print_subroutine_group (&os, RECOG, &insn_root);
5426*38fd1498Szrj print_subroutine_group (&os, SPLIT, &split_root);
5427*38fd1498Szrj print_subroutine_group (&os, PEEPHOLE2, &peephole2_root);
5428*38fd1498Szrj
5429*38fd1498Szrj fflush (stdout);
5430*38fd1498Szrj return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
5431*38fd1498Szrj }
5432