]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genmatch.cc
build: Use of cargo not yet supported here in Canadian cross configurations
[thirdparty/gcc.git] / gcc / genmatch.cc
CommitLineData
3d2cf79f
RB
1/* Generate pattern matching and transform code shared between
2 GENERIC and GIMPLE folding code from match-and-simplify description.
3
a945c346 4 Copyright (C) 2014-2024 Free Software Foundation, Inc.
3d2cf79f
RB
5 Contributed by Richard Biener <rguenther@suse.de>
6 and Prathamesh Kulkarni <bilbotheelffriend@gmail.com>
7
8This file is part of GCC.
9
10GCC is free software; you can redistribute it and/or modify it under
11the terms of the GNU General Public License as published by the Free
12Software Foundation; either version 3, or (at your option) any later
13version.
14
15GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16WARRANTY; without even the implied warranty of MERCHANTABILITY or
17FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18for more details.
19
20You should have received a copy of the GNU General Public License
21along with GCC; see the file COPYING3. If not see
22<http://www.gnu.org/licenses/>. */
23
24#include "bconfig.h"
3d2cf79f
RB
25#include "system.h"
26#include "coretypes.h"
27#include <cpplib.h>
78d132d7 28#include "rich-location.h"
3d2cf79f 29#include "errors.h"
3d2cf79f 30#include "hash-table.h"
1c9b0448 31#include "hash-set.h"
3d2cf79f 32#include "is-a.h"
e6b616c0 33#include "ordered-hash-map.h"
3d2cf79f
RB
34
35
f1308e4b
RB
36/* Stubs for GGC referenced through instantiations triggered by hash-map. */
37void *ggc_internal_cleared_alloc (size_t, void (*)(void *),
e7d1000c 38 size_t, size_t MEM_STAT_DECL)
f1308e4b
RB
39{
40 return NULL;
41}
42void ggc_free (void *)
43{
44}
45
46
53a19317
RB
47/* Global state. */
48
49/* Verboseness. 0 is quiet, 1 adds some warnings, 2 is for debugging. */
50unsigned verbose;
51
52
3d2cf79f
RB
53/* libccp helpers. */
54
99b1c316 55static class line_maps *line_table;
3d2cf79f 56
8a645150 57/* The rich_location class within libcpp requires a way to expand
620e594b 58 location_t instances, and relies on the client code
8a645150
DM
59 providing a symbol named
60 linemap_client_expand_location_to_spelling_point
61 to do this.
62
63 This is the implementation for genmatch. */
64
65expanded_location
8625aa24
DM
66linemap_client_expand_location_to_spelling_point (const line_maps *set,
67 location_t loc,
c471c6ed 68 enum location_aspect)
8a645150
DM
69{
70 const struct line_map_ordinary *map;
8625aa24
DM
71 loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map);
72 return linemap_expand_location (set, map, loc);
8a645150
DM
73}
74
3d2cf79f
RB
75static bool
76#if GCC_VERSION >= 4001
8a645150 77__attribute__((format (printf, 5, 0)))
3d2cf79f 78#endif
c24300ba
DM
79diagnostic_cb (cpp_reader *, enum cpp_diagnostic_level errtype,
80 enum cpp_warning_reason, rich_location *richloc,
81 const char *msg, va_list *ap)
3d2cf79f 82{
0e50b624 83 const line_map_ordinary *map;
620e594b 84 location_t location = richloc->get_loc ();
3d2cf79f
RB
85 linemap_resolve_location (line_table, location, LRK_SPELLING_LOCATION, &map);
86 expanded_location loc = linemap_expand_location (line_table, map, location);
72eb311d
RB
87 fprintf (stderr, "%s:%d:%d %s: ", loc.file, loc.line, loc.column,
88 (errtype == CPP_DL_WARNING) ? "warning" : "error");
3d2cf79f
RB
89 vfprintf (stderr, msg, *ap);
90 fprintf (stderr, "\n");
91 FILE *f = fopen (loc.file, "r");
92 if (f)
93 {
94 char buf[128];
95 while (loc.line > 0)
96 {
97 if (!fgets (buf, 128, f))
98 goto notfound;
99 if (buf[strlen (buf) - 1] != '\n')
100 {
101 if (loc.line > 1)
102 loc.line++;
103 }
104 loc.line--;
105 }
106 fprintf (stderr, "%s", buf);
107 for (int i = 0; i < loc.column - 1; ++i)
108 fputc (' ', stderr);
109 fputc ('^', stderr);
110 fputc ('\n', stderr);
111notfound:
112 fclose (f);
113 }
72eb311d
RB
114
115 if (errtype == CPP_DL_FATAL)
116 exit (1);
117 return false;
3d2cf79f
RB
118}
119
120static void
121#if GCC_VERSION >= 4001
122__attribute__((format (printf, 2, 3)))
123#endif
124fatal_at (const cpp_token *tk, const char *msg, ...)
125{
ebedc9a3 126 rich_location richloc (line_table, tk->src_loc);
3d2cf79f
RB
127 va_list ap;
128 va_start (ap, msg);
c24300ba 129 diagnostic_cb (NULL, CPP_DL_FATAL, CPP_W_NONE, &richloc, msg, &ap);
3d2cf79f
RB
130 va_end (ap);
131}
132
1c9b0448
RB
133static void
134#if GCC_VERSION >= 4001
135__attribute__((format (printf, 2, 3)))
136#endif
620e594b 137fatal_at (location_t loc, const char *msg, ...)
1c9b0448 138{
ebedc9a3 139 rich_location richloc (line_table, loc);
1c9b0448
RB
140 va_list ap;
141 va_start (ap, msg);
c24300ba 142 diagnostic_cb (NULL, CPP_DL_FATAL, CPP_W_NONE, &richloc, msg, &ap);
1c9b0448
RB
143 va_end (ap);
144}
145
72eb311d
RB
146static void
147#if GCC_VERSION >= 4001
148__attribute__((format (printf, 2, 3)))
149#endif
150warning_at (const cpp_token *tk, const char *msg, ...)
151{
ebedc9a3 152 rich_location richloc (line_table, tk->src_loc);
72eb311d
RB
153 va_list ap;
154 va_start (ap, msg);
c24300ba 155 diagnostic_cb (NULL, CPP_DL_WARNING, CPP_W_NONE, &richloc, msg, &ap);
72eb311d
RB
156 va_end (ap);
157}
158
53a19317
RB
159static void
160#if GCC_VERSION >= 4001
161__attribute__((format (printf, 2, 3)))
162#endif
620e594b 163warning_at (location_t loc, const char *msg, ...)
53a19317 164{
ebedc9a3 165 rich_location richloc (line_table, loc);
53a19317
RB
166 va_list ap;
167 va_start (ap, msg);
c24300ba 168 diagnostic_cb (NULL, CPP_DL_WARNING, CPP_W_NONE, &richloc, msg, &ap);
53a19317
RB
169 va_end (ap);
170}
171
c551c21d
MM
172/* Like fprintf, but print INDENT spaces at the beginning. */
173
174static void
175#if GCC_VERSION >= 4001
176__attribute__((format (printf, 3, 4)))
177#endif
178fprintf_indent (FILE *f, unsigned int indent, const char *format, ...)
179{
180 va_list ap;
181 for (; indent >= 8; indent -= 8)
182 fputc ('\t', f);
183 fprintf (f, "%*s", indent, "");
184 va_start (ap, format);
185 vfprintf (f, format, ap);
186 va_end (ap);
187}
188
2ed6dd97
AM
189/* Secondary stream for fp_decl. */
190static FILE *header_file;
703417a0 191
2ed6dd97
AM
192/* Start or continue emitting a declaration in fprintf-like manner,
193 printing both to F and global header_file, if non-null. */
703417a0
TC
194static void
195#if GCC_VERSION >= 4001
2ed6dd97 196__attribute__((format (printf, 2, 3)))
703417a0 197#endif
2ed6dd97 198fp_decl (FILE *f, const char *format, ...)
703417a0 199{
2ed6dd97
AM
200 va_list ap;
201 va_start (ap, format);
202 vfprintf (f, format, ap);
203 va_end (ap);
703417a0 204
2ed6dd97
AM
205 if (!header_file)
206 return;
207
208 va_start (ap, format);
209 vfprintf (header_file, format, ap);
210 va_end (ap);
211}
212
213/* Finish a declaration being emitted by fp_decl. */
214static void
215fp_decl_done (FILE *f, const char *trailer)
216{
217 fprintf (f, "%s\n", trailer);
218 if (header_file)
219 fprintf (header_file, "%s;", trailer);
703417a0
TC
220}
221
d9dc70cc
AT
222/* Line numbers for use by indirect line directives. */
223static vec<int> dbg_line_numbers;
224
225static void
226write_header_declarations (bool gimple, FILE *f)
227{
228 fprintf (f, "\nextern void\n%s_dump_logs (const char *file1, int line1_id, "
229 "const char *file2, int line2, bool simplify);\n",
230 gimple ? "gimple" : "generic");
231}
232
233static void
234define_dump_logs (bool gimple, FILE *f)
235{
236 if (dbg_line_numbers.is_empty ())
237 return;
238
239 fprintf (f , "void\n%s_dump_logs (const char *file1, int line1_id, "
240 "const char *file2, int line2, bool simplify)\n{\n",
241 gimple ? "gimple" : "generic");
242
243 fprintf_indent (f, 2, "static int dbg_line_numbers[%d] = {",
244 dbg_line_numbers.length ());
245
246 for (unsigned i = 0; i < dbg_line_numbers.length () - 1; i++)
247 {
248 if (i % 20 == 0)
249 fprintf (f, "\n\t");
250
251 fprintf (f, "%d, ", dbg_line_numbers[i]);
252 }
253 fprintf (f, "%d\n };\n\n", dbg_line_numbers.last ());
254
255
256 fprintf_indent (f, 2, "fprintf (dump_file, \"%%s "
257 "%%s:%%d, %%s:%%d\\n\",\n");
258 fprintf_indent (f, 10, "simplify ? \"Applying pattern\" : "
259 "\"Matching expression\", file1, "
260 "dbg_line_numbers[line1_id], file2, line2);");
261
262 fprintf (f, "\n}\n\n");
263}
264
3d2cf79f 265static void
620e594b 266output_line_directive (FILE *f, location_t location,
d9dc70cc
AT
267 bool dumpfile = false, bool fnargs = false,
268 bool indirect_line_numbers = false)
3d2cf79f 269{
d9dc70cc
AT
270 typedef pair_hash<nofree_string_hash, int_hash<int, -1>> location_hash;
271 static hash_map<location_hash, int> loc_id_map;
0e50b624 272 const line_map_ordinary *map;
3d2cf79f
RB
273 linemap_resolve_location (line_table, location, LRK_SPELLING_LOCATION, &map);
274 expanded_location loc = linemap_expand_location (line_table, map, location);
275 if (dumpfile)
276 {
277 /* When writing to a dumpfile only dump the filename. */
278 const char *file = strrchr (loc.file, DIR_SEPARATOR);
c265c2dd
RB
279#if defined(DIR_SEPARATOR_2)
280 const char *pos2 = strrchr (loc.file, DIR_SEPARATOR_2);
281 if (pos2 && (!file || (pos2 > file)))
282 file = pos2;
283#endif
3d2cf79f
RB
284 if (!file)
285 file = loc.file;
286 else
287 ++file;
8fcfe047
ML
288
289 if (fnargs)
d9dc70cc
AT
290 {
291 if (indirect_line_numbers)
292 {
293 bool existed;
294 int &loc_id = loc_id_map.get_or_insert (
295 std::make_pair (file, loc.line), &existed);
296 if (!existed)
297 {
298 loc_id = dbg_line_numbers.length ();
299 dbg_line_numbers.safe_push (loc.line);
300 }
301
302 fprintf (f, "\"%s\", %d", file, loc_id);
303 }
304 else
305 fprintf (f, "\"%s\", %d", file, loc.line);
306 }
8fcfe047
ML
307 else
308 fprintf (f, "%s:%d", file, loc.line);
3d2cf79f 309 }
e487fcc0 310 else if (verbose >= 2)
3d2cf79f
RB
311 /* Other gen programs really output line directives here, at least for
312 development it's right now more convenient to have line information
313 from the generated file. Still keep the directives as comment for now
314 to easily back-point to the meta-description. */
315 fprintf (f, "/* #line %d \"%s\" */\n", loc.line, loc.file);
316}
317
703417a0
TC
318/* Find the file to write into next. We try to evenly distribute the contents
319 over the different files. */
320
321#define SIZED_BASED_CHUNKS 1
322
153eafaa
AM
323static FILE *
324choose_output (const vec<FILE *> &parts)
703417a0
TC
325{
326#ifdef SIZED_BASED_CHUNKS
153eafaa
AM
327 FILE *shortest = NULL;
328 long min = 0;
329 for (FILE *part : parts)
330 {
331 long len = ftell (part);
332 if (!shortest || min > len)
333 shortest = part, min = len;
334 }
335 return shortest;
703417a0 336#else
153eafaa 337 static int current_file;
703417a0
TC
338 return parts[current_file++ % parts.length ()];
339#endif
340}
341
3d2cf79f
RB
342
343/* Pull in tree codes and builtin function codes from their
344 definition files. */
345
346#define DEFTREECODE(SYM, STRING, TYPE, NARGS) SYM,
347enum tree_code {
348#include "tree.def"
3d2cf79f
RB
349MAX_TREE_CODES
350};
351#undef DEFTREECODE
352
353#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) ENUM,
354enum built_in_function {
355#include "builtins.def"
356END_BUILTINS
357};
3d2cf79f 358
c9e926ce
RS
359#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) IFN_##CODE,
360enum internal_fn {
361#include "internal-fn.def"
362 IFN_LAST
363};
364
c566cc9f
RS
365enum combined_fn {
366#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \
367 CFN_##ENUM = int (ENUM),
368#include "builtins.def"
369
370#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
371 CFN_##CODE = int (END_BUILTINS) + int (IFN_##CODE),
372#include "internal-fn.def"
373
374 CFN_LAST
375};
376
377#include "case-cfn-macros.h"
378
805a5406
RB
379/* Return true if CODE represents a commutative tree code. Otherwise
380 return false. */
381bool
382commutative_tree_code (enum tree_code code)
383{
384 switch (code)
385 {
386 case PLUS_EXPR:
387 case MULT_EXPR:
388 case MULT_HIGHPART_EXPR:
389 case MIN_EXPR:
390 case MAX_EXPR:
391 case BIT_IOR_EXPR:
392 case BIT_XOR_EXPR:
393 case BIT_AND_EXPR:
394 case NE_EXPR:
395 case EQ_EXPR:
396 case UNORDERED_EXPR:
397 case ORDERED_EXPR:
398 case UNEQ_EXPR:
399 case LTGT_EXPR:
400 case TRUTH_AND_EXPR:
401 case TRUTH_XOR_EXPR:
402 case TRUTH_OR_EXPR:
403 case WIDEN_MULT_EXPR:
404 case VEC_WIDEN_MULT_HI_EXPR:
405 case VEC_WIDEN_MULT_LO_EXPR:
406 case VEC_WIDEN_MULT_EVEN_EXPR:
407 case VEC_WIDEN_MULT_ODD_EXPR:
408 return true;
409
410 default:
411 break;
412 }
413 return false;
414}
415
416/* Return true if CODE represents a ternary tree code for which the
417 first two operands are commutative. Otherwise return false. */
418bool
419commutative_ternary_tree_code (enum tree_code code)
420{
421 switch (code)
422 {
423 case WIDEN_MULT_PLUS_EXPR:
424 case WIDEN_MULT_MINUS_EXPR:
425 case DOT_PROD_EXPR:
805a5406
RB
426 return true;
427
428 default:
429 break;
430 }
431 return false;
432}
433
e04d2a35
RB
434/* Return true if CODE is a comparison. */
435
436bool
437comparison_code_p (enum tree_code code)
438{
439 switch (code)
440 {
441 case EQ_EXPR:
442 case NE_EXPR:
443 case ORDERED_EXPR:
444 case UNORDERED_EXPR:
445 case LTGT_EXPR:
446 case UNEQ_EXPR:
447 case GT_EXPR:
448 case GE_EXPR:
449 case LT_EXPR:
450 case LE_EXPR:
451 case UNGT_EXPR:
452 case UNGE_EXPR:
453 case UNLT_EXPR:
454 case UNLE_EXPR:
455 return true;
456
457 default:
458 break;
459 }
460 return false;
461}
462
3d2cf79f
RB
463
464/* Base class for all identifiers the parser knows. */
465
6c1dae73 466class id_base : public nofree_ptr_hash<id_base>
3d2cf79f 467{
6c1dae73 468public:
fa74b47a 469 enum id_kind { CODE, FN, PREDICATE, USER, NULL_ID } kind;
3d2cf79f
RB
470
471 id_base (id_kind, const char *, int = -1);
472
473 hashval_t hashval;
474 int nargs;
475 const char *id;
476
477 /* hash_table support. */
67f58944
TS
478 static inline hashval_t hash (const id_base *);
479 static inline int equal (const id_base *, const id_base *);
3d2cf79f
RB
480};
481
482inline hashval_t
67f58944 483id_base::hash (const id_base *op)
3d2cf79f
RB
484{
485 return op->hashval;
486}
487
488inline int
67f58944
TS
489id_base::equal (const id_base *op1,
490 const id_base *op2)
3d2cf79f
RB
491{
492 return (op1->hashval == op2->hashval
493 && strcmp (op1->id, op2->id) == 0);
494}
495
fa74b47a
RS
496/* The special id "null", which matches nothing. */
497static id_base *null_id;
498
3d2cf79f
RB
499/* Hashtable of known pattern operators. This is pre-seeded from
500 all known tree codes and all known builtin function ids. */
501static hash_table<id_base> *operators;
502
503id_base::id_base (id_kind kind_, const char *id_, int nargs_)
504{
505 kind = kind_;
506 id = id_;
507 nargs = nargs_;
508 hashval = htab_hash_string (id);
509}
510
511/* Identifier that maps to a tree code. */
512
6c1dae73 513class operator_id : public id_base
3d2cf79f 514{
6c1dae73 515public:
3d2cf79f
RB
516 operator_id (enum tree_code code_, const char *id_, unsigned nargs_,
517 const char *tcc_)
518 : id_base (id_base::CODE, id_, nargs_), code (code_), tcc (tcc_) {}
519 enum tree_code code;
520 const char *tcc;
521};
522
c9e926ce 523/* Identifier that maps to a builtin or internal function code. */
3d2cf79f 524
6c1dae73 525class fn_id : public id_base
3d2cf79f 526{
6c1dae73 527public:
3d2cf79f
RB
528 fn_id (enum built_in_function fn_, const char *id_)
529 : id_base (id_base::FN, id_), fn (fn_) {}
c9e926ce
RS
530 fn_id (enum internal_fn fn_, const char *id_)
531 : id_base (id_base::FN, id_), fn (int (END_BUILTINS) + int (fn_)) {}
532 unsigned int fn;
3d2cf79f
RB
533};
534
99b1c316 535class simplify;
3d2cf79f
RB
536
537/* Identifier that maps to a user-defined predicate. */
538
6c1dae73 539class predicate_id : public id_base
3d2cf79f 540{
6c1dae73 541public:
3d2cf79f
RB
542 predicate_id (const char *id_)
543 : id_base (id_base::PREDICATE, id_), matchers (vNULL) {}
544 vec<simplify *> matchers;
545};
546
547/* Identifier that maps to a operator defined by a 'for' directive. */
548
6c1dae73 549class user_id : public id_base
3d2cf79f 550{
6c1dae73 551public:
72eb311d
RB
552 user_id (const char *id_, bool is_oper_list_ = false)
553 : id_base (id_base::USER, id_), substitutes (vNULL),
554 used (false), is_oper_list (is_oper_list_) {}
3d2cf79f 555 vec<id_base *> substitutes;
72eb311d
RB
556 bool used;
557 bool is_oper_list;
3d2cf79f
RB
558};
559
560template<>
561template<>
562inline bool
563is_a_helper <fn_id *>::test (id_base *id)
564{
565 return id->kind == id_base::FN;
566}
567
568template<>
569template<>
570inline bool
571is_a_helper <operator_id *>::test (id_base *id)
572{
573 return id->kind == id_base::CODE;
574}
575
576template<>
577template<>
578inline bool
579is_a_helper <predicate_id *>::test (id_base *id)
580{
581 return id->kind == id_base::PREDICATE;
582}
583
584template<>
585template<>
586inline bool
587is_a_helper <user_id *>::test (id_base *id)
588{
589 return id->kind == id_base::USER;
590}
591
c566cc9f
RS
592/* If ID has a pair of consecutive, commutative operands, return the
593 index of the first, otherwise return -1. */
594
595static int
596commutative_op (id_base *id)
597{
598 if (operator_id *code = dyn_cast <operator_id *> (id))
599 {
600 if (commutative_tree_code (code->code)
601 || commutative_ternary_tree_code (code->code))
602 return 0;
603 return -1;
604 }
605 if (fn_id *fn = dyn_cast <fn_id *> (id))
606 switch (fn->fn)
607 {
608 CASE_CFN_FMA:
609 case CFN_FMS:
610 case CFN_FNMA:
611 case CFN_FNMS:
612 return 0;
613
7486fe15
RS
614 case CFN_COND_ADD:
615 case CFN_COND_MUL:
616 case CFN_COND_MIN:
617 case CFN_COND_MAX:
618 case CFN_COND_FMIN:
619 case CFN_COND_FMAX:
620 case CFN_COND_AND:
621 case CFN_COND_IOR:
622 case CFN_COND_XOR:
623 case CFN_COND_FMA:
624 case CFN_COND_FMS:
625 case CFN_COND_FNMA:
626 case CFN_COND_FNMS:
834f3494
JZZ
627 case CFN_COND_LEN_ADD:
628 case CFN_COND_LEN_MUL:
629 case CFN_COND_LEN_MIN:
630 case CFN_COND_LEN_MAX:
631 case CFN_COND_LEN_FMIN:
632 case CFN_COND_LEN_FMAX:
633 case CFN_COND_LEN_AND:
634 case CFN_COND_LEN_IOR:
635 case CFN_COND_LEN_XOR:
636 case CFN_COND_LEN_FMA:
637 case CFN_COND_LEN_FMS:
638 case CFN_COND_LEN_FNMA:
639 case CFN_COND_LEN_FNMS:
7486fe15
RS
640 return 1;
641
c566cc9f
RS
642 default:
643 return -1;
644 }
645 if (user_id *uid = dyn_cast<user_id *> (id))
646 {
647 int res = commutative_op (uid->substitutes[0]);
648 if (res < 0)
46034c46 649 return -1;
c566cc9f
RS
650 for (unsigned i = 1; i < uid->substitutes.length (); ++i)
651 if (res != commutative_op (uid->substitutes[i]))
652 return -1;
653 return res;
654 }
655 return -1;
656}
657
3d2cf79f
RB
658/* Add a predicate identifier to the hash. */
659
660static predicate_id *
661add_predicate (const char *id)
662{
663 predicate_id *p = new predicate_id (id);
664 id_base **slot = operators->find_slot_with_hash (p, p->hashval, INSERT);
665 if (*slot)
666 fatal ("duplicate id definition");
667 *slot = p;
668 return p;
669}
670
671/* Add a tree code identifier to the hash. */
672
673static void
674add_operator (enum tree_code code, const char *id,
675 const char *tcc, unsigned nargs)
676{
677 if (strcmp (tcc, "tcc_unary") != 0
678 && strcmp (tcc, "tcc_binary") != 0
679 && strcmp (tcc, "tcc_comparison") != 0
680 && strcmp (tcc, "tcc_expression") != 0
681 /* For {REAL,IMAG}PART_EXPR and VIEW_CONVERT_EXPR. */
682 && strcmp (tcc, "tcc_reference") != 0
683 /* To have INTEGER_CST and friends as "predicate operators". */
10230017
RB
684 && strcmp (tcc, "tcc_constant") != 0
685 /* And allow CONSTRUCTOR for vector initializers. */
96a111a3
RB
686 && !(code == CONSTRUCTOR)
687 /* Allow SSA_NAME as predicate operator. */
688 && !(code == SSA_NAME))
3d2cf79f 689 return;
99e943a2
RB
690 /* Treat ADDR_EXPR as atom, thus don't allow matching its operand. */
691 if (code == ADDR_EXPR)
692 nargs = 0;
3d2cf79f
RB
693 operator_id *op = new operator_id (code, id, nargs, tcc);
694 id_base **slot = operators->find_slot_with_hash (op, op->hashval, INSERT);
695 if (*slot)
696 fatal ("duplicate id definition");
697 *slot = op;
698}
699
c9e926ce
RS
700/* Add a built-in or internal function identifier to the hash. ID is
701 the name of its CFN_* enumeration value. */
3d2cf79f 702
c9e926ce 703template <typename T>
3d2cf79f 704static void
c9e926ce 705add_function (T code, const char *id)
3d2cf79f
RB
706{
707 fn_id *fn = new fn_id (code, id);
708 id_base **slot = operators->find_slot_with_hash (fn, fn->hashval, INSERT);
709 if (*slot)
710 fatal ("duplicate id definition");
711 *slot = fn;
712}
713
714/* Helper for easy comparing ID with tree code CODE. */
715
716static bool
717operator==(id_base &id, enum tree_code code)
718{
719 if (operator_id *oid = dyn_cast <operator_id *> (&id))
720 return oid->code == code;
721 return false;
722}
723
fa74b47a 724/* Lookup the identifier ID. Allow "null" if ALLOW_NULL. */
3d2cf79f
RB
725
726id_base *
fa74b47a 727get_operator (const char *id, bool allow_null = false)
3d2cf79f 728{
fa74b47a
RS
729 if (allow_null && strcmp (id, "null") == 0)
730 return null_id;
731
3d2cf79f
RB
732 id_base tem (id_base::CODE, id);
733
734 id_base *op = operators->find_with_hash (&tem, tem.hashval);
735 if (op)
72eb311d
RB
736 {
737 /* If this is a user-defined identifier track whether it was used. */
738 if (user_id *uid = dyn_cast<user_id *> (op))
739 uid->used = true;
740 return op;
741 }
3d2cf79f 742
c9e926ce
RS
743 char *id2;
744 bool all_upper = true;
745 bool all_lower = true;
746 for (unsigned int i = 0; id[i]; ++i)
747 if (ISUPPER (id[i]))
748 all_lower = false;
749 else if (ISLOWER (id[i]))
750 all_upper = false;
751 if (all_lower)
3d2cf79f 752 {
c9e926ce
RS
753 /* Try in caps with _EXPR appended. */
754 id2 = ACONCAT ((id, "_EXPR", NULL));
755 for (unsigned int i = 0; id2[i]; ++i)
756 id2[i] = TOUPPER (id2[i]);
3d2cf79f 757 }
6ba3079d 758 else if (all_upper && startswith (id, "IFN_"))
c9e926ce
RS
759 /* Try CFN_ instead of IFN_. */
760 id2 = ACONCAT (("CFN_", id + 4, NULL));
6ba3079d 761 else if (all_upper && startswith (id, "BUILT_IN_"))
c9e926ce
RS
762 /* Try prepending CFN_. */
763 id2 = ACONCAT (("CFN_", id, NULL));
764 else
765 return NULL;
3d2cf79f 766
3d2cf79f 767 new (&tem) id_base (id_base::CODE, id2);
c9e926ce 768 return operators->find_with_hash (&tem, tem.hashval);
3d2cf79f
RB
769}
770
e04d2a35
RB
771/* Return the comparison operators that results if the operands are
772 swapped. This is safe for floating-point. */
773
774id_base *
775swap_tree_comparison (operator_id *p)
776{
777 switch (p->code)
778 {
779 case EQ_EXPR:
780 case NE_EXPR:
781 case ORDERED_EXPR:
782 case UNORDERED_EXPR:
783 case LTGT_EXPR:
784 case UNEQ_EXPR:
785 return p;
786 case GT_EXPR:
787 return get_operator ("LT_EXPR");
788 case GE_EXPR:
789 return get_operator ("LE_EXPR");
790 case LT_EXPR:
791 return get_operator ("GT_EXPR");
792 case LE_EXPR:
793 return get_operator ("GE_EXPR");
794 case UNGT_EXPR:
795 return get_operator ("UNLT_EXPR");
796 case UNGE_EXPR:
797 return get_operator ("UNLE_EXPR");
798 case UNLT_EXPR:
799 return get_operator ("UNGT_EXPR");
800 case UNLE_EXPR:
801 return get_operator ("UNGE_EXPR");
802 default:
803 gcc_unreachable ();
804 }
805}
806
fb5c464a 807typedef hash_map<nofree_string_hash, unsigned> cid_map_t;
f1308e4b 808
3d2cf79f
RB
809
810/* The AST produced by parsing of the pattern definitions. */
811
99b1c316
MS
812class dt_operand;
813class capture_info;
3d2cf79f
RB
814
815/* The base class for operands. */
816
6c1dae73
MS
817class operand {
818public:
8fdc6c67 819 enum op_type { OP_PREDICATE, OP_EXPR, OP_CAPTURE, OP_C_EXPR, OP_IF, OP_WITH };
620e594b 820 operand (enum op_type type_, location_t loc_)
0889c52f 821 : type (type_), location (loc_) {}
3d2cf79f 822 enum op_type type;
620e594b 823 location_t location;
c551c21d 824 virtual void gen_transform (FILE *, int, const char *, bool, int,
47b25362
RB
825 const char *, capture_info *,
826 dt_operand ** = 0,
a3ca1bc5 827 int = 0)
3d2cf79f
RB
828 { gcc_unreachable (); }
829};
830
831/* A predicate operand. Predicates are leafs in the AST. */
832
6c1dae73 833class predicate : public operand
3d2cf79f 834{
6c1dae73 835public:
620e594b 836 predicate (predicate_id *p_, location_t loc)
0889c52f 837 : operand (OP_PREDICATE, loc), p (p_) {}
3d2cf79f
RB
838 predicate_id *p;
839};
840
841/* An operand that constitutes an expression. Expressions include
842 function calls and user-defined predicate invocations. */
843
6c1dae73 844class expr : public operand
3d2cf79f 845{
6c1dae73 846public:
620e594b 847 expr (id_base *operation_, location_t loc, bool is_commutative_ = false)
0889c52f 848 : operand (OP_EXPR, loc), operation (operation_),
47b25362 849 ops (vNULL), expr_type (NULL), is_commutative (is_commutative_),
14c35be3
RB
850 is_generic (false), force_single_use (false), force_leaf (false),
851 opt_grp (0) {}
44fc0a51 852 expr (expr *e)
0889c52f 853 : operand (OP_EXPR, e->location), operation (e->operation),
44fc0a51 854 ops (vNULL), expr_type (e->expr_type), is_commutative (e->is_commutative),
28fabd43 855 is_generic (e->is_generic), force_single_use (e->force_single_use),
14c35be3 856 force_leaf (e->force_leaf), opt_grp (e->opt_grp) {}
3d2cf79f
RB
857 void append_op (operand *op) { ops.safe_push (op); }
858 /* The operator and its operands. */
859 id_base *operation;
860 vec<operand *> ops;
861 /* An explicitely specified type - used exclusively for conversions. */
862 const char *expr_type;
863 /* Whether the operation is to be applied commutatively. This is
864 later lowered to two separate patterns. */
865 bool is_commutative;
47b25362
RB
866 /* Whether the expression is expected to be in GENERIC form. */
867 bool is_generic;
44fc0a51
RB
868 /* Whether pushing any stmt to the sequence should be conditional
869 on this expression having a single-use. */
870 bool force_single_use;
14c35be3
RB
871 /* Whether in the result expression this should be a leaf node
872 with any children simplified down to simple operands. */
873 bool force_leaf;
28fabd43
RB
874 /* If non-zero, the group for optional handling. */
875 unsigned char opt_grp;
26f77c4d
DM
876 void gen_transform (FILE *f, int, const char *, bool, int,
877 const char *, capture_info *,
878 dt_operand ** = 0, int = 0) override;
3d2cf79f
RB
879};
880
881/* An operator that is represented by native C code. This is always
882 a leaf operand in the AST. This class is also used to represent
883 the code to be generated for 'if' and 'with' expressions. */
884
6c1dae73 885class c_expr : public operand
3d2cf79f 886{
6c1dae73 887public:
3d2cf79f
RB
888 /* A mapping of an identifier and its replacement. Used to apply
889 'for' lowering. */
6c1dae73
MS
890 class id_tab {
891 public:
3d2cf79f
RB
892 const char *id;
893 const char *oper;
894 id_tab (const char *id_, const char *oper_): id (id_), oper (oper_) {}
895 };
896
620e594b 897 c_expr (cpp_reader *r_, location_t loc,
0889c52f 898 vec<cpp_token> code_, unsigned nr_stmts_,
f1308e4b 899 vec<id_tab> ids_, cid_map_t *capture_ids_)
0889c52f
RB
900 : operand (OP_C_EXPR, loc), r (r_), code (code_),
901 capture_ids (capture_ids_), nr_stmts (nr_stmts_), ids (ids_) {}
3d2cf79f
RB
902 /* cpplib tokens and state to transform this back to source. */
903 cpp_reader *r;
904 vec<cpp_token> code;
f1308e4b 905 cid_map_t *capture_ids;
3d2cf79f
RB
906 /* The number of statements parsed (well, the number of ';'s). */
907 unsigned nr_stmts;
908 /* The identifier replacement vector. */
909 vec<id_tab> ids;
26f77c4d
DM
910 void gen_transform (FILE *f, int, const char *, bool, int,
911 const char *, capture_info *,
912 dt_operand ** = 0, int = 0) final override;
3d2cf79f
RB
913};
914
915/* A wrapper around another operand that captures its value. */
916
6c1dae73 917class capture : public operand
3d2cf79f 918{
6c1dae73 919public:
620e594b 920 capture (location_t loc, unsigned where_, operand *what_, bool value_)
2eef1fc1
RB
921 : operand (OP_CAPTURE, loc), where (where_), value_match (value_),
922 what (what_) {}
3d2cf79f
RB
923 /* Identifier index for the value. */
924 unsigned where;
2eef1fc1
RB
925 /* Whether in a match of two operands the compare should be for
926 equal values rather than equal atoms (boils down to a type
927 check or not). */
928 bool value_match;
3d2cf79f
RB
929 /* The captured value. */
930 operand *what;
26f77c4d
DM
931 void gen_transform (FILE *f, int, const char *, bool, int,
932 const char *, capture_info *,
933 dt_operand ** = 0, int = 0) final override;
3d2cf79f
RB
934};
935
8fdc6c67
RB
936/* if expression. */
937
6c1dae73 938class if_expr : public operand
8fdc6c67 939{
6c1dae73 940public:
620e594b 941 if_expr (location_t loc)
0889c52f 942 : operand (OP_IF, loc), cond (NULL), trueexpr (NULL), falseexpr (NULL) {}
8fdc6c67
RB
943 c_expr *cond;
944 operand *trueexpr;
945 operand *falseexpr;
946};
947
948/* with expression. */
949
6c1dae73 950class with_expr : public operand
8fdc6c67 951{
6c1dae73 952public:
620e594b 953 with_expr (location_t loc)
0889c52f 954 : operand (OP_WITH, loc), with (NULL), subexpr (NULL) {}
8fdc6c67
RB
955 c_expr *with;
956 operand *subexpr;
957};
958
3d2cf79f
RB
959template<>
960template<>
961inline bool
962is_a_helper <capture *>::test (operand *op)
963{
964 return op->type == operand::OP_CAPTURE;
965}
966
967template<>
968template<>
969inline bool
970is_a_helper <predicate *>::test (operand *op)
971{
972 return op->type == operand::OP_PREDICATE;
973}
974
975template<>
976template<>
977inline bool
978is_a_helper <c_expr *>::test (operand *op)
979{
980 return op->type == operand::OP_C_EXPR;
981}
982
983template<>
984template<>
985inline bool
986is_a_helper <expr *>::test (operand *op)
987{
988 return op->type == operand::OP_EXPR;
989}
990
8fdc6c67
RB
991template<>
992template<>
993inline bool
994is_a_helper <if_expr *>::test (operand *op)
995{
996 return op->type == operand::OP_IF;
997}
3d2cf79f 998
8fdc6c67
RB
999template<>
1000template<>
1001inline bool
1002is_a_helper <with_expr *>::test (operand *op)
3d2cf79f 1003{
8fdc6c67
RB
1004 return op->type == operand::OP_WITH;
1005}
3d2cf79f
RB
1006
1007/* The main class of a pattern and its transform. This is used to
1008 represent both (simplify ...) and (match ...) kinds. The AST
1009 duplicates all outer 'if' and 'for' expressions here so each
1010 simplify can exist in isolation. */
1011
6c1dae73 1012class simplify
3d2cf79f 1013{
6c1dae73 1014public:
8fdc6c67
RB
1015 enum simplify_kind { SIMPLIFY, MATCH };
1016
6c35e5b0
RB
1017 simplify (simplify_kind kind_, unsigned id_, operand *match_,
1018 operand *result_, vec<vec<user_id *> > for_vec_,
1019 cid_map_t *capture_ids_)
1020 : kind (kind_), id (id_), match (match_), result (result_),
d4b71b95 1021 for_vec (for_vec_), for_subst_vec (vNULL),
f1308e4b 1022 capture_ids (capture_ids_), capture_max (capture_ids_->elements () - 1) {}
3d2cf79f 1023
8fdc6c67 1024 simplify_kind kind;
6c35e5b0
RB
1025 /* ID. This is kept to easily associate related simplifies expanded
1026 from the same original one. */
1027 unsigned id;
3d2cf79f
RB
1028 /* The expression that is matched against the GENERIC or GIMPLE IL. */
1029 operand *match;
8fdc6c67
RB
1030 /* For a (simplify ...) an expression with ifs and withs with the expression
1031 produced when the pattern applies in the leafs.
1032 For a (match ...) the leafs are either empty if it is a simple predicate
1033 or the single expression specifying the matched operands. */
99b1c316 1034 class operand *result;
3d2cf79f
RB
1035 /* Collected 'for' expression operators that have to be replaced
1036 in the lowering phase. */
1037 vec<vec<user_id *> > for_vec;
d4b71b95 1038 vec<std::pair<user_id *, id_base *> > for_subst_vec;
3d2cf79f 1039 /* A map of capture identifiers to indexes. */
f1308e4b 1040 cid_map_t *capture_ids;
3d2cf79f
RB
1041 int capture_max;
1042};
1043
1044/* Debugging routines for dumping the AST. */
1045
1046DEBUG_FUNCTION void
1047print_operand (operand *o, FILE *f = stderr, bool flattened = false)
1048{
1049 if (capture *c = dyn_cast<capture *> (o))
1050 {
3d2cf79f 1051 if (c->what && flattened == false)
eee7b6c4
RB
1052 print_operand (c->what, f, flattened);
1053 fprintf (f, "@%u", c->where);
3d2cf79f
RB
1054 }
1055
1056 else if (predicate *p = dyn_cast<predicate *> (o))
1057 fprintf (f, "%s", p->p->id);
1058
1059 else if (is_a<c_expr *> (o))
1060 fprintf (f, "c_expr");
1061
1062 else if (expr *e = dyn_cast<expr *> (o))
1063 {
eee7b6c4
RB
1064 if (e->ops.length () == 0)
1065 fprintf (f, "%s", e->operation->id);
1066 else
3d2cf79f 1067 {
eee7b6c4
RB
1068 fprintf (f, "(%s", e->operation->id);
1069
1070 if (flattened == false)
3d2cf79f 1071 {
eee7b6c4
RB
1072 for (unsigned i = 0; i < e->ops.length (); ++i)
1073 {
1074 putc (' ', f);
1075 print_operand (e->ops[i], f, flattened);
1076 }
3d2cf79f 1077 }
eee7b6c4 1078 putc (')', f);
3d2cf79f 1079 }
3d2cf79f
RB
1080 }
1081
1082 else
1083 gcc_unreachable ();
1084}
1085
1086DEBUG_FUNCTION void
99b1c316 1087print_matches (class simplify *s, FILE *f = stderr)
3d2cf79f
RB
1088{
1089 fprintf (f, "for expression: ");
1090 print_operand (s->match, f);
1091 putc ('\n', f);
1092}
1093
1094
1095/* AST lowering. */
1096
1097/* Lowering of commutative operators. */
1098
1099static void
1100cartesian_product (const vec< vec<operand *> >& ops_vector,
1101 vec< vec<operand *> >& result, vec<operand *>& v, unsigned n)
1102{
1103 if (n == ops_vector.length ())
1104 {
1105 vec<operand *> xv = v.copy ();
1106 result.safe_push (xv);
1107 return;
1108 }
1109
1110 for (unsigned i = 0; i < ops_vector[n].length (); ++i)
1111 {
1112 v[n] = ops_vector[n][i];
1113 cartesian_product (ops_vector, result, v, n + 1);
1114 }
1115}
1116
1117/* Lower OP to two operands in case it is marked as commutative. */
1118
1119static vec<operand *>
e04d2a35 1120commutate (operand *op, vec<vec<user_id *> > &for_vec)
3d2cf79f
RB
1121{
1122 vec<operand *> ret = vNULL;
1123
1124 if (capture *c = dyn_cast <capture *> (op))
1125 {
1126 if (!c->what)
1127 {
1128 ret.safe_push (op);
1129 return ret;
1130 }
e04d2a35 1131 vec<operand *> v = commutate (c->what, for_vec);
3d2cf79f
RB
1132 for (unsigned i = 0; i < v.length (); ++i)
1133 {
2eef1fc1
RB
1134 capture *nc = new capture (c->location, c->where, v[i],
1135 c->value_match);
3d2cf79f
RB
1136 ret.safe_push (nc);
1137 }
1138 return ret;
1139 }
1140
1141 expr *e = dyn_cast <expr *> (op);
1142 if (!e || e->ops.length () == 0)
1143 {
1144 ret.safe_push (op);
1145 return ret;
1146 }
1147
1148 vec< vec<operand *> > ops_vector = vNULL;
1149 for (unsigned i = 0; i < e->ops.length (); ++i)
e04d2a35 1150 ops_vector.safe_push (commutate (e->ops[i], for_vec));
3d2cf79f
RB
1151
1152 auto_vec< vec<operand *> > result;
1153 auto_vec<operand *> v (e->ops.length ());
1154 v.quick_grow_cleared (e->ops.length ());
1155 cartesian_product (ops_vector, result, v, 0);
1156
1157
1158 for (unsigned i = 0; i < result.length (); ++i)
1159 {
44fc0a51
RB
1160 expr *ne = new expr (e);
1161 ne->is_commutative = false;
3d2cf79f
RB
1162 for (unsigned j = 0; j < result[i].length (); ++j)
1163 ne->append_op (result[i][j]);
1164 ret.safe_push (ne);
1165 }
1166
1167 if (!e->is_commutative)
1168 return ret;
1169
c566cc9f
RS
1170 /* The operation is always binary if it isn't inherently commutative. */
1171 int natural_opno = commutative_op (e->operation);
1172 unsigned int opno = natural_opno >= 0 ? natural_opno : 0;
3d2cf79f
RB
1173 for (unsigned i = 0; i < result.length (); ++i)
1174 {
44fc0a51 1175 expr *ne = new expr (e);
4e4791ff 1176 if (operator_id *r = dyn_cast <operator_id *> (ne->operation))
e04d2a35 1177 {
4e4791ff
BE
1178 if (comparison_code_p (r->code))
1179 ne->operation = swap_tree_comparison (r);
e04d2a35
RB
1180 }
1181 else if (user_id *p = dyn_cast <user_id *> (ne->operation))
1182 {
1183 bool found_compare = false;
1184 for (unsigned j = 0; j < p->substitutes.length (); ++j)
1185 if (operator_id *q = dyn_cast <operator_id *> (p->substitutes[j]))
1186 {
1187 if (comparison_code_p (q->code)
1188 && swap_tree_comparison (q) != q)
1189 {
1190 found_compare = true;
1191 break;
1192 }
1193 }
1194 if (found_compare)
1195 {
1196 user_id *newop = new user_id ("<internal>");
1197 for (unsigned j = 0; j < p->substitutes.length (); ++j)
1198 {
1199 id_base *subst = p->substitutes[j];
1200 if (operator_id *q = dyn_cast <operator_id *> (subst))
1201 {
1202 if (comparison_code_p (q->code))
1203 subst = swap_tree_comparison (q);
1204 }
1205 newop->substitutes.safe_push (subst);
1206 }
1207 ne->operation = newop;
1208 /* Search for 'p' inside the for vector and push 'newop'
1209 to the same level. */
1210 for (unsigned j = 0; newop && j < for_vec.length (); ++j)
1211 for (unsigned k = 0; k < for_vec[j].length (); ++k)
1212 if (for_vec[j][k] == p)
1213 {
1214 for_vec[j].safe_push (newop);
1215 newop = NULL;
1216 break;
1217 }
1218 }
1219 }
44fc0a51 1220 ne->is_commutative = false;
c566cc9f
RS
1221 for (unsigned j = 0; j < result[i].length (); ++j)
1222 {
1223 int old_j = (j == opno ? opno + 1 : j == opno + 1 ? opno : j);
1224 ne->append_op (result[i][old_j]);
1225 }
3d2cf79f
RB
1226 ret.safe_push (ne);
1227 }
1228
1229 return ret;
1230}
1231
1232/* Lower operations marked as commutative in the AST of S and push
1233 the resulting patterns to SIMPLIFIERS. */
1234
1235static void
1236lower_commutative (simplify *s, vec<simplify *>& simplifiers)
1237{
e04d2a35 1238 vec<operand *> matchers = commutate (s->match, s->for_vec);
3d2cf79f
RB
1239 for (unsigned i = 0; i < matchers.length (); ++i)
1240 {
6c35e5b0 1241 simplify *ns = new simplify (s->kind, s->id, matchers[i], s->result,
3d2cf79f
RB
1242 s->for_vec, s->capture_ids);
1243 simplifiers.safe_push (ns);
1244 }
1245}
1246
28fabd43
RB
1247/* Strip conditional operations using group GRP from O and its
1248 children if STRIP, else replace them with an unconditional operation. */
3d2cf79f
RB
1249
1250operand *
28fabd43 1251lower_opt (operand *o, unsigned char grp, bool strip)
3d2cf79f
RB
1252{
1253 if (capture *c = dyn_cast<capture *> (o))
1254 {
1255 if (c->what)
0889c52f 1256 return new capture (c->location, c->where,
28fabd43 1257 lower_opt (c->what, grp, strip),
2eef1fc1 1258 c->value_match);
3d2cf79f
RB
1259 else
1260 return c;
1261 }
1262
1263 expr *e = dyn_cast<expr *> (o);
1264 if (!e)
1265 return o;
1266
28fabd43 1267 if (e->opt_grp == grp)
3d2cf79f
RB
1268 {
1269 if (strip)
28fabd43 1270 return lower_opt (e->ops[0], grp, strip);
3d2cf79f 1271
44fc0a51 1272 expr *ne = new expr (e);
28fabd43
RB
1273 ne->opt_grp = 0;
1274 ne->append_op (lower_opt (e->ops[0], grp, strip));
3d2cf79f
RB
1275 return ne;
1276 }
1277
44fc0a51 1278 expr *ne = new expr (e);
3d2cf79f 1279 for (unsigned i = 0; i < e->ops.length (); ++i)
28fabd43 1280 ne->append_op (lower_opt (e->ops[i], grp, strip));
3d2cf79f
RB
1281
1282 return ne;
1283}
1284
28fabd43
RB
1285/* Determine whether O or its children uses the conditional operation
1286 group GRP. */
3d2cf79f
RB
1287
1288static bool
28fabd43 1289has_opt (operand *o, unsigned char grp)
3d2cf79f
RB
1290{
1291 if (capture *c = dyn_cast<capture *> (o))
1292 {
1293 if (c->what)
28fabd43 1294 return has_opt (c->what, grp);
3d2cf79f
RB
1295 else
1296 return false;
1297 }
1298
1299 expr *e = dyn_cast<expr *> (o);
1300 if (!e)
1301 return false;
1302
28fabd43 1303 if (e->opt_grp == grp)
3d2cf79f
RB
1304 return true;
1305
1306 for (unsigned i = 0; i < e->ops.length (); ++i)
28fabd43 1307 if (has_opt (e->ops[i], grp))
3d2cf79f
RB
1308 return true;
1309
1310 return false;
1311}
1312
1313/* Lower conditional convert operators in O, expanding it to a vector
1314 if required. */
1315
1316static vec<operand *>
28fabd43 1317lower_opt (operand *o)
3d2cf79f
RB
1318{
1319 vec<operand *> v1 = vNULL, v2;
1320
1321 v1.safe_push (o);
1322
28fabd43
RB
1323 /* Conditional operations are lowered to a pattern with the
1324 operation and one without. All different conditional operation
1325 groups are lowered separately. */
3d2cf79f 1326
28fabd43 1327 for (unsigned i = 1; i <= 10; ++i)
3d2cf79f
RB
1328 {
1329 v2 = vNULL;
1330 for (unsigned j = 0; j < v1.length (); ++j)
28fabd43 1331 if (has_opt (v1[j], i))
3d2cf79f 1332 {
28fabd43
RB
1333 v2.safe_push (lower_opt (v1[j], i, false));
1334 v2.safe_push (lower_opt (v1[j], i, true));
3d2cf79f
RB
1335 }
1336
1337 if (v2 != vNULL)
1338 {
1339 v1 = vNULL;
1340 for (unsigned j = 0; j < v2.length (); ++j)
1341 v1.safe_push (v2[j]);
1342 }
1343 }
1344
1345 return v1;
1346}
1347
1348/* Lower conditional convert operators in the AST of S and push
1349 the resulting multiple patterns to SIMPLIFIERS. */
1350
1351static void
28fabd43 1352lower_opt (simplify *s, vec<simplify *>& simplifiers)
3d2cf79f 1353{
28fabd43 1354 vec<operand *> matchers = lower_opt (s->match);
3d2cf79f
RB
1355 for (unsigned i = 0; i < matchers.length (); ++i)
1356 {
6c35e5b0 1357 simplify *ns = new simplify (s->kind, s->id, matchers[i], s->result,
3d2cf79f
RB
1358 s->for_vec, s->capture_ids);
1359 simplifiers.safe_push (ns);
1360 }
1361}
1362
35b2be21 1363/* Lower the compare operand of COND_EXPRs to a
47b25362
RB
1364 GENERIC and a GIMPLE variant. */
1365
1366static vec<operand *>
1367lower_cond (operand *o)
1368{
1369 vec<operand *> ro = vNULL;
1370
1371 if (capture *c = dyn_cast<capture *> (o))
1372 {
1373 if (c->what)
1374 {
1375 vec<operand *> lop = vNULL;
1376 lop = lower_cond (c->what);
1377
1378 for (unsigned i = 0; i < lop.length (); ++i)
2eef1fc1
RB
1379 ro.safe_push (new capture (c->location, c->where, lop[i],
1380 c->value_match));
47b25362
RB
1381 return ro;
1382 }
1383 }
1384
1385 expr *e = dyn_cast<expr *> (o);
1386 if (!e || e->ops.length () == 0)
1387 {
1388 ro.safe_push (o);
1389 return ro;
1390 }
1391
1392 vec< vec<operand *> > ops_vector = vNULL;
1393 for (unsigned i = 0; i < e->ops.length (); ++i)
1394 ops_vector.safe_push (lower_cond (e->ops[i]));
1395
1396 auto_vec< vec<operand *> > result;
1397 auto_vec<operand *> v (e->ops.length ());
1398 v.quick_grow_cleared (e->ops.length ());
1399 cartesian_product (ops_vector, result, v, 0);
1400
1401 for (unsigned i = 0; i < result.length (); ++i)
1402 {
44fc0a51 1403 expr *ne = new expr (e);
47b25362
RB
1404 for (unsigned j = 0; j < result[i].length (); ++j)
1405 ne->append_op (result[i][j]);
1406 ro.safe_push (ne);
1407 /* If this is a COND with a captured expression or an
1408 expression with two operands then also match a GENERIC
1409 form on the compare. */
35b2be21 1410 if (*e->operation == COND_EXPR
47b25362
RB
1411 && ((is_a <capture *> (e->ops[0])
1412 && as_a <capture *> (e->ops[0])->what
1413 && is_a <expr *> (as_a <capture *> (e->ops[0])->what)
1414 && as_a <expr *>
1415 (as_a <capture *> (e->ops[0])->what)->ops.length () == 2)
1416 || (is_a <expr *> (e->ops[0])
1417 && as_a <expr *> (e->ops[0])->ops.length () == 2)))
1418 {
4e4791ff 1419 ne = new expr (e);
47b25362
RB
1420 for (unsigned j = 0; j < result[i].length (); ++j)
1421 ne->append_op (result[i][j]);
1422 if (capture *c = dyn_cast <capture *> (ne->ops[0]))
1423 {
1424 expr *ocmp = as_a <expr *> (c->what);
44fc0a51 1425 expr *cmp = new expr (ocmp);
47b25362
RB
1426 for (unsigned j = 0; j < ocmp->ops.length (); ++j)
1427 cmp->append_op (ocmp->ops[j]);
1428 cmp->is_generic = true;
2eef1fc1
RB
1429 ne->ops[0] = new capture (c->location, c->where, cmp,
1430 c->value_match);
47b25362
RB
1431 }
1432 else
1433 {
1434 expr *ocmp = as_a <expr *> (ne->ops[0]);
44fc0a51 1435 expr *cmp = new expr (ocmp);
47b25362
RB
1436 for (unsigned j = 0; j < ocmp->ops.length (); ++j)
1437 cmp->append_op (ocmp->ops[j]);
1438 cmp->is_generic = true;
1439 ne->ops[0] = cmp;
1440 }
1441 ro.safe_push (ne);
1442 }
1443 }
1444
1445 return ro;
1446}
1447
35b2be21 1448/* Lower the compare operand of COND_EXPRs to a
47b25362
RB
1449 GENERIC and a GIMPLE variant. */
1450
1451static void
1452lower_cond (simplify *s, vec<simplify *>& simplifiers)
1453{
1454 vec<operand *> matchers = lower_cond (s->match);
1455 for (unsigned i = 0; i < matchers.length (); ++i)
1456 {
6c35e5b0 1457 simplify *ns = new simplify (s->kind, s->id, matchers[i], s->result,
47b25362 1458 s->for_vec, s->capture_ids);
2afe8828 1459 ns->for_subst_vec.safe_splice (s->for_subst_vec);
47b25362
RB
1460 simplifiers.safe_push (ns);
1461 }
1462}
1463
fa74b47a
RS
1464/* Return true if O refers to ID. */
1465
1466bool
1467contains_id (operand *o, user_id *id)
1468{
1469 if (capture *c = dyn_cast<capture *> (o))
1470 return c->what && contains_id (c->what, id);
1471
1472 if (expr *e = dyn_cast<expr *> (o))
1473 {
1474 if (e->operation == id)
1475 return true;
1476 for (unsigned i = 0; i < e->ops.length (); ++i)
1477 if (contains_id (e->ops[i], id))
1478 return true;
1479 return false;
1480 }
1481
1482 if (with_expr *w = dyn_cast <with_expr *> (o))
1483 return (contains_id (w->with, id)
1484 || contains_id (w->subexpr, id));
1485
1486 if (if_expr *ife = dyn_cast <if_expr *> (o))
1487 return (contains_id (ife->cond, id)
1488 || contains_id (ife->trueexpr, id)
1489 || (ife->falseexpr && contains_id (ife->falseexpr, id)));
1490
1491 if (c_expr *ce = dyn_cast<c_expr *> (o))
1492 return ce->capture_ids && ce->capture_ids->get (id->id);
1493
1494 return false;
1495}
1496
1497
3d2cf79f
RB
1498/* In AST operand O replace operator ID with operator WITH. */
1499
1500operand *
1501replace_id (operand *o, user_id *id, id_base *with)
1502{
1503 /* Deep-copy captures and expressions, replacing operations as
1504 needed. */
1505 if (capture *c = dyn_cast<capture *> (o))
1506 {
1507 if (!c->what)
1508 return c;
0889c52f 1509 return new capture (c->location, c->where,
2eef1fc1 1510 replace_id (c->what, id, with), c->value_match);
3d2cf79f
RB
1511 }
1512 else if (expr *e = dyn_cast<expr *> (o))
1513 {
44fc0a51
RB
1514 expr *ne = new expr (e);
1515 if (e->operation == id)
1516 ne->operation = with;
3d2cf79f
RB
1517 for (unsigned i = 0; i < e->ops.length (); ++i)
1518 ne->append_op (replace_id (e->ops[i], id, with));
1519 return ne;
1520 }
8fdc6c67
RB
1521 else if (with_expr *w = dyn_cast <with_expr *> (o))
1522 {
0889c52f 1523 with_expr *nw = new with_expr (w->location);
8fdc6c67
RB
1524 nw->with = as_a <c_expr *> (replace_id (w->with, id, with));
1525 nw->subexpr = replace_id (w->subexpr, id, with);
1526 return nw;
1527 }
1528 else if (if_expr *ife = dyn_cast <if_expr *> (o))
1529 {
0889c52f 1530 if_expr *nife = new if_expr (ife->location);
8fdc6c67
RB
1531 nife->cond = as_a <c_expr *> (replace_id (ife->cond, id, with));
1532 nife->trueexpr = replace_id (ife->trueexpr, id, with);
1533 if (ife->falseexpr)
1534 nife->falseexpr = replace_id (ife->falseexpr, id, with);
1535 return nife;
1536 }
3d2cf79f
RB
1537
1538 /* For c_expr we simply record a string replacement table which is
1539 applied at code-generation time. */
1540 if (c_expr *ce = dyn_cast<c_expr *> (o))
1541 {
1542 vec<c_expr::id_tab> ids = ce->ids.copy ();
1543 ids.safe_push (c_expr::id_tab (id->id, with->id));
0889c52f
RB
1544 return new c_expr (ce->r, ce->location,
1545 ce->code, ce->nr_stmts, ids, ce->capture_ids);
3d2cf79f
RB
1546 }
1547
1548 return o;
1549}
1550
d4b71b95
RB
1551/* Return true if the binary operator OP is ok for delayed substitution
1552 during for lowering. */
1553
1554static bool
1555binary_ok (operator_id *op)
1556{
1557 switch (op->code)
1558 {
1559 case PLUS_EXPR:
1560 case MINUS_EXPR:
1561 case MULT_EXPR:
1562 case TRUNC_DIV_EXPR:
1563 case CEIL_DIV_EXPR:
1564 case FLOOR_DIV_EXPR:
1565 case ROUND_DIV_EXPR:
1566 case TRUNC_MOD_EXPR:
1567 case CEIL_MOD_EXPR:
1568 case FLOOR_MOD_EXPR:
1569 case ROUND_MOD_EXPR:
1570 case RDIV_EXPR:
1571 case EXACT_DIV_EXPR:
1572 case MIN_EXPR:
1573 case MAX_EXPR:
1574 case BIT_IOR_EXPR:
1575 case BIT_XOR_EXPR:
1576 case BIT_AND_EXPR:
1577 return true;
1578 default:
1579 return false;
1580 }
1581}
1582
3d2cf79f
RB
1583/* Lower recorded fors for SIN and output to SIMPLIFIERS. */
1584
1585static void
1586lower_for (simplify *sin, vec<simplify *>& simplifiers)
1587{
1588 vec<vec<user_id *> >& for_vec = sin->for_vec;
1589 unsigned worklist_start = 0;
1590 auto_vec<simplify *> worklist;
1591 worklist.safe_push (sin);
1592
1593 /* Lower each recorded for separately, operating on the
1594 set of simplifiers created by the previous one.
1595 Lower inner-to-outer so inner for substitutes can refer
1596 to operators replaced by outer fors. */
1597 for (int fi = for_vec.length () - 1; fi >= 0; --fi)
1598 {
1599 vec<user_id *>& ids = for_vec[fi];
1600 unsigned n_ids = ids.length ();
1601 unsigned max_n_opers = 0;
75cda3be 1602 bool can_delay_subst = true;
3d2cf79f 1603 for (unsigned i = 0; i < n_ids; ++i)
d4b71b95
RB
1604 {
1605 if (ids[i]->substitutes.length () > max_n_opers)
1606 max_n_opers = ids[i]->substitutes.length ();
1607 /* Require that all substitutes are of the same kind so that
1608 if we delay substitution to the result op code generation
1609 can look at the first substitute for deciding things like
1610 types of operands. */
1611 enum id_base::id_kind kind = ids[i]->substitutes[0]->kind;
1612 for (unsigned j = 0; j < ids[i]->substitutes.length (); ++j)
1613 if (ids[i]->substitutes[j]->kind != kind)
1614 can_delay_subst = false;
1615 else if (operator_id *op
1616 = dyn_cast <operator_id *> (ids[i]->substitutes[j]))
1617 {
1618 operator_id *op0
1619 = as_a <operator_id *> (ids[i]->substitutes[0]);
1620 if (strcmp (op->tcc, "tcc_comparison") == 0
1621 && strcmp (op0->tcc, "tcc_comparison") == 0)
1622 ;
1623 /* Unfortunately we can't just allow all tcc_binary. */
1624 else if (strcmp (op->tcc, "tcc_binary") == 0
1625 && strcmp (op0->tcc, "tcc_binary") == 0
1626 && binary_ok (op)
1627 && binary_ok (op0))
1628 ;
1629 else if ((strcmp (op->id + 1, "SHIFT_EXPR") == 0
1630 || strcmp (op->id + 1, "ROTATE_EXPR") == 0)
1631 && (strcmp (op0->id + 1, "SHIFT_EXPR") == 0
1632 || strcmp (op0->id + 1, "ROTATE_EXPR") == 0))
1633 ;
1634 else
1635 can_delay_subst = false;
1636 }
1637 else if (is_a <fn_id *> (ids[i]->substitutes[j]))
1638 ;
1639 else
1640 can_delay_subst = false;
1641 }
75cda3be
RB
1642 if (sin->kind == simplify::MATCH
1643 && can_delay_subst)
1644 continue;
3d2cf79f
RB
1645
1646 unsigned worklist_end = worklist.length ();
1647 for (unsigned si = worklist_start; si < worklist_end; ++si)
1648 {
1649 simplify *s = worklist[si];
1650 for (unsigned j = 0; j < max_n_opers; ++j)
1651 {
1652 operand *match_op = s->match;
1653 operand *result_op = s->result;
8c681247 1654 auto_vec<std::pair<user_id *, id_base *> > subst (n_ids);
fa74b47a 1655 bool skip = false;
3d2cf79f
RB
1656 for (unsigned i = 0; i < n_ids; ++i)
1657 {
1658 user_id *id = ids[i];
1659 id_base *oper = id->substitutes[j % id->substitutes.length ()];
fa74b47a
RS
1660 if (oper == null_id
1661 && (contains_id (match_op, id)
1662 || contains_id (result_op, id)))
1663 {
1664 skip = true;
1665 break;
1666 }
d4b71b95 1667 subst.quick_push (std::make_pair (id, oper));
75cda3be
RB
1668 if (sin->kind == simplify::SIMPLIFY
1669 || !can_delay_subst)
1670 match_op = replace_id (match_op, id, oper);
d4b71b95
RB
1671 if (result_op
1672 && !can_delay_subst)
3d2cf79f 1673 result_op = replace_id (result_op, id, oper);
3d2cf79f 1674 }
fa74b47a 1675 if (skip)
8c681247
TS
1676 continue;
1677
6c35e5b0 1678 simplify *ns = new simplify (s->kind, s->id, match_op, result_op,
8fdc6c67 1679 vNULL, s->capture_ids);
d4b71b95
RB
1680 ns->for_subst_vec.safe_splice (s->for_subst_vec);
1681 if (result_op
1682 && can_delay_subst)
1683 ns->for_subst_vec.safe_splice (subst);
8c681247 1684
3d2cf79f
RB
1685 worklist.safe_push (ns);
1686 }
1687 }
1688 worklist_start = worklist_end;
1689 }
1690
1691 /* Copy out the result from the last for lowering. */
1692 for (unsigned i = worklist_start; i < worklist.length (); ++i)
1693 simplifiers.safe_push (worklist[i]);
1694}
1695
1696/* Lower the AST for everything in SIMPLIFIERS. */
1697
1698static void
47b25362 1699lower (vec<simplify *>& simplifiers, bool gimple)
3d2cf79f 1700{
47b25362 1701 auto_vec<simplify *> out_simplifiers;
2afe8828
AP
1702 for (auto s: simplifiers)
1703 lower_opt (s, out_simplifiers);
47b25362
RB
1704
1705 simplifiers.truncate (0);
2afe8828
AP
1706 for (auto s: out_simplifiers)
1707 lower_commutative (s, simplifiers);
47b25362 1708
2afe8828
AP
1709 /* Lower for needs to happen before lowering cond
1710 to support (for cnd (cond vec_cond)). This is
1711 safe as substitution delay does not happen for
1712 cond or vec_cond. */
47b25362 1713 out_simplifiers.truncate (0);
2afe8828
AP
1714 for (auto s: simplifiers)
1715 lower_for (s, out_simplifiers);
3d2cf79f
RB
1716
1717 simplifiers.truncate (0);
2afe8828
AP
1718 if (gimple)
1719 for (auto s: out_simplifiers)
1720 lower_cond (s, simplifiers);
1721 else
1722 simplifiers.safe_splice (out_simplifiers);
3d2cf79f
RB
1723}
1724
1725
1726
1727
1728/* The decision tree built for generating GIMPLE and GENERIC pattern
1729 matching code. It represents the 'match' expression of all
1730 simplifies and has those as its leafs. */
1731
99b1c316 1732class dt_simplify;
03038b8b
RB
1733
1734/* A hash-map collecting semantically equivalent leafs in the decision
1735 tree for splitting out to separate functions. */
1736struct sinfo
1737{
1738 dt_simplify *s;
1739
1740 const char *fname;
1741 unsigned cnt;
1742};
1743
76b6ddbf
TS
1744struct sinfo_hashmap_traits : simple_hashmap_traits<pointer_hash<dt_simplify>,
1745 sinfo *>
03038b8b
RB
1746{
1747 static inline hashval_t hash (const key_type &);
1748 static inline bool equal_keys (const key_type &, const key_type &);
1749 template <typename T> static inline void remove (T &) {}
1750};
1751
e6b616c0 1752typedef ordered_hash_map<void * /* unused */, sinfo *, sinfo_hashmap_traits>
03038b8b
RB
1753 sinfo_map_t;
1754
6c35e5b0
RB
1755/* Current simplifier ID we are processing during insertion into the
1756 decision tree. */
1757static unsigned current_id;
03038b8b 1758
6c35e5b0 1759/* Decision tree base class, used for DT_NODE. */
3d2cf79f 1760
6c1dae73 1761class dt_node
3d2cf79f 1762{
6c1dae73 1763public:
3d2cf79f
RB
1764 enum dt_type { DT_NODE, DT_OPERAND, DT_TRUE, DT_MATCH, DT_SIMPLIFY };
1765
1766 enum dt_type type;
1767 unsigned level;
6c35e5b0 1768 dt_node *parent;
3d2cf79f
RB
1769 vec<dt_node *> kids;
1770
803835de
RB
1771 /* Statistics. */
1772 unsigned num_leafs;
1773 unsigned total_size;
1774 unsigned max_level;
1775
6c35e5b0
RB
1776 dt_node (enum dt_type type_, dt_node *parent_)
1777 : type (type_), level (0), parent (parent_), kids (vNULL) {}
3d2cf79f
RB
1778
1779 dt_node *append_node (dt_node *);
6c35e5b0
RB
1780 dt_node *append_op (operand *, dt_node *parent, unsigned pos);
1781 dt_node *append_true_op (operand *, dt_node *parent, unsigned pos);
1782 dt_node *append_match_op (operand *, dt_operand *, dt_node *parent,
1783 unsigned pos);
3d2cf79f
RB
1784 dt_node *append_simplify (simplify *, unsigned, dt_operand **);
1785
4e4791ff 1786 virtual void gen (FILE *, int, bool, int) {}
3d2cf79f 1787
4e4791ff
BE
1788 void gen_kids (FILE *, int, bool, int);
1789 void gen_kids_1 (FILE *, int, bool, int,
00dcc88a
MS
1790 const vec<dt_operand *> &, const vec<dt_operand *> &,
1791 const vec<dt_operand *> &, const vec<dt_operand *> &,
1792 const vec<dt_operand *> &, const vec<dt_node *> &);
803835de 1793
03038b8b 1794 void analyze (sinfo_map_t &);
3d2cf79f
RB
1795};
1796
6c35e5b0 1797/* Generic decision tree node used for DT_OPERAND, DT_MATCH and DT_TRUE. */
3d2cf79f 1798
6c1dae73 1799class dt_operand : public dt_node
3d2cf79f 1800{
6c1dae73 1801public:
3d2cf79f
RB
1802 operand *op;
1803 dt_operand *match_dop;
3d2cf79f 1804 unsigned pos;
2eef1fc1 1805 bool value_match;
6c35e5b0 1806 unsigned for_id;
3d2cf79f
RB
1807
1808 dt_operand (enum dt_type type, operand *op_, dt_operand *match_dop_,
6c35e5b0
RB
1809 dt_operand *parent_, unsigned pos_)
1810 : dt_node (type, parent_), op (op_), match_dop (match_dop_),
1811 pos (pos_), value_match (false), for_id (current_id) {}
3d2cf79f 1812
26f77c4d 1813 void gen (FILE *, int, bool, int) final override;
c551c21d 1814 unsigned gen_predicate (FILE *, int, const char *, bool);
39bb7d01 1815 unsigned gen_match_op (FILE *, int, const char *, bool);
3d2cf79f 1816
4e4791ff 1817 unsigned gen_gimple_expr (FILE *, int, int);
c551c21d 1818 unsigned gen_generic_expr (FILE *, int, const char *);
3d2cf79f
RB
1819
1820 char *get_name (char *);
1821 void gen_opname (char *, unsigned);
1822};
1823
1824/* Leaf node of the decision tree, used for DT_SIMPLIFY. */
1825
6c1dae73 1826class dt_simplify : public dt_node
3d2cf79f 1827{
6c1dae73 1828public:
3d2cf79f
RB
1829 simplify *s;
1830 unsigned pattern_no;
1831 dt_operand **indexes;
03038b8b 1832 sinfo *info;
3d2cf79f
RB
1833
1834 dt_simplify (simplify *s_, unsigned pattern_no_, dt_operand **indexes_)
6c35e5b0 1835 : dt_node (DT_SIMPLIFY, NULL), s (s_), pattern_no (pattern_no_),
03038b8b 1836 indexes (indexes_), info (NULL) {}
3d2cf79f 1837
8fdc6c67 1838 void gen_1 (FILE *, int, bool, operand *);
26f77c4d 1839 void gen (FILE *f, int, bool, int) final override;
3d2cf79f
RB
1840};
1841
1842template<>
1843template<>
1844inline bool
1845is_a_helper <dt_operand *>::test (dt_node *n)
1846{
1847 return (n->type == dt_node::DT_OPERAND
6c35e5b0
RB
1848 || n->type == dt_node::DT_MATCH
1849 || n->type == dt_node::DT_TRUE);
3d2cf79f
RB
1850}
1851
03038b8b
RB
1852template<>
1853template<>
1854inline bool
1855is_a_helper <dt_simplify *>::test (dt_node *n)
1856{
1857 return n->type == dt_node::DT_SIMPLIFY;
1858}
1859
1860
1861
3d2cf79f
RB
1862/* A container for the actual decision tree. */
1863
6c1dae73 1864class decision_tree
3d2cf79f 1865{
6c1dae73 1866public:
3d2cf79f
RB
1867 dt_node *root;
1868
99b1c316 1869 void insert (class simplify *, unsigned);
703417a0 1870 void gen (vec <FILE *> &f, bool gimple);
3d2cf79f
RB
1871 void print (FILE *f = stderr);
1872
6c35e5b0 1873 decision_tree () { root = new dt_node (dt_node::DT_NODE, NULL); }
3d2cf79f
RB
1874
1875 static dt_node *insert_operand (dt_node *, operand *, dt_operand **indexes,
1876 unsigned pos = 0, dt_node *parent = 0);
1877 static dt_node *find_node (vec<dt_node *>&, dt_node *);
1878 static bool cmp_node (dt_node *, dt_node *);
1879 static void print_node (dt_node *, FILE *f = stderr, unsigned = 0);
1880};
1881
1882/* Compare two AST operands O1 and O2 and return true if they are equal. */
1883
1884bool
1885cmp_operand (operand *o1, operand *o2)
1886{
1887 if (!o1 || !o2 || o1->type != o2->type)
1888 return false;
1889
1890 if (o1->type == operand::OP_PREDICATE)
1891 {
1892 predicate *p1 = as_a<predicate *>(o1);
1893 predicate *p2 = as_a<predicate *>(o2);
1894 return p1->p == p2->p;
1895 }
1896 else if (o1->type == operand::OP_EXPR)
1897 {
1898 expr *e1 = static_cast<expr *>(o1);
1899 expr *e2 = static_cast<expr *>(o2);
7383cb56
JJ
1900 if (e1->operation != e2->operation
1901 || e1->is_generic != e2->is_generic)
1902 return false;
1903 if (e1->operation->kind == id_base::FN
1904 /* For function calls also compare number of arguments. */
1905 && e1->ops.length () != e2->ops.length ())
1906 return false;
1907 return true;
3d2cf79f
RB
1908 }
1909 else
1910 return false;
1911}
1912
1913/* Compare two decision tree nodes N1 and N2 and return true if they
1914 are equal. */
1915
1916bool
1917decision_tree::cmp_node (dt_node *n1, dt_node *n2)
1918{
1919 if (!n1 || !n2 || n1->type != n2->type)
1920 return false;
1921
7e015fce 1922 if (n1 == n2)
3d2cf79f
RB
1923 return true;
1924
7e015fce
RB
1925 if (n1->type == dt_node::DT_TRUE)
1926 return false;
1927
3d2cf79f
RB
1928 if (n1->type == dt_node::DT_OPERAND)
1929 return cmp_operand ((as_a<dt_operand *> (n1))->op,
1930 (as_a<dt_operand *> (n2))->op);
1931 else if (n1->type == dt_node::DT_MATCH)
2eef1fc1
RB
1932 return (((as_a<dt_operand *> (n1))->match_dop
1933 == (as_a<dt_operand *> (n2))->match_dop)
1934 && ((as_a<dt_operand *> (n1))->value_match
1935 == (as_a<dt_operand *> (n2))->value_match));
3d2cf79f
RB
1936 return false;
1937}
1938
1939/* Search OPS for a decision tree node like P and return it if found. */
1940
1941dt_node *
1942decision_tree::find_node (vec<dt_node *>& ops, dt_node *p)
1943{
7e015fce
RB
1944 /* We can merge adjacent DT_TRUE. */
1945 if (p->type == dt_node::DT_TRUE
1946 && !ops.is_empty ()
1947 && ops.last ()->type == dt_node::DT_TRUE)
1948 return ops.last ();
6c35e5b0 1949 dt_operand *true_node = NULL;
7e015fce
RB
1950 for (int i = ops.length () - 1; i >= 0; --i)
1951 {
1952 /* But we can't merge across DT_TRUE nodes as they serve as
1953 pattern order barriers to make sure that patterns apply
1954 in order of appearance in case multiple matches are possible. */
1955 if (ops[i]->type == dt_node::DT_TRUE)
6c35e5b0
RB
1956 {
1957 if (! true_node
1958 || as_a <dt_operand *> (ops[i])->for_id > true_node->for_id)
1959 true_node = as_a <dt_operand *> (ops[i]);
1960 }
7e015fce 1961 if (decision_tree::cmp_node (ops[i], p))
6c35e5b0
RB
1962 {
1963 /* Unless we are processing the same pattern or the blocking
1964 pattern is before the one we are going to merge with. */
1965 if (true_node
1966 && true_node->for_id != current_id
1967 && true_node->for_id > as_a <dt_operand *> (ops[i])->for_id)
1968 {
1969 if (verbose >= 1)
1970 {
620e594b 1971 location_t p_loc = 0;
6c35e5b0
RB
1972 if (p->type == dt_node::DT_OPERAND)
1973 p_loc = as_a <dt_operand *> (p)->op->location;
620e594b 1974 location_t op_loc = 0;
6c35e5b0
RB
1975 if (ops[i]->type == dt_node::DT_OPERAND)
1976 op_loc = as_a <dt_operand *> (ops[i])->op->location;
620e594b 1977 location_t true_loc = 0;
6c35e5b0
RB
1978 true_loc = true_node->op->location;
1979 warning_at (p_loc,
1980 "failed to merge decision tree node");
1981 warning_at (op_loc,
1982 "with the following");
1983 warning_at (true_loc,
1984 "because of the following which serves as ordering "
1985 "barrier");
1986 }
1987 return NULL;
1988 }
1989 return ops[i];
1990 }
7e015fce 1991 }
3d2cf79f
RB
1992 return NULL;
1993}
1994
1995/* Append N to the decision tree if it there is not already an existing
1996 identical child. */
1997
1998dt_node *
1999dt_node::append_node (dt_node *n)
2000{
2001 dt_node *kid;
2002
2003 kid = decision_tree::find_node (kids, n);
2004 if (kid)
2005 return kid;
2006
2007 kids.safe_push (n);
2008 n->level = this->level + 1;
2009
3d2cf79f
RB
2010 return n;
2011}
2012
2013/* Append OP to the decision tree. */
2014
2015dt_node *
2016dt_node::append_op (operand *op, dt_node *parent, unsigned pos)
2017{
2018 dt_operand *parent_ = safe_as_a<dt_operand *> (parent);
2019 dt_operand *n = new dt_operand (DT_OPERAND, op, 0, parent_, pos);
2020 return append_node (n);
2021}
2022
2023/* Append a DT_TRUE decision tree node. */
2024
2025dt_node *
6c35e5b0 2026dt_node::append_true_op (operand *op, dt_node *parent, unsigned pos)
3d2cf79f 2027{
5609420f 2028 dt_operand *parent_ = safe_as_a<dt_operand *> (parent);
6c35e5b0 2029 dt_operand *n = new dt_operand (DT_TRUE, op, 0, parent_, pos);
3d2cf79f
RB
2030 return append_node (n);
2031}
2032
2033/* Append a DT_MATCH decision tree node. */
2034
2035dt_node *
6c35e5b0
RB
2036dt_node::append_match_op (operand *op, dt_operand *match_dop,
2037 dt_node *parent, unsigned pos)
3d2cf79f
RB
2038{
2039 dt_operand *parent_ = as_a<dt_operand *> (parent);
6c35e5b0 2040 dt_operand *n = new dt_operand (DT_MATCH, op, match_dop, parent_, pos);
3d2cf79f
RB
2041 return append_node (n);
2042}
2043
2044/* Append S to the decision tree. */
2045
2046dt_node *
2047dt_node::append_simplify (simplify *s, unsigned pattern_no,
2048 dt_operand **indexes)
2049{
ae9c3507 2050 dt_simplify *s2;
3d2cf79f 2051 dt_simplify *n = new dt_simplify (s, pattern_no, indexes);
eee7b6c4 2052 for (unsigned i = 0; i < kids.length (); ++i)
ae9c3507
ML
2053 if ((s2 = dyn_cast <dt_simplify *> (kids[i]))
2054 && (verbose >= 1
2055 || s->match->location != s2->s->match->location))
eee7b6c4 2056 {
ae9c3507
ML
2057 /* With a nested patters, it's hard to avoid these in order
2058 to keep match.pd rules relatively small. */
eee7b6c4
RB
2059 warning_at (s->match->location, "duplicate pattern");
2060 warning_at (s2->s->match->location, "previous pattern defined here");
2061 print_operand (s->match, stderr);
2062 fprintf (stderr, "\n");
2063 }
3d2cf79f
RB
2064 return append_node (n);
2065}
2066
803835de
RB
2067/* Analyze the node and its children. */
2068
2069void
03038b8b 2070dt_node::analyze (sinfo_map_t &map)
803835de
RB
2071{
2072 num_leafs = 0;
2073 total_size = 1;
2074 max_level = level;
2075
2076 if (type == DT_SIMPLIFY)
2077 {
03038b8b
RB
2078 /* Populate the map of equivalent simplifies. */
2079 dt_simplify *s = as_a <dt_simplify *> (this);
2080 bool existed;
2081 sinfo *&si = map.get_or_insert (s, &existed);
2082 if (!existed)
2083 {
2084 si = new sinfo;
2085 si->s = s;
2086 si->cnt = 1;
2087 si->fname = NULL;
2088 }
2089 else
2090 si->cnt++;
2091 s->info = si;
803835de
RB
2092 num_leafs = 1;
2093 return;
2094 }
2095
2096 for (unsigned i = 0; i < kids.length (); ++i)
2097 {
03038b8b 2098 kids[i]->analyze (map);
803835de
RB
2099 num_leafs += kids[i]->num_leafs;
2100 total_size += kids[i]->total_size;
2101 max_level = MAX (max_level, kids[i]->max_level);
2102 }
2103}
2104
3d2cf79f
RB
2105/* Insert O into the decision tree and return the decision tree node found
2106 or created. */
2107
2108dt_node *
2109decision_tree::insert_operand (dt_node *p, operand *o, dt_operand **indexes,
2110 unsigned pos, dt_node *parent)
2111{
2112 dt_node *q, *elm = 0;
2113
2114 if (capture *c = dyn_cast<capture *> (o))
2115 {
2116 unsigned capt_index = c->where;
2117
2118 if (indexes[capt_index] == 0)
2119 {
2120 if (c->what)
2121 q = insert_operand (p, c->what, indexes, pos, parent);
2122 else
2123 {
6c35e5b0 2124 q = elm = p->append_true_op (o, parent, pos);
3d2cf79f
RB
2125 goto at_assert_elm;
2126 }
2127 // get to the last capture
2128 for (operand *what = c->what;
2129 what && is_a<capture *> (what);
2130 c = as_a<capture *> (what), what = c->what)
2131 ;
2132
2133 if (!c->what)
2134 {
2135 unsigned cc_index = c->where;
2136 dt_operand *match_op = indexes[cc_index];
2137
6c35e5b0 2138 dt_operand temp (dt_node::DT_TRUE, 0, 0, 0, 0);
3d2cf79f
RB
2139 elm = decision_tree::find_node (p->kids, &temp);
2140
2141 if (elm == 0)
2142 {
4e4791ff
BE
2143 dt_operand match (dt_node::DT_MATCH, 0, match_op, 0, 0);
2144 match.value_match = c->value_match;
2145 elm = decision_tree::find_node (p->kids, &match);
3d2cf79f
RB
2146 }
2147 }
2148 else
2149 {
6c35e5b0 2150 dt_operand temp (dt_node::DT_OPERAND, c->what, 0, 0, 0);
3d2cf79f
RB
2151 elm = decision_tree::find_node (p->kids, &temp);
2152 }
2153
2154at_assert_elm:
2155 gcc_assert (elm->type == dt_node::DT_TRUE
2156 || elm->type == dt_node::DT_OPERAND
2157 || elm->type == dt_node::DT_MATCH);
2158 indexes[capt_index] = static_cast<dt_operand *> (elm);
2159 return q;
2160 }
2161 else
2162 {
6c35e5b0 2163 p = p->append_match_op (o, indexes[capt_index], parent, pos);
2eef1fc1 2164 as_a <dt_operand *>(p)->value_match = c->value_match;
3d2cf79f
RB
2165 if (c->what)
2166 return insert_operand (p, c->what, indexes, 0, p);
2167 else
2168 return p;
2169 }
2170 }
2171 p = p->append_op (o, parent, pos);
2172 q = p;
2173
2174 if (expr *e = dyn_cast <expr *>(o))
2175 {
2176 for (unsigned i = 0; i < e->ops.length (); ++i)
2177 q = decision_tree::insert_operand (q, e->ops[i], indexes, i, p);
2178 }
2179
2180 return q;
2181}
2182
2183/* Insert S into the decision tree. */
2184
2185void
99b1c316 2186decision_tree::insert (class simplify *s, unsigned pattern_no)
3d2cf79f 2187{
6c35e5b0 2188 current_id = s->id;
3d2cf79f
RB
2189 dt_operand **indexes = XCNEWVEC (dt_operand *, s->capture_max + 1);
2190 dt_node *p = decision_tree::insert_operand (root, s->match, indexes);
2191 p->append_simplify (s, pattern_no, indexes);
2192}
2193
2194/* Debug functions to dump the decision tree. */
2195
2196DEBUG_FUNCTION void
2197decision_tree::print_node (dt_node *p, FILE *f, unsigned indent)
2198{
2199 if (p->type == dt_node::DT_NODE)
2200 fprintf (f, "root");
2201 else
2202 {
2203 fprintf (f, "|");
2204 for (unsigned i = 0; i < indent; i++)
2205 fprintf (f, "-");
2206
2207 if (p->type == dt_node::DT_OPERAND)
2208 {
2209 dt_operand *dop = static_cast<dt_operand *>(p);
2210 print_operand (dop->op, f, true);
2211 }
2212 else if (p->type == dt_node::DT_TRUE)
2213 fprintf (f, "true");
2214 else if (p->type == dt_node::DT_MATCH)
2215 fprintf (f, "match (%p)", (void *)((as_a<dt_operand *>(p))->match_dop));
2216 else if (p->type == dt_node::DT_SIMPLIFY)
2217 {
2218 dt_simplify *s = static_cast<dt_simplify *> (p);
2219 fprintf (f, "simplify_%u { ", s->pattern_no);
2220 for (int i = 0; i <= s->s->capture_max; ++i)
2221 fprintf (f, "%p, ", (void *) s->indexes[i]);
2222 fprintf (f, " } ");
2223 }
6c35e5b0
RB
2224 if (is_a <dt_operand *> (p))
2225 fprintf (f, " [%u]", as_a <dt_operand *> (p)->for_id);
3d2cf79f
RB
2226 }
2227
6c35e5b0
RB
2228 fprintf (stderr, " (%p, %p), %u, %u\n",
2229 (void *) p, (void *) p->parent, p->level, p->kids.length ());
3d2cf79f
RB
2230
2231 for (unsigned i = 0; i < p->kids.length (); ++i)
2232 decision_tree::print_node (p->kids[i], f, indent + 2);
2233}
2234
2235DEBUG_FUNCTION void
2236decision_tree::print (FILE *f)
2237{
2238 return decision_tree::print_node (root, f);
2239}
2240
2241
47b25362
RB
2242/* For GENERIC we have to take care of wrapping multiple-used
2243 expressions with side-effects in save_expr and preserve side-effects
2244 of expressions with omit_one_operand. Analyze captures in
2245 match, result and with expressions and perform early-outs
2246 on the outermost match expression operands for cases we cannot
2247 handle. */
2248
6c1dae73 2249class capture_info
47b25362 2250{
6c1dae73 2251public:
53a19317 2252 capture_info (simplify *s, operand *, bool);
47b25362 2253 void walk_match (operand *o, unsigned toplevel_arg, bool, bool);
8fdc6c67 2254 bool walk_result (operand *o, bool, operand *);
47b25362
RB
2255 void walk_c_expr (c_expr *);
2256
2257 struct cinfo
2258 {
2259 bool expr_p;
2260 bool cse_p;
2261 bool force_no_side_effects_p;
44fc0a51 2262 bool force_single_use;
47b25362
RB
2263 bool cond_expr_cond_p;
2264 unsigned long toplevel_msk;
2d3f4bf7
RB
2265 unsigned match_use_count;
2266 unsigned result_use_count;
fa138f6e 2267 unsigned same_as;
53a19317 2268 capture *c;
47b25362
RB
2269 };
2270
2271 auto_vec<cinfo> info;
2272 unsigned long force_no_side_effects;
53a19317 2273 bool gimple;
47b25362
RB
2274};
2275
2276/* Analyze captures in S. */
2277
53a19317 2278capture_info::capture_info (simplify *s, operand *result, bool gimple_)
47b25362 2279{
53a19317
RB
2280 gimple = gimple_;
2281
47b25362 2282 expr *e;
8fdc6c67 2283 if (s->kind == simplify::MATCH)
47b25362
RB
2284 {
2285 force_no_side_effects = -1;
2286 return;
2287 }
2288
2289 force_no_side_effects = 0;
cb3874dc 2290 info.safe_grow_cleared (s->capture_max + 1, true);
fa138f6e
RB
2291 for (int i = 0; i <= s->capture_max; ++i)
2292 info[i].same_as = i;
2293
47b25362
RB
2294 e = as_a <expr *> (s->match);
2295 for (unsigned i = 0; i < e->ops.length (); ++i)
2296 walk_match (e->ops[i], i,
2297 (i != 0 && *e->operation == COND_EXPR)
2298 || *e->operation == TRUTH_ANDIF_EXPR
2299 || *e->operation == TRUTH_ORIF_EXPR,
35b2be21 2300 i == 0 && *e->operation == COND_EXPR);
47b25362 2301
8fdc6c67 2302 walk_result (s->result, false, result);
47b25362
RB
2303}
2304
2305/* Analyze captures in the match expression piece O. */
2306
2307void
2308capture_info::walk_match (operand *o, unsigned toplevel_arg,
2309 bool conditional_p, bool cond_expr_cond_p)
2310{
2311 if (capture *c = dyn_cast <capture *> (o))
2312 {
2d799646 2313 unsigned where = c->where;
2d3f4bf7 2314 info[where].match_use_count++;
2d799646
RB
2315 info[where].toplevel_msk |= 1 << toplevel_arg;
2316 info[where].force_no_side_effects_p |= conditional_p;
2317 info[where].cond_expr_cond_p |= cond_expr_cond_p;
53a19317
RB
2318 if (!info[where].c)
2319 info[where].c = c;
2d799646
RB
2320 if (!c->what)
2321 return;
2322 /* Recurse to exprs and captures. */
2323 if (is_a <capture *> (c->what)
2324 || is_a <expr *> (c->what))
2325 walk_match (c->what, toplevel_arg, conditional_p, false);
2326 /* We need to look past multiple captures to find a captured
2327 expression as with conditional converts two captures
fa138f6e
RB
2328 can be collapsed onto the same expression. Also collect
2329 what captures capture the same thing. */
2d799646 2330 while (c->what && is_a <capture *> (c->what))
fa138f6e
RB
2331 {
2332 c = as_a <capture *> (c->what);
2333 if (info[c->where].same_as != c->where
2334 && info[c->where].same_as != info[where].same_as)
2335 fatal_at (c->location, "cannot handle this collapsed capture");
2336 info[c->where].same_as = info[where].same_as;
2337 }
2d799646 2338 /* Mark expr (non-leaf) captures and forced single-use exprs. */
44fc0a51 2339 expr *e;
47b25362 2340 if (c->what
44fc0a51 2341 && (e = dyn_cast <expr *> (c->what)))
47b25362 2342 {
9348eb67
RB
2343 /* Zero-operand expression captures like ADDR_EXPR@0 are
2344 similar as predicates -- if they are not mentioned in
2345 the result we have to force them to have no side-effects. */
2346 if (e->ops.length () != 0)
2347 info[where].expr_p = true;
2d799646 2348 info[where].force_single_use |= e->force_single_use;
47b25362
RB
2349 }
2350 }
2351 else if (expr *e = dyn_cast <expr *> (o))
2352 {
2353 for (unsigned i = 0; i < e->ops.length (); ++i)
2354 {
2355 bool cond_p = conditional_p;
4e4791ff 2356 bool expr_cond_p = false;
47b25362
RB
2357 if (i != 0 && *e->operation == COND_EXPR)
2358 cond_p = true;
2359 else if (*e->operation == TRUTH_ANDIF_EXPR
2360 || *e->operation == TRUTH_ORIF_EXPR)
2361 cond_p = true;
2362 if (i == 0
35b2be21 2363 && *e->operation == COND_EXPR)
4e4791ff
BE
2364 expr_cond_p = true;
2365 walk_match (e->ops[i], toplevel_arg, cond_p, expr_cond_p);
47b25362
RB
2366 }
2367 }
2368 else if (is_a <predicate *> (o))
2369 {
2370 /* Mark non-captured leafs toplevel arg for checking. */
2371 force_no_side_effects |= 1 << toplevel_arg;
53a19317
RB
2372 if (verbose >= 1
2373 && !gimple)
2374 warning_at (o->location,
2375 "forcing no side-effects on possibly lost leaf");
47b25362
RB
2376 }
2377 else
2378 gcc_unreachable ();
2379}
2380
8fdc6c67
RB
2381/* Analyze captures in the result expression piece O. Return true
2382 if RESULT was visited in one of the children. Only visit
2383 non-if/with children if they are rooted on RESULT. */
47b25362 2384
8fdc6c67
RB
2385bool
2386capture_info::walk_result (operand *o, bool conditional_p, operand *result)
47b25362
RB
2387{
2388 if (capture *c = dyn_cast <capture *> (o))
2389 {
fa138f6e
RB
2390 unsigned where = info[c->where].same_as;
2391 info[where].result_use_count++;
47b25362
RB
2392 /* If we substitute an expression capture we don't know
2393 which captures this will end up using (well, we don't
2394 compute that). Force the uses to be side-effect free
2395 which means forcing the toplevels that reach the
2396 expression side-effect free. */
fa138f6e
RB
2397 if (info[where].expr_p)
2398 force_no_side_effects |= info[where].toplevel_msk;
026c3cfd 2399 /* Mark CSE capture uses as forced to have no side-effects. */
47b25362
RB
2400 if (c->what
2401 && is_a <expr *> (c->what))
2402 {
fa138f6e 2403 info[where].cse_p = true;
8fdc6c67 2404 walk_result (c->what, true, result);
47b25362
RB
2405 }
2406 }
2407 else if (expr *e = dyn_cast <expr *> (o))
2408 {
d4b71b95
RB
2409 id_base *opr = e->operation;
2410 if (user_id *uid = dyn_cast <user_id *> (opr))
2411 opr = uid->substitutes[0];
47b25362
RB
2412 for (unsigned i = 0; i < e->ops.length (); ++i)
2413 {
2414 bool cond_p = conditional_p;
2415 if (i != 0 && *e->operation == COND_EXPR)
2416 cond_p = true;
2417 else if (*e->operation == TRUTH_ANDIF_EXPR
2418 || *e->operation == TRUTH_ORIF_EXPR)
2419 cond_p = true;
8fdc6c67
RB
2420 walk_result (e->ops[i], cond_p, result);
2421 }
2422 }
4e4791ff 2423 else if (if_expr *ie = dyn_cast <if_expr *> (o))
8fdc6c67
RB
2424 {
2425 /* 'if' conditions should be all fine. */
4e4791ff 2426 if (ie->trueexpr == result)
8fdc6c67 2427 {
4e4791ff 2428 walk_result (ie->trueexpr, false, result);
8fdc6c67
RB
2429 return true;
2430 }
4e4791ff 2431 if (ie->falseexpr == result)
8fdc6c67 2432 {
4e4791ff 2433 walk_result (ie->falseexpr, false, result);
8fdc6c67 2434 return true;
47b25362 2435 }
8fdc6c67 2436 bool res = false;
4e4791ff
BE
2437 if (is_a <if_expr *> (ie->trueexpr)
2438 || is_a <with_expr *> (ie->trueexpr))
2439 res |= walk_result (ie->trueexpr, false, result);
2440 if (ie->falseexpr
2441 && (is_a <if_expr *> (ie->falseexpr)
2442 || is_a <with_expr *> (ie->falseexpr)))
2443 res |= walk_result (ie->falseexpr, false, result);
8fdc6c67
RB
2444 return res;
2445 }
4e4791ff 2446 else if (with_expr *we = dyn_cast <with_expr *> (o))
8fdc6c67 2447 {
4e4791ff 2448 bool res = (we->subexpr == result);
8fdc6c67 2449 if (res
4e4791ff
BE
2450 || is_a <if_expr *> (we->subexpr)
2451 || is_a <with_expr *> (we->subexpr))
2452 res |= walk_result (we->subexpr, false, result);
8fdc6c67 2453 if (res)
4e4791ff 2454 walk_c_expr (we->with);
8fdc6c67 2455 return res;
47b25362 2456 }
4e4791ff
BE
2457 else if (c_expr *ce = dyn_cast <c_expr *> (o))
2458 walk_c_expr (ce);
47b25362
RB
2459 else
2460 gcc_unreachable ();
8fdc6c67
RB
2461
2462 return false;
47b25362
RB
2463}
2464
2465/* Look for captures in the C expr E. */
2466
2467void
2468capture_info::walk_c_expr (c_expr *e)
2469{
53a19317
RB
2470 /* Give up for C exprs mentioning captures not inside TREE_TYPE,
2471 TREE_REAL_CST, TREE_CODE or a predicate where they cannot
2472 really escape through. */
47b25362
RB
2473 unsigned p_depth = 0;
2474 for (unsigned i = 0; i < e->code.length (); ++i)
2475 {
2476 const cpp_token *t = &e->code[i];
2477 const cpp_token *n = i < e->code.length () - 1 ? &e->code[i+1] : NULL;
53a19317 2478 id_base *id;
47b25362 2479 if (t->type == CPP_NAME
53a19317
RB
2480 && (strcmp ((const char *)CPP_HASHNODE
2481 (t->val.node.node)->ident.str, "TREE_TYPE") == 0
2482 || strcmp ((const char *)CPP_HASHNODE
2483 (t->val.node.node)->ident.str, "TREE_CODE") == 0
2484 || strcmp ((const char *)CPP_HASHNODE
2485 (t->val.node.node)->ident.str, "TREE_REAL_CST") == 0
2486 || ((id = get_operator ((const char *)CPP_HASHNODE
2487 (t->val.node.node)->ident.str))
2488 && is_a <predicate_id *> (id)))
47b25362
RB
2489 && n->type == CPP_OPEN_PAREN)
2490 p_depth++;
2491 else if (t->type == CPP_CLOSE_PAREN
2492 && p_depth > 0)
2493 p_depth--;
2494 else if (p_depth == 0
2495 && t->type == CPP_ATSIGN
2496 && (n->type == CPP_NUMBER
2497 || n->type == CPP_NAME)
2498 && !(n->flags & PREV_WHITE))
2499 {
4e4791ff 2500 const char *id1;
47b25362 2501 if (n->type == CPP_NUMBER)
4e4791ff 2502 id1 = (const char *)n->val.str.text;
47b25362 2503 else
4e4791ff
BE
2504 id1 = (const char *)CPP_HASHNODE (n->val.node.node)->ident.str;
2505 unsigned *where = e->capture_ids->get(id1);
496326bc 2506 if (! where)
4e4791ff 2507 fatal_at (n, "unknown capture id '%s'", id1);
496326bc 2508 info[info[*where].same_as].force_no_side_effects_p = true;
53a19317
RB
2509 if (verbose >= 1
2510 && !gimple)
2511 warning_at (t, "capture escapes");
47b25362
RB
2512 }
2513 }
2514}
2515
3d2cf79f 2516
f0699540
RB
2517/* The current label failing the current matched pattern during
2518 code generation. */
2519static char *fail_label;
2520
3d2cf79f
RB
2521/* Code generation off the decision tree and the refered AST nodes. */
2522
2523bool
2524is_conversion (id_base *op)
2525{
2526 return (*op == CONVERT_EXPR
2527 || *op == NOP_EXPR
2528 || *op == FLOAT_EXPR
2529 || *op == FIX_TRUNC_EXPR
2530 || *op == VIEW_CONVERT_EXPR);
2531}
2532
f00b6283 2533/* Get the type to be used for generating operand POS of OP from the
3d2cf79f
RB
2534 various sources. */
2535
2536static const char *
f00b6283
RB
2537get_operand_type (id_base *op, unsigned pos,
2538 const char *in_type,
3d2cf79f
RB
2539 const char *expr_type,
2540 const char *other_oprnd_type)
2541{
2542 /* Generally operands whose type does not match the type of the
2543 expression generated need to know their types but match and
2544 thus can fall back to 'other_oprnd_type'. */
2545 if (is_conversion (op))
2546 return other_oprnd_type;
2547 else if (*op == REALPART_EXPR
2548 || *op == IMAGPART_EXPR)
2549 return other_oprnd_type;
2550 else if (is_a <operator_id *> (op)
2551 && strcmp (as_a <operator_id *> (op)->tcc, "tcc_comparison") == 0)
2552 return other_oprnd_type;
f00b6283
RB
2553 else if (*op == COND_EXPR
2554 && pos == 0)
2555 return "boolean_type_node";
6ba3079d 2556 else if (startswith (op->id, "CFN_COND_"))
0d2b3bca
RS
2557 {
2558 /* IFN_COND_* operands 1 and later by default have the same type
2559 as the result. The type of operand 0 needs to be specified
2560 explicitly. */
2561 if (pos > 0 && expr_type)
2562 return expr_type;
2563 else if (pos > 0 && in_type)
2564 return in_type;
2565 else
2566 return NULL;
2567 }
3d2cf79f
RB
2568 else
2569 {
2570 /* Otherwise all types should match - choose one in order of
2571 preference. */
2572 if (expr_type)
2573 return expr_type;
2574 else if (in_type)
2575 return in_type;
2576 else
2577 return other_oprnd_type;
2578 }
2579}
2580
2581/* Generate transform code for an expression. */
2582
2583void
c551c21d
MM
2584expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
2585 int depth, const char *in_type, capture_info *cinfo,
a3ca1bc5 2586 dt_operand **indexes, int)
3d2cf79f 2587{
d4b71b95
RB
2588 id_base *opr = operation;
2589 /* When we delay operator substituting during lowering of fors we
2590 make sure that for code-gen purposes the effects of each substitute
2591 are the same. Thus just look at that. */
2592 if (user_id *uid = dyn_cast <user_id *> (opr))
2593 opr = uid->substitutes[0];
2594
2595 bool conversion_p = is_conversion (opr);
3d2cf79f
RB
2596 const char *type = expr_type;
2597 char optype[64];
2598 if (type)
2599 /* If there was a type specification in the pattern use it. */
2600 ;
2601 else if (conversion_p)
2602 /* For conversions we need to build the expression using the
2603 outer type passed in. */
2604 type = in_type;
d4b71b95
RB
2605 else if (*opr == REALPART_EXPR
2606 || *opr == IMAGPART_EXPR)
3d2cf79f
RB
2607 {
2608 /* __real and __imag use the component type of its operand. */
4e4791ff
BE
2609 snprintf (optype, sizeof (optype), "TREE_TYPE (TREE_TYPE (_o%d[0]))",
2610 depth);
3d2cf79f
RB
2611 type = optype;
2612 }
d4b71b95
RB
2613 else if (is_a <operator_id *> (opr)
2614 && !strcmp (as_a <operator_id *> (opr)->tcc, "tcc_comparison"))
3d2cf79f
RB
2615 {
2616 /* comparisons use boolean_type_node (or what gets in), but
2617 their operands need to figure out the types themselves. */
30934c5d
RB
2618 if (in_type)
2619 type = in_type;
2620 else
2621 {
4e4791ff 2622 snprintf (optype, sizeof (optype), "boolean_type_node");
30934c5d
RB
2623 type = optype;
2624 }
2625 in_type = NULL;
3d2cf79f 2626 }
d4b71b95 2627 else if (*opr == COND_EXPR
0d2b3bca 2628 || *opr == VEC_COND_EXPR
6ba3079d 2629 || startswith (opr->id, "CFN_COND_"))
7026b8df
MG
2630 {
2631 /* Conditions are of the same type as their first alternative. */
4e4791ff 2632 snprintf (optype, sizeof (optype), "TREE_TYPE (_o%d[1])", depth);
7026b8df
MG
2633 type = optype;
2634 }
3d2cf79f
RB
2635 else
2636 {
2637 /* Other operations are of the same type as their first operand. */
4e4791ff 2638 snprintf (optype, sizeof (optype), "TREE_TYPE (_o%d[0])", depth);
3d2cf79f
RB
2639 type = optype;
2640 }
2641 if (!type)
38b52b2f 2642 fatal_at (location, "cannot determine type of operand");
3d2cf79f 2643
c551c21d
MM
2644 fprintf_indent (f, indent, "{\n");
2645 indent += 2;
4e4791ff
BE
2646 fprintf_indent (f, indent,
2647 "tree _o%d[%u], _r%d;\n", depth, ops.length (), depth);
3d2cf79f 2648 char op0type[64];
4e4791ff 2649 snprintf (op0type, sizeof (op0type), "TREE_TYPE (_o%d[0])", depth);
3d2cf79f
RB
2650 for (unsigned i = 0; i < ops.length (); ++i)
2651 {
4e4791ff
BE
2652 char dest1[32];
2653 snprintf (dest1, sizeof (dest1), "_o%d[%u]", depth, i);
2654 const char *optype1
f00b6283 2655 = get_operand_type (opr, i, in_type, expr_type,
3d2cf79f 2656 i == 0 ? NULL : op0type);
4e4791ff 2657 ops[i]->gen_transform (f, indent, dest1, gimple, depth + 1, optype1,
c551c21d 2658 cinfo, indexes,
35b2be21 2659 *opr == COND_EXPR && i == 0 ? 1 : 2);
3d2cf79f
RB
2660 }
2661
d4b71b95 2662 const char *opr_name;
32dfd2e0 2663 if (*operation == CONVERT_EXPR)
d4b71b95 2664 opr_name = "NOP_EXPR";
32dfd2e0 2665 else
d4b71b95 2666 opr_name = operation->id;
32dfd2e0 2667
3d2cf79f
RB
2668 if (gimple)
2669 {
d4b71b95 2670 if (*opr == CONVERT_EXPR)
c551c21d
MM
2671 {
2672 fprintf_indent (f, indent,
4e4791ff 2673 "if (%s != TREE_TYPE (_o%d[0])\n",
c551c21d
MM
2674 type, depth);
2675 fprintf_indent (f, indent,
4e4791ff
BE
2676 " && !useless_type_conversion_p (%s, TREE_TYPE "
2677 "(_o%d[0])))\n",
c551c21d
MM
2678 type, depth);
2679 fprintf_indent (f, indent + 2, "{\n");
2680 indent += 4;
2681 }
c09a3914
RB
2682 /* ??? Building a stmt can fail for various reasons here, seq being
2683 NULL or the stmt referencing SSA names occuring in abnormal PHIs.
2684 So if we fail here we should continue matching other patterns. */
6a86928d
RS
2685 fprintf_indent (f, indent, "gimple_match_op tem_op "
2686 "(res_op->cond.any_else (), %s, %s", opr_name, type);
3d2cf79f 2687 for (unsigned i = 0; i < ops.length (); ++i)
4e4791ff 2688 fprintf (f, ", _o%d[%u]", depth, i);
5d75ad95 2689 fprintf (f, ");\n");
605d1297
RB
2690 fprintf_indent (f, indent, "tem_op.resimplify (%s, valueize);\n",
2691 !force_leaf ? "lseq" : "NULL");
c551c21d 2692 fprintf_indent (f, indent,
14c35be3
RB
2693 "_r%d = maybe_push_res_to_seq (&tem_op, %s);\n", depth,
2694 !force_leaf ? "lseq" : "NULL");
c551c21d 2695 fprintf_indent (f, indent,
f0699540
RB
2696 "if (!_r%d) goto %s;\n",
2697 depth, fail_label);
d4b71b95 2698 if (*opr == CONVERT_EXPR)
c551c21d
MM
2699 {
2700 indent -= 4;
2701 fprintf_indent (f, indent, " }\n");
2702 fprintf_indent (f, indent, "else\n");
4e4791ff 2703 fprintf_indent (f, indent, " _r%d = _o%d[0];\n", depth, depth);
c551c21d 2704 }
3d2cf79f
RB
2705 }
2706 else
2707 {
d4b71b95 2708 if (*opr == CONVERT_EXPR)
c551c21d 2709 {
4e4791ff 2710 fprintf_indent (f, indent, "if (TREE_TYPE (_o%d[0]) != %s)\n",
c551c21d 2711 depth, type);
820d1aec
RB
2712 fprintf_indent (f, indent + 2, "{\n");
2713 indent += 4;
c551c21d 2714 }
d4b71b95 2715 if (opr->kind == id_base::CODE)
4e4791ff
BE
2716 fprintf_indent (f, indent, "_r%d = fold_build%d_loc (loc, %s, %s",
2717 depth, ops.length(), opr_name, type);
3d2cf79f 2718 else
fdc46830
RB
2719 fprintf_indent (f, indent, "_r%d = maybe_build_call_expr_loc (loc, "
2720 "%s, %s, %d", depth, opr_name, type, ops.length());
3d2cf79f 2721 for (unsigned i = 0; i < ops.length (); ++i)
4e4791ff 2722 fprintf (f, ", _o%d[%u]", depth, i);
3d2cf79f 2723 fprintf (f, ");\n");
e4cdf6a8 2724 if (opr->kind != id_base::CODE)
c9e926ce 2725 {
fdc46830
RB
2726 fprintf_indent (f, indent, "if (!_r%d)\n", depth);
2727 fprintf_indent (f, indent, " goto %s;\n", fail_label);
2728 }
2729 if (force_leaf)
2730 {
2731 fprintf_indent (f, indent, "if (EXPR_P (_r%d))\n", depth);
2732 fprintf_indent (f, indent, " goto %s;\n", fail_label);
c9e926ce 2733 }
d4b71b95 2734 if (*opr == CONVERT_EXPR)
c551c21d 2735 {
820d1aec
RB
2736 fprintf_indent (f, indent - 2, "}\n");
2737 indent -= 4;
c551c21d 2738 fprintf_indent (f, indent, "else\n");
4e4791ff 2739 fprintf_indent (f, indent, " _r%d = _o%d[0];\n", depth, depth);
c551c21d 2740 }
3d2cf79f 2741 }
4e4791ff 2742 fprintf_indent (f, indent, "%s = _r%d;\n", dest, depth);
c551c21d
MM
2743 indent -= 2;
2744 fprintf_indent (f, indent, "}\n");
3d2cf79f
RB
2745}
2746
2747/* Generate code for a c_expr which is either the expression inside
2748 an if statement or a sequence of statements which computes a
2749 result to be stored to DEST. */
2750
2751void
c551c21d 2752c_expr::gen_transform (FILE *f, int indent, const char *dest,
47b25362 2753 bool, int, const char *, capture_info *,
a3ca1bc5 2754 dt_operand **, int)
3d2cf79f
RB
2755{
2756 if (dest && nr_stmts == 1)
c551c21d 2757 fprintf_indent (f, indent, "%s = ", dest);
3d2cf79f
RB
2758
2759 unsigned stmt_nr = 1;
330a968c 2760 int prev_line = -1;
3d2cf79f
RB
2761 for (unsigned i = 0; i < code.length (); ++i)
2762 {
2763 const cpp_token *token = &code[i];
2764
330a968c
RB
2765 /* We can't recover from all lexing losses but we can roughly restore line
2766 breaks from location info. */
2767 const line_map_ordinary *map;
2768 linemap_resolve_location (line_table, token->src_loc,
2769 LRK_SPELLING_LOCATION, &map);
2770 expanded_location loc = linemap_expand_location (line_table, map,
2771 token->src_loc);
2772 if (prev_line != -1 && loc.line != prev_line)
2773 fputc ('\n', f);
2774 prev_line = loc.line;
2775
3d2cf79f
RB
2776 /* Replace captures for code-gen. */
2777 if (token->type == CPP_ATSIGN)
2778 {
2779 const cpp_token *n = &code[i+1];
2780 if ((n->type == CPP_NUMBER
2781 || n->type == CPP_NAME)
2782 && !(n->flags & PREV_WHITE))
2783 {
2784 if (token->flags & PREV_WHITE)
2785 fputc (' ', f);
2786 const char *id;
2787 if (n->type == CPP_NUMBER)
2788 id = (const char *)n->val.str.text;
2789 else
2790 id = (const char *)CPP_HASHNODE (n->val.node.node)->ident.str;
c56f494f
RB
2791 unsigned *cid = capture_ids->get (id);
2792 if (!cid)
2793 fatal_at (token, "unknown capture id");
2794 fprintf (f, "captures[%u]", *cid);
3d2cf79f
RB
2795 ++i;
2796 continue;
2797 }
2798 }
2799
2800 if (token->flags & PREV_WHITE)
2801 fputc (' ', f);
2802
2803 if (token->type == CPP_NAME)
2804 {
2805 const char *id = (const char *) NODE_NAME (token->val.node.node);
2806 unsigned j;
2807 for (j = 0; j < ids.length (); ++j)
2808 {
2809 if (strcmp (id, ids[j].id) == 0)
2810 {
2811 fprintf (f, "%s", ids[j].oper);
2812 break;
2813 }
2814 }
2815 if (j < ids.length ())
2816 continue;
2817 }
2818
2819 /* Output the token as string. */
2820 char *tk = (char *)cpp_token_as_text (r, token);
2821 fputs (tk, f);
2822
2823 if (token->type == CPP_SEMICOLON)
2824 {
2825 stmt_nr++;
2826 if (dest && stmt_nr == nr_stmts)
c551c21d 2827 fprintf_indent (f, indent, "%s = ", dest);
3d2cf79f
RB
2828 }
2829 }
330a968c 2830 fputc ('\n', f);
3d2cf79f
RB
2831}
2832
2833/* Generate transform code for a capture. */
2834
2835void
c551c21d
MM
2836capture::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
2837 int depth, const char *in_type, capture_info *cinfo,
a3ca1bc5 2838 dt_operand **indexes, int cond_handling)
3d2cf79f
RB
2839{
2840 if (what && is_a<expr *> (what))
2841 {
2842 if (indexes[where] == 0)
2843 {
2844 char buf[20];
4e4791ff 2845 snprintf (buf, sizeof (buf), "captures[%u]", where);
c551c21d
MM
2846 what->gen_transform (f, indent, buf, gimple, depth, in_type,
2847 cinfo, NULL);
3d2cf79f
RB
2848 }
2849 }
2850
e1201dff
JJ
2851 /* If in GENERIC some capture is used multiple times, unshare it except
2852 when emitting the last use. */
2853 if (!gimple
2854 && cinfo->info.exists ()
2855 && cinfo->info[cinfo->info[where].same_as].result_use_count > 1)
2856 {
2857 fprintf_indent (f, indent, "%s = unshare_expr (captures[%u]);\n",
2858 dest, where);
2859 cinfo->info[cinfo->info[where].same_as].result_use_count--;
2860 }
2861 else
2862 fprintf_indent (f, indent, "%s = captures[%u];\n", dest, where);
47b25362
RB
2863
2864 /* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal
a3ca1bc5
RB
2865 with substituting a capture of that. */
2866 if (gimple
2867 && cond_handling != 0
47b25362 2868 && cinfo->info[where].cond_expr_cond_p)
c551c21d 2869 {
a3ca1bc5
RB
2870 /* If substituting into a cond_expr condition, unshare. */
2871 if (cond_handling == 1)
2872 fprintf_indent (f, indent, "%s = unshare_expr (%s);\n", dest, dest);
2873 /* If substituting elsewhere we might need to decompose it. */
2874 else if (cond_handling == 2)
2875 {
2876 /* ??? Returning false here will also not allow any other patterns
2877 to match unless this generator was split out. */
2878 fprintf_indent (f, indent, "if (COMPARISON_CLASS_P (%s))\n", dest);
2879 fprintf_indent (f, indent, " {\n");
2880 fprintf_indent (f, indent, " if (!seq) return false;\n");
2881 fprintf_indent (f, indent, " %s = gimple_build (seq,"
2882 " TREE_CODE (%s),"
2883 " TREE_TYPE (%s), TREE_OPERAND (%s, 0),"
2884 " TREE_OPERAND (%s, 1));\n",
2885 dest, dest, dest, dest, dest);
2886 fprintf_indent (f, indent, " }\n");
2887 }
c551c21d 2888 }
3d2cf79f
RB
2889}
2890
2891/* Return the name of the operand representing the decision tree node.
2892 Use NAME as space to generate it. */
2893
2894char *
2895dt_operand::get_name (char *name)
2896{
6c35e5b0 2897 if (! parent)
3d2cf79f
RB
2898 sprintf (name, "t");
2899 else if (parent->level == 1)
4e4791ff 2900 sprintf (name, "_p%u", pos);
3d2cf79f 2901 else if (parent->type == dt_node::DT_MATCH)
6c35e5b0 2902 return as_a <dt_operand *> (parent)->get_name (name);
3d2cf79f 2903 else
4e4791ff 2904 sprintf (name, "_q%u%u", parent->level, pos);
3d2cf79f
RB
2905 return name;
2906}
2907
2908/* Fill NAME with the operand name at position POS. */
2909
2910void
2911dt_operand::gen_opname (char *name, unsigned pos)
2912{
6c35e5b0 2913 if (! parent)
4e4791ff 2914 sprintf (name, "_p%u", pos);
3d2cf79f 2915 else
4e4791ff 2916 sprintf (name, "_q%u%u", level, pos);
3d2cf79f
RB
2917}
2918
2919/* Generate matching code for the decision tree operand which is
2920 a predicate. */
2921
2922unsigned
c551c21d 2923dt_operand::gen_predicate (FILE *f, int indent, const char *opname, bool gimple)
3d2cf79f
RB
2924{
2925 predicate *p = as_a <predicate *> (op);
2926
2927 if (p->p->matchers.exists ())
2928 {
2929 /* If this is a predicate generated from a pattern mangle its
2930 name and pass on the valueize hook. */
2931 if (gimple)
c551c21d
MM
2932 fprintf_indent (f, indent, "if (gimple_%s (%s, valueize))\n",
2933 p->p->id, opname);
3d2cf79f 2934 else
c551c21d 2935 fprintf_indent (f, indent, "if (tree_%s (%s))\n", p->p->id, opname);
3d2cf79f
RB
2936 }
2937 else
c551c21d
MM
2938 fprintf_indent (f, indent, "if (%s (%s))\n", p->p->id, opname);
2939 fprintf_indent (f, indent + 2, "{\n");
3d2cf79f
RB
2940 return 1;
2941}
2942
2943/* Generate matching code for the decision tree operand which is
2944 a capture-match. */
2945
2946unsigned
2eef1fc1 2947dt_operand::gen_match_op (FILE *f, int indent, const char *opname, bool)
3d2cf79f
RB
2948{
2949 char match_opname[20];
2950 match_dop->get_name (match_opname);
2eef1fc1 2951 if (value_match)
1544db9a
BE
2952 fprintf_indent (f, indent, "if ((%s == %s && ! TREE_SIDE_EFFECTS (%s)) "
2953 "|| operand_equal_p (%s, %s, 0))\n",
2954 opname, match_opname, opname, opname, match_opname);
2eef1fc1 2955 else
1544db9a
BE
2956 fprintf_indent (f, indent, "if ((%s == %s && ! TREE_SIDE_EFFECTS (%s)) "
2957 "|| (operand_equal_p (%s, %s, 0) "
39bb7d01 2958 "&& types_match (%s, %s)))\n",
1544db9a 2959 opname, match_opname, opname, opname, match_opname,
39bb7d01 2960 opname, match_opname);
c551c21d 2961 fprintf_indent (f, indent + 2, "{\n");
3d2cf79f
RB
2962 return 1;
2963}
2964
2965/* Generate GIMPLE matching code for the decision tree operand. */
2966
2967unsigned
4e4791ff 2968dt_operand::gen_gimple_expr (FILE *f, int indent, int depth)
3d2cf79f
RB
2969{
2970 expr *e = static_cast<expr *> (op);
2971 id_base *id = e->operation;
2972 unsigned n_ops = e->ops.length ();
4f450a2b 2973 unsigned n_braces = 0;
3d2cf79f 2974
75cda3be
RB
2975 if (user_id *u = dyn_cast <user_id *> (id))
2976 id = u->substitutes[0];
2977
3d2cf79f
RB
2978 for (unsigned i = 0; i < n_ops; ++i)
2979 {
2980 char child_opname[20];
2981 gen_opname (child_opname, i);
2982
2983 if (id->kind == id_base::CODE)
2984 {
47b25362
RB
2985 if (e->is_generic
2986 || *id == REALPART_EXPR || *id == IMAGPART_EXPR
3d2cf79f
RB
2987 || *id == BIT_FIELD_REF || *id == VIEW_CONVERT_EXPR)
2988 {
2989 /* ??? If this is a memory operation we can't (and should not)
2990 match this. The only sensible operand types are
2991 SSA names and invariants. */
699acd5b
RB
2992 if (e->is_generic)
2993 {
2994 char opname[20];
2995 get_name (opname);
2996 fprintf_indent (f, indent,
2997 "tree %s = TREE_OPERAND (%s, %i);\n",
2998 child_opname, opname, i);
2999 }
3000 else
3001 fprintf_indent (f, indent,
3002 "tree %s = TREE_OPERAND "
4e4791ff
BE
3003 "(gimple_assign_rhs1 (_a%d), %i);\n",
3004 child_opname, depth, i);
c551c21d
MM
3005 fprintf_indent (f, indent,
3006 "if ((TREE_CODE (%s) == SSA_NAME\n",
3007 child_opname);
3008 fprintf_indent (f, indent,
4f450a2b 3009 " || is_gimple_min_invariant (%s)))\n",
c551c21d 3010 child_opname);
c551c21d
MM
3011 fprintf_indent (f, indent,
3012 " {\n");
3013 indent += 4;
4f450a2b
RB
3014 n_braces++;
3015 fprintf_indent (f, indent,
3016 "%s = do_valueize (valueize, %s);\n",
3017 child_opname, child_opname);
3d2cf79f
RB
3018 continue;
3019 }
3020 else
c551c21d 3021 fprintf_indent (f, indent,
4e4791ff
BE
3022 "tree %s = gimple_assign_rhs%u (_a%d);\n",
3023 child_opname, i + 1, depth);
3d2cf79f
RB
3024 }
3025 else
c551c21d 3026 fprintf_indent (f, indent,
4e4791ff
BE
3027 "tree %s = gimple_call_arg (_c%d, %u);\n",
3028 child_opname, depth, i);
c551c21d 3029 fprintf_indent (f, indent,
4f450a2b 3030 "%s = do_valueize (valueize, %s);\n",
c551c21d 3031 child_opname, child_opname);
3d2cf79f 3032 }
805a5406
RB
3033 /* While the toplevel operands are canonicalized by the caller
3034 after valueizing operands of sub-expressions we have to
3035 re-canonicalize operand order. */
c566cc9f
RS
3036 int opno = commutative_op (id);
3037 if (opno >= 0)
805a5406 3038 {
c566cc9f
RS
3039 char child_opname0[20], child_opname1[20];
3040 gen_opname (child_opname0, opno);
3041 gen_opname (child_opname1, opno + 1);
3042 fprintf_indent (f, indent,
3043 "if (tree_swap_operands_p (%s, %s))\n",
3044 child_opname0, child_opname1);
3045 fprintf_indent (f, indent,
3046 " std::swap (%s, %s);\n",
3047 child_opname0, child_opname1);
805a5406 3048 }
3d2cf79f 3049
4f450a2b 3050 return n_braces;
3d2cf79f
RB
3051}
3052
3053/* Generate GENERIC matching code for the decision tree operand. */
3054
3055unsigned
c551c21d 3056dt_operand::gen_generic_expr (FILE *f, int indent, const char *opname)
3d2cf79f
RB
3057{
3058 expr *e = static_cast<expr *> (op);
75cda3be 3059 id_base *id = e->operation;
3d2cf79f
RB
3060 unsigned n_ops = e->ops.length ();
3061
75cda3be
RB
3062 if (user_id *u = dyn_cast <user_id *> (id))
3063 id = u->substitutes[0];
3064
3d2cf79f
RB
3065 for (unsigned i = 0; i < n_ops; ++i)
3066 {
3067 char child_opname[20];
3068 gen_opname (child_opname, i);
3069
75cda3be 3070 if (id->kind == id_base::CODE)
c551c21d
MM
3071 fprintf_indent (f, indent, "tree %s = TREE_OPERAND (%s, %u);\n",
3072 child_opname, opname, i);
3d2cf79f 3073 else
c551c21d
MM
3074 fprintf_indent (f, indent, "tree %s = CALL_EXPR_ARG (%s, %u);\n",
3075 child_opname, opname, i);
3d2cf79f
RB
3076 }
3077
3078 return 0;
3079}
3080
7383cb56
JJ
3081/* Compare 2 fns or generic_fns vector entries for vector sorting.
3082 Same operation entries with different number of arguments should
3083 be adjacent. */
3084
3085static int
3086fns_cmp (const void *p1, const void *p2)
3087{
3088 dt_operand *op1 = *(dt_operand *const *) p1;
3089 dt_operand *op2 = *(dt_operand *const *) p2;
3090 expr *e1 = as_a <expr *> (op1->op);
3091 expr *e2 = as_a <expr *> (op2->op);
3092 id_base *b1 = e1->operation;
3093 id_base *b2 = e2->operation;
3094 if (b1->hashval < b2->hashval)
3095 return -1;
3096 if (b1->hashval > b2->hashval)
3097 return 1;
3098 return strcmp (b1->id, b2->id);
3099}
3100
3d2cf79f
RB
3101/* Generate matching code for the children of the decision tree node. */
3102
3103void
4e4791ff 3104dt_node::gen_kids (FILE *f, int indent, bool gimple, int depth)
3d2cf79f
RB
3105{
3106 auto_vec<dt_operand *> gimple_exprs;
3107 auto_vec<dt_operand *> generic_exprs;
3108 auto_vec<dt_operand *> fns;
3109 auto_vec<dt_operand *> generic_fns;
3110 auto_vec<dt_operand *> preds;
3111 auto_vec<dt_node *> others;
3d2cf79f
RB
3112
3113 for (unsigned i = 0; i < kids.length (); ++i)
3114 {
3115 if (kids[i]->type == dt_node::DT_OPERAND)
3116 {
3117 dt_operand *op = as_a<dt_operand *> (kids[i]);
3118 if (expr *e = dyn_cast <expr *> (op->op))
3119 {
10230017 3120 if (e->ops.length () == 0
26295a06
RB
3121 /* In GIMPLE a CONSTRUCTOR always appears in a
3122 separate definition. */
10230017 3123 && (!gimple || !(*e->operation == CONSTRUCTOR)))
26295a06
RB
3124 {
3125 generic_exprs.safe_push (op);
3126 /* But ADDR_EXPRs can appear directly when invariant
3127 and in a separate definition when not. */
3128 if (gimple && *e->operation == ADDR_EXPR)
3129 gimple_exprs.safe_push (op);
3130 }
3d2cf79f
RB
3131 else if (e->operation->kind == id_base::FN)
3132 {
3133 if (gimple)
3134 fns.safe_push (op);
3135 else
3136 generic_fns.safe_push (op);
3137 }
3138 else if (e->operation->kind == id_base::PREDICATE)
3139 preds.safe_push (op);
3140 else
3141 {
75cda3be
RB
3142 user_id *u = dyn_cast <user_id *> (e->operation);
3143 if (u && u->substitutes[0]->kind == id_base::FN)
3144 {
3145 if (gimple)
3146 fns.safe_push (op);
3147 else
3148 generic_fns.safe_push (op);
3149 }
3d2cf79f 3150 else
75cda3be
RB
3151 {
3152 if (gimple && !e->is_generic)
3153 gimple_exprs.safe_push (op);
3154 else
3155 generic_exprs.safe_push (op);
3156 }
3d2cf79f
RB
3157 }
3158 }
3159 else if (op->op->type == operand::OP_PREDICATE)
3160 others.safe_push (kids[i]);
3161 else
3162 gcc_unreachable ();
3163 }
69746629 3164 else if (kids[i]->type == dt_node::DT_SIMPLIFY)
3d2cf79f 3165 others.safe_push (kids[i]);
69746629
RB
3166 else if (kids[i]->type == dt_node::DT_MATCH
3167 || kids[i]->type == dt_node::DT_TRUE)
7e015fce
RB
3168 {
3169 /* A DT_TRUE operand serves as a barrier - generate code now
69746629
RB
3170 for what we have collected sofar.
3171 Like DT_TRUE, DT_MATCH serves as a barrier as it can cause
3172 dependent matches to get out-of-order. Generate code now
7e015fce 3173 for what we have collected sofar. */
7383cb56
JJ
3174 fns.qsort (fns_cmp);
3175 generic_fns.qsort (fns_cmp);
4e4791ff 3176 gen_kids_1 (f, indent, gimple, depth, gimple_exprs, generic_exprs,
7e015fce
RB
3177 fns, generic_fns, preds, others);
3178 /* And output the true operand itself. */
4e4791ff 3179 kids[i]->gen (f, indent, gimple, depth);
7e015fce
RB
3180 gimple_exprs.truncate (0);
3181 generic_exprs.truncate (0);
3182 fns.truncate (0);
3183 generic_fns.truncate (0);
3184 preds.truncate (0);
3185 others.truncate (0);
3186 }
3d2cf79f
RB
3187 else
3188 gcc_unreachable ();
3189 }
3190
7e015fce 3191 /* Generate code for the remains. */
7383cb56
JJ
3192 fns.qsort (fns_cmp);
3193 generic_fns.qsort (fns_cmp);
4e4791ff 3194 gen_kids_1 (f, indent, gimple, depth, gimple_exprs, generic_exprs,
7e015fce
RB
3195 fns, generic_fns, preds, others);
3196}
3197
3198/* Generate matching code for the children of the decision tree node. */
3199
3200void
4e4791ff 3201dt_node::gen_kids_1 (FILE *f, int indent, bool gimple, int depth,
00dcc88a
MS
3202 const vec<dt_operand *> &gimple_exprs,
3203 const vec<dt_operand *> &generic_exprs,
3204 const vec<dt_operand *> &fns,
3205 const vec<dt_operand *> &generic_fns,
3206 const vec<dt_operand *> &preds,
3207 const vec<dt_node *> &others)
7e015fce 3208{
3d2cf79f
RB
3209 char buf[128];
3210 char *kid_opname = buf;
3211
3212 unsigned exprs_len = gimple_exprs.length ();
3213 unsigned gexprs_len = generic_exprs.length ();
3214 unsigned fns_len = fns.length ();
3215 unsigned gfns_len = generic_fns.length ();
3216
3217 if (exprs_len || fns_len || gexprs_len || gfns_len)
3218 {
3219 if (exprs_len)
3220 gimple_exprs[0]->get_name (kid_opname);
3221 else if (fns_len)
3222 fns[0]->get_name (kid_opname);
3223 else if (gfns_len)
3224 generic_fns[0]->get_name (kid_opname);
3225 else
3226 generic_exprs[0]->get_name (kid_opname);
3227
c551c21d
MM
3228 fprintf_indent (f, indent, "switch (TREE_CODE (%s))\n", kid_opname);
3229 fprintf_indent (f, indent, " {\n");
1651e9b1 3230 indent += 2;
3d2cf79f
RB
3231 }
3232
3233 if (exprs_len || fns_len)
3234 {
4e4791ff 3235 depth++;
c551c21d
MM
3236 fprintf_indent (f, indent,
3237 "case SSA_NAME:\n");
3238 fprintf_indent (f, indent,
4e4791ff
BE
3239 " if (gimple *_d%d = get_def (valueize, %s))\n",
3240 depth, kid_opname);
c551c21d
MM
3241 fprintf_indent (f, indent,
3242 " {\n");
c551c21d 3243 indent += 6;
3d2cf79f
RB
3244 if (exprs_len)
3245 {
c551c21d 3246 fprintf_indent (f, indent,
4e4791ff
BE
3247 "if (gassign *_a%d = dyn_cast <gassign *> (_d%d))\n",
3248 depth, depth);
c551c21d 3249 fprintf_indent (f, indent,
4e4791ff
BE
3250 " switch (gimple_assign_rhs_code (_a%d))\n",
3251 depth);
c551c21d
MM
3252 indent += 4;
3253 fprintf_indent (f, indent, "{\n");
3d2cf79f
RB
3254 for (unsigned i = 0; i < exprs_len; ++i)
3255 {
3256 expr *e = as_a <expr *> (gimple_exprs[i]->op);
75cda3be
RB
3257 if (user_id *u = dyn_cast <user_id *> (e->operation))
3258 {
3259 for (auto id : u->substitutes)
3260 fprintf_indent (f, indent, "case %s:\n", id->id);
3261 }
3d2cf79f 3262 else
75cda3be
RB
3263 {
3264 id_base *op = e->operation;
3265 if (*op == CONVERT_EXPR || *op == NOP_EXPR)
3266 fprintf_indent (f, indent, "CASE_CONVERT:\n");
3267 else
3268 fprintf_indent (f, indent, "case %s:\n", op->id);
3269 }
1651e9b1 3270 fprintf_indent (f, indent, " {\n");
4e4791ff 3271 gimple_exprs[i]->gen (f, indent + 4, true, depth);
1651e9b1
RB
3272 fprintf_indent (f, indent, " break;\n");
3273 fprintf_indent (f, indent, " }\n");
3d2cf79f 3274 }
1651e9b1 3275 fprintf_indent (f, indent, "default:;\n");
c551c21d 3276 fprintf_indent (f, indent, "}\n");
1ec1fa94 3277 indent -= 4;
3d2cf79f
RB
3278 }
3279
3280 if (fns_len)
3281 {
c8136c36 3282 fprintf_indent (f, indent,
4e4791ff
BE
3283 "%sif (gcall *_c%d = dyn_cast <gcall *> (_d%d))\n",
3284 exprs_len ? "else " : "", depth, depth);
c551c21d 3285 fprintf_indent (f, indent,
4e4791ff
BE
3286 " switch (gimple_call_combined_fn (_c%d))\n",
3287 depth);
3d2cf79f 3288
c9e926ce
RS
3289 indent += 4;
3290 fprintf_indent (f, indent, "{\n");
7383cb56 3291 id_base *last_op = NULL;
3d2cf79f
RB
3292 for (unsigned i = 0; i < fns_len; ++i)
3293 {
3294 expr *e = as_a <expr *>(fns[i]->op);
7383cb56
JJ
3295 if (e->operation != last_op)
3296 {
3297 if (i)
3298 fprintf_indent (f, indent, " break;\n");
3299 if (user_id *u = dyn_cast <user_id *> (e->operation))
3300 for (auto id : u->substitutes)
3301 fprintf_indent (f, indent, "case %s:\n", id->id);
3302 else
3303 fprintf_indent (f, indent, "case %s:\n", e->operation->id);
3304 }
3305 last_op = e->operation;
1105cf81
RB
3306 /* We need to be defensive against bogus prototypes allowing
3307 calls with not enough arguments. */
3308 fprintf_indent (f, indent,
f0699540
RB
3309 " if (gimple_call_num_args (_c%d) == %d)\n",
3310 depth, e->ops.length ());
3311 fprintf_indent (f, indent, " {\n");
1105cf81 3312 fns[i]->gen (f, indent + 6, true, depth);
f0699540 3313 fprintf_indent (f, indent, " }\n");
3d2cf79f
RB
3314 }
3315
7383cb56 3316 fprintf_indent (f, indent, " break;\n");
c551c21d 3317 fprintf_indent (f, indent, "default:;\n");
1ec1fa94 3318 fprintf_indent (f, indent, "}\n");
c9e926ce 3319 indent -= 4;
3d2cf79f
RB
3320 }
3321
c551c21d 3322 indent -= 6;
4e4791ff 3323 depth--;
c551c21d 3324 fprintf_indent (f, indent, " }\n");
d003cf5e
JJ
3325 /* See if there is SSA_NAME among generic_exprs and if yes, emit it
3326 here rather than in the next loop. */
3327 for (unsigned i = 0; i < generic_exprs.length (); ++i)
3328 {
3329 expr *e = as_a <expr *>(generic_exprs[i]->op);
3330 id_base *op = e->operation;
3331 if (*op == SSA_NAME && (exprs_len || fns_len))
3332 {
3333 fprintf_indent (f, indent + 4, "{\n");
4e4791ff 3334 generic_exprs[i]->gen (f, indent + 6, gimple, depth);
d003cf5e
JJ
3335 fprintf_indent (f, indent + 4, "}\n");
3336 }
3337 }
3338
c551c21d 3339 fprintf_indent (f, indent, " break;\n");
3d2cf79f
RB
3340 }
3341
3342 for (unsigned i = 0; i < generic_exprs.length (); ++i)
3343 {
3344 expr *e = as_a <expr *>(generic_exprs[i]->op);
3345 id_base *op = e->operation;
3346 if (*op == CONVERT_EXPR || *op == NOP_EXPR)
c551c21d 3347 fprintf_indent (f, indent, "CASE_CONVERT:\n");
d003cf5e
JJ
3348 else if (*op == SSA_NAME && (exprs_len || fns_len))
3349 /* Already handled above. */
3350 continue;
3d2cf79f 3351 else
75cda3be
RB
3352 {
3353 if (user_id *u = dyn_cast <user_id *> (op))
3354 for (auto id : u->substitutes)
3355 fprintf_indent (f, indent, "case %s:\n", id->id);
3356 else
3357 fprintf_indent (f, indent, "case %s:\n", op->id);
3358 }
c551c21d 3359 fprintf_indent (f, indent, " {\n");
4e4791ff 3360 generic_exprs[i]->gen (f, indent + 4, gimple, depth);
c551c21d
MM
3361 fprintf_indent (f, indent, " break;\n");
3362 fprintf_indent (f, indent, " }\n");
3d2cf79f
RB
3363 }
3364
3365 if (gfns_len)
3366 {
c551c21d
MM
3367 fprintf_indent (f, indent,
3368 "case CALL_EXPR:\n");
3369 fprintf_indent (f, indent,
c9e926ce 3370 " switch (get_call_combined_fn (%s))\n",
c551c21d
MM
3371 kid_opname);
3372 fprintf_indent (f, indent,
c9e926ce
RS
3373 " {\n");
3374 indent += 4;
3d2cf79f 3375
7383cb56 3376 id_base *last_op = NULL;
3d2cf79f
RB
3377 for (unsigned j = 0; j < generic_fns.length (); ++j)
3378 {
3379 expr *e = as_a <expr *>(generic_fns[j]->op);
3380 gcc_assert (e->operation->kind == id_base::FN);
3381
7383cb56
JJ
3382 if (e->operation != last_op)
3383 {
3384 if (j)
3385 fprintf_indent (f, indent, " break;\n");
3386 fprintf_indent (f, indent, "case %s:\n", e->operation->id);
3387 }
3388 last_op = e->operation;
1105cf81
RB
3389 fprintf_indent (f, indent, " if (call_expr_nargs (%s) == %d)\n"
3390 " {\n", kid_opname, e->ops.length ());
3391 generic_fns[j]->gen (f, indent + 6, false, depth);
7383cb56 3392 fprintf_indent (f, indent, " }\n");
3d2cf79f 3393 }
7383cb56 3394 fprintf_indent (f, indent, " break;\n");
c9e926ce 3395 fprintf_indent (f, indent, "default:;\n");
3d2cf79f 3396
c9e926ce
RS
3397 indent -= 4;
3398 fprintf_indent (f, indent, " }\n");
3399 fprintf_indent (f, indent, " break;\n");
3d2cf79f
RB
3400 }
3401
3402 /* Close switch (TREE_CODE ()). */
3403 if (exprs_len || fns_len || gexprs_len || gfns_len)
c551c21d
MM
3404 {
3405 indent -= 4;
3406 fprintf_indent (f, indent, " default:;\n");
1ec1fa94 3407 fprintf_indent (f, indent, " }\n");
c551c21d 3408 }
3d2cf79f
RB
3409
3410 for (unsigned i = 0; i < preds.length (); ++i)
3411 {
3412 expr *e = as_a <expr *> (preds[i]->op);
3413 predicate_id *p = as_a <predicate_id *> (e->operation);
3414 preds[i]->get_name (kid_opname);
3a6461f3
RB
3415 fprintf_indent (f, indent, "{\n");
3416 indent += 2;
c551c21d
MM
3417 fprintf_indent (f, indent, "tree %s_pops[%d];\n", kid_opname, p->nargs);
3418 fprintf_indent (f, indent, "if (%s_%s (%s, %s_pops%s))\n",
3d2cf79f
RB
3419 gimple ? "gimple" : "tree",
3420 p->id, kid_opname, kid_opname,
3421 gimple ? ", valueize" : "");
c551c21d 3422 fprintf_indent (f, indent, " {\n");
3d2cf79f
RB
3423 for (int j = 0; j < p->nargs; ++j)
3424 {
3425 char child_opname[20];
3426 preds[i]->gen_opname (child_opname, j);
c551c21d
MM
3427 fprintf_indent (f, indent + 4, "tree %s = %s_pops[%d];\n",
3428 child_opname, kid_opname, j);
3d2cf79f 3429 }
4e4791ff 3430 preds[i]->gen_kids (f, indent + 4, gimple, depth);
3d2cf79f 3431 fprintf (f, "}\n");
3a6461f3
RB
3432 indent -= 2;
3433 fprintf_indent (f, indent, "}\n");
3d2cf79f
RB
3434 }
3435
3436 for (unsigned i = 0; i < others.length (); ++i)
4e4791ff 3437 others[i]->gen (f, indent, gimple, depth);
3d2cf79f
RB
3438}
3439
3440/* Generate matching code for the decision tree operand. */
3441
3442void
4e4791ff 3443dt_operand::gen (FILE *f, int indent, bool gimple, int depth)
3d2cf79f
RB
3444{
3445 char opname[20];
3446 get_name (opname);
3447
3448 unsigned n_braces = 0;
3449
3450 if (type == DT_OPERAND)
3451 switch (op->type)
3452 {
3453 case operand::OP_PREDICATE:
c551c21d 3454 n_braces = gen_predicate (f, indent, opname, gimple);
3d2cf79f
RB
3455 break;
3456
3457 case operand::OP_EXPR:
3458 if (gimple)
4e4791ff 3459 n_braces = gen_gimple_expr (f, indent, depth);
3d2cf79f 3460 else
c551c21d 3461 n_braces = gen_generic_expr (f, indent, opname);
3d2cf79f
RB
3462 break;
3463
3464 default:
3465 gcc_unreachable ();
3466 }
3467 else if (type == DT_TRUE)
3468 ;
3469 else if (type == DT_MATCH)
39bb7d01 3470 n_braces = gen_match_op (f, indent, opname, gimple);
3d2cf79f
RB
3471 else
3472 gcc_unreachable ();
3473
c551c21d 3474 indent += 4 * n_braces;
4e4791ff 3475 gen_kids (f, indent, gimple, depth);
3d2cf79f
RB
3476
3477 for (unsigned i = 0; i < n_braces; ++i)
c551c21d
MM
3478 {
3479 indent -= 4;
3480 if (indent < 0)
3481 indent = 0;
3482 fprintf_indent (f, indent, " }\n");
3483 }
3d2cf79f
RB
3484}
3485
d9dc70cc 3486/* Emit a logging call to the debug file to the file F, with the INDENT from
497e8e24
AP
3487 either the RESULT location or the S's match location if RESULT is null. */
3488static void
d9dc70cc
AT
3489emit_logging_call (FILE *f, int indent, class simplify *s, operand *result,
3490 bool gimple)
497e8e24
AP
3491{
3492 fprintf_indent (f, indent, "if (UNLIKELY (debug_dump)) "
d9dc70cc 3493 "%s_dump_logs (", gimple ? "gimple" : "generic");
497e8e24 3494 output_line_directive (f,
d9dc70cc
AT
3495 result ? result->location : s->match->location,
3496 true, true, true);
3497 fprintf (f, ", __FILE__, __LINE__, %s);\n",
3498 s->kind == simplify::SIMPLIFY ? "true" : "false");
497e8e24 3499}
e0ee10ed 3500
3d2cf79f
RB
3501/* Generate code for the '(if ...)', '(with ..)' and actual transform
3502 step of a '(simplify ...)' or '(match ...)'. This handles everything
8fdc6c67
RB
3503 that is not part of the decision tree (simplify->match).
3504 Main recursive worker. */
3d2cf79f
RB
3505
3506void
8fdc6c67 3507dt_simplify::gen_1 (FILE *f, int indent, bool gimple, operand *result)
3d2cf79f 3508{
8fdc6c67 3509 if (result)
3d2cf79f 3510 {
8fdc6c67 3511 if (with_expr *w = dyn_cast <with_expr *> (result))
3d2cf79f 3512 {
8fdc6c67
RB
3513 fprintf_indent (f, indent, "{\n");
3514 indent += 4;
0889c52f 3515 output_line_directive (f, w->location);
8fdc6c67
RB
3516 w->with->gen_transform (f, indent, NULL, true, 1, "type", NULL);
3517 gen_1 (f, indent, gimple, w->subexpr);
3518 indent -= 4;
3519 fprintf_indent (f, indent, "}\n");
3520 return;
3521 }
3522 else if (if_expr *ife = dyn_cast <if_expr *> (result))
3523 {
0889c52f 3524 output_line_directive (f, ife->location);
8fdc6c67
RB
3525 fprintf_indent (f, indent, "if (");
3526 ife->cond->gen_transform (f, indent, NULL, true, 1, "type", NULL);
3527 fprintf (f, ")\n");
3528 fprintf_indent (f, indent + 2, "{\n");
3529 indent += 4;
3530 gen_1 (f, indent, gimple, ife->trueexpr);
3531 indent -= 4;
3532 fprintf_indent (f, indent + 2, "}\n");
3533 if (ife->falseexpr)
3d2cf79f 3534 {
8fdc6c67
RB
3535 fprintf_indent (f, indent, "else\n");
3536 fprintf_indent (f, indent + 2, "{\n");
c551c21d 3537 indent += 4;
8fdc6c67
RB
3538 gen_1 (f, indent, gimple, ife->falseexpr);
3539 indent -= 4;
3540 fprintf_indent (f, indent + 2, "}\n");
3d2cf79f 3541 }
8fdc6c67 3542 return;
3d2cf79f 3543 }
3d2cf79f
RB
3544 }
3545
f0699540
RB
3546 static unsigned fail_label_cnt;
3547 char local_fail_label[256];
3548 snprintf (local_fail_label, 256, "next_after_fail%u", ++fail_label_cnt);
3549 fail_label = local_fail_label;
580cda3c 3550 bool needs_label = false;
f0699540 3551
e0ee10ed
RB
3552 /* Analyze captures and perform early-outs on the incoming arguments
3553 that cover cases we cannot handle. */
53a19317 3554 capture_info cinfo (s, result, gimple);
8fdc6c67 3555 if (s->kind == simplify::SIMPLIFY)
e0ee10ed 3556 {
44fc0a51
RB
3557 if (!gimple)
3558 {
3559 for (unsigned i = 0; i < as_a <expr *> (s->match)->ops.length (); ++i)
3560 if (cinfo.force_no_side_effects & (1 << i))
53a19317
RB
3561 {
3562 fprintf_indent (f, indent,
f0699540
RB
3563 "if (TREE_SIDE_EFFECTS (_p%d)) goto %s;\n",
3564 i, fail_label);
580cda3c 3565 needs_label = true;
53a19317
RB
3566 if (verbose >= 1)
3567 warning_at (as_a <expr *> (s->match)->ops[i]->location,
3568 "forcing toplevel operand to have no "
3569 "side-effects");
3570 }
44fc0a51
RB
3571 for (int i = 0; i <= s->capture_max; ++i)
3572 if (cinfo.info[i].cse_p)
3573 ;
3574 else if (cinfo.info[i].force_no_side_effects_p
3575 && (cinfo.info[i].toplevel_msk
3576 & cinfo.force_no_side_effects) == 0)
53a19317
RB
3577 {
3578 fprintf_indent (f, indent,
3579 "if (TREE_SIDE_EFFECTS (captures[%d])) "
f0699540 3580 "goto %s;\n", i, fail_label);
580cda3c 3581 needs_label = true;
53a19317
RB
3582 if (verbose >= 1)
3583 warning_at (cinfo.info[i].c->location,
3584 "forcing captured operand to have no "
3585 "side-effects");
3586 }
44fc0a51
RB
3587 else if ((cinfo.info[i].toplevel_msk
3588 & cinfo.force_no_side_effects) != 0)
3589 /* Mark capture as having no side-effects if we had to verify
3590 that via forced toplevel operand checks. */
3591 cinfo.info[i].force_no_side_effects_p = true;
3592 }
3593 if (gimple)
3594 {
3595 /* Force single-use restriction by only allowing simple
3596 results via setting seq to NULL. */
c551c21d 3597 fprintf_indent (f, indent, "gimple_seq *lseq = seq;\n");
44fc0a51
RB
3598 bool first_p = true;
3599 for (int i = 0; i <= s->capture_max; ++i)
3600 if (cinfo.info[i].force_single_use)
3601 {
3602 if (first_p)
3603 {
c551c21d
MM
3604 fprintf_indent (f, indent, "if (lseq\n");
3605 fprintf_indent (f, indent, " && (");
44fc0a51
RB
3606 first_p = false;
3607 }
3608 else
c551c21d
MM
3609 {
3610 fprintf (f, "\n");
3611 fprintf_indent (f, indent, " || ");
3612 }
44fc0a51
RB
3613 fprintf (f, "!single_use (captures[%d])", i);
3614 }
3615 if (!first_p)
c551c21d
MM
3616 {
3617 fprintf (f, "))\n");
3618 fprintf_indent (f, indent, " lseq = NULL;\n");
3619 }
44fc0a51 3620 }
e0ee10ed
RB
3621 }
3622
d398999d 3623 if (s->kind == simplify::SIMPLIFY)
580cda3c
TC
3624 {
3625 fprintf_indent (f, indent, "if (UNLIKELY (!dbg_cnt (match))) goto %s;\n", fail_label);
3626 needs_label = true;
3627 }
d398999d 3628
f0699540
RB
3629 fprintf_indent (f, indent, "{\n");
3630 indent += 2;
e0ee10ed 3631 if (!result)
3d2cf79f
RB
3632 {
3633 /* If there is no result then this is a predicate implementation. */
d9dc70cc 3634 emit_logging_call (f, indent, s, result, gimple);
c551c21d 3635 fprintf_indent (f, indent, "return true;\n");
3d2cf79f
RB
3636 }
3637 else if (gimple)
3638 {
e0ee10ed
RB
3639 /* For GIMPLE simply drop NON_LVALUE_EXPR (which only appears
3640 in outermost position). */
3641 if (result->type == operand::OP_EXPR
3642 && *as_a <expr *> (result)->operation == NON_LVALUE_EXPR)
3643 result = as_a <expr *> (result)->ops[0];
3644 if (result->type == operand::OP_EXPR)
3d2cf79f 3645 {
e0ee10ed 3646 expr *e = as_a <expr *> (result);
d4b71b95
RB
3647 id_base *opr = e->operation;
3648 bool is_predicate = false;
3649 /* When we delay operator substituting during lowering of fors we
3650 make sure that for code-gen purposes the effects of each substitute
3651 are the same. Thus just look at that. */
3652 if (user_id *uid = dyn_cast <user_id *> (opr))
3653 opr = uid->substitutes[0];
3654 else if (is_a <predicate_id *> (opr))
3655 is_predicate = true;
3d2cf79f 3656 if (!is_predicate)
5d75ad95 3657 fprintf_indent (f, indent, "res_op->set_op (%s, type, %d);\n",
c551c21d 3658 *e->operation == CONVERT_EXPR
5d75ad95
RS
3659 ? "NOP_EXPR" : e->operation->id,
3660 e->ops.length ());
3d2cf79f
RB
3661 for (unsigned j = 0; j < e->ops.length (); ++j)
3662 {
3663 char dest[32];
5d75ad95 3664 if (is_predicate)
4e4791ff 3665 snprintf (dest, sizeof (dest), "res_ops[%d]", j);
5d75ad95 3666 else
4e4791ff 3667 snprintf (dest, sizeof (dest), "res_op->ops[%d]", j);
3d2cf79f 3668 const char *optype
f00b6283 3669 = get_operand_type (opr, j,
3d2cf79f 3670 "type", e->expr_type,
5d75ad95
RS
3671 j == 0 ? NULL
3672 : "TREE_TYPE (res_op->ops[0])");
47b25362 3673 /* We need to expand GENERIC conditions we captured from
a3ca1bc5
RB
3674 COND_EXPRs and we need to unshare them when substituting
3675 into COND_EXPRs. */
3676 int cond_handling = 0;
3677 if (!is_predicate)
35b2be21 3678 cond_handling = (*opr == COND_EXPR && j == 0) ? 1 : 2;
c551c21d 3679 e->ops[j]->gen_transform (f, indent, dest, true, 1, optype,
a3ca1bc5 3680 &cinfo, indexes, cond_handling);
3d2cf79f
RB
3681 }
3682
3683 /* Re-fold the toplevel result. It's basically an embedded
3684 gimple_build w/o actually building the stmt. */
3685 if (!is_predicate)
f9d2def0
FX
3686 {
3687 fprintf_indent (f, indent,
605d1297
RB
3688 "res_op->resimplify (%s, valueize);\n",
3689 !e->force_leaf ? "lseq" : "NULL");
f9d2def0 3690 if (e->force_leaf)
580cda3c
TC
3691 {
3692 fprintf_indent (f, indent,
3693 "if (!maybe_push_res_to_seq (res_op, NULL)) "
3694 "goto %s;\n", fail_label);
3695 needs_label = true;
3696 }
f9d2def0 3697 }
3d2cf79f 3698 }
e0ee10ed
RB
3699 else if (result->type == operand::OP_CAPTURE
3700 || result->type == operand::OP_C_EXPR)
3d2cf79f 3701 {
5d75ad95
RS
3702 fprintf_indent (f, indent, "tree tem;\n");
3703 result->gen_transform (f, indent, "tem", true, 1, "type",
a3ca1bc5 3704 &cinfo, indexes);
5d75ad95 3705 fprintf_indent (f, indent, "res_op->set_value (tem);\n");
47b25362
RB
3706 if (is_a <capture *> (result)
3707 && cinfo.info[as_a <capture *> (result)->where].cond_expr_cond_p)
3708 {
3709 /* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal
3710 with substituting a capture of that. */
c551c21d 3711 fprintf_indent (f, indent,
5d75ad95 3712 "if (COMPARISON_CLASS_P (tem))\n");
c551c21d
MM
3713 fprintf_indent (f, indent,
3714 " {\n");
3715 fprintf_indent (f, indent,
5d75ad95 3716 " res_op->ops[0] = TREE_OPERAND (tem, 0);\n");
c551c21d 3717 fprintf_indent (f, indent,
5d75ad95 3718 " res_op->ops[1] = TREE_OPERAND (tem, 1);\n");
c551c21d
MM
3719 fprintf_indent (f, indent,
3720 " }\n");
47b25362 3721 }
3d2cf79f
RB
3722 }
3723 else
3724 gcc_unreachable ();
d9dc70cc 3725 emit_logging_call (f, indent, s, result, gimple);
c551c21d 3726 fprintf_indent (f, indent, "return true;\n");
3d2cf79f
RB
3727 }
3728 else /* GENERIC */
3729 {
e0ee10ed
RB
3730 bool is_predicate = false;
3731 if (result->type == operand::OP_EXPR)
3d2cf79f 3732 {
e0ee10ed 3733 expr *e = as_a <expr *> (result);
d4b71b95
RB
3734 id_base *opr = e->operation;
3735 /* When we delay operator substituting during lowering of fors we
3736 make sure that for code-gen purposes the effects of each substitute
3737 are the same. Thus just look at that. */
3738 if (user_id *uid = dyn_cast <user_id *> (opr))
3739 opr = uid->substitutes[0];
3740 else if (is_a <predicate_id *> (opr))
3741 is_predicate = true;
e0ee10ed 3742 /* Search for captures used multiple times in the result expression
2d3f4bf7
RB
3743 and wrap them in a SAVE_EXPR. Allow as many uses as in the
3744 original expression. */
e0ee10ed
RB
3745 if (!is_predicate)
3746 for (int i = 0; i < s->capture_max + 1; ++i)
3747 {
2d3f4bf7
RB
3748 if (cinfo.info[i].same_as != (unsigned)i
3749 || cinfo.info[i].cse_p)
fa138f6e 3750 continue;
2d3f4bf7
RB
3751 if (cinfo.info[i].result_use_count
3752 > cinfo.info[i].match_use_count)
580cda3c
TC
3753 {
3754 fprintf_indent (f, indent,
3755 "if (! tree_invariant_p (captures[%d])) "
3756 "goto %s;\n", i, fail_label);
3757 needs_label = true;
3758 }
e0ee10ed 3759 }
3d2cf79f
RB
3760 for (unsigned j = 0; j < e->ops.length (); ++j)
3761 {
3762 char dest[32];
3763 if (is_predicate)
4e4791ff 3764 snprintf (dest, sizeof (dest), "res_ops[%d]", j);
3d2cf79f
RB
3765 else
3766 {
c551c21d 3767 fprintf_indent (f, indent, "tree res_op%d;\n", j);
4e4791ff 3768 snprintf (dest, sizeof (dest), "res_op%d", j);
3d2cf79f
RB
3769 }
3770 const char *optype
f00b6283 3771 = get_operand_type (opr, j,
3d2cf79f
RB
3772 "type", e->expr_type,
3773 j == 0
3774 ? NULL : "TREE_TYPE (res_op0)");
c551c21d 3775 e->ops[j]->gen_transform (f, indent, dest, false, 1, optype,
47b25362 3776 &cinfo, indexes);
3d2cf79f 3777 }
e0ee10ed 3778 if (is_predicate)
497e8e24 3779 {
d9dc70cc 3780 emit_logging_call (f, indent, s, result, gimple);
497e8e24
AP
3781 fprintf_indent (f, indent, "return true;\n");
3782 }
3d2cf79f
RB
3783 else
3784 {
4e4791ff 3785 fprintf_indent (f, indent, "tree _r;\n");
e0ee10ed 3786 /* Re-fold the toplevel result. Use non_lvalue to
4e4791ff 3787 build NON_LVALUE_EXPRs so they get properly
e0ee10ed 3788 ignored when in GIMPLE form. */
d4b71b95 3789 if (*opr == NON_LVALUE_EXPR)
c551c21d 3790 fprintf_indent (f, indent,
4e4791ff 3791 "_r = non_lvalue_loc (loc, res_op0);\n");
3d2cf79f 3792 else
e0ee10ed 3793 {
d4b71b95 3794 if (is_a <operator_id *> (opr))
c551c21d 3795 fprintf_indent (f, indent,
4e4791ff 3796 "_r = fold_build%d_loc (loc, %s, type",
c551c21d
MM
3797 e->ops.length (),
3798 *e->operation == CONVERT_EXPR
3799 ? "NOP_EXPR" : e->operation->id);
e0ee10ed 3800 else
c9e926ce 3801 fprintf_indent (f, indent,
4e4791ff 3802 "_r = maybe_build_call_expr_loc (loc, "
c9e926ce
RS
3803 "%s, type, %d", e->operation->id,
3804 e->ops.length());
e0ee10ed
RB
3805 for (unsigned j = 0; j < e->ops.length (); ++j)
3806 fprintf (f, ", res_op%d", j);
3807 fprintf (f, ");\n");
e4cdf6a8 3808 if (!is_a <operator_id *> (opr))
c9e926ce 3809 {
4e4791ff 3810 fprintf_indent (f, indent, "if (!_r)\n");
f0699540 3811 fprintf_indent (f, indent, " goto %s;\n", fail_label);
580cda3c 3812 needs_label = true;
c9e926ce 3813 }
e0ee10ed 3814 }
3d2cf79f
RB
3815 }
3816 }
e0ee10ed
RB
3817 else if (result->type == operand::OP_CAPTURE
3818 || result->type == operand::OP_C_EXPR)
3819
3d2cf79f 3820 {
4e4791ff
BE
3821 fprintf_indent (f, indent, "tree _r;\n");
3822 result->gen_transform (f, indent, "_r", false, 1, "type",
47b25362 3823 &cinfo, indexes);
3d2cf79f
RB
3824 }
3825 else
3826 gcc_unreachable ();
e0ee10ed
RB
3827 if (!is_predicate)
3828 {
3829 /* Search for captures not used in the result expression and dependent
3830 on TREE_SIDE_EFFECTS emit omit_one_operand. */
3831 for (int i = 0; i < s->capture_max + 1; ++i)
3832 {
fa138f6e
RB
3833 if (cinfo.info[i].same_as != (unsigned)i)
3834 continue;
e0ee10ed
RB
3835 if (!cinfo.info[i].force_no_side_effects_p
3836 && !cinfo.info[i].expr_p
3837 && cinfo.info[i].result_use_count == 0)
c551c21d
MM
3838 {
3839 fprintf_indent (f, indent,
3840 "if (TREE_SIDE_EFFECTS (captures[%d]))\n",
3841 i);
3842 fprintf_indent (f, indent + 2,
4e4791ff
BE
3843 "_r = build2_loc (loc, COMPOUND_EXPR, type, "
3844 "fold_ignored_result (captures[%d]), _r);\n",
c551c21d
MM
3845 i);
3846 }
e0ee10ed 3847 }
d9dc70cc 3848 emit_logging_call (f, indent, s, result, gimple);
4e4791ff 3849 fprintf_indent (f, indent, "return _r;\n");
e0ee10ed 3850 }
3d2cf79f 3851 }
f0699540
RB
3852 indent -= 2;
3853 fprintf_indent (f, indent, "}\n");
580cda3c
TC
3854 if (needs_label)
3855 fprintf (f, "%s:;\n", fail_label);
f0699540 3856 fail_label = NULL;
8fdc6c67 3857}
3d2cf79f 3858
8fdc6c67
RB
3859/* Generate code for the '(if ...)', '(with ..)' and actual transform
3860 step of a '(simplify ...)' or '(match ...)'. This handles everything
3861 that is not part of the decision tree (simplify->match). */
3862
3863void
4e4791ff 3864dt_simplify::gen (FILE *f, int indent, bool gimple, int depth ATTRIBUTE_UNUSED)
8fdc6c67
RB
3865{
3866 fprintf_indent (f, indent, "{\n");
3867 indent += 2;
0889c52f
RB
3868 output_line_directive (f,
3869 s->result ? s->result->location : s->match->location);
8fdc6c67 3870 if (s->capture_max >= 0)
1d2fdec6
RB
3871 {
3872 char opname[20];
49bf49bb
RB
3873 fprintf_indent (f, indent, "tree captures[%u] ATTRIBUTE_UNUSED = { %s",
3874 s->capture_max + 1, indexes[0]->get_name (opname));
8fdc6c67 3875
49bf49bb 3876 for (int i = 1; i <= s->capture_max; ++i)
96285749
RS
3877 {
3878 if (!indexes[i])
3879 break;
49bf49bb 3880 fprintf (f, ", %s", indexes[i]->get_name (opname));
96285749 3881 }
1d2fdec6
RB
3882 fprintf (f, " };\n");
3883 }
8fdc6c67 3884
03038b8b
RB
3885 /* If we have a split-out function for the actual transform, call it. */
3886 if (info && info->fname)
3887 {
3888 if (gimple)
3889 {
5d75ad95 3890 fprintf_indent (f, indent, "if (%s (res_op, seq, "
d4b71b95
RB
3891 "valueize, type, captures", info->fname);
3892 for (unsigned i = 0; i < s->for_subst_vec.length (); ++i)
e04d2a35
RB
3893 if (s->for_subst_vec[i].first->used)
3894 fprintf (f, ", %s", s->for_subst_vec[i].second->id);
d4b71b95 3895 fprintf (f, "))\n");
03038b8b
RB
3896 fprintf_indent (f, indent, " return true;\n");
3897 }
3898 else
3899 {
3900 fprintf_indent (f, indent, "tree res = %s (loc, type",
3901 info->fname);
3902 for (unsigned i = 0; i < as_a <expr *> (s->match)->ops.length (); ++i)
4e4791ff 3903 fprintf (f, ", _p%d", i);
d4b71b95
RB
3904 fprintf (f, ", captures");
3905 for (unsigned i = 0; i < s->for_subst_vec.length (); ++i)
e04d2a35
RB
3906 {
3907 if (s->for_subst_vec[i].first->used)
3908 fprintf (f, ", %s", s->for_subst_vec[i].second->id);
3909 }
d4b71b95 3910 fprintf (f, ");\n");
03038b8b
RB
3911 fprintf_indent (f, indent, "if (res) return res;\n");
3912 }
3913 }
3914 else
d4b71b95
RB
3915 {
3916 for (unsigned i = 0; i < s->for_subst_vec.length (); ++i)
3917 {
e04d2a35
RB
3918 if (! s->for_subst_vec[i].first->used)
3919 continue;
d4b71b95 3920 if (is_a <operator_id *> (s->for_subst_vec[i].second))
9e7af053 3921 fprintf_indent (f, indent, "const enum tree_code %s = %s;\n",
d4b71b95
RB
3922 s->for_subst_vec[i].first->id,
3923 s->for_subst_vec[i].second->id);
3924 else if (is_a <fn_id *> (s->for_subst_vec[i].second))
9e7af053 3925 fprintf_indent (f, indent, "const combined_fn %s = %s;\n",
d4b71b95
RB
3926 s->for_subst_vec[i].first->id,
3927 s->for_subst_vec[i].second->id);
3928 else
3929 gcc_unreachable ();
3930 }
3931 gen_1 (f, indent, gimple, s->result);
3932 }
3d2cf79f 3933
c551c21d
MM
3934 indent -= 2;
3935 fprintf_indent (f, indent, "}\n");
3d2cf79f
RB
3936}
3937
03038b8b
RB
3938
3939/* Hash function for finding equivalent transforms. */
3940
3941hashval_t
3942sinfo_hashmap_traits::hash (const key_type &v)
3943{
3944 /* Only bother to compare those originating from the same source pattern. */
3945 return v->s->result->location;
3946}
3947
3948/* Compare function for finding equivalent transforms. */
3949
3950static bool
3951compare_op (operand *o1, simplify *s1, operand *o2, simplify *s2)
3952{
3953 if (o1->type != o2->type)
3954 return false;
3955
3956 switch (o1->type)
3957 {
3958 case operand::OP_IF:
3959 {
3960 if_expr *if1 = as_a <if_expr *> (o1);
3961 if_expr *if2 = as_a <if_expr *> (o2);
3962 /* ??? Properly compare c-exprs. */
3963 if (if1->cond != if2->cond)
3964 return false;
3965 if (!compare_op (if1->trueexpr, s1, if2->trueexpr, s2))
3966 return false;
3967 if (if1->falseexpr != if2->falseexpr
3968 || (if1->falseexpr
3969 && !compare_op (if1->falseexpr, s1, if2->falseexpr, s2)))
3970 return false;
3971 return true;
3972 }
3973 case operand::OP_WITH:
3974 {
3975 with_expr *with1 = as_a <with_expr *> (o1);
3976 with_expr *with2 = as_a <with_expr *> (o2);
3977 if (with1->with != with2->with)
3978 return false;
3979 return compare_op (with1->subexpr, s1, with2->subexpr, s2);
3980 }
3981 default:;
3982 }
3983
3984 /* We've hit a result. Time to compare capture-infos - this is required
3985 in addition to the conservative pointer-equivalency of the result IL. */
3986 capture_info cinfo1 (s1, o1, true);
3987 capture_info cinfo2 (s2, o2, true);
3988
3989 if (cinfo1.force_no_side_effects != cinfo2.force_no_side_effects
3990 || cinfo1.info.length () != cinfo2.info.length ())
3991 return false;
3992
3993 for (unsigned i = 0; i < cinfo1.info.length (); ++i)
3994 {
3995 if (cinfo1.info[i].expr_p != cinfo2.info[i].expr_p
3996 || cinfo1.info[i].cse_p != cinfo2.info[i].cse_p
3997 || (cinfo1.info[i].force_no_side_effects_p
3998 != cinfo2.info[i].force_no_side_effects_p)
3999 || cinfo1.info[i].force_single_use != cinfo2.info[i].force_single_use
4000 || cinfo1.info[i].cond_expr_cond_p != cinfo2.info[i].cond_expr_cond_p
4001 /* toplevel_msk is an optimization */
4002 || cinfo1.info[i].result_use_count != cinfo2.info[i].result_use_count
4003 || cinfo1.info[i].same_as != cinfo2.info[i].same_as
4004 /* the pointer back to the capture is for diagnostics only */)
4005 return false;
4006 }
4007
4008 /* ??? Deep-compare the actual result. */
4009 return o1 == o2;
4010}
4011
4012bool
4013sinfo_hashmap_traits::equal_keys (const key_type &v,
4014 const key_type &candidate)
4015{
4016 return compare_op (v->s->result, v->s, candidate->s->result, candidate->s);
4017}
4018
4019
3d2cf79f
RB
4020/* Main entry to generate code for matching GIMPLE IL off the decision
4021 tree. */
4022
4023void
703417a0 4024decision_tree::gen (vec <FILE *> &files, bool gimple)
3d2cf79f 4025{
03038b8b
RB
4026 sinfo_map_t si;
4027
4028 root->analyze (si);
803835de 4029
b21ce9ce
RB
4030 fprintf (stderr, "%s decision tree has %u leafs, maximum depth %u and "
4031 "a total number of %u nodes\n",
4032 gimple ? "GIMPLE" : "GENERIC",
4033 root->num_leafs, root->max_level, root->total_size);
803835de 4034
03038b8b
RB
4035 /* First split out the transform part of equal leafs. */
4036 unsigned rcnt = 0;
4037 unsigned fcnt = 1;
4038 for (sinfo_map_t::iterator iter = si.begin ();
4039 iter != si.end (); ++iter)
4040 {
4041 sinfo *s = (*iter).second;
4042 /* Do not split out single uses. */
4043 if (s->cnt <= 1)
4044 continue;
4045
4046 rcnt += s->cnt - 1;
4047 if (verbose >= 1)
4048 {
4049 fprintf (stderr, "found %u uses of", s->cnt);
4050 output_line_directive (stderr, s->s->s->result->location);
4051 }
4052
703417a0 4053 /* Cycle the file buffers. */
153eafaa 4054 FILE *f = choose_output (files);
703417a0 4055
03038b8b
RB
4056 /* Generate a split out function with the leaf transform code. */
4057 s->fname = xasprintf ("%s_simplify_%u", gimple ? "gimple" : "generic",
4058 fcnt++);
4059 if (gimple)
2ed6dd97 4060 fp_decl (f, "\nbool\n"
5d75ad95
RS
4061 "%s (gimple_match_op *res_op, gimple_seq *seq,\n"
4062 " tree (*valueize)(tree) ATTRIBUTE_UNUSED,\n"
9e7af053 4063 " const tree ARG_UNUSED (type), tree *ARG_UNUSED "
2ed6dd97 4064 "(captures)",
03038b8b
RB
4065 s->fname);
4066 else
4067 {
2ed6dd97 4068 fp_decl (f, "\ntree\n"
9e7af053 4069 "%s (location_t ARG_UNUSED (loc), const tree ARG_UNUSED (type),\n",
03038b8b
RB
4070 (*iter).second->fname);
4071 for (unsigned i = 0;
4072 i < as_a <expr *>(s->s->s->match)->ops.length (); ++i)
2ed6dd97 4073 fp_decl (f, " tree ARG_UNUSED (_p%d),", i);
95b6ee96 4074 fp_decl (f, " tree *ARG_UNUSED (captures)");
d4b71b95
RB
4075 }
4076 for (unsigned i = 0; i < s->s->s->for_subst_vec.length (); ++i)
4077 {
e04d2a35
RB
4078 if (! s->s->s->for_subst_vec[i].first->used)
4079 continue;
d4b71b95 4080 if (is_a <operator_id *> (s->s->s->for_subst_vec[i].second))
2ed6dd97 4081 fp_decl (f, ",\n const enum tree_code ARG_UNUSED (%s)",
d4b71b95
RB
4082 s->s->s->for_subst_vec[i].first->id);
4083 else if (is_a <fn_id *> (s->s->s->for_subst_vec[i].second))
2ed6dd97 4084 fp_decl (f, ",\n const combined_fn ARG_UNUSED (%s)",
d4b71b95 4085 s->s->s->for_subst_vec[i].first->id);
03038b8b
RB
4086 }
4087
2ed6dd97 4088 fp_decl_done (f, ")");
703417a0 4089 fprintf (f, "{\n");
c0ce29bc
TC
4090 fprintf_indent (f, 2, "const bool debug_dump = "
4091 "dump_file && (dump_flags & TDF_FOLDING);\n");
03038b8b
RB
4092 s->s->gen_1 (f, 2, gimple, s->s->s->result);
4093 if (gimple)
4094 fprintf (f, " return false;\n");
4095 else
4096 fprintf (f, " return NULL_TREE;\n");
4097 fprintf (f, "}\n");
4098 }
4099 fprintf (stderr, "removed %u duplicate tails\n", rcnt);
4100
2a0de833 4101 for (unsigned n = 1; n <= 7; ++n)
3d2cf79f 4102 {
ef59e1fb
RS
4103 bool has_kids_p = false;
4104
0fd357f2 4105 /* First generate split-out functions. */
4e4791ff 4106 for (unsigned j = 0; j < root->kids.length (); j++)
0fd357f2 4107 {
4e4791ff 4108 dt_operand *dop = static_cast<dt_operand *>(root->kids[j]);
0fd357f2
RB
4109 expr *e = static_cast<expr *>(dop->op);
4110 if (e->ops.length () != n
4111 /* Builtin simplifications are somewhat premature on
b21ce9ce 4112 GENERIC. The following drops patterns with outermost
0fd357f2
RB
4113 calls. It's easy to emit overloads for function code
4114 though if necessary. */
b21ce9ce
RB
4115 || (!gimple
4116 && e->operation->kind != id_base::CODE))
0fd357f2
RB
4117 continue;
4118
703417a0
TC
4119
4120 /* Cycle the file buffers. */
153eafaa 4121 FILE *f = choose_output (files);
703417a0 4122
b21ce9ce 4123 if (gimple)
2ed6dd97 4124 fp_decl (f, "\nbool\n"
5d75ad95
RS
4125 "gimple_simplify_%s (gimple_match_op *res_op,"
4126 " gimple_seq *seq,\n"
4127 " tree (*valueize)(tree) "
b21ce9ce
RB
4128 "ATTRIBUTE_UNUSED,\n"
4129 " code_helper ARG_UNUSED (code), tree "
2ed6dd97 4130 "ARG_UNUSED (type)",
b21ce9ce
RB
4131 e->operation->id);
4132 else
2ed6dd97 4133 fp_decl (f, "\ntree\n"
b21ce9ce 4134 "generic_simplify_%s (location_t ARG_UNUSED (loc), enum "
9e7af053 4135 "tree_code ARG_UNUSED (code), const tree ARG_UNUSED (type)",
b21ce9ce 4136 e->operation->id);
0fd357f2 4137 for (unsigned i = 0; i < n; ++i)
2ed6dd97
AM
4138 fp_decl (f, ", tree _p%d", i);
4139 fp_decl_done (f, ")");
0fd357f2 4140 fprintf (f, "{\n");
c0ce29bc
TC
4141 fprintf_indent (f, 2, "const bool debug_dump = "
4142 "dump_file && (dump_flags & TDF_FOLDING);\n");
4e4791ff 4143 dop->gen_kids (f, 2, gimple, 0);
b21ce9ce
RB
4144 if (gimple)
4145 fprintf (f, " return false;\n");
4146 else
4147 fprintf (f, " return NULL_TREE;\n");
0fd357f2 4148 fprintf (f, "}\n");
ef59e1fb
RS
4149 has_kids_p = true;
4150 }
4151
4152 /* If this main entry has no children, avoid generating code
4153 with compiler warnings, by generating a simple stub. */
4154 if (! has_kids_p)
4155 {
703417a0
TC
4156
4157 /* Cycle the file buffers. */
153eafaa 4158 FILE *f = choose_output (files);
703417a0 4159
ef59e1fb 4160 if (gimple)
2ed6dd97 4161 fp_decl (f, "\nbool\n"
ef59e1fb
RS
4162 "gimple_simplify (gimple_match_op*, gimple_seq*,\n"
4163 " tree (*)(tree), code_helper,\n"
4164 " const tree");
4165 else
2ed6dd97 4166 fp_decl (f, "\ntree\n"
ef59e1fb
RS
4167 "generic_simplify (location_t, enum tree_code,\n"
4168 " const tree");
4169 for (unsigned i = 0; i < n; ++i)
2ed6dd97
AM
4170 fp_decl (f, ", tree");
4171 fp_decl_done (f, ")");
ef59e1fb
RS
4172 fprintf (f, "{\n");
4173 if (gimple)
4174 fprintf (f, " return false;\n");
4175 else
4176 fprintf (f, " return NULL_TREE;\n");
4177 fprintf (f, "}\n");
4178 continue;
0fd357f2
RB
4179 }
4180
703417a0
TC
4181
4182 /* Cycle the file buffers. */
153eafaa 4183 FILE *f = choose_output (files);
703417a0 4184
0fd357f2
RB
4185 /* Then generate the main entry with the outermost switch and
4186 tail-calls to the split-out functions. */
b21ce9ce 4187 if (gimple)
2ed6dd97 4188 fp_decl (f, "\nbool\n"
5d75ad95
RS
4189 "gimple_simplify (gimple_match_op *res_op, gimple_seq *seq,\n"
4190 " tree (*valueize)(tree) ATTRIBUTE_UNUSED,\n"
9e7af053 4191 " code_helper code, const tree type");
b21ce9ce 4192 else
2ed6dd97 4193 fp_decl (f, "\ntree\n"
b21ce9ce 4194 "generic_simplify (location_t loc, enum tree_code code, "
9e7af053 4195 "const tree type ATTRIBUTE_UNUSED");
3d2cf79f 4196 for (unsigned i = 0; i < n; ++i)
2ed6dd97
AM
4197 fp_decl (f, ", tree _p%d", i);
4198 fp_decl_done (f, ")");
3d2cf79f
RB
4199 fprintf (f, "{\n");
4200
b21ce9ce
RB
4201 if (gimple)
4202 fprintf (f, " switch (code.get_rep())\n"
4203 " {\n");
4204 else
4205 fprintf (f, " switch (code)\n"
4206 " {\n");
3d2cf79f
RB
4207 for (unsigned i = 0; i < root->kids.length (); i++)
4208 {
4209 dt_operand *dop = static_cast<dt_operand *>(root->kids[i]);
4210 expr *e = static_cast<expr *>(dop->op);
4211 if (e->ops.length () != n
4212 /* Builtin simplifications are somewhat premature on
b21ce9ce 4213 GENERIC. The following drops patterns with outermost
3d2cf79f
RB
4214 calls. It's easy to emit overloads for function code
4215 though if necessary. */
b21ce9ce
RB
4216 || (!gimple
4217 && e->operation->kind != id_base::CODE))
3d2cf79f
RB
4218 continue;
4219
b21ce9ce
RB
4220 if (*e->operation == CONVERT_EXPR
4221 || *e->operation == NOP_EXPR)
1651e9b1 4222 fprintf (f, " CASE_CONVERT:\n");
3d2cf79f 4223 else
b21ce9ce
RB
4224 fprintf (f, " case %s%s:\n",
4225 is_a <fn_id *> (e->operation) ? "-" : "",
4226 e->operation->id);
4227 if (gimple)
5d75ad95 4228 fprintf (f, " return gimple_simplify_%s (res_op, "
b21ce9ce
RB
4229 "seq, valueize, code, type", e->operation->id);
4230 else
4231 fprintf (f, " return generic_simplify_%s (loc, code, type",
4232 e->operation->id);
4e4791ff
BE
4233 for (unsigned j = 0; j < n; ++j)
4234 fprintf (f, ", _p%d", j);
0fd357f2 4235 fprintf (f, ");\n");
3d2cf79f 4236 }
b21ce9ce
RB
4237 fprintf (f, " default:;\n"
4238 " }\n");
3d2cf79f 4239
b21ce9ce
RB
4240 if (gimple)
4241 fprintf (f, " return false;\n");
4242 else
4243 fprintf (f, " return NULL_TREE;\n");
3d2cf79f
RB
4244 fprintf (f, "}\n");
4245 }
4246}
4247
4248/* Output code to implement the predicate P from the decision tree DT. */
4249
4250void
4251write_predicate (FILE *f, predicate_id *p, decision_tree &dt, bool gimple)
4252{
2ed6dd97
AM
4253 fp_decl (f, "\nbool\n%s%s (tree t%s%s)",
4254 gimple ? "gimple_" : "tree_", p->id,
4255 p->nargs > 0 ? ", tree *res_ops" : "",
4256 gimple ? ", tree (*valueize)(tree) ATTRIBUTE_UNUSED" : "");
4257 fp_decl_done (f, "");
703417a0 4258 fprintf (f, "{\n");
3d2cf79f 4259 /* Conveniently make 'type' available. */
9e7af053 4260 fprintf_indent (f, 2, "const tree type = TREE_TYPE (t);\n");
c0ce29bc
TC
4261 fprintf_indent (f, 2, "const bool debug_dump = "
4262 "dump_file && (dump_flags & TDF_FOLDING);\n");
3d2cf79f
RB
4263
4264 if (!gimple)
c551c21d 4265 fprintf_indent (f, 2, "if (TREE_SIDE_EFFECTS (t)) return false;\n");
4e4791ff 4266 dt.root->gen_kids (f, 2, gimple, 0);
3d2cf79f 4267
c551c21d 4268 fprintf_indent (f, 2, "return false;\n"
3d2cf79f
RB
4269 "}\n");
4270}
4271
4272/* Write the common header for the GIMPLE/GENERIC IL matching routines. */
4273
4274static void
4275write_header (FILE *f, const char *head)
4276{
4277 fprintf (f, "/* Generated automatically by the program `genmatch' from\n");
4278 fprintf (f, " a IL pattern matching and simplification description. */\n");
703417a0
TC
4279 fprintf (f, "#pragma GCC diagnostic push\n");
4280 fprintf (f, "#pragma GCC diagnostic ignored \"-Wunused-variable\"\n");
4281 fprintf (f, "#pragma GCC diagnostic ignored \"-Wunused-function\"\n");
3d2cf79f
RB
4282
4283 /* Include the header instead of writing it awkwardly quoted here. */
703417a0
TC
4284 if (head)
4285 fprintf (f, "\n#include \"%s\"\n", head);
3d2cf79f
RB
4286}
4287
4288
4289
4290/* AST parsing. */
4291
4292class parser
4293{
4294public:
f2ec836a 4295 parser (cpp_reader *, bool gimple);
3d2cf79f
RB
4296
4297private:
4298 const cpp_token *next ();
64d3a1f0
RB
4299 const cpp_token *peek (unsigned = 1);
4300 const cpp_token *peek_ident (const char * = NULL, unsigned = 1);
3d2cf79f 4301 const cpp_token *expect (enum cpp_ttype);
64d3a1f0 4302 const cpp_token *eat_token (enum cpp_ttype);
3d2cf79f
RB
4303 const char *get_string ();
4304 const char *get_ident ();
64d3a1f0 4305 const cpp_token *eat_ident (const char *);
3d2cf79f
RB
4306 const char *get_number ();
4307
2eef1fc1
RB
4308 unsigned get_internal_capture_id ();
4309
28fabd43 4310 id_base *parse_operation (unsigned char &);
c56f494f 4311 operand *parse_capture (operand *, bool);
3d2cf79f
RB
4312 operand *parse_expr ();
4313 c_expr *parse_c_expr (cpp_ttype);
4314 operand *parse_op ();
4315
620e594b 4316 void record_operlist (location_t, user_id *);
1c9b0448 4317
3d2cf79f 4318 void parse_pattern ();
8fdc6c67
RB
4319 operand *parse_result (operand *, predicate_id *);
4320 void push_simplify (simplify::simplify_kind,
0889c52f 4321 vec<simplify *>&, operand *, operand *);
8fdc6c67 4322 void parse_simplify (simplify::simplify_kind,
0889c52f 4323 vec<simplify *>&, predicate_id *, operand *);
620e594b
DM
4324 void parse_for (location_t);
4325 void parse_if (location_t);
4326 void parse_predicates (location_t);
4327 void parse_operator_list (location_t);
3d2cf79f 4328
2eef1fc1
RB
4329 void finish_match_operand (operand *);
4330
3d2cf79f 4331 cpp_reader *r;
f2ec836a 4332 bool gimple;
8fdc6c67 4333 vec<c_expr *> active_ifs;
3d2cf79f 4334 vec<vec<user_id *> > active_fors;
1c9b0448
RB
4335 hash_set<user_id *> *oper_lists_set;
4336 vec<user_id *> oper_lists;
3d2cf79f 4337
f1308e4b 4338 cid_map_t *capture_ids;
6c35e5b0 4339 unsigned last_id;
3d2cf79f
RB
4340
4341public:
4342 vec<simplify *> simplifiers;
4343 vec<predicate_id *> user_predicates;
72eb311d 4344 bool parsing_match_operand;
3d2cf79f
RB
4345};
4346
4347/* Lexing helpers. */
4348
4349/* Read the next non-whitespace token from R. */
4350
4351const cpp_token *
4352parser::next ()
4353{
4354 const cpp_token *token;
4355 do
4356 {
4357 token = cpp_get_token (r);
4358 }
d59b7253 4359 while (token->type == CPP_PADDING);
3d2cf79f
RB
4360 return token;
4361}
4362
4363/* Peek at the next non-whitespace token from R. */
4364
4365const cpp_token *
64d3a1f0 4366parser::peek (unsigned num)
3d2cf79f
RB
4367{
4368 const cpp_token *token;
4369 unsigned i = 0;
4370 do
4371 {
4372 token = cpp_peek_token (r, i++);
4373 }
d59b7253 4374 while (token->type == CPP_PADDING
64d3a1f0 4375 || (--num > 0));
3d2cf79f
RB
4376 /* If we peek at EOF this is a fatal error as it leaves the
4377 cpp_reader in unusable state. Assume we really wanted a
4378 token and thus this EOF is unexpected. */
4379 if (token->type == CPP_EOF)
4380 fatal_at (token, "unexpected end of file");
4381 return token;
4382}
4383
4384/* Peek at the next identifier token (or return NULL if the next
4385 token is not an identifier or equal to ID if supplied). */
4386
4387const cpp_token *
64d3a1f0 4388parser::peek_ident (const char *id, unsigned num)
3d2cf79f 4389{
64d3a1f0 4390 const cpp_token *token = peek (num);
3d2cf79f
RB
4391 if (token->type != CPP_NAME)
4392 return 0;
4393
4394 if (id == 0)
4395 return token;
4396
4397 const char *t = (const char *) CPP_HASHNODE (token->val.node.node)->ident.str;
4398 if (strcmp (id, t) == 0)
4399 return token;
4400
4401 return 0;
4402}
4403
4404/* Read the next token from R and assert it is of type TK. */
4405
4406const cpp_token *
4407parser::expect (enum cpp_ttype tk)
4408{
4409 const cpp_token *token = next ();
4410 if (token->type != tk)
4411 fatal_at (token, "expected %s, got %s",
4412 cpp_type2name (tk, 0), cpp_type2name (token->type, 0));
4413
4414 return token;
4415}
4416
4417/* Consume the next token from R and assert it is of type TK. */
4418
64d3a1f0 4419const cpp_token *
3d2cf79f
RB
4420parser::eat_token (enum cpp_ttype tk)
4421{
64d3a1f0 4422 return expect (tk);
3d2cf79f
RB
4423}
4424
4425/* Read the next token from R and assert it is of type CPP_STRING and
4426 return its value. */
4427
4428const char *
4429parser::get_string ()
4430{
4431 const cpp_token *token = expect (CPP_STRING);
4432 return (const char *)token->val.str.text;
4433}
4434
4435/* Read the next token from R and assert it is of type CPP_NAME and
4436 return its value. */
4437
4438const char *
4439parser::get_ident ()
4440{
4441 const cpp_token *token = expect (CPP_NAME);
4442 return (const char *)CPP_HASHNODE (token->val.node.node)->ident.str;
4443}
4444
4445/* Eat an identifier token with value S from R. */
4446
64d3a1f0 4447const cpp_token *
3d2cf79f
RB
4448parser::eat_ident (const char *s)
4449{
4450 const cpp_token *token = peek ();
4451 const char *t = get_ident ();
4452 if (strcmp (s, t) != 0)
4453 fatal_at (token, "expected '%s' got '%s'\n", s, t);
64d3a1f0 4454 return token;
3d2cf79f
RB
4455}
4456
4457/* Read the next token from R and assert it is of type CPP_NUMBER and
4458 return its value. */
4459
4460const char *
4461parser::get_number ()
4462{
4463 const cpp_token *token = expect (CPP_NUMBER);
4464 return (const char *)token->val.str.text;
4465}
4466
2eef1fc1
RB
4467/* Return a capture ID that can be used internally. */
4468
4469unsigned
4470parser::get_internal_capture_id ()
4471{
4472 unsigned newid = capture_ids->elements ();
4473 /* Big enough for a 32-bit UINT_MAX plus prefix. */
4474 char id[13];
4475 bool existed;
4e4791ff 4476 snprintf (id, sizeof (id), "__%u", newid);
2eef1fc1
RB
4477 capture_ids->get_or_insert (xstrdup (id), &existed);
4478 if (existed)
4479 fatal ("reserved capture id '%s' already used", id);
4480 return newid;
4481}
3d2cf79f 4482
1c9b0448
RB
4483/* Record an operator-list use for transparent for handling. */
4484
4485void
620e594b 4486parser::record_operlist (location_t loc, user_id *p)
1c9b0448
RB
4487{
4488 if (!oper_lists_set->add (p))
4489 {
4490 if (!oper_lists.is_empty ()
4491 && oper_lists[0]->substitutes.length () != p->substitutes.length ())
4492 fatal_at (loc, "User-defined operator list does not have the "
4493 "same number of entries as others used in the pattern");
4494 oper_lists.safe_push (p);
4495 }
4496}
4497
3d2cf79f
RB
4498/* Parse the operator ID, special-casing convert?, convert1? and
4499 convert2? */
4500
4501id_base *
28fabd43 4502parser::parse_operation (unsigned char &opt_grp)
3d2cf79f
RB
4503{
4504 const cpp_token *id_tok = peek ();
28fabd43 4505 char *alt_id = NULL;
3d2cf79f
RB
4506 const char *id = get_ident ();
4507 const cpp_token *token = peek ();
28fabd43 4508 opt_grp = 0;
3d2cf79f
RB
4509 if (token->type == CPP_QUERY
4510 && !(token->flags & PREV_WHITE))
4511 {
72eb311d
RB
4512 if (!parsing_match_operand)
4513 fatal_at (id_tok, "conditional convert can only be used in "
4514 "match expression");
28fabd43
RB
4515 if (ISDIGIT (id[strlen (id) - 1]))
4516 {
4517 opt_grp = id[strlen (id) - 1] - '0' + 1;
4518 alt_id = xstrdup (id);
4519 alt_id[strlen (id) - 1] = '\0';
4520 if (opt_grp == 1)
4521 fatal_at (id_tok, "use '%s?' here", alt_id);
4522 }
4523 else
4524 opt_grp = 1;
3d2cf79f
RB
4525 eat_token (CPP_QUERY);
4526 }
28fabd43 4527 id_base *op = get_operator (alt_id ? alt_id : id);
3d2cf79f 4528 if (!op)
28fabd43
RB
4529 fatal_at (id_tok, "unknown operator %s", alt_id ? alt_id : id);
4530 if (alt_id)
4531 free (alt_id);
72eb311d
RB
4532 user_id *p = dyn_cast<user_id *> (op);
4533 if (p && p->is_oper_list)
94cbafd1
PK
4534 {
4535 if (active_fors.length() == 0)
4536 record_operlist (id_tok->src_loc, p);
4537 else
35574a7b 4538 fatal_at (id_tok, "operator-list %s cannot be expanded inside 'for'", id);
94cbafd1 4539 }
3d2cf79f
RB
4540 return op;
4541}
4542
4543/* Parse a capture.
4544 capture = '@'<number> */
4545
99b1c316 4546class operand *
c56f494f 4547parser::parse_capture (operand *op, bool require_existing)
3d2cf79f 4548{
620e594b 4549 location_t src_loc = eat_token (CPP_ATSIGN)->src_loc;
3d2cf79f 4550 const cpp_token *token = peek ();
72eb311d 4551 const char *id = NULL;
2eef1fc1
RB
4552 bool value_match = false;
4553 /* For matches parse @@ as a value-match denoting the prevailing operand. */
4554 if (token->type == CPP_ATSIGN
4555 && ! (token->flags & PREV_WHITE)
4556 && parsing_match_operand)
4557 {
4558 eat_token (CPP_ATSIGN);
4559 token = peek ();
4560 value_match = true;
4561 }
3d2cf79f
RB
4562 if (token->type == CPP_NUMBER)
4563 id = get_number ();
4564 else if (token->type == CPP_NAME)
4565 id = get_ident ();
4566 else
4567 fatal_at (token, "expected number or identifier");
f1308e4b
RB
4568 unsigned next_id = capture_ids->elements ();
4569 bool existed;
4570 unsigned &num = capture_ids->get_or_insert (id, &existed);
4571 if (!existed)
c56f494f
RB
4572 {
4573 if (require_existing)
4574 fatal_at (src_loc, "unknown capture id");
4575 num = next_id;
4576 }
2eef1fc1 4577 return new capture (src_loc, num, op, value_match);
3d2cf79f
RB
4578}
4579
4580/* Parse an expression
4581 expr = '(' <operation>[capture][flag][type] <operand>... ')' */
4582
99b1c316 4583class operand *
3d2cf79f
RB
4584parser::parse_expr ()
4585{
3d2cf79f 4586 const cpp_token *token = peek ();
28fabd43
RB
4587 unsigned char opt_grp;
4588 expr *e = new expr (parse_operation (opt_grp), token->src_loc);
0889c52f 4589 token = peek ();
3d2cf79f
RB
4590 operand *op;
4591 bool is_commutative = false;
44fc0a51 4592 bool force_capture = false;
3d2cf79f
RB
4593 const char *expr_type = NULL;
4594
14c35be3
RB
4595 if (!parsing_match_operand
4596 && token->type == CPP_NOT
4597 && !(token->flags & PREV_WHITE))
4598 {
4599 eat_token (CPP_NOT);
4600 e->force_leaf = true;
4601 }
4602
3d2cf79f
RB
4603 if (token->type == CPP_COLON
4604 && !(token->flags & PREV_WHITE))
4605 {
4606 eat_token (CPP_COLON);
4607 token = peek ();
4608 if (token->type == CPP_NAME
4609 && !(token->flags & PREV_WHITE))
4610 {
4611 const char *s = get_ident ();
44fc0a51
RB
4612 if (!parsing_match_operand)
4613 expr_type = s;
4614 else
72eb311d 4615 {
44fc0a51
RB
4616 const char *sp = s;
4617 while (*sp)
4618 {
4619 if (*sp == 'c')
e04d2a35 4620 {
4e4791ff 4621 if (operator_id *o
e04d2a35
RB
4622 = dyn_cast<operator_id *> (e->operation))
4623 {
4e4791ff
BE
4624 if (!commutative_tree_code (o->code)
4625 && !comparison_code_p (o->code))
e04d2a35
RB
4626 fatal_at (token, "operation is not commutative");
4627 }
4628 else if (user_id *p = dyn_cast<user_id *> (e->operation))
4629 for (unsigned i = 0;
4630 i < p->substitutes.length (); ++i)
4631 {
4632 if (operator_id *q
4633 = dyn_cast<operator_id *> (p->substitutes[i]))
4634 {
4635 if (!commutative_tree_code (q->code)
4636 && !comparison_code_p (q->code))
4637 fatal_at (token, "operation %s is not "
4638 "commutative", q->id);
4639 }
4640 }
4641 is_commutative = true;
4642 }
4643 else if (*sp == 'C')
44fc0a51
RB
4644 is_commutative = true;
4645 else if (*sp == 's')
4646 {
4647 e->force_single_use = true;
4648 force_capture = true;
4649 }
4650 else
4651 fatal_at (token, "flag %c not recognized", *sp);
4652 sp++;
4653 }
72eb311d 4654 }
3d2cf79f
RB
4655 token = peek ();
4656 }
4657 else
4658 fatal_at (token, "expected flag or type specifying identifier");
4659 }
4660
4661 if (token->type == CPP_ATSIGN
4662 && !(token->flags & PREV_WHITE))
96285749 4663 op = parse_capture (e, false);
44fc0a51
RB
4664 else if (force_capture)
4665 {
2eef1fc1
RB
4666 unsigned num = get_internal_capture_id ();
4667 op = new capture (token->src_loc, num, e, false);
44fc0a51 4668 }
3d2cf79f
RB
4669 else
4670 op = e;
4671 do
4672 {
4e4791ff 4673 token = peek ();
3d2cf79f
RB
4674 if (token->type == CPP_CLOSE_PAREN)
4675 {
4676 if (e->operation->nargs != -1
4677 && e->operation->nargs != (int) e->ops.length ())
4678 fatal_at (token, "'%s' expects %u operands, not %u",
4679 e->operation->id, e->operation->nargs, e->ops.length ());
4680 if (is_commutative)
4681 {
c566cc9f
RS
4682 if (e->ops.length () == 2
4683 || commutative_op (e->operation) >= 0)
3d2cf79f
RB
4684 e->is_commutative = true;
4685 else
c566cc9f
RS
4686 fatal_at (token, "only binary operators or functions with "
4687 "two arguments can be marked commutative, "
4688 "unless the operation is known to be inherently "
4689 "commutative");
3d2cf79f
RB
4690 }
4691 e->expr_type = expr_type;
28fabd43
RB
4692 if (opt_grp != 0)
4693 {
4694 if (e->ops.length () != 1)
4695 fatal_at (token, "only unary operations can be conditional");
4696 e->opt_grp = opt_grp;
4697 }
3d2cf79f
RB
4698 return op;
4699 }
2e96ac06
RB
4700 else if (!(token->flags & PREV_WHITE))
4701 fatal_at (token, "expected expression operand");
4702
3d2cf79f
RB
4703 e->append_op (parse_op ());
4704 }
4705 while (1);
4706}
4707
4708/* Lex native C code delimited by START recording the preprocessing tokens
4709 for later processing.
4710 c_expr = ('{'|'(') <pp token>... ('}'|')') */
4711
4712c_expr *
4713parser::parse_c_expr (cpp_ttype start)
4714{
4715 const cpp_token *token;
4716 cpp_ttype end;
4717 unsigned opencnt;
4718 vec<cpp_token> code = vNULL;
4719 unsigned nr_stmts = 0;
620e594b 4720 location_t loc = eat_token (start)->src_loc;
3d2cf79f
RB
4721 if (start == CPP_OPEN_PAREN)
4722 end = CPP_CLOSE_PAREN;
4723 else if (start == CPP_OPEN_BRACE)
4724 end = CPP_CLOSE_BRACE;
4725 else
4726 gcc_unreachable ();
4727 opencnt = 1;
4728 do
4729 {
4730 token = next ();
4731
4732 /* Count brace pairs to find the end of the expr to match. */
4733 if (token->type == start)
4734 opencnt++;
4735 else if (token->type == end
4736 && --opencnt == 0)
4737 break;
a5382f1c
RB
4738 else if (token->type == CPP_EOF)
4739 fatal_at (token, "unexpected end of file");
3d2cf79f
RB
4740
4741 /* This is a lame way of counting the number of statements. */
4742 if (token->type == CPP_SEMICOLON)
4743 nr_stmts++;
4744
72eb311d
RB
4745 /* If this is possibly a user-defined identifier mark it used. */
4746 if (token->type == CPP_NAME)
1c9b0448 4747 {
786e4c02
RB
4748 const char *str
4749 = (const char *)CPP_HASHNODE (token->val.node.node)->ident.str;
4750 if (strcmp (str, "return") == 0)
4751 fatal_at (token, "return statement not allowed in C expression");
af66ad89
RB
4752 /* Mark user operators corresponding to 'str' as used. */
4753 get_operator (str);
1c9b0448 4754 }
72eb311d 4755
3d2cf79f
RB
4756 /* Record the token. */
4757 code.safe_push (*token);
4758 }
4759 while (1);
0889c52f 4760 return new c_expr (r, loc, code, nr_stmts, vNULL, capture_ids);
3d2cf79f
RB
4761}
4762
4763/* Parse an operand which is either an expression, a predicate or
4764 a standalone capture.
4765 op = predicate | expr | c_expr | capture */
4766
99b1c316 4767class operand *
3d2cf79f
RB
4768parser::parse_op ()
4769{
4770 const cpp_token *token = peek ();
99b1c316 4771 class operand *op = NULL;
3d2cf79f
RB
4772 if (token->type == CPP_OPEN_PAREN)
4773 {
4774 eat_token (CPP_OPEN_PAREN);
4775 op = parse_expr ();
4776 eat_token (CPP_CLOSE_PAREN);
4777 }
4778 else if (token->type == CPP_OPEN_BRACE)
4779 {
4780 op = parse_c_expr (CPP_OPEN_BRACE);
4781 }
4782 else
4783 {
4784 /* Remaining ops are either empty or predicates */
4785 if (token->type == CPP_NAME)
4786 {
4787 const char *id = get_ident ();
4788 id_base *opr = get_operator (id);
4789 if (!opr)
4790 fatal_at (token, "expected predicate name");
4e4791ff 4791 if (operator_id *code1 = dyn_cast <operator_id *> (opr))
3d2cf79f 4792 {
4e4791ff 4793 if (code1->nargs != 0)
3d2cf79f
RB
4794 fatal_at (token, "using an operator with operands as predicate");
4795 /* Parse the zero-operand operator "predicates" as
4796 expression. */
0889c52f 4797 op = new expr (opr, token->src_loc);
3d2cf79f 4798 }
4e4791ff 4799 else if (user_id *code2 = dyn_cast <user_id *> (opr))
10230017 4800 {
4e4791ff 4801 if (code2->nargs != 0)
10230017
RB
4802 fatal_at (token, "using an operator with operands as predicate");
4803 /* Parse the zero-operand operator "predicates" as
4804 expression. */
0889c52f 4805 op = new expr (opr, token->src_loc);
10230017 4806 }
3d2cf79f 4807 else if (predicate_id *p = dyn_cast <predicate_id *> (opr))
0889c52f 4808 op = new predicate (p, token->src_loc);
3d2cf79f
RB
4809 else
4810 fatal_at (token, "using an unsupported operator as predicate");
72eb311d
RB
4811 if (!parsing_match_operand)
4812 fatal_at (token, "predicates are only allowed in match expression");
3d2cf79f
RB
4813 token = peek ();
4814 if (token->flags & PREV_WHITE)
4815 return op;
4816 }
4817 else if (token->type != CPP_COLON
4818 && token->type != CPP_ATSIGN)
4819 fatal_at (token, "expected expression or predicate");
4820 /* optionally followed by a capture and a predicate. */
4821 if (token->type == CPP_COLON)
4822 fatal_at (token, "not implemented: predicate on leaf operand");
4823 if (token->type == CPP_ATSIGN)
c56f494f 4824 op = parse_capture (op, !parsing_match_operand);
3d2cf79f
RB
4825 }
4826
4827 return op;
4828}
4829
1c9b0448
RB
4830/* Create a new simplify from the current parsing state and MATCH,
4831 MATCH_LOC, RESULT and RESULT_LOC and push it to SIMPLIFIERS. */
4832
4833void
8fdc6c67
RB
4834parser::push_simplify (simplify::simplify_kind kind,
4835 vec<simplify *>& simplifiers,
0889c52f 4836 operand *match, operand *result)
1c9b0448 4837{
026c3cfd 4838 /* Build and push a temporary for operator list uses in expressions. */
1c9b0448
RB
4839 if (!oper_lists.is_empty ())
4840 active_fors.safe_push (oper_lists);
4841
4842 simplifiers.safe_push
6c35e5b0 4843 (new simplify (kind, last_id++, match, result,
8fdc6c67 4844 active_fors.copy (), capture_ids));
1c9b0448
RB
4845
4846 if (!oper_lists.is_empty ())
4847 active_fors.pop ();
4848}
4849
3d2cf79f 4850/* Parse
3d2cf79f
RB
4851 <result-op> = <op> | <if> | <with>
4852 <if> = '(' 'if' '(' <c-expr> ')' <result-op> ')'
4853 <with> = '(' 'with' '{' <c-expr> '}' <result-op> ')'
8fdc6c67
RB
4854 and return it. */
4855
4856operand *
4857parser::parse_result (operand *result, predicate_id *matcher)
4858{
4859 const cpp_token *token = peek ();
4860 if (token->type != CPP_OPEN_PAREN)
4861 return parse_op ();
4862
4863 eat_token (CPP_OPEN_PAREN);
4864 if (peek_ident ("if"))
4865 {
4866 eat_ident ("if");
0889c52f 4867 if_expr *ife = new if_expr (token->src_loc);
8fdc6c67
RB
4868 ife->cond = parse_c_expr (CPP_OPEN_PAREN);
4869 if (peek ()->type == CPP_OPEN_PAREN)
4870 {
4871 ife->trueexpr = parse_result (result, matcher);
4872 if (peek ()->type == CPP_OPEN_PAREN)
4873 ife->falseexpr = parse_result (result, matcher);
4874 else if (peek ()->type != CPP_CLOSE_PAREN)
4875 ife->falseexpr = parse_op ();
4876 }
4877 else if (peek ()->type != CPP_CLOSE_PAREN)
4878 {
4879 ife->trueexpr = parse_op ();
4880 if (peek ()->type == CPP_OPEN_PAREN)
4881 ife->falseexpr = parse_result (result, matcher);
4882 else if (peek ()->type != CPP_CLOSE_PAREN)
4883 ife->falseexpr = parse_op ();
4884 }
4885 /* If this if is immediately closed then it contains a
4886 manual matcher or is part of a predicate definition. */
4887 else /* if (peek ()->type == CPP_CLOSE_PAREN) */
4888 {
4889 if (!matcher)
4890 fatal_at (peek (), "manual transform not implemented");
d3b0b692 4891 ife->trueexpr = result;
8fdc6c67
RB
4892 }
4893 eat_token (CPP_CLOSE_PAREN);
4894 return ife;
4895 }
4896 else if (peek_ident ("with"))
4897 {
4898 eat_ident ("with");
0889c52f 4899 with_expr *withe = new with_expr (token->src_loc);
8fdc6c67
RB
4900 /* Parse (with c-expr expr) as (if-with (true) expr). */
4901 withe->with = parse_c_expr (CPP_OPEN_BRACE);
4902 withe->with->nr_stmts = 0;
4903 withe->subexpr = parse_result (result, matcher);
4904 eat_token (CPP_CLOSE_PAREN);
4905 return withe;
4906 }
64d3a1f0
RB
4907 else if (peek_ident ("switch"))
4908 {
4909 token = eat_ident ("switch");
620e594b 4910 location_t ifloc = eat_token (CPP_OPEN_PAREN)->src_loc;
64d3a1f0 4911 eat_ident ("if");
0889c52f 4912 if_expr *ife = new if_expr (ifloc);
64d3a1f0
RB
4913 operand *res = ife;
4914 ife->cond = parse_c_expr (CPP_OPEN_PAREN);
4915 if (peek ()->type == CPP_OPEN_PAREN)
4916 ife->trueexpr = parse_result (result, matcher);
4917 else
4918 ife->trueexpr = parse_op ();
4919 eat_token (CPP_CLOSE_PAREN);
4920 if (peek ()->type != CPP_OPEN_PAREN
4921 || !peek_ident ("if", 2))
4922 fatal_at (token, "switch can be implemented with a single if");
4923 while (peek ()->type != CPP_CLOSE_PAREN)
4924 {
4925 if (peek ()->type == CPP_OPEN_PAREN)
4926 {
4927 if (peek_ident ("if", 2))
4928 {
0889c52f 4929 ifloc = eat_token (CPP_OPEN_PAREN)->src_loc;
64d3a1f0 4930 eat_ident ("if");
0889c52f 4931 ife->falseexpr = new if_expr (ifloc);
64d3a1f0
RB
4932 ife = as_a <if_expr *> (ife->falseexpr);
4933 ife->cond = parse_c_expr (CPP_OPEN_PAREN);
4934 if (peek ()->type == CPP_OPEN_PAREN)
4935 ife->trueexpr = parse_result (result, matcher);
4936 else
4937 ife->trueexpr = parse_op ();
4241415b
AP
4938 if (peek ()->type == CPP_OPEN_PAREN)
4939 fatal_at (peek(), "if inside switch cannot have an else");
64d3a1f0
RB
4940 eat_token (CPP_CLOSE_PAREN);
4941 }
4942 else
4943 {
4944 /* switch default clause */
4945 ife->falseexpr = parse_result (result, matcher);
4946 eat_token (CPP_CLOSE_PAREN);
4947 return res;
4948 }
4949 }
4950 else
4951 {
4952 /* switch default clause */
4953 ife->falseexpr = parse_op ();
4954 eat_token (CPP_CLOSE_PAREN);
4955 return res;
4956 }
4957 }
4958 eat_token (CPP_CLOSE_PAREN);
4959 return res;
4960 }
8fdc6c67
RB
4961 else
4962 {
4963 operand *op = result;
4964 if (!matcher)
4965 op = parse_expr ();
4966 eat_token (CPP_CLOSE_PAREN);
4967 return op;
4968 }
4969}
4970
4971/* Parse
4972 simplify = 'simplify' <expr> <result-op>
4973 or
4974 match = 'match' <ident> <expr> [<result-op>]
3d2cf79f
RB
4975 and fill SIMPLIFIERS with the results. */
4976
4977void
8fdc6c67 4978parser::parse_simplify (simplify::simplify_kind kind,
3d2cf79f 4979 vec<simplify *>& simplifiers, predicate_id *matcher,
8fdc6c67 4980 operand *result)
3d2cf79f
RB
4981{
4982 /* Reset the capture map. */
d0af2c65
RB
4983 if (!capture_ids)
4984 capture_ids = new cid_map_t;
1c9b0448
RB
4985 /* Reset oper_lists and set. */
4986 hash_set <user_id *> olist;
4987 oper_lists_set = &olist;
4988 oper_lists = vNULL;
3d2cf79f
RB
4989
4990 const cpp_token *loc = peek ();
72eb311d 4991 parsing_match_operand = true;
99b1c316 4992 class operand *match = parse_op ();
2eef1fc1 4993 finish_match_operand (match);
72eb311d 4994 parsing_match_operand = false;
3d2cf79f
RB
4995 if (match->type == operand::OP_CAPTURE && !matcher)
4996 fatal_at (loc, "outermost expression cannot be captured");
4997 if (match->type == operand::OP_EXPR
4998 && is_a <predicate_id *> (as_a <expr *> (match)->operation))
4999 fatal_at (loc, "outermost expression cannot be a predicate");
5000
8fdc6c67
RB
5001 /* Splice active_ifs onto result and continue parsing the
5002 "then" expr. */
5003 if_expr *active_if = NULL;
5004 for (int i = active_ifs.length (); i > 0; --i)
5005 {
0889c52f 5006 if_expr *ifc = new if_expr (active_ifs[i-1]->location);
8fdc6c67
RB
5007 ifc->cond = active_ifs[i-1];
5008 ifc->trueexpr = active_if;
5009 active_if = ifc;
5010 }
5011 if_expr *outermost_if = active_if;
5012 while (active_if && active_if->trueexpr)
5013 active_if = as_a <if_expr *> (active_if->trueexpr);
5014
3d2cf79f
RB
5015 const cpp_token *token = peek ();
5016
5017 /* If this if is immediately closed then it is part of a predicate
5018 definition. Push it. */
5019 if (token->type == CPP_CLOSE_PAREN)
5020 {
5021 if (!matcher)
5022 fatal_at (token, "expected transform expression");
8fdc6c67
RB
5023 if (active_if)
5024 {
5025 active_if->trueexpr = result;
5026 result = outermost_if;
5027 }
0889c52f 5028 push_simplify (kind, simplifiers, match, result);
3d2cf79f
RB
5029 return;
5030 }
5031
8fdc6c67
RB
5032 operand *tem = parse_result (result, matcher);
5033 if (active_if)
3d2cf79f 5034 {
8fdc6c67
RB
5035 active_if->trueexpr = tem;
5036 result = outermost_if;
3d2cf79f 5037 }
8fdc6c67
RB
5038 else
5039 result = tem;
5040
0889c52f 5041 push_simplify (kind, simplifiers, match, result);
3d2cf79f
RB
5042}
5043
5044/* Parsing of the outer control structures. */
5045
5046/* Parse a for expression
5047 for = '(' 'for' <subst>... <pattern> ')'
5048 subst = <ident> '(' <ident>... ')' */
5049
5050void
620e594b 5051parser::parse_for (location_t)
3d2cf79f 5052{
72eb311d 5053 auto_vec<const cpp_token *> user_id_tokens;
3d2cf79f
RB
5054 vec<user_id *> user_ids = vNULL;
5055 const cpp_token *token;
5056 unsigned min_n_opers = 0, max_n_opers = 0;
5057
5058 while (1)
5059 {
72eb311d
RB
5060 token = peek ();
5061 if (token->type != CPP_NAME)
3d2cf79f
RB
5062 break;
5063
5064 /* Insert the user defined operators into the operator hash. */
5065 const char *id = get_ident ();
fa74b47a 5066 if (get_operator (id, true) != NULL)
72eb311d 5067 fatal_at (token, "operator already defined");
3d2cf79f
RB
5068 user_id *op = new user_id (id);
5069 id_base **slot = operators->find_slot_with_hash (op, op->hashval, INSERT);
3d2cf79f
RB
5070 *slot = op;
5071 user_ids.safe_push (op);
72eb311d 5072 user_id_tokens.safe_push (token);
3d2cf79f
RB
5073
5074 eat_token (CPP_OPEN_PAREN);
5075
5076 int arity = -1;
5077 while ((token = peek_ident ()) != 0)
5078 {
5079 const char *oper = get_ident ();
fa74b47a 5080 id_base *idb = get_operator (oper, true);
3d2cf79f
RB
5081 if (idb == NULL)
5082 fatal_at (token, "no such operator '%s'", oper);
3d2cf79f
RB
5083
5084 if (arity == -1)
5085 arity = idb->nargs;
5086 else if (idb->nargs == -1)
5087 ;
5088 else if (idb->nargs != arity)
5089 fatal_at (token, "operator '%s' with arity %d does not match "
5090 "others with arity %d", oper, idb->nargs, arity);
5091
72eb311d 5092 user_id *p = dyn_cast<user_id *> (idb);
7523ca9b
PK
5093 if (p)
5094 {
5095 if (p->is_oper_list)
5096 op->substitutes.safe_splice (p->substitutes);
5097 else
5098 fatal_at (token, "iterator cannot be used as operator-list");
5099 }
72eb311d
RB
5100 else
5101 op->substitutes.safe_push (idb);
3d2cf79f
RB
5102 }
5103 op->nargs = arity;
5104 token = expect (CPP_CLOSE_PAREN);
5105
5106 unsigned nsubstitutes = op->substitutes.length ();
5107 if (nsubstitutes == 0)
5108 fatal_at (token, "A user-defined operator must have at least "
5109 "one substitution");
5110 if (max_n_opers == 0)
5111 {
5112 min_n_opers = nsubstitutes;
5113 max_n_opers = nsubstitutes;
5114 }
5115 else
5116 {
5117 if (nsubstitutes % min_n_opers != 0
5118 && min_n_opers % nsubstitutes != 0)
5119 fatal_at (token, "All user-defined identifiers must have a "
5120 "multiple number of operator substitutions of the "
5121 "smallest number of substitutions");
5122 if (nsubstitutes < min_n_opers)
5123 min_n_opers = nsubstitutes;
5124 else if (nsubstitutes > max_n_opers)
5125 max_n_opers = nsubstitutes;
5126 }
5127 }
5128
5129 unsigned n_ids = user_ids.length ();
5130 if (n_ids == 0)
5131 fatal_at (token, "for requires at least one user-defined identifier");
5132
5133 token = peek ();
5134 if (token->type == CPP_CLOSE_PAREN)
5135 fatal_at (token, "no pattern defined in for");
5136
5137 active_fors.safe_push (user_ids);
5138 while (1)
5139 {
5140 token = peek ();
5141 if (token->type == CPP_CLOSE_PAREN)
5142 break;
5143 parse_pattern ();
5144 }
5145 active_fors.pop ();
5146
5147 /* Remove user-defined operators from the hash again. */
5148 for (unsigned i = 0; i < user_ids.length (); ++i)
72eb311d
RB
5149 {
5150 if (!user_ids[i]->used)
5151 warning_at (user_id_tokens[i],
5152 "operator %s defined but not used", user_ids[i]->id);
5153 operators->remove_elt (user_ids[i]);
5154 }
5155}
5156
5157/* Parse an identifier associated with a list of operators.
5158 oprs = '(' 'define_operator_list' <ident> <ident>... ')' */
5159
5160void
620e594b 5161parser::parse_operator_list (location_t)
72eb311d
RB
5162{
5163 const cpp_token *token = peek ();
5164 const char *id = get_ident ();
5165
fa74b47a 5166 if (get_operator (id, true) != 0)
72eb311d
RB
5167 fatal_at (token, "operator %s already defined", id);
5168
5169 user_id *op = new user_id (id, true);
5170 int arity = -1;
5171
5172 while ((token = peek_ident ()) != 0)
5173 {
5174 token = peek ();
5175 const char *oper = get_ident ();
fa74b47a 5176 id_base *idb = get_operator (oper, true);
72eb311d
RB
5177
5178 if (idb == 0)
5179 fatal_at (token, "no such operator '%s'", oper);
5180
5181 if (arity == -1)
5182 arity = idb->nargs;
5183 else if (idb->nargs == -1)
5184 ;
5185 else if (arity != idb->nargs)
5186 fatal_at (token, "operator '%s' with arity %d does not match "
5187 "others with arity %d", oper, idb->nargs, arity);
5188
5189 /* We allow composition of multiple operator lists. */
5190 if (user_id *p = dyn_cast<user_id *> (idb))
5191 op->substitutes.safe_splice (p->substitutes);
5192 else
5193 op->substitutes.safe_push (idb);
5194 }
5195
b78be014
PK
5196 // Check that there is no junk after id-list
5197 token = peek();
5198 if (token->type != CPP_CLOSE_PAREN)
5199 fatal_at (token, "expected identifier got %s", cpp_type2name (token->type, 0));
5200
72eb311d
RB
5201 if (op->substitutes.length () == 0)
5202 fatal_at (token, "operator-list cannot be empty");
5203
5204 op->nargs = arity;
5205 id_base **slot = operators->find_slot_with_hash (op, op->hashval, INSERT);
5206 *slot = op;
3d2cf79f
RB
5207}
5208
5209/* Parse an outer if expression.
5210 if = '(' 'if' '(' <c-expr> ')' <pattern> ')' */
5211
5212void
620e594b 5213parser::parse_if (location_t)
3d2cf79f 5214{
8fdc6c67 5215 c_expr *ifexpr = parse_c_expr (CPP_OPEN_PAREN);
3d2cf79f
RB
5216
5217 const cpp_token *token = peek ();
5218 if (token->type == CPP_CLOSE_PAREN)
5219 fatal_at (token, "no pattern defined in if");
5220
8fdc6c67 5221 active_ifs.safe_push (ifexpr);
3d2cf79f
RB
5222 while (1)
5223 {
4e4791ff 5224 token = peek ();
3d2cf79f
RB
5225 if (token->type == CPP_CLOSE_PAREN)
5226 break;
5227
5228 parse_pattern ();
5229 }
5230 active_ifs.pop ();
5231}
5232
5233/* Parse a list of predefined predicate identifiers.
5234 preds = '(' 'define_predicates' <ident>... ')' */
5235
5236void
620e594b 5237parser::parse_predicates (location_t)
3d2cf79f
RB
5238{
5239 do
5240 {
5241 const cpp_token *token = peek ();
5242 if (token->type != CPP_NAME)
5243 break;
5244
5245 add_predicate (get_ident ());
5246 }
5247 while (1);
5248}
5249
5250/* Parse outer control structures.
5251 pattern = <preds>|<for>|<if>|<simplify>|<match> */
5252
5253void
5254parser::parse_pattern ()
5255{
5256 /* All clauses start with '('. */
5257 eat_token (CPP_OPEN_PAREN);
5258 const cpp_token *token = peek ();
5259 const char *id = get_ident ();
5260 if (strcmp (id, "simplify") == 0)
d0af2c65 5261 {
0889c52f 5262 parse_simplify (simplify::SIMPLIFY, simplifiers, NULL, NULL);
d0af2c65
RB
5263 capture_ids = NULL;
5264 }
3d2cf79f
RB
5265 else if (strcmp (id, "match") == 0)
5266 {
5267 bool with_args = false;
620e594b 5268 location_t e_loc = peek ()->src_loc;
3d2cf79f
RB
5269 if (peek ()->type == CPP_OPEN_PAREN)
5270 {
5271 eat_token (CPP_OPEN_PAREN);
5272 with_args = true;
5273 }
5274 const char *name = get_ident ();
4e4791ff 5275 id_base *id1 = get_operator (name);
3d2cf79f 5276 predicate_id *p;
4e4791ff 5277 if (!id1)
3d2cf79f
RB
5278 {
5279 p = add_predicate (name);
5280 user_predicates.safe_push (p);
5281 }
4e4791ff 5282 else if ((p = dyn_cast <predicate_id *> (id1)))
3d2cf79f
RB
5283 ;
5284 else
5285 fatal_at (token, "cannot add a match to a non-predicate ID");
5286 /* Parse (match <id> <arg>... (match-expr)) here. */
5287 expr *e = NULL;
5288 if (with_args)
5289 {
d0af2c65 5290 capture_ids = new cid_map_t;
0889c52f 5291 e = new expr (p, e_loc);
3d2cf79f 5292 while (peek ()->type == CPP_ATSIGN)
c56f494f 5293 e->append_op (parse_capture (NULL, false));
3d2cf79f
RB
5294 eat_token (CPP_CLOSE_PAREN);
5295 }
5296 if (p->nargs != -1
5297 && ((e && e->ops.length () != (unsigned)p->nargs)
5298 || (!e && p->nargs != 0)))
5299 fatal_at (token, "non-matching number of match operands");
5300 p->nargs = e ? e->ops.length () : 0;
0889c52f 5301 parse_simplify (simplify::MATCH, p->matchers, p, e);
d0af2c65 5302 capture_ids = NULL;
3d2cf79f
RB
5303 }
5304 else if (strcmp (id, "for") == 0)
5305 parse_for (token->src_loc);
5306 else if (strcmp (id, "if") == 0)
5307 parse_if (token->src_loc);
5308 else if (strcmp (id, "define_predicates") == 0)
5309 {
5310 if (active_ifs.length () > 0
5311 || active_fors.length () > 0)
5312 fatal_at (token, "define_predicates inside if or for is not supported");
5313 parse_predicates (token->src_loc);
5314 }
72eb311d
RB
5315 else if (strcmp (id, "define_operator_list") == 0)
5316 {
5317 if (active_ifs.length () > 0
5318 || active_fors.length () > 0)
5319 fatal_at (token, "operator-list inside if or for is not supported");
5320 parse_operator_list (token->src_loc);
5321 }
3d2cf79f
RB
5322 else
5323 fatal_at (token, "expected %s'simplify', 'match', 'for' or 'if'",
5324 active_ifs.length () == 0 && active_fors.length () == 0
5325 ? "'define_predicates', " : "");
5326
5327 eat_token (CPP_CLOSE_PAREN);
5328}
5329
2eef1fc1
RB
5330/* Helper for finish_match_operand, collecting captures of OP in CPTS
5331 recursively. */
5332
5333static void
00dcc88a 5334walk_captures (operand *op, vec<vec<capture *> > &cpts)
2eef1fc1
RB
5335{
5336 if (! op)
5337 return;
5338
5339 if (capture *c = dyn_cast <capture *> (op))
5340 {
5341 cpts[c->where].safe_push (c);
5342 walk_captures (c->what, cpts);
5343 }
5344 else if (expr *e = dyn_cast <expr *> (op))
5345 for (unsigned i = 0; i < e->ops.length (); ++i)
5346 walk_captures (e->ops[i], cpts);
5347}
5348
5349/* Finish up OP which is a match operand. */
5350
5351void
5352parser::finish_match_operand (operand *op)
5353{
5354 /* Look for matching captures, diagnose mis-uses of @@ and apply
5355 early lowering and distribution of value_match. */
5356 auto_vec<vec<capture *> > cpts;
cb3874dc 5357 cpts.safe_grow_cleared (capture_ids->elements (), true);
2eef1fc1
RB
5358 walk_captures (op, cpts);
5359 for (unsigned i = 0; i < cpts.length (); ++i)
5360 {
5361 capture *value_match = NULL;
5362 for (unsigned j = 0; j < cpts[i].length (); ++j)
5363 {
5364 if (cpts[i][j]->value_match)
5365 {
5366 if (value_match)
5367 fatal_at (cpts[i][j]->location, "duplicate @@");
5368 value_match = cpts[i][j];
5369 }
5370 }
5371 if (cpts[i].length () == 1 && value_match)
5372 fatal_at (value_match->location, "@@ without a matching capture");
5373 if (value_match)
5374 {
5375 /* Duplicate prevailing capture with the existing ID, create
5376 a fake ID and rewrite all captures to use it. This turns
5377 @@1 into @__<newid>@1 and @1 into @__<newid>. */
5378 value_match->what = new capture (value_match->location,
5379 value_match->where,
5380 value_match->what, false);
5381 /* Create a fake ID and rewrite all captures to use it. */
5382 unsigned newid = get_internal_capture_id ();
5383 for (unsigned j = 0; j < cpts[i].length (); ++j)
5384 {
5385 cpts[i][j]->where = newid;
5386 cpts[i][j]->value_match = true;
5387 }
5388 }
5389 cpts[i].release ();
5390 }
5391}
5392
3d2cf79f
RB
5393/* Main entry of the parser. Repeatedly parse outer control structures. */
5394
f2ec836a 5395parser::parser (cpp_reader *r_, bool gimple_)
3d2cf79f
RB
5396{
5397 r = r_;
f2ec836a 5398 gimple = gimple_;
3d2cf79f
RB
5399 active_ifs = vNULL;
5400 active_fors = vNULL;
5401 simplifiers = vNULL;
1c9b0448
RB
5402 oper_lists_set = NULL;
5403 oper_lists = vNULL;
d0af2c65 5404 capture_ids = NULL;
3d2cf79f 5405 user_predicates = vNULL;
72eb311d 5406 parsing_match_operand = false;
6c35e5b0 5407 last_id = 0;
3d2cf79f
RB
5408
5409 const cpp_token *token = next ();
5410 while (token->type != CPP_EOF)
5411 {
5412 _cpp_backup_tokens (r, 1);
5413 parse_pattern ();
5414 token = next ();
5415 }
5416}
5417
5418
5419/* Helper for the linemap code. */
5420
5421static size_t
5422round_alloc_size (size_t s)
5423{
5424 return s;
5425}
5426
5427
703417a0
TC
5428/* Construct and display the help menu. */
5429
5430static void
425198bb 5431usage ()
703417a0 5432{
425198bb
AM
5433 const char *usage = "Usage:\n"
5434 " %s [--gimple|--generic] [-v[v]] <input>\n"
5435 " %s [options] [--include=FILE] --header=FILE <input> <output>...\n";
5436 fprintf (stderr, usage, progname, progname);
703417a0
TC
5437}
5438
5439/* Write out the correct include to the match-head fle containing the helper
5440 files. */
5441
5442static void
5443write_header_includes (bool gimple, FILE *header_file)
5444{
5445 if (gimple)
5446 fprintf (header_file, "#include \"gimple-match-head.cc\"\n");
5447 else
5448 fprintf (header_file, "#include \"generic-match-head.cc\"\n");
5449}
5450
ef59e1fb 5451/* The genmatch generator program. It reads from a pattern description
3d2cf79f
RB
5452 and outputs GIMPLE or GENERIC IL matching and simplification routines. */
5453
5454int
5455main (int argc, char **argv)
5456{
5457 cpp_reader *r;
5458
5459 progname = "genmatch";
5460
3d2cf79f 5461 bool gimple = true;
703417a0
TC
5462 char *s_header_file = NULL;
5463 char *s_include_file = NULL;
5464 auto_vec <char *> files;
5465 char *input = NULL;
5466 int last_file = argc - 1;
5467 for (int i = argc - 1; i >= 1; --i)
3d2cf79f
RB
5468 {
5469 if (strcmp (argv[i], "--gimple") == 0)
5470 gimple = true;
5471 else if (strcmp (argv[i], "--generic") == 0)
5472 gimple = false;
703417a0
TC
5473 else if (strncmp (argv[i], "--header=", 9) == 0)
5474 s_header_file = &argv[i][9];
5475 else if (strncmp (argv[i], "--include=", 10) == 0)
5476 s_include_file = &argv[i][10];
3d2cf79f 5477 else if (strcmp (argv[i], "-v") == 0)
53a19317
RB
5478 verbose = 1;
5479 else if (strcmp (argv[i], "-vv") == 0)
5480 verbose = 2;
703417a0
TC
5481 else if (strncmp (argv[i], "--", 2) != 0 && last_file-- == i)
5482 files.safe_push (argv[i]);
3d2cf79f
RB
5483 else
5484 {
425198bb 5485 usage ();
3d2cf79f
RB
5486 return 1;
5487 }
5488 }
5489
703417a0
TC
5490 /* Validate if the combinations are valid. */
5491 if ((files.length () > 1 && !s_header_file) || files.is_empty ())
425198bb
AM
5492 {
5493 usage ();
5494 return 1;
5495 }
703417a0
TC
5496
5497 if (!s_include_file)
5498 s_include_file = s_header_file;
5499
5500 /* Input file is the last in the reverse list. */
5501 input = files.pop ();
5502
99b1c316 5503 line_table = XCNEW (class line_maps);
3d2cf79f 5504 linemap_init (line_table, 0);
1f68a3e8
DM
5505 line_table->m_reallocator = xrealloc;
5506 line_table->m_round_alloc_size = round_alloc_size;
3d2cf79f
RB
5507
5508 r = cpp_create_reader (CLK_GNUC99, NULL, line_table);
5509 cpp_callbacks *cb = cpp_get_callbacks (r);
c24300ba 5510 cb->diagnostic = diagnostic_cb;
3d2cf79f 5511
b1dc4a20
RS
5512 /* Add the build directory to the #include "" search path. */
5513 cpp_dir *dir = XCNEW (cpp_dir);
5514 dir->name = getpwd ();
5515 if (!dir->name)
5516 dir->name = ASTRDUP (".");
5517 cpp_set_include_chains (r, dir, NULL, false);
5518
3d2cf79f
RB
5519 if (!cpp_read_main_file (r, input))
5520 return 1;
5521 cpp_define (r, gimple ? "GIMPLE=1": "GENERIC=1");
5522 cpp_define (r, gimple ? "GENERIC=0": "GIMPLE=0");
5523
fa74b47a
RS
5524 null_id = new id_base (id_base::NULL_ID, "null");
5525
3d2cf79f
RB
5526 /* Pre-seed operators. */
5527 operators = new hash_table<id_base> (1024);
5528#define DEFTREECODE(SYM, STRING, TYPE, NARGS) \
5529 add_operator (SYM, # SYM, # TYPE, NARGS);
5530#define END_OF_BASE_TREE_CODES
5531#include "tree.def"
3d2cf79f
RB
5532#undef END_OF_BASE_TREE_CODES
5533#undef DEFTREECODE
5534
5535 /* Pre-seed builtin functions.
5536 ??? Cannot use N (name) as that is targetm.emultls.get_address
5537 for BUILT_IN_EMUTLS_GET_ADDRESS ... */
5538#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \
c9e926ce 5539 add_function (ENUM, "CFN_" # ENUM);
3d2cf79f 5540#include "builtins.def"
3d2cf79f 5541
c9e926ce
RS
5542#define DEF_INTERNAL_FN(CODE, NAME, FNSPEC) \
5543 add_function (IFN_##CODE, "CFN_" #CODE);
5544#include "internal-fn.def"
5545
3d2cf79f 5546 /* Parse ahead! */
f2ec836a 5547 parser p (r, gimple);
3d2cf79f 5548
703417a0
TC
5549 /* Create file buffers. */
5550 int n_parts = files.is_empty () ? 1 : files.length ();
5551 auto_vec <FILE *> parts (n_parts);
5552 if (files.is_empty ())
5553 {
5554 parts.quick_push (stdout);
5555 write_header (stdout, s_include_file);
5556 write_header_includes (gimple, stdout);
d9dc70cc 5557 write_header_declarations (gimple, stdout);
703417a0 5558 }
3d2cf79f 5559 else
703417a0
TC
5560 {
5561 for (char *s_file : files)
5562 {
5563 parts.quick_push (fopen (s_file, "w"));
5564 write_header (parts.last (), s_include_file);
5565 }
5566
5567 header_file = fopen (s_header_file, "w");
5568 fprintf (header_file, "#ifndef GCC_GIMPLE_MATCH_AUTO_H\n"
5569 "#define GCC_GIMPLE_MATCH_AUTO_H\n");
5570 write_header_includes (gimple, header_file);
d9dc70cc 5571 write_header_declarations (gimple, header_file);
703417a0 5572 }
3d2cf79f
RB
5573
5574 /* Go over all predicates defined with patterns and perform
5575 lowering and code generation. */
5576 for (unsigned i = 0; i < p.user_predicates.length (); ++i)
5577 {
5578 predicate_id *pred = p.user_predicates[i];
47b25362 5579 lower (pred->matchers, gimple);
3d2cf79f 5580
53a19317 5581 if (verbose == 2)
4e4791ff
BE
5582 for (unsigned j = 0; j < pred->matchers.length (); ++j)
5583 print_matches (pred->matchers[j]);
3d2cf79f
RB
5584
5585 decision_tree dt;
4e4791ff
BE
5586 for (unsigned j = 0; j < pred->matchers.length (); ++j)
5587 dt.insert (pred->matchers[j], j);
3d2cf79f 5588
53a19317 5589 if (verbose == 2)
3d2cf79f
RB
5590 dt.print (stderr);
5591
703417a0 5592 /* Cycle the file buffers. */
153eafaa 5593 FILE *f = choose_output (parts);
703417a0
TC
5594
5595 write_predicate (f, pred, dt, gimple);
3d2cf79f
RB
5596 }
5597
5598 /* Lower the main simplifiers and generate code for them. */
47b25362 5599 lower (p.simplifiers, gimple);
3d2cf79f 5600
53a19317 5601 if (verbose == 2)
3d2cf79f
RB
5602 for (unsigned i = 0; i < p.simplifiers.length (); ++i)
5603 print_matches (p.simplifiers[i]);
5604
5605 decision_tree dt;
5606 for (unsigned i = 0; i < p.simplifiers.length (); ++i)
5607 dt.insert (p.simplifiers[i], i);
5608
53a19317 5609 if (verbose == 2)
3d2cf79f
RB
5610 dt.print (stderr);
5611
703417a0
TC
5612 dt.gen (parts, gimple);
5613
d9dc70cc
AT
5614 define_dump_logs (gimple, choose_output (parts));
5615
703417a0
TC
5616 for (FILE *f : parts)
5617 {
5618 fprintf (f, "#pragma GCC diagnostic pop\n");
5619 fclose (f);
5620 }
5621
5622 if (header_file)
5623 {
2ed6dd97 5624 fprintf (header_file, "\n#endif /* GCC_GIMPLE_MATCH_AUTO_H. */\n");
703417a0
TC
5625 fclose (header_file);
5626 }
3d2cf79f
RB
5627
5628 /* Finalize. */
5629 cpp_finish (r, NULL);
5630 cpp_destroy (r);
5631
5632 delete operators;
5633
5634 return 0;
5635}