1 /* Generate pattern matching and transform code shared between
2 GENERIC and GIMPLE folding code from match-and-simplify description.
4 Copyright (C) 2014-2023 Free Software Foundation, Inc.
5 Contributed by Richard Biener <rguenther@suse.de>
6 and Prathamesh Kulkarni <bilbotheelffriend@gmail.com>
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
26 #include "coretypes.h"
29 #include "hash-table.h"
32 #include "ordered-hash-map.h"
35 /* Stubs for GGC referenced through instantiations triggered by hash-map. */
36 void *ggc_internal_cleared_alloc (size_t, void (*)(void *),
37 size_t, size_t MEM_STAT_DECL
)
41 void ggc_free (void *)
48 /* Verboseness. 0 is quiet, 1 adds some warnings, 2 is for debugging. */
54 static class line_maps
*line_table
;
56 /* The rich_location class within libcpp requires a way to expand
57 location_t instances, and relies on the client code
58 providing a symbol named
59 linemap_client_expand_location_to_spelling_point
62 This is the implementation for genmatch. */
65 linemap_client_expand_location_to_spelling_point (const line_maps
*set
,
69 const struct line_map_ordinary
*map
;
70 loc
= linemap_resolve_location (set
, loc
, LRK_SPELLING_LOCATION
, &map
);
71 return linemap_expand_location (set
, map
, loc
);
75 #if GCC_VERSION >= 4001
76 __attribute__((format (printf
, 5, 0)))
78 diagnostic_cb (cpp_reader
*, enum cpp_diagnostic_level errtype
,
79 enum cpp_warning_reason
, rich_location
*richloc
,
80 const char *msg
, va_list *ap
)
82 const line_map_ordinary
*map
;
83 location_t location
= richloc
->get_loc ();
84 linemap_resolve_location (line_table
, location
, LRK_SPELLING_LOCATION
, &map
);
85 expanded_location loc
= linemap_expand_location (line_table
, map
, location
);
86 fprintf (stderr
, "%s:%d:%d %s: ", loc
.file
, loc
.line
, loc
.column
,
87 (errtype
== CPP_DL_WARNING
) ? "warning" : "error");
88 vfprintf (stderr
, msg
, *ap
);
89 fprintf (stderr
, "\n");
90 FILE *f
= fopen (loc
.file
, "r");
96 if (!fgets (buf
, 128, f
))
98 if (buf
[strlen (buf
) - 1] != '\n')
105 fprintf (stderr
, "%s", buf
);
106 for (int i
= 0; i
< loc
.column
- 1; ++i
)
109 fputc ('\n', stderr
);
114 if (errtype
== CPP_DL_FATAL
)
120 #if GCC_VERSION >= 4001
121 __attribute__((format (printf
, 2, 3)))
123 fatal_at (const cpp_token
*tk
, const char *msg
, ...)
125 rich_location
richloc (line_table
, tk
->src_loc
);
128 diagnostic_cb (NULL
, CPP_DL_FATAL
, CPP_W_NONE
, &richloc
, msg
, &ap
);
133 #if GCC_VERSION >= 4001
134 __attribute__((format (printf
, 2, 3)))
136 fatal_at (location_t loc
, const char *msg
, ...)
138 rich_location
richloc (line_table
, loc
);
141 diagnostic_cb (NULL
, CPP_DL_FATAL
, CPP_W_NONE
, &richloc
, msg
, &ap
);
146 #if GCC_VERSION >= 4001
147 __attribute__((format (printf
, 2, 3)))
149 warning_at (const cpp_token
*tk
, const char *msg
, ...)
151 rich_location
richloc (line_table
, tk
->src_loc
);
154 diagnostic_cb (NULL
, CPP_DL_WARNING
, CPP_W_NONE
, &richloc
, msg
, &ap
);
159 #if GCC_VERSION >= 4001
160 __attribute__((format (printf
, 2, 3)))
162 warning_at (location_t loc
, const char *msg
, ...)
164 rich_location
richloc (line_table
, loc
);
167 diagnostic_cb (NULL
, CPP_DL_WARNING
, CPP_W_NONE
, &richloc
, msg
, &ap
);
171 /* Like fprintf, but print INDENT spaces at the beginning. */
174 #if GCC_VERSION >= 4001
175 __attribute__((format (printf
, 3, 4)))
177 fprintf_indent (FILE *f
, unsigned int indent
, const char *format
, ...)
180 for (; indent
>= 8; indent
-= 8)
182 fprintf (f
, "%*s", indent
, "");
183 va_start (ap
, format
);
184 vfprintf (f
, format
, ap
);
188 /* Secondary stream for fp_decl. */
189 static FILE *header_file
;
191 /* Start or continue emitting a declaration in fprintf-like manner,
192 printing both to F and global header_file, if non-null. */
194 #if GCC_VERSION >= 4001
195 __attribute__((format (printf
, 2, 3)))
197 fp_decl (FILE *f
, const char *format
, ...)
200 va_start (ap
, format
);
201 vfprintf (f
, format
, ap
);
207 va_start (ap
, format
);
208 vfprintf (header_file
, format
, ap
);
212 /* Finish a declaration being emitted by fp_decl. */
214 fp_decl_done (FILE *f
, const char *trailer
)
216 fprintf (f
, "%s\n", trailer
);
218 fprintf (header_file
, "%s;", trailer
);
221 /* Line numbers for use by indirect line directives. */
222 static vec
<int> dbg_line_numbers
;
225 write_header_declarations (bool gimple
, FILE *f
)
227 fprintf (f
, "\nextern void\n%s_dump_logs (const char *file1, int line1_id, "
228 "const char *file2, int line2, bool simplify);\n",
229 gimple
? "gimple" : "generic");
233 define_dump_logs (bool gimple
, FILE *f
)
235 if (dbg_line_numbers
.is_empty ())
238 fprintf (f
, "void\n%s_dump_logs (const char *file1, int line1_id, "
239 "const char *file2, int line2, bool simplify)\n{\n",
240 gimple
? "gimple" : "generic");
242 fprintf_indent (f
, 2, "static int dbg_line_numbers[%d] = {",
243 dbg_line_numbers
.length ());
245 for (unsigned i
= 0; i
< dbg_line_numbers
.length () - 1; i
++)
250 fprintf (f
, "%d, ", dbg_line_numbers
[i
]);
252 fprintf (f
, "%d\n };\n\n", dbg_line_numbers
.last ());
255 fprintf_indent (f
, 2, "fprintf (dump_file, \"%%s "
256 "%%s:%%d, %%s:%%d\\n\",\n");
257 fprintf_indent (f
, 10, "simplify ? \"Applying pattern\" : "
258 "\"Matching expression\", file1, "
259 "dbg_line_numbers[line1_id], file2, line2);");
261 fprintf (f
, "\n}\n\n");
265 output_line_directive (FILE *f
, location_t location
,
266 bool dumpfile
= false, bool fnargs
= false,
267 bool indirect_line_numbers
= false)
269 typedef pair_hash
<nofree_string_hash
, int_hash
<int, -1>> location_hash
;
270 static hash_map
<location_hash
, int> loc_id_map
;
271 const line_map_ordinary
*map
;
272 linemap_resolve_location (line_table
, location
, LRK_SPELLING_LOCATION
, &map
);
273 expanded_location loc
= linemap_expand_location (line_table
, map
, location
);
276 /* When writing to a dumpfile only dump the filename. */
277 const char *file
= strrchr (loc
.file
, DIR_SEPARATOR
);
278 #if defined(DIR_SEPARATOR_2)
279 const char *pos2
= strrchr (loc
.file
, DIR_SEPARATOR_2
);
280 if (pos2
&& (!file
|| (pos2
> file
)))
290 if (indirect_line_numbers
)
293 int &loc_id
= loc_id_map
.get_or_insert (
294 std::make_pair (file
, loc
.line
), &existed
);
297 loc_id
= dbg_line_numbers
.length ();
298 dbg_line_numbers
.safe_push (loc
.line
);
301 fprintf (f
, "\"%s\", %d", file
, loc_id
);
304 fprintf (f
, "\"%s\", %d", file
, loc
.line
);
307 fprintf (f
, "%s:%d", file
, loc
.line
);
309 else if (verbose
>= 2)
310 /* Other gen programs really output line directives here, at least for
311 development it's right now more convenient to have line information
312 from the generated file. Still keep the directives as comment for now
313 to easily back-point to the meta-description. */
314 fprintf (f
, "/* #line %d \"%s\" */\n", loc
.line
, loc
.file
);
317 /* Find the file to write into next. We try to evenly distribute the contents
318 over the different files. */
320 #define SIZED_BASED_CHUNKS 1
323 choose_output (const vec
<FILE *> &parts
)
325 #ifdef SIZED_BASED_CHUNKS
326 FILE *shortest
= NULL
;
328 for (FILE *part
: parts
)
330 long len
= ftell (part
);
331 if (!shortest
|| min
> len
)
332 shortest
= part
, min
= len
;
336 static int current_file
;
337 return parts
[current_file
++ % parts
.length ()];
342 /* Pull in tree codes and builtin function codes from their
345 #define DEFTREECODE(SYM, STRING, TYPE, NARGS) SYM,
352 #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) ENUM,
353 enum built_in_function
{
354 #include "builtins.def"
358 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) IFN_##CODE,
360 #include "internal-fn.def"
365 #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \
366 CFN_##ENUM = int (ENUM),
367 #include "builtins.def"
369 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
370 CFN_##CODE = int (END_BUILTINS) + int (IFN_##CODE),
371 #include "internal-fn.def"
376 #include "case-cfn-macros.h"
378 /* Return true if CODE represents a commutative tree code. Otherwise
381 commutative_tree_code (enum tree_code code
)
387 case MULT_HIGHPART_EXPR
:
402 case WIDEN_MULT_EXPR
:
403 case VEC_WIDEN_MULT_HI_EXPR
:
404 case VEC_WIDEN_MULT_LO_EXPR
:
405 case VEC_WIDEN_MULT_EVEN_EXPR
:
406 case VEC_WIDEN_MULT_ODD_EXPR
:
415 /* Return true if CODE represents a ternary tree code for which the
416 first two operands are commutative. Otherwise return false. */
418 commutative_ternary_tree_code (enum tree_code code
)
422 case WIDEN_MULT_PLUS_EXPR
:
423 case WIDEN_MULT_MINUS_EXPR
:
433 /* Return true if CODE is a comparison. */
436 comparison_code_p (enum tree_code code
)
463 /* Base class for all identifiers the parser knows. */
465 class id_base
: public nofree_ptr_hash
<id_base
>
468 enum id_kind
{ CODE
, FN
, PREDICATE
, USER
, NULL_ID
} kind
;
470 id_base (id_kind
, const char *, int = -1);
476 /* hash_table support. */
477 static inline hashval_t
hash (const id_base
*);
478 static inline int equal (const id_base
*, const id_base
*);
482 id_base::hash (const id_base
*op
)
488 id_base::equal (const id_base
*op1
,
491 return (op1
->hashval
== op2
->hashval
492 && strcmp (op1
->id
, op2
->id
) == 0);
495 /* The special id "null", which matches nothing. */
496 static id_base
*null_id
;
498 /* Hashtable of known pattern operators. This is pre-seeded from
499 all known tree codes and all known builtin function ids. */
500 static hash_table
<id_base
> *operators
;
502 id_base::id_base (id_kind kind_
, const char *id_
, int nargs_
)
507 hashval
= htab_hash_string (id
);
510 /* Identifier that maps to a tree code. */
512 class operator_id
: public id_base
515 operator_id (enum tree_code code_
, const char *id_
, unsigned nargs_
,
517 : id_base (id_base::CODE
, id_
, nargs_
), code (code_
), tcc (tcc_
) {}
522 /* Identifier that maps to a builtin or internal function code. */
524 class fn_id
: public id_base
527 fn_id (enum built_in_function fn_
, const char *id_
)
528 : id_base (id_base::FN
, id_
), fn (fn_
) {}
529 fn_id (enum internal_fn fn_
, const char *id_
)
530 : id_base (id_base::FN
, id_
), fn (int (END_BUILTINS
) + int (fn_
)) {}
536 /* Identifier that maps to a user-defined predicate. */
538 class predicate_id
: public id_base
541 predicate_id (const char *id_
)
542 : id_base (id_base::PREDICATE
, id_
), matchers (vNULL
) {}
543 vec
<simplify
*> matchers
;
546 /* Identifier that maps to a operator defined by a 'for' directive. */
548 class user_id
: public id_base
551 user_id (const char *id_
, bool is_oper_list_
= false)
552 : id_base (id_base::USER
, id_
), substitutes (vNULL
),
553 used (false), is_oper_list (is_oper_list_
) {}
554 vec
<id_base
*> substitutes
;
562 is_a_helper
<fn_id
*>::test (id_base
*id
)
564 return id
->kind
== id_base::FN
;
570 is_a_helper
<operator_id
*>::test (id_base
*id
)
572 return id
->kind
== id_base::CODE
;
578 is_a_helper
<predicate_id
*>::test (id_base
*id
)
580 return id
->kind
== id_base::PREDICATE
;
586 is_a_helper
<user_id
*>::test (id_base
*id
)
588 return id
->kind
== id_base::USER
;
591 /* If ID has a pair of consecutive, commutative operands, return the
592 index of the first, otherwise return -1. */
595 commutative_op (id_base
*id
)
597 if (operator_id
*code
= dyn_cast
<operator_id
*> (id
))
599 if (commutative_tree_code (code
->code
)
600 || commutative_ternary_tree_code (code
->code
))
604 if (fn_id
*fn
= dyn_cast
<fn_id
*> (id
))
626 case CFN_COND_LEN_ADD
:
627 case CFN_COND_LEN_MUL
:
628 case CFN_COND_LEN_MIN
:
629 case CFN_COND_LEN_MAX
:
630 case CFN_COND_LEN_FMIN
:
631 case CFN_COND_LEN_FMAX
:
632 case CFN_COND_LEN_AND
:
633 case CFN_COND_LEN_IOR
:
634 case CFN_COND_LEN_XOR
:
635 case CFN_COND_LEN_FMA
:
636 case CFN_COND_LEN_FMS
:
637 case CFN_COND_LEN_FNMA
:
638 case CFN_COND_LEN_FNMS
:
644 if (user_id
*uid
= dyn_cast
<user_id
*> (id
))
646 int res
= commutative_op (uid
->substitutes
[0]);
649 for (unsigned i
= 1; i
< uid
->substitutes
.length (); ++i
)
650 if (res
!= commutative_op (uid
->substitutes
[i
]))
657 /* Add a predicate identifier to the hash. */
659 static predicate_id
*
660 add_predicate (const char *id
)
662 predicate_id
*p
= new predicate_id (id
);
663 id_base
**slot
= operators
->find_slot_with_hash (p
, p
->hashval
, INSERT
);
665 fatal ("duplicate id definition");
670 /* Add a tree code identifier to the hash. */
673 add_operator (enum tree_code code
, const char *id
,
674 const char *tcc
, unsigned nargs
)
676 if (strcmp (tcc
, "tcc_unary") != 0
677 && strcmp (tcc
, "tcc_binary") != 0
678 && strcmp (tcc
, "tcc_comparison") != 0
679 && strcmp (tcc
, "tcc_expression") != 0
680 /* For {REAL,IMAG}PART_EXPR and VIEW_CONVERT_EXPR. */
681 && strcmp (tcc
, "tcc_reference") != 0
682 /* To have INTEGER_CST and friends as "predicate operators". */
683 && strcmp (tcc
, "tcc_constant") != 0
684 /* And allow CONSTRUCTOR for vector initializers. */
685 && !(code
== CONSTRUCTOR
)
686 /* Allow SSA_NAME as predicate operator. */
687 && !(code
== SSA_NAME
))
689 /* Treat ADDR_EXPR as atom, thus don't allow matching its operand. */
690 if (code
== ADDR_EXPR
)
692 operator_id
*op
= new operator_id (code
, id
, nargs
, tcc
);
693 id_base
**slot
= operators
->find_slot_with_hash (op
, op
->hashval
, INSERT
);
695 fatal ("duplicate id definition");
699 /* Add a built-in or internal function identifier to the hash. ID is
700 the name of its CFN_* enumeration value. */
702 template <typename T
>
704 add_function (T code
, const char *id
)
706 fn_id
*fn
= new fn_id (code
, id
);
707 id_base
**slot
= operators
->find_slot_with_hash (fn
, fn
->hashval
, INSERT
);
709 fatal ("duplicate id definition");
713 /* Helper for easy comparing ID with tree code CODE. */
716 operator==(id_base
&id
, enum tree_code code
)
718 if (operator_id
*oid
= dyn_cast
<operator_id
*> (&id
))
719 return oid
->code
== code
;
723 /* Lookup the identifier ID. Allow "null" if ALLOW_NULL. */
726 get_operator (const char *id
, bool allow_null
= false)
728 if (allow_null
&& strcmp (id
, "null") == 0)
731 id_base
tem (id_base::CODE
, id
);
733 id_base
*op
= operators
->find_with_hash (&tem
, tem
.hashval
);
736 /* If this is a user-defined identifier track whether it was used. */
737 if (user_id
*uid
= dyn_cast
<user_id
*> (op
))
743 bool all_upper
= true;
744 bool all_lower
= true;
745 for (unsigned int i
= 0; id
[i
]; ++i
)
748 else if (ISLOWER (id
[i
]))
752 /* Try in caps with _EXPR appended. */
753 id2
= ACONCAT ((id
, "_EXPR", NULL
));
754 for (unsigned int i
= 0; id2
[i
]; ++i
)
755 id2
[i
] = TOUPPER (id2
[i
]);
757 else if (all_upper
&& startswith (id
, "IFN_"))
758 /* Try CFN_ instead of IFN_. */
759 id2
= ACONCAT (("CFN_", id
+ 4, NULL
));
760 else if (all_upper
&& startswith (id
, "BUILT_IN_"))
761 /* Try prepending CFN_. */
762 id2
= ACONCAT (("CFN_", id
, NULL
));
766 new (&tem
) id_base (id_base::CODE
, id2
);
767 return operators
->find_with_hash (&tem
, tem
.hashval
);
770 /* Return the comparison operators that results if the operands are
771 swapped. This is safe for floating-point. */
774 swap_tree_comparison (operator_id
*p
)
786 return get_operator ("LT_EXPR");
788 return get_operator ("LE_EXPR");
790 return get_operator ("GT_EXPR");
792 return get_operator ("GE_EXPR");
794 return get_operator ("UNLT_EXPR");
796 return get_operator ("UNLE_EXPR");
798 return get_operator ("UNGT_EXPR");
800 return get_operator ("UNGE_EXPR");
806 typedef hash_map
<nofree_string_hash
, unsigned> cid_map_t
;
809 /* The AST produced by parsing of the pattern definitions. */
814 /* The base class for operands. */
818 enum op_type
{ OP_PREDICATE
, OP_EXPR
, OP_CAPTURE
, OP_C_EXPR
, OP_IF
, OP_WITH
};
819 operand (enum op_type type_
, location_t loc_
)
820 : type (type_
), location (loc_
) {}
823 virtual void gen_transform (FILE *, int, const char *, bool, int,
824 const char *, capture_info
*,
827 { gcc_unreachable (); }
830 /* A predicate operand. Predicates are leafs in the AST. */
832 class predicate
: public operand
835 predicate (predicate_id
*p_
, location_t loc
)
836 : operand (OP_PREDICATE
, loc
), p (p_
) {}
840 /* An operand that constitutes an expression. Expressions include
841 function calls and user-defined predicate invocations. */
843 class expr
: public operand
846 expr (id_base
*operation_
, location_t loc
, bool is_commutative_
= false)
847 : operand (OP_EXPR
, loc
), operation (operation_
),
848 ops (vNULL
), expr_type (NULL
), is_commutative (is_commutative_
),
849 is_generic (false), force_single_use (false), force_leaf (false),
852 : operand (OP_EXPR
, e
->location
), operation (e
->operation
),
853 ops (vNULL
), expr_type (e
->expr_type
), is_commutative (e
->is_commutative
),
854 is_generic (e
->is_generic
), force_single_use (e
->force_single_use
),
855 force_leaf (e
->force_leaf
), opt_grp (e
->opt_grp
) {}
856 void append_op (operand
*op
) { ops
.safe_push (op
); }
857 /* The operator and its operands. */
860 /* An explicitely specified type - used exclusively for conversions. */
861 const char *expr_type
;
862 /* Whether the operation is to be applied commutatively. This is
863 later lowered to two separate patterns. */
865 /* Whether the expression is expected to be in GENERIC form. */
867 /* Whether pushing any stmt to the sequence should be conditional
868 on this expression having a single-use. */
869 bool force_single_use
;
870 /* Whether in the result expression this should be a leaf node
871 with any children simplified down to simple operands. */
873 /* If non-zero, the group for optional handling. */
874 unsigned char opt_grp
;
875 void gen_transform (FILE *f
, int, const char *, bool, int,
876 const char *, capture_info
*,
877 dt_operand
** = 0, int = 0) override
;
880 /* An operator that is represented by native C code. This is always
881 a leaf operand in the AST. This class is also used to represent
882 the code to be generated for 'if' and 'with' expressions. */
884 class c_expr
: public operand
887 /* A mapping of an identifier and its replacement. Used to apply
893 id_tab (const char *id_
, const char *oper_
): id (id_
), oper (oper_
) {}
896 c_expr (cpp_reader
*r_
, location_t loc
,
897 vec
<cpp_token
> code_
, unsigned nr_stmts_
,
898 vec
<id_tab
> ids_
, cid_map_t
*capture_ids_
)
899 : operand (OP_C_EXPR
, loc
), r (r_
), code (code_
),
900 capture_ids (capture_ids_
), nr_stmts (nr_stmts_
), ids (ids_
) {}
901 /* cpplib tokens and state to transform this back to source. */
904 cid_map_t
*capture_ids
;
905 /* The number of statements parsed (well, the number of ';'s). */
907 /* The identifier replacement vector. */
909 void gen_transform (FILE *f
, int, const char *, bool, int,
910 const char *, capture_info
*,
911 dt_operand
** = 0, int = 0) final override
;
914 /* A wrapper around another operand that captures its value. */
916 class capture
: public operand
919 capture (location_t loc
, unsigned where_
, operand
*what_
, bool value_
)
920 : operand (OP_CAPTURE
, loc
), where (where_
), value_match (value_
),
922 /* Identifier index for the value. */
924 /* Whether in a match of two operands the compare should be for
925 equal values rather than equal atoms (boils down to a type
928 /* The captured value. */
930 void gen_transform (FILE *f
, int, const char *, bool, int,
931 const char *, capture_info
*,
932 dt_operand
** = 0, int = 0) final override
;
937 class if_expr
: public operand
940 if_expr (location_t loc
)
941 : operand (OP_IF
, loc
), cond (NULL
), trueexpr (NULL
), falseexpr (NULL
) {}
947 /* with expression. */
949 class with_expr
: public operand
952 with_expr (location_t loc
)
953 : operand (OP_WITH
, loc
), with (NULL
), subexpr (NULL
) {}
961 is_a_helper
<capture
*>::test (operand
*op
)
963 return op
->type
== operand::OP_CAPTURE
;
969 is_a_helper
<predicate
*>::test (operand
*op
)
971 return op
->type
== operand::OP_PREDICATE
;
977 is_a_helper
<c_expr
*>::test (operand
*op
)
979 return op
->type
== operand::OP_C_EXPR
;
985 is_a_helper
<expr
*>::test (operand
*op
)
987 return op
->type
== operand::OP_EXPR
;
993 is_a_helper
<if_expr
*>::test (operand
*op
)
995 return op
->type
== operand::OP_IF
;
1001 is_a_helper
<with_expr
*>::test (operand
*op
)
1003 return op
->type
== operand::OP_WITH
;
1006 /* The main class of a pattern and its transform. This is used to
1007 represent both (simplify ...) and (match ...) kinds. The AST
1008 duplicates all outer 'if' and 'for' expressions here so each
1009 simplify can exist in isolation. */
1014 enum simplify_kind
{ SIMPLIFY
, MATCH
};
1016 simplify (simplify_kind kind_
, unsigned id_
, operand
*match_
,
1017 operand
*result_
, vec
<vec
<user_id
*> > for_vec_
,
1018 cid_map_t
*capture_ids_
)
1019 : kind (kind_
), id (id_
), match (match_
), result (result_
),
1020 for_vec (for_vec_
), for_subst_vec (vNULL
),
1021 capture_ids (capture_ids_
), capture_max (capture_ids_
->elements () - 1) {}
1024 /* ID. This is kept to easily associate related simplifies expanded
1025 from the same original one. */
1027 /* The expression that is matched against the GENERIC or GIMPLE IL. */
1029 /* For a (simplify ...) an expression with ifs and withs with the expression
1030 produced when the pattern applies in the leafs.
1031 For a (match ...) the leafs are either empty if it is a simple predicate
1032 or the single expression specifying the matched operands. */
1033 class operand
*result
;
1034 /* Collected 'for' expression operators that have to be replaced
1035 in the lowering phase. */
1036 vec
<vec
<user_id
*> > for_vec
;
1037 vec
<std::pair
<user_id
*, id_base
*> > for_subst_vec
;
1038 /* A map of capture identifiers to indexes. */
1039 cid_map_t
*capture_ids
;
1043 /* Debugging routines for dumping the AST. */
1046 print_operand (operand
*o
, FILE *f
= stderr
, bool flattened
= false)
1048 if (capture
*c
= dyn_cast
<capture
*> (o
))
1050 if (c
->what
&& flattened
== false)
1051 print_operand (c
->what
, f
, flattened
);
1052 fprintf (f
, "@%u", c
->where
);
1055 else if (predicate
*p
= dyn_cast
<predicate
*> (o
))
1056 fprintf (f
, "%s", p
->p
->id
);
1058 else if (is_a
<c_expr
*> (o
))
1059 fprintf (f
, "c_expr");
1061 else if (expr
*e
= dyn_cast
<expr
*> (o
))
1063 if (e
->ops
.length () == 0)
1064 fprintf (f
, "%s", e
->operation
->id
);
1067 fprintf (f
, "(%s", e
->operation
->id
);
1069 if (flattened
== false)
1071 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1074 print_operand (e
->ops
[i
], f
, flattened
);
1086 print_matches (class simplify
*s
, FILE *f
= stderr
)
1088 fprintf (f
, "for expression: ");
1089 print_operand (s
->match
, f
);
1096 /* Lowering of commutative operators. */
1099 cartesian_product (const vec
< vec
<operand
*> >& ops_vector
,
1100 vec
< vec
<operand
*> >& result
, vec
<operand
*>& v
, unsigned n
)
1102 if (n
== ops_vector
.length ())
1104 vec
<operand
*> xv
= v
.copy ();
1105 result
.safe_push (xv
);
1109 for (unsigned i
= 0; i
< ops_vector
[n
].length (); ++i
)
1111 v
[n
] = ops_vector
[n
][i
];
1112 cartesian_product (ops_vector
, result
, v
, n
+ 1);
1116 /* Lower OP to two operands in case it is marked as commutative. */
1118 static vec
<operand
*>
1119 commutate (operand
*op
, vec
<vec
<user_id
*> > &for_vec
)
1121 vec
<operand
*> ret
= vNULL
;
1123 if (capture
*c
= dyn_cast
<capture
*> (op
))
1130 vec
<operand
*> v
= commutate (c
->what
, for_vec
);
1131 for (unsigned i
= 0; i
< v
.length (); ++i
)
1133 capture
*nc
= new capture (c
->location
, c
->where
, v
[i
],
1140 expr
*e
= dyn_cast
<expr
*> (op
);
1141 if (!e
|| e
->ops
.length () == 0)
1147 vec
< vec
<operand
*> > ops_vector
= vNULL
;
1148 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1149 ops_vector
.safe_push (commutate (e
->ops
[i
], for_vec
));
1151 auto_vec
< vec
<operand
*> > result
;
1152 auto_vec
<operand
*> v (e
->ops
.length ());
1153 v
.quick_grow_cleared (e
->ops
.length ());
1154 cartesian_product (ops_vector
, result
, v
, 0);
1157 for (unsigned i
= 0; i
< result
.length (); ++i
)
1159 expr
*ne
= new expr (e
);
1160 ne
->is_commutative
= false;
1161 for (unsigned j
= 0; j
< result
[i
].length (); ++j
)
1162 ne
->append_op (result
[i
][j
]);
1166 if (!e
->is_commutative
)
1169 /* The operation is always binary if it isn't inherently commutative. */
1170 int natural_opno
= commutative_op (e
->operation
);
1171 unsigned int opno
= natural_opno
>= 0 ? natural_opno
: 0;
1172 for (unsigned i
= 0; i
< result
.length (); ++i
)
1174 expr
*ne
= new expr (e
);
1175 if (operator_id
*r
= dyn_cast
<operator_id
*> (ne
->operation
))
1177 if (comparison_code_p (r
->code
))
1178 ne
->operation
= swap_tree_comparison (r
);
1180 else if (user_id
*p
= dyn_cast
<user_id
*> (ne
->operation
))
1182 bool found_compare
= false;
1183 for (unsigned j
= 0; j
< p
->substitutes
.length (); ++j
)
1184 if (operator_id
*q
= dyn_cast
<operator_id
*> (p
->substitutes
[j
]))
1186 if (comparison_code_p (q
->code
)
1187 && swap_tree_comparison (q
) != q
)
1189 found_compare
= true;
1195 user_id
*newop
= new user_id ("<internal>");
1196 for (unsigned j
= 0; j
< p
->substitutes
.length (); ++j
)
1198 id_base
*subst
= p
->substitutes
[j
];
1199 if (operator_id
*q
= dyn_cast
<operator_id
*> (subst
))
1201 if (comparison_code_p (q
->code
))
1202 subst
= swap_tree_comparison (q
);
1204 newop
->substitutes
.safe_push (subst
);
1206 ne
->operation
= newop
;
1207 /* Search for 'p' inside the for vector and push 'newop'
1208 to the same level. */
1209 for (unsigned j
= 0; newop
&& j
< for_vec
.length (); ++j
)
1210 for (unsigned k
= 0; k
< for_vec
[j
].length (); ++k
)
1211 if (for_vec
[j
][k
] == p
)
1213 for_vec
[j
].safe_push (newop
);
1219 ne
->is_commutative
= false;
1220 for (unsigned j
= 0; j
< result
[i
].length (); ++j
)
1222 int old_j
= (j
== opno
? opno
+ 1 : j
== opno
+ 1 ? opno
: j
);
1223 ne
->append_op (result
[i
][old_j
]);
1231 /* Lower operations marked as commutative in the AST of S and push
1232 the resulting patterns to SIMPLIFIERS. */
1235 lower_commutative (simplify
*s
, vec
<simplify
*>& simplifiers
)
1237 vec
<operand
*> matchers
= commutate (s
->match
, s
->for_vec
);
1238 for (unsigned i
= 0; i
< matchers
.length (); ++i
)
1240 simplify
*ns
= new simplify (s
->kind
, s
->id
, matchers
[i
], s
->result
,
1241 s
->for_vec
, s
->capture_ids
);
1242 simplifiers
.safe_push (ns
);
1246 /* Strip conditional operations using group GRP from O and its
1247 children if STRIP, else replace them with an unconditional operation. */
1250 lower_opt (operand
*o
, unsigned char grp
, bool strip
)
1252 if (capture
*c
= dyn_cast
<capture
*> (o
))
1255 return new capture (c
->location
, c
->where
,
1256 lower_opt (c
->what
, grp
, strip
),
1262 expr
*e
= dyn_cast
<expr
*> (o
);
1266 if (e
->opt_grp
== grp
)
1269 return lower_opt (e
->ops
[0], grp
, strip
);
1271 expr
*ne
= new expr (e
);
1273 ne
->append_op (lower_opt (e
->ops
[0], grp
, strip
));
1277 expr
*ne
= new expr (e
);
1278 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1279 ne
->append_op (lower_opt (e
->ops
[i
], grp
, strip
));
1284 /* Determine whether O or its children uses the conditional operation
1288 has_opt (operand
*o
, unsigned char grp
)
1290 if (capture
*c
= dyn_cast
<capture
*> (o
))
1293 return has_opt (c
->what
, grp
);
1298 expr
*e
= dyn_cast
<expr
*> (o
);
1302 if (e
->opt_grp
== grp
)
1305 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1306 if (has_opt (e
->ops
[i
], grp
))
1312 /* Lower conditional convert operators in O, expanding it to a vector
1315 static vec
<operand
*>
1316 lower_opt (operand
*o
)
1318 vec
<operand
*> v1
= vNULL
, v2
;
1322 /* Conditional operations are lowered to a pattern with the
1323 operation and one without. All different conditional operation
1324 groups are lowered separately. */
1326 for (unsigned i
= 1; i
<= 10; ++i
)
1329 for (unsigned j
= 0; j
< v1
.length (); ++j
)
1330 if (has_opt (v1
[j
], i
))
1332 v2
.safe_push (lower_opt (v1
[j
], i
, false));
1333 v2
.safe_push (lower_opt (v1
[j
], i
, true));
1339 for (unsigned j
= 0; j
< v2
.length (); ++j
)
1340 v1
.safe_push (v2
[j
]);
1347 /* Lower conditional convert operators in the AST of S and push
1348 the resulting multiple patterns to SIMPLIFIERS. */
1351 lower_opt (simplify
*s
, vec
<simplify
*>& simplifiers
)
1353 vec
<operand
*> matchers
= lower_opt (s
->match
);
1354 for (unsigned i
= 0; i
< matchers
.length (); ++i
)
1356 simplify
*ns
= new simplify (s
->kind
, s
->id
, matchers
[i
], s
->result
,
1357 s
->for_vec
, s
->capture_ids
);
1358 simplifiers
.safe_push (ns
);
1362 /* Lower the compare operand of COND_EXPRs to a
1363 GENERIC and a GIMPLE variant. */
1365 static vec
<operand
*>
1366 lower_cond (operand
*o
)
1368 vec
<operand
*> ro
= vNULL
;
1370 if (capture
*c
= dyn_cast
<capture
*> (o
))
1374 vec
<operand
*> lop
= vNULL
;
1375 lop
= lower_cond (c
->what
);
1377 for (unsigned i
= 0; i
< lop
.length (); ++i
)
1378 ro
.safe_push (new capture (c
->location
, c
->where
, lop
[i
],
1384 expr
*e
= dyn_cast
<expr
*> (o
);
1385 if (!e
|| e
->ops
.length () == 0)
1391 vec
< vec
<operand
*> > ops_vector
= vNULL
;
1392 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1393 ops_vector
.safe_push (lower_cond (e
->ops
[i
]));
1395 auto_vec
< vec
<operand
*> > result
;
1396 auto_vec
<operand
*> v (e
->ops
.length ());
1397 v
.quick_grow_cleared (e
->ops
.length ());
1398 cartesian_product (ops_vector
, result
, v
, 0);
1400 for (unsigned i
= 0; i
< result
.length (); ++i
)
1402 expr
*ne
= new expr (e
);
1403 for (unsigned j
= 0; j
< result
[i
].length (); ++j
)
1404 ne
->append_op (result
[i
][j
]);
1406 /* If this is a COND with a captured expression or an
1407 expression with two operands then also match a GENERIC
1408 form on the compare. */
1409 if (*e
->operation
== COND_EXPR
1410 && ((is_a
<capture
*> (e
->ops
[0])
1411 && as_a
<capture
*> (e
->ops
[0])->what
1412 && is_a
<expr
*> (as_a
<capture
*> (e
->ops
[0])->what
)
1414 (as_a
<capture
*> (e
->ops
[0])->what
)->ops
.length () == 2)
1415 || (is_a
<expr
*> (e
->ops
[0])
1416 && as_a
<expr
*> (e
->ops
[0])->ops
.length () == 2)))
1419 for (unsigned j
= 0; j
< result
[i
].length (); ++j
)
1420 ne
->append_op (result
[i
][j
]);
1421 if (capture
*c
= dyn_cast
<capture
*> (ne
->ops
[0]))
1423 expr
*ocmp
= as_a
<expr
*> (c
->what
);
1424 expr
*cmp
= new expr (ocmp
);
1425 for (unsigned j
= 0; j
< ocmp
->ops
.length (); ++j
)
1426 cmp
->append_op (ocmp
->ops
[j
]);
1427 cmp
->is_generic
= true;
1428 ne
->ops
[0] = new capture (c
->location
, c
->where
, cmp
,
1433 expr
*ocmp
= as_a
<expr
*> (ne
->ops
[0]);
1434 expr
*cmp
= new expr (ocmp
);
1435 for (unsigned j
= 0; j
< ocmp
->ops
.length (); ++j
)
1436 cmp
->append_op (ocmp
->ops
[j
]);
1437 cmp
->is_generic
= true;
1447 /* Lower the compare operand of COND_EXPRs to a
1448 GENERIC and a GIMPLE variant. */
1451 lower_cond (simplify
*s
, vec
<simplify
*>& simplifiers
)
1453 vec
<operand
*> matchers
= lower_cond (s
->match
);
1454 for (unsigned i
= 0; i
< matchers
.length (); ++i
)
1456 simplify
*ns
= new simplify (s
->kind
, s
->id
, matchers
[i
], s
->result
,
1457 s
->for_vec
, s
->capture_ids
);
1458 ns
->for_subst_vec
.safe_splice (s
->for_subst_vec
);
1459 simplifiers
.safe_push (ns
);
1463 /* Return true if O refers to ID. */
1466 contains_id (operand
*o
, user_id
*id
)
1468 if (capture
*c
= dyn_cast
<capture
*> (o
))
1469 return c
->what
&& contains_id (c
->what
, id
);
1471 if (expr
*e
= dyn_cast
<expr
*> (o
))
1473 if (e
->operation
== id
)
1475 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1476 if (contains_id (e
->ops
[i
], id
))
1481 if (with_expr
*w
= dyn_cast
<with_expr
*> (o
))
1482 return (contains_id (w
->with
, id
)
1483 || contains_id (w
->subexpr
, id
));
1485 if (if_expr
*ife
= dyn_cast
<if_expr
*> (o
))
1486 return (contains_id (ife
->cond
, id
)
1487 || contains_id (ife
->trueexpr
, id
)
1488 || (ife
->falseexpr
&& contains_id (ife
->falseexpr
, id
)));
1490 if (c_expr
*ce
= dyn_cast
<c_expr
*> (o
))
1491 return ce
->capture_ids
&& ce
->capture_ids
->get (id
->id
);
1497 /* In AST operand O replace operator ID with operator WITH. */
1500 replace_id (operand
*o
, user_id
*id
, id_base
*with
)
1502 /* Deep-copy captures and expressions, replacing operations as
1504 if (capture
*c
= dyn_cast
<capture
*> (o
))
1508 return new capture (c
->location
, c
->where
,
1509 replace_id (c
->what
, id
, with
), c
->value_match
);
1511 else if (expr
*e
= dyn_cast
<expr
*> (o
))
1513 expr
*ne
= new expr (e
);
1514 if (e
->operation
== id
)
1515 ne
->operation
= with
;
1516 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1517 ne
->append_op (replace_id (e
->ops
[i
], id
, with
));
1520 else if (with_expr
*w
= dyn_cast
<with_expr
*> (o
))
1522 with_expr
*nw
= new with_expr (w
->location
);
1523 nw
->with
= as_a
<c_expr
*> (replace_id (w
->with
, id
, with
));
1524 nw
->subexpr
= replace_id (w
->subexpr
, id
, with
);
1527 else if (if_expr
*ife
= dyn_cast
<if_expr
*> (o
))
1529 if_expr
*nife
= new if_expr (ife
->location
);
1530 nife
->cond
= as_a
<c_expr
*> (replace_id (ife
->cond
, id
, with
));
1531 nife
->trueexpr
= replace_id (ife
->trueexpr
, id
, with
);
1533 nife
->falseexpr
= replace_id (ife
->falseexpr
, id
, with
);
1537 /* For c_expr we simply record a string replacement table which is
1538 applied at code-generation time. */
1539 if (c_expr
*ce
= dyn_cast
<c_expr
*> (o
))
1541 vec
<c_expr::id_tab
> ids
= ce
->ids
.copy ();
1542 ids
.safe_push (c_expr::id_tab (id
->id
, with
->id
));
1543 return new c_expr (ce
->r
, ce
->location
,
1544 ce
->code
, ce
->nr_stmts
, ids
, ce
->capture_ids
);
1550 /* Return true if the binary operator OP is ok for delayed substitution
1551 during for lowering. */
1554 binary_ok (operator_id
*op
)
1561 case TRUNC_DIV_EXPR
:
1563 case FLOOR_DIV_EXPR
:
1564 case ROUND_DIV_EXPR
:
1565 case TRUNC_MOD_EXPR
:
1567 case FLOOR_MOD_EXPR
:
1568 case ROUND_MOD_EXPR
:
1570 case EXACT_DIV_EXPR
:
1582 /* Lower recorded fors for SIN and output to SIMPLIFIERS. */
1585 lower_for (simplify
*sin
, vec
<simplify
*>& simplifiers
)
1587 vec
<vec
<user_id
*> >& for_vec
= sin
->for_vec
;
1588 unsigned worklist_start
= 0;
1589 auto_vec
<simplify
*> worklist
;
1590 worklist
.safe_push (sin
);
1592 /* Lower each recorded for separately, operating on the
1593 set of simplifiers created by the previous one.
1594 Lower inner-to-outer so inner for substitutes can refer
1595 to operators replaced by outer fors. */
1596 for (int fi
= for_vec
.length () - 1; fi
>= 0; --fi
)
1598 vec
<user_id
*>& ids
= for_vec
[fi
];
1599 unsigned n_ids
= ids
.length ();
1600 unsigned max_n_opers
= 0;
1601 bool can_delay_subst
= true;
1602 for (unsigned i
= 0; i
< n_ids
; ++i
)
1604 if (ids
[i
]->substitutes
.length () > max_n_opers
)
1605 max_n_opers
= ids
[i
]->substitutes
.length ();
1606 /* Require that all substitutes are of the same kind so that
1607 if we delay substitution to the result op code generation
1608 can look at the first substitute for deciding things like
1609 types of operands. */
1610 enum id_base::id_kind kind
= ids
[i
]->substitutes
[0]->kind
;
1611 for (unsigned j
= 0; j
< ids
[i
]->substitutes
.length (); ++j
)
1612 if (ids
[i
]->substitutes
[j
]->kind
!= kind
)
1613 can_delay_subst
= false;
1614 else if (operator_id
*op
1615 = dyn_cast
<operator_id
*> (ids
[i
]->substitutes
[j
]))
1618 = as_a
<operator_id
*> (ids
[i
]->substitutes
[0]);
1619 if (strcmp (op
->tcc
, "tcc_comparison") == 0
1620 && strcmp (op0
->tcc
, "tcc_comparison") == 0)
1622 /* Unfortunately we can't just allow all tcc_binary. */
1623 else if (strcmp (op
->tcc
, "tcc_binary") == 0
1624 && strcmp (op0
->tcc
, "tcc_binary") == 0
1628 else if ((strcmp (op
->id
+ 1, "SHIFT_EXPR") == 0
1629 || strcmp (op
->id
+ 1, "ROTATE_EXPR") == 0)
1630 && (strcmp (op0
->id
+ 1, "SHIFT_EXPR") == 0
1631 || strcmp (op0
->id
+ 1, "ROTATE_EXPR") == 0))
1634 can_delay_subst
= false;
1636 else if (is_a
<fn_id
*> (ids
[i
]->substitutes
[j
]))
1639 can_delay_subst
= false;
1641 if (sin
->kind
== simplify::MATCH
1645 unsigned worklist_end
= worklist
.length ();
1646 for (unsigned si
= worklist_start
; si
< worklist_end
; ++si
)
1648 simplify
*s
= worklist
[si
];
1649 for (unsigned j
= 0; j
< max_n_opers
; ++j
)
1651 operand
*match_op
= s
->match
;
1652 operand
*result_op
= s
->result
;
1653 auto_vec
<std::pair
<user_id
*, id_base
*> > subst (n_ids
);
1655 for (unsigned i
= 0; i
< n_ids
; ++i
)
1657 user_id
*id
= ids
[i
];
1658 id_base
*oper
= id
->substitutes
[j
% id
->substitutes
.length ()];
1660 && (contains_id (match_op
, id
)
1661 || contains_id (result_op
, id
)))
1666 subst
.quick_push (std::make_pair (id
, oper
));
1667 if (sin
->kind
== simplify::SIMPLIFY
1668 || !can_delay_subst
)
1669 match_op
= replace_id (match_op
, id
, oper
);
1671 && !can_delay_subst
)
1672 result_op
= replace_id (result_op
, id
, oper
);
1677 simplify
*ns
= new simplify (s
->kind
, s
->id
, match_op
, result_op
,
1678 vNULL
, s
->capture_ids
);
1679 ns
->for_subst_vec
.safe_splice (s
->for_subst_vec
);
1682 ns
->for_subst_vec
.safe_splice (subst
);
1684 worklist
.safe_push (ns
);
1687 worklist_start
= worklist_end
;
1690 /* Copy out the result from the last for lowering. */
1691 for (unsigned i
= worklist_start
; i
< worklist
.length (); ++i
)
1692 simplifiers
.safe_push (worklist
[i
]);
1695 /* Lower the AST for everything in SIMPLIFIERS. */
1698 lower (vec
<simplify
*>& simplifiers
, bool gimple
)
1700 auto_vec
<simplify
*> out_simplifiers
;
1701 for (auto s
: simplifiers
)
1702 lower_opt (s
, out_simplifiers
);
1704 simplifiers
.truncate (0);
1705 for (auto s
: out_simplifiers
)
1706 lower_commutative (s
, simplifiers
);
1708 /* Lower for needs to happen before lowering cond
1709 to support (for cnd (cond vec_cond)). This is
1710 safe as substitution delay does not happen for
1711 cond or vec_cond. */
1712 out_simplifiers
.truncate (0);
1713 for (auto s
: simplifiers
)
1714 lower_for (s
, out_simplifiers
);
1716 simplifiers
.truncate (0);
1718 for (auto s
: out_simplifiers
)
1719 lower_cond (s
, simplifiers
);
1721 simplifiers
.safe_splice (out_simplifiers
);
1727 /* The decision tree built for generating GIMPLE and GENERIC pattern
1728 matching code. It represents the 'match' expression of all
1729 simplifies and has those as its leafs. */
1733 /* A hash-map collecting semantically equivalent leafs in the decision
1734 tree for splitting out to separate functions. */
1743 struct sinfo_hashmap_traits
: simple_hashmap_traits
<pointer_hash
<dt_simplify
>,
1746 static inline hashval_t
hash (const key_type
&);
1747 static inline bool equal_keys (const key_type
&, const key_type
&);
1748 template <typename T
> static inline void remove (T
&) {}
1751 typedef ordered_hash_map
<void * /* unused */, sinfo
*, sinfo_hashmap_traits
>
1754 /* Current simplifier ID we are processing during insertion into the
1756 static unsigned current_id
;
1758 /* Decision tree base class, used for DT_NODE. */
1763 enum dt_type
{ DT_NODE
, DT_OPERAND
, DT_TRUE
, DT_MATCH
, DT_SIMPLIFY
};
1768 vec
<dt_node
*> kids
;
1772 unsigned total_size
;
1775 dt_node (enum dt_type type_
, dt_node
*parent_
)
1776 : type (type_
), level (0), parent (parent_
), kids (vNULL
) {}
1778 dt_node
*append_node (dt_node
*);
1779 dt_node
*append_op (operand
*, dt_node
*parent
, unsigned pos
);
1780 dt_node
*append_true_op (operand
*, dt_node
*parent
, unsigned pos
);
1781 dt_node
*append_match_op (operand
*, dt_operand
*, dt_node
*parent
,
1783 dt_node
*append_simplify (simplify
*, unsigned, dt_operand
**);
1785 virtual void gen (FILE *, int, bool, int) {}
1787 void gen_kids (FILE *, int, bool, int);
1788 void gen_kids_1 (FILE *, int, bool, int,
1789 const vec
<dt_operand
*> &, const vec
<dt_operand
*> &,
1790 const vec
<dt_operand
*> &, const vec
<dt_operand
*> &,
1791 const vec
<dt_operand
*> &, const vec
<dt_node
*> &);
1793 void analyze (sinfo_map_t
&);
1796 /* Generic decision tree node used for DT_OPERAND, DT_MATCH and DT_TRUE. */
1798 class dt_operand
: public dt_node
1802 dt_operand
*match_dop
;
1807 dt_operand (enum dt_type type
, operand
*op_
, dt_operand
*match_dop_
,
1808 dt_operand
*parent_
, unsigned pos_
)
1809 : dt_node (type
, parent_
), op (op_
), match_dop (match_dop_
),
1810 pos (pos_
), value_match (false), for_id (current_id
) {}
1812 void gen (FILE *, int, bool, int) final override
;
1813 unsigned gen_predicate (FILE *, int, const char *, bool);
1814 unsigned gen_match_op (FILE *, int, const char *, bool);
1816 unsigned gen_gimple_expr (FILE *, int, int);
1817 unsigned gen_generic_expr (FILE *, int, const char *);
1819 char *get_name (char *);
1820 void gen_opname (char *, unsigned);
1823 /* Leaf node of the decision tree, used for DT_SIMPLIFY. */
1825 class dt_simplify
: public dt_node
1829 unsigned pattern_no
;
1830 dt_operand
**indexes
;
1833 dt_simplify (simplify
*s_
, unsigned pattern_no_
, dt_operand
**indexes_
)
1834 : dt_node (DT_SIMPLIFY
, NULL
), s (s_
), pattern_no (pattern_no_
),
1835 indexes (indexes_
), info (NULL
) {}
1837 void gen_1 (FILE *, int, bool, operand
*);
1838 void gen (FILE *f
, int, bool, int) final override
;
1844 is_a_helper
<dt_operand
*>::test (dt_node
*n
)
1846 return (n
->type
== dt_node::DT_OPERAND
1847 || n
->type
== dt_node::DT_MATCH
1848 || n
->type
== dt_node::DT_TRUE
);
1854 is_a_helper
<dt_simplify
*>::test (dt_node
*n
)
1856 return n
->type
== dt_node::DT_SIMPLIFY
;
1861 /* A container for the actual decision tree. */
1868 void insert (class simplify
*, unsigned);
1869 void gen (vec
<FILE *> &f
, bool gimple
);
1870 void print (FILE *f
= stderr
);
1872 decision_tree () { root
= new dt_node (dt_node::DT_NODE
, NULL
); }
1874 static dt_node
*insert_operand (dt_node
*, operand
*, dt_operand
**indexes
,
1875 unsigned pos
= 0, dt_node
*parent
= 0);
1876 static dt_node
*find_node (vec
<dt_node
*>&, dt_node
*);
1877 static bool cmp_node (dt_node
*, dt_node
*);
1878 static void print_node (dt_node
*, FILE *f
= stderr
, unsigned = 0);
1881 /* Compare two AST operands O1 and O2 and return true if they are equal. */
1884 cmp_operand (operand
*o1
, operand
*o2
)
1886 if (!o1
|| !o2
|| o1
->type
!= o2
->type
)
1889 if (o1
->type
== operand::OP_PREDICATE
)
1891 predicate
*p1
= as_a
<predicate
*>(o1
);
1892 predicate
*p2
= as_a
<predicate
*>(o2
);
1893 return p1
->p
== p2
->p
;
1895 else if (o1
->type
== operand::OP_EXPR
)
1897 expr
*e1
= static_cast<expr
*>(o1
);
1898 expr
*e2
= static_cast<expr
*>(o2
);
1899 return (e1
->operation
== e2
->operation
1900 && e1
->is_generic
== e2
->is_generic
);
1906 /* Compare two decision tree nodes N1 and N2 and return true if they
1910 decision_tree::cmp_node (dt_node
*n1
, dt_node
*n2
)
1912 if (!n1
|| !n2
|| n1
->type
!= n2
->type
)
1918 if (n1
->type
== dt_node::DT_TRUE
)
1921 if (n1
->type
== dt_node::DT_OPERAND
)
1922 return cmp_operand ((as_a
<dt_operand
*> (n1
))->op
,
1923 (as_a
<dt_operand
*> (n2
))->op
);
1924 else if (n1
->type
== dt_node::DT_MATCH
)
1925 return (((as_a
<dt_operand
*> (n1
))->match_dop
1926 == (as_a
<dt_operand
*> (n2
))->match_dop
)
1927 && ((as_a
<dt_operand
*> (n1
))->value_match
1928 == (as_a
<dt_operand
*> (n2
))->value_match
));
1932 /* Search OPS for a decision tree node like P and return it if found. */
1935 decision_tree::find_node (vec
<dt_node
*>& ops
, dt_node
*p
)
1937 /* We can merge adjacent DT_TRUE. */
1938 if (p
->type
== dt_node::DT_TRUE
1940 && ops
.last ()->type
== dt_node::DT_TRUE
)
1942 dt_operand
*true_node
= NULL
;
1943 for (int i
= ops
.length () - 1; i
>= 0; --i
)
1945 /* But we can't merge across DT_TRUE nodes as they serve as
1946 pattern order barriers to make sure that patterns apply
1947 in order of appearance in case multiple matches are possible. */
1948 if (ops
[i
]->type
== dt_node::DT_TRUE
)
1951 || as_a
<dt_operand
*> (ops
[i
])->for_id
> true_node
->for_id
)
1952 true_node
= as_a
<dt_operand
*> (ops
[i
]);
1954 if (decision_tree::cmp_node (ops
[i
], p
))
1956 /* Unless we are processing the same pattern or the blocking
1957 pattern is before the one we are going to merge with. */
1959 && true_node
->for_id
!= current_id
1960 && true_node
->for_id
> as_a
<dt_operand
*> (ops
[i
])->for_id
)
1964 location_t p_loc
= 0;
1965 if (p
->type
== dt_node::DT_OPERAND
)
1966 p_loc
= as_a
<dt_operand
*> (p
)->op
->location
;
1967 location_t op_loc
= 0;
1968 if (ops
[i
]->type
== dt_node::DT_OPERAND
)
1969 op_loc
= as_a
<dt_operand
*> (ops
[i
])->op
->location
;
1970 location_t true_loc
= 0;
1971 true_loc
= true_node
->op
->location
;
1973 "failed to merge decision tree node");
1975 "with the following");
1976 warning_at (true_loc
,
1977 "because of the following which serves as ordering "
1988 /* Append N to the decision tree if it there is not already an existing
1992 dt_node::append_node (dt_node
*n
)
1996 kid
= decision_tree::find_node (kids
, n
);
2001 n
->level
= this->level
+ 1;
2006 /* Append OP to the decision tree. */
2009 dt_node::append_op (operand
*op
, dt_node
*parent
, unsigned pos
)
2011 dt_operand
*parent_
= safe_as_a
<dt_operand
*> (parent
);
2012 dt_operand
*n
= new dt_operand (DT_OPERAND
, op
, 0, parent_
, pos
);
2013 return append_node (n
);
2016 /* Append a DT_TRUE decision tree node. */
2019 dt_node::append_true_op (operand
*op
, dt_node
*parent
, unsigned pos
)
2021 dt_operand
*parent_
= safe_as_a
<dt_operand
*> (parent
);
2022 dt_operand
*n
= new dt_operand (DT_TRUE
, op
, 0, parent_
, pos
);
2023 return append_node (n
);
2026 /* Append a DT_MATCH decision tree node. */
2029 dt_node::append_match_op (operand
*op
, dt_operand
*match_dop
,
2030 dt_node
*parent
, unsigned pos
)
2032 dt_operand
*parent_
= as_a
<dt_operand
*> (parent
);
2033 dt_operand
*n
= new dt_operand (DT_MATCH
, op
, match_dop
, parent_
, pos
);
2034 return append_node (n
);
2037 /* Append S to the decision tree. */
2040 dt_node::append_simplify (simplify
*s
, unsigned pattern_no
,
2041 dt_operand
**indexes
)
2044 dt_simplify
*n
= new dt_simplify (s
, pattern_no
, indexes
);
2045 for (unsigned i
= 0; i
< kids
.length (); ++i
)
2046 if ((s2
= dyn_cast
<dt_simplify
*> (kids
[i
]))
2048 || s
->match
->location
!= s2
->s
->match
->location
))
2050 /* With a nested patters, it's hard to avoid these in order
2051 to keep match.pd rules relatively small. */
2052 warning_at (s
->match
->location
, "duplicate pattern");
2053 warning_at (s2
->s
->match
->location
, "previous pattern defined here");
2054 print_operand (s
->match
, stderr
);
2055 fprintf (stderr
, "\n");
2057 return append_node (n
);
2060 /* Analyze the node and its children. */
2063 dt_node::analyze (sinfo_map_t
&map
)
2069 if (type
== DT_SIMPLIFY
)
2071 /* Populate the map of equivalent simplifies. */
2072 dt_simplify
*s
= as_a
<dt_simplify
*> (this);
2074 sinfo
*&si
= map
.get_or_insert (s
, &existed
);
2089 for (unsigned i
= 0; i
< kids
.length (); ++i
)
2091 kids
[i
]->analyze (map
);
2092 num_leafs
+= kids
[i
]->num_leafs
;
2093 total_size
+= kids
[i
]->total_size
;
2094 max_level
= MAX (max_level
, kids
[i
]->max_level
);
2098 /* Insert O into the decision tree and return the decision tree node found
2102 decision_tree::insert_operand (dt_node
*p
, operand
*o
, dt_operand
**indexes
,
2103 unsigned pos
, dt_node
*parent
)
2105 dt_node
*q
, *elm
= 0;
2107 if (capture
*c
= dyn_cast
<capture
*> (o
))
2109 unsigned capt_index
= c
->where
;
2111 if (indexes
[capt_index
] == 0)
2114 q
= insert_operand (p
, c
->what
, indexes
, pos
, parent
);
2117 q
= elm
= p
->append_true_op (o
, parent
, pos
);
2120 // get to the last capture
2121 for (operand
*what
= c
->what
;
2122 what
&& is_a
<capture
*> (what
);
2123 c
= as_a
<capture
*> (what
), what
= c
->what
)
2128 unsigned cc_index
= c
->where
;
2129 dt_operand
*match_op
= indexes
[cc_index
];
2131 dt_operand
temp (dt_node::DT_TRUE
, 0, 0, 0, 0);
2132 elm
= decision_tree::find_node (p
->kids
, &temp
);
2136 dt_operand
match (dt_node::DT_MATCH
, 0, match_op
, 0, 0);
2137 match
.value_match
= c
->value_match
;
2138 elm
= decision_tree::find_node (p
->kids
, &match
);
2143 dt_operand
temp (dt_node::DT_OPERAND
, c
->what
, 0, 0, 0);
2144 elm
= decision_tree::find_node (p
->kids
, &temp
);
2148 gcc_assert (elm
->type
== dt_node::DT_TRUE
2149 || elm
->type
== dt_node::DT_OPERAND
2150 || elm
->type
== dt_node::DT_MATCH
);
2151 indexes
[capt_index
] = static_cast<dt_operand
*> (elm
);
2156 p
= p
->append_match_op (o
, indexes
[capt_index
], parent
, pos
);
2157 as_a
<dt_operand
*>(p
)->value_match
= c
->value_match
;
2159 return insert_operand (p
, c
->what
, indexes
, 0, p
);
2164 p
= p
->append_op (o
, parent
, pos
);
2167 if (expr
*e
= dyn_cast
<expr
*>(o
))
2169 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
2170 q
= decision_tree::insert_operand (q
, e
->ops
[i
], indexes
, i
, p
);
2176 /* Insert S into the decision tree. */
2179 decision_tree::insert (class simplify
*s
, unsigned pattern_no
)
2182 dt_operand
**indexes
= XCNEWVEC (dt_operand
*, s
->capture_max
+ 1);
2183 dt_node
*p
= decision_tree::insert_operand (root
, s
->match
, indexes
);
2184 p
->append_simplify (s
, pattern_no
, indexes
);
2187 /* Debug functions to dump the decision tree. */
2190 decision_tree::print_node (dt_node
*p
, FILE *f
, unsigned indent
)
2192 if (p
->type
== dt_node::DT_NODE
)
2193 fprintf (f
, "root");
2197 for (unsigned i
= 0; i
< indent
; i
++)
2200 if (p
->type
== dt_node::DT_OPERAND
)
2202 dt_operand
*dop
= static_cast<dt_operand
*>(p
);
2203 print_operand (dop
->op
, f
, true);
2205 else if (p
->type
== dt_node::DT_TRUE
)
2206 fprintf (f
, "true");
2207 else if (p
->type
== dt_node::DT_MATCH
)
2208 fprintf (f
, "match (%p)", (void *)((as_a
<dt_operand
*>(p
))->match_dop
));
2209 else if (p
->type
== dt_node::DT_SIMPLIFY
)
2211 dt_simplify
*s
= static_cast<dt_simplify
*> (p
);
2212 fprintf (f
, "simplify_%u { ", s
->pattern_no
);
2213 for (int i
= 0; i
<= s
->s
->capture_max
; ++i
)
2214 fprintf (f
, "%p, ", (void *) s
->indexes
[i
]);
2217 if (is_a
<dt_operand
*> (p
))
2218 fprintf (f
, " [%u]", as_a
<dt_operand
*> (p
)->for_id
);
2221 fprintf (stderr
, " (%p, %p), %u, %u\n",
2222 (void *) p
, (void *) p
->parent
, p
->level
, p
->kids
.length ());
2224 for (unsigned i
= 0; i
< p
->kids
.length (); ++i
)
2225 decision_tree::print_node (p
->kids
[i
], f
, indent
+ 2);
2229 decision_tree::print (FILE *f
)
2231 return decision_tree::print_node (root
, f
);
2235 /* For GENERIC we have to take care of wrapping multiple-used
2236 expressions with side-effects in save_expr and preserve side-effects
2237 of expressions with omit_one_operand. Analyze captures in
2238 match, result and with expressions and perform early-outs
2239 on the outermost match expression operands for cases we cannot
2245 capture_info (simplify
*s
, operand
*, bool);
2246 void walk_match (operand
*o
, unsigned toplevel_arg
, bool, bool);
2247 bool walk_result (operand
*o
, bool, operand
*);
2248 void walk_c_expr (c_expr
*);
2254 bool force_no_side_effects_p
;
2255 bool force_single_use
;
2256 bool cond_expr_cond_p
;
2257 unsigned long toplevel_msk
;
2258 unsigned match_use_count
;
2259 unsigned result_use_count
;
2264 auto_vec
<cinfo
> info
;
2265 unsigned long force_no_side_effects
;
2269 /* Analyze captures in S. */
2271 capture_info::capture_info (simplify
*s
, operand
*result
, bool gimple_
)
2276 if (s
->kind
== simplify::MATCH
)
2278 force_no_side_effects
= -1;
2282 force_no_side_effects
= 0;
2283 info
.safe_grow_cleared (s
->capture_max
+ 1, true);
2284 for (int i
= 0; i
<= s
->capture_max
; ++i
)
2285 info
[i
].same_as
= i
;
2287 e
= as_a
<expr
*> (s
->match
);
2288 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
2289 walk_match (e
->ops
[i
], i
,
2290 (i
!= 0 && *e
->operation
== COND_EXPR
)
2291 || *e
->operation
== TRUTH_ANDIF_EXPR
2292 || *e
->operation
== TRUTH_ORIF_EXPR
,
2293 i
== 0 && *e
->operation
== COND_EXPR
);
2295 walk_result (s
->result
, false, result
);
2298 /* Analyze captures in the match expression piece O. */
2301 capture_info::walk_match (operand
*o
, unsigned toplevel_arg
,
2302 bool conditional_p
, bool cond_expr_cond_p
)
2304 if (capture
*c
= dyn_cast
<capture
*> (o
))
2306 unsigned where
= c
->where
;
2307 info
[where
].match_use_count
++;
2308 info
[where
].toplevel_msk
|= 1 << toplevel_arg
;
2309 info
[where
].force_no_side_effects_p
|= conditional_p
;
2310 info
[where
].cond_expr_cond_p
|= cond_expr_cond_p
;
2315 /* Recurse to exprs and captures. */
2316 if (is_a
<capture
*> (c
->what
)
2317 || is_a
<expr
*> (c
->what
))
2318 walk_match (c
->what
, toplevel_arg
, conditional_p
, false);
2319 /* We need to look past multiple captures to find a captured
2320 expression as with conditional converts two captures
2321 can be collapsed onto the same expression. Also collect
2322 what captures capture the same thing. */
2323 while (c
->what
&& is_a
<capture
*> (c
->what
))
2325 c
= as_a
<capture
*> (c
->what
);
2326 if (info
[c
->where
].same_as
!= c
->where
2327 && info
[c
->where
].same_as
!= info
[where
].same_as
)
2328 fatal_at (c
->location
, "cannot handle this collapsed capture");
2329 info
[c
->where
].same_as
= info
[where
].same_as
;
2331 /* Mark expr (non-leaf) captures and forced single-use exprs. */
2334 && (e
= dyn_cast
<expr
*> (c
->what
)))
2336 /* Zero-operand expression captures like ADDR_EXPR@0 are
2337 similar as predicates -- if they are not mentioned in
2338 the result we have to force them to have no side-effects. */
2339 if (e
->ops
.length () != 0)
2340 info
[where
].expr_p
= true;
2341 info
[where
].force_single_use
|= e
->force_single_use
;
2344 else if (expr
*e
= dyn_cast
<expr
*> (o
))
2346 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
2348 bool cond_p
= conditional_p
;
2349 bool expr_cond_p
= false;
2350 if (i
!= 0 && *e
->operation
== COND_EXPR
)
2352 else if (*e
->operation
== TRUTH_ANDIF_EXPR
2353 || *e
->operation
== TRUTH_ORIF_EXPR
)
2356 && *e
->operation
== COND_EXPR
)
2358 walk_match (e
->ops
[i
], toplevel_arg
, cond_p
, expr_cond_p
);
2361 else if (is_a
<predicate
*> (o
))
2363 /* Mark non-captured leafs toplevel arg for checking. */
2364 force_no_side_effects
|= 1 << toplevel_arg
;
2367 warning_at (o
->location
,
2368 "forcing no side-effects on possibly lost leaf");
2374 /* Analyze captures in the result expression piece O. Return true
2375 if RESULT was visited in one of the children. Only visit
2376 non-if/with children if they are rooted on RESULT. */
2379 capture_info::walk_result (operand
*o
, bool conditional_p
, operand
*result
)
2381 if (capture
*c
= dyn_cast
<capture
*> (o
))
2383 unsigned where
= info
[c
->where
].same_as
;
2384 info
[where
].result_use_count
++;
2385 /* If we substitute an expression capture we don't know
2386 which captures this will end up using (well, we don't
2387 compute that). Force the uses to be side-effect free
2388 which means forcing the toplevels that reach the
2389 expression side-effect free. */
2390 if (info
[where
].expr_p
)
2391 force_no_side_effects
|= info
[where
].toplevel_msk
;
2392 /* Mark CSE capture uses as forced to have no side-effects. */
2394 && is_a
<expr
*> (c
->what
))
2396 info
[where
].cse_p
= true;
2397 walk_result (c
->what
, true, result
);
2400 else if (expr
*e
= dyn_cast
<expr
*> (o
))
2402 id_base
*opr
= e
->operation
;
2403 if (user_id
*uid
= dyn_cast
<user_id
*> (opr
))
2404 opr
= uid
->substitutes
[0];
2405 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
2407 bool cond_p
= conditional_p
;
2408 if (i
!= 0 && *e
->operation
== COND_EXPR
)
2410 else if (*e
->operation
== TRUTH_ANDIF_EXPR
2411 || *e
->operation
== TRUTH_ORIF_EXPR
)
2413 walk_result (e
->ops
[i
], cond_p
, result
);
2416 else if (if_expr
*ie
= dyn_cast
<if_expr
*> (o
))
2418 /* 'if' conditions should be all fine. */
2419 if (ie
->trueexpr
== result
)
2421 walk_result (ie
->trueexpr
, false, result
);
2424 if (ie
->falseexpr
== result
)
2426 walk_result (ie
->falseexpr
, false, result
);
2430 if (is_a
<if_expr
*> (ie
->trueexpr
)
2431 || is_a
<with_expr
*> (ie
->trueexpr
))
2432 res
|= walk_result (ie
->trueexpr
, false, result
);
2434 && (is_a
<if_expr
*> (ie
->falseexpr
)
2435 || is_a
<with_expr
*> (ie
->falseexpr
)))
2436 res
|= walk_result (ie
->falseexpr
, false, result
);
2439 else if (with_expr
*we
= dyn_cast
<with_expr
*> (o
))
2441 bool res
= (we
->subexpr
== result
);
2443 || is_a
<if_expr
*> (we
->subexpr
)
2444 || is_a
<with_expr
*> (we
->subexpr
))
2445 res
|= walk_result (we
->subexpr
, false, result
);
2447 walk_c_expr (we
->with
);
2450 else if (c_expr
*ce
= dyn_cast
<c_expr
*> (o
))
2458 /* Look for captures in the C expr E. */
2461 capture_info::walk_c_expr (c_expr
*e
)
2463 /* Give up for C exprs mentioning captures not inside TREE_TYPE,
2464 TREE_REAL_CST, TREE_CODE or a predicate where they cannot
2465 really escape through. */
2466 unsigned p_depth
= 0;
2467 for (unsigned i
= 0; i
< e
->code
.length (); ++i
)
2469 const cpp_token
*t
= &e
->code
[i
];
2470 const cpp_token
*n
= i
< e
->code
.length () - 1 ? &e
->code
[i
+1] : NULL
;
2472 if (t
->type
== CPP_NAME
2473 && (strcmp ((const char *)CPP_HASHNODE
2474 (t
->val
.node
.node
)->ident
.str
, "TREE_TYPE") == 0
2475 || strcmp ((const char *)CPP_HASHNODE
2476 (t
->val
.node
.node
)->ident
.str
, "TREE_CODE") == 0
2477 || strcmp ((const char *)CPP_HASHNODE
2478 (t
->val
.node
.node
)->ident
.str
, "TREE_REAL_CST") == 0
2479 || ((id
= get_operator ((const char *)CPP_HASHNODE
2480 (t
->val
.node
.node
)->ident
.str
))
2481 && is_a
<predicate_id
*> (id
)))
2482 && n
->type
== CPP_OPEN_PAREN
)
2484 else if (t
->type
== CPP_CLOSE_PAREN
2487 else if (p_depth
== 0
2488 && t
->type
== CPP_ATSIGN
2489 && (n
->type
== CPP_NUMBER
2490 || n
->type
== CPP_NAME
)
2491 && !(n
->flags
& PREV_WHITE
))
2494 if (n
->type
== CPP_NUMBER
)
2495 id1
= (const char *)n
->val
.str
.text
;
2497 id1
= (const char *)CPP_HASHNODE (n
->val
.node
.node
)->ident
.str
;
2498 unsigned *where
= e
->capture_ids
->get(id1
);
2500 fatal_at (n
, "unknown capture id '%s'", id1
);
2501 info
[info
[*where
].same_as
].force_no_side_effects_p
= true;
2504 warning_at (t
, "capture escapes");
2510 /* The current label failing the current matched pattern during
2512 static char *fail_label
;
2514 /* Code generation off the decision tree and the refered AST nodes. */
2517 is_conversion (id_base
*op
)
2519 return (*op
== CONVERT_EXPR
2521 || *op
== FLOAT_EXPR
2522 || *op
== FIX_TRUNC_EXPR
2523 || *op
== VIEW_CONVERT_EXPR
);
2526 /* Get the type to be used for generating operand POS of OP from the
2530 get_operand_type (id_base
*op
, unsigned pos
,
2531 const char *in_type
,
2532 const char *expr_type
,
2533 const char *other_oprnd_type
)
2535 /* Generally operands whose type does not match the type of the
2536 expression generated need to know their types but match and
2537 thus can fall back to 'other_oprnd_type'. */
2538 if (is_conversion (op
))
2539 return other_oprnd_type
;
2540 else if (*op
== REALPART_EXPR
2541 || *op
== IMAGPART_EXPR
)
2542 return other_oprnd_type
;
2543 else if (is_a
<operator_id
*> (op
)
2544 && strcmp (as_a
<operator_id
*> (op
)->tcc
, "tcc_comparison") == 0)
2545 return other_oprnd_type
;
2546 else if (*op
== COND_EXPR
2548 return "boolean_type_node";
2549 else if (startswith (op
->id
, "CFN_COND_"))
2551 /* IFN_COND_* operands 1 and later by default have the same type
2552 as the result. The type of operand 0 needs to be specified
2554 if (pos
> 0 && expr_type
)
2556 else if (pos
> 0 && in_type
)
2563 /* Otherwise all types should match - choose one in order of
2570 return other_oprnd_type
;
2574 /* Generate transform code for an expression. */
2577 expr::gen_transform (FILE *f
, int indent
, const char *dest
, bool gimple
,
2578 int depth
, const char *in_type
, capture_info
*cinfo
,
2579 dt_operand
**indexes
, int)
2581 id_base
*opr
= operation
;
2582 /* When we delay operator substituting during lowering of fors we
2583 make sure that for code-gen purposes the effects of each substitute
2584 are the same. Thus just look at that. */
2585 if (user_id
*uid
= dyn_cast
<user_id
*> (opr
))
2586 opr
= uid
->substitutes
[0];
2588 bool conversion_p
= is_conversion (opr
);
2589 const char *type
= expr_type
;
2592 /* If there was a type specification in the pattern use it. */
2594 else if (conversion_p
)
2595 /* For conversions we need to build the expression using the
2596 outer type passed in. */
2598 else if (*opr
== REALPART_EXPR
2599 || *opr
== IMAGPART_EXPR
)
2601 /* __real and __imag use the component type of its operand. */
2602 snprintf (optype
, sizeof (optype
), "TREE_TYPE (TREE_TYPE (_o%d[0]))",
2606 else if (is_a
<operator_id
*> (opr
)
2607 && !strcmp (as_a
<operator_id
*> (opr
)->tcc
, "tcc_comparison"))
2609 /* comparisons use boolean_type_node (or what gets in), but
2610 their operands need to figure out the types themselves. */
2615 snprintf (optype
, sizeof (optype
), "boolean_type_node");
2620 else if (*opr
== COND_EXPR
2621 || *opr
== VEC_COND_EXPR
2622 || startswith (opr
->id
, "CFN_COND_"))
2624 /* Conditions are of the same type as their first alternative. */
2625 snprintf (optype
, sizeof (optype
), "TREE_TYPE (_o%d[1])", depth
);
2630 /* Other operations are of the same type as their first operand. */
2631 snprintf (optype
, sizeof (optype
), "TREE_TYPE (_o%d[0])", depth
);
2635 fatal_at (location
, "cannot determine type of operand");
2637 fprintf_indent (f
, indent
, "{\n");
2639 fprintf_indent (f
, indent
,
2640 "tree _o%d[%u], _r%d;\n", depth
, ops
.length (), depth
);
2642 snprintf (op0type
, sizeof (op0type
), "TREE_TYPE (_o%d[0])", depth
);
2643 for (unsigned i
= 0; i
< ops
.length (); ++i
)
2646 snprintf (dest1
, sizeof (dest1
), "_o%d[%u]", depth
, i
);
2648 = get_operand_type (opr
, i
, in_type
, expr_type
,
2649 i
== 0 ? NULL
: op0type
);
2650 ops
[i
]->gen_transform (f
, indent
, dest1
, gimple
, depth
+ 1, optype1
,
2652 *opr
== COND_EXPR
&& i
== 0 ? 1 : 2);
2655 const char *opr_name
;
2656 if (*operation
== CONVERT_EXPR
)
2657 opr_name
= "NOP_EXPR";
2659 opr_name
= operation
->id
;
2663 if (*opr
== CONVERT_EXPR
)
2665 fprintf_indent (f
, indent
,
2666 "if (%s != TREE_TYPE (_o%d[0])\n",
2668 fprintf_indent (f
, indent
,
2669 " && !useless_type_conversion_p (%s, TREE_TYPE "
2672 fprintf_indent (f
, indent
+ 2, "{\n");
2675 /* ??? Building a stmt can fail for various reasons here, seq being
2676 NULL or the stmt referencing SSA names occuring in abnormal PHIs.
2677 So if we fail here we should continue matching other patterns. */
2678 fprintf_indent (f
, indent
, "gimple_match_op tem_op "
2679 "(res_op->cond.any_else (), %s, %s", opr_name
, type
);
2680 for (unsigned i
= 0; i
< ops
.length (); ++i
)
2681 fprintf (f
, ", _o%d[%u]", depth
, i
);
2682 fprintf (f
, ");\n");
2683 fprintf_indent (f
, indent
, "tem_op.resimplify (%s, valueize);\n",
2684 !force_leaf
? "lseq" : "NULL");
2685 fprintf_indent (f
, indent
,
2686 "_r%d = maybe_push_res_to_seq (&tem_op, %s);\n", depth
,
2687 !force_leaf
? "lseq" : "NULL");
2688 fprintf_indent (f
, indent
,
2689 "if (!_r%d) goto %s;\n",
2691 if (*opr
== CONVERT_EXPR
)
2694 fprintf_indent (f
, indent
, " }\n");
2695 fprintf_indent (f
, indent
, "else\n");
2696 fprintf_indent (f
, indent
, " _r%d = _o%d[0];\n", depth
, depth
);
2701 if (*opr
== CONVERT_EXPR
)
2703 fprintf_indent (f
, indent
, "if (TREE_TYPE (_o%d[0]) != %s)\n",
2705 fprintf_indent (f
, indent
+ 2, "{\n");
2708 if (opr
->kind
== id_base::CODE
)
2709 fprintf_indent (f
, indent
, "_r%d = fold_build%d_loc (loc, %s, %s",
2710 depth
, ops
.length(), opr_name
, type
);
2712 fprintf_indent (f
, indent
, "_r%d = maybe_build_call_expr_loc (loc, "
2713 "%s, %s, %d", depth
, opr_name
, type
, ops
.length());
2714 for (unsigned i
= 0; i
< ops
.length (); ++i
)
2715 fprintf (f
, ", _o%d[%u]", depth
, i
);
2716 fprintf (f
, ");\n");
2717 if (opr
->kind
!= id_base::CODE
)
2719 fprintf_indent (f
, indent
, "if (!_r%d)\n", depth
);
2720 fprintf_indent (f
, indent
, " goto %s;\n", fail_label
);
2724 fprintf_indent (f
, indent
, "if (EXPR_P (_r%d))\n", depth
);
2725 fprintf_indent (f
, indent
, " goto %s;\n", fail_label
);
2727 if (*opr
== CONVERT_EXPR
)
2729 fprintf_indent (f
, indent
- 2, "}\n");
2731 fprintf_indent (f
, indent
, "else\n");
2732 fprintf_indent (f
, indent
, " _r%d = _o%d[0];\n", depth
, depth
);
2735 fprintf_indent (f
, indent
, "%s = _r%d;\n", dest
, depth
);
2737 fprintf_indent (f
, indent
, "}\n");
2740 /* Generate code for a c_expr which is either the expression inside
2741 an if statement or a sequence of statements which computes a
2742 result to be stored to DEST. */
2745 c_expr::gen_transform (FILE *f
, int indent
, const char *dest
,
2746 bool, int, const char *, capture_info
*,
2749 if (dest
&& nr_stmts
== 1)
2750 fprintf_indent (f
, indent
, "%s = ", dest
);
2752 unsigned stmt_nr
= 1;
2754 for (unsigned i
= 0; i
< code
.length (); ++i
)
2756 const cpp_token
*token
= &code
[i
];
2758 /* We can't recover from all lexing losses but we can roughly restore line
2759 breaks from location info. */
2760 const line_map_ordinary
*map
;
2761 linemap_resolve_location (line_table
, token
->src_loc
,
2762 LRK_SPELLING_LOCATION
, &map
);
2763 expanded_location loc
= linemap_expand_location (line_table
, map
,
2765 if (prev_line
!= -1 && loc
.line
!= prev_line
)
2767 prev_line
= loc
.line
;
2769 /* Replace captures for code-gen. */
2770 if (token
->type
== CPP_ATSIGN
)
2772 const cpp_token
*n
= &code
[i
+1];
2773 if ((n
->type
== CPP_NUMBER
2774 || n
->type
== CPP_NAME
)
2775 && !(n
->flags
& PREV_WHITE
))
2777 if (token
->flags
& PREV_WHITE
)
2780 if (n
->type
== CPP_NUMBER
)
2781 id
= (const char *)n
->val
.str
.text
;
2783 id
= (const char *)CPP_HASHNODE (n
->val
.node
.node
)->ident
.str
;
2784 unsigned *cid
= capture_ids
->get (id
);
2786 fatal_at (token
, "unknown capture id");
2787 fprintf (f
, "captures[%u]", *cid
);
2793 if (token
->flags
& PREV_WHITE
)
2796 if (token
->type
== CPP_NAME
)
2798 const char *id
= (const char *) NODE_NAME (token
->val
.node
.node
);
2800 for (j
= 0; j
< ids
.length (); ++j
)
2802 if (strcmp (id
, ids
[j
].id
) == 0)
2804 fprintf (f
, "%s", ids
[j
].oper
);
2808 if (j
< ids
.length ())
2812 /* Output the token as string. */
2813 char *tk
= (char *)cpp_token_as_text (r
, token
);
2816 if (token
->type
== CPP_SEMICOLON
)
2819 if (dest
&& stmt_nr
== nr_stmts
)
2820 fprintf_indent (f
, indent
, "%s = ", dest
);
2826 /* Generate transform code for a capture. */
2829 capture::gen_transform (FILE *f
, int indent
, const char *dest
, bool gimple
,
2830 int depth
, const char *in_type
, capture_info
*cinfo
,
2831 dt_operand
**indexes
, int cond_handling
)
2833 if (what
&& is_a
<expr
*> (what
))
2835 if (indexes
[where
] == 0)
2838 snprintf (buf
, sizeof (buf
), "captures[%u]", where
);
2839 what
->gen_transform (f
, indent
, buf
, gimple
, depth
, in_type
,
2844 /* If in GENERIC some capture is used multiple times, unshare it except
2845 when emitting the last use. */
2847 && cinfo
->info
.exists ()
2848 && cinfo
->info
[cinfo
->info
[where
].same_as
].result_use_count
> 1)
2850 fprintf_indent (f
, indent
, "%s = unshare_expr (captures[%u]);\n",
2852 cinfo
->info
[cinfo
->info
[where
].same_as
].result_use_count
--;
2855 fprintf_indent (f
, indent
, "%s = captures[%u];\n", dest
, where
);
2857 /* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal
2858 with substituting a capture of that. */
2860 && cond_handling
!= 0
2861 && cinfo
->info
[where
].cond_expr_cond_p
)
2863 /* If substituting into a cond_expr condition, unshare. */
2864 if (cond_handling
== 1)
2865 fprintf_indent (f
, indent
, "%s = unshare_expr (%s);\n", dest
, dest
);
2866 /* If substituting elsewhere we might need to decompose it. */
2867 else if (cond_handling
== 2)
2869 /* ??? Returning false here will also not allow any other patterns
2870 to match unless this generator was split out. */
2871 fprintf_indent (f
, indent
, "if (COMPARISON_CLASS_P (%s))\n", dest
);
2872 fprintf_indent (f
, indent
, " {\n");
2873 fprintf_indent (f
, indent
, " if (!seq) return false;\n");
2874 fprintf_indent (f
, indent
, " %s = gimple_build (seq,"
2876 " TREE_TYPE (%s), TREE_OPERAND (%s, 0),"
2877 " TREE_OPERAND (%s, 1));\n",
2878 dest
, dest
, dest
, dest
, dest
);
2879 fprintf_indent (f
, indent
, " }\n");
2884 /* Return the name of the operand representing the decision tree node.
2885 Use NAME as space to generate it. */
2888 dt_operand::get_name (char *name
)
2891 sprintf (name
, "t");
2892 else if (parent
->level
== 1)
2893 sprintf (name
, "_p%u", pos
);
2894 else if (parent
->type
== dt_node::DT_MATCH
)
2895 return as_a
<dt_operand
*> (parent
)->get_name (name
);
2897 sprintf (name
, "_q%u%u", parent
->level
, pos
);
2901 /* Fill NAME with the operand name at position POS. */
2904 dt_operand::gen_opname (char *name
, unsigned pos
)
2907 sprintf (name
, "_p%u", pos
);
2909 sprintf (name
, "_q%u%u", level
, pos
);
2912 /* Generate matching code for the decision tree operand which is
2916 dt_operand::gen_predicate (FILE *f
, int indent
, const char *opname
, bool gimple
)
2918 predicate
*p
= as_a
<predicate
*> (op
);
2920 if (p
->p
->matchers
.exists ())
2922 /* If this is a predicate generated from a pattern mangle its
2923 name and pass on the valueize hook. */
2925 fprintf_indent (f
, indent
, "if (gimple_%s (%s, valueize))\n",
2928 fprintf_indent (f
, indent
, "if (tree_%s (%s))\n", p
->p
->id
, opname
);
2931 fprintf_indent (f
, indent
, "if (%s (%s))\n", p
->p
->id
, opname
);
2932 fprintf_indent (f
, indent
+ 2, "{\n");
2936 /* Generate matching code for the decision tree operand which is
2940 dt_operand::gen_match_op (FILE *f
, int indent
, const char *opname
, bool)
2942 char match_opname
[20];
2943 match_dop
->get_name (match_opname
);
2945 fprintf_indent (f
, indent
, "if ((%s == %s && ! TREE_SIDE_EFFECTS (%s)) "
2946 "|| operand_equal_p (%s, %s, 0))\n",
2947 opname
, match_opname
, opname
, opname
, match_opname
);
2949 fprintf_indent (f
, indent
, "if ((%s == %s && ! TREE_SIDE_EFFECTS (%s)) "
2950 "|| (operand_equal_p (%s, %s, 0) "
2951 "&& types_match (%s, %s)))\n",
2952 opname
, match_opname
, opname
, opname
, match_opname
,
2953 opname
, match_opname
);
2954 fprintf_indent (f
, indent
+ 2, "{\n");
2958 /* Generate GIMPLE matching code for the decision tree operand. */
2961 dt_operand::gen_gimple_expr (FILE *f
, int indent
, int depth
)
2963 expr
*e
= static_cast<expr
*> (op
);
2964 id_base
*id
= e
->operation
;
2965 unsigned n_ops
= e
->ops
.length ();
2966 unsigned n_braces
= 0;
2968 if (user_id
*u
= dyn_cast
<user_id
*> (id
))
2969 id
= u
->substitutes
[0];
2971 for (unsigned i
= 0; i
< n_ops
; ++i
)
2973 char child_opname
[20];
2974 gen_opname (child_opname
, i
);
2976 if (id
->kind
== id_base::CODE
)
2979 || *id
== REALPART_EXPR
|| *id
== IMAGPART_EXPR
2980 || *id
== BIT_FIELD_REF
|| *id
== VIEW_CONVERT_EXPR
)
2982 /* ??? If this is a memory operation we can't (and should not)
2983 match this. The only sensible operand types are
2984 SSA names and invariants. */
2989 fprintf_indent (f
, indent
,
2990 "tree %s = TREE_OPERAND (%s, %i);\n",
2991 child_opname
, opname
, i
);
2994 fprintf_indent (f
, indent
,
2995 "tree %s = TREE_OPERAND "
2996 "(gimple_assign_rhs1 (_a%d), %i);\n",
2997 child_opname
, depth
, i
);
2998 fprintf_indent (f
, indent
,
2999 "if ((TREE_CODE (%s) == SSA_NAME\n",
3001 fprintf_indent (f
, indent
,
3002 " || is_gimple_min_invariant (%s)))\n",
3004 fprintf_indent (f
, indent
,
3008 fprintf_indent (f
, indent
,
3009 "%s = do_valueize (valueize, %s);\n",
3010 child_opname
, child_opname
);
3014 fprintf_indent (f
, indent
,
3015 "tree %s = gimple_assign_rhs%u (_a%d);\n",
3016 child_opname
, i
+ 1, depth
);
3019 fprintf_indent (f
, indent
,
3020 "tree %s = gimple_call_arg (_c%d, %u);\n",
3021 child_opname
, depth
, i
);
3022 fprintf_indent (f
, indent
,
3023 "%s = do_valueize (valueize, %s);\n",
3024 child_opname
, child_opname
);
3026 /* While the toplevel operands are canonicalized by the caller
3027 after valueizing operands of sub-expressions we have to
3028 re-canonicalize operand order. */
3029 int opno
= commutative_op (id
);
3032 char child_opname0
[20], child_opname1
[20];
3033 gen_opname (child_opname0
, opno
);
3034 gen_opname (child_opname1
, opno
+ 1);
3035 fprintf_indent (f
, indent
,
3036 "if (tree_swap_operands_p (%s, %s))\n",
3037 child_opname0
, child_opname1
);
3038 fprintf_indent (f
, indent
,
3039 " std::swap (%s, %s);\n",
3040 child_opname0
, child_opname1
);
3046 /* Generate GENERIC matching code for the decision tree operand. */
3049 dt_operand::gen_generic_expr (FILE *f
, int indent
, const char *opname
)
3051 expr
*e
= static_cast<expr
*> (op
);
3052 id_base
*id
= e
->operation
;
3053 unsigned n_ops
= e
->ops
.length ();
3055 if (user_id
*u
= dyn_cast
<user_id
*> (id
))
3056 id
= u
->substitutes
[0];
3058 for (unsigned i
= 0; i
< n_ops
; ++i
)
3060 char child_opname
[20];
3061 gen_opname (child_opname
, i
);
3063 if (id
->kind
== id_base::CODE
)
3064 fprintf_indent (f
, indent
, "tree %s = TREE_OPERAND (%s, %u);\n",
3065 child_opname
, opname
, i
);
3067 fprintf_indent (f
, indent
, "tree %s = CALL_EXPR_ARG (%s, %u);\n",
3068 child_opname
, opname
, i
);
3074 /* Generate matching code for the children of the decision tree node. */
3077 dt_node::gen_kids (FILE *f
, int indent
, bool gimple
, int depth
)
3079 auto_vec
<dt_operand
*> gimple_exprs
;
3080 auto_vec
<dt_operand
*> generic_exprs
;
3081 auto_vec
<dt_operand
*> fns
;
3082 auto_vec
<dt_operand
*> generic_fns
;
3083 auto_vec
<dt_operand
*> preds
;
3084 auto_vec
<dt_node
*> others
;
3086 for (unsigned i
= 0; i
< kids
.length (); ++i
)
3088 if (kids
[i
]->type
== dt_node::DT_OPERAND
)
3090 dt_operand
*op
= as_a
<dt_operand
*> (kids
[i
]);
3091 if (expr
*e
= dyn_cast
<expr
*> (op
->op
))
3093 if (e
->ops
.length () == 0
3094 /* In GIMPLE a CONSTRUCTOR always appears in a
3095 separate definition. */
3096 && (!gimple
|| !(*e
->operation
== CONSTRUCTOR
)))
3098 generic_exprs
.safe_push (op
);
3099 /* But ADDR_EXPRs can appear directly when invariant
3100 and in a separate definition when not. */
3101 if (gimple
&& *e
->operation
== ADDR_EXPR
)
3102 gimple_exprs
.safe_push (op
);
3104 else if (e
->operation
->kind
== id_base::FN
)
3109 generic_fns
.safe_push (op
);
3111 else if (e
->operation
->kind
== id_base::PREDICATE
)
3112 preds
.safe_push (op
);
3115 user_id
*u
= dyn_cast
<user_id
*> (e
->operation
);
3116 if (u
&& u
->substitutes
[0]->kind
== id_base::FN
)
3121 generic_fns
.safe_push (op
);
3125 if (gimple
&& !e
->is_generic
)
3126 gimple_exprs
.safe_push (op
);
3128 generic_exprs
.safe_push (op
);
3132 else if (op
->op
->type
== operand::OP_PREDICATE
)
3133 others
.safe_push (kids
[i
]);
3137 else if (kids
[i
]->type
== dt_node::DT_SIMPLIFY
)
3138 others
.safe_push (kids
[i
]);
3139 else if (kids
[i
]->type
== dt_node::DT_MATCH
3140 || kids
[i
]->type
== dt_node::DT_TRUE
)
3142 /* A DT_TRUE operand serves as a barrier - generate code now
3143 for what we have collected sofar.
3144 Like DT_TRUE, DT_MATCH serves as a barrier as it can cause
3145 dependent matches to get out-of-order. Generate code now
3146 for what we have collected sofar. */
3147 gen_kids_1 (f
, indent
, gimple
, depth
, gimple_exprs
, generic_exprs
,
3148 fns
, generic_fns
, preds
, others
);
3149 /* And output the true operand itself. */
3150 kids
[i
]->gen (f
, indent
, gimple
, depth
);
3151 gimple_exprs
.truncate (0);
3152 generic_exprs
.truncate (0);
3154 generic_fns
.truncate (0);
3156 others
.truncate (0);
3162 /* Generate code for the remains. */
3163 gen_kids_1 (f
, indent
, gimple
, depth
, gimple_exprs
, generic_exprs
,
3164 fns
, generic_fns
, preds
, others
);
3167 /* Generate matching code for the children of the decision tree node. */
3170 dt_node::gen_kids_1 (FILE *f
, int indent
, bool gimple
, int depth
,
3171 const vec
<dt_operand
*> &gimple_exprs
,
3172 const vec
<dt_operand
*> &generic_exprs
,
3173 const vec
<dt_operand
*> &fns
,
3174 const vec
<dt_operand
*> &generic_fns
,
3175 const vec
<dt_operand
*> &preds
,
3176 const vec
<dt_node
*> &others
)
3179 char *kid_opname
= buf
;
3181 unsigned exprs_len
= gimple_exprs
.length ();
3182 unsigned gexprs_len
= generic_exprs
.length ();
3183 unsigned fns_len
= fns
.length ();
3184 unsigned gfns_len
= generic_fns
.length ();
3186 if (exprs_len
|| fns_len
|| gexprs_len
|| gfns_len
)
3189 gimple_exprs
[0]->get_name (kid_opname
);
3191 fns
[0]->get_name (kid_opname
);
3193 generic_fns
[0]->get_name (kid_opname
);
3195 generic_exprs
[0]->get_name (kid_opname
);
3197 fprintf_indent (f
, indent
, "switch (TREE_CODE (%s))\n", kid_opname
);
3198 fprintf_indent (f
, indent
, " {\n");
3202 if (exprs_len
|| fns_len
)
3205 fprintf_indent (f
, indent
,
3206 "case SSA_NAME:\n");
3207 fprintf_indent (f
, indent
,
3208 " if (gimple *_d%d = get_def (valueize, %s))\n",
3210 fprintf_indent (f
, indent
,
3215 fprintf_indent (f
, indent
,
3216 "if (gassign *_a%d = dyn_cast <gassign *> (_d%d))\n",
3218 fprintf_indent (f
, indent
,
3219 " switch (gimple_assign_rhs_code (_a%d))\n",
3222 fprintf_indent (f
, indent
, "{\n");
3223 for (unsigned i
= 0; i
< exprs_len
; ++i
)
3225 expr
*e
= as_a
<expr
*> (gimple_exprs
[i
]->op
);
3226 if (user_id
*u
= dyn_cast
<user_id
*> (e
->operation
))
3228 for (auto id
: u
->substitutes
)
3229 fprintf_indent (f
, indent
, "case %s:\n", id
->id
);
3233 id_base
*op
= e
->operation
;
3234 if (*op
== CONVERT_EXPR
|| *op
== NOP_EXPR
)
3235 fprintf_indent (f
, indent
, "CASE_CONVERT:\n");
3237 fprintf_indent (f
, indent
, "case %s:\n", op
->id
);
3239 fprintf_indent (f
, indent
, " {\n");
3240 gimple_exprs
[i
]->gen (f
, indent
+ 4, true, depth
);
3241 fprintf_indent (f
, indent
, " break;\n");
3242 fprintf_indent (f
, indent
, " }\n");
3244 fprintf_indent (f
, indent
, "default:;\n");
3245 fprintf_indent (f
, indent
, "}\n");
3251 fprintf_indent (f
, indent
,
3252 "%sif (gcall *_c%d = dyn_cast <gcall *> (_d%d))\n",
3253 exprs_len
? "else " : "", depth
, depth
);
3254 fprintf_indent (f
, indent
,
3255 " switch (gimple_call_combined_fn (_c%d))\n",
3259 fprintf_indent (f
, indent
, "{\n");
3260 for (unsigned i
= 0; i
< fns_len
; ++i
)
3262 expr
*e
= as_a
<expr
*>(fns
[i
]->op
);
3263 if (user_id
*u
= dyn_cast
<user_id
*> (e
->operation
))
3264 for (auto id
: u
->substitutes
)
3265 fprintf_indent (f
, indent
, "case %s:\n", id
->id
);
3267 fprintf_indent (f
, indent
, "case %s:\n", e
->operation
->id
);
3268 /* We need to be defensive against bogus prototypes allowing
3269 calls with not enough arguments. */
3270 fprintf_indent (f
, indent
,
3271 " if (gimple_call_num_args (_c%d) == %d)\n",
3272 depth
, e
->ops
.length ());
3273 fprintf_indent (f
, indent
, " {\n");
3274 fns
[i
]->gen (f
, indent
+ 6, true, depth
);
3275 fprintf_indent (f
, indent
, " }\n");
3276 fprintf_indent (f
, indent
, " break;\n");
3279 fprintf_indent (f
, indent
, "default:;\n");
3280 fprintf_indent (f
, indent
, "}\n");
3286 fprintf_indent (f
, indent
, " }\n");
3287 /* See if there is SSA_NAME among generic_exprs and if yes, emit it
3288 here rather than in the next loop. */
3289 for (unsigned i
= 0; i
< generic_exprs
.length (); ++i
)
3291 expr
*e
= as_a
<expr
*>(generic_exprs
[i
]->op
);
3292 id_base
*op
= e
->operation
;
3293 if (*op
== SSA_NAME
&& (exprs_len
|| fns_len
))
3295 fprintf_indent (f
, indent
+ 4, "{\n");
3296 generic_exprs
[i
]->gen (f
, indent
+ 6, gimple
, depth
);
3297 fprintf_indent (f
, indent
+ 4, "}\n");
3301 fprintf_indent (f
, indent
, " break;\n");
3304 for (unsigned i
= 0; i
< generic_exprs
.length (); ++i
)
3306 expr
*e
= as_a
<expr
*>(generic_exprs
[i
]->op
);
3307 id_base
*op
= e
->operation
;
3308 if (*op
== CONVERT_EXPR
|| *op
== NOP_EXPR
)
3309 fprintf_indent (f
, indent
, "CASE_CONVERT:\n");
3310 else if (*op
== SSA_NAME
&& (exprs_len
|| fns_len
))
3311 /* Already handled above. */
3315 if (user_id
*u
= dyn_cast
<user_id
*> (op
))
3316 for (auto id
: u
->substitutes
)
3317 fprintf_indent (f
, indent
, "case %s:\n", id
->id
);
3319 fprintf_indent (f
, indent
, "case %s:\n", op
->id
);
3321 fprintf_indent (f
, indent
, " {\n");
3322 generic_exprs
[i
]->gen (f
, indent
+ 4, gimple
, depth
);
3323 fprintf_indent (f
, indent
, " break;\n");
3324 fprintf_indent (f
, indent
, " }\n");
3329 fprintf_indent (f
, indent
,
3330 "case CALL_EXPR:\n");
3331 fprintf_indent (f
, indent
,
3332 " switch (get_call_combined_fn (%s))\n",
3334 fprintf_indent (f
, indent
,
3338 for (unsigned j
= 0; j
< generic_fns
.length (); ++j
)
3340 expr
*e
= as_a
<expr
*>(generic_fns
[j
]->op
);
3341 gcc_assert (e
->operation
->kind
== id_base::FN
);
3343 fprintf_indent (f
, indent
, "case %s:\n", e
->operation
->id
);
3344 fprintf_indent (f
, indent
, " if (call_expr_nargs (%s) == %d)\n"
3345 " {\n", kid_opname
, e
->ops
.length ());
3346 generic_fns
[j
]->gen (f
, indent
+ 6, false, depth
);
3347 fprintf_indent (f
, indent
, " }\n"
3350 fprintf_indent (f
, indent
, "default:;\n");
3353 fprintf_indent (f
, indent
, " }\n");
3354 fprintf_indent (f
, indent
, " break;\n");
3357 /* Close switch (TREE_CODE ()). */
3358 if (exprs_len
|| fns_len
|| gexprs_len
|| gfns_len
)
3361 fprintf_indent (f
, indent
, " default:;\n");
3362 fprintf_indent (f
, indent
, " }\n");
3365 for (unsigned i
= 0; i
< preds
.length (); ++i
)
3367 expr
*e
= as_a
<expr
*> (preds
[i
]->op
);
3368 predicate_id
*p
= as_a
<predicate_id
*> (e
->operation
);
3369 preds
[i
]->get_name (kid_opname
);
3370 fprintf_indent (f
, indent
, "{\n");
3372 fprintf_indent (f
, indent
, "tree %s_pops[%d];\n", kid_opname
, p
->nargs
);
3373 fprintf_indent (f
, indent
, "if (%s_%s (%s, %s_pops%s))\n",
3374 gimple
? "gimple" : "tree",
3375 p
->id
, kid_opname
, kid_opname
,
3376 gimple
? ", valueize" : "");
3377 fprintf_indent (f
, indent
, " {\n");
3378 for (int j
= 0; j
< p
->nargs
; ++j
)
3380 char child_opname
[20];
3381 preds
[i
]->gen_opname (child_opname
, j
);
3382 fprintf_indent (f
, indent
+ 4, "tree %s = %s_pops[%d];\n",
3383 child_opname
, kid_opname
, j
);
3385 preds
[i
]->gen_kids (f
, indent
+ 4, gimple
, depth
);
3388 fprintf_indent (f
, indent
, "}\n");
3391 for (unsigned i
= 0; i
< others
.length (); ++i
)
3392 others
[i
]->gen (f
, indent
, gimple
, depth
);
3395 /* Generate matching code for the decision tree operand. */
3398 dt_operand::gen (FILE *f
, int indent
, bool gimple
, int depth
)
3403 unsigned n_braces
= 0;
3405 if (type
== DT_OPERAND
)
3408 case operand::OP_PREDICATE
:
3409 n_braces
= gen_predicate (f
, indent
, opname
, gimple
);
3412 case operand::OP_EXPR
:
3414 n_braces
= gen_gimple_expr (f
, indent
, depth
);
3416 n_braces
= gen_generic_expr (f
, indent
, opname
);
3422 else if (type
== DT_TRUE
)
3424 else if (type
== DT_MATCH
)
3425 n_braces
= gen_match_op (f
, indent
, opname
, gimple
);
3429 indent
+= 4 * n_braces
;
3430 gen_kids (f
, indent
, gimple
, depth
);
3432 for (unsigned i
= 0; i
< n_braces
; ++i
)
3437 fprintf_indent (f
, indent
, " }\n");
3441 /* Emit a logging call to the debug file to the file F, with the INDENT from
3442 either the RESULT location or the S's match location if RESULT is null. */
3444 emit_logging_call (FILE *f
, int indent
, class simplify
*s
, operand
*result
,
3447 fprintf_indent (f
, indent
, "if (UNLIKELY (debug_dump)) "
3448 "%s_dump_logs (", gimple
? "gimple" : "generic");
3449 output_line_directive (f
,
3450 result
? result
->location
: s
->match
->location
,
3452 fprintf (f
, ", __FILE__, __LINE__, %s);\n",
3453 s
->kind
== simplify::SIMPLIFY
? "true" : "false");
3456 /* Generate code for the '(if ...)', '(with ..)' and actual transform
3457 step of a '(simplify ...)' or '(match ...)'. This handles everything
3458 that is not part of the decision tree (simplify->match).
3459 Main recursive worker. */
3462 dt_simplify::gen_1 (FILE *f
, int indent
, bool gimple
, operand
*result
)
3466 if (with_expr
*w
= dyn_cast
<with_expr
*> (result
))
3468 fprintf_indent (f
, indent
, "{\n");
3470 output_line_directive (f
, w
->location
);
3471 w
->with
->gen_transform (f
, indent
, NULL
, true, 1, "type", NULL
);
3472 gen_1 (f
, indent
, gimple
, w
->subexpr
);
3474 fprintf_indent (f
, indent
, "}\n");
3477 else if (if_expr
*ife
= dyn_cast
<if_expr
*> (result
))
3479 output_line_directive (f
, ife
->location
);
3480 fprintf_indent (f
, indent
, "if (");
3481 ife
->cond
->gen_transform (f
, indent
, NULL
, true, 1, "type", NULL
);
3483 fprintf_indent (f
, indent
+ 2, "{\n");
3485 gen_1 (f
, indent
, gimple
, ife
->trueexpr
);
3487 fprintf_indent (f
, indent
+ 2, "}\n");
3490 fprintf_indent (f
, indent
, "else\n");
3491 fprintf_indent (f
, indent
+ 2, "{\n");
3493 gen_1 (f
, indent
, gimple
, ife
->falseexpr
);
3495 fprintf_indent (f
, indent
+ 2, "}\n");
3501 static unsigned fail_label_cnt
;
3502 char local_fail_label
[256];
3503 snprintf (local_fail_label
, 256, "next_after_fail%u", ++fail_label_cnt
);
3504 fail_label
= local_fail_label
;
3505 bool needs_label
= false;
3507 /* Analyze captures and perform early-outs on the incoming arguments
3508 that cover cases we cannot handle. */
3509 capture_info
cinfo (s
, result
, gimple
);
3510 if (s
->kind
== simplify::SIMPLIFY
)
3514 for (unsigned i
= 0; i
< as_a
<expr
*> (s
->match
)->ops
.length (); ++i
)
3515 if (cinfo
.force_no_side_effects
& (1 << i
))
3517 fprintf_indent (f
, indent
,
3518 "if (TREE_SIDE_EFFECTS (_p%d)) goto %s;\n",
3522 warning_at (as_a
<expr
*> (s
->match
)->ops
[i
]->location
,
3523 "forcing toplevel operand to have no "
3526 for (int i
= 0; i
<= s
->capture_max
; ++i
)
3527 if (cinfo
.info
[i
].cse_p
)
3529 else if (cinfo
.info
[i
].force_no_side_effects_p
3530 && (cinfo
.info
[i
].toplevel_msk
3531 & cinfo
.force_no_side_effects
) == 0)
3533 fprintf_indent (f
, indent
,
3534 "if (TREE_SIDE_EFFECTS (captures[%d])) "
3535 "goto %s;\n", i
, fail_label
);
3538 warning_at (cinfo
.info
[i
].c
->location
,
3539 "forcing captured operand to have no "
3542 else if ((cinfo
.info
[i
].toplevel_msk
3543 & cinfo
.force_no_side_effects
) != 0)
3544 /* Mark capture as having no side-effects if we had to verify
3545 that via forced toplevel operand checks. */
3546 cinfo
.info
[i
].force_no_side_effects_p
= true;
3550 /* Force single-use restriction by only allowing simple
3551 results via setting seq to NULL. */
3552 fprintf_indent (f
, indent
, "gimple_seq *lseq = seq;\n");
3553 bool first_p
= true;
3554 for (int i
= 0; i
<= s
->capture_max
; ++i
)
3555 if (cinfo
.info
[i
].force_single_use
)
3559 fprintf_indent (f
, indent
, "if (lseq\n");
3560 fprintf_indent (f
, indent
, " && (");
3566 fprintf_indent (f
, indent
, " || ");
3568 fprintf (f
, "!single_use (captures[%d])", i
);
3572 fprintf (f
, "))\n");
3573 fprintf_indent (f
, indent
, " lseq = NULL;\n");
3578 if (s
->kind
== simplify::SIMPLIFY
)
3580 fprintf_indent (f
, indent
, "if (UNLIKELY (!dbg_cnt (match))) goto %s;\n", fail_label
);
3584 fprintf_indent (f
, indent
, "{\n");
3588 /* If there is no result then this is a predicate implementation. */
3589 emit_logging_call (f
, indent
, s
, result
, gimple
);
3590 fprintf_indent (f
, indent
, "return true;\n");
3594 /* For GIMPLE simply drop NON_LVALUE_EXPR (which only appears
3595 in outermost position). */
3596 if (result
->type
== operand::OP_EXPR
3597 && *as_a
<expr
*> (result
)->operation
== NON_LVALUE_EXPR
)
3598 result
= as_a
<expr
*> (result
)->ops
[0];
3599 if (result
->type
== operand::OP_EXPR
)
3601 expr
*e
= as_a
<expr
*> (result
);
3602 id_base
*opr
= e
->operation
;
3603 bool is_predicate
= false;
3604 /* When we delay operator substituting during lowering of fors we
3605 make sure that for code-gen purposes the effects of each substitute
3606 are the same. Thus just look at that. */
3607 if (user_id
*uid
= dyn_cast
<user_id
*> (opr
))
3608 opr
= uid
->substitutes
[0];
3609 else if (is_a
<predicate_id
*> (opr
))
3610 is_predicate
= true;
3612 fprintf_indent (f
, indent
, "res_op->set_op (%s, type, %d);\n",
3613 *e
->operation
== CONVERT_EXPR
3614 ? "NOP_EXPR" : e
->operation
->id
,
3616 for (unsigned j
= 0; j
< e
->ops
.length (); ++j
)
3620 snprintf (dest
, sizeof (dest
), "res_ops[%d]", j
);
3622 snprintf (dest
, sizeof (dest
), "res_op->ops[%d]", j
);
3624 = get_operand_type (opr
, j
,
3625 "type", e
->expr_type
,
3627 : "TREE_TYPE (res_op->ops[0])");
3628 /* We need to expand GENERIC conditions we captured from
3629 COND_EXPRs and we need to unshare them when substituting
3631 int cond_handling
= 0;
3633 cond_handling
= (*opr
== COND_EXPR
&& j
== 0) ? 1 : 2;
3634 e
->ops
[j
]->gen_transform (f
, indent
, dest
, true, 1, optype
,
3635 &cinfo
, indexes
, cond_handling
);
3638 /* Re-fold the toplevel result. It's basically an embedded
3639 gimple_build w/o actually building the stmt. */
3642 fprintf_indent (f
, indent
,
3643 "res_op->resimplify (%s, valueize);\n",
3644 !e
->force_leaf
? "lseq" : "NULL");
3647 fprintf_indent (f
, indent
,
3648 "if (!maybe_push_res_to_seq (res_op, NULL)) "
3649 "goto %s;\n", fail_label
);
3654 else if (result
->type
== operand::OP_CAPTURE
3655 || result
->type
== operand::OP_C_EXPR
)
3657 fprintf_indent (f
, indent
, "tree tem;\n");
3658 result
->gen_transform (f
, indent
, "tem", true, 1, "type",
3660 fprintf_indent (f
, indent
, "res_op->set_value (tem);\n");
3661 if (is_a
<capture
*> (result
)
3662 && cinfo
.info
[as_a
<capture
*> (result
)->where
].cond_expr_cond_p
)
3664 /* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal
3665 with substituting a capture of that. */
3666 fprintf_indent (f
, indent
,
3667 "if (COMPARISON_CLASS_P (tem))\n");
3668 fprintf_indent (f
, indent
,
3670 fprintf_indent (f
, indent
,
3671 " res_op->ops[0] = TREE_OPERAND (tem, 0);\n");
3672 fprintf_indent (f
, indent
,
3673 " res_op->ops[1] = TREE_OPERAND (tem, 1);\n");
3674 fprintf_indent (f
, indent
,
3680 emit_logging_call (f
, indent
, s
, result
, gimple
);
3681 fprintf_indent (f
, indent
, "return true;\n");
3685 bool is_predicate
= false;
3686 if (result
->type
== operand::OP_EXPR
)
3688 expr
*e
= as_a
<expr
*> (result
);
3689 id_base
*opr
= e
->operation
;
3690 /* When we delay operator substituting during lowering of fors we
3691 make sure that for code-gen purposes the effects of each substitute
3692 are the same. Thus just look at that. */
3693 if (user_id
*uid
= dyn_cast
<user_id
*> (opr
))
3694 opr
= uid
->substitutes
[0];
3695 else if (is_a
<predicate_id
*> (opr
))
3696 is_predicate
= true;
3697 /* Search for captures used multiple times in the result expression
3698 and wrap them in a SAVE_EXPR. Allow as many uses as in the
3699 original expression. */
3701 for (int i
= 0; i
< s
->capture_max
+ 1; ++i
)
3703 if (cinfo
.info
[i
].same_as
!= (unsigned)i
3704 || cinfo
.info
[i
].cse_p
)
3706 if (cinfo
.info
[i
].result_use_count
3707 > cinfo
.info
[i
].match_use_count
)
3709 fprintf_indent (f
, indent
,
3710 "if (! tree_invariant_p (captures[%d])) "
3711 "goto %s;\n", i
, fail_label
);
3715 for (unsigned j
= 0; j
< e
->ops
.length (); ++j
)
3719 snprintf (dest
, sizeof (dest
), "res_ops[%d]", j
);
3722 fprintf_indent (f
, indent
, "tree res_op%d;\n", j
);
3723 snprintf (dest
, sizeof (dest
), "res_op%d", j
);
3726 = get_operand_type (opr
, j
,
3727 "type", e
->expr_type
,
3729 ? NULL
: "TREE_TYPE (res_op0)");
3730 e
->ops
[j
]->gen_transform (f
, indent
, dest
, false, 1, optype
,
3735 emit_logging_call (f
, indent
, s
, result
, gimple
);
3736 fprintf_indent (f
, indent
, "return true;\n");
3740 fprintf_indent (f
, indent
, "tree _r;\n");
3741 /* Re-fold the toplevel result. Use non_lvalue to
3742 build NON_LVALUE_EXPRs so they get properly
3743 ignored when in GIMPLE form. */
3744 if (*opr
== NON_LVALUE_EXPR
)
3745 fprintf_indent (f
, indent
,
3746 "_r = non_lvalue_loc (loc, res_op0);\n");
3749 if (is_a
<operator_id
*> (opr
))
3750 fprintf_indent (f
, indent
,
3751 "_r = fold_build%d_loc (loc, %s, type",
3753 *e
->operation
== CONVERT_EXPR
3754 ? "NOP_EXPR" : e
->operation
->id
);
3756 fprintf_indent (f
, indent
,
3757 "_r = maybe_build_call_expr_loc (loc, "
3758 "%s, type, %d", e
->operation
->id
,
3760 for (unsigned j
= 0; j
< e
->ops
.length (); ++j
)
3761 fprintf (f
, ", res_op%d", j
);
3762 fprintf (f
, ");\n");
3763 if (!is_a
<operator_id
*> (opr
))
3765 fprintf_indent (f
, indent
, "if (!_r)\n");
3766 fprintf_indent (f
, indent
, " goto %s;\n", fail_label
);
3772 else if (result
->type
== operand::OP_CAPTURE
3773 || result
->type
== operand::OP_C_EXPR
)
3776 fprintf_indent (f
, indent
, "tree _r;\n");
3777 result
->gen_transform (f
, indent
, "_r", false, 1, "type",
3784 /* Search for captures not used in the result expression and dependent
3785 on TREE_SIDE_EFFECTS emit omit_one_operand. */
3786 for (int i
= 0; i
< s
->capture_max
+ 1; ++i
)
3788 if (cinfo
.info
[i
].same_as
!= (unsigned)i
)
3790 if (!cinfo
.info
[i
].force_no_side_effects_p
3791 && !cinfo
.info
[i
].expr_p
3792 && cinfo
.info
[i
].result_use_count
== 0)
3794 fprintf_indent (f
, indent
,
3795 "if (TREE_SIDE_EFFECTS (captures[%d]))\n",
3797 fprintf_indent (f
, indent
+ 2,
3798 "_r = build2_loc (loc, COMPOUND_EXPR, type, "
3799 "fold_ignored_result (captures[%d]), _r);\n",
3803 emit_logging_call (f
, indent
, s
, result
, gimple
);
3804 fprintf_indent (f
, indent
, "return _r;\n");
3808 fprintf_indent (f
, indent
, "}\n");
3810 fprintf (f
, "%s:;\n", fail_label
);
3814 /* Generate code for the '(if ...)', '(with ..)' and actual transform
3815 step of a '(simplify ...)' or '(match ...)'. This handles everything
3816 that is not part of the decision tree (simplify->match). */
3819 dt_simplify::gen (FILE *f
, int indent
, bool gimple
, int depth ATTRIBUTE_UNUSED
)
3821 fprintf_indent (f
, indent
, "{\n");
3823 output_line_directive (f
,
3824 s
->result
? s
->result
->location
: s
->match
->location
);
3825 if (s
->capture_max
>= 0)
3828 fprintf_indent (f
, indent
, "tree captures[%u] ATTRIBUTE_UNUSED = { %s",
3829 s
->capture_max
+ 1, indexes
[0]->get_name (opname
));
3831 for (int i
= 1; i
<= s
->capture_max
; ++i
)
3835 fprintf (f
, ", %s", indexes
[i
]->get_name (opname
));
3837 fprintf (f
, " };\n");
3840 /* If we have a split-out function for the actual transform, call it. */
3841 if (info
&& info
->fname
)
3845 fprintf_indent (f
, indent
, "if (%s (res_op, seq, "
3846 "valueize, type, captures", info
->fname
);
3847 for (unsigned i
= 0; i
< s
->for_subst_vec
.length (); ++i
)
3848 if (s
->for_subst_vec
[i
].first
->used
)
3849 fprintf (f
, ", %s", s
->for_subst_vec
[i
].second
->id
);
3850 fprintf (f
, "))\n");
3851 fprintf_indent (f
, indent
, " return true;\n");
3855 fprintf_indent (f
, indent
, "tree res = %s (loc, type",
3857 for (unsigned i
= 0; i
< as_a
<expr
*> (s
->match
)->ops
.length (); ++i
)
3858 fprintf (f
, ", _p%d", i
);
3859 fprintf (f
, ", captures");
3860 for (unsigned i
= 0; i
< s
->for_subst_vec
.length (); ++i
)
3862 if (s
->for_subst_vec
[i
].first
->used
)
3863 fprintf (f
, ", %s", s
->for_subst_vec
[i
].second
->id
);
3865 fprintf (f
, ");\n");
3866 fprintf_indent (f
, indent
, "if (res) return res;\n");
3871 for (unsigned i
= 0; i
< s
->for_subst_vec
.length (); ++i
)
3873 if (! s
->for_subst_vec
[i
].first
->used
)
3875 if (is_a
<operator_id
*> (s
->for_subst_vec
[i
].second
))
3876 fprintf_indent (f
, indent
, "const enum tree_code %s = %s;\n",
3877 s
->for_subst_vec
[i
].first
->id
,
3878 s
->for_subst_vec
[i
].second
->id
);
3879 else if (is_a
<fn_id
*> (s
->for_subst_vec
[i
].second
))
3880 fprintf_indent (f
, indent
, "const combined_fn %s = %s;\n",
3881 s
->for_subst_vec
[i
].first
->id
,
3882 s
->for_subst_vec
[i
].second
->id
);
3886 gen_1 (f
, indent
, gimple
, s
->result
);
3890 fprintf_indent (f
, indent
, "}\n");
3894 /* Hash function for finding equivalent transforms. */
3897 sinfo_hashmap_traits::hash (const key_type
&v
)
3899 /* Only bother to compare those originating from the same source pattern. */
3900 return v
->s
->result
->location
;
3903 /* Compare function for finding equivalent transforms. */
3906 compare_op (operand
*o1
, simplify
*s1
, operand
*o2
, simplify
*s2
)
3908 if (o1
->type
!= o2
->type
)
3913 case operand::OP_IF
:
3915 if_expr
*if1
= as_a
<if_expr
*> (o1
);
3916 if_expr
*if2
= as_a
<if_expr
*> (o2
);
3917 /* ??? Properly compare c-exprs. */
3918 if (if1
->cond
!= if2
->cond
)
3920 if (!compare_op (if1
->trueexpr
, s1
, if2
->trueexpr
, s2
))
3922 if (if1
->falseexpr
!= if2
->falseexpr
3924 && !compare_op (if1
->falseexpr
, s1
, if2
->falseexpr
, s2
)))
3928 case operand::OP_WITH
:
3930 with_expr
*with1
= as_a
<with_expr
*> (o1
);
3931 with_expr
*with2
= as_a
<with_expr
*> (o2
);
3932 if (with1
->with
!= with2
->with
)
3934 return compare_op (with1
->subexpr
, s1
, with2
->subexpr
, s2
);
3939 /* We've hit a result. Time to compare capture-infos - this is required
3940 in addition to the conservative pointer-equivalency of the result IL. */
3941 capture_info
cinfo1 (s1
, o1
, true);
3942 capture_info
cinfo2 (s2
, o2
, true);
3944 if (cinfo1
.force_no_side_effects
!= cinfo2
.force_no_side_effects
3945 || cinfo1
.info
.length () != cinfo2
.info
.length ())
3948 for (unsigned i
= 0; i
< cinfo1
.info
.length (); ++i
)
3950 if (cinfo1
.info
[i
].expr_p
!= cinfo2
.info
[i
].expr_p
3951 || cinfo1
.info
[i
].cse_p
!= cinfo2
.info
[i
].cse_p
3952 || (cinfo1
.info
[i
].force_no_side_effects_p
3953 != cinfo2
.info
[i
].force_no_side_effects_p
)
3954 || cinfo1
.info
[i
].force_single_use
!= cinfo2
.info
[i
].force_single_use
3955 || cinfo1
.info
[i
].cond_expr_cond_p
!= cinfo2
.info
[i
].cond_expr_cond_p
3956 /* toplevel_msk is an optimization */
3957 || cinfo1
.info
[i
].result_use_count
!= cinfo2
.info
[i
].result_use_count
3958 || cinfo1
.info
[i
].same_as
!= cinfo2
.info
[i
].same_as
3959 /* the pointer back to the capture is for diagnostics only */)
3963 /* ??? Deep-compare the actual result. */
3968 sinfo_hashmap_traits::equal_keys (const key_type
&v
,
3969 const key_type
&candidate
)
3971 return compare_op (v
->s
->result
, v
->s
, candidate
->s
->result
, candidate
->s
);
3975 /* Main entry to generate code for matching GIMPLE IL off the decision
3979 decision_tree::gen (vec
<FILE *> &files
, bool gimple
)
3985 fprintf (stderr
, "%s decision tree has %u leafs, maximum depth %u and "
3986 "a total number of %u nodes\n",
3987 gimple
? "GIMPLE" : "GENERIC",
3988 root
->num_leafs
, root
->max_level
, root
->total_size
);
3990 /* First split out the transform part of equal leafs. */
3993 for (sinfo_map_t::iterator iter
= si
.begin ();
3994 iter
!= si
.end (); ++iter
)
3996 sinfo
*s
= (*iter
).second
;
3997 /* Do not split out single uses. */
4004 fprintf (stderr
, "found %u uses of", s
->cnt
);
4005 output_line_directive (stderr
, s
->s
->s
->result
->location
);
4008 /* Cycle the file buffers. */
4009 FILE *f
= choose_output (files
);
4011 /* Generate a split out function with the leaf transform code. */
4012 s
->fname
= xasprintf ("%s_simplify_%u", gimple
? "gimple" : "generic",
4015 fp_decl (f
, "\nbool\n"
4016 "%s (gimple_match_op *res_op, gimple_seq *seq,\n"
4017 " tree (*valueize)(tree) ATTRIBUTE_UNUSED,\n"
4018 " const tree ARG_UNUSED (type), tree *ARG_UNUSED "
4023 fp_decl (f
, "\ntree\n"
4024 "%s (location_t ARG_UNUSED (loc), const tree ARG_UNUSED (type),\n",
4025 (*iter
).second
->fname
);
4026 for (unsigned i
= 0;
4027 i
< as_a
<expr
*>(s
->s
->s
->match
)->ops
.length (); ++i
)
4028 fp_decl (f
, " tree ARG_UNUSED (_p%d),", i
);
4029 fp_decl (f
, " tree *captures");
4031 for (unsigned i
= 0; i
< s
->s
->s
->for_subst_vec
.length (); ++i
)
4033 if (! s
->s
->s
->for_subst_vec
[i
].first
->used
)
4035 if (is_a
<operator_id
*> (s
->s
->s
->for_subst_vec
[i
].second
))
4036 fp_decl (f
, ",\n const enum tree_code ARG_UNUSED (%s)",
4037 s
->s
->s
->for_subst_vec
[i
].first
->id
);
4038 else if (is_a
<fn_id
*> (s
->s
->s
->for_subst_vec
[i
].second
))
4039 fp_decl (f
, ",\n const combined_fn ARG_UNUSED (%s)",
4040 s
->s
->s
->for_subst_vec
[i
].first
->id
);
4043 fp_decl_done (f
, ")");
4045 fprintf_indent (f
, 2, "const bool debug_dump = "
4046 "dump_file && (dump_flags & TDF_FOLDING);\n");
4047 s
->s
->gen_1 (f
, 2, gimple
, s
->s
->s
->result
);
4049 fprintf (f
, " return false;\n");
4051 fprintf (f
, " return NULL_TREE;\n");
4054 fprintf (stderr
, "removed %u duplicate tails\n", rcnt
);
4056 for (unsigned n
= 1; n
<= 7; ++n
)
4058 bool has_kids_p
= false;
4060 /* First generate split-out functions. */
4061 for (unsigned j
= 0; j
< root
->kids
.length (); j
++)
4063 dt_operand
*dop
= static_cast<dt_operand
*>(root
->kids
[j
]);
4064 expr
*e
= static_cast<expr
*>(dop
->op
);
4065 if (e
->ops
.length () != n
4066 /* Builtin simplifications are somewhat premature on
4067 GENERIC. The following drops patterns with outermost
4068 calls. It's easy to emit overloads for function code
4069 though if necessary. */
4071 && e
->operation
->kind
!= id_base::CODE
))
4075 /* Cycle the file buffers. */
4076 FILE *f
= choose_output (files
);
4079 fp_decl (f
, "\nbool\n"
4080 "gimple_simplify_%s (gimple_match_op *res_op,"
4081 " gimple_seq *seq,\n"
4082 " tree (*valueize)(tree) "
4083 "ATTRIBUTE_UNUSED,\n"
4084 " code_helper ARG_UNUSED (code), tree "
4085 "ARG_UNUSED (type)",
4088 fp_decl (f
, "\ntree\n"
4089 "generic_simplify_%s (location_t ARG_UNUSED (loc), enum "
4090 "tree_code ARG_UNUSED (code), const tree ARG_UNUSED (type)",
4092 for (unsigned i
= 0; i
< n
; ++i
)
4093 fp_decl (f
, ", tree _p%d", i
);
4094 fp_decl_done (f
, ")");
4096 fprintf_indent (f
, 2, "const bool debug_dump = "
4097 "dump_file && (dump_flags & TDF_FOLDING);\n");
4098 dop
->gen_kids (f
, 2, gimple
, 0);
4100 fprintf (f
, " return false;\n");
4102 fprintf (f
, " return NULL_TREE;\n");
4107 /* If this main entry has no children, avoid generating code
4108 with compiler warnings, by generating a simple stub. */
4112 /* Cycle the file buffers. */
4113 FILE *f
= choose_output (files
);
4116 fp_decl (f
, "\nbool\n"
4117 "gimple_simplify (gimple_match_op*, gimple_seq*,\n"
4118 " tree (*)(tree), code_helper,\n"
4121 fp_decl (f
, "\ntree\n"
4122 "generic_simplify (location_t, enum tree_code,\n"
4124 for (unsigned i
= 0; i
< n
; ++i
)
4125 fp_decl (f
, ", tree");
4126 fp_decl_done (f
, ")");
4129 fprintf (f
, " return false;\n");
4131 fprintf (f
, " return NULL_TREE;\n");
4137 /* Cycle the file buffers. */
4138 FILE *f
= choose_output (files
);
4140 /* Then generate the main entry with the outermost switch and
4141 tail-calls to the split-out functions. */
4143 fp_decl (f
, "\nbool\n"
4144 "gimple_simplify (gimple_match_op *res_op, gimple_seq *seq,\n"
4145 " tree (*valueize)(tree) ATTRIBUTE_UNUSED,\n"
4146 " code_helper code, const tree type");
4148 fp_decl (f
, "\ntree\n"
4149 "generic_simplify (location_t loc, enum tree_code code, "
4150 "const tree type ATTRIBUTE_UNUSED");
4151 for (unsigned i
= 0; i
< n
; ++i
)
4152 fp_decl (f
, ", tree _p%d", i
);
4153 fp_decl_done (f
, ")");
4157 fprintf (f
, " switch (code.get_rep())\n"
4160 fprintf (f
, " switch (code)\n"
4162 for (unsigned i
= 0; i
< root
->kids
.length (); i
++)
4164 dt_operand
*dop
= static_cast<dt_operand
*>(root
->kids
[i
]);
4165 expr
*e
= static_cast<expr
*>(dop
->op
);
4166 if (e
->ops
.length () != n
4167 /* Builtin simplifications are somewhat premature on
4168 GENERIC. The following drops patterns with outermost
4169 calls. It's easy to emit overloads for function code
4170 though if necessary. */
4172 && e
->operation
->kind
!= id_base::CODE
))
4175 if (*e
->operation
== CONVERT_EXPR
4176 || *e
->operation
== NOP_EXPR
)
4177 fprintf (f
, " CASE_CONVERT:\n");
4179 fprintf (f
, " case %s%s:\n",
4180 is_a
<fn_id
*> (e
->operation
) ? "-" : "",
4183 fprintf (f
, " return gimple_simplify_%s (res_op, "
4184 "seq, valueize, code, type", e
->operation
->id
);
4186 fprintf (f
, " return generic_simplify_%s (loc, code, type",
4188 for (unsigned j
= 0; j
< n
; ++j
)
4189 fprintf (f
, ", _p%d", j
);
4190 fprintf (f
, ");\n");
4192 fprintf (f
, " default:;\n"
4196 fprintf (f
, " return false;\n");
4198 fprintf (f
, " return NULL_TREE;\n");
4203 /* Output code to implement the predicate P from the decision tree DT. */
4206 write_predicate (FILE *f
, predicate_id
*p
, decision_tree
&dt
, bool gimple
)
4208 fp_decl (f
, "\nbool\n%s%s (tree t%s%s)",
4209 gimple
? "gimple_" : "tree_", p
->id
,
4210 p
->nargs
> 0 ? ", tree *res_ops" : "",
4211 gimple
? ", tree (*valueize)(tree) ATTRIBUTE_UNUSED" : "");
4212 fp_decl_done (f
, "");
4214 /* Conveniently make 'type' available. */
4215 fprintf_indent (f
, 2, "const tree type = TREE_TYPE (t);\n");
4216 fprintf_indent (f
, 2, "const bool debug_dump = "
4217 "dump_file && (dump_flags & TDF_FOLDING);\n");
4220 fprintf_indent (f
, 2, "if (TREE_SIDE_EFFECTS (t)) return false;\n");
4221 dt
.root
->gen_kids (f
, 2, gimple
, 0);
4223 fprintf_indent (f
, 2, "return false;\n"
4227 /* Write the common header for the GIMPLE/GENERIC IL matching routines. */
4230 write_header (FILE *f
, const char *head
)
4232 fprintf (f
, "/* Generated automatically by the program `genmatch' from\n");
4233 fprintf (f
, " a IL pattern matching and simplification description. */\n");
4234 fprintf (f
, "#pragma GCC diagnostic push\n");
4235 fprintf (f
, "#pragma GCC diagnostic ignored \"-Wunused-variable\"\n");
4236 fprintf (f
, "#pragma GCC diagnostic ignored \"-Wunused-function\"\n");
4238 /* Include the header instead of writing it awkwardly quoted here. */
4240 fprintf (f
, "\n#include \"%s\"\n", head
);
4250 parser (cpp_reader
*, bool gimple
);
4253 const cpp_token
*next ();
4254 const cpp_token
*peek (unsigned = 1);
4255 const cpp_token
*peek_ident (const char * = NULL
, unsigned = 1);
4256 const cpp_token
*expect (enum cpp_ttype
);
4257 const cpp_token
*eat_token (enum cpp_ttype
);
4258 const char *get_string ();
4259 const char *get_ident ();
4260 const cpp_token
*eat_ident (const char *);
4261 const char *get_number ();
4263 unsigned get_internal_capture_id ();
4265 id_base
*parse_operation (unsigned char &);
4266 operand
*parse_capture (operand
*, bool);
4267 operand
*parse_expr ();
4268 c_expr
*parse_c_expr (cpp_ttype
);
4269 operand
*parse_op ();
4271 void record_operlist (location_t
, user_id
*);
4273 void parse_pattern ();
4274 operand
*parse_result (operand
*, predicate_id
*);
4275 void push_simplify (simplify::simplify_kind
,
4276 vec
<simplify
*>&, operand
*, operand
*);
4277 void parse_simplify (simplify::simplify_kind
,
4278 vec
<simplify
*>&, predicate_id
*, operand
*);
4279 void parse_for (location_t
);
4280 void parse_if (location_t
);
4281 void parse_predicates (location_t
);
4282 void parse_operator_list (location_t
);
4284 void finish_match_operand (operand
*);
4288 vec
<c_expr
*> active_ifs
;
4289 vec
<vec
<user_id
*> > active_fors
;
4290 hash_set
<user_id
*> *oper_lists_set
;
4291 vec
<user_id
*> oper_lists
;
4293 cid_map_t
*capture_ids
;
4297 vec
<simplify
*> simplifiers
;
4298 vec
<predicate_id
*> user_predicates
;
4299 bool parsing_match_operand
;
4302 /* Lexing helpers. */
4304 /* Read the next non-whitespace token from R. */
4309 const cpp_token
*token
;
4312 token
= cpp_get_token (r
);
4314 while (token
->type
== CPP_PADDING
);
4318 /* Peek at the next non-whitespace token from R. */
4321 parser::peek (unsigned num
)
4323 const cpp_token
*token
;
4327 token
= cpp_peek_token (r
, i
++);
4329 while (token
->type
== CPP_PADDING
4331 /* If we peek at EOF this is a fatal error as it leaves the
4332 cpp_reader in unusable state. Assume we really wanted a
4333 token and thus this EOF is unexpected. */
4334 if (token
->type
== CPP_EOF
)
4335 fatal_at (token
, "unexpected end of file");
4339 /* Peek at the next identifier token (or return NULL if the next
4340 token is not an identifier or equal to ID if supplied). */
4343 parser::peek_ident (const char *id
, unsigned num
)
4345 const cpp_token
*token
= peek (num
);
4346 if (token
->type
!= CPP_NAME
)
4352 const char *t
= (const char *) CPP_HASHNODE (token
->val
.node
.node
)->ident
.str
;
4353 if (strcmp (id
, t
) == 0)
4359 /* Read the next token from R and assert it is of type TK. */
4362 parser::expect (enum cpp_ttype tk
)
4364 const cpp_token
*token
= next ();
4365 if (token
->type
!= tk
)
4366 fatal_at (token
, "expected %s, got %s",
4367 cpp_type2name (tk
, 0), cpp_type2name (token
->type
, 0));
4372 /* Consume the next token from R and assert it is of type TK. */
4375 parser::eat_token (enum cpp_ttype tk
)
4380 /* Read the next token from R and assert it is of type CPP_STRING and
4381 return its value. */
4384 parser::get_string ()
4386 const cpp_token
*token
= expect (CPP_STRING
);
4387 return (const char *)token
->val
.str
.text
;
4390 /* Read the next token from R and assert it is of type CPP_NAME and
4391 return its value. */
4394 parser::get_ident ()
4396 const cpp_token
*token
= expect (CPP_NAME
);
4397 return (const char *)CPP_HASHNODE (token
->val
.node
.node
)->ident
.str
;
4400 /* Eat an identifier token with value S from R. */
4403 parser::eat_ident (const char *s
)
4405 const cpp_token
*token
= peek ();
4406 const char *t
= get_ident ();
4407 if (strcmp (s
, t
) != 0)
4408 fatal_at (token
, "expected '%s' got '%s'\n", s
, t
);
4412 /* Read the next token from R and assert it is of type CPP_NUMBER and
4413 return its value. */
4416 parser::get_number ()
4418 const cpp_token
*token
= expect (CPP_NUMBER
);
4419 return (const char *)token
->val
.str
.text
;
4422 /* Return a capture ID that can be used internally. */
4425 parser::get_internal_capture_id ()
4427 unsigned newid
= capture_ids
->elements ();
4428 /* Big enough for a 32-bit UINT_MAX plus prefix. */
4431 snprintf (id
, sizeof (id
), "__%u", newid
);
4432 capture_ids
->get_or_insert (xstrdup (id
), &existed
);
4434 fatal ("reserved capture id '%s' already used", id
);
4438 /* Record an operator-list use for transparent for handling. */
4441 parser::record_operlist (location_t loc
, user_id
*p
)
4443 if (!oper_lists_set
->add (p
))
4445 if (!oper_lists
.is_empty ()
4446 && oper_lists
[0]->substitutes
.length () != p
->substitutes
.length ())
4447 fatal_at (loc
, "User-defined operator list does not have the "
4448 "same number of entries as others used in the pattern");
4449 oper_lists
.safe_push (p
);
4453 /* Parse the operator ID, special-casing convert?, convert1? and
4457 parser::parse_operation (unsigned char &opt_grp
)
4459 const cpp_token
*id_tok
= peek ();
4460 char *alt_id
= NULL
;
4461 const char *id
= get_ident ();
4462 const cpp_token
*token
= peek ();
4464 if (token
->type
== CPP_QUERY
4465 && !(token
->flags
& PREV_WHITE
))
4467 if (!parsing_match_operand
)
4468 fatal_at (id_tok
, "conditional convert can only be used in "
4469 "match expression");
4470 if (ISDIGIT (id
[strlen (id
) - 1]))
4472 opt_grp
= id
[strlen (id
) - 1] - '0' + 1;
4473 alt_id
= xstrdup (id
);
4474 alt_id
[strlen (id
) - 1] = '\0';
4476 fatal_at (id_tok
, "use '%s?' here", alt_id
);
4480 eat_token (CPP_QUERY
);
4482 id_base
*op
= get_operator (alt_id
? alt_id
: id
);
4484 fatal_at (id_tok
, "unknown operator %s", alt_id
? alt_id
: id
);
4487 user_id
*p
= dyn_cast
<user_id
*> (op
);
4488 if (p
&& p
->is_oper_list
)
4490 if (active_fors
.length() == 0)
4491 record_operlist (id_tok
->src_loc
, p
);
4493 fatal_at (id_tok
, "operator-list %s cannot be expanded inside 'for'", id
);
4499 capture = '@'<number> */
4502 parser::parse_capture (operand
*op
, bool require_existing
)
4504 location_t src_loc
= eat_token (CPP_ATSIGN
)->src_loc
;
4505 const cpp_token
*token
= peek ();
4506 const char *id
= NULL
;
4507 bool value_match
= false;
4508 /* For matches parse @@ as a value-match denoting the prevailing operand. */
4509 if (token
->type
== CPP_ATSIGN
4510 && ! (token
->flags
& PREV_WHITE
)
4511 && parsing_match_operand
)
4513 eat_token (CPP_ATSIGN
);
4517 if (token
->type
== CPP_NUMBER
)
4519 else if (token
->type
== CPP_NAME
)
4522 fatal_at (token
, "expected number or identifier");
4523 unsigned next_id
= capture_ids
->elements ();
4525 unsigned &num
= capture_ids
->get_or_insert (id
, &existed
);
4528 if (require_existing
)
4529 fatal_at (src_loc
, "unknown capture id");
4532 return new capture (src_loc
, num
, op
, value_match
);
4535 /* Parse an expression
4536 expr = '(' <operation>[capture][flag][type] <operand>... ')' */
4539 parser::parse_expr ()
4541 const cpp_token
*token
= peek ();
4542 unsigned char opt_grp
;
4543 expr
*e
= new expr (parse_operation (opt_grp
), token
->src_loc
);
4546 bool is_commutative
= false;
4547 bool force_capture
= false;
4548 const char *expr_type
= NULL
;
4550 if (!parsing_match_operand
4551 && token
->type
== CPP_NOT
4552 && !(token
->flags
& PREV_WHITE
))
4554 eat_token (CPP_NOT
);
4555 e
->force_leaf
= true;
4558 if (token
->type
== CPP_COLON
4559 && !(token
->flags
& PREV_WHITE
))
4561 eat_token (CPP_COLON
);
4563 if (token
->type
== CPP_NAME
4564 && !(token
->flags
& PREV_WHITE
))
4566 const char *s
= get_ident ();
4567 if (!parsing_match_operand
)
4577 = dyn_cast
<operator_id
*> (e
->operation
))
4579 if (!commutative_tree_code (o
->code
)
4580 && !comparison_code_p (o
->code
))
4581 fatal_at (token
, "operation is not commutative");
4583 else if (user_id
*p
= dyn_cast
<user_id
*> (e
->operation
))
4584 for (unsigned i
= 0;
4585 i
< p
->substitutes
.length (); ++i
)
4588 = dyn_cast
<operator_id
*> (p
->substitutes
[i
]))
4590 if (!commutative_tree_code (q
->code
)
4591 && !comparison_code_p (q
->code
))
4592 fatal_at (token
, "operation %s is not "
4593 "commutative", q
->id
);
4596 is_commutative
= true;
4598 else if (*sp
== 'C')
4599 is_commutative
= true;
4600 else if (*sp
== 's')
4602 e
->force_single_use
= true;
4603 force_capture
= true;
4606 fatal_at (token
, "flag %c not recognized", *sp
);
4613 fatal_at (token
, "expected flag or type specifying identifier");
4616 if (token
->type
== CPP_ATSIGN
4617 && !(token
->flags
& PREV_WHITE
))
4618 op
= parse_capture (e
, false);
4619 else if (force_capture
)
4621 unsigned num
= get_internal_capture_id ();
4622 op
= new capture (token
->src_loc
, num
, e
, false);
4629 if (token
->type
== CPP_CLOSE_PAREN
)
4631 if (e
->operation
->nargs
!= -1
4632 && e
->operation
->nargs
!= (int) e
->ops
.length ())
4633 fatal_at (token
, "'%s' expects %u operands, not %u",
4634 e
->operation
->id
, e
->operation
->nargs
, e
->ops
.length ());
4637 if (e
->ops
.length () == 2
4638 || commutative_op (e
->operation
) >= 0)
4639 e
->is_commutative
= true;
4641 fatal_at (token
, "only binary operators or functions with "
4642 "two arguments can be marked commutative, "
4643 "unless the operation is known to be inherently "
4646 e
->expr_type
= expr_type
;
4649 if (e
->ops
.length () != 1)
4650 fatal_at (token
, "only unary operations can be conditional");
4651 e
->opt_grp
= opt_grp
;
4655 else if (!(token
->flags
& PREV_WHITE
))
4656 fatal_at (token
, "expected expression operand");
4658 e
->append_op (parse_op ());
4663 /* Lex native C code delimited by START recording the preprocessing tokens
4664 for later processing.
4665 c_expr = ('{'|'(') <pp token>... ('}'|')') */
4668 parser::parse_c_expr (cpp_ttype start
)
4670 const cpp_token
*token
;
4673 vec
<cpp_token
> code
= vNULL
;
4674 unsigned nr_stmts
= 0;
4675 location_t loc
= eat_token (start
)->src_loc
;
4676 if (start
== CPP_OPEN_PAREN
)
4677 end
= CPP_CLOSE_PAREN
;
4678 else if (start
== CPP_OPEN_BRACE
)
4679 end
= CPP_CLOSE_BRACE
;
4687 /* Count brace pairs to find the end of the expr to match. */
4688 if (token
->type
== start
)
4690 else if (token
->type
== end
4693 else if (token
->type
== CPP_EOF
)
4694 fatal_at (token
, "unexpected end of file");
4696 /* This is a lame way of counting the number of statements. */
4697 if (token
->type
== CPP_SEMICOLON
)
4700 /* If this is possibly a user-defined identifier mark it used. */
4701 if (token
->type
== CPP_NAME
)
4704 = (const char *)CPP_HASHNODE (token
->val
.node
.node
)->ident
.str
;
4705 if (strcmp (str
, "return") == 0)
4706 fatal_at (token
, "return statement not allowed in C expression");
4707 id_base
*idb
= get_operator (str
);
4709 if (idb
&& (p
= dyn_cast
<user_id
*> (idb
)) && p
->is_oper_list
)
4710 record_operlist (token
->src_loc
, p
);
4713 /* Record the token. */
4714 code
.safe_push (*token
);
4717 return new c_expr (r
, loc
, code
, nr_stmts
, vNULL
, capture_ids
);
4720 /* Parse an operand which is either an expression, a predicate or
4721 a standalone capture.
4722 op = predicate | expr | c_expr | capture */
4727 const cpp_token
*token
= peek ();
4728 class operand
*op
= NULL
;
4729 if (token
->type
== CPP_OPEN_PAREN
)
4731 eat_token (CPP_OPEN_PAREN
);
4733 eat_token (CPP_CLOSE_PAREN
);
4735 else if (token
->type
== CPP_OPEN_BRACE
)
4737 op
= parse_c_expr (CPP_OPEN_BRACE
);
4741 /* Remaining ops are either empty or predicates */
4742 if (token
->type
== CPP_NAME
)
4744 const char *id
= get_ident ();
4745 id_base
*opr
= get_operator (id
);
4747 fatal_at (token
, "expected predicate name");
4748 if (operator_id
*code1
= dyn_cast
<operator_id
*> (opr
))
4750 if (code1
->nargs
!= 0)
4751 fatal_at (token
, "using an operator with operands as predicate");
4752 /* Parse the zero-operand operator "predicates" as
4754 op
= new expr (opr
, token
->src_loc
);
4756 else if (user_id
*code2
= dyn_cast
<user_id
*> (opr
))
4758 if (code2
->nargs
!= 0)
4759 fatal_at (token
, "using an operator with operands as predicate");
4760 /* Parse the zero-operand operator "predicates" as
4762 op
= new expr (opr
, token
->src_loc
);
4764 else if (predicate_id
*p
= dyn_cast
<predicate_id
*> (opr
))
4765 op
= new predicate (p
, token
->src_loc
);
4767 fatal_at (token
, "using an unsupported operator as predicate");
4768 if (!parsing_match_operand
)
4769 fatal_at (token
, "predicates are only allowed in match expression");
4771 if (token
->flags
& PREV_WHITE
)
4774 else if (token
->type
!= CPP_COLON
4775 && token
->type
!= CPP_ATSIGN
)
4776 fatal_at (token
, "expected expression or predicate");
4777 /* optionally followed by a capture and a predicate. */
4778 if (token
->type
== CPP_COLON
)
4779 fatal_at (token
, "not implemented: predicate on leaf operand");
4780 if (token
->type
== CPP_ATSIGN
)
4781 op
= parse_capture (op
, !parsing_match_operand
);
4787 /* Create a new simplify from the current parsing state and MATCH,
4788 MATCH_LOC, RESULT and RESULT_LOC and push it to SIMPLIFIERS. */
4791 parser::push_simplify (simplify::simplify_kind kind
,
4792 vec
<simplify
*>& simplifiers
,
4793 operand
*match
, operand
*result
)
4795 /* Build and push a temporary for operator list uses in expressions. */
4796 if (!oper_lists
.is_empty ())
4797 active_fors
.safe_push (oper_lists
);
4799 simplifiers
.safe_push
4800 (new simplify (kind
, last_id
++, match
, result
,
4801 active_fors
.copy (), capture_ids
));
4803 if (!oper_lists
.is_empty ())
4808 <result-op> = <op> | <if> | <with>
4809 <if> = '(' 'if' '(' <c-expr> ')' <result-op> ')'
4810 <with> = '(' 'with' '{' <c-expr> '}' <result-op> ')'
4814 parser::parse_result (operand
*result
, predicate_id
*matcher
)
4816 const cpp_token
*token
= peek ();
4817 if (token
->type
!= CPP_OPEN_PAREN
)
4820 eat_token (CPP_OPEN_PAREN
);
4821 if (peek_ident ("if"))
4824 if_expr
*ife
= new if_expr (token
->src_loc
);
4825 ife
->cond
= parse_c_expr (CPP_OPEN_PAREN
);
4826 if (peek ()->type
== CPP_OPEN_PAREN
)
4828 ife
->trueexpr
= parse_result (result
, matcher
);
4829 if (peek ()->type
== CPP_OPEN_PAREN
)
4830 ife
->falseexpr
= parse_result (result
, matcher
);
4831 else if (peek ()->type
!= CPP_CLOSE_PAREN
)
4832 ife
->falseexpr
= parse_op ();
4834 else if (peek ()->type
!= CPP_CLOSE_PAREN
)
4836 ife
->trueexpr
= parse_op ();
4837 if (peek ()->type
== CPP_OPEN_PAREN
)
4838 ife
->falseexpr
= parse_result (result
, matcher
);
4839 else if (peek ()->type
!= CPP_CLOSE_PAREN
)
4840 ife
->falseexpr
= parse_op ();
4842 /* If this if is immediately closed then it contains a
4843 manual matcher or is part of a predicate definition. */
4844 else /* if (peek ()->type == CPP_CLOSE_PAREN) */
4847 fatal_at (peek (), "manual transform not implemented");
4848 ife
->trueexpr
= result
;
4850 eat_token (CPP_CLOSE_PAREN
);
4853 else if (peek_ident ("with"))
4856 with_expr
*withe
= new with_expr (token
->src_loc
);
4857 /* Parse (with c-expr expr) as (if-with (true) expr). */
4858 withe
->with
= parse_c_expr (CPP_OPEN_BRACE
);
4859 withe
->with
->nr_stmts
= 0;
4860 withe
->subexpr
= parse_result (result
, matcher
);
4861 eat_token (CPP_CLOSE_PAREN
);
4864 else if (peek_ident ("switch"))
4866 token
= eat_ident ("switch");
4867 location_t ifloc
= eat_token (CPP_OPEN_PAREN
)->src_loc
;
4869 if_expr
*ife
= new if_expr (ifloc
);
4871 ife
->cond
= parse_c_expr (CPP_OPEN_PAREN
);
4872 if (peek ()->type
== CPP_OPEN_PAREN
)
4873 ife
->trueexpr
= parse_result (result
, matcher
);
4875 ife
->trueexpr
= parse_op ();
4876 eat_token (CPP_CLOSE_PAREN
);
4877 if (peek ()->type
!= CPP_OPEN_PAREN
4878 || !peek_ident ("if", 2))
4879 fatal_at (token
, "switch can be implemented with a single if");
4880 while (peek ()->type
!= CPP_CLOSE_PAREN
)
4882 if (peek ()->type
== CPP_OPEN_PAREN
)
4884 if (peek_ident ("if", 2))
4886 ifloc
= eat_token (CPP_OPEN_PAREN
)->src_loc
;
4888 ife
->falseexpr
= new if_expr (ifloc
);
4889 ife
= as_a
<if_expr
*> (ife
->falseexpr
);
4890 ife
->cond
= parse_c_expr (CPP_OPEN_PAREN
);
4891 if (peek ()->type
== CPP_OPEN_PAREN
)
4892 ife
->trueexpr
= parse_result (result
, matcher
);
4894 ife
->trueexpr
= parse_op ();
4895 if (peek ()->type
== CPP_OPEN_PAREN
)
4896 fatal_at (peek(), "if inside switch cannot have an else");
4897 eat_token (CPP_CLOSE_PAREN
);
4901 /* switch default clause */
4902 ife
->falseexpr
= parse_result (result
, matcher
);
4903 eat_token (CPP_CLOSE_PAREN
);
4909 /* switch default clause */
4910 ife
->falseexpr
= parse_op ();
4911 eat_token (CPP_CLOSE_PAREN
);
4915 eat_token (CPP_CLOSE_PAREN
);
4920 operand
*op
= result
;
4923 eat_token (CPP_CLOSE_PAREN
);
4929 simplify = 'simplify' <expr> <result-op>
4931 match = 'match' <ident> <expr> [<result-op>]
4932 and fill SIMPLIFIERS with the results. */
4935 parser::parse_simplify (simplify::simplify_kind kind
,
4936 vec
<simplify
*>& simplifiers
, predicate_id
*matcher
,
4939 /* Reset the capture map. */
4941 capture_ids
= new cid_map_t
;
4942 /* Reset oper_lists and set. */
4943 hash_set
<user_id
*> olist
;
4944 oper_lists_set
= &olist
;
4947 const cpp_token
*loc
= peek ();
4948 parsing_match_operand
= true;
4949 class operand
*match
= parse_op ();
4950 finish_match_operand (match
);
4951 parsing_match_operand
= false;
4952 if (match
->type
== operand::OP_CAPTURE
&& !matcher
)
4953 fatal_at (loc
, "outermost expression cannot be captured");
4954 if (match
->type
== operand::OP_EXPR
4955 && is_a
<predicate_id
*> (as_a
<expr
*> (match
)->operation
))
4956 fatal_at (loc
, "outermost expression cannot be a predicate");
4958 /* Splice active_ifs onto result and continue parsing the
4960 if_expr
*active_if
= NULL
;
4961 for (int i
= active_ifs
.length (); i
> 0; --i
)
4963 if_expr
*ifc
= new if_expr (active_ifs
[i
-1]->location
);
4964 ifc
->cond
= active_ifs
[i
-1];
4965 ifc
->trueexpr
= active_if
;
4968 if_expr
*outermost_if
= active_if
;
4969 while (active_if
&& active_if
->trueexpr
)
4970 active_if
= as_a
<if_expr
*> (active_if
->trueexpr
);
4972 const cpp_token
*token
= peek ();
4974 /* If this if is immediately closed then it is part of a predicate
4975 definition. Push it. */
4976 if (token
->type
== CPP_CLOSE_PAREN
)
4979 fatal_at (token
, "expected transform expression");
4982 active_if
->trueexpr
= result
;
4983 result
= outermost_if
;
4985 push_simplify (kind
, simplifiers
, match
, result
);
4989 operand
*tem
= parse_result (result
, matcher
);
4992 active_if
->trueexpr
= tem
;
4993 result
= outermost_if
;
4998 push_simplify (kind
, simplifiers
, match
, result
);
5001 /* Parsing of the outer control structures. */
5003 /* Parse a for expression
5004 for = '(' 'for' <subst>... <pattern> ')'
5005 subst = <ident> '(' <ident>... ')' */
5008 parser::parse_for (location_t
)
5010 auto_vec
<const cpp_token
*> user_id_tokens
;
5011 vec
<user_id
*> user_ids
= vNULL
;
5012 const cpp_token
*token
;
5013 unsigned min_n_opers
= 0, max_n_opers
= 0;
5018 if (token
->type
!= CPP_NAME
)
5021 /* Insert the user defined operators into the operator hash. */
5022 const char *id
= get_ident ();
5023 if (get_operator (id
, true) != NULL
)
5024 fatal_at (token
, "operator already defined");
5025 user_id
*op
= new user_id (id
);
5026 id_base
**slot
= operators
->find_slot_with_hash (op
, op
->hashval
, INSERT
);
5028 user_ids
.safe_push (op
);
5029 user_id_tokens
.safe_push (token
);
5031 eat_token (CPP_OPEN_PAREN
);
5034 while ((token
= peek_ident ()) != 0)
5036 const char *oper
= get_ident ();
5037 id_base
*idb
= get_operator (oper
, true);
5039 fatal_at (token
, "no such operator '%s'", oper
);
5043 else if (idb
->nargs
== -1)
5045 else if (idb
->nargs
!= arity
)
5046 fatal_at (token
, "operator '%s' with arity %d does not match "
5047 "others with arity %d", oper
, idb
->nargs
, arity
);
5049 user_id
*p
= dyn_cast
<user_id
*> (idb
);
5052 if (p
->is_oper_list
)
5053 op
->substitutes
.safe_splice (p
->substitutes
);
5055 fatal_at (token
, "iterator cannot be used as operator-list");
5058 op
->substitutes
.safe_push (idb
);
5061 token
= expect (CPP_CLOSE_PAREN
);
5063 unsigned nsubstitutes
= op
->substitutes
.length ();
5064 if (nsubstitutes
== 0)
5065 fatal_at (token
, "A user-defined operator must have at least "
5066 "one substitution");
5067 if (max_n_opers
== 0)
5069 min_n_opers
= nsubstitutes
;
5070 max_n_opers
= nsubstitutes
;
5074 if (nsubstitutes
% min_n_opers
!= 0
5075 && min_n_opers
% nsubstitutes
!= 0)
5076 fatal_at (token
, "All user-defined identifiers must have a "
5077 "multiple number of operator substitutions of the "
5078 "smallest number of substitutions");
5079 if (nsubstitutes
< min_n_opers
)
5080 min_n_opers
= nsubstitutes
;
5081 else if (nsubstitutes
> max_n_opers
)
5082 max_n_opers
= nsubstitutes
;
5086 unsigned n_ids
= user_ids
.length ();
5088 fatal_at (token
, "for requires at least one user-defined identifier");
5091 if (token
->type
== CPP_CLOSE_PAREN
)
5092 fatal_at (token
, "no pattern defined in for");
5094 active_fors
.safe_push (user_ids
);
5098 if (token
->type
== CPP_CLOSE_PAREN
)
5104 /* Remove user-defined operators from the hash again. */
5105 for (unsigned i
= 0; i
< user_ids
.length (); ++i
)
5107 if (!user_ids
[i
]->used
)
5108 warning_at (user_id_tokens
[i
],
5109 "operator %s defined but not used", user_ids
[i
]->id
);
5110 operators
->remove_elt (user_ids
[i
]);
5114 /* Parse an identifier associated with a list of operators.
5115 oprs = '(' 'define_operator_list' <ident> <ident>... ')' */
5118 parser::parse_operator_list (location_t
)
5120 const cpp_token
*token
= peek ();
5121 const char *id
= get_ident ();
5123 if (get_operator (id
, true) != 0)
5124 fatal_at (token
, "operator %s already defined", id
);
5126 user_id
*op
= new user_id (id
, true);
5129 while ((token
= peek_ident ()) != 0)
5132 const char *oper
= get_ident ();
5133 id_base
*idb
= get_operator (oper
, true);
5136 fatal_at (token
, "no such operator '%s'", oper
);
5140 else if (idb
->nargs
== -1)
5142 else if (arity
!= idb
->nargs
)
5143 fatal_at (token
, "operator '%s' with arity %d does not match "
5144 "others with arity %d", oper
, idb
->nargs
, arity
);
5146 /* We allow composition of multiple operator lists. */
5147 if (user_id
*p
= dyn_cast
<user_id
*> (idb
))
5148 op
->substitutes
.safe_splice (p
->substitutes
);
5150 op
->substitutes
.safe_push (idb
);
5153 // Check that there is no junk after id-list
5155 if (token
->type
!= CPP_CLOSE_PAREN
)
5156 fatal_at (token
, "expected identifier got %s", cpp_type2name (token
->type
, 0));
5158 if (op
->substitutes
.length () == 0)
5159 fatal_at (token
, "operator-list cannot be empty");
5162 id_base
**slot
= operators
->find_slot_with_hash (op
, op
->hashval
, INSERT
);
5166 /* Parse an outer if expression.
5167 if = '(' 'if' '(' <c-expr> ')' <pattern> ')' */
5170 parser::parse_if (location_t
)
5172 c_expr
*ifexpr
= parse_c_expr (CPP_OPEN_PAREN
);
5174 const cpp_token
*token
= peek ();
5175 if (token
->type
== CPP_CLOSE_PAREN
)
5176 fatal_at (token
, "no pattern defined in if");
5178 active_ifs
.safe_push (ifexpr
);
5182 if (token
->type
== CPP_CLOSE_PAREN
)
5190 /* Parse a list of predefined predicate identifiers.
5191 preds = '(' 'define_predicates' <ident>... ')' */
5194 parser::parse_predicates (location_t
)
5198 const cpp_token
*token
= peek ();
5199 if (token
->type
!= CPP_NAME
)
5202 add_predicate (get_ident ());
5207 /* Parse outer control structures.
5208 pattern = <preds>|<for>|<if>|<simplify>|<match> */
5211 parser::parse_pattern ()
5213 /* All clauses start with '('. */
5214 eat_token (CPP_OPEN_PAREN
);
5215 const cpp_token
*token
= peek ();
5216 const char *id
= get_ident ();
5217 if (strcmp (id
, "simplify") == 0)
5219 parse_simplify (simplify::SIMPLIFY
, simplifiers
, NULL
, NULL
);
5222 else if (strcmp (id
, "match") == 0)
5224 bool with_args
= false;
5225 location_t e_loc
= peek ()->src_loc
;
5226 if (peek ()->type
== CPP_OPEN_PAREN
)
5228 eat_token (CPP_OPEN_PAREN
);
5231 const char *name
= get_ident ();
5232 id_base
*id1
= get_operator (name
);
5236 p
= add_predicate (name
);
5237 user_predicates
.safe_push (p
);
5239 else if ((p
= dyn_cast
<predicate_id
*> (id1
)))
5242 fatal_at (token
, "cannot add a match to a non-predicate ID");
5243 /* Parse (match <id> <arg>... (match-expr)) here. */
5247 capture_ids
= new cid_map_t
;
5248 e
= new expr (p
, e_loc
);
5249 while (peek ()->type
== CPP_ATSIGN
)
5250 e
->append_op (parse_capture (NULL
, false));
5251 eat_token (CPP_CLOSE_PAREN
);
5254 && ((e
&& e
->ops
.length () != (unsigned)p
->nargs
)
5255 || (!e
&& p
->nargs
!= 0)))
5256 fatal_at (token
, "non-matching number of match operands");
5257 p
->nargs
= e
? e
->ops
.length () : 0;
5258 parse_simplify (simplify::MATCH
, p
->matchers
, p
, e
);
5261 else if (strcmp (id
, "for") == 0)
5262 parse_for (token
->src_loc
);
5263 else if (strcmp (id
, "if") == 0)
5264 parse_if (token
->src_loc
);
5265 else if (strcmp (id
, "define_predicates") == 0)
5267 if (active_ifs
.length () > 0
5268 || active_fors
.length () > 0)
5269 fatal_at (token
, "define_predicates inside if or for is not supported");
5270 parse_predicates (token
->src_loc
);
5272 else if (strcmp (id
, "define_operator_list") == 0)
5274 if (active_ifs
.length () > 0
5275 || active_fors
.length () > 0)
5276 fatal_at (token
, "operator-list inside if or for is not supported");
5277 parse_operator_list (token
->src_loc
);
5280 fatal_at (token
, "expected %s'simplify', 'match', 'for' or 'if'",
5281 active_ifs
.length () == 0 && active_fors
.length () == 0
5282 ? "'define_predicates', " : "");
5284 eat_token (CPP_CLOSE_PAREN
);
5287 /* Helper for finish_match_operand, collecting captures of OP in CPTS
5291 walk_captures (operand
*op
, vec
<vec
<capture
*> > &cpts
)
5296 if (capture
*c
= dyn_cast
<capture
*> (op
))
5298 cpts
[c
->where
].safe_push (c
);
5299 walk_captures (c
->what
, cpts
);
5301 else if (expr
*e
= dyn_cast
<expr
*> (op
))
5302 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
5303 walk_captures (e
->ops
[i
], cpts
);
5306 /* Finish up OP which is a match operand. */
5309 parser::finish_match_operand (operand
*op
)
5311 /* Look for matching captures, diagnose mis-uses of @@ and apply
5312 early lowering and distribution of value_match. */
5313 auto_vec
<vec
<capture
*> > cpts
;
5314 cpts
.safe_grow_cleared (capture_ids
->elements (), true);
5315 walk_captures (op
, cpts
);
5316 for (unsigned i
= 0; i
< cpts
.length (); ++i
)
5318 capture
*value_match
= NULL
;
5319 for (unsigned j
= 0; j
< cpts
[i
].length (); ++j
)
5321 if (cpts
[i
][j
]->value_match
)
5324 fatal_at (cpts
[i
][j
]->location
, "duplicate @@");
5325 value_match
= cpts
[i
][j
];
5328 if (cpts
[i
].length () == 1 && value_match
)
5329 fatal_at (value_match
->location
, "@@ without a matching capture");
5332 /* Duplicate prevailing capture with the existing ID, create
5333 a fake ID and rewrite all captures to use it. This turns
5334 @@1 into @__<newid>@1 and @1 into @__<newid>. */
5335 value_match
->what
= new capture (value_match
->location
,
5337 value_match
->what
, false);
5338 /* Create a fake ID and rewrite all captures to use it. */
5339 unsigned newid
= get_internal_capture_id ();
5340 for (unsigned j
= 0; j
< cpts
[i
].length (); ++j
)
5342 cpts
[i
][j
]->where
= newid
;
5343 cpts
[i
][j
]->value_match
= true;
5350 /* Main entry of the parser. Repeatedly parse outer control structures. */
5352 parser::parser (cpp_reader
*r_
, bool gimple_
)
5357 active_fors
= vNULL
;
5358 simplifiers
= vNULL
;
5359 oper_lists_set
= NULL
;
5362 user_predicates
= vNULL
;
5363 parsing_match_operand
= false;
5366 const cpp_token
*token
= next ();
5367 while (token
->type
!= CPP_EOF
)
5369 _cpp_backup_tokens (r
, 1);
5376 /* Helper for the linemap code. */
5379 round_alloc_size (size_t s
)
5385 /* Construct and display the help menu. */
5390 const char *usage
= "Usage:\n"
5391 " %s [--gimple|--generic] [-v[v]] <input>\n"
5392 " %s [options] [--include=FILE] --header=FILE <input> <output>...\n";
5393 fprintf (stderr
, usage
, progname
, progname
);
5396 /* Write out the correct include to the match-head fle containing the helper
5400 write_header_includes (bool gimple
, FILE *header_file
)
5403 fprintf (header_file
, "#include \"gimple-match-head.cc\"\n");
5405 fprintf (header_file
, "#include \"generic-match-head.cc\"\n");
5408 /* The genmatch generator program. It reads from a pattern description
5409 and outputs GIMPLE or GENERIC IL matching and simplification routines. */
5412 main (int argc
, char **argv
)
5416 progname
= "genmatch";
5419 char *s_header_file
= NULL
;
5420 char *s_include_file
= NULL
;
5421 auto_vec
<char *> files
;
5423 int last_file
= argc
- 1;
5424 for (int i
= argc
- 1; i
>= 1; --i
)
5426 if (strcmp (argv
[i
], "--gimple") == 0)
5428 else if (strcmp (argv
[i
], "--generic") == 0)
5430 else if (strncmp (argv
[i
], "--header=", 9) == 0)
5431 s_header_file
= &argv
[i
][9];
5432 else if (strncmp (argv
[i
], "--include=", 10) == 0)
5433 s_include_file
= &argv
[i
][10];
5434 else if (strcmp (argv
[i
], "-v") == 0)
5436 else if (strcmp (argv
[i
], "-vv") == 0)
5438 else if (strncmp (argv
[i
], "--", 2) != 0 && last_file
-- == i
)
5439 files
.safe_push (argv
[i
]);
5447 /* Validate if the combinations are valid. */
5448 if ((files
.length () > 1 && !s_header_file
) || files
.is_empty ())
5454 if (!s_include_file
)
5455 s_include_file
= s_header_file
;
5457 /* Input file is the last in the reverse list. */
5458 input
= files
.pop ();
5460 line_table
= XCNEW (class line_maps
);
5461 linemap_init (line_table
, 0);
5462 line_table
->m_reallocator
= xrealloc
;
5463 line_table
->m_round_alloc_size
= round_alloc_size
;
5465 r
= cpp_create_reader (CLK_GNUC99
, NULL
, line_table
);
5466 cpp_callbacks
*cb
= cpp_get_callbacks (r
);
5467 cb
->diagnostic
= diagnostic_cb
;
5469 /* Add the build directory to the #include "" search path. */
5470 cpp_dir
*dir
= XCNEW (cpp_dir
);
5471 dir
->name
= getpwd ();
5473 dir
->name
= ASTRDUP (".");
5474 cpp_set_include_chains (r
, dir
, NULL
, false);
5476 if (!cpp_read_main_file (r
, input
))
5478 cpp_define (r
, gimple
? "GIMPLE=1": "GENERIC=1");
5479 cpp_define (r
, gimple
? "GENERIC=0": "GIMPLE=0");
5481 null_id
= new id_base (id_base::NULL_ID
, "null");
5483 /* Pre-seed operators. */
5484 operators
= new hash_table
<id_base
> (1024);
5485 #define DEFTREECODE(SYM, STRING, TYPE, NARGS) \
5486 add_operator (SYM, # SYM, # TYPE, NARGS);
5487 #define END_OF_BASE_TREE_CODES
5489 #undef END_OF_BASE_TREE_CODES
5492 /* Pre-seed builtin functions.
5493 ??? Cannot use N (name) as that is targetm.emultls.get_address
5494 for BUILT_IN_EMUTLS_GET_ADDRESS ... */
5495 #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \
5496 add_function (ENUM, "CFN_" # ENUM);
5497 #include "builtins.def"
5499 #define DEF_INTERNAL_FN(CODE, NAME, FNSPEC) \
5500 add_function (IFN_##CODE, "CFN_" #CODE);
5501 #include "internal-fn.def"
5504 parser
p (r
, gimple
);
5506 /* Create file buffers. */
5507 int n_parts
= files
.is_empty () ? 1 : files
.length ();
5508 auto_vec
<FILE *> parts (n_parts
);
5509 if (files
.is_empty ())
5511 parts
.quick_push (stdout
);
5512 write_header (stdout
, s_include_file
);
5513 write_header_includes (gimple
, stdout
);
5514 write_header_declarations (gimple
, stdout
);
5518 for (char *s_file
: files
)
5520 parts
.quick_push (fopen (s_file
, "w"));
5521 write_header (parts
.last (), s_include_file
);
5524 header_file
= fopen (s_header_file
, "w");
5525 fprintf (header_file
, "#ifndef GCC_GIMPLE_MATCH_AUTO_H\n"
5526 "#define GCC_GIMPLE_MATCH_AUTO_H\n");
5527 write_header_includes (gimple
, header_file
);
5528 write_header_declarations (gimple
, header_file
);
5531 /* Go over all predicates defined with patterns and perform
5532 lowering and code generation. */
5533 for (unsigned i
= 0; i
< p
.user_predicates
.length (); ++i
)
5535 predicate_id
*pred
= p
.user_predicates
[i
];
5536 lower (pred
->matchers
, gimple
);
5539 for (unsigned j
= 0; j
< pred
->matchers
.length (); ++j
)
5540 print_matches (pred
->matchers
[j
]);
5543 for (unsigned j
= 0; j
< pred
->matchers
.length (); ++j
)
5544 dt
.insert (pred
->matchers
[j
], j
);
5549 /* Cycle the file buffers. */
5550 FILE *f
= choose_output (parts
);
5552 write_predicate (f
, pred
, dt
, gimple
);
5555 /* Lower the main simplifiers and generate code for them. */
5556 lower (p
.simplifiers
, gimple
);
5559 for (unsigned i
= 0; i
< p
.simplifiers
.length (); ++i
)
5560 print_matches (p
.simplifiers
[i
]);
5563 for (unsigned i
= 0; i
< p
.simplifiers
.length (); ++i
)
5564 dt
.insert (p
.simplifiers
[i
], i
);
5569 dt
.gen (parts
, gimple
);
5571 define_dump_logs (gimple
, choose_output (parts
));
5573 for (FILE *f
: parts
)
5575 fprintf (f
, "#pragma GCC diagnostic pop\n");
5581 fprintf (header_file
, "\n#endif /* GCC_GIMPLE_MATCH_AUTO_H. */\n");
5582 fclose (header_file
);
5586 cpp_finish (r
, NULL
);