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 if (e1
->operation
!= e2
->operation
1900 || e1
->is_generic
!= e2
->is_generic
)
1902 if (e1
->operation
->kind
== id_base::FN
1903 /* For function calls also compare number of arguments. */
1904 && e1
->ops
.length () != e2
->ops
.length ())
1912 /* Compare two decision tree nodes N1 and N2 and return true if they
1916 decision_tree::cmp_node (dt_node
*n1
, dt_node
*n2
)
1918 if (!n1
|| !n2
|| n1
->type
!= n2
->type
)
1924 if (n1
->type
== dt_node::DT_TRUE
)
1927 if (n1
->type
== dt_node::DT_OPERAND
)
1928 return cmp_operand ((as_a
<dt_operand
*> (n1
))->op
,
1929 (as_a
<dt_operand
*> (n2
))->op
);
1930 else if (n1
->type
== dt_node::DT_MATCH
)
1931 return (((as_a
<dt_operand
*> (n1
))->match_dop
1932 == (as_a
<dt_operand
*> (n2
))->match_dop
)
1933 && ((as_a
<dt_operand
*> (n1
))->value_match
1934 == (as_a
<dt_operand
*> (n2
))->value_match
));
1938 /* Search OPS for a decision tree node like P and return it if found. */
1941 decision_tree::find_node (vec
<dt_node
*>& ops
, dt_node
*p
)
1943 /* We can merge adjacent DT_TRUE. */
1944 if (p
->type
== dt_node::DT_TRUE
1946 && ops
.last ()->type
== dt_node::DT_TRUE
)
1948 dt_operand
*true_node
= NULL
;
1949 for (int i
= ops
.length () - 1; i
>= 0; --i
)
1951 /* But we can't merge across DT_TRUE nodes as they serve as
1952 pattern order barriers to make sure that patterns apply
1953 in order of appearance in case multiple matches are possible. */
1954 if (ops
[i
]->type
== dt_node::DT_TRUE
)
1957 || as_a
<dt_operand
*> (ops
[i
])->for_id
> true_node
->for_id
)
1958 true_node
= as_a
<dt_operand
*> (ops
[i
]);
1960 if (decision_tree::cmp_node (ops
[i
], p
))
1962 /* Unless we are processing the same pattern or the blocking
1963 pattern is before the one we are going to merge with. */
1965 && true_node
->for_id
!= current_id
1966 && true_node
->for_id
> as_a
<dt_operand
*> (ops
[i
])->for_id
)
1970 location_t p_loc
= 0;
1971 if (p
->type
== dt_node::DT_OPERAND
)
1972 p_loc
= as_a
<dt_operand
*> (p
)->op
->location
;
1973 location_t op_loc
= 0;
1974 if (ops
[i
]->type
== dt_node::DT_OPERAND
)
1975 op_loc
= as_a
<dt_operand
*> (ops
[i
])->op
->location
;
1976 location_t true_loc
= 0;
1977 true_loc
= true_node
->op
->location
;
1979 "failed to merge decision tree node");
1981 "with the following");
1982 warning_at (true_loc
,
1983 "because of the following which serves as ordering "
1994 /* Append N to the decision tree if it there is not already an existing
1998 dt_node::append_node (dt_node
*n
)
2002 kid
= decision_tree::find_node (kids
, n
);
2007 n
->level
= this->level
+ 1;
2012 /* Append OP to the decision tree. */
2015 dt_node::append_op (operand
*op
, dt_node
*parent
, unsigned pos
)
2017 dt_operand
*parent_
= safe_as_a
<dt_operand
*> (parent
);
2018 dt_operand
*n
= new dt_operand (DT_OPERAND
, op
, 0, parent_
, pos
);
2019 return append_node (n
);
2022 /* Append a DT_TRUE decision tree node. */
2025 dt_node::append_true_op (operand
*op
, dt_node
*parent
, unsigned pos
)
2027 dt_operand
*parent_
= safe_as_a
<dt_operand
*> (parent
);
2028 dt_operand
*n
= new dt_operand (DT_TRUE
, op
, 0, parent_
, pos
);
2029 return append_node (n
);
2032 /* Append a DT_MATCH decision tree node. */
2035 dt_node::append_match_op (operand
*op
, dt_operand
*match_dop
,
2036 dt_node
*parent
, unsigned pos
)
2038 dt_operand
*parent_
= as_a
<dt_operand
*> (parent
);
2039 dt_operand
*n
= new dt_operand (DT_MATCH
, op
, match_dop
, parent_
, pos
);
2040 return append_node (n
);
2043 /* Append S to the decision tree. */
2046 dt_node::append_simplify (simplify
*s
, unsigned pattern_no
,
2047 dt_operand
**indexes
)
2050 dt_simplify
*n
= new dt_simplify (s
, pattern_no
, indexes
);
2051 for (unsigned i
= 0; i
< kids
.length (); ++i
)
2052 if ((s2
= dyn_cast
<dt_simplify
*> (kids
[i
]))
2054 || s
->match
->location
!= s2
->s
->match
->location
))
2056 /* With a nested patters, it's hard to avoid these in order
2057 to keep match.pd rules relatively small. */
2058 warning_at (s
->match
->location
, "duplicate pattern");
2059 warning_at (s2
->s
->match
->location
, "previous pattern defined here");
2060 print_operand (s
->match
, stderr
);
2061 fprintf (stderr
, "\n");
2063 return append_node (n
);
2066 /* Analyze the node and its children. */
2069 dt_node::analyze (sinfo_map_t
&map
)
2075 if (type
== DT_SIMPLIFY
)
2077 /* Populate the map of equivalent simplifies. */
2078 dt_simplify
*s
= as_a
<dt_simplify
*> (this);
2080 sinfo
*&si
= map
.get_or_insert (s
, &existed
);
2095 for (unsigned i
= 0; i
< kids
.length (); ++i
)
2097 kids
[i
]->analyze (map
);
2098 num_leafs
+= kids
[i
]->num_leafs
;
2099 total_size
+= kids
[i
]->total_size
;
2100 max_level
= MAX (max_level
, kids
[i
]->max_level
);
2104 /* Insert O into the decision tree and return the decision tree node found
2108 decision_tree::insert_operand (dt_node
*p
, operand
*o
, dt_operand
**indexes
,
2109 unsigned pos
, dt_node
*parent
)
2111 dt_node
*q
, *elm
= 0;
2113 if (capture
*c
= dyn_cast
<capture
*> (o
))
2115 unsigned capt_index
= c
->where
;
2117 if (indexes
[capt_index
] == 0)
2120 q
= insert_operand (p
, c
->what
, indexes
, pos
, parent
);
2123 q
= elm
= p
->append_true_op (o
, parent
, pos
);
2126 // get to the last capture
2127 for (operand
*what
= c
->what
;
2128 what
&& is_a
<capture
*> (what
);
2129 c
= as_a
<capture
*> (what
), what
= c
->what
)
2134 unsigned cc_index
= c
->where
;
2135 dt_operand
*match_op
= indexes
[cc_index
];
2137 dt_operand
temp (dt_node::DT_TRUE
, 0, 0, 0, 0);
2138 elm
= decision_tree::find_node (p
->kids
, &temp
);
2142 dt_operand
match (dt_node::DT_MATCH
, 0, match_op
, 0, 0);
2143 match
.value_match
= c
->value_match
;
2144 elm
= decision_tree::find_node (p
->kids
, &match
);
2149 dt_operand
temp (dt_node::DT_OPERAND
, c
->what
, 0, 0, 0);
2150 elm
= decision_tree::find_node (p
->kids
, &temp
);
2154 gcc_assert (elm
->type
== dt_node::DT_TRUE
2155 || elm
->type
== dt_node::DT_OPERAND
2156 || elm
->type
== dt_node::DT_MATCH
);
2157 indexes
[capt_index
] = static_cast<dt_operand
*> (elm
);
2162 p
= p
->append_match_op (o
, indexes
[capt_index
], parent
, pos
);
2163 as_a
<dt_operand
*>(p
)->value_match
= c
->value_match
;
2165 return insert_operand (p
, c
->what
, indexes
, 0, p
);
2170 p
= p
->append_op (o
, parent
, pos
);
2173 if (expr
*e
= dyn_cast
<expr
*>(o
))
2175 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
2176 q
= decision_tree::insert_operand (q
, e
->ops
[i
], indexes
, i
, p
);
2182 /* Insert S into the decision tree. */
2185 decision_tree::insert (class simplify
*s
, unsigned pattern_no
)
2188 dt_operand
**indexes
= XCNEWVEC (dt_operand
*, s
->capture_max
+ 1);
2189 dt_node
*p
= decision_tree::insert_operand (root
, s
->match
, indexes
);
2190 p
->append_simplify (s
, pattern_no
, indexes
);
2193 /* Debug functions to dump the decision tree. */
2196 decision_tree::print_node (dt_node
*p
, FILE *f
, unsigned indent
)
2198 if (p
->type
== dt_node::DT_NODE
)
2199 fprintf (f
, "root");
2203 for (unsigned i
= 0; i
< indent
; i
++)
2206 if (p
->type
== dt_node::DT_OPERAND
)
2208 dt_operand
*dop
= static_cast<dt_operand
*>(p
);
2209 print_operand (dop
->op
, f
, true);
2211 else if (p
->type
== dt_node::DT_TRUE
)
2212 fprintf (f
, "true");
2213 else if (p
->type
== dt_node::DT_MATCH
)
2214 fprintf (f
, "match (%p)", (void *)((as_a
<dt_operand
*>(p
))->match_dop
));
2215 else if (p
->type
== dt_node::DT_SIMPLIFY
)
2217 dt_simplify
*s
= static_cast<dt_simplify
*> (p
);
2218 fprintf (f
, "simplify_%u { ", s
->pattern_no
);
2219 for (int i
= 0; i
<= s
->s
->capture_max
; ++i
)
2220 fprintf (f
, "%p, ", (void *) s
->indexes
[i
]);
2223 if (is_a
<dt_operand
*> (p
))
2224 fprintf (f
, " [%u]", as_a
<dt_operand
*> (p
)->for_id
);
2227 fprintf (stderr
, " (%p, %p), %u, %u\n",
2228 (void *) p
, (void *) p
->parent
, p
->level
, p
->kids
.length ());
2230 for (unsigned i
= 0; i
< p
->kids
.length (); ++i
)
2231 decision_tree::print_node (p
->kids
[i
], f
, indent
+ 2);
2235 decision_tree::print (FILE *f
)
2237 return decision_tree::print_node (root
, f
);
2241 /* For GENERIC we have to take care of wrapping multiple-used
2242 expressions with side-effects in save_expr and preserve side-effects
2243 of expressions with omit_one_operand. Analyze captures in
2244 match, result and with expressions and perform early-outs
2245 on the outermost match expression operands for cases we cannot
2251 capture_info (simplify
*s
, operand
*, bool);
2252 void walk_match (operand
*o
, unsigned toplevel_arg
, bool, bool);
2253 bool walk_result (operand
*o
, bool, operand
*);
2254 void walk_c_expr (c_expr
*);
2260 bool force_no_side_effects_p
;
2261 bool force_single_use
;
2262 bool cond_expr_cond_p
;
2263 unsigned long toplevel_msk
;
2264 unsigned match_use_count
;
2265 unsigned result_use_count
;
2270 auto_vec
<cinfo
> info
;
2271 unsigned long force_no_side_effects
;
2275 /* Analyze captures in S. */
2277 capture_info::capture_info (simplify
*s
, operand
*result
, bool gimple_
)
2282 if (s
->kind
== simplify::MATCH
)
2284 force_no_side_effects
= -1;
2288 force_no_side_effects
= 0;
2289 info
.safe_grow_cleared (s
->capture_max
+ 1, true);
2290 for (int i
= 0; i
<= s
->capture_max
; ++i
)
2291 info
[i
].same_as
= i
;
2293 e
= as_a
<expr
*> (s
->match
);
2294 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
2295 walk_match (e
->ops
[i
], i
,
2296 (i
!= 0 && *e
->operation
== COND_EXPR
)
2297 || *e
->operation
== TRUTH_ANDIF_EXPR
2298 || *e
->operation
== TRUTH_ORIF_EXPR
,
2299 i
== 0 && *e
->operation
== COND_EXPR
);
2301 walk_result (s
->result
, false, result
);
2304 /* Analyze captures in the match expression piece O. */
2307 capture_info::walk_match (operand
*o
, unsigned toplevel_arg
,
2308 bool conditional_p
, bool cond_expr_cond_p
)
2310 if (capture
*c
= dyn_cast
<capture
*> (o
))
2312 unsigned where
= c
->where
;
2313 info
[where
].match_use_count
++;
2314 info
[where
].toplevel_msk
|= 1 << toplevel_arg
;
2315 info
[where
].force_no_side_effects_p
|= conditional_p
;
2316 info
[where
].cond_expr_cond_p
|= cond_expr_cond_p
;
2321 /* Recurse to exprs and captures. */
2322 if (is_a
<capture
*> (c
->what
)
2323 || is_a
<expr
*> (c
->what
))
2324 walk_match (c
->what
, toplevel_arg
, conditional_p
, false);
2325 /* We need to look past multiple captures to find a captured
2326 expression as with conditional converts two captures
2327 can be collapsed onto the same expression. Also collect
2328 what captures capture the same thing. */
2329 while (c
->what
&& is_a
<capture
*> (c
->what
))
2331 c
= as_a
<capture
*> (c
->what
);
2332 if (info
[c
->where
].same_as
!= c
->where
2333 && info
[c
->where
].same_as
!= info
[where
].same_as
)
2334 fatal_at (c
->location
, "cannot handle this collapsed capture");
2335 info
[c
->where
].same_as
= info
[where
].same_as
;
2337 /* Mark expr (non-leaf) captures and forced single-use exprs. */
2340 && (e
= dyn_cast
<expr
*> (c
->what
)))
2342 /* Zero-operand expression captures like ADDR_EXPR@0 are
2343 similar as predicates -- if they are not mentioned in
2344 the result we have to force them to have no side-effects. */
2345 if (e
->ops
.length () != 0)
2346 info
[where
].expr_p
= true;
2347 info
[where
].force_single_use
|= e
->force_single_use
;
2350 else if (expr
*e
= dyn_cast
<expr
*> (o
))
2352 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
2354 bool cond_p
= conditional_p
;
2355 bool expr_cond_p
= false;
2356 if (i
!= 0 && *e
->operation
== COND_EXPR
)
2358 else if (*e
->operation
== TRUTH_ANDIF_EXPR
2359 || *e
->operation
== TRUTH_ORIF_EXPR
)
2362 && *e
->operation
== COND_EXPR
)
2364 walk_match (e
->ops
[i
], toplevel_arg
, cond_p
, expr_cond_p
);
2367 else if (is_a
<predicate
*> (o
))
2369 /* Mark non-captured leafs toplevel arg for checking. */
2370 force_no_side_effects
|= 1 << toplevel_arg
;
2373 warning_at (o
->location
,
2374 "forcing no side-effects on possibly lost leaf");
2380 /* Analyze captures in the result expression piece O. Return true
2381 if RESULT was visited in one of the children. Only visit
2382 non-if/with children if they are rooted on RESULT. */
2385 capture_info::walk_result (operand
*o
, bool conditional_p
, operand
*result
)
2387 if (capture
*c
= dyn_cast
<capture
*> (o
))
2389 unsigned where
= info
[c
->where
].same_as
;
2390 info
[where
].result_use_count
++;
2391 /* If we substitute an expression capture we don't know
2392 which captures this will end up using (well, we don't
2393 compute that). Force the uses to be side-effect free
2394 which means forcing the toplevels that reach the
2395 expression side-effect free. */
2396 if (info
[where
].expr_p
)
2397 force_no_side_effects
|= info
[where
].toplevel_msk
;
2398 /* Mark CSE capture uses as forced to have no side-effects. */
2400 && is_a
<expr
*> (c
->what
))
2402 info
[where
].cse_p
= true;
2403 walk_result (c
->what
, true, result
);
2406 else if (expr
*e
= dyn_cast
<expr
*> (o
))
2408 id_base
*opr
= e
->operation
;
2409 if (user_id
*uid
= dyn_cast
<user_id
*> (opr
))
2410 opr
= uid
->substitutes
[0];
2411 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
2413 bool cond_p
= conditional_p
;
2414 if (i
!= 0 && *e
->operation
== COND_EXPR
)
2416 else if (*e
->operation
== TRUTH_ANDIF_EXPR
2417 || *e
->operation
== TRUTH_ORIF_EXPR
)
2419 walk_result (e
->ops
[i
], cond_p
, result
);
2422 else if (if_expr
*ie
= dyn_cast
<if_expr
*> (o
))
2424 /* 'if' conditions should be all fine. */
2425 if (ie
->trueexpr
== result
)
2427 walk_result (ie
->trueexpr
, false, result
);
2430 if (ie
->falseexpr
== result
)
2432 walk_result (ie
->falseexpr
, false, result
);
2436 if (is_a
<if_expr
*> (ie
->trueexpr
)
2437 || is_a
<with_expr
*> (ie
->trueexpr
))
2438 res
|= walk_result (ie
->trueexpr
, false, result
);
2440 && (is_a
<if_expr
*> (ie
->falseexpr
)
2441 || is_a
<with_expr
*> (ie
->falseexpr
)))
2442 res
|= walk_result (ie
->falseexpr
, false, result
);
2445 else if (with_expr
*we
= dyn_cast
<with_expr
*> (o
))
2447 bool res
= (we
->subexpr
== result
);
2449 || is_a
<if_expr
*> (we
->subexpr
)
2450 || is_a
<with_expr
*> (we
->subexpr
))
2451 res
|= walk_result (we
->subexpr
, false, result
);
2453 walk_c_expr (we
->with
);
2456 else if (c_expr
*ce
= dyn_cast
<c_expr
*> (o
))
2464 /* Look for captures in the C expr E. */
2467 capture_info::walk_c_expr (c_expr
*e
)
2469 /* Give up for C exprs mentioning captures not inside TREE_TYPE,
2470 TREE_REAL_CST, TREE_CODE or a predicate where they cannot
2471 really escape through. */
2472 unsigned p_depth
= 0;
2473 for (unsigned i
= 0; i
< e
->code
.length (); ++i
)
2475 const cpp_token
*t
= &e
->code
[i
];
2476 const cpp_token
*n
= i
< e
->code
.length () - 1 ? &e
->code
[i
+1] : NULL
;
2478 if (t
->type
== CPP_NAME
2479 && (strcmp ((const char *)CPP_HASHNODE
2480 (t
->val
.node
.node
)->ident
.str
, "TREE_TYPE") == 0
2481 || strcmp ((const char *)CPP_HASHNODE
2482 (t
->val
.node
.node
)->ident
.str
, "TREE_CODE") == 0
2483 || strcmp ((const char *)CPP_HASHNODE
2484 (t
->val
.node
.node
)->ident
.str
, "TREE_REAL_CST") == 0
2485 || ((id
= get_operator ((const char *)CPP_HASHNODE
2486 (t
->val
.node
.node
)->ident
.str
))
2487 && is_a
<predicate_id
*> (id
)))
2488 && n
->type
== CPP_OPEN_PAREN
)
2490 else if (t
->type
== CPP_CLOSE_PAREN
2493 else if (p_depth
== 0
2494 && t
->type
== CPP_ATSIGN
2495 && (n
->type
== CPP_NUMBER
2496 || n
->type
== CPP_NAME
)
2497 && !(n
->flags
& PREV_WHITE
))
2500 if (n
->type
== CPP_NUMBER
)
2501 id1
= (const char *)n
->val
.str
.text
;
2503 id1
= (const char *)CPP_HASHNODE (n
->val
.node
.node
)->ident
.str
;
2504 unsigned *where
= e
->capture_ids
->get(id1
);
2506 fatal_at (n
, "unknown capture id '%s'", id1
);
2507 info
[info
[*where
].same_as
].force_no_side_effects_p
= true;
2510 warning_at (t
, "capture escapes");
2516 /* The current label failing the current matched pattern during
2518 static char *fail_label
;
2520 /* Code generation off the decision tree and the refered AST nodes. */
2523 is_conversion (id_base
*op
)
2525 return (*op
== CONVERT_EXPR
2527 || *op
== FLOAT_EXPR
2528 || *op
== FIX_TRUNC_EXPR
2529 || *op
== VIEW_CONVERT_EXPR
);
2532 /* Get the type to be used for generating operand POS of OP from the
2536 get_operand_type (id_base
*op
, unsigned pos
,
2537 const char *in_type
,
2538 const char *expr_type
,
2539 const char *other_oprnd_type
)
2541 /* Generally operands whose type does not match the type of the
2542 expression generated need to know their types but match and
2543 thus can fall back to 'other_oprnd_type'. */
2544 if (is_conversion (op
))
2545 return other_oprnd_type
;
2546 else if (*op
== REALPART_EXPR
2547 || *op
== IMAGPART_EXPR
)
2548 return other_oprnd_type
;
2549 else if (is_a
<operator_id
*> (op
)
2550 && strcmp (as_a
<operator_id
*> (op
)->tcc
, "tcc_comparison") == 0)
2551 return other_oprnd_type
;
2552 else if (*op
== COND_EXPR
2554 return "boolean_type_node";
2555 else if (startswith (op
->id
, "CFN_COND_"))
2557 /* IFN_COND_* operands 1 and later by default have the same type
2558 as the result. The type of operand 0 needs to be specified
2560 if (pos
> 0 && expr_type
)
2562 else if (pos
> 0 && in_type
)
2569 /* Otherwise all types should match - choose one in order of
2576 return other_oprnd_type
;
2580 /* Generate transform code for an expression. */
2583 expr::gen_transform (FILE *f
, int indent
, const char *dest
, bool gimple
,
2584 int depth
, const char *in_type
, capture_info
*cinfo
,
2585 dt_operand
**indexes
, int)
2587 id_base
*opr
= operation
;
2588 /* When we delay operator substituting during lowering of fors we
2589 make sure that for code-gen purposes the effects of each substitute
2590 are the same. Thus just look at that. */
2591 if (user_id
*uid
= dyn_cast
<user_id
*> (opr
))
2592 opr
= uid
->substitutes
[0];
2594 bool conversion_p
= is_conversion (opr
);
2595 const char *type
= expr_type
;
2598 /* If there was a type specification in the pattern use it. */
2600 else if (conversion_p
)
2601 /* For conversions we need to build the expression using the
2602 outer type passed in. */
2604 else if (*opr
== REALPART_EXPR
2605 || *opr
== IMAGPART_EXPR
)
2607 /* __real and __imag use the component type of its operand. */
2608 snprintf (optype
, sizeof (optype
), "TREE_TYPE (TREE_TYPE (_o%d[0]))",
2612 else if (is_a
<operator_id
*> (opr
)
2613 && !strcmp (as_a
<operator_id
*> (opr
)->tcc
, "tcc_comparison"))
2615 /* comparisons use boolean_type_node (or what gets in), but
2616 their operands need to figure out the types themselves. */
2621 snprintf (optype
, sizeof (optype
), "boolean_type_node");
2626 else if (*opr
== COND_EXPR
2627 || *opr
== VEC_COND_EXPR
2628 || startswith (opr
->id
, "CFN_COND_"))
2630 /* Conditions are of the same type as their first alternative. */
2631 snprintf (optype
, sizeof (optype
), "TREE_TYPE (_o%d[1])", depth
);
2636 /* Other operations are of the same type as their first operand. */
2637 snprintf (optype
, sizeof (optype
), "TREE_TYPE (_o%d[0])", depth
);
2641 fatal_at (location
, "cannot determine type of operand");
2643 fprintf_indent (f
, indent
, "{\n");
2645 fprintf_indent (f
, indent
,
2646 "tree _o%d[%u], _r%d;\n", depth
, ops
.length (), depth
);
2648 snprintf (op0type
, sizeof (op0type
), "TREE_TYPE (_o%d[0])", depth
);
2649 for (unsigned i
= 0; i
< ops
.length (); ++i
)
2652 snprintf (dest1
, sizeof (dest1
), "_o%d[%u]", depth
, i
);
2654 = get_operand_type (opr
, i
, in_type
, expr_type
,
2655 i
== 0 ? NULL
: op0type
);
2656 ops
[i
]->gen_transform (f
, indent
, dest1
, gimple
, depth
+ 1, optype1
,
2658 *opr
== COND_EXPR
&& i
== 0 ? 1 : 2);
2661 const char *opr_name
;
2662 if (*operation
== CONVERT_EXPR
)
2663 opr_name
= "NOP_EXPR";
2665 opr_name
= operation
->id
;
2669 if (*opr
== CONVERT_EXPR
)
2671 fprintf_indent (f
, indent
,
2672 "if (%s != TREE_TYPE (_o%d[0])\n",
2674 fprintf_indent (f
, indent
,
2675 " && !useless_type_conversion_p (%s, TREE_TYPE "
2678 fprintf_indent (f
, indent
+ 2, "{\n");
2681 /* ??? Building a stmt can fail for various reasons here, seq being
2682 NULL or the stmt referencing SSA names occuring in abnormal PHIs.
2683 So if we fail here we should continue matching other patterns. */
2684 fprintf_indent (f
, indent
, "gimple_match_op tem_op "
2685 "(res_op->cond.any_else (), %s, %s", opr_name
, type
);
2686 for (unsigned i
= 0; i
< ops
.length (); ++i
)
2687 fprintf (f
, ", _o%d[%u]", depth
, i
);
2688 fprintf (f
, ");\n");
2689 fprintf_indent (f
, indent
, "tem_op.resimplify (%s, valueize);\n",
2690 !force_leaf
? "lseq" : "NULL");
2691 fprintf_indent (f
, indent
,
2692 "_r%d = maybe_push_res_to_seq (&tem_op, %s);\n", depth
,
2693 !force_leaf
? "lseq" : "NULL");
2694 fprintf_indent (f
, indent
,
2695 "if (!_r%d) goto %s;\n",
2697 if (*opr
== CONVERT_EXPR
)
2700 fprintf_indent (f
, indent
, " }\n");
2701 fprintf_indent (f
, indent
, "else\n");
2702 fprintf_indent (f
, indent
, " _r%d = _o%d[0];\n", depth
, depth
);
2707 if (*opr
== CONVERT_EXPR
)
2709 fprintf_indent (f
, indent
, "if (TREE_TYPE (_o%d[0]) != %s)\n",
2711 fprintf_indent (f
, indent
+ 2, "{\n");
2714 if (opr
->kind
== id_base::CODE
)
2715 fprintf_indent (f
, indent
, "_r%d = fold_build%d_loc (loc, %s, %s",
2716 depth
, ops
.length(), opr_name
, type
);
2718 fprintf_indent (f
, indent
, "_r%d = maybe_build_call_expr_loc (loc, "
2719 "%s, %s, %d", depth
, opr_name
, type
, ops
.length());
2720 for (unsigned i
= 0; i
< ops
.length (); ++i
)
2721 fprintf (f
, ", _o%d[%u]", depth
, i
);
2722 fprintf (f
, ");\n");
2723 if (opr
->kind
!= id_base::CODE
)
2725 fprintf_indent (f
, indent
, "if (!_r%d)\n", depth
);
2726 fprintf_indent (f
, indent
, " goto %s;\n", fail_label
);
2730 fprintf_indent (f
, indent
, "if (EXPR_P (_r%d))\n", depth
);
2731 fprintf_indent (f
, indent
, " goto %s;\n", fail_label
);
2733 if (*opr
== CONVERT_EXPR
)
2735 fprintf_indent (f
, indent
- 2, "}\n");
2737 fprintf_indent (f
, indent
, "else\n");
2738 fprintf_indent (f
, indent
, " _r%d = _o%d[0];\n", depth
, depth
);
2741 fprintf_indent (f
, indent
, "%s = _r%d;\n", dest
, depth
);
2743 fprintf_indent (f
, indent
, "}\n");
2746 /* Generate code for a c_expr which is either the expression inside
2747 an if statement or a sequence of statements which computes a
2748 result to be stored to DEST. */
2751 c_expr::gen_transform (FILE *f
, int indent
, const char *dest
,
2752 bool, int, const char *, capture_info
*,
2755 if (dest
&& nr_stmts
== 1)
2756 fprintf_indent (f
, indent
, "%s = ", dest
);
2758 unsigned stmt_nr
= 1;
2760 for (unsigned i
= 0; i
< code
.length (); ++i
)
2762 const cpp_token
*token
= &code
[i
];
2764 /* We can't recover from all lexing losses but we can roughly restore line
2765 breaks from location info. */
2766 const line_map_ordinary
*map
;
2767 linemap_resolve_location (line_table
, token
->src_loc
,
2768 LRK_SPELLING_LOCATION
, &map
);
2769 expanded_location loc
= linemap_expand_location (line_table
, map
,
2771 if (prev_line
!= -1 && loc
.line
!= prev_line
)
2773 prev_line
= loc
.line
;
2775 /* Replace captures for code-gen. */
2776 if (token
->type
== CPP_ATSIGN
)
2778 const cpp_token
*n
= &code
[i
+1];
2779 if ((n
->type
== CPP_NUMBER
2780 || n
->type
== CPP_NAME
)
2781 && !(n
->flags
& PREV_WHITE
))
2783 if (token
->flags
& PREV_WHITE
)
2786 if (n
->type
== CPP_NUMBER
)
2787 id
= (const char *)n
->val
.str
.text
;
2789 id
= (const char *)CPP_HASHNODE (n
->val
.node
.node
)->ident
.str
;
2790 unsigned *cid
= capture_ids
->get (id
);
2792 fatal_at (token
, "unknown capture id");
2793 fprintf (f
, "captures[%u]", *cid
);
2799 if (token
->flags
& PREV_WHITE
)
2802 if (token
->type
== CPP_NAME
)
2804 const char *id
= (const char *) NODE_NAME (token
->val
.node
.node
);
2806 for (j
= 0; j
< ids
.length (); ++j
)
2808 if (strcmp (id
, ids
[j
].id
) == 0)
2810 fprintf (f
, "%s", ids
[j
].oper
);
2814 if (j
< ids
.length ())
2818 /* Output the token as string. */
2819 char *tk
= (char *)cpp_token_as_text (r
, token
);
2822 if (token
->type
== CPP_SEMICOLON
)
2825 if (dest
&& stmt_nr
== nr_stmts
)
2826 fprintf_indent (f
, indent
, "%s = ", dest
);
2832 /* Generate transform code for a capture. */
2835 capture::gen_transform (FILE *f
, int indent
, const char *dest
, bool gimple
,
2836 int depth
, const char *in_type
, capture_info
*cinfo
,
2837 dt_operand
**indexes
, int cond_handling
)
2839 if (what
&& is_a
<expr
*> (what
))
2841 if (indexes
[where
] == 0)
2844 snprintf (buf
, sizeof (buf
), "captures[%u]", where
);
2845 what
->gen_transform (f
, indent
, buf
, gimple
, depth
, in_type
,
2850 /* If in GENERIC some capture is used multiple times, unshare it except
2851 when emitting the last use. */
2853 && cinfo
->info
.exists ()
2854 && cinfo
->info
[cinfo
->info
[where
].same_as
].result_use_count
> 1)
2856 fprintf_indent (f
, indent
, "%s = unshare_expr (captures[%u]);\n",
2858 cinfo
->info
[cinfo
->info
[where
].same_as
].result_use_count
--;
2861 fprintf_indent (f
, indent
, "%s = captures[%u];\n", dest
, where
);
2863 /* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal
2864 with substituting a capture of that. */
2866 && cond_handling
!= 0
2867 && cinfo
->info
[where
].cond_expr_cond_p
)
2869 /* If substituting into a cond_expr condition, unshare. */
2870 if (cond_handling
== 1)
2871 fprintf_indent (f
, indent
, "%s = unshare_expr (%s);\n", dest
, dest
);
2872 /* If substituting elsewhere we might need to decompose it. */
2873 else if (cond_handling
== 2)
2875 /* ??? Returning false here will also not allow any other patterns
2876 to match unless this generator was split out. */
2877 fprintf_indent (f
, indent
, "if (COMPARISON_CLASS_P (%s))\n", dest
);
2878 fprintf_indent (f
, indent
, " {\n");
2879 fprintf_indent (f
, indent
, " if (!seq) return false;\n");
2880 fprintf_indent (f
, indent
, " %s = gimple_build (seq,"
2882 " TREE_TYPE (%s), TREE_OPERAND (%s, 0),"
2883 " TREE_OPERAND (%s, 1));\n",
2884 dest
, dest
, dest
, dest
, dest
);
2885 fprintf_indent (f
, indent
, " }\n");
2890 /* Return the name of the operand representing the decision tree node.
2891 Use NAME as space to generate it. */
2894 dt_operand::get_name (char *name
)
2897 sprintf (name
, "t");
2898 else if (parent
->level
== 1)
2899 sprintf (name
, "_p%u", pos
);
2900 else if (parent
->type
== dt_node::DT_MATCH
)
2901 return as_a
<dt_operand
*> (parent
)->get_name (name
);
2903 sprintf (name
, "_q%u%u", parent
->level
, pos
);
2907 /* Fill NAME with the operand name at position POS. */
2910 dt_operand::gen_opname (char *name
, unsigned pos
)
2913 sprintf (name
, "_p%u", pos
);
2915 sprintf (name
, "_q%u%u", level
, pos
);
2918 /* Generate matching code for the decision tree operand which is
2922 dt_operand::gen_predicate (FILE *f
, int indent
, const char *opname
, bool gimple
)
2924 predicate
*p
= as_a
<predicate
*> (op
);
2926 if (p
->p
->matchers
.exists ())
2928 /* If this is a predicate generated from a pattern mangle its
2929 name and pass on the valueize hook. */
2931 fprintf_indent (f
, indent
, "if (gimple_%s (%s, valueize))\n",
2934 fprintf_indent (f
, indent
, "if (tree_%s (%s))\n", p
->p
->id
, opname
);
2937 fprintf_indent (f
, indent
, "if (%s (%s))\n", p
->p
->id
, opname
);
2938 fprintf_indent (f
, indent
+ 2, "{\n");
2942 /* Generate matching code for the decision tree operand which is
2946 dt_operand::gen_match_op (FILE *f
, int indent
, const char *opname
, bool)
2948 char match_opname
[20];
2949 match_dop
->get_name (match_opname
);
2951 fprintf_indent (f
, indent
, "if ((%s == %s && ! TREE_SIDE_EFFECTS (%s)) "
2952 "|| operand_equal_p (%s, %s, 0))\n",
2953 opname
, match_opname
, opname
, opname
, match_opname
);
2955 fprintf_indent (f
, indent
, "if ((%s == %s && ! TREE_SIDE_EFFECTS (%s)) "
2956 "|| (operand_equal_p (%s, %s, 0) "
2957 "&& types_match (%s, %s)))\n",
2958 opname
, match_opname
, opname
, opname
, match_opname
,
2959 opname
, match_opname
);
2960 fprintf_indent (f
, indent
+ 2, "{\n");
2964 /* Generate GIMPLE matching code for the decision tree operand. */
2967 dt_operand::gen_gimple_expr (FILE *f
, int indent
, int depth
)
2969 expr
*e
= static_cast<expr
*> (op
);
2970 id_base
*id
= e
->operation
;
2971 unsigned n_ops
= e
->ops
.length ();
2972 unsigned n_braces
= 0;
2974 if (user_id
*u
= dyn_cast
<user_id
*> (id
))
2975 id
= u
->substitutes
[0];
2977 for (unsigned i
= 0; i
< n_ops
; ++i
)
2979 char child_opname
[20];
2980 gen_opname (child_opname
, i
);
2982 if (id
->kind
== id_base::CODE
)
2985 || *id
== REALPART_EXPR
|| *id
== IMAGPART_EXPR
2986 || *id
== BIT_FIELD_REF
|| *id
== VIEW_CONVERT_EXPR
)
2988 /* ??? If this is a memory operation we can't (and should not)
2989 match this. The only sensible operand types are
2990 SSA names and invariants. */
2995 fprintf_indent (f
, indent
,
2996 "tree %s = TREE_OPERAND (%s, %i);\n",
2997 child_opname
, opname
, i
);
3000 fprintf_indent (f
, indent
,
3001 "tree %s = TREE_OPERAND "
3002 "(gimple_assign_rhs1 (_a%d), %i);\n",
3003 child_opname
, depth
, i
);
3004 fprintf_indent (f
, indent
,
3005 "if ((TREE_CODE (%s) == SSA_NAME\n",
3007 fprintf_indent (f
, indent
,
3008 " || is_gimple_min_invariant (%s)))\n",
3010 fprintf_indent (f
, indent
,
3014 fprintf_indent (f
, indent
,
3015 "%s = do_valueize (valueize, %s);\n",
3016 child_opname
, child_opname
);
3020 fprintf_indent (f
, indent
,
3021 "tree %s = gimple_assign_rhs%u (_a%d);\n",
3022 child_opname
, i
+ 1, depth
);
3025 fprintf_indent (f
, indent
,
3026 "tree %s = gimple_call_arg (_c%d, %u);\n",
3027 child_opname
, depth
, i
);
3028 fprintf_indent (f
, indent
,
3029 "%s = do_valueize (valueize, %s);\n",
3030 child_opname
, child_opname
);
3032 /* While the toplevel operands are canonicalized by the caller
3033 after valueizing operands of sub-expressions we have to
3034 re-canonicalize operand order. */
3035 int opno
= commutative_op (id
);
3038 char child_opname0
[20], child_opname1
[20];
3039 gen_opname (child_opname0
, opno
);
3040 gen_opname (child_opname1
, opno
+ 1);
3041 fprintf_indent (f
, indent
,
3042 "if (tree_swap_operands_p (%s, %s))\n",
3043 child_opname0
, child_opname1
);
3044 fprintf_indent (f
, indent
,
3045 " std::swap (%s, %s);\n",
3046 child_opname0
, child_opname1
);
3052 /* Generate GENERIC matching code for the decision tree operand. */
3055 dt_operand::gen_generic_expr (FILE *f
, int indent
, const char *opname
)
3057 expr
*e
= static_cast<expr
*> (op
);
3058 id_base
*id
= e
->operation
;
3059 unsigned n_ops
= e
->ops
.length ();
3061 if (user_id
*u
= dyn_cast
<user_id
*> (id
))
3062 id
= u
->substitutes
[0];
3064 for (unsigned i
= 0; i
< n_ops
; ++i
)
3066 char child_opname
[20];
3067 gen_opname (child_opname
, i
);
3069 if (id
->kind
== id_base::CODE
)
3070 fprintf_indent (f
, indent
, "tree %s = TREE_OPERAND (%s, %u);\n",
3071 child_opname
, opname
, i
);
3073 fprintf_indent (f
, indent
, "tree %s = CALL_EXPR_ARG (%s, %u);\n",
3074 child_opname
, opname
, i
);
3080 /* Compare 2 fns or generic_fns vector entries for vector sorting.
3081 Same operation entries with different number of arguments should
3085 fns_cmp (const void *p1
, const void *p2
)
3087 dt_operand
*op1
= *(dt_operand
*const *) p1
;
3088 dt_operand
*op2
= *(dt_operand
*const *) p2
;
3089 expr
*e1
= as_a
<expr
*> (op1
->op
);
3090 expr
*e2
= as_a
<expr
*> (op2
->op
);
3091 id_base
*b1
= e1
->operation
;
3092 id_base
*b2
= e2
->operation
;
3093 if (b1
->hashval
< b2
->hashval
)
3095 if (b1
->hashval
> b2
->hashval
)
3097 return strcmp (b1
->id
, b2
->id
);
3100 /* Generate matching code for the children of the decision tree node. */
3103 dt_node::gen_kids (FILE *f
, int indent
, bool gimple
, int depth
)
3105 auto_vec
<dt_operand
*> gimple_exprs
;
3106 auto_vec
<dt_operand
*> generic_exprs
;
3107 auto_vec
<dt_operand
*> fns
;
3108 auto_vec
<dt_operand
*> generic_fns
;
3109 auto_vec
<dt_operand
*> preds
;
3110 auto_vec
<dt_node
*> others
;
3112 for (unsigned i
= 0; i
< kids
.length (); ++i
)
3114 if (kids
[i
]->type
== dt_node::DT_OPERAND
)
3116 dt_operand
*op
= as_a
<dt_operand
*> (kids
[i
]);
3117 if (expr
*e
= dyn_cast
<expr
*> (op
->op
))
3119 if (e
->ops
.length () == 0
3120 /* In GIMPLE a CONSTRUCTOR always appears in a
3121 separate definition. */
3122 && (!gimple
|| !(*e
->operation
== CONSTRUCTOR
)))
3124 generic_exprs
.safe_push (op
);
3125 /* But ADDR_EXPRs can appear directly when invariant
3126 and in a separate definition when not. */
3127 if (gimple
&& *e
->operation
== ADDR_EXPR
)
3128 gimple_exprs
.safe_push (op
);
3130 else if (e
->operation
->kind
== id_base::FN
)
3135 generic_fns
.safe_push (op
);
3137 else if (e
->operation
->kind
== id_base::PREDICATE
)
3138 preds
.safe_push (op
);
3141 user_id
*u
= dyn_cast
<user_id
*> (e
->operation
);
3142 if (u
&& u
->substitutes
[0]->kind
== id_base::FN
)
3147 generic_fns
.safe_push (op
);
3151 if (gimple
&& !e
->is_generic
)
3152 gimple_exprs
.safe_push (op
);
3154 generic_exprs
.safe_push (op
);
3158 else if (op
->op
->type
== operand::OP_PREDICATE
)
3159 others
.safe_push (kids
[i
]);
3163 else if (kids
[i
]->type
== dt_node::DT_SIMPLIFY
)
3164 others
.safe_push (kids
[i
]);
3165 else if (kids
[i
]->type
== dt_node::DT_MATCH
3166 || kids
[i
]->type
== dt_node::DT_TRUE
)
3168 /* A DT_TRUE operand serves as a barrier - generate code now
3169 for what we have collected sofar.
3170 Like DT_TRUE, DT_MATCH serves as a barrier as it can cause
3171 dependent matches to get out-of-order. Generate code now
3172 for what we have collected sofar. */
3173 fns
.qsort (fns_cmp
);
3174 generic_fns
.qsort (fns_cmp
);
3175 gen_kids_1 (f
, indent
, gimple
, depth
, gimple_exprs
, generic_exprs
,
3176 fns
, generic_fns
, preds
, others
);
3177 /* And output the true operand itself. */
3178 kids
[i
]->gen (f
, indent
, gimple
, depth
);
3179 gimple_exprs
.truncate (0);
3180 generic_exprs
.truncate (0);
3182 generic_fns
.truncate (0);
3184 others
.truncate (0);
3190 /* Generate code for the remains. */
3191 fns
.qsort (fns_cmp
);
3192 generic_fns
.qsort (fns_cmp
);
3193 gen_kids_1 (f
, indent
, gimple
, depth
, gimple_exprs
, generic_exprs
,
3194 fns
, generic_fns
, preds
, others
);
3197 /* Generate matching code for the children of the decision tree node. */
3200 dt_node::gen_kids_1 (FILE *f
, int indent
, bool gimple
, int depth
,
3201 const vec
<dt_operand
*> &gimple_exprs
,
3202 const vec
<dt_operand
*> &generic_exprs
,
3203 const vec
<dt_operand
*> &fns
,
3204 const vec
<dt_operand
*> &generic_fns
,
3205 const vec
<dt_operand
*> &preds
,
3206 const vec
<dt_node
*> &others
)
3209 char *kid_opname
= buf
;
3211 unsigned exprs_len
= gimple_exprs
.length ();
3212 unsigned gexprs_len
= generic_exprs
.length ();
3213 unsigned fns_len
= fns
.length ();
3214 unsigned gfns_len
= generic_fns
.length ();
3216 if (exprs_len
|| fns_len
|| gexprs_len
|| gfns_len
)
3219 gimple_exprs
[0]->get_name (kid_opname
);
3221 fns
[0]->get_name (kid_opname
);
3223 generic_fns
[0]->get_name (kid_opname
);
3225 generic_exprs
[0]->get_name (kid_opname
);
3227 fprintf_indent (f
, indent
, "switch (TREE_CODE (%s))\n", kid_opname
);
3228 fprintf_indent (f
, indent
, " {\n");
3232 if (exprs_len
|| fns_len
)
3235 fprintf_indent (f
, indent
,
3236 "case SSA_NAME:\n");
3237 fprintf_indent (f
, indent
,
3238 " if (gimple *_d%d = get_def (valueize, %s))\n",
3240 fprintf_indent (f
, indent
,
3245 fprintf_indent (f
, indent
,
3246 "if (gassign *_a%d = dyn_cast <gassign *> (_d%d))\n",
3248 fprintf_indent (f
, indent
,
3249 " switch (gimple_assign_rhs_code (_a%d))\n",
3252 fprintf_indent (f
, indent
, "{\n");
3253 for (unsigned i
= 0; i
< exprs_len
; ++i
)
3255 expr
*e
= as_a
<expr
*> (gimple_exprs
[i
]->op
);
3256 if (user_id
*u
= dyn_cast
<user_id
*> (e
->operation
))
3258 for (auto id
: u
->substitutes
)
3259 fprintf_indent (f
, indent
, "case %s:\n", id
->id
);
3263 id_base
*op
= e
->operation
;
3264 if (*op
== CONVERT_EXPR
|| *op
== NOP_EXPR
)
3265 fprintf_indent (f
, indent
, "CASE_CONVERT:\n");
3267 fprintf_indent (f
, indent
, "case %s:\n", op
->id
);
3269 fprintf_indent (f
, indent
, " {\n");
3270 gimple_exprs
[i
]->gen (f
, indent
+ 4, true, depth
);
3271 fprintf_indent (f
, indent
, " break;\n");
3272 fprintf_indent (f
, indent
, " }\n");
3274 fprintf_indent (f
, indent
, "default:;\n");
3275 fprintf_indent (f
, indent
, "}\n");
3281 fprintf_indent (f
, indent
,
3282 "%sif (gcall *_c%d = dyn_cast <gcall *> (_d%d))\n",
3283 exprs_len
? "else " : "", depth
, depth
);
3284 fprintf_indent (f
, indent
,
3285 " switch (gimple_call_combined_fn (_c%d))\n",
3289 fprintf_indent (f
, indent
, "{\n");
3290 id_base
*last_op
= NULL
;
3291 for (unsigned i
= 0; i
< fns_len
; ++i
)
3293 expr
*e
= as_a
<expr
*>(fns
[i
]->op
);
3294 if (e
->operation
!= last_op
)
3297 fprintf_indent (f
, indent
, " break;\n");
3298 if (user_id
*u
= dyn_cast
<user_id
*> (e
->operation
))
3299 for (auto id
: u
->substitutes
)
3300 fprintf_indent (f
, indent
, "case %s:\n", id
->id
);
3302 fprintf_indent (f
, indent
, "case %s:\n", e
->operation
->id
);
3304 last_op
= e
->operation
;
3305 /* We need to be defensive against bogus prototypes allowing
3306 calls with not enough arguments. */
3307 fprintf_indent (f
, indent
,
3308 " if (gimple_call_num_args (_c%d) == %d)\n",
3309 depth
, e
->ops
.length ());
3310 fprintf_indent (f
, indent
, " {\n");
3311 fns
[i
]->gen (f
, indent
+ 6, true, depth
);
3312 fprintf_indent (f
, indent
, " }\n");
3315 fprintf_indent (f
, indent
, " break;\n");
3316 fprintf_indent (f
, indent
, "default:;\n");
3317 fprintf_indent (f
, indent
, "}\n");
3323 fprintf_indent (f
, indent
, " }\n");
3324 /* See if there is SSA_NAME among generic_exprs and if yes, emit it
3325 here rather than in the next loop. */
3326 for (unsigned i
= 0; i
< generic_exprs
.length (); ++i
)
3328 expr
*e
= as_a
<expr
*>(generic_exprs
[i
]->op
);
3329 id_base
*op
= e
->operation
;
3330 if (*op
== SSA_NAME
&& (exprs_len
|| fns_len
))
3332 fprintf_indent (f
, indent
+ 4, "{\n");
3333 generic_exprs
[i
]->gen (f
, indent
+ 6, gimple
, depth
);
3334 fprintf_indent (f
, indent
+ 4, "}\n");
3338 fprintf_indent (f
, indent
, " break;\n");
3341 for (unsigned i
= 0; i
< generic_exprs
.length (); ++i
)
3343 expr
*e
= as_a
<expr
*>(generic_exprs
[i
]->op
);
3344 id_base
*op
= e
->operation
;
3345 if (*op
== CONVERT_EXPR
|| *op
== NOP_EXPR
)
3346 fprintf_indent (f
, indent
, "CASE_CONVERT:\n");
3347 else if (*op
== SSA_NAME
&& (exprs_len
|| fns_len
))
3348 /* Already handled above. */
3352 if (user_id
*u
= dyn_cast
<user_id
*> (op
))
3353 for (auto id
: u
->substitutes
)
3354 fprintf_indent (f
, indent
, "case %s:\n", id
->id
);
3356 fprintf_indent (f
, indent
, "case %s:\n", op
->id
);
3358 fprintf_indent (f
, indent
, " {\n");
3359 generic_exprs
[i
]->gen (f
, indent
+ 4, gimple
, depth
);
3360 fprintf_indent (f
, indent
, " break;\n");
3361 fprintf_indent (f
, indent
, " }\n");
3366 fprintf_indent (f
, indent
,
3367 "case CALL_EXPR:\n");
3368 fprintf_indent (f
, indent
,
3369 " switch (get_call_combined_fn (%s))\n",
3371 fprintf_indent (f
, indent
,
3375 id_base
*last_op
= NULL
;
3376 for (unsigned j
= 0; j
< generic_fns
.length (); ++j
)
3378 expr
*e
= as_a
<expr
*>(generic_fns
[j
]->op
);
3379 gcc_assert (e
->operation
->kind
== id_base::FN
);
3381 if (e
->operation
!= last_op
)
3384 fprintf_indent (f
, indent
, " break;\n");
3385 fprintf_indent (f
, indent
, "case %s:\n", e
->operation
->id
);
3387 last_op
= e
->operation
;
3388 fprintf_indent (f
, indent
, " if (call_expr_nargs (%s) == %d)\n"
3389 " {\n", kid_opname
, e
->ops
.length ());
3390 generic_fns
[j
]->gen (f
, indent
+ 6, false, depth
);
3391 fprintf_indent (f
, indent
, " }\n");
3393 fprintf_indent (f
, indent
, " break;\n");
3394 fprintf_indent (f
, indent
, "default:;\n");
3397 fprintf_indent (f
, indent
, " }\n");
3398 fprintf_indent (f
, indent
, " break;\n");
3401 /* Close switch (TREE_CODE ()). */
3402 if (exprs_len
|| fns_len
|| gexprs_len
|| gfns_len
)
3405 fprintf_indent (f
, indent
, " default:;\n");
3406 fprintf_indent (f
, indent
, " }\n");
3409 for (unsigned i
= 0; i
< preds
.length (); ++i
)
3411 expr
*e
= as_a
<expr
*> (preds
[i
]->op
);
3412 predicate_id
*p
= as_a
<predicate_id
*> (e
->operation
);
3413 preds
[i
]->get_name (kid_opname
);
3414 fprintf_indent (f
, indent
, "{\n");
3416 fprintf_indent (f
, indent
, "tree %s_pops[%d];\n", kid_opname
, p
->nargs
);
3417 fprintf_indent (f
, indent
, "if (%s_%s (%s, %s_pops%s))\n",
3418 gimple
? "gimple" : "tree",
3419 p
->id
, kid_opname
, kid_opname
,
3420 gimple
? ", valueize" : "");
3421 fprintf_indent (f
, indent
, " {\n");
3422 for (int j
= 0; j
< p
->nargs
; ++j
)
3424 char child_opname
[20];
3425 preds
[i
]->gen_opname (child_opname
, j
);
3426 fprintf_indent (f
, indent
+ 4, "tree %s = %s_pops[%d];\n",
3427 child_opname
, kid_opname
, j
);
3429 preds
[i
]->gen_kids (f
, indent
+ 4, gimple
, depth
);
3432 fprintf_indent (f
, indent
, "}\n");
3435 for (unsigned i
= 0; i
< others
.length (); ++i
)
3436 others
[i
]->gen (f
, indent
, gimple
, depth
);
3439 /* Generate matching code for the decision tree operand. */
3442 dt_operand::gen (FILE *f
, int indent
, bool gimple
, int depth
)
3447 unsigned n_braces
= 0;
3449 if (type
== DT_OPERAND
)
3452 case operand::OP_PREDICATE
:
3453 n_braces
= gen_predicate (f
, indent
, opname
, gimple
);
3456 case operand::OP_EXPR
:
3458 n_braces
= gen_gimple_expr (f
, indent
, depth
);
3460 n_braces
= gen_generic_expr (f
, indent
, opname
);
3466 else if (type
== DT_TRUE
)
3468 else if (type
== DT_MATCH
)
3469 n_braces
= gen_match_op (f
, indent
, opname
, gimple
);
3473 indent
+= 4 * n_braces
;
3474 gen_kids (f
, indent
, gimple
, depth
);
3476 for (unsigned i
= 0; i
< n_braces
; ++i
)
3481 fprintf_indent (f
, indent
, " }\n");
3485 /* Emit a logging call to the debug file to the file F, with the INDENT from
3486 either the RESULT location or the S's match location if RESULT is null. */
3488 emit_logging_call (FILE *f
, int indent
, class simplify
*s
, operand
*result
,
3491 fprintf_indent (f
, indent
, "if (UNLIKELY (debug_dump)) "
3492 "%s_dump_logs (", gimple
? "gimple" : "generic");
3493 output_line_directive (f
,
3494 result
? result
->location
: s
->match
->location
,
3496 fprintf (f
, ", __FILE__, __LINE__, %s);\n",
3497 s
->kind
== simplify::SIMPLIFY
? "true" : "false");
3500 /* Generate code for the '(if ...)', '(with ..)' and actual transform
3501 step of a '(simplify ...)' or '(match ...)'. This handles everything
3502 that is not part of the decision tree (simplify->match).
3503 Main recursive worker. */
3506 dt_simplify::gen_1 (FILE *f
, int indent
, bool gimple
, operand
*result
)
3510 if (with_expr
*w
= dyn_cast
<with_expr
*> (result
))
3512 fprintf_indent (f
, indent
, "{\n");
3514 output_line_directive (f
, w
->location
);
3515 w
->with
->gen_transform (f
, indent
, NULL
, true, 1, "type", NULL
);
3516 gen_1 (f
, indent
, gimple
, w
->subexpr
);
3518 fprintf_indent (f
, indent
, "}\n");
3521 else if (if_expr
*ife
= dyn_cast
<if_expr
*> (result
))
3523 output_line_directive (f
, ife
->location
);
3524 fprintf_indent (f
, indent
, "if (");
3525 ife
->cond
->gen_transform (f
, indent
, NULL
, true, 1, "type", NULL
);
3527 fprintf_indent (f
, indent
+ 2, "{\n");
3529 gen_1 (f
, indent
, gimple
, ife
->trueexpr
);
3531 fprintf_indent (f
, indent
+ 2, "}\n");
3534 fprintf_indent (f
, indent
, "else\n");
3535 fprintf_indent (f
, indent
+ 2, "{\n");
3537 gen_1 (f
, indent
, gimple
, ife
->falseexpr
);
3539 fprintf_indent (f
, indent
+ 2, "}\n");
3545 static unsigned fail_label_cnt
;
3546 char local_fail_label
[256];
3547 snprintf (local_fail_label
, 256, "next_after_fail%u", ++fail_label_cnt
);
3548 fail_label
= local_fail_label
;
3549 bool needs_label
= false;
3551 /* Analyze captures and perform early-outs on the incoming arguments
3552 that cover cases we cannot handle. */
3553 capture_info
cinfo (s
, result
, gimple
);
3554 if (s
->kind
== simplify::SIMPLIFY
)
3558 for (unsigned i
= 0; i
< as_a
<expr
*> (s
->match
)->ops
.length (); ++i
)
3559 if (cinfo
.force_no_side_effects
& (1 << i
))
3561 fprintf_indent (f
, indent
,
3562 "if (TREE_SIDE_EFFECTS (_p%d)) goto %s;\n",
3566 warning_at (as_a
<expr
*> (s
->match
)->ops
[i
]->location
,
3567 "forcing toplevel operand to have no "
3570 for (int i
= 0; i
<= s
->capture_max
; ++i
)
3571 if (cinfo
.info
[i
].cse_p
)
3573 else if (cinfo
.info
[i
].force_no_side_effects_p
3574 && (cinfo
.info
[i
].toplevel_msk
3575 & cinfo
.force_no_side_effects
) == 0)
3577 fprintf_indent (f
, indent
,
3578 "if (TREE_SIDE_EFFECTS (captures[%d])) "
3579 "goto %s;\n", i
, fail_label
);
3582 warning_at (cinfo
.info
[i
].c
->location
,
3583 "forcing captured operand to have no "
3586 else if ((cinfo
.info
[i
].toplevel_msk
3587 & cinfo
.force_no_side_effects
) != 0)
3588 /* Mark capture as having no side-effects if we had to verify
3589 that via forced toplevel operand checks. */
3590 cinfo
.info
[i
].force_no_side_effects_p
= true;
3594 /* Force single-use restriction by only allowing simple
3595 results via setting seq to NULL. */
3596 fprintf_indent (f
, indent
, "gimple_seq *lseq = seq;\n");
3597 bool first_p
= true;
3598 for (int i
= 0; i
<= s
->capture_max
; ++i
)
3599 if (cinfo
.info
[i
].force_single_use
)
3603 fprintf_indent (f
, indent
, "if (lseq\n");
3604 fprintf_indent (f
, indent
, " && (");
3610 fprintf_indent (f
, indent
, " || ");
3612 fprintf (f
, "!single_use (captures[%d])", i
);
3616 fprintf (f
, "))\n");
3617 fprintf_indent (f
, indent
, " lseq = NULL;\n");
3622 if (s
->kind
== simplify::SIMPLIFY
)
3624 fprintf_indent (f
, indent
, "if (UNLIKELY (!dbg_cnt (match))) goto %s;\n", fail_label
);
3628 fprintf_indent (f
, indent
, "{\n");
3632 /* If there is no result then this is a predicate implementation. */
3633 emit_logging_call (f
, indent
, s
, result
, gimple
);
3634 fprintf_indent (f
, indent
, "return true;\n");
3638 /* For GIMPLE simply drop NON_LVALUE_EXPR (which only appears
3639 in outermost position). */
3640 if (result
->type
== operand::OP_EXPR
3641 && *as_a
<expr
*> (result
)->operation
== NON_LVALUE_EXPR
)
3642 result
= as_a
<expr
*> (result
)->ops
[0];
3643 if (result
->type
== operand::OP_EXPR
)
3645 expr
*e
= as_a
<expr
*> (result
);
3646 id_base
*opr
= e
->operation
;
3647 bool is_predicate
= false;
3648 /* When we delay operator substituting during lowering of fors we
3649 make sure that for code-gen purposes the effects of each substitute
3650 are the same. Thus just look at that. */
3651 if (user_id
*uid
= dyn_cast
<user_id
*> (opr
))
3652 opr
= uid
->substitutes
[0];
3653 else if (is_a
<predicate_id
*> (opr
))
3654 is_predicate
= true;
3656 fprintf_indent (f
, indent
, "res_op->set_op (%s, type, %d);\n",
3657 *e
->operation
== CONVERT_EXPR
3658 ? "NOP_EXPR" : e
->operation
->id
,
3660 for (unsigned j
= 0; j
< e
->ops
.length (); ++j
)
3664 snprintf (dest
, sizeof (dest
), "res_ops[%d]", j
);
3666 snprintf (dest
, sizeof (dest
), "res_op->ops[%d]", j
);
3668 = get_operand_type (opr
, j
,
3669 "type", e
->expr_type
,
3671 : "TREE_TYPE (res_op->ops[0])");
3672 /* We need to expand GENERIC conditions we captured from
3673 COND_EXPRs and we need to unshare them when substituting
3675 int cond_handling
= 0;
3677 cond_handling
= (*opr
== COND_EXPR
&& j
== 0) ? 1 : 2;
3678 e
->ops
[j
]->gen_transform (f
, indent
, dest
, true, 1, optype
,
3679 &cinfo
, indexes
, cond_handling
);
3682 /* Re-fold the toplevel result. It's basically an embedded
3683 gimple_build w/o actually building the stmt. */
3686 fprintf_indent (f
, indent
,
3687 "res_op->resimplify (%s, valueize);\n",
3688 !e
->force_leaf
? "lseq" : "NULL");
3691 fprintf_indent (f
, indent
,
3692 "if (!maybe_push_res_to_seq (res_op, NULL)) "
3693 "goto %s;\n", fail_label
);
3698 else if (result
->type
== operand::OP_CAPTURE
3699 || result
->type
== operand::OP_C_EXPR
)
3701 fprintf_indent (f
, indent
, "tree tem;\n");
3702 result
->gen_transform (f
, indent
, "tem", true, 1, "type",
3704 fprintf_indent (f
, indent
, "res_op->set_value (tem);\n");
3705 if (is_a
<capture
*> (result
)
3706 && cinfo
.info
[as_a
<capture
*> (result
)->where
].cond_expr_cond_p
)
3708 /* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal
3709 with substituting a capture of that. */
3710 fprintf_indent (f
, indent
,
3711 "if (COMPARISON_CLASS_P (tem))\n");
3712 fprintf_indent (f
, indent
,
3714 fprintf_indent (f
, indent
,
3715 " res_op->ops[0] = TREE_OPERAND (tem, 0);\n");
3716 fprintf_indent (f
, indent
,
3717 " res_op->ops[1] = TREE_OPERAND (tem, 1);\n");
3718 fprintf_indent (f
, indent
,
3724 emit_logging_call (f
, indent
, s
, result
, gimple
);
3725 fprintf_indent (f
, indent
, "return true;\n");
3729 bool is_predicate
= false;
3730 if (result
->type
== operand::OP_EXPR
)
3732 expr
*e
= as_a
<expr
*> (result
);
3733 id_base
*opr
= e
->operation
;
3734 /* When we delay operator substituting during lowering of fors we
3735 make sure that for code-gen purposes the effects of each substitute
3736 are the same. Thus just look at that. */
3737 if (user_id
*uid
= dyn_cast
<user_id
*> (opr
))
3738 opr
= uid
->substitutes
[0];
3739 else if (is_a
<predicate_id
*> (opr
))
3740 is_predicate
= true;
3741 /* Search for captures used multiple times in the result expression
3742 and wrap them in a SAVE_EXPR. Allow as many uses as in the
3743 original expression. */
3745 for (int i
= 0; i
< s
->capture_max
+ 1; ++i
)
3747 if (cinfo
.info
[i
].same_as
!= (unsigned)i
3748 || cinfo
.info
[i
].cse_p
)
3750 if (cinfo
.info
[i
].result_use_count
3751 > cinfo
.info
[i
].match_use_count
)
3753 fprintf_indent (f
, indent
,
3754 "if (! tree_invariant_p (captures[%d])) "
3755 "goto %s;\n", i
, fail_label
);
3759 for (unsigned j
= 0; j
< e
->ops
.length (); ++j
)
3763 snprintf (dest
, sizeof (dest
), "res_ops[%d]", j
);
3766 fprintf_indent (f
, indent
, "tree res_op%d;\n", j
);
3767 snprintf (dest
, sizeof (dest
), "res_op%d", j
);
3770 = get_operand_type (opr
, j
,
3771 "type", e
->expr_type
,
3773 ? NULL
: "TREE_TYPE (res_op0)");
3774 e
->ops
[j
]->gen_transform (f
, indent
, dest
, false, 1, optype
,
3779 emit_logging_call (f
, indent
, s
, result
, gimple
);
3780 fprintf_indent (f
, indent
, "return true;\n");
3784 fprintf_indent (f
, indent
, "tree _r;\n");
3785 /* Re-fold the toplevel result. Use non_lvalue to
3786 build NON_LVALUE_EXPRs so they get properly
3787 ignored when in GIMPLE form. */
3788 if (*opr
== NON_LVALUE_EXPR
)
3789 fprintf_indent (f
, indent
,
3790 "_r = non_lvalue_loc (loc, res_op0);\n");
3793 if (is_a
<operator_id
*> (opr
))
3794 fprintf_indent (f
, indent
,
3795 "_r = fold_build%d_loc (loc, %s, type",
3797 *e
->operation
== CONVERT_EXPR
3798 ? "NOP_EXPR" : e
->operation
->id
);
3800 fprintf_indent (f
, indent
,
3801 "_r = maybe_build_call_expr_loc (loc, "
3802 "%s, type, %d", e
->operation
->id
,
3804 for (unsigned j
= 0; j
< e
->ops
.length (); ++j
)
3805 fprintf (f
, ", res_op%d", j
);
3806 fprintf (f
, ");\n");
3807 if (!is_a
<operator_id
*> (opr
))
3809 fprintf_indent (f
, indent
, "if (!_r)\n");
3810 fprintf_indent (f
, indent
, " goto %s;\n", fail_label
);
3816 else if (result
->type
== operand::OP_CAPTURE
3817 || result
->type
== operand::OP_C_EXPR
)
3820 fprintf_indent (f
, indent
, "tree _r;\n");
3821 result
->gen_transform (f
, indent
, "_r", false, 1, "type",
3828 /* Search for captures not used in the result expression and dependent
3829 on TREE_SIDE_EFFECTS emit omit_one_operand. */
3830 for (int i
= 0; i
< s
->capture_max
+ 1; ++i
)
3832 if (cinfo
.info
[i
].same_as
!= (unsigned)i
)
3834 if (!cinfo
.info
[i
].force_no_side_effects_p
3835 && !cinfo
.info
[i
].expr_p
3836 && cinfo
.info
[i
].result_use_count
== 0)
3838 fprintf_indent (f
, indent
,
3839 "if (TREE_SIDE_EFFECTS (captures[%d]))\n",
3841 fprintf_indent (f
, indent
+ 2,
3842 "_r = build2_loc (loc, COMPOUND_EXPR, type, "
3843 "fold_ignored_result (captures[%d]), _r);\n",
3847 emit_logging_call (f
, indent
, s
, result
, gimple
);
3848 fprintf_indent (f
, indent
, "return _r;\n");
3852 fprintf_indent (f
, indent
, "}\n");
3854 fprintf (f
, "%s:;\n", fail_label
);
3858 /* Generate code for the '(if ...)', '(with ..)' and actual transform
3859 step of a '(simplify ...)' or '(match ...)'. This handles everything
3860 that is not part of the decision tree (simplify->match). */
3863 dt_simplify::gen (FILE *f
, int indent
, bool gimple
, int depth ATTRIBUTE_UNUSED
)
3865 fprintf_indent (f
, indent
, "{\n");
3867 output_line_directive (f
,
3868 s
->result
? s
->result
->location
: s
->match
->location
);
3869 if (s
->capture_max
>= 0)
3872 fprintf_indent (f
, indent
, "tree captures[%u] ATTRIBUTE_UNUSED = { %s",
3873 s
->capture_max
+ 1, indexes
[0]->get_name (opname
));
3875 for (int i
= 1; i
<= s
->capture_max
; ++i
)
3879 fprintf (f
, ", %s", indexes
[i
]->get_name (opname
));
3881 fprintf (f
, " };\n");
3884 /* If we have a split-out function for the actual transform, call it. */
3885 if (info
&& info
->fname
)
3889 fprintf_indent (f
, indent
, "if (%s (res_op, seq, "
3890 "valueize, type, captures", info
->fname
);
3891 for (unsigned i
= 0; i
< s
->for_subst_vec
.length (); ++i
)
3892 if (s
->for_subst_vec
[i
].first
->used
)
3893 fprintf (f
, ", %s", s
->for_subst_vec
[i
].second
->id
);
3894 fprintf (f
, "))\n");
3895 fprintf_indent (f
, indent
, " return true;\n");
3899 fprintf_indent (f
, indent
, "tree res = %s (loc, type",
3901 for (unsigned i
= 0; i
< as_a
<expr
*> (s
->match
)->ops
.length (); ++i
)
3902 fprintf (f
, ", _p%d", i
);
3903 fprintf (f
, ", captures");
3904 for (unsigned i
= 0; i
< s
->for_subst_vec
.length (); ++i
)
3906 if (s
->for_subst_vec
[i
].first
->used
)
3907 fprintf (f
, ", %s", s
->for_subst_vec
[i
].second
->id
);
3909 fprintf (f
, ");\n");
3910 fprintf_indent (f
, indent
, "if (res) return res;\n");
3915 for (unsigned i
= 0; i
< s
->for_subst_vec
.length (); ++i
)
3917 if (! s
->for_subst_vec
[i
].first
->used
)
3919 if (is_a
<operator_id
*> (s
->for_subst_vec
[i
].second
))
3920 fprintf_indent (f
, indent
, "const enum tree_code %s = %s;\n",
3921 s
->for_subst_vec
[i
].first
->id
,
3922 s
->for_subst_vec
[i
].second
->id
);
3923 else if (is_a
<fn_id
*> (s
->for_subst_vec
[i
].second
))
3924 fprintf_indent (f
, indent
, "const combined_fn %s = %s;\n",
3925 s
->for_subst_vec
[i
].first
->id
,
3926 s
->for_subst_vec
[i
].second
->id
);
3930 gen_1 (f
, indent
, gimple
, s
->result
);
3934 fprintf_indent (f
, indent
, "}\n");
3938 /* Hash function for finding equivalent transforms. */
3941 sinfo_hashmap_traits::hash (const key_type
&v
)
3943 /* Only bother to compare those originating from the same source pattern. */
3944 return v
->s
->result
->location
;
3947 /* Compare function for finding equivalent transforms. */
3950 compare_op (operand
*o1
, simplify
*s1
, operand
*o2
, simplify
*s2
)
3952 if (o1
->type
!= o2
->type
)
3957 case operand::OP_IF
:
3959 if_expr
*if1
= as_a
<if_expr
*> (o1
);
3960 if_expr
*if2
= as_a
<if_expr
*> (o2
);
3961 /* ??? Properly compare c-exprs. */
3962 if (if1
->cond
!= if2
->cond
)
3964 if (!compare_op (if1
->trueexpr
, s1
, if2
->trueexpr
, s2
))
3966 if (if1
->falseexpr
!= if2
->falseexpr
3968 && !compare_op (if1
->falseexpr
, s1
, if2
->falseexpr
, s2
)))
3972 case operand::OP_WITH
:
3974 with_expr
*with1
= as_a
<with_expr
*> (o1
);
3975 with_expr
*with2
= as_a
<with_expr
*> (o2
);
3976 if (with1
->with
!= with2
->with
)
3978 return compare_op (with1
->subexpr
, s1
, with2
->subexpr
, s2
);
3983 /* We've hit a result. Time to compare capture-infos - this is required
3984 in addition to the conservative pointer-equivalency of the result IL. */
3985 capture_info
cinfo1 (s1
, o1
, true);
3986 capture_info
cinfo2 (s2
, o2
, true);
3988 if (cinfo1
.force_no_side_effects
!= cinfo2
.force_no_side_effects
3989 || cinfo1
.info
.length () != cinfo2
.info
.length ())
3992 for (unsigned i
= 0; i
< cinfo1
.info
.length (); ++i
)
3994 if (cinfo1
.info
[i
].expr_p
!= cinfo2
.info
[i
].expr_p
3995 || cinfo1
.info
[i
].cse_p
!= cinfo2
.info
[i
].cse_p
3996 || (cinfo1
.info
[i
].force_no_side_effects_p
3997 != cinfo2
.info
[i
].force_no_side_effects_p
)
3998 || cinfo1
.info
[i
].force_single_use
!= cinfo2
.info
[i
].force_single_use
3999 || cinfo1
.info
[i
].cond_expr_cond_p
!= cinfo2
.info
[i
].cond_expr_cond_p
4000 /* toplevel_msk is an optimization */
4001 || cinfo1
.info
[i
].result_use_count
!= cinfo2
.info
[i
].result_use_count
4002 || cinfo1
.info
[i
].same_as
!= cinfo2
.info
[i
].same_as
4003 /* the pointer back to the capture is for diagnostics only */)
4007 /* ??? Deep-compare the actual result. */
4012 sinfo_hashmap_traits::equal_keys (const key_type
&v
,
4013 const key_type
&candidate
)
4015 return compare_op (v
->s
->result
, v
->s
, candidate
->s
->result
, candidate
->s
);
4019 /* Main entry to generate code for matching GIMPLE IL off the decision
4023 decision_tree::gen (vec
<FILE *> &files
, bool gimple
)
4029 fprintf (stderr
, "%s decision tree has %u leafs, maximum depth %u and "
4030 "a total number of %u nodes\n",
4031 gimple
? "GIMPLE" : "GENERIC",
4032 root
->num_leafs
, root
->max_level
, root
->total_size
);
4034 /* First split out the transform part of equal leafs. */
4037 for (sinfo_map_t::iterator iter
= si
.begin ();
4038 iter
!= si
.end (); ++iter
)
4040 sinfo
*s
= (*iter
).second
;
4041 /* Do not split out single uses. */
4048 fprintf (stderr
, "found %u uses of", s
->cnt
);
4049 output_line_directive (stderr
, s
->s
->s
->result
->location
);
4052 /* Cycle the file buffers. */
4053 FILE *f
= choose_output (files
);
4055 /* Generate a split out function with the leaf transform code. */
4056 s
->fname
= xasprintf ("%s_simplify_%u", gimple
? "gimple" : "generic",
4059 fp_decl (f
, "\nbool\n"
4060 "%s (gimple_match_op *res_op, gimple_seq *seq,\n"
4061 " tree (*valueize)(tree) ATTRIBUTE_UNUSED,\n"
4062 " const tree ARG_UNUSED (type), tree *ARG_UNUSED "
4067 fp_decl (f
, "\ntree\n"
4068 "%s (location_t ARG_UNUSED (loc), const tree ARG_UNUSED (type),\n",
4069 (*iter
).second
->fname
);
4070 for (unsigned i
= 0;
4071 i
< as_a
<expr
*>(s
->s
->s
->match
)->ops
.length (); ++i
)
4072 fp_decl (f
, " tree ARG_UNUSED (_p%d),", i
);
4073 fp_decl (f
, " tree *captures");
4075 for (unsigned i
= 0; i
< s
->s
->s
->for_subst_vec
.length (); ++i
)
4077 if (! s
->s
->s
->for_subst_vec
[i
].first
->used
)
4079 if (is_a
<operator_id
*> (s
->s
->s
->for_subst_vec
[i
].second
))
4080 fp_decl (f
, ",\n const enum tree_code ARG_UNUSED (%s)",
4081 s
->s
->s
->for_subst_vec
[i
].first
->id
);
4082 else if (is_a
<fn_id
*> (s
->s
->s
->for_subst_vec
[i
].second
))
4083 fp_decl (f
, ",\n const combined_fn ARG_UNUSED (%s)",
4084 s
->s
->s
->for_subst_vec
[i
].first
->id
);
4087 fp_decl_done (f
, ")");
4089 fprintf_indent (f
, 2, "const bool debug_dump = "
4090 "dump_file && (dump_flags & TDF_FOLDING);\n");
4091 s
->s
->gen_1 (f
, 2, gimple
, s
->s
->s
->result
);
4093 fprintf (f
, " return false;\n");
4095 fprintf (f
, " return NULL_TREE;\n");
4098 fprintf (stderr
, "removed %u duplicate tails\n", rcnt
);
4100 for (unsigned n
= 1; n
<= 7; ++n
)
4102 bool has_kids_p
= false;
4104 /* First generate split-out functions. */
4105 for (unsigned j
= 0; j
< root
->kids
.length (); j
++)
4107 dt_operand
*dop
= static_cast<dt_operand
*>(root
->kids
[j
]);
4108 expr
*e
= static_cast<expr
*>(dop
->op
);
4109 if (e
->ops
.length () != n
4110 /* Builtin simplifications are somewhat premature on
4111 GENERIC. The following drops patterns with outermost
4112 calls. It's easy to emit overloads for function code
4113 though if necessary. */
4115 && e
->operation
->kind
!= id_base::CODE
))
4119 /* Cycle the file buffers. */
4120 FILE *f
= choose_output (files
);
4123 fp_decl (f
, "\nbool\n"
4124 "gimple_simplify_%s (gimple_match_op *res_op,"
4125 " gimple_seq *seq,\n"
4126 " tree (*valueize)(tree) "
4127 "ATTRIBUTE_UNUSED,\n"
4128 " code_helper ARG_UNUSED (code), tree "
4129 "ARG_UNUSED (type)",
4132 fp_decl (f
, "\ntree\n"
4133 "generic_simplify_%s (location_t ARG_UNUSED (loc), enum "
4134 "tree_code ARG_UNUSED (code), const tree ARG_UNUSED (type)",
4136 for (unsigned i
= 0; i
< n
; ++i
)
4137 fp_decl (f
, ", tree _p%d", i
);
4138 fp_decl_done (f
, ")");
4140 fprintf_indent (f
, 2, "const bool debug_dump = "
4141 "dump_file && (dump_flags & TDF_FOLDING);\n");
4142 dop
->gen_kids (f
, 2, gimple
, 0);
4144 fprintf (f
, " return false;\n");
4146 fprintf (f
, " return NULL_TREE;\n");
4151 /* If this main entry has no children, avoid generating code
4152 with compiler warnings, by generating a simple stub. */
4156 /* Cycle the file buffers. */
4157 FILE *f
= choose_output (files
);
4160 fp_decl (f
, "\nbool\n"
4161 "gimple_simplify (gimple_match_op*, gimple_seq*,\n"
4162 " tree (*)(tree), code_helper,\n"
4165 fp_decl (f
, "\ntree\n"
4166 "generic_simplify (location_t, enum tree_code,\n"
4168 for (unsigned i
= 0; i
< n
; ++i
)
4169 fp_decl (f
, ", tree");
4170 fp_decl_done (f
, ")");
4173 fprintf (f
, " return false;\n");
4175 fprintf (f
, " return NULL_TREE;\n");
4181 /* Cycle the file buffers. */
4182 FILE *f
= choose_output (files
);
4184 /* Then generate the main entry with the outermost switch and
4185 tail-calls to the split-out functions. */
4187 fp_decl (f
, "\nbool\n"
4188 "gimple_simplify (gimple_match_op *res_op, gimple_seq *seq,\n"
4189 " tree (*valueize)(tree) ATTRIBUTE_UNUSED,\n"
4190 " code_helper code, const tree type");
4192 fp_decl (f
, "\ntree\n"
4193 "generic_simplify (location_t loc, enum tree_code code, "
4194 "const tree type ATTRIBUTE_UNUSED");
4195 for (unsigned i
= 0; i
< n
; ++i
)
4196 fp_decl (f
, ", tree _p%d", i
);
4197 fp_decl_done (f
, ")");
4201 fprintf (f
, " switch (code.get_rep())\n"
4204 fprintf (f
, " switch (code)\n"
4206 for (unsigned i
= 0; i
< root
->kids
.length (); i
++)
4208 dt_operand
*dop
= static_cast<dt_operand
*>(root
->kids
[i
]);
4209 expr
*e
= static_cast<expr
*>(dop
->op
);
4210 if (e
->ops
.length () != n
4211 /* Builtin simplifications are somewhat premature on
4212 GENERIC. The following drops patterns with outermost
4213 calls. It's easy to emit overloads for function code
4214 though if necessary. */
4216 && e
->operation
->kind
!= id_base::CODE
))
4219 if (*e
->operation
== CONVERT_EXPR
4220 || *e
->operation
== NOP_EXPR
)
4221 fprintf (f
, " CASE_CONVERT:\n");
4223 fprintf (f
, " case %s%s:\n",
4224 is_a
<fn_id
*> (e
->operation
) ? "-" : "",
4227 fprintf (f
, " return gimple_simplify_%s (res_op, "
4228 "seq, valueize, code, type", e
->operation
->id
);
4230 fprintf (f
, " return generic_simplify_%s (loc, code, type",
4232 for (unsigned j
= 0; j
< n
; ++j
)
4233 fprintf (f
, ", _p%d", j
);
4234 fprintf (f
, ");\n");
4236 fprintf (f
, " default:;\n"
4240 fprintf (f
, " return false;\n");
4242 fprintf (f
, " return NULL_TREE;\n");
4247 /* Output code to implement the predicate P from the decision tree DT. */
4250 write_predicate (FILE *f
, predicate_id
*p
, decision_tree
&dt
, bool gimple
)
4252 fp_decl (f
, "\nbool\n%s%s (tree t%s%s)",
4253 gimple
? "gimple_" : "tree_", p
->id
,
4254 p
->nargs
> 0 ? ", tree *res_ops" : "",
4255 gimple
? ", tree (*valueize)(tree) ATTRIBUTE_UNUSED" : "");
4256 fp_decl_done (f
, "");
4258 /* Conveniently make 'type' available. */
4259 fprintf_indent (f
, 2, "const tree type = TREE_TYPE (t);\n");
4260 fprintf_indent (f
, 2, "const bool debug_dump = "
4261 "dump_file && (dump_flags & TDF_FOLDING);\n");
4264 fprintf_indent (f
, 2, "if (TREE_SIDE_EFFECTS (t)) return false;\n");
4265 dt
.root
->gen_kids (f
, 2, gimple
, 0);
4267 fprintf_indent (f
, 2, "return false;\n"
4271 /* Write the common header for the GIMPLE/GENERIC IL matching routines. */
4274 write_header (FILE *f
, const char *head
)
4276 fprintf (f
, "/* Generated automatically by the program `genmatch' from\n");
4277 fprintf (f
, " a IL pattern matching and simplification description. */\n");
4278 fprintf (f
, "#pragma GCC diagnostic push\n");
4279 fprintf (f
, "#pragma GCC diagnostic ignored \"-Wunused-variable\"\n");
4280 fprintf (f
, "#pragma GCC diagnostic ignored \"-Wunused-function\"\n");
4282 /* Include the header instead of writing it awkwardly quoted here. */
4284 fprintf (f
, "\n#include \"%s\"\n", head
);
4294 parser (cpp_reader
*, bool gimple
);
4297 const cpp_token
*next ();
4298 const cpp_token
*peek (unsigned = 1);
4299 const cpp_token
*peek_ident (const char * = NULL
, unsigned = 1);
4300 const cpp_token
*expect (enum cpp_ttype
);
4301 const cpp_token
*eat_token (enum cpp_ttype
);
4302 const char *get_string ();
4303 const char *get_ident ();
4304 const cpp_token
*eat_ident (const char *);
4305 const char *get_number ();
4307 unsigned get_internal_capture_id ();
4309 id_base
*parse_operation (unsigned char &);
4310 operand
*parse_capture (operand
*, bool);
4311 operand
*parse_expr ();
4312 c_expr
*parse_c_expr (cpp_ttype
);
4313 operand
*parse_op ();
4315 void record_operlist (location_t
, user_id
*);
4317 void parse_pattern ();
4318 operand
*parse_result (operand
*, predicate_id
*);
4319 void push_simplify (simplify::simplify_kind
,
4320 vec
<simplify
*>&, operand
*, operand
*);
4321 void parse_simplify (simplify::simplify_kind
,
4322 vec
<simplify
*>&, predicate_id
*, operand
*);
4323 void parse_for (location_t
);
4324 void parse_if (location_t
);
4325 void parse_predicates (location_t
);
4326 void parse_operator_list (location_t
);
4328 void finish_match_operand (operand
*);
4332 vec
<c_expr
*> active_ifs
;
4333 vec
<vec
<user_id
*> > active_fors
;
4334 hash_set
<user_id
*> *oper_lists_set
;
4335 vec
<user_id
*> oper_lists
;
4337 cid_map_t
*capture_ids
;
4341 vec
<simplify
*> simplifiers
;
4342 vec
<predicate_id
*> user_predicates
;
4343 bool parsing_match_operand
;
4346 /* Lexing helpers. */
4348 /* Read the next non-whitespace token from R. */
4353 const cpp_token
*token
;
4356 token
= cpp_get_token (r
);
4358 while (token
->type
== CPP_PADDING
);
4362 /* Peek at the next non-whitespace token from R. */
4365 parser::peek (unsigned num
)
4367 const cpp_token
*token
;
4371 token
= cpp_peek_token (r
, i
++);
4373 while (token
->type
== CPP_PADDING
4375 /* If we peek at EOF this is a fatal error as it leaves the
4376 cpp_reader in unusable state. Assume we really wanted a
4377 token and thus this EOF is unexpected. */
4378 if (token
->type
== CPP_EOF
)
4379 fatal_at (token
, "unexpected end of file");
4383 /* Peek at the next identifier token (or return NULL if the next
4384 token is not an identifier or equal to ID if supplied). */
4387 parser::peek_ident (const char *id
, unsigned num
)
4389 const cpp_token
*token
= peek (num
);
4390 if (token
->type
!= CPP_NAME
)
4396 const char *t
= (const char *) CPP_HASHNODE (token
->val
.node
.node
)->ident
.str
;
4397 if (strcmp (id
, t
) == 0)
4403 /* Read the next token from R and assert it is of type TK. */
4406 parser::expect (enum cpp_ttype tk
)
4408 const cpp_token
*token
= next ();
4409 if (token
->type
!= tk
)
4410 fatal_at (token
, "expected %s, got %s",
4411 cpp_type2name (tk
, 0), cpp_type2name (token
->type
, 0));
4416 /* Consume the next token from R and assert it is of type TK. */
4419 parser::eat_token (enum cpp_ttype tk
)
4424 /* Read the next token from R and assert it is of type CPP_STRING and
4425 return its value. */
4428 parser::get_string ()
4430 const cpp_token
*token
= expect (CPP_STRING
);
4431 return (const char *)token
->val
.str
.text
;
4434 /* Read the next token from R and assert it is of type CPP_NAME and
4435 return its value. */
4438 parser::get_ident ()
4440 const cpp_token
*token
= expect (CPP_NAME
);
4441 return (const char *)CPP_HASHNODE (token
->val
.node
.node
)->ident
.str
;
4444 /* Eat an identifier token with value S from R. */
4447 parser::eat_ident (const char *s
)
4449 const cpp_token
*token
= peek ();
4450 const char *t
= get_ident ();
4451 if (strcmp (s
, t
) != 0)
4452 fatal_at (token
, "expected '%s' got '%s'\n", s
, t
);
4456 /* Read the next token from R and assert it is of type CPP_NUMBER and
4457 return its value. */
4460 parser::get_number ()
4462 const cpp_token
*token
= expect (CPP_NUMBER
);
4463 return (const char *)token
->val
.str
.text
;
4466 /* Return a capture ID that can be used internally. */
4469 parser::get_internal_capture_id ()
4471 unsigned newid
= capture_ids
->elements ();
4472 /* Big enough for a 32-bit UINT_MAX plus prefix. */
4475 snprintf (id
, sizeof (id
), "__%u", newid
);
4476 capture_ids
->get_or_insert (xstrdup (id
), &existed
);
4478 fatal ("reserved capture id '%s' already used", id
);
4482 /* Record an operator-list use for transparent for handling. */
4485 parser::record_operlist (location_t loc
, user_id
*p
)
4487 if (!oper_lists_set
->add (p
))
4489 if (!oper_lists
.is_empty ()
4490 && oper_lists
[0]->substitutes
.length () != p
->substitutes
.length ())
4491 fatal_at (loc
, "User-defined operator list does not have the "
4492 "same number of entries as others used in the pattern");
4493 oper_lists
.safe_push (p
);
4497 /* Parse the operator ID, special-casing convert?, convert1? and
4501 parser::parse_operation (unsigned char &opt_grp
)
4503 const cpp_token
*id_tok
= peek ();
4504 char *alt_id
= NULL
;
4505 const char *id
= get_ident ();
4506 const cpp_token
*token
= peek ();
4508 if (token
->type
== CPP_QUERY
4509 && !(token
->flags
& PREV_WHITE
))
4511 if (!parsing_match_operand
)
4512 fatal_at (id_tok
, "conditional convert can only be used in "
4513 "match expression");
4514 if (ISDIGIT (id
[strlen (id
) - 1]))
4516 opt_grp
= id
[strlen (id
) - 1] - '0' + 1;
4517 alt_id
= xstrdup (id
);
4518 alt_id
[strlen (id
) - 1] = '\0';
4520 fatal_at (id_tok
, "use '%s?' here", alt_id
);
4524 eat_token (CPP_QUERY
);
4526 id_base
*op
= get_operator (alt_id
? alt_id
: id
);
4528 fatal_at (id_tok
, "unknown operator %s", alt_id
? alt_id
: id
);
4531 user_id
*p
= dyn_cast
<user_id
*> (op
);
4532 if (p
&& p
->is_oper_list
)
4534 if (active_fors
.length() == 0)
4535 record_operlist (id_tok
->src_loc
, p
);
4537 fatal_at (id_tok
, "operator-list %s cannot be expanded inside 'for'", id
);
4543 capture = '@'<number> */
4546 parser::parse_capture (operand
*op
, bool require_existing
)
4548 location_t src_loc
= eat_token (CPP_ATSIGN
)->src_loc
;
4549 const cpp_token
*token
= peek ();
4550 const char *id
= NULL
;
4551 bool value_match
= false;
4552 /* For matches parse @@ as a value-match denoting the prevailing operand. */
4553 if (token
->type
== CPP_ATSIGN
4554 && ! (token
->flags
& PREV_WHITE
)
4555 && parsing_match_operand
)
4557 eat_token (CPP_ATSIGN
);
4561 if (token
->type
== CPP_NUMBER
)
4563 else if (token
->type
== CPP_NAME
)
4566 fatal_at (token
, "expected number or identifier");
4567 unsigned next_id
= capture_ids
->elements ();
4569 unsigned &num
= capture_ids
->get_or_insert (id
, &existed
);
4572 if (require_existing
)
4573 fatal_at (src_loc
, "unknown capture id");
4576 return new capture (src_loc
, num
, op
, value_match
);
4579 /* Parse an expression
4580 expr = '(' <operation>[capture][flag][type] <operand>... ')' */
4583 parser::parse_expr ()
4585 const cpp_token
*token
= peek ();
4586 unsigned char opt_grp
;
4587 expr
*e
= new expr (parse_operation (opt_grp
), token
->src_loc
);
4590 bool is_commutative
= false;
4591 bool force_capture
= false;
4592 const char *expr_type
= NULL
;
4594 if (!parsing_match_operand
4595 && token
->type
== CPP_NOT
4596 && !(token
->flags
& PREV_WHITE
))
4598 eat_token (CPP_NOT
);
4599 e
->force_leaf
= true;
4602 if (token
->type
== CPP_COLON
4603 && !(token
->flags
& PREV_WHITE
))
4605 eat_token (CPP_COLON
);
4607 if (token
->type
== CPP_NAME
4608 && !(token
->flags
& PREV_WHITE
))
4610 const char *s
= get_ident ();
4611 if (!parsing_match_operand
)
4621 = dyn_cast
<operator_id
*> (e
->operation
))
4623 if (!commutative_tree_code (o
->code
)
4624 && !comparison_code_p (o
->code
))
4625 fatal_at (token
, "operation is not commutative");
4627 else if (user_id
*p
= dyn_cast
<user_id
*> (e
->operation
))
4628 for (unsigned i
= 0;
4629 i
< p
->substitutes
.length (); ++i
)
4632 = dyn_cast
<operator_id
*> (p
->substitutes
[i
]))
4634 if (!commutative_tree_code (q
->code
)
4635 && !comparison_code_p (q
->code
))
4636 fatal_at (token
, "operation %s is not "
4637 "commutative", q
->id
);
4640 is_commutative
= true;
4642 else if (*sp
== 'C')
4643 is_commutative
= true;
4644 else if (*sp
== 's')
4646 e
->force_single_use
= true;
4647 force_capture
= true;
4650 fatal_at (token
, "flag %c not recognized", *sp
);
4657 fatal_at (token
, "expected flag or type specifying identifier");
4660 if (token
->type
== CPP_ATSIGN
4661 && !(token
->flags
& PREV_WHITE
))
4662 op
= parse_capture (e
, false);
4663 else if (force_capture
)
4665 unsigned num
= get_internal_capture_id ();
4666 op
= new capture (token
->src_loc
, num
, e
, false);
4673 if (token
->type
== CPP_CLOSE_PAREN
)
4675 if (e
->operation
->nargs
!= -1
4676 && e
->operation
->nargs
!= (int) e
->ops
.length ())
4677 fatal_at (token
, "'%s' expects %u operands, not %u",
4678 e
->operation
->id
, e
->operation
->nargs
, e
->ops
.length ());
4681 if (e
->ops
.length () == 2
4682 || commutative_op (e
->operation
) >= 0)
4683 e
->is_commutative
= true;
4685 fatal_at (token
, "only binary operators or functions with "
4686 "two arguments can be marked commutative, "
4687 "unless the operation is known to be inherently "
4690 e
->expr_type
= expr_type
;
4693 if (e
->ops
.length () != 1)
4694 fatal_at (token
, "only unary operations can be conditional");
4695 e
->opt_grp
= opt_grp
;
4699 else if (!(token
->flags
& PREV_WHITE
))
4700 fatal_at (token
, "expected expression operand");
4702 e
->append_op (parse_op ());
4707 /* Lex native C code delimited by START recording the preprocessing tokens
4708 for later processing.
4709 c_expr = ('{'|'(') <pp token>... ('}'|')') */
4712 parser::parse_c_expr (cpp_ttype start
)
4714 const cpp_token
*token
;
4717 vec
<cpp_token
> code
= vNULL
;
4718 unsigned nr_stmts
= 0;
4719 location_t loc
= eat_token (start
)->src_loc
;
4720 if (start
== CPP_OPEN_PAREN
)
4721 end
= CPP_CLOSE_PAREN
;
4722 else if (start
== CPP_OPEN_BRACE
)
4723 end
= CPP_CLOSE_BRACE
;
4731 /* Count brace pairs to find the end of the expr to match. */
4732 if (token
->type
== start
)
4734 else if (token
->type
== end
4737 else if (token
->type
== CPP_EOF
)
4738 fatal_at (token
, "unexpected end of file");
4740 /* This is a lame way of counting the number of statements. */
4741 if (token
->type
== CPP_SEMICOLON
)
4744 /* If this is possibly a user-defined identifier mark it used. */
4745 if (token
->type
== CPP_NAME
)
4748 = (const char *)CPP_HASHNODE (token
->val
.node
.node
)->ident
.str
;
4749 if (strcmp (str
, "return") == 0)
4750 fatal_at (token
, "return statement not allowed in C expression");
4751 id_base
*idb
= get_operator (str
);
4753 if (idb
&& (p
= dyn_cast
<user_id
*> (idb
)) && p
->is_oper_list
)
4754 record_operlist (token
->src_loc
, p
);
4757 /* Record the token. */
4758 code
.safe_push (*token
);
4761 return new c_expr (r
, loc
, code
, nr_stmts
, vNULL
, capture_ids
);
4764 /* Parse an operand which is either an expression, a predicate or
4765 a standalone capture.
4766 op = predicate | expr | c_expr | capture */
4771 const cpp_token
*token
= peek ();
4772 class operand
*op
= NULL
;
4773 if (token
->type
== CPP_OPEN_PAREN
)
4775 eat_token (CPP_OPEN_PAREN
);
4777 eat_token (CPP_CLOSE_PAREN
);
4779 else if (token
->type
== CPP_OPEN_BRACE
)
4781 op
= parse_c_expr (CPP_OPEN_BRACE
);
4785 /* Remaining ops are either empty or predicates */
4786 if (token
->type
== CPP_NAME
)
4788 const char *id
= get_ident ();
4789 id_base
*opr
= get_operator (id
);
4791 fatal_at (token
, "expected predicate name");
4792 if (operator_id
*code1
= dyn_cast
<operator_id
*> (opr
))
4794 if (code1
->nargs
!= 0)
4795 fatal_at (token
, "using an operator with operands as predicate");
4796 /* Parse the zero-operand operator "predicates" as
4798 op
= new expr (opr
, token
->src_loc
);
4800 else if (user_id
*code2
= dyn_cast
<user_id
*> (opr
))
4802 if (code2
->nargs
!= 0)
4803 fatal_at (token
, "using an operator with operands as predicate");
4804 /* Parse the zero-operand operator "predicates" as
4806 op
= new expr (opr
, token
->src_loc
);
4808 else if (predicate_id
*p
= dyn_cast
<predicate_id
*> (opr
))
4809 op
= new predicate (p
, token
->src_loc
);
4811 fatal_at (token
, "using an unsupported operator as predicate");
4812 if (!parsing_match_operand
)
4813 fatal_at (token
, "predicates are only allowed in match expression");
4815 if (token
->flags
& PREV_WHITE
)
4818 else if (token
->type
!= CPP_COLON
4819 && token
->type
!= CPP_ATSIGN
)
4820 fatal_at (token
, "expected expression or predicate");
4821 /* optionally followed by a capture and a predicate. */
4822 if (token
->type
== CPP_COLON
)
4823 fatal_at (token
, "not implemented: predicate on leaf operand");
4824 if (token
->type
== CPP_ATSIGN
)
4825 op
= parse_capture (op
, !parsing_match_operand
);
4831 /* Create a new simplify from the current parsing state and MATCH,
4832 MATCH_LOC, RESULT and RESULT_LOC and push it to SIMPLIFIERS. */
4835 parser::push_simplify (simplify::simplify_kind kind
,
4836 vec
<simplify
*>& simplifiers
,
4837 operand
*match
, operand
*result
)
4839 /* Build and push a temporary for operator list uses in expressions. */
4840 if (!oper_lists
.is_empty ())
4841 active_fors
.safe_push (oper_lists
);
4843 simplifiers
.safe_push
4844 (new simplify (kind
, last_id
++, match
, result
,
4845 active_fors
.copy (), capture_ids
));
4847 if (!oper_lists
.is_empty ())
4852 <result-op> = <op> | <if> | <with>
4853 <if> = '(' 'if' '(' <c-expr> ')' <result-op> ')'
4854 <with> = '(' 'with' '{' <c-expr> '}' <result-op> ')'
4858 parser::parse_result (operand
*result
, predicate_id
*matcher
)
4860 const cpp_token
*token
= peek ();
4861 if (token
->type
!= CPP_OPEN_PAREN
)
4864 eat_token (CPP_OPEN_PAREN
);
4865 if (peek_ident ("if"))
4868 if_expr
*ife
= new if_expr (token
->src_loc
);
4869 ife
->cond
= parse_c_expr (CPP_OPEN_PAREN
);
4870 if (peek ()->type
== CPP_OPEN_PAREN
)
4872 ife
->trueexpr
= parse_result (result
, matcher
);
4873 if (peek ()->type
== CPP_OPEN_PAREN
)
4874 ife
->falseexpr
= parse_result (result
, matcher
);
4875 else if (peek ()->type
!= CPP_CLOSE_PAREN
)
4876 ife
->falseexpr
= parse_op ();
4878 else if (peek ()->type
!= CPP_CLOSE_PAREN
)
4880 ife
->trueexpr
= parse_op ();
4881 if (peek ()->type
== CPP_OPEN_PAREN
)
4882 ife
->falseexpr
= parse_result (result
, matcher
);
4883 else if (peek ()->type
!= CPP_CLOSE_PAREN
)
4884 ife
->falseexpr
= parse_op ();
4886 /* If this if is immediately closed then it contains a
4887 manual matcher or is part of a predicate definition. */
4888 else /* if (peek ()->type == CPP_CLOSE_PAREN) */
4891 fatal_at (peek (), "manual transform not implemented");
4892 ife
->trueexpr
= result
;
4894 eat_token (CPP_CLOSE_PAREN
);
4897 else if (peek_ident ("with"))
4900 with_expr
*withe
= new with_expr (token
->src_loc
);
4901 /* Parse (with c-expr expr) as (if-with (true) expr). */
4902 withe
->with
= parse_c_expr (CPP_OPEN_BRACE
);
4903 withe
->with
->nr_stmts
= 0;
4904 withe
->subexpr
= parse_result (result
, matcher
);
4905 eat_token (CPP_CLOSE_PAREN
);
4908 else if (peek_ident ("switch"))
4910 token
= eat_ident ("switch");
4911 location_t ifloc
= eat_token (CPP_OPEN_PAREN
)->src_loc
;
4913 if_expr
*ife
= new if_expr (ifloc
);
4915 ife
->cond
= parse_c_expr (CPP_OPEN_PAREN
);
4916 if (peek ()->type
== CPP_OPEN_PAREN
)
4917 ife
->trueexpr
= parse_result (result
, matcher
);
4919 ife
->trueexpr
= parse_op ();
4920 eat_token (CPP_CLOSE_PAREN
);
4921 if (peek ()->type
!= CPP_OPEN_PAREN
4922 || !peek_ident ("if", 2))
4923 fatal_at (token
, "switch can be implemented with a single if");
4924 while (peek ()->type
!= CPP_CLOSE_PAREN
)
4926 if (peek ()->type
== CPP_OPEN_PAREN
)
4928 if (peek_ident ("if", 2))
4930 ifloc
= eat_token (CPP_OPEN_PAREN
)->src_loc
;
4932 ife
->falseexpr
= new if_expr (ifloc
);
4933 ife
= as_a
<if_expr
*> (ife
->falseexpr
);
4934 ife
->cond
= parse_c_expr (CPP_OPEN_PAREN
);
4935 if (peek ()->type
== CPP_OPEN_PAREN
)
4936 ife
->trueexpr
= parse_result (result
, matcher
);
4938 ife
->trueexpr
= parse_op ();
4939 if (peek ()->type
== CPP_OPEN_PAREN
)
4940 fatal_at (peek(), "if inside switch cannot have an else");
4941 eat_token (CPP_CLOSE_PAREN
);
4945 /* switch default clause */
4946 ife
->falseexpr
= parse_result (result
, matcher
);
4947 eat_token (CPP_CLOSE_PAREN
);
4953 /* switch default clause */
4954 ife
->falseexpr
= parse_op ();
4955 eat_token (CPP_CLOSE_PAREN
);
4959 eat_token (CPP_CLOSE_PAREN
);
4964 operand
*op
= result
;
4967 eat_token (CPP_CLOSE_PAREN
);
4973 simplify = 'simplify' <expr> <result-op>
4975 match = 'match' <ident> <expr> [<result-op>]
4976 and fill SIMPLIFIERS with the results. */
4979 parser::parse_simplify (simplify::simplify_kind kind
,
4980 vec
<simplify
*>& simplifiers
, predicate_id
*matcher
,
4983 /* Reset the capture map. */
4985 capture_ids
= new cid_map_t
;
4986 /* Reset oper_lists and set. */
4987 hash_set
<user_id
*> olist
;
4988 oper_lists_set
= &olist
;
4991 const cpp_token
*loc
= peek ();
4992 parsing_match_operand
= true;
4993 class operand
*match
= parse_op ();
4994 finish_match_operand (match
);
4995 parsing_match_operand
= false;
4996 if (match
->type
== operand::OP_CAPTURE
&& !matcher
)
4997 fatal_at (loc
, "outermost expression cannot be captured");
4998 if (match
->type
== operand::OP_EXPR
4999 && is_a
<predicate_id
*> (as_a
<expr
*> (match
)->operation
))
5000 fatal_at (loc
, "outermost expression cannot be a predicate");
5002 /* Splice active_ifs onto result and continue parsing the
5004 if_expr
*active_if
= NULL
;
5005 for (int i
= active_ifs
.length (); i
> 0; --i
)
5007 if_expr
*ifc
= new if_expr (active_ifs
[i
-1]->location
);
5008 ifc
->cond
= active_ifs
[i
-1];
5009 ifc
->trueexpr
= active_if
;
5012 if_expr
*outermost_if
= active_if
;
5013 while (active_if
&& active_if
->trueexpr
)
5014 active_if
= as_a
<if_expr
*> (active_if
->trueexpr
);
5016 const cpp_token
*token
= peek ();
5018 /* If this if is immediately closed then it is part of a predicate
5019 definition. Push it. */
5020 if (token
->type
== CPP_CLOSE_PAREN
)
5023 fatal_at (token
, "expected transform expression");
5026 active_if
->trueexpr
= result
;
5027 result
= outermost_if
;
5029 push_simplify (kind
, simplifiers
, match
, result
);
5033 operand
*tem
= parse_result (result
, matcher
);
5036 active_if
->trueexpr
= tem
;
5037 result
= outermost_if
;
5042 push_simplify (kind
, simplifiers
, match
, result
);
5045 /* Parsing of the outer control structures. */
5047 /* Parse a for expression
5048 for = '(' 'for' <subst>... <pattern> ')'
5049 subst = <ident> '(' <ident>... ')' */
5052 parser::parse_for (location_t
)
5054 auto_vec
<const cpp_token
*> user_id_tokens
;
5055 vec
<user_id
*> user_ids
= vNULL
;
5056 const cpp_token
*token
;
5057 unsigned min_n_opers
= 0, max_n_opers
= 0;
5062 if (token
->type
!= CPP_NAME
)
5065 /* Insert the user defined operators into the operator hash. */
5066 const char *id
= get_ident ();
5067 if (get_operator (id
, true) != NULL
)
5068 fatal_at (token
, "operator already defined");
5069 user_id
*op
= new user_id (id
);
5070 id_base
**slot
= operators
->find_slot_with_hash (op
, op
->hashval
, INSERT
);
5072 user_ids
.safe_push (op
);
5073 user_id_tokens
.safe_push (token
);
5075 eat_token (CPP_OPEN_PAREN
);
5078 while ((token
= peek_ident ()) != 0)
5080 const char *oper
= get_ident ();
5081 id_base
*idb
= get_operator (oper
, true);
5083 fatal_at (token
, "no such operator '%s'", oper
);
5087 else if (idb
->nargs
== -1)
5089 else if (idb
->nargs
!= arity
)
5090 fatal_at (token
, "operator '%s' with arity %d does not match "
5091 "others with arity %d", oper
, idb
->nargs
, arity
);
5093 user_id
*p
= dyn_cast
<user_id
*> (idb
);
5096 if (p
->is_oper_list
)
5097 op
->substitutes
.safe_splice (p
->substitutes
);
5099 fatal_at (token
, "iterator cannot be used as operator-list");
5102 op
->substitutes
.safe_push (idb
);
5105 token
= expect (CPP_CLOSE_PAREN
);
5107 unsigned nsubstitutes
= op
->substitutes
.length ();
5108 if (nsubstitutes
== 0)
5109 fatal_at (token
, "A user-defined operator must have at least "
5110 "one substitution");
5111 if (max_n_opers
== 0)
5113 min_n_opers
= nsubstitutes
;
5114 max_n_opers
= nsubstitutes
;
5118 if (nsubstitutes
% min_n_opers
!= 0
5119 && min_n_opers
% nsubstitutes
!= 0)
5120 fatal_at (token
, "All user-defined identifiers must have a "
5121 "multiple number of operator substitutions of the "
5122 "smallest number of substitutions");
5123 if (nsubstitutes
< min_n_opers
)
5124 min_n_opers
= nsubstitutes
;
5125 else if (nsubstitutes
> max_n_opers
)
5126 max_n_opers
= nsubstitutes
;
5130 unsigned n_ids
= user_ids
.length ();
5132 fatal_at (token
, "for requires at least one user-defined identifier");
5135 if (token
->type
== CPP_CLOSE_PAREN
)
5136 fatal_at (token
, "no pattern defined in for");
5138 active_fors
.safe_push (user_ids
);
5142 if (token
->type
== CPP_CLOSE_PAREN
)
5148 /* Remove user-defined operators from the hash again. */
5149 for (unsigned i
= 0; i
< user_ids
.length (); ++i
)
5151 if (!user_ids
[i
]->used
)
5152 warning_at (user_id_tokens
[i
],
5153 "operator %s defined but not used", user_ids
[i
]->id
);
5154 operators
->remove_elt (user_ids
[i
]);
5158 /* Parse an identifier associated with a list of operators.
5159 oprs = '(' 'define_operator_list' <ident> <ident>... ')' */
5162 parser::parse_operator_list (location_t
)
5164 const cpp_token
*token
= peek ();
5165 const char *id
= get_ident ();
5167 if (get_operator (id
, true) != 0)
5168 fatal_at (token
, "operator %s already defined", id
);
5170 user_id
*op
= new user_id (id
, true);
5173 while ((token
= peek_ident ()) != 0)
5176 const char *oper
= get_ident ();
5177 id_base
*idb
= get_operator (oper
, true);
5180 fatal_at (token
, "no such operator '%s'", oper
);
5184 else if (idb
->nargs
== -1)
5186 else if (arity
!= idb
->nargs
)
5187 fatal_at (token
, "operator '%s' with arity %d does not match "
5188 "others with arity %d", oper
, idb
->nargs
, arity
);
5190 /* We allow composition of multiple operator lists. */
5191 if (user_id
*p
= dyn_cast
<user_id
*> (idb
))
5192 op
->substitutes
.safe_splice (p
->substitutes
);
5194 op
->substitutes
.safe_push (idb
);
5197 // Check that there is no junk after id-list
5199 if (token
->type
!= CPP_CLOSE_PAREN
)
5200 fatal_at (token
, "expected identifier got %s", cpp_type2name (token
->type
, 0));
5202 if (op
->substitutes
.length () == 0)
5203 fatal_at (token
, "operator-list cannot be empty");
5206 id_base
**slot
= operators
->find_slot_with_hash (op
, op
->hashval
, INSERT
);
5210 /* Parse an outer if expression.
5211 if = '(' 'if' '(' <c-expr> ')' <pattern> ')' */
5214 parser::parse_if (location_t
)
5216 c_expr
*ifexpr
= parse_c_expr (CPP_OPEN_PAREN
);
5218 const cpp_token
*token
= peek ();
5219 if (token
->type
== CPP_CLOSE_PAREN
)
5220 fatal_at (token
, "no pattern defined in if");
5222 active_ifs
.safe_push (ifexpr
);
5226 if (token
->type
== CPP_CLOSE_PAREN
)
5234 /* Parse a list of predefined predicate identifiers.
5235 preds = '(' 'define_predicates' <ident>... ')' */
5238 parser::parse_predicates (location_t
)
5242 const cpp_token
*token
= peek ();
5243 if (token
->type
!= CPP_NAME
)
5246 add_predicate (get_ident ());
5251 /* Parse outer control structures.
5252 pattern = <preds>|<for>|<if>|<simplify>|<match> */
5255 parser::parse_pattern ()
5257 /* All clauses start with '('. */
5258 eat_token (CPP_OPEN_PAREN
);
5259 const cpp_token
*token
= peek ();
5260 const char *id
= get_ident ();
5261 if (strcmp (id
, "simplify") == 0)
5263 parse_simplify (simplify::SIMPLIFY
, simplifiers
, NULL
, NULL
);
5266 else if (strcmp (id
, "match") == 0)
5268 bool with_args
= false;
5269 location_t e_loc
= peek ()->src_loc
;
5270 if (peek ()->type
== CPP_OPEN_PAREN
)
5272 eat_token (CPP_OPEN_PAREN
);
5275 const char *name
= get_ident ();
5276 id_base
*id1
= get_operator (name
);
5280 p
= add_predicate (name
);
5281 user_predicates
.safe_push (p
);
5283 else if ((p
= dyn_cast
<predicate_id
*> (id1
)))
5286 fatal_at (token
, "cannot add a match to a non-predicate ID");
5287 /* Parse (match <id> <arg>... (match-expr)) here. */
5291 capture_ids
= new cid_map_t
;
5292 e
= new expr (p
, e_loc
);
5293 while (peek ()->type
== CPP_ATSIGN
)
5294 e
->append_op (parse_capture (NULL
, false));
5295 eat_token (CPP_CLOSE_PAREN
);
5298 && ((e
&& e
->ops
.length () != (unsigned)p
->nargs
)
5299 || (!e
&& p
->nargs
!= 0)))
5300 fatal_at (token
, "non-matching number of match operands");
5301 p
->nargs
= e
? e
->ops
.length () : 0;
5302 parse_simplify (simplify::MATCH
, p
->matchers
, p
, e
);
5305 else if (strcmp (id
, "for") == 0)
5306 parse_for (token
->src_loc
);
5307 else if (strcmp (id
, "if") == 0)
5308 parse_if (token
->src_loc
);
5309 else if (strcmp (id
, "define_predicates") == 0)
5311 if (active_ifs
.length () > 0
5312 || active_fors
.length () > 0)
5313 fatal_at (token
, "define_predicates inside if or for is not supported");
5314 parse_predicates (token
->src_loc
);
5316 else if (strcmp (id
, "define_operator_list") == 0)
5318 if (active_ifs
.length () > 0
5319 || active_fors
.length () > 0)
5320 fatal_at (token
, "operator-list inside if or for is not supported");
5321 parse_operator_list (token
->src_loc
);
5324 fatal_at (token
, "expected %s'simplify', 'match', 'for' or 'if'",
5325 active_ifs
.length () == 0 && active_fors
.length () == 0
5326 ? "'define_predicates', " : "");
5328 eat_token (CPP_CLOSE_PAREN
);
5331 /* Helper for finish_match_operand, collecting captures of OP in CPTS
5335 walk_captures (operand
*op
, vec
<vec
<capture
*> > &cpts
)
5340 if (capture
*c
= dyn_cast
<capture
*> (op
))
5342 cpts
[c
->where
].safe_push (c
);
5343 walk_captures (c
->what
, cpts
);
5345 else if (expr
*e
= dyn_cast
<expr
*> (op
))
5346 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
5347 walk_captures (e
->ops
[i
], cpts
);
5350 /* Finish up OP which is a match operand. */
5353 parser::finish_match_operand (operand
*op
)
5355 /* Look for matching captures, diagnose mis-uses of @@ and apply
5356 early lowering and distribution of value_match. */
5357 auto_vec
<vec
<capture
*> > cpts
;
5358 cpts
.safe_grow_cleared (capture_ids
->elements (), true);
5359 walk_captures (op
, cpts
);
5360 for (unsigned i
= 0; i
< cpts
.length (); ++i
)
5362 capture
*value_match
= NULL
;
5363 for (unsigned j
= 0; j
< cpts
[i
].length (); ++j
)
5365 if (cpts
[i
][j
]->value_match
)
5368 fatal_at (cpts
[i
][j
]->location
, "duplicate @@");
5369 value_match
= cpts
[i
][j
];
5372 if (cpts
[i
].length () == 1 && value_match
)
5373 fatal_at (value_match
->location
, "@@ without a matching capture");
5376 /* Duplicate prevailing capture with the existing ID, create
5377 a fake ID and rewrite all captures to use it. This turns
5378 @@1 into @__<newid>@1 and @1 into @__<newid>. */
5379 value_match
->what
= new capture (value_match
->location
,
5381 value_match
->what
, false);
5382 /* Create a fake ID and rewrite all captures to use it. */
5383 unsigned newid
= get_internal_capture_id ();
5384 for (unsigned j
= 0; j
< cpts
[i
].length (); ++j
)
5386 cpts
[i
][j
]->where
= newid
;
5387 cpts
[i
][j
]->value_match
= true;
5394 /* Main entry of the parser. Repeatedly parse outer control structures. */
5396 parser::parser (cpp_reader
*r_
, bool gimple_
)
5401 active_fors
= vNULL
;
5402 simplifiers
= vNULL
;
5403 oper_lists_set
= NULL
;
5406 user_predicates
= vNULL
;
5407 parsing_match_operand
= false;
5410 const cpp_token
*token
= next ();
5411 while (token
->type
!= CPP_EOF
)
5413 _cpp_backup_tokens (r
, 1);
5420 /* Helper for the linemap code. */
5423 round_alloc_size (size_t s
)
5429 /* Construct and display the help menu. */
5434 const char *usage
= "Usage:\n"
5435 " %s [--gimple|--generic] [-v[v]] <input>\n"
5436 " %s [options] [--include=FILE] --header=FILE <input> <output>...\n";
5437 fprintf (stderr
, usage
, progname
, progname
);
5440 /* Write out the correct include to the match-head fle containing the helper
5444 write_header_includes (bool gimple
, FILE *header_file
)
5447 fprintf (header_file
, "#include \"gimple-match-head.cc\"\n");
5449 fprintf (header_file
, "#include \"generic-match-head.cc\"\n");
5452 /* The genmatch generator program. It reads from a pattern description
5453 and outputs GIMPLE or GENERIC IL matching and simplification routines. */
5456 main (int argc
, char **argv
)
5460 progname
= "genmatch";
5463 char *s_header_file
= NULL
;
5464 char *s_include_file
= NULL
;
5465 auto_vec
<char *> files
;
5467 int last_file
= argc
- 1;
5468 for (int i
= argc
- 1; i
>= 1; --i
)
5470 if (strcmp (argv
[i
], "--gimple") == 0)
5472 else if (strcmp (argv
[i
], "--generic") == 0)
5474 else if (strncmp (argv
[i
], "--header=", 9) == 0)
5475 s_header_file
= &argv
[i
][9];
5476 else if (strncmp (argv
[i
], "--include=", 10) == 0)
5477 s_include_file
= &argv
[i
][10];
5478 else if (strcmp (argv
[i
], "-v") == 0)
5480 else if (strcmp (argv
[i
], "-vv") == 0)
5482 else if (strncmp (argv
[i
], "--", 2) != 0 && last_file
-- == i
)
5483 files
.safe_push (argv
[i
]);
5491 /* Validate if the combinations are valid. */
5492 if ((files
.length () > 1 && !s_header_file
) || files
.is_empty ())
5498 if (!s_include_file
)
5499 s_include_file
= s_header_file
;
5501 /* Input file is the last in the reverse list. */
5502 input
= files
.pop ();
5504 line_table
= XCNEW (class line_maps
);
5505 linemap_init (line_table
, 0);
5506 line_table
->m_reallocator
= xrealloc
;
5507 line_table
->m_round_alloc_size
= round_alloc_size
;
5509 r
= cpp_create_reader (CLK_GNUC99
, NULL
, line_table
);
5510 cpp_callbacks
*cb
= cpp_get_callbacks (r
);
5511 cb
->diagnostic
= diagnostic_cb
;
5513 /* Add the build directory to the #include "" search path. */
5514 cpp_dir
*dir
= XCNEW (cpp_dir
);
5515 dir
->name
= getpwd ();
5517 dir
->name
= ASTRDUP (".");
5518 cpp_set_include_chains (r
, dir
, NULL
, false);
5520 if (!cpp_read_main_file (r
, input
))
5522 cpp_define (r
, gimple
? "GIMPLE=1": "GENERIC=1");
5523 cpp_define (r
, gimple
? "GENERIC=0": "GIMPLE=0");
5525 null_id
= new id_base (id_base::NULL_ID
, "null");
5527 /* Pre-seed operators. */
5528 operators
= new hash_table
<id_base
> (1024);
5529 #define DEFTREECODE(SYM, STRING, TYPE, NARGS) \
5530 add_operator (SYM, # SYM, # TYPE, NARGS);
5531 #define END_OF_BASE_TREE_CODES
5533 #undef END_OF_BASE_TREE_CODES
5536 /* Pre-seed builtin functions.
5537 ??? Cannot use N (name) as that is targetm.emultls.get_address
5538 for BUILT_IN_EMUTLS_GET_ADDRESS ... */
5539 #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \
5540 add_function (ENUM, "CFN_" # ENUM);
5541 #include "builtins.def"
5543 #define DEF_INTERNAL_FN(CODE, NAME, FNSPEC) \
5544 add_function (IFN_##CODE, "CFN_" #CODE);
5545 #include "internal-fn.def"
5548 parser
p (r
, gimple
);
5550 /* Create file buffers. */
5551 int n_parts
= files
.is_empty () ? 1 : files
.length ();
5552 auto_vec
<FILE *> parts (n_parts
);
5553 if (files
.is_empty ())
5555 parts
.quick_push (stdout
);
5556 write_header (stdout
, s_include_file
);
5557 write_header_includes (gimple
, stdout
);
5558 write_header_declarations (gimple
, stdout
);
5562 for (char *s_file
: files
)
5564 parts
.quick_push (fopen (s_file
, "w"));
5565 write_header (parts
.last (), s_include_file
);
5568 header_file
= fopen (s_header_file
, "w");
5569 fprintf (header_file
, "#ifndef GCC_GIMPLE_MATCH_AUTO_H\n"
5570 "#define GCC_GIMPLE_MATCH_AUTO_H\n");
5571 write_header_includes (gimple
, header_file
);
5572 write_header_declarations (gimple
, header_file
);
5575 /* Go over all predicates defined with patterns and perform
5576 lowering and code generation. */
5577 for (unsigned i
= 0; i
< p
.user_predicates
.length (); ++i
)
5579 predicate_id
*pred
= p
.user_predicates
[i
];
5580 lower (pred
->matchers
, gimple
);
5583 for (unsigned j
= 0; j
< pred
->matchers
.length (); ++j
)
5584 print_matches (pred
->matchers
[j
]);
5587 for (unsigned j
= 0; j
< pred
->matchers
.length (); ++j
)
5588 dt
.insert (pred
->matchers
[j
], j
);
5593 /* Cycle the file buffers. */
5594 FILE *f
= choose_output (parts
);
5596 write_predicate (f
, pred
, dt
, gimple
);
5599 /* Lower the main simplifiers and generate code for them. */
5600 lower (p
.simplifiers
, gimple
);
5603 for (unsigned i
= 0; i
< p
.simplifiers
.length (); ++i
)
5604 print_matches (p
.simplifiers
[i
]);
5607 for (unsigned i
= 0; i
< p
.simplifiers
.length (); ++i
)
5608 dt
.insert (p
.simplifiers
[i
], i
);
5613 dt
.gen (parts
, gimple
);
5615 define_dump_logs (gimple
, choose_output (parts
));
5617 for (FILE *f
: parts
)
5619 fprintf (f
, "#pragma GCC diagnostic pop\n");
5625 fprintf (header_file
, "\n#endif /* GCC_GIMPLE_MATCH_AUTO_H. */\n");
5626 fclose (header_file
);
5630 cpp_finish (r
, NULL
);