xref: /dflybsd-src/contrib/gcc-8.0/gcc/genrecog.c (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
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 &param1, const parameter &param2)
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 &param1, const parameter &param2)
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> &params, 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> &params1, vec <parameter> &params2,
2530*38fd1498Szrj 	       const parameter &param1, const parameter &param2,
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 &param1 = to1_res->params[j];
2691*38fd1498Szrj 	    const parameter &param2 = 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, &param_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, &param_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> &params)
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> &params)
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 &param = 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 &param = 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 &param = 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 &param)
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