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"
28 #include "rich-location.h"
30 #include "hash-table.h"
33 #include "ordered-hash-map.h"
36 /* Stubs for GGC referenced through instantiations triggered by hash-map. */
37 void *ggc_internal_cleared_alloc (size_t, void (*)(void *),
38 size_t, size_t MEM_STAT_DECL
)
42 void ggc_free (void *)
49 /* Verboseness. 0 is quiet, 1 adds some warnings, 2 is for debugging. */
55 static class line_maps
*line_table
;
57 /* The rich_location class within libcpp requires a way to expand
58 location_t instances, and relies on the client code
59 providing a symbol named
60 linemap_client_expand_location_to_spelling_point
63 This is the implementation for genmatch. */
66 linemap_client_expand_location_to_spelling_point (const line_maps
*set
,
70 const struct line_map_ordinary
*map
;
71 loc
= linemap_resolve_location (set
, loc
, LRK_SPELLING_LOCATION
, &map
);
72 return linemap_expand_location (set
, map
, loc
);
76 #if GCC_VERSION >= 4001
77 __attribute__((format (printf
, 5, 0)))
79 diagnostic_cb (cpp_reader
*, enum cpp_diagnostic_level errtype
,
80 enum cpp_warning_reason
, rich_location
*richloc
,
81 const char *msg
, va_list *ap
)
83 const line_map_ordinary
*map
;
84 location_t location
= richloc
->get_loc ();
85 linemap_resolve_location (line_table
, location
, LRK_SPELLING_LOCATION
, &map
);
86 expanded_location loc
= linemap_expand_location (line_table
, map
, location
);
87 fprintf (stderr
, "%s:%d:%d %s: ", loc
.file
, loc
.line
, loc
.column
,
88 (errtype
== CPP_DL_WARNING
) ? "warning" : "error");
89 vfprintf (stderr
, msg
, *ap
);
90 fprintf (stderr
, "\n");
91 FILE *f
= fopen (loc
.file
, "r");
97 if (!fgets (buf
, 128, f
))
99 if (buf
[strlen (buf
) - 1] != '\n')
106 fprintf (stderr
, "%s", buf
);
107 for (int i
= 0; i
< loc
.column
- 1; ++i
)
110 fputc ('\n', stderr
);
115 if (errtype
== CPP_DL_FATAL
)
121 #if GCC_VERSION >= 4001
122 __attribute__((format (printf
, 2, 3)))
124 fatal_at (const cpp_token
*tk
, const char *msg
, ...)
126 rich_location
richloc (line_table
, tk
->src_loc
);
129 diagnostic_cb (NULL
, CPP_DL_FATAL
, CPP_W_NONE
, &richloc
, msg
, &ap
);
134 #if GCC_VERSION >= 4001
135 __attribute__((format (printf
, 2, 3)))
137 fatal_at (location_t loc
, const char *msg
, ...)
139 rich_location
richloc (line_table
, loc
);
142 diagnostic_cb (NULL
, CPP_DL_FATAL
, CPP_W_NONE
, &richloc
, msg
, &ap
);
147 #if GCC_VERSION >= 4001
148 __attribute__((format (printf
, 2, 3)))
150 warning_at (const cpp_token
*tk
, const char *msg
, ...)
152 rich_location
richloc (line_table
, tk
->src_loc
);
155 diagnostic_cb (NULL
, CPP_DL_WARNING
, CPP_W_NONE
, &richloc
, msg
, &ap
);
160 #if GCC_VERSION >= 4001
161 __attribute__((format (printf
, 2, 3)))
163 warning_at (location_t loc
, const char *msg
, ...)
165 rich_location
richloc (line_table
, loc
);
168 diagnostic_cb (NULL
, CPP_DL_WARNING
, CPP_W_NONE
, &richloc
, msg
, &ap
);
172 /* Like fprintf, but print INDENT spaces at the beginning. */
175 #if GCC_VERSION >= 4001
176 __attribute__((format (printf
, 3, 4)))
178 fprintf_indent (FILE *f
, unsigned int indent
, const char *format
, ...)
181 for (; indent
>= 8; indent
-= 8)
183 fprintf (f
, "%*s", indent
, "");
184 va_start (ap
, format
);
185 vfprintf (f
, format
, ap
);
189 /* Secondary stream for fp_decl. */
190 static FILE *header_file
;
192 /* Start or continue emitting a declaration in fprintf-like manner,
193 printing both to F and global header_file, if non-null. */
195 #if GCC_VERSION >= 4001
196 __attribute__((format (printf
, 2, 3)))
198 fp_decl (FILE *f
, const char *format
, ...)
201 va_start (ap
, format
);
202 vfprintf (f
, format
, ap
);
208 va_start (ap
, format
);
209 vfprintf (header_file
, format
, ap
);
213 /* Finish a declaration being emitted by fp_decl. */
215 fp_decl_done (FILE *f
, const char *trailer
)
217 fprintf (f
, "%s\n", trailer
);
219 fprintf (header_file
, "%s;", trailer
);
222 /* Line numbers for use by indirect line directives. */
223 static vec
<int> dbg_line_numbers
;
226 write_header_declarations (bool gimple
, FILE *f
)
228 fprintf (f
, "\nextern void\n%s_dump_logs (const char *file1, int line1_id, "
229 "const char *file2, int line2, bool simplify);\n",
230 gimple
? "gimple" : "generic");
234 define_dump_logs (bool gimple
, FILE *f
)
236 if (dbg_line_numbers
.is_empty ())
239 fprintf (f
, "void\n%s_dump_logs (const char *file1, int line1_id, "
240 "const char *file2, int line2, bool simplify)\n{\n",
241 gimple
? "gimple" : "generic");
243 fprintf_indent (f
, 2, "static int dbg_line_numbers[%d] = {",
244 dbg_line_numbers
.length ());
246 for (unsigned i
= 0; i
< dbg_line_numbers
.length () - 1; i
++)
251 fprintf (f
, "%d, ", dbg_line_numbers
[i
]);
253 fprintf (f
, "%d\n };\n\n", dbg_line_numbers
.last ());
256 fprintf_indent (f
, 2, "fprintf (dump_file, \"%%s "
257 "%%s:%%d, %%s:%%d\\n\",\n");
258 fprintf_indent (f
, 10, "simplify ? \"Applying pattern\" : "
259 "\"Matching expression\", file1, "
260 "dbg_line_numbers[line1_id], file2, line2);");
262 fprintf (f
, "\n}\n\n");
266 output_line_directive (FILE *f
, location_t location
,
267 bool dumpfile
= false, bool fnargs
= false,
268 bool indirect_line_numbers
= false)
270 typedef pair_hash
<nofree_string_hash
, int_hash
<int, -1>> location_hash
;
271 static hash_map
<location_hash
, int> loc_id_map
;
272 const line_map_ordinary
*map
;
273 linemap_resolve_location (line_table
, location
, LRK_SPELLING_LOCATION
, &map
);
274 expanded_location loc
= linemap_expand_location (line_table
, map
, location
);
277 /* When writing to a dumpfile only dump the filename. */
278 const char *file
= strrchr (loc
.file
, DIR_SEPARATOR
);
279 #if defined(DIR_SEPARATOR_2)
280 const char *pos2
= strrchr (loc
.file
, DIR_SEPARATOR_2
);
281 if (pos2
&& (!file
|| (pos2
> file
)))
291 if (indirect_line_numbers
)
294 int &loc_id
= loc_id_map
.get_or_insert (
295 std::make_pair (file
, loc
.line
), &existed
);
298 loc_id
= dbg_line_numbers
.length ();
299 dbg_line_numbers
.safe_push (loc
.line
);
302 fprintf (f
, "\"%s\", %d", file
, loc_id
);
305 fprintf (f
, "\"%s\", %d", file
, loc
.line
);
308 fprintf (f
, "%s:%d", file
, loc
.line
);
310 else if (verbose
>= 2)
311 /* Other gen programs really output line directives here, at least for
312 development it's right now more convenient to have line information
313 from the generated file. Still keep the directives as comment for now
314 to easily back-point to the meta-description. */
315 fprintf (f
, "/* #line %d \"%s\" */\n", loc
.line
, loc
.file
);
318 /* Find the file to write into next. We try to evenly distribute the contents
319 over the different files. */
321 #define SIZED_BASED_CHUNKS 1
324 choose_output (const vec
<FILE *> &parts
)
326 #ifdef SIZED_BASED_CHUNKS
327 FILE *shortest
= NULL
;
329 for (FILE *part
: parts
)
331 long len
= ftell (part
);
332 if (!shortest
|| min
> len
)
333 shortest
= part
, min
= len
;
337 static int current_file
;
338 return parts
[current_file
++ % parts
.length ()];
343 /* Pull in tree codes and builtin function codes from their
346 #define DEFTREECODE(SYM, STRING, TYPE, NARGS) SYM,
353 #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) ENUM,
354 enum built_in_function
{
355 #include "builtins.def"
359 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) IFN_##CODE,
361 #include "internal-fn.def"
366 #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \
367 CFN_##ENUM = int (ENUM),
368 #include "builtins.def"
370 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
371 CFN_##CODE = int (END_BUILTINS) + int (IFN_##CODE),
372 #include "internal-fn.def"
377 #include "case-cfn-macros.h"
379 /* Return true if CODE represents a commutative tree code. Otherwise
382 commutative_tree_code (enum tree_code code
)
388 case MULT_HIGHPART_EXPR
:
403 case WIDEN_MULT_EXPR
:
404 case VEC_WIDEN_MULT_HI_EXPR
:
405 case VEC_WIDEN_MULT_LO_EXPR
:
406 case VEC_WIDEN_MULT_EVEN_EXPR
:
407 case VEC_WIDEN_MULT_ODD_EXPR
:
416 /* Return true if CODE represents a ternary tree code for which the
417 first two operands are commutative. Otherwise return false. */
419 commutative_ternary_tree_code (enum tree_code code
)
423 case WIDEN_MULT_PLUS_EXPR
:
424 case WIDEN_MULT_MINUS_EXPR
:
434 /* Return true if CODE is a comparison. */
437 comparison_code_p (enum tree_code code
)
464 /* Base class for all identifiers the parser knows. */
466 class id_base
: public nofree_ptr_hash
<id_base
>
469 enum id_kind
{ CODE
, FN
, PREDICATE
, USER
, NULL_ID
} kind
;
471 id_base (id_kind
, const char *, int = -1);
477 /* hash_table support. */
478 static inline hashval_t
hash (const id_base
*);
479 static inline int equal (const id_base
*, const id_base
*);
483 id_base::hash (const id_base
*op
)
489 id_base::equal (const id_base
*op1
,
492 return (op1
->hashval
== op2
->hashval
493 && strcmp (op1
->id
, op2
->id
) == 0);
496 /* The special id "null", which matches nothing. */
497 static id_base
*null_id
;
499 /* Hashtable of known pattern operators. This is pre-seeded from
500 all known tree codes and all known builtin function ids. */
501 static hash_table
<id_base
> *operators
;
503 id_base::id_base (id_kind kind_
, const char *id_
, int nargs_
)
508 hashval
= htab_hash_string (id
);
511 /* Identifier that maps to a tree code. */
513 class operator_id
: public id_base
516 operator_id (enum tree_code code_
, const char *id_
, unsigned nargs_
,
518 : id_base (id_base::CODE
, id_
, nargs_
), code (code_
), tcc (tcc_
) {}
523 /* Identifier that maps to a builtin or internal function code. */
525 class fn_id
: public id_base
528 fn_id (enum built_in_function fn_
, const char *id_
)
529 : id_base (id_base::FN
, id_
), fn (fn_
) {}
530 fn_id (enum internal_fn fn_
, const char *id_
)
531 : id_base (id_base::FN
, id_
), fn (int (END_BUILTINS
) + int (fn_
)) {}
537 /* Identifier that maps to a user-defined predicate. */
539 class predicate_id
: public id_base
542 predicate_id (const char *id_
)
543 : id_base (id_base::PREDICATE
, id_
), matchers (vNULL
) {}
544 vec
<simplify
*> matchers
;
547 /* Identifier that maps to a operator defined by a 'for' directive. */
549 class user_id
: public id_base
552 user_id (const char *id_
, bool is_oper_list_
= false)
553 : id_base (id_base::USER
, id_
), substitutes (vNULL
),
554 used (false), is_oper_list (is_oper_list_
) {}
555 vec
<id_base
*> substitutes
;
563 is_a_helper
<fn_id
*>::test (id_base
*id
)
565 return id
->kind
== id_base::FN
;
571 is_a_helper
<operator_id
*>::test (id_base
*id
)
573 return id
->kind
== id_base::CODE
;
579 is_a_helper
<predicate_id
*>::test (id_base
*id
)
581 return id
->kind
== id_base::PREDICATE
;
587 is_a_helper
<user_id
*>::test (id_base
*id
)
589 return id
->kind
== id_base::USER
;
592 /* If ID has a pair of consecutive, commutative operands, return the
593 index of the first, otherwise return -1. */
596 commutative_op (id_base
*id
)
598 if (operator_id
*code
= dyn_cast
<operator_id
*> (id
))
600 if (commutative_tree_code (code
->code
)
601 || commutative_ternary_tree_code (code
->code
))
605 if (fn_id
*fn
= dyn_cast
<fn_id
*> (id
))
627 case CFN_COND_LEN_ADD
:
628 case CFN_COND_LEN_MUL
:
629 case CFN_COND_LEN_MIN
:
630 case CFN_COND_LEN_MAX
:
631 case CFN_COND_LEN_FMIN
:
632 case CFN_COND_LEN_FMAX
:
633 case CFN_COND_LEN_AND
:
634 case CFN_COND_LEN_IOR
:
635 case CFN_COND_LEN_XOR
:
636 case CFN_COND_LEN_FMA
:
637 case CFN_COND_LEN_FMS
:
638 case CFN_COND_LEN_FNMA
:
639 case CFN_COND_LEN_FNMS
:
645 if (user_id
*uid
= dyn_cast
<user_id
*> (id
))
647 int res
= commutative_op (uid
->substitutes
[0]);
650 for (unsigned i
= 1; i
< uid
->substitutes
.length (); ++i
)
651 if (res
!= commutative_op (uid
->substitutes
[i
]))
658 /* Add a predicate identifier to the hash. */
660 static predicate_id
*
661 add_predicate (const char *id
)
663 predicate_id
*p
= new predicate_id (id
);
664 id_base
**slot
= operators
->find_slot_with_hash (p
, p
->hashval
, INSERT
);
666 fatal ("duplicate id definition");
671 /* Add a tree code identifier to the hash. */
674 add_operator (enum tree_code code
, const char *id
,
675 const char *tcc
, unsigned nargs
)
677 if (strcmp (tcc
, "tcc_unary") != 0
678 && strcmp (tcc
, "tcc_binary") != 0
679 && strcmp (tcc
, "tcc_comparison") != 0
680 && strcmp (tcc
, "tcc_expression") != 0
681 /* For {REAL,IMAG}PART_EXPR and VIEW_CONVERT_EXPR. */
682 && strcmp (tcc
, "tcc_reference") != 0
683 /* To have INTEGER_CST and friends as "predicate operators". */
684 && strcmp (tcc
, "tcc_constant") != 0
685 /* And allow CONSTRUCTOR for vector initializers. */
686 && !(code
== CONSTRUCTOR
)
687 /* Allow SSA_NAME as predicate operator. */
688 && !(code
== SSA_NAME
))
690 /* Treat ADDR_EXPR as atom, thus don't allow matching its operand. */
691 if (code
== ADDR_EXPR
)
693 operator_id
*op
= new operator_id (code
, id
, nargs
, tcc
);
694 id_base
**slot
= operators
->find_slot_with_hash (op
, op
->hashval
, INSERT
);
696 fatal ("duplicate id definition");
700 /* Add a built-in or internal function identifier to the hash. ID is
701 the name of its CFN_* enumeration value. */
703 template <typename T
>
705 add_function (T code
, const char *id
)
707 fn_id
*fn
= new fn_id (code
, id
);
708 id_base
**slot
= operators
->find_slot_with_hash (fn
, fn
->hashval
, INSERT
);
710 fatal ("duplicate id definition");
714 /* Helper for easy comparing ID with tree code CODE. */
717 operator==(id_base
&id
, enum tree_code code
)
719 if (operator_id
*oid
= dyn_cast
<operator_id
*> (&id
))
720 return oid
->code
== code
;
724 /* Lookup the identifier ID. Allow "null" if ALLOW_NULL. */
727 get_operator (const char *id
, bool allow_null
= false)
729 if (allow_null
&& strcmp (id
, "null") == 0)
732 id_base
tem (id_base::CODE
, id
);
734 id_base
*op
= operators
->find_with_hash (&tem
, tem
.hashval
);
737 /* If this is a user-defined identifier track whether it was used. */
738 if (user_id
*uid
= dyn_cast
<user_id
*> (op
))
744 bool all_upper
= true;
745 bool all_lower
= true;
746 for (unsigned int i
= 0; id
[i
]; ++i
)
749 else if (ISLOWER (id
[i
]))
753 /* Try in caps with _EXPR appended. */
754 id2
= ACONCAT ((id
, "_EXPR", NULL
));
755 for (unsigned int i
= 0; id2
[i
]; ++i
)
756 id2
[i
] = TOUPPER (id2
[i
]);
758 else if (all_upper
&& startswith (id
, "IFN_"))
759 /* Try CFN_ instead of IFN_. */
760 id2
= ACONCAT (("CFN_", id
+ 4, NULL
));
761 else if (all_upper
&& startswith (id
, "BUILT_IN_"))
762 /* Try prepending CFN_. */
763 id2
= ACONCAT (("CFN_", id
, NULL
));
767 new (&tem
) id_base (id_base::CODE
, id2
);
768 return operators
->find_with_hash (&tem
, tem
.hashval
);
771 /* Return the comparison operators that results if the operands are
772 swapped. This is safe for floating-point. */
775 swap_tree_comparison (operator_id
*p
)
787 return get_operator ("LT_EXPR");
789 return get_operator ("LE_EXPR");
791 return get_operator ("GT_EXPR");
793 return get_operator ("GE_EXPR");
795 return get_operator ("UNLT_EXPR");
797 return get_operator ("UNLE_EXPR");
799 return get_operator ("UNGT_EXPR");
801 return get_operator ("UNGE_EXPR");
807 typedef hash_map
<nofree_string_hash
, unsigned> cid_map_t
;
810 /* The AST produced by parsing of the pattern definitions. */
815 /* The base class for operands. */
819 enum op_type
{ OP_PREDICATE
, OP_EXPR
, OP_CAPTURE
, OP_C_EXPR
, OP_IF
, OP_WITH
};
820 operand (enum op_type type_
, location_t loc_
)
821 : type (type_
), location (loc_
) {}
824 virtual void gen_transform (FILE *, int, const char *, bool, int,
825 const char *, capture_info
*,
828 { gcc_unreachable (); }
831 /* A predicate operand. Predicates are leafs in the AST. */
833 class predicate
: public operand
836 predicate (predicate_id
*p_
, location_t loc
)
837 : operand (OP_PREDICATE
, loc
), p (p_
) {}
841 /* An operand that constitutes an expression. Expressions include
842 function calls and user-defined predicate invocations. */
844 class expr
: public operand
847 expr (id_base
*operation_
, location_t loc
, bool is_commutative_
= false)
848 : operand (OP_EXPR
, loc
), operation (operation_
),
849 ops (vNULL
), expr_type (NULL
), is_commutative (is_commutative_
),
850 is_generic (false), force_single_use (false), force_leaf (false),
853 : operand (OP_EXPR
, e
->location
), operation (e
->operation
),
854 ops (vNULL
), expr_type (e
->expr_type
), is_commutative (e
->is_commutative
),
855 is_generic (e
->is_generic
), force_single_use (e
->force_single_use
),
856 force_leaf (e
->force_leaf
), opt_grp (e
->opt_grp
) {}
857 void append_op (operand
*op
) { ops
.safe_push (op
); }
858 /* The operator and its operands. */
861 /* An explicitely specified type - used exclusively for conversions. */
862 const char *expr_type
;
863 /* Whether the operation is to be applied commutatively. This is
864 later lowered to two separate patterns. */
866 /* Whether the expression is expected to be in GENERIC form. */
868 /* Whether pushing any stmt to the sequence should be conditional
869 on this expression having a single-use. */
870 bool force_single_use
;
871 /* Whether in the result expression this should be a leaf node
872 with any children simplified down to simple operands. */
874 /* If non-zero, the group for optional handling. */
875 unsigned char opt_grp
;
876 void gen_transform (FILE *f
, int, const char *, bool, int,
877 const char *, capture_info
*,
878 dt_operand
** = 0, int = 0) override
;
881 /* An operator that is represented by native C code. This is always
882 a leaf operand in the AST. This class is also used to represent
883 the code to be generated for 'if' and 'with' expressions. */
885 class c_expr
: public operand
888 /* A mapping of an identifier and its replacement. Used to apply
894 id_tab (const char *id_
, const char *oper_
): id (id_
), oper (oper_
) {}
897 c_expr (cpp_reader
*r_
, location_t loc
,
898 vec
<cpp_token
> code_
, unsigned nr_stmts_
,
899 vec
<id_tab
> ids_
, cid_map_t
*capture_ids_
)
900 : operand (OP_C_EXPR
, loc
), r (r_
), code (code_
),
901 capture_ids (capture_ids_
), nr_stmts (nr_stmts_
), ids (ids_
) {}
902 /* cpplib tokens and state to transform this back to source. */
905 cid_map_t
*capture_ids
;
906 /* The number of statements parsed (well, the number of ';'s). */
908 /* The identifier replacement vector. */
910 void gen_transform (FILE *f
, int, const char *, bool, int,
911 const char *, capture_info
*,
912 dt_operand
** = 0, int = 0) final override
;
915 /* A wrapper around another operand that captures its value. */
917 class capture
: public operand
920 capture (location_t loc
, unsigned where_
, operand
*what_
, bool value_
)
921 : operand (OP_CAPTURE
, loc
), where (where_
), value_match (value_
),
923 /* Identifier index for the value. */
925 /* Whether in a match of two operands the compare should be for
926 equal values rather than equal atoms (boils down to a type
929 /* The captured value. */
931 void gen_transform (FILE *f
, int, const char *, bool, int,
932 const char *, capture_info
*,
933 dt_operand
** = 0, int = 0) final override
;
938 class if_expr
: public operand
941 if_expr (location_t loc
)
942 : operand (OP_IF
, loc
), cond (NULL
), trueexpr (NULL
), falseexpr (NULL
) {}
948 /* with expression. */
950 class with_expr
: public operand
953 with_expr (location_t loc
)
954 : operand (OP_WITH
, loc
), with (NULL
), subexpr (NULL
) {}
962 is_a_helper
<capture
*>::test (operand
*op
)
964 return op
->type
== operand::OP_CAPTURE
;
970 is_a_helper
<predicate
*>::test (operand
*op
)
972 return op
->type
== operand::OP_PREDICATE
;
978 is_a_helper
<c_expr
*>::test (operand
*op
)
980 return op
->type
== operand::OP_C_EXPR
;
986 is_a_helper
<expr
*>::test (operand
*op
)
988 return op
->type
== operand::OP_EXPR
;
994 is_a_helper
<if_expr
*>::test (operand
*op
)
996 return op
->type
== operand::OP_IF
;
1002 is_a_helper
<with_expr
*>::test (operand
*op
)
1004 return op
->type
== operand::OP_WITH
;
1007 /* The main class of a pattern and its transform. This is used to
1008 represent both (simplify ...) and (match ...) kinds. The AST
1009 duplicates all outer 'if' and 'for' expressions here so each
1010 simplify can exist in isolation. */
1015 enum simplify_kind
{ SIMPLIFY
, MATCH
};
1017 simplify (simplify_kind kind_
, unsigned id_
, operand
*match_
,
1018 operand
*result_
, vec
<vec
<user_id
*> > for_vec_
,
1019 cid_map_t
*capture_ids_
)
1020 : kind (kind_
), id (id_
), match (match_
), result (result_
),
1021 for_vec (for_vec_
), for_subst_vec (vNULL
),
1022 capture_ids (capture_ids_
), capture_max (capture_ids_
->elements () - 1) {}
1025 /* ID. This is kept to easily associate related simplifies expanded
1026 from the same original one. */
1028 /* The expression that is matched against the GENERIC or GIMPLE IL. */
1030 /* For a (simplify ...) an expression with ifs and withs with the expression
1031 produced when the pattern applies in the leafs.
1032 For a (match ...) the leafs are either empty if it is a simple predicate
1033 or the single expression specifying the matched operands. */
1034 class operand
*result
;
1035 /* Collected 'for' expression operators that have to be replaced
1036 in the lowering phase. */
1037 vec
<vec
<user_id
*> > for_vec
;
1038 vec
<std::pair
<user_id
*, id_base
*> > for_subst_vec
;
1039 /* A map of capture identifiers to indexes. */
1040 cid_map_t
*capture_ids
;
1044 /* Debugging routines for dumping the AST. */
1047 print_operand (operand
*o
, FILE *f
= stderr
, bool flattened
= false)
1049 if (capture
*c
= dyn_cast
<capture
*> (o
))
1051 if (c
->what
&& flattened
== false)
1052 print_operand (c
->what
, f
, flattened
);
1053 fprintf (f
, "@%u", c
->where
);
1056 else if (predicate
*p
= dyn_cast
<predicate
*> (o
))
1057 fprintf (f
, "%s", p
->p
->id
);
1059 else if (is_a
<c_expr
*> (o
))
1060 fprintf (f
, "c_expr");
1062 else if (expr
*e
= dyn_cast
<expr
*> (o
))
1064 if (e
->ops
.length () == 0)
1065 fprintf (f
, "%s", e
->operation
->id
);
1068 fprintf (f
, "(%s", e
->operation
->id
);
1070 if (flattened
== false)
1072 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1075 print_operand (e
->ops
[i
], f
, flattened
);
1087 print_matches (class simplify
*s
, FILE *f
= stderr
)
1089 fprintf (f
, "for expression: ");
1090 print_operand (s
->match
, f
);
1097 /* Lowering of commutative operators. */
1100 cartesian_product (const vec
< vec
<operand
*> >& ops_vector
,
1101 vec
< vec
<operand
*> >& result
, vec
<operand
*>& v
, unsigned n
)
1103 if (n
== ops_vector
.length ())
1105 vec
<operand
*> xv
= v
.copy ();
1106 result
.safe_push (xv
);
1110 for (unsigned i
= 0; i
< ops_vector
[n
].length (); ++i
)
1112 v
[n
] = ops_vector
[n
][i
];
1113 cartesian_product (ops_vector
, result
, v
, n
+ 1);
1117 /* Lower OP to two operands in case it is marked as commutative. */
1119 static vec
<operand
*>
1120 commutate (operand
*op
, vec
<vec
<user_id
*> > &for_vec
)
1122 vec
<operand
*> ret
= vNULL
;
1124 if (capture
*c
= dyn_cast
<capture
*> (op
))
1131 vec
<operand
*> v
= commutate (c
->what
, for_vec
);
1132 for (unsigned i
= 0; i
< v
.length (); ++i
)
1134 capture
*nc
= new capture (c
->location
, c
->where
, v
[i
],
1141 expr
*e
= dyn_cast
<expr
*> (op
);
1142 if (!e
|| e
->ops
.length () == 0)
1148 vec
< vec
<operand
*> > ops_vector
= vNULL
;
1149 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1150 ops_vector
.safe_push (commutate (e
->ops
[i
], for_vec
));
1152 auto_vec
< vec
<operand
*> > result
;
1153 auto_vec
<operand
*> v (e
->ops
.length ());
1154 v
.quick_grow_cleared (e
->ops
.length ());
1155 cartesian_product (ops_vector
, result
, v
, 0);
1158 for (unsigned i
= 0; i
< result
.length (); ++i
)
1160 expr
*ne
= new expr (e
);
1161 ne
->is_commutative
= false;
1162 for (unsigned j
= 0; j
< result
[i
].length (); ++j
)
1163 ne
->append_op (result
[i
][j
]);
1167 if (!e
->is_commutative
)
1170 /* The operation is always binary if it isn't inherently commutative. */
1171 int natural_opno
= commutative_op (e
->operation
);
1172 unsigned int opno
= natural_opno
>= 0 ? natural_opno
: 0;
1173 for (unsigned i
= 0; i
< result
.length (); ++i
)
1175 expr
*ne
= new expr (e
);
1176 if (operator_id
*r
= dyn_cast
<operator_id
*> (ne
->operation
))
1178 if (comparison_code_p (r
->code
))
1179 ne
->operation
= swap_tree_comparison (r
);
1181 else if (user_id
*p
= dyn_cast
<user_id
*> (ne
->operation
))
1183 bool found_compare
= false;
1184 for (unsigned j
= 0; j
< p
->substitutes
.length (); ++j
)
1185 if (operator_id
*q
= dyn_cast
<operator_id
*> (p
->substitutes
[j
]))
1187 if (comparison_code_p (q
->code
)
1188 && swap_tree_comparison (q
) != q
)
1190 found_compare
= true;
1196 user_id
*newop
= new user_id ("<internal>");
1197 for (unsigned j
= 0; j
< p
->substitutes
.length (); ++j
)
1199 id_base
*subst
= p
->substitutes
[j
];
1200 if (operator_id
*q
= dyn_cast
<operator_id
*> (subst
))
1202 if (comparison_code_p (q
->code
))
1203 subst
= swap_tree_comparison (q
);
1205 newop
->substitutes
.safe_push (subst
);
1207 ne
->operation
= newop
;
1208 /* Search for 'p' inside the for vector and push 'newop'
1209 to the same level. */
1210 for (unsigned j
= 0; newop
&& j
< for_vec
.length (); ++j
)
1211 for (unsigned k
= 0; k
< for_vec
[j
].length (); ++k
)
1212 if (for_vec
[j
][k
] == p
)
1214 for_vec
[j
].safe_push (newop
);
1220 ne
->is_commutative
= false;
1221 for (unsigned j
= 0; j
< result
[i
].length (); ++j
)
1223 int old_j
= (j
== opno
? opno
+ 1 : j
== opno
+ 1 ? opno
: j
);
1224 ne
->append_op (result
[i
][old_j
]);
1232 /* Lower operations marked as commutative in the AST of S and push
1233 the resulting patterns to SIMPLIFIERS. */
1236 lower_commutative (simplify
*s
, vec
<simplify
*>& simplifiers
)
1238 vec
<operand
*> matchers
= commutate (s
->match
, s
->for_vec
);
1239 for (unsigned i
= 0; i
< matchers
.length (); ++i
)
1241 simplify
*ns
= new simplify (s
->kind
, s
->id
, matchers
[i
], s
->result
,
1242 s
->for_vec
, s
->capture_ids
);
1243 simplifiers
.safe_push (ns
);
1247 /* Strip conditional operations using group GRP from O and its
1248 children if STRIP, else replace them with an unconditional operation. */
1251 lower_opt (operand
*o
, unsigned char grp
, bool strip
)
1253 if (capture
*c
= dyn_cast
<capture
*> (o
))
1256 return new capture (c
->location
, c
->where
,
1257 lower_opt (c
->what
, grp
, strip
),
1263 expr
*e
= dyn_cast
<expr
*> (o
);
1267 if (e
->opt_grp
== grp
)
1270 return lower_opt (e
->ops
[0], grp
, strip
);
1272 expr
*ne
= new expr (e
);
1274 ne
->append_op (lower_opt (e
->ops
[0], grp
, strip
));
1278 expr
*ne
= new expr (e
);
1279 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1280 ne
->append_op (lower_opt (e
->ops
[i
], grp
, strip
));
1285 /* Determine whether O or its children uses the conditional operation
1289 has_opt (operand
*o
, unsigned char grp
)
1291 if (capture
*c
= dyn_cast
<capture
*> (o
))
1294 return has_opt (c
->what
, grp
);
1299 expr
*e
= dyn_cast
<expr
*> (o
);
1303 if (e
->opt_grp
== grp
)
1306 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1307 if (has_opt (e
->ops
[i
], grp
))
1313 /* Lower conditional convert operators in O, expanding it to a vector
1316 static vec
<operand
*>
1317 lower_opt (operand
*o
)
1319 vec
<operand
*> v1
= vNULL
, v2
;
1323 /* Conditional operations are lowered to a pattern with the
1324 operation and one without. All different conditional operation
1325 groups are lowered separately. */
1327 for (unsigned i
= 1; i
<= 10; ++i
)
1330 for (unsigned j
= 0; j
< v1
.length (); ++j
)
1331 if (has_opt (v1
[j
], i
))
1333 v2
.safe_push (lower_opt (v1
[j
], i
, false));
1334 v2
.safe_push (lower_opt (v1
[j
], i
, true));
1340 for (unsigned j
= 0; j
< v2
.length (); ++j
)
1341 v1
.safe_push (v2
[j
]);
1348 /* Lower conditional convert operators in the AST of S and push
1349 the resulting multiple patterns to SIMPLIFIERS. */
1352 lower_opt (simplify
*s
, vec
<simplify
*>& simplifiers
)
1354 vec
<operand
*> matchers
= lower_opt (s
->match
);
1355 for (unsigned i
= 0; i
< matchers
.length (); ++i
)
1357 simplify
*ns
= new simplify (s
->kind
, s
->id
, matchers
[i
], s
->result
,
1358 s
->for_vec
, s
->capture_ids
);
1359 simplifiers
.safe_push (ns
);
1363 /* Lower the compare operand of COND_EXPRs to a
1364 GENERIC and a GIMPLE variant. */
1366 static vec
<operand
*>
1367 lower_cond (operand
*o
)
1369 vec
<operand
*> ro
= vNULL
;
1371 if (capture
*c
= dyn_cast
<capture
*> (o
))
1375 vec
<operand
*> lop
= vNULL
;
1376 lop
= lower_cond (c
->what
);
1378 for (unsigned i
= 0; i
< lop
.length (); ++i
)
1379 ro
.safe_push (new capture (c
->location
, c
->where
, lop
[i
],
1385 expr
*e
= dyn_cast
<expr
*> (o
);
1386 if (!e
|| e
->ops
.length () == 0)
1392 vec
< vec
<operand
*> > ops_vector
= vNULL
;
1393 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1394 ops_vector
.safe_push (lower_cond (e
->ops
[i
]));
1396 auto_vec
< vec
<operand
*> > result
;
1397 auto_vec
<operand
*> v (e
->ops
.length ());
1398 v
.quick_grow_cleared (e
->ops
.length ());
1399 cartesian_product (ops_vector
, result
, v
, 0);
1401 for (unsigned i
= 0; i
< result
.length (); ++i
)
1403 expr
*ne
= new expr (e
);
1404 for (unsigned j
= 0; j
< result
[i
].length (); ++j
)
1405 ne
->append_op (result
[i
][j
]);
1407 /* If this is a COND with a captured expression or an
1408 expression with two operands then also match a GENERIC
1409 form on the compare. */
1410 if (*e
->operation
== COND_EXPR
1411 && ((is_a
<capture
*> (e
->ops
[0])
1412 && as_a
<capture
*> (e
->ops
[0])->what
1413 && is_a
<expr
*> (as_a
<capture
*> (e
->ops
[0])->what
)
1415 (as_a
<capture
*> (e
->ops
[0])->what
)->ops
.length () == 2)
1416 || (is_a
<expr
*> (e
->ops
[0])
1417 && as_a
<expr
*> (e
->ops
[0])->ops
.length () == 2)))
1420 for (unsigned j
= 0; j
< result
[i
].length (); ++j
)
1421 ne
->append_op (result
[i
][j
]);
1422 if (capture
*c
= dyn_cast
<capture
*> (ne
->ops
[0]))
1424 expr
*ocmp
= as_a
<expr
*> (c
->what
);
1425 expr
*cmp
= new expr (ocmp
);
1426 for (unsigned j
= 0; j
< ocmp
->ops
.length (); ++j
)
1427 cmp
->append_op (ocmp
->ops
[j
]);
1428 cmp
->is_generic
= true;
1429 ne
->ops
[0] = new capture (c
->location
, c
->where
, cmp
,
1434 expr
*ocmp
= as_a
<expr
*> (ne
->ops
[0]);
1435 expr
*cmp
= new expr (ocmp
);
1436 for (unsigned j
= 0; j
< ocmp
->ops
.length (); ++j
)
1437 cmp
->append_op (ocmp
->ops
[j
]);
1438 cmp
->is_generic
= true;
1448 /* Lower the compare operand of COND_EXPRs to a
1449 GENERIC and a GIMPLE variant. */
1452 lower_cond (simplify
*s
, vec
<simplify
*>& simplifiers
)
1454 vec
<operand
*> matchers
= lower_cond (s
->match
);
1455 for (unsigned i
= 0; i
< matchers
.length (); ++i
)
1457 simplify
*ns
= new simplify (s
->kind
, s
->id
, matchers
[i
], s
->result
,
1458 s
->for_vec
, s
->capture_ids
);
1459 ns
->for_subst_vec
.safe_splice (s
->for_subst_vec
);
1460 simplifiers
.safe_push (ns
);
1464 /* Return true if O refers to ID. */
1467 contains_id (operand
*o
, user_id
*id
)
1469 if (capture
*c
= dyn_cast
<capture
*> (o
))
1470 return c
->what
&& contains_id (c
->what
, id
);
1472 if (expr
*e
= dyn_cast
<expr
*> (o
))
1474 if (e
->operation
== id
)
1476 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1477 if (contains_id (e
->ops
[i
], id
))
1482 if (with_expr
*w
= dyn_cast
<with_expr
*> (o
))
1483 return (contains_id (w
->with
, id
)
1484 || contains_id (w
->subexpr
, id
));
1486 if (if_expr
*ife
= dyn_cast
<if_expr
*> (o
))
1487 return (contains_id (ife
->cond
, id
)
1488 || contains_id (ife
->trueexpr
, id
)
1489 || (ife
->falseexpr
&& contains_id (ife
->falseexpr
, id
)));
1491 if (c_expr
*ce
= dyn_cast
<c_expr
*> (o
))
1492 return ce
->capture_ids
&& ce
->capture_ids
->get (id
->id
);
1498 /* In AST operand O replace operator ID with operator WITH. */
1501 replace_id (operand
*o
, user_id
*id
, id_base
*with
)
1503 /* Deep-copy captures and expressions, replacing operations as
1505 if (capture
*c
= dyn_cast
<capture
*> (o
))
1509 return new capture (c
->location
, c
->where
,
1510 replace_id (c
->what
, id
, with
), c
->value_match
);
1512 else if (expr
*e
= dyn_cast
<expr
*> (o
))
1514 expr
*ne
= new expr (e
);
1515 if (e
->operation
== id
)
1516 ne
->operation
= with
;
1517 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
1518 ne
->append_op (replace_id (e
->ops
[i
], id
, with
));
1521 else if (with_expr
*w
= dyn_cast
<with_expr
*> (o
))
1523 with_expr
*nw
= new with_expr (w
->location
);
1524 nw
->with
= as_a
<c_expr
*> (replace_id (w
->with
, id
, with
));
1525 nw
->subexpr
= replace_id (w
->subexpr
, id
, with
);
1528 else if (if_expr
*ife
= dyn_cast
<if_expr
*> (o
))
1530 if_expr
*nife
= new if_expr (ife
->location
);
1531 nife
->cond
= as_a
<c_expr
*> (replace_id (ife
->cond
, id
, with
));
1532 nife
->trueexpr
= replace_id (ife
->trueexpr
, id
, with
);
1534 nife
->falseexpr
= replace_id (ife
->falseexpr
, id
, with
);
1538 /* For c_expr we simply record a string replacement table which is
1539 applied at code-generation time. */
1540 if (c_expr
*ce
= dyn_cast
<c_expr
*> (o
))
1542 vec
<c_expr::id_tab
> ids
= ce
->ids
.copy ();
1543 ids
.safe_push (c_expr::id_tab (id
->id
, with
->id
));
1544 return new c_expr (ce
->r
, ce
->location
,
1545 ce
->code
, ce
->nr_stmts
, ids
, ce
->capture_ids
);
1551 /* Return true if the binary operator OP is ok for delayed substitution
1552 during for lowering. */
1555 binary_ok (operator_id
*op
)
1562 case TRUNC_DIV_EXPR
:
1564 case FLOOR_DIV_EXPR
:
1565 case ROUND_DIV_EXPR
:
1566 case TRUNC_MOD_EXPR
:
1568 case FLOOR_MOD_EXPR
:
1569 case ROUND_MOD_EXPR
:
1571 case EXACT_DIV_EXPR
:
1583 /* Lower recorded fors for SIN and output to SIMPLIFIERS. */
1586 lower_for (simplify
*sin
, vec
<simplify
*>& simplifiers
)
1588 vec
<vec
<user_id
*> >& for_vec
= sin
->for_vec
;
1589 unsigned worklist_start
= 0;
1590 auto_vec
<simplify
*> worklist
;
1591 worklist
.safe_push (sin
);
1593 /* Lower each recorded for separately, operating on the
1594 set of simplifiers created by the previous one.
1595 Lower inner-to-outer so inner for substitutes can refer
1596 to operators replaced by outer fors. */
1597 for (int fi
= for_vec
.length () - 1; fi
>= 0; --fi
)
1599 vec
<user_id
*>& ids
= for_vec
[fi
];
1600 unsigned n_ids
= ids
.length ();
1601 unsigned max_n_opers
= 0;
1602 bool can_delay_subst
= true;
1603 for (unsigned i
= 0; i
< n_ids
; ++i
)
1605 if (ids
[i
]->substitutes
.length () > max_n_opers
)
1606 max_n_opers
= ids
[i
]->substitutes
.length ();
1607 /* Require that all substitutes are of the same kind so that
1608 if we delay substitution to the result op code generation
1609 can look at the first substitute for deciding things like
1610 types of operands. */
1611 enum id_base::id_kind kind
= ids
[i
]->substitutes
[0]->kind
;
1612 for (unsigned j
= 0; j
< ids
[i
]->substitutes
.length (); ++j
)
1613 if (ids
[i
]->substitutes
[j
]->kind
!= kind
)
1614 can_delay_subst
= false;
1615 else if (operator_id
*op
1616 = dyn_cast
<operator_id
*> (ids
[i
]->substitutes
[j
]))
1619 = as_a
<operator_id
*> (ids
[i
]->substitutes
[0]);
1620 if (strcmp (op
->tcc
, "tcc_comparison") == 0
1621 && strcmp (op0
->tcc
, "tcc_comparison") == 0)
1623 /* Unfortunately we can't just allow all tcc_binary. */
1624 else if (strcmp (op
->tcc
, "tcc_binary") == 0
1625 && strcmp (op0
->tcc
, "tcc_binary") == 0
1629 else if ((strcmp (op
->id
+ 1, "SHIFT_EXPR") == 0
1630 || strcmp (op
->id
+ 1, "ROTATE_EXPR") == 0)
1631 && (strcmp (op0
->id
+ 1, "SHIFT_EXPR") == 0
1632 || strcmp (op0
->id
+ 1, "ROTATE_EXPR") == 0))
1635 can_delay_subst
= false;
1637 else if (is_a
<fn_id
*> (ids
[i
]->substitutes
[j
]))
1640 can_delay_subst
= false;
1642 if (sin
->kind
== simplify::MATCH
1646 unsigned worklist_end
= worklist
.length ();
1647 for (unsigned si
= worklist_start
; si
< worklist_end
; ++si
)
1649 simplify
*s
= worklist
[si
];
1650 for (unsigned j
= 0; j
< max_n_opers
; ++j
)
1652 operand
*match_op
= s
->match
;
1653 operand
*result_op
= s
->result
;
1654 auto_vec
<std::pair
<user_id
*, id_base
*> > subst (n_ids
);
1656 for (unsigned i
= 0; i
< n_ids
; ++i
)
1658 user_id
*id
= ids
[i
];
1659 id_base
*oper
= id
->substitutes
[j
% id
->substitutes
.length ()];
1661 && (contains_id (match_op
, id
)
1662 || contains_id (result_op
, id
)))
1667 subst
.quick_push (std::make_pair (id
, oper
));
1668 if (sin
->kind
== simplify::SIMPLIFY
1669 || !can_delay_subst
)
1670 match_op
= replace_id (match_op
, id
, oper
);
1672 && !can_delay_subst
)
1673 result_op
= replace_id (result_op
, id
, oper
);
1678 simplify
*ns
= new simplify (s
->kind
, s
->id
, match_op
, result_op
,
1679 vNULL
, s
->capture_ids
);
1680 ns
->for_subst_vec
.safe_splice (s
->for_subst_vec
);
1683 ns
->for_subst_vec
.safe_splice (subst
);
1685 worklist
.safe_push (ns
);
1688 worklist_start
= worklist_end
;
1691 /* Copy out the result from the last for lowering. */
1692 for (unsigned i
= worklist_start
; i
< worklist
.length (); ++i
)
1693 simplifiers
.safe_push (worklist
[i
]);
1696 /* Lower the AST for everything in SIMPLIFIERS. */
1699 lower (vec
<simplify
*>& simplifiers
, bool gimple
)
1701 auto_vec
<simplify
*> out_simplifiers
;
1702 for (auto s
: simplifiers
)
1703 lower_opt (s
, out_simplifiers
);
1705 simplifiers
.truncate (0);
1706 for (auto s
: out_simplifiers
)
1707 lower_commutative (s
, simplifiers
);
1709 /* Lower for needs to happen before lowering cond
1710 to support (for cnd (cond vec_cond)). This is
1711 safe as substitution delay does not happen for
1712 cond or vec_cond. */
1713 out_simplifiers
.truncate (0);
1714 for (auto s
: simplifiers
)
1715 lower_for (s
, out_simplifiers
);
1717 simplifiers
.truncate (0);
1719 for (auto s
: out_simplifiers
)
1720 lower_cond (s
, simplifiers
);
1722 simplifiers
.safe_splice (out_simplifiers
);
1728 /* The decision tree built for generating GIMPLE and GENERIC pattern
1729 matching code. It represents the 'match' expression of all
1730 simplifies and has those as its leafs. */
1734 /* A hash-map collecting semantically equivalent leafs in the decision
1735 tree for splitting out to separate functions. */
1744 struct sinfo_hashmap_traits
: simple_hashmap_traits
<pointer_hash
<dt_simplify
>,
1747 static inline hashval_t
hash (const key_type
&);
1748 static inline bool equal_keys (const key_type
&, const key_type
&);
1749 template <typename T
> static inline void remove (T
&) {}
1752 typedef ordered_hash_map
<void * /* unused */, sinfo
*, sinfo_hashmap_traits
>
1755 /* Current simplifier ID we are processing during insertion into the
1757 static unsigned current_id
;
1759 /* Decision tree base class, used for DT_NODE. */
1764 enum dt_type
{ DT_NODE
, DT_OPERAND
, DT_TRUE
, DT_MATCH
, DT_SIMPLIFY
};
1769 vec
<dt_node
*> kids
;
1773 unsigned total_size
;
1776 dt_node (enum dt_type type_
, dt_node
*parent_
)
1777 : type (type_
), level (0), parent (parent_
), kids (vNULL
) {}
1779 dt_node
*append_node (dt_node
*);
1780 dt_node
*append_op (operand
*, dt_node
*parent
, unsigned pos
);
1781 dt_node
*append_true_op (operand
*, dt_node
*parent
, unsigned pos
);
1782 dt_node
*append_match_op (operand
*, dt_operand
*, dt_node
*parent
,
1784 dt_node
*append_simplify (simplify
*, unsigned, dt_operand
**);
1786 virtual void gen (FILE *, int, bool, int) {}
1788 void gen_kids (FILE *, int, bool, int);
1789 void gen_kids_1 (FILE *, int, bool, int,
1790 const vec
<dt_operand
*> &, const vec
<dt_operand
*> &,
1791 const vec
<dt_operand
*> &, const vec
<dt_operand
*> &,
1792 const vec
<dt_operand
*> &, const vec
<dt_node
*> &);
1794 void analyze (sinfo_map_t
&);
1797 /* Generic decision tree node used for DT_OPERAND, DT_MATCH and DT_TRUE. */
1799 class dt_operand
: public dt_node
1803 dt_operand
*match_dop
;
1808 dt_operand (enum dt_type type
, operand
*op_
, dt_operand
*match_dop_
,
1809 dt_operand
*parent_
, unsigned pos_
)
1810 : dt_node (type
, parent_
), op (op_
), match_dop (match_dop_
),
1811 pos (pos_
), value_match (false), for_id (current_id
) {}
1813 void gen (FILE *, int, bool, int) final override
;
1814 unsigned gen_predicate (FILE *, int, const char *, bool);
1815 unsigned gen_match_op (FILE *, int, const char *, bool);
1817 unsigned gen_gimple_expr (FILE *, int, int);
1818 unsigned gen_generic_expr (FILE *, int, const char *);
1820 char *get_name (char *);
1821 void gen_opname (char *, unsigned);
1824 /* Leaf node of the decision tree, used for DT_SIMPLIFY. */
1826 class dt_simplify
: public dt_node
1830 unsigned pattern_no
;
1831 dt_operand
**indexes
;
1834 dt_simplify (simplify
*s_
, unsigned pattern_no_
, dt_operand
**indexes_
)
1835 : dt_node (DT_SIMPLIFY
, NULL
), s (s_
), pattern_no (pattern_no_
),
1836 indexes (indexes_
), info (NULL
) {}
1838 void gen_1 (FILE *, int, bool, operand
*);
1839 void gen (FILE *f
, int, bool, int) final override
;
1845 is_a_helper
<dt_operand
*>::test (dt_node
*n
)
1847 return (n
->type
== dt_node::DT_OPERAND
1848 || n
->type
== dt_node::DT_MATCH
1849 || n
->type
== dt_node::DT_TRUE
);
1855 is_a_helper
<dt_simplify
*>::test (dt_node
*n
)
1857 return n
->type
== dt_node::DT_SIMPLIFY
;
1862 /* A container for the actual decision tree. */
1869 void insert (class simplify
*, unsigned);
1870 void gen (vec
<FILE *> &f
, bool gimple
);
1871 void print (FILE *f
= stderr
);
1873 decision_tree () { root
= new dt_node (dt_node::DT_NODE
, NULL
); }
1875 static dt_node
*insert_operand (dt_node
*, operand
*, dt_operand
**indexes
,
1876 unsigned pos
= 0, dt_node
*parent
= 0);
1877 static dt_node
*find_node (vec
<dt_node
*>&, dt_node
*);
1878 static bool cmp_node (dt_node
*, dt_node
*);
1879 static void print_node (dt_node
*, FILE *f
= stderr
, unsigned = 0);
1882 /* Compare two AST operands O1 and O2 and return true if they are equal. */
1885 cmp_operand (operand
*o1
, operand
*o2
)
1887 if (!o1
|| !o2
|| o1
->type
!= o2
->type
)
1890 if (o1
->type
== operand::OP_PREDICATE
)
1892 predicate
*p1
= as_a
<predicate
*>(o1
);
1893 predicate
*p2
= as_a
<predicate
*>(o2
);
1894 return p1
->p
== p2
->p
;
1896 else if (o1
->type
== operand::OP_EXPR
)
1898 expr
*e1
= static_cast<expr
*>(o1
);
1899 expr
*e2
= static_cast<expr
*>(o2
);
1900 if (e1
->operation
!= e2
->operation
1901 || e1
->is_generic
!= e2
->is_generic
)
1903 if (e1
->operation
->kind
== id_base::FN
1904 /* For function calls also compare number of arguments. */
1905 && e1
->ops
.length () != e2
->ops
.length ())
1913 /* Compare two decision tree nodes N1 and N2 and return true if they
1917 decision_tree::cmp_node (dt_node
*n1
, dt_node
*n2
)
1919 if (!n1
|| !n2
|| n1
->type
!= n2
->type
)
1925 if (n1
->type
== dt_node::DT_TRUE
)
1928 if (n1
->type
== dt_node::DT_OPERAND
)
1929 return cmp_operand ((as_a
<dt_operand
*> (n1
))->op
,
1930 (as_a
<dt_operand
*> (n2
))->op
);
1931 else if (n1
->type
== dt_node::DT_MATCH
)
1932 return (((as_a
<dt_operand
*> (n1
))->match_dop
1933 == (as_a
<dt_operand
*> (n2
))->match_dop
)
1934 && ((as_a
<dt_operand
*> (n1
))->value_match
1935 == (as_a
<dt_operand
*> (n2
))->value_match
));
1939 /* Search OPS for a decision tree node like P and return it if found. */
1942 decision_tree::find_node (vec
<dt_node
*>& ops
, dt_node
*p
)
1944 /* We can merge adjacent DT_TRUE. */
1945 if (p
->type
== dt_node::DT_TRUE
1947 && ops
.last ()->type
== dt_node::DT_TRUE
)
1949 dt_operand
*true_node
= NULL
;
1950 for (int i
= ops
.length () - 1; i
>= 0; --i
)
1952 /* But we can't merge across DT_TRUE nodes as they serve as
1953 pattern order barriers to make sure that patterns apply
1954 in order of appearance in case multiple matches are possible. */
1955 if (ops
[i
]->type
== dt_node::DT_TRUE
)
1958 || as_a
<dt_operand
*> (ops
[i
])->for_id
> true_node
->for_id
)
1959 true_node
= as_a
<dt_operand
*> (ops
[i
]);
1961 if (decision_tree::cmp_node (ops
[i
], p
))
1963 /* Unless we are processing the same pattern or the blocking
1964 pattern is before the one we are going to merge with. */
1966 && true_node
->for_id
!= current_id
1967 && true_node
->for_id
> as_a
<dt_operand
*> (ops
[i
])->for_id
)
1971 location_t p_loc
= 0;
1972 if (p
->type
== dt_node::DT_OPERAND
)
1973 p_loc
= as_a
<dt_operand
*> (p
)->op
->location
;
1974 location_t op_loc
= 0;
1975 if (ops
[i
]->type
== dt_node::DT_OPERAND
)
1976 op_loc
= as_a
<dt_operand
*> (ops
[i
])->op
->location
;
1977 location_t true_loc
= 0;
1978 true_loc
= true_node
->op
->location
;
1980 "failed to merge decision tree node");
1982 "with the following");
1983 warning_at (true_loc
,
1984 "because of the following which serves as ordering "
1995 /* Append N to the decision tree if it there is not already an existing
1999 dt_node::append_node (dt_node
*n
)
2003 kid
= decision_tree::find_node (kids
, n
);
2008 n
->level
= this->level
+ 1;
2013 /* Append OP to the decision tree. */
2016 dt_node::append_op (operand
*op
, dt_node
*parent
, unsigned pos
)
2018 dt_operand
*parent_
= safe_as_a
<dt_operand
*> (parent
);
2019 dt_operand
*n
= new dt_operand (DT_OPERAND
, op
, 0, parent_
, pos
);
2020 return append_node (n
);
2023 /* Append a DT_TRUE decision tree node. */
2026 dt_node::append_true_op (operand
*op
, dt_node
*parent
, unsigned pos
)
2028 dt_operand
*parent_
= safe_as_a
<dt_operand
*> (parent
);
2029 dt_operand
*n
= new dt_operand (DT_TRUE
, op
, 0, parent_
, pos
);
2030 return append_node (n
);
2033 /* Append a DT_MATCH decision tree node. */
2036 dt_node::append_match_op (operand
*op
, dt_operand
*match_dop
,
2037 dt_node
*parent
, unsigned pos
)
2039 dt_operand
*parent_
= as_a
<dt_operand
*> (parent
);
2040 dt_operand
*n
= new dt_operand (DT_MATCH
, op
, match_dop
, parent_
, pos
);
2041 return append_node (n
);
2044 /* Append S to the decision tree. */
2047 dt_node::append_simplify (simplify
*s
, unsigned pattern_no
,
2048 dt_operand
**indexes
)
2051 dt_simplify
*n
= new dt_simplify (s
, pattern_no
, indexes
);
2052 for (unsigned i
= 0; i
< kids
.length (); ++i
)
2053 if ((s2
= dyn_cast
<dt_simplify
*> (kids
[i
]))
2055 || s
->match
->location
!= s2
->s
->match
->location
))
2057 /* With a nested patters, it's hard to avoid these in order
2058 to keep match.pd rules relatively small. */
2059 warning_at (s
->match
->location
, "duplicate pattern");
2060 warning_at (s2
->s
->match
->location
, "previous pattern defined here");
2061 print_operand (s
->match
, stderr
);
2062 fprintf (stderr
, "\n");
2064 return append_node (n
);
2067 /* Analyze the node and its children. */
2070 dt_node::analyze (sinfo_map_t
&map
)
2076 if (type
== DT_SIMPLIFY
)
2078 /* Populate the map of equivalent simplifies. */
2079 dt_simplify
*s
= as_a
<dt_simplify
*> (this);
2081 sinfo
*&si
= map
.get_or_insert (s
, &existed
);
2096 for (unsigned i
= 0; i
< kids
.length (); ++i
)
2098 kids
[i
]->analyze (map
);
2099 num_leafs
+= kids
[i
]->num_leafs
;
2100 total_size
+= kids
[i
]->total_size
;
2101 max_level
= MAX (max_level
, kids
[i
]->max_level
);
2105 /* Insert O into the decision tree and return the decision tree node found
2109 decision_tree::insert_operand (dt_node
*p
, operand
*o
, dt_operand
**indexes
,
2110 unsigned pos
, dt_node
*parent
)
2112 dt_node
*q
, *elm
= 0;
2114 if (capture
*c
= dyn_cast
<capture
*> (o
))
2116 unsigned capt_index
= c
->where
;
2118 if (indexes
[capt_index
] == 0)
2121 q
= insert_operand (p
, c
->what
, indexes
, pos
, parent
);
2124 q
= elm
= p
->append_true_op (o
, parent
, pos
);
2127 // get to the last capture
2128 for (operand
*what
= c
->what
;
2129 what
&& is_a
<capture
*> (what
);
2130 c
= as_a
<capture
*> (what
), what
= c
->what
)
2135 unsigned cc_index
= c
->where
;
2136 dt_operand
*match_op
= indexes
[cc_index
];
2138 dt_operand
temp (dt_node::DT_TRUE
, 0, 0, 0, 0);
2139 elm
= decision_tree::find_node (p
->kids
, &temp
);
2143 dt_operand
match (dt_node::DT_MATCH
, 0, match_op
, 0, 0);
2144 match
.value_match
= c
->value_match
;
2145 elm
= decision_tree::find_node (p
->kids
, &match
);
2150 dt_operand
temp (dt_node::DT_OPERAND
, c
->what
, 0, 0, 0);
2151 elm
= decision_tree::find_node (p
->kids
, &temp
);
2155 gcc_assert (elm
->type
== dt_node::DT_TRUE
2156 || elm
->type
== dt_node::DT_OPERAND
2157 || elm
->type
== dt_node::DT_MATCH
);
2158 indexes
[capt_index
] = static_cast<dt_operand
*> (elm
);
2163 p
= p
->append_match_op (o
, indexes
[capt_index
], parent
, pos
);
2164 as_a
<dt_operand
*>(p
)->value_match
= c
->value_match
;
2166 return insert_operand (p
, c
->what
, indexes
, 0, p
);
2171 p
= p
->append_op (o
, parent
, pos
);
2174 if (expr
*e
= dyn_cast
<expr
*>(o
))
2176 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
2177 q
= decision_tree::insert_operand (q
, e
->ops
[i
], indexes
, i
, p
);
2183 /* Insert S into the decision tree. */
2186 decision_tree::insert (class simplify
*s
, unsigned pattern_no
)
2189 dt_operand
**indexes
= XCNEWVEC (dt_operand
*, s
->capture_max
+ 1);
2190 dt_node
*p
= decision_tree::insert_operand (root
, s
->match
, indexes
);
2191 p
->append_simplify (s
, pattern_no
, indexes
);
2194 /* Debug functions to dump the decision tree. */
2197 decision_tree::print_node (dt_node
*p
, FILE *f
, unsigned indent
)
2199 if (p
->type
== dt_node::DT_NODE
)
2200 fprintf (f
, "root");
2204 for (unsigned i
= 0; i
< indent
; i
++)
2207 if (p
->type
== dt_node::DT_OPERAND
)
2209 dt_operand
*dop
= static_cast<dt_operand
*>(p
);
2210 print_operand (dop
->op
, f
, true);
2212 else if (p
->type
== dt_node::DT_TRUE
)
2213 fprintf (f
, "true");
2214 else if (p
->type
== dt_node::DT_MATCH
)
2215 fprintf (f
, "match (%p)", (void *)((as_a
<dt_operand
*>(p
))->match_dop
));
2216 else if (p
->type
== dt_node::DT_SIMPLIFY
)
2218 dt_simplify
*s
= static_cast<dt_simplify
*> (p
);
2219 fprintf (f
, "simplify_%u { ", s
->pattern_no
);
2220 for (int i
= 0; i
<= s
->s
->capture_max
; ++i
)
2221 fprintf (f
, "%p, ", (void *) s
->indexes
[i
]);
2224 if (is_a
<dt_operand
*> (p
))
2225 fprintf (f
, " [%u]", as_a
<dt_operand
*> (p
)->for_id
);
2228 fprintf (stderr
, " (%p, %p), %u, %u\n",
2229 (void *) p
, (void *) p
->parent
, p
->level
, p
->kids
.length ());
2231 for (unsigned i
= 0; i
< p
->kids
.length (); ++i
)
2232 decision_tree::print_node (p
->kids
[i
], f
, indent
+ 2);
2236 decision_tree::print (FILE *f
)
2238 return decision_tree::print_node (root
, f
);
2242 /* For GENERIC we have to take care of wrapping multiple-used
2243 expressions with side-effects in save_expr and preserve side-effects
2244 of expressions with omit_one_operand. Analyze captures in
2245 match, result and with expressions and perform early-outs
2246 on the outermost match expression operands for cases we cannot
2252 capture_info (simplify
*s
, operand
*, bool);
2253 void walk_match (operand
*o
, unsigned toplevel_arg
, bool, bool);
2254 bool walk_result (operand
*o
, bool, operand
*);
2255 void walk_c_expr (c_expr
*);
2261 bool force_no_side_effects_p
;
2262 bool force_single_use
;
2263 bool cond_expr_cond_p
;
2264 unsigned long toplevel_msk
;
2265 unsigned match_use_count
;
2266 unsigned result_use_count
;
2271 auto_vec
<cinfo
> info
;
2272 unsigned long force_no_side_effects
;
2276 /* Analyze captures in S. */
2278 capture_info::capture_info (simplify
*s
, operand
*result
, bool gimple_
)
2283 if (s
->kind
== simplify::MATCH
)
2285 force_no_side_effects
= -1;
2289 force_no_side_effects
= 0;
2290 info
.safe_grow_cleared (s
->capture_max
+ 1, true);
2291 for (int i
= 0; i
<= s
->capture_max
; ++i
)
2292 info
[i
].same_as
= i
;
2294 e
= as_a
<expr
*> (s
->match
);
2295 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
2296 walk_match (e
->ops
[i
], i
,
2297 (i
!= 0 && *e
->operation
== COND_EXPR
)
2298 || *e
->operation
== TRUTH_ANDIF_EXPR
2299 || *e
->operation
== TRUTH_ORIF_EXPR
,
2300 i
== 0 && *e
->operation
== COND_EXPR
);
2302 walk_result (s
->result
, false, result
);
2305 /* Analyze captures in the match expression piece O. */
2308 capture_info::walk_match (operand
*o
, unsigned toplevel_arg
,
2309 bool conditional_p
, bool cond_expr_cond_p
)
2311 if (capture
*c
= dyn_cast
<capture
*> (o
))
2313 unsigned where
= c
->where
;
2314 info
[where
].match_use_count
++;
2315 info
[where
].toplevel_msk
|= 1 << toplevel_arg
;
2316 info
[where
].force_no_side_effects_p
|= conditional_p
;
2317 info
[where
].cond_expr_cond_p
|= cond_expr_cond_p
;
2322 /* Recurse to exprs and captures. */
2323 if (is_a
<capture
*> (c
->what
)
2324 || is_a
<expr
*> (c
->what
))
2325 walk_match (c
->what
, toplevel_arg
, conditional_p
, false);
2326 /* We need to look past multiple captures to find a captured
2327 expression as with conditional converts two captures
2328 can be collapsed onto the same expression. Also collect
2329 what captures capture the same thing. */
2330 while (c
->what
&& is_a
<capture
*> (c
->what
))
2332 c
= as_a
<capture
*> (c
->what
);
2333 if (info
[c
->where
].same_as
!= c
->where
2334 && info
[c
->where
].same_as
!= info
[where
].same_as
)
2335 fatal_at (c
->location
, "cannot handle this collapsed capture");
2336 info
[c
->where
].same_as
= info
[where
].same_as
;
2338 /* Mark expr (non-leaf) captures and forced single-use exprs. */
2341 && (e
= dyn_cast
<expr
*> (c
->what
)))
2343 /* Zero-operand expression captures like ADDR_EXPR@0 are
2344 similar as predicates -- if they are not mentioned in
2345 the result we have to force them to have no side-effects. */
2346 if (e
->ops
.length () != 0)
2347 info
[where
].expr_p
= true;
2348 info
[where
].force_single_use
|= e
->force_single_use
;
2351 else if (expr
*e
= dyn_cast
<expr
*> (o
))
2353 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
2355 bool cond_p
= conditional_p
;
2356 bool expr_cond_p
= false;
2357 if (i
!= 0 && *e
->operation
== COND_EXPR
)
2359 else if (*e
->operation
== TRUTH_ANDIF_EXPR
2360 || *e
->operation
== TRUTH_ORIF_EXPR
)
2363 && *e
->operation
== COND_EXPR
)
2365 walk_match (e
->ops
[i
], toplevel_arg
, cond_p
, expr_cond_p
);
2368 else if (is_a
<predicate
*> (o
))
2370 /* Mark non-captured leafs toplevel arg for checking. */
2371 force_no_side_effects
|= 1 << toplevel_arg
;
2374 warning_at (o
->location
,
2375 "forcing no side-effects on possibly lost leaf");
2381 /* Analyze captures in the result expression piece O. Return true
2382 if RESULT was visited in one of the children. Only visit
2383 non-if/with children if they are rooted on RESULT. */
2386 capture_info::walk_result (operand
*o
, bool conditional_p
, operand
*result
)
2388 if (capture
*c
= dyn_cast
<capture
*> (o
))
2390 unsigned where
= info
[c
->where
].same_as
;
2391 info
[where
].result_use_count
++;
2392 /* If we substitute an expression capture we don't know
2393 which captures this will end up using (well, we don't
2394 compute that). Force the uses to be side-effect free
2395 which means forcing the toplevels that reach the
2396 expression side-effect free. */
2397 if (info
[where
].expr_p
)
2398 force_no_side_effects
|= info
[where
].toplevel_msk
;
2399 /* Mark CSE capture uses as forced to have no side-effects. */
2401 && is_a
<expr
*> (c
->what
))
2403 info
[where
].cse_p
= true;
2404 walk_result (c
->what
, true, result
);
2407 else if (expr
*e
= dyn_cast
<expr
*> (o
))
2409 id_base
*opr
= e
->operation
;
2410 if (user_id
*uid
= dyn_cast
<user_id
*> (opr
))
2411 opr
= uid
->substitutes
[0];
2412 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
2414 bool cond_p
= conditional_p
;
2415 if (i
!= 0 && *e
->operation
== COND_EXPR
)
2417 else if (*e
->operation
== TRUTH_ANDIF_EXPR
2418 || *e
->operation
== TRUTH_ORIF_EXPR
)
2420 walk_result (e
->ops
[i
], cond_p
, result
);
2423 else if (if_expr
*ie
= dyn_cast
<if_expr
*> (o
))
2425 /* 'if' conditions should be all fine. */
2426 if (ie
->trueexpr
== result
)
2428 walk_result (ie
->trueexpr
, false, result
);
2431 if (ie
->falseexpr
== result
)
2433 walk_result (ie
->falseexpr
, false, result
);
2437 if (is_a
<if_expr
*> (ie
->trueexpr
)
2438 || is_a
<with_expr
*> (ie
->trueexpr
))
2439 res
|= walk_result (ie
->trueexpr
, false, result
);
2441 && (is_a
<if_expr
*> (ie
->falseexpr
)
2442 || is_a
<with_expr
*> (ie
->falseexpr
)))
2443 res
|= walk_result (ie
->falseexpr
, false, result
);
2446 else if (with_expr
*we
= dyn_cast
<with_expr
*> (o
))
2448 bool res
= (we
->subexpr
== result
);
2450 || is_a
<if_expr
*> (we
->subexpr
)
2451 || is_a
<with_expr
*> (we
->subexpr
))
2452 res
|= walk_result (we
->subexpr
, false, result
);
2454 walk_c_expr (we
->with
);
2457 else if (c_expr
*ce
= dyn_cast
<c_expr
*> (o
))
2465 /* Look for captures in the C expr E. */
2468 capture_info::walk_c_expr (c_expr
*e
)
2470 /* Give up for C exprs mentioning captures not inside TREE_TYPE,
2471 TREE_REAL_CST, TREE_CODE or a predicate where they cannot
2472 really escape through. */
2473 unsigned p_depth
= 0;
2474 for (unsigned i
= 0; i
< e
->code
.length (); ++i
)
2476 const cpp_token
*t
= &e
->code
[i
];
2477 const cpp_token
*n
= i
< e
->code
.length () - 1 ? &e
->code
[i
+1] : NULL
;
2479 if (t
->type
== CPP_NAME
2480 && (strcmp ((const char *)CPP_HASHNODE
2481 (t
->val
.node
.node
)->ident
.str
, "TREE_TYPE") == 0
2482 || strcmp ((const char *)CPP_HASHNODE
2483 (t
->val
.node
.node
)->ident
.str
, "TREE_CODE") == 0
2484 || strcmp ((const char *)CPP_HASHNODE
2485 (t
->val
.node
.node
)->ident
.str
, "TREE_REAL_CST") == 0
2486 || ((id
= get_operator ((const char *)CPP_HASHNODE
2487 (t
->val
.node
.node
)->ident
.str
))
2488 && is_a
<predicate_id
*> (id
)))
2489 && n
->type
== CPP_OPEN_PAREN
)
2491 else if (t
->type
== CPP_CLOSE_PAREN
2494 else if (p_depth
== 0
2495 && t
->type
== CPP_ATSIGN
2496 && (n
->type
== CPP_NUMBER
2497 || n
->type
== CPP_NAME
)
2498 && !(n
->flags
& PREV_WHITE
))
2501 if (n
->type
== CPP_NUMBER
)
2502 id1
= (const char *)n
->val
.str
.text
;
2504 id1
= (const char *)CPP_HASHNODE (n
->val
.node
.node
)->ident
.str
;
2505 unsigned *where
= e
->capture_ids
->get(id1
);
2507 fatal_at (n
, "unknown capture id '%s'", id1
);
2508 info
[info
[*where
].same_as
].force_no_side_effects_p
= true;
2511 warning_at (t
, "capture escapes");
2517 /* The current label failing the current matched pattern during
2519 static char *fail_label
;
2521 /* Code generation off the decision tree and the refered AST nodes. */
2524 is_conversion (id_base
*op
)
2526 return (*op
== CONVERT_EXPR
2528 || *op
== FLOAT_EXPR
2529 || *op
== FIX_TRUNC_EXPR
2530 || *op
== VIEW_CONVERT_EXPR
);
2533 /* Get the type to be used for generating operand POS of OP from the
2537 get_operand_type (id_base
*op
, unsigned pos
,
2538 const char *in_type
,
2539 const char *expr_type
,
2540 const char *other_oprnd_type
)
2542 /* Generally operands whose type does not match the type of the
2543 expression generated need to know their types but match and
2544 thus can fall back to 'other_oprnd_type'. */
2545 if (is_conversion (op
))
2546 return other_oprnd_type
;
2547 else if (*op
== REALPART_EXPR
2548 || *op
== IMAGPART_EXPR
)
2549 return other_oprnd_type
;
2550 else if (is_a
<operator_id
*> (op
)
2551 && strcmp (as_a
<operator_id
*> (op
)->tcc
, "tcc_comparison") == 0)
2552 return other_oprnd_type
;
2553 else if (*op
== COND_EXPR
2555 return "boolean_type_node";
2556 else if (startswith (op
->id
, "CFN_COND_"))
2558 /* IFN_COND_* operands 1 and later by default have the same type
2559 as the result. The type of operand 0 needs to be specified
2561 if (pos
> 0 && expr_type
)
2563 else if (pos
> 0 && in_type
)
2570 /* Otherwise all types should match - choose one in order of
2577 return other_oprnd_type
;
2581 /* Generate transform code for an expression. */
2584 expr::gen_transform (FILE *f
, int indent
, const char *dest
, bool gimple
,
2585 int depth
, const char *in_type
, capture_info
*cinfo
,
2586 dt_operand
**indexes
, int)
2588 id_base
*opr
= operation
;
2589 /* When we delay operator substituting during lowering of fors we
2590 make sure that for code-gen purposes the effects of each substitute
2591 are the same. Thus just look at that. */
2592 if (user_id
*uid
= dyn_cast
<user_id
*> (opr
))
2593 opr
= uid
->substitutes
[0];
2595 bool conversion_p
= is_conversion (opr
);
2596 const char *type
= expr_type
;
2599 /* If there was a type specification in the pattern use it. */
2601 else if (conversion_p
)
2602 /* For conversions we need to build the expression using the
2603 outer type passed in. */
2605 else if (*opr
== REALPART_EXPR
2606 || *opr
== IMAGPART_EXPR
)
2608 /* __real and __imag use the component type of its operand. */
2609 snprintf (optype
, sizeof (optype
), "TREE_TYPE (TREE_TYPE (_o%d[0]))",
2613 else if (is_a
<operator_id
*> (opr
)
2614 && !strcmp (as_a
<operator_id
*> (opr
)->tcc
, "tcc_comparison"))
2616 /* comparisons use boolean_type_node (or what gets in), but
2617 their operands need to figure out the types themselves. */
2622 snprintf (optype
, sizeof (optype
), "boolean_type_node");
2627 else if (*opr
== COND_EXPR
2628 || *opr
== VEC_COND_EXPR
2629 || startswith (opr
->id
, "CFN_COND_"))
2631 /* Conditions are of the same type as their first alternative. */
2632 snprintf (optype
, sizeof (optype
), "TREE_TYPE (_o%d[1])", depth
);
2637 /* Other operations are of the same type as their first operand. */
2638 snprintf (optype
, sizeof (optype
), "TREE_TYPE (_o%d[0])", depth
);
2642 fatal_at (location
, "cannot determine type of operand");
2644 fprintf_indent (f
, indent
, "{\n");
2646 fprintf_indent (f
, indent
,
2647 "tree _o%d[%u], _r%d;\n", depth
, ops
.length (), depth
);
2649 snprintf (op0type
, sizeof (op0type
), "TREE_TYPE (_o%d[0])", depth
);
2650 for (unsigned i
= 0; i
< ops
.length (); ++i
)
2653 snprintf (dest1
, sizeof (dest1
), "_o%d[%u]", depth
, i
);
2655 = get_operand_type (opr
, i
, in_type
, expr_type
,
2656 i
== 0 ? NULL
: op0type
);
2657 ops
[i
]->gen_transform (f
, indent
, dest1
, gimple
, depth
+ 1, optype1
,
2659 *opr
== COND_EXPR
&& i
== 0 ? 1 : 2);
2662 const char *opr_name
;
2663 if (*operation
== CONVERT_EXPR
)
2664 opr_name
= "NOP_EXPR";
2666 opr_name
= operation
->id
;
2670 if (*opr
== CONVERT_EXPR
)
2672 fprintf_indent (f
, indent
,
2673 "if (%s != TREE_TYPE (_o%d[0])\n",
2675 fprintf_indent (f
, indent
,
2676 " && !useless_type_conversion_p (%s, TREE_TYPE "
2679 fprintf_indent (f
, indent
+ 2, "{\n");
2682 /* ??? Building a stmt can fail for various reasons here, seq being
2683 NULL or the stmt referencing SSA names occuring in abnormal PHIs.
2684 So if we fail here we should continue matching other patterns. */
2685 fprintf_indent (f
, indent
, "gimple_match_op tem_op "
2686 "(res_op->cond.any_else (), %s, %s", opr_name
, type
);
2687 for (unsigned i
= 0; i
< ops
.length (); ++i
)
2688 fprintf (f
, ", _o%d[%u]", depth
, i
);
2689 fprintf (f
, ");\n");
2690 fprintf_indent (f
, indent
, "tem_op.resimplify (%s, valueize);\n",
2691 !force_leaf
? "lseq" : "NULL");
2692 fprintf_indent (f
, indent
,
2693 "_r%d = maybe_push_res_to_seq (&tem_op, %s);\n", depth
,
2694 !force_leaf
? "lseq" : "NULL");
2695 fprintf_indent (f
, indent
,
2696 "if (!_r%d) goto %s;\n",
2698 if (*opr
== CONVERT_EXPR
)
2701 fprintf_indent (f
, indent
, " }\n");
2702 fprintf_indent (f
, indent
, "else\n");
2703 fprintf_indent (f
, indent
, " _r%d = _o%d[0];\n", depth
, depth
);
2708 if (*opr
== CONVERT_EXPR
)
2710 fprintf_indent (f
, indent
, "if (TREE_TYPE (_o%d[0]) != %s)\n",
2712 fprintf_indent (f
, indent
+ 2, "{\n");
2715 if (opr
->kind
== id_base::CODE
)
2716 fprintf_indent (f
, indent
, "_r%d = fold_build%d_loc (loc, %s, %s",
2717 depth
, ops
.length(), opr_name
, type
);
2719 fprintf_indent (f
, indent
, "_r%d = maybe_build_call_expr_loc (loc, "
2720 "%s, %s, %d", depth
, opr_name
, type
, ops
.length());
2721 for (unsigned i
= 0; i
< ops
.length (); ++i
)
2722 fprintf (f
, ", _o%d[%u]", depth
, i
);
2723 fprintf (f
, ");\n");
2724 if (opr
->kind
!= id_base::CODE
)
2726 fprintf_indent (f
, indent
, "if (!_r%d)\n", depth
);
2727 fprintf_indent (f
, indent
, " goto %s;\n", fail_label
);
2731 fprintf_indent (f
, indent
, "if (EXPR_P (_r%d))\n", depth
);
2732 fprintf_indent (f
, indent
, " goto %s;\n", fail_label
);
2734 if (*opr
== CONVERT_EXPR
)
2736 fprintf_indent (f
, indent
- 2, "}\n");
2738 fprintf_indent (f
, indent
, "else\n");
2739 fprintf_indent (f
, indent
, " _r%d = _o%d[0];\n", depth
, depth
);
2742 fprintf_indent (f
, indent
, "%s = _r%d;\n", dest
, depth
);
2744 fprintf_indent (f
, indent
, "}\n");
2747 /* Generate code for a c_expr which is either the expression inside
2748 an if statement or a sequence of statements which computes a
2749 result to be stored to DEST. */
2752 c_expr::gen_transform (FILE *f
, int indent
, const char *dest
,
2753 bool, int, const char *, capture_info
*,
2756 if (dest
&& nr_stmts
== 1)
2757 fprintf_indent (f
, indent
, "%s = ", dest
);
2759 unsigned stmt_nr
= 1;
2761 for (unsigned i
= 0; i
< code
.length (); ++i
)
2763 const cpp_token
*token
= &code
[i
];
2765 /* We can't recover from all lexing losses but we can roughly restore line
2766 breaks from location info. */
2767 const line_map_ordinary
*map
;
2768 linemap_resolve_location (line_table
, token
->src_loc
,
2769 LRK_SPELLING_LOCATION
, &map
);
2770 expanded_location loc
= linemap_expand_location (line_table
, map
,
2772 if (prev_line
!= -1 && loc
.line
!= prev_line
)
2774 prev_line
= loc
.line
;
2776 /* Replace captures for code-gen. */
2777 if (token
->type
== CPP_ATSIGN
)
2779 const cpp_token
*n
= &code
[i
+1];
2780 if ((n
->type
== CPP_NUMBER
2781 || n
->type
== CPP_NAME
)
2782 && !(n
->flags
& PREV_WHITE
))
2784 if (token
->flags
& PREV_WHITE
)
2787 if (n
->type
== CPP_NUMBER
)
2788 id
= (const char *)n
->val
.str
.text
;
2790 id
= (const char *)CPP_HASHNODE (n
->val
.node
.node
)->ident
.str
;
2791 unsigned *cid
= capture_ids
->get (id
);
2793 fatal_at (token
, "unknown capture id");
2794 fprintf (f
, "captures[%u]", *cid
);
2800 if (token
->flags
& PREV_WHITE
)
2803 if (token
->type
== CPP_NAME
)
2805 const char *id
= (const char *) NODE_NAME (token
->val
.node
.node
);
2807 for (j
= 0; j
< ids
.length (); ++j
)
2809 if (strcmp (id
, ids
[j
].id
) == 0)
2811 fprintf (f
, "%s", ids
[j
].oper
);
2815 if (j
< ids
.length ())
2819 /* Output the token as string. */
2820 char *tk
= (char *)cpp_token_as_text (r
, token
);
2823 if (token
->type
== CPP_SEMICOLON
)
2826 if (dest
&& stmt_nr
== nr_stmts
)
2827 fprintf_indent (f
, indent
, "%s = ", dest
);
2833 /* Generate transform code for a capture. */
2836 capture::gen_transform (FILE *f
, int indent
, const char *dest
, bool gimple
,
2837 int depth
, const char *in_type
, capture_info
*cinfo
,
2838 dt_operand
**indexes
, int cond_handling
)
2840 if (what
&& is_a
<expr
*> (what
))
2842 if (indexes
[where
] == 0)
2845 snprintf (buf
, sizeof (buf
), "captures[%u]", where
);
2846 what
->gen_transform (f
, indent
, buf
, gimple
, depth
, in_type
,
2851 /* If in GENERIC some capture is used multiple times, unshare it except
2852 when emitting the last use. */
2854 && cinfo
->info
.exists ()
2855 && cinfo
->info
[cinfo
->info
[where
].same_as
].result_use_count
> 1)
2857 fprintf_indent (f
, indent
, "%s = unshare_expr (captures[%u]);\n",
2859 cinfo
->info
[cinfo
->info
[where
].same_as
].result_use_count
--;
2862 fprintf_indent (f
, indent
, "%s = captures[%u];\n", dest
, where
);
2864 /* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal
2865 with substituting a capture of that. */
2867 && cond_handling
!= 0
2868 && cinfo
->info
[where
].cond_expr_cond_p
)
2870 /* If substituting into a cond_expr condition, unshare. */
2871 if (cond_handling
== 1)
2872 fprintf_indent (f
, indent
, "%s = unshare_expr (%s);\n", dest
, dest
);
2873 /* If substituting elsewhere we might need to decompose it. */
2874 else if (cond_handling
== 2)
2876 /* ??? Returning false here will also not allow any other patterns
2877 to match unless this generator was split out. */
2878 fprintf_indent (f
, indent
, "if (COMPARISON_CLASS_P (%s))\n", dest
);
2879 fprintf_indent (f
, indent
, " {\n");
2880 fprintf_indent (f
, indent
, " if (!seq) return false;\n");
2881 fprintf_indent (f
, indent
, " %s = gimple_build (seq,"
2883 " TREE_TYPE (%s), TREE_OPERAND (%s, 0),"
2884 " TREE_OPERAND (%s, 1));\n",
2885 dest
, dest
, dest
, dest
, dest
);
2886 fprintf_indent (f
, indent
, " }\n");
2891 /* Return the name of the operand representing the decision tree node.
2892 Use NAME as space to generate it. */
2895 dt_operand::get_name (char *name
)
2898 sprintf (name
, "t");
2899 else if (parent
->level
== 1)
2900 sprintf (name
, "_p%u", pos
);
2901 else if (parent
->type
== dt_node::DT_MATCH
)
2902 return as_a
<dt_operand
*> (parent
)->get_name (name
);
2904 sprintf (name
, "_q%u%u", parent
->level
, pos
);
2908 /* Fill NAME with the operand name at position POS. */
2911 dt_operand::gen_opname (char *name
, unsigned pos
)
2914 sprintf (name
, "_p%u", pos
);
2916 sprintf (name
, "_q%u%u", level
, pos
);
2919 /* Generate matching code for the decision tree operand which is
2923 dt_operand::gen_predicate (FILE *f
, int indent
, const char *opname
, bool gimple
)
2925 predicate
*p
= as_a
<predicate
*> (op
);
2927 if (p
->p
->matchers
.exists ())
2929 /* If this is a predicate generated from a pattern mangle its
2930 name and pass on the valueize hook. */
2932 fprintf_indent (f
, indent
, "if (gimple_%s (%s, valueize))\n",
2935 fprintf_indent (f
, indent
, "if (tree_%s (%s))\n", p
->p
->id
, opname
);
2938 fprintf_indent (f
, indent
, "if (%s (%s))\n", p
->p
->id
, opname
);
2939 fprintf_indent (f
, indent
+ 2, "{\n");
2943 /* Generate matching code for the decision tree operand which is
2947 dt_operand::gen_match_op (FILE *f
, int indent
, const char *opname
, bool)
2949 char match_opname
[20];
2950 match_dop
->get_name (match_opname
);
2952 fprintf_indent (f
, indent
, "if ((%s == %s && ! TREE_SIDE_EFFECTS (%s)) "
2953 "|| operand_equal_p (%s, %s, 0))\n",
2954 opname
, match_opname
, opname
, opname
, match_opname
);
2956 fprintf_indent (f
, indent
, "if ((%s == %s && ! TREE_SIDE_EFFECTS (%s)) "
2957 "|| (operand_equal_p (%s, %s, 0) "
2958 "&& types_match (%s, %s)))\n",
2959 opname
, match_opname
, opname
, opname
, match_opname
,
2960 opname
, match_opname
);
2961 fprintf_indent (f
, indent
+ 2, "{\n");
2965 /* Generate GIMPLE matching code for the decision tree operand. */
2968 dt_operand::gen_gimple_expr (FILE *f
, int indent
, int depth
)
2970 expr
*e
= static_cast<expr
*> (op
);
2971 id_base
*id
= e
->operation
;
2972 unsigned n_ops
= e
->ops
.length ();
2973 unsigned n_braces
= 0;
2975 if (user_id
*u
= dyn_cast
<user_id
*> (id
))
2976 id
= u
->substitutes
[0];
2978 for (unsigned i
= 0; i
< n_ops
; ++i
)
2980 char child_opname
[20];
2981 gen_opname (child_opname
, i
);
2983 if (id
->kind
== id_base::CODE
)
2986 || *id
== REALPART_EXPR
|| *id
== IMAGPART_EXPR
2987 || *id
== BIT_FIELD_REF
|| *id
== VIEW_CONVERT_EXPR
)
2989 /* ??? If this is a memory operation we can't (and should not)
2990 match this. The only sensible operand types are
2991 SSA names and invariants. */
2996 fprintf_indent (f
, indent
,
2997 "tree %s = TREE_OPERAND (%s, %i);\n",
2998 child_opname
, opname
, i
);
3001 fprintf_indent (f
, indent
,
3002 "tree %s = TREE_OPERAND "
3003 "(gimple_assign_rhs1 (_a%d), %i);\n",
3004 child_opname
, depth
, i
);
3005 fprintf_indent (f
, indent
,
3006 "if ((TREE_CODE (%s) == SSA_NAME\n",
3008 fprintf_indent (f
, indent
,
3009 " || is_gimple_min_invariant (%s)))\n",
3011 fprintf_indent (f
, indent
,
3015 fprintf_indent (f
, indent
,
3016 "%s = do_valueize (valueize, %s);\n",
3017 child_opname
, child_opname
);
3021 fprintf_indent (f
, indent
,
3022 "tree %s = gimple_assign_rhs%u (_a%d);\n",
3023 child_opname
, i
+ 1, depth
);
3026 fprintf_indent (f
, indent
,
3027 "tree %s = gimple_call_arg (_c%d, %u);\n",
3028 child_opname
, depth
, i
);
3029 fprintf_indent (f
, indent
,
3030 "%s = do_valueize (valueize, %s);\n",
3031 child_opname
, child_opname
);
3033 /* While the toplevel operands are canonicalized by the caller
3034 after valueizing operands of sub-expressions we have to
3035 re-canonicalize operand order. */
3036 int opno
= commutative_op (id
);
3039 char child_opname0
[20], child_opname1
[20];
3040 gen_opname (child_opname0
, opno
);
3041 gen_opname (child_opname1
, opno
+ 1);
3042 fprintf_indent (f
, indent
,
3043 "if (tree_swap_operands_p (%s, %s))\n",
3044 child_opname0
, child_opname1
);
3045 fprintf_indent (f
, indent
,
3046 " std::swap (%s, %s);\n",
3047 child_opname0
, child_opname1
);
3053 /* Generate GENERIC matching code for the decision tree operand. */
3056 dt_operand::gen_generic_expr (FILE *f
, int indent
, const char *opname
)
3058 expr
*e
= static_cast<expr
*> (op
);
3059 id_base
*id
= e
->operation
;
3060 unsigned n_ops
= e
->ops
.length ();
3062 if (user_id
*u
= dyn_cast
<user_id
*> (id
))
3063 id
= u
->substitutes
[0];
3065 for (unsigned i
= 0; i
< n_ops
; ++i
)
3067 char child_opname
[20];
3068 gen_opname (child_opname
, i
);
3070 if (id
->kind
== id_base::CODE
)
3071 fprintf_indent (f
, indent
, "tree %s = TREE_OPERAND (%s, %u);\n",
3072 child_opname
, opname
, i
);
3074 fprintf_indent (f
, indent
, "tree %s = CALL_EXPR_ARG (%s, %u);\n",
3075 child_opname
, opname
, i
);
3081 /* Compare 2 fns or generic_fns vector entries for vector sorting.
3082 Same operation entries with different number of arguments should
3086 fns_cmp (const void *p1
, const void *p2
)
3088 dt_operand
*op1
= *(dt_operand
*const *) p1
;
3089 dt_operand
*op2
= *(dt_operand
*const *) p2
;
3090 expr
*e1
= as_a
<expr
*> (op1
->op
);
3091 expr
*e2
= as_a
<expr
*> (op2
->op
);
3092 id_base
*b1
= e1
->operation
;
3093 id_base
*b2
= e2
->operation
;
3094 if (b1
->hashval
< b2
->hashval
)
3096 if (b1
->hashval
> b2
->hashval
)
3098 return strcmp (b1
->id
, b2
->id
);
3101 /* Generate matching code for the children of the decision tree node. */
3104 dt_node::gen_kids (FILE *f
, int indent
, bool gimple
, int depth
)
3106 auto_vec
<dt_operand
*> gimple_exprs
;
3107 auto_vec
<dt_operand
*> generic_exprs
;
3108 auto_vec
<dt_operand
*> fns
;
3109 auto_vec
<dt_operand
*> generic_fns
;
3110 auto_vec
<dt_operand
*> preds
;
3111 auto_vec
<dt_node
*> others
;
3113 for (unsigned i
= 0; i
< kids
.length (); ++i
)
3115 if (kids
[i
]->type
== dt_node::DT_OPERAND
)
3117 dt_operand
*op
= as_a
<dt_operand
*> (kids
[i
]);
3118 if (expr
*e
= dyn_cast
<expr
*> (op
->op
))
3120 if (e
->ops
.length () == 0
3121 /* In GIMPLE a CONSTRUCTOR always appears in a
3122 separate definition. */
3123 && (!gimple
|| !(*e
->operation
== CONSTRUCTOR
)))
3125 generic_exprs
.safe_push (op
);
3126 /* But ADDR_EXPRs can appear directly when invariant
3127 and in a separate definition when not. */
3128 if (gimple
&& *e
->operation
== ADDR_EXPR
)
3129 gimple_exprs
.safe_push (op
);
3131 else if (e
->operation
->kind
== id_base::FN
)
3136 generic_fns
.safe_push (op
);
3138 else if (e
->operation
->kind
== id_base::PREDICATE
)
3139 preds
.safe_push (op
);
3142 user_id
*u
= dyn_cast
<user_id
*> (e
->operation
);
3143 if (u
&& u
->substitutes
[0]->kind
== id_base::FN
)
3148 generic_fns
.safe_push (op
);
3152 if (gimple
&& !e
->is_generic
)
3153 gimple_exprs
.safe_push (op
);
3155 generic_exprs
.safe_push (op
);
3159 else if (op
->op
->type
== operand::OP_PREDICATE
)
3160 others
.safe_push (kids
[i
]);
3164 else if (kids
[i
]->type
== dt_node::DT_SIMPLIFY
)
3165 others
.safe_push (kids
[i
]);
3166 else if (kids
[i
]->type
== dt_node::DT_MATCH
3167 || kids
[i
]->type
== dt_node::DT_TRUE
)
3169 /* A DT_TRUE operand serves as a barrier - generate code now
3170 for what we have collected sofar.
3171 Like DT_TRUE, DT_MATCH serves as a barrier as it can cause
3172 dependent matches to get out-of-order. Generate code now
3173 for what we have collected sofar. */
3174 fns
.qsort (fns_cmp
);
3175 generic_fns
.qsort (fns_cmp
);
3176 gen_kids_1 (f
, indent
, gimple
, depth
, gimple_exprs
, generic_exprs
,
3177 fns
, generic_fns
, preds
, others
);
3178 /* And output the true operand itself. */
3179 kids
[i
]->gen (f
, indent
, gimple
, depth
);
3180 gimple_exprs
.truncate (0);
3181 generic_exprs
.truncate (0);
3183 generic_fns
.truncate (0);
3185 others
.truncate (0);
3191 /* Generate code for the remains. */
3192 fns
.qsort (fns_cmp
);
3193 generic_fns
.qsort (fns_cmp
);
3194 gen_kids_1 (f
, indent
, gimple
, depth
, gimple_exprs
, generic_exprs
,
3195 fns
, generic_fns
, preds
, others
);
3198 /* Generate matching code for the children of the decision tree node. */
3201 dt_node::gen_kids_1 (FILE *f
, int indent
, bool gimple
, int depth
,
3202 const vec
<dt_operand
*> &gimple_exprs
,
3203 const vec
<dt_operand
*> &generic_exprs
,
3204 const vec
<dt_operand
*> &fns
,
3205 const vec
<dt_operand
*> &generic_fns
,
3206 const vec
<dt_operand
*> &preds
,
3207 const vec
<dt_node
*> &others
)
3210 char *kid_opname
= buf
;
3212 unsigned exprs_len
= gimple_exprs
.length ();
3213 unsigned gexprs_len
= generic_exprs
.length ();
3214 unsigned fns_len
= fns
.length ();
3215 unsigned gfns_len
= generic_fns
.length ();
3217 if (exprs_len
|| fns_len
|| gexprs_len
|| gfns_len
)
3220 gimple_exprs
[0]->get_name (kid_opname
);
3222 fns
[0]->get_name (kid_opname
);
3224 generic_fns
[0]->get_name (kid_opname
);
3226 generic_exprs
[0]->get_name (kid_opname
);
3228 fprintf_indent (f
, indent
, "switch (TREE_CODE (%s))\n", kid_opname
);
3229 fprintf_indent (f
, indent
, " {\n");
3233 if (exprs_len
|| fns_len
)
3236 fprintf_indent (f
, indent
,
3237 "case SSA_NAME:\n");
3238 fprintf_indent (f
, indent
,
3239 " if (gimple *_d%d = get_def (valueize, %s))\n",
3241 fprintf_indent (f
, indent
,
3246 fprintf_indent (f
, indent
,
3247 "if (gassign *_a%d = dyn_cast <gassign *> (_d%d))\n",
3249 fprintf_indent (f
, indent
,
3250 " switch (gimple_assign_rhs_code (_a%d))\n",
3253 fprintf_indent (f
, indent
, "{\n");
3254 for (unsigned i
= 0; i
< exprs_len
; ++i
)
3256 expr
*e
= as_a
<expr
*> (gimple_exprs
[i
]->op
);
3257 if (user_id
*u
= dyn_cast
<user_id
*> (e
->operation
))
3259 for (auto id
: u
->substitutes
)
3260 fprintf_indent (f
, indent
, "case %s:\n", id
->id
);
3264 id_base
*op
= e
->operation
;
3265 if (*op
== CONVERT_EXPR
|| *op
== NOP_EXPR
)
3266 fprintf_indent (f
, indent
, "CASE_CONVERT:\n");
3268 fprintf_indent (f
, indent
, "case %s:\n", op
->id
);
3270 fprintf_indent (f
, indent
, " {\n");
3271 gimple_exprs
[i
]->gen (f
, indent
+ 4, true, depth
);
3272 fprintf_indent (f
, indent
, " break;\n");
3273 fprintf_indent (f
, indent
, " }\n");
3275 fprintf_indent (f
, indent
, "default:;\n");
3276 fprintf_indent (f
, indent
, "}\n");
3282 fprintf_indent (f
, indent
,
3283 "%sif (gcall *_c%d = dyn_cast <gcall *> (_d%d))\n",
3284 exprs_len
? "else " : "", depth
, depth
);
3285 fprintf_indent (f
, indent
,
3286 " switch (gimple_call_combined_fn (_c%d))\n",
3290 fprintf_indent (f
, indent
, "{\n");
3291 id_base
*last_op
= NULL
;
3292 for (unsigned i
= 0; i
< fns_len
; ++i
)
3294 expr
*e
= as_a
<expr
*>(fns
[i
]->op
);
3295 if (e
->operation
!= last_op
)
3298 fprintf_indent (f
, indent
, " break;\n");
3299 if (user_id
*u
= dyn_cast
<user_id
*> (e
->operation
))
3300 for (auto id
: u
->substitutes
)
3301 fprintf_indent (f
, indent
, "case %s:\n", id
->id
);
3303 fprintf_indent (f
, indent
, "case %s:\n", e
->operation
->id
);
3305 last_op
= e
->operation
;
3306 /* We need to be defensive against bogus prototypes allowing
3307 calls with not enough arguments. */
3308 fprintf_indent (f
, indent
,
3309 " if (gimple_call_num_args (_c%d) == %d)\n",
3310 depth
, e
->ops
.length ());
3311 fprintf_indent (f
, indent
, " {\n");
3312 fns
[i
]->gen (f
, indent
+ 6, true, depth
);
3313 fprintf_indent (f
, indent
, " }\n");
3316 fprintf_indent (f
, indent
, " break;\n");
3317 fprintf_indent (f
, indent
, "default:;\n");
3318 fprintf_indent (f
, indent
, "}\n");
3324 fprintf_indent (f
, indent
, " }\n");
3325 /* See if there is SSA_NAME among generic_exprs and if yes, emit it
3326 here rather than in the next loop. */
3327 for (unsigned i
= 0; i
< generic_exprs
.length (); ++i
)
3329 expr
*e
= as_a
<expr
*>(generic_exprs
[i
]->op
);
3330 id_base
*op
= e
->operation
;
3331 if (*op
== SSA_NAME
&& (exprs_len
|| fns_len
))
3333 fprintf_indent (f
, indent
+ 4, "{\n");
3334 generic_exprs
[i
]->gen (f
, indent
+ 6, gimple
, depth
);
3335 fprintf_indent (f
, indent
+ 4, "}\n");
3339 fprintf_indent (f
, indent
, " break;\n");
3342 for (unsigned i
= 0; i
< generic_exprs
.length (); ++i
)
3344 expr
*e
= as_a
<expr
*>(generic_exprs
[i
]->op
);
3345 id_base
*op
= e
->operation
;
3346 if (*op
== CONVERT_EXPR
|| *op
== NOP_EXPR
)
3347 fprintf_indent (f
, indent
, "CASE_CONVERT:\n");
3348 else if (*op
== SSA_NAME
&& (exprs_len
|| fns_len
))
3349 /* Already handled above. */
3353 if (user_id
*u
= dyn_cast
<user_id
*> (op
))
3354 for (auto id
: u
->substitutes
)
3355 fprintf_indent (f
, indent
, "case %s:\n", id
->id
);
3357 fprintf_indent (f
, indent
, "case %s:\n", op
->id
);
3359 fprintf_indent (f
, indent
, " {\n");
3360 generic_exprs
[i
]->gen (f
, indent
+ 4, gimple
, depth
);
3361 fprintf_indent (f
, indent
, " break;\n");
3362 fprintf_indent (f
, indent
, " }\n");
3367 fprintf_indent (f
, indent
,
3368 "case CALL_EXPR:\n");
3369 fprintf_indent (f
, indent
,
3370 " switch (get_call_combined_fn (%s))\n",
3372 fprintf_indent (f
, indent
,
3376 id_base
*last_op
= NULL
;
3377 for (unsigned j
= 0; j
< generic_fns
.length (); ++j
)
3379 expr
*e
= as_a
<expr
*>(generic_fns
[j
]->op
);
3380 gcc_assert (e
->operation
->kind
== id_base::FN
);
3382 if (e
->operation
!= last_op
)
3385 fprintf_indent (f
, indent
, " break;\n");
3386 fprintf_indent (f
, indent
, "case %s:\n", e
->operation
->id
);
3388 last_op
= e
->operation
;
3389 fprintf_indent (f
, indent
, " if (call_expr_nargs (%s) == %d)\n"
3390 " {\n", kid_opname
, e
->ops
.length ());
3391 generic_fns
[j
]->gen (f
, indent
+ 6, false, depth
);
3392 fprintf_indent (f
, indent
, " }\n");
3394 fprintf_indent (f
, indent
, " break;\n");
3395 fprintf_indent (f
, indent
, "default:;\n");
3398 fprintf_indent (f
, indent
, " }\n");
3399 fprintf_indent (f
, indent
, " break;\n");
3402 /* Close switch (TREE_CODE ()). */
3403 if (exprs_len
|| fns_len
|| gexprs_len
|| gfns_len
)
3406 fprintf_indent (f
, indent
, " default:;\n");
3407 fprintf_indent (f
, indent
, " }\n");
3410 for (unsigned i
= 0; i
< preds
.length (); ++i
)
3412 expr
*e
= as_a
<expr
*> (preds
[i
]->op
);
3413 predicate_id
*p
= as_a
<predicate_id
*> (e
->operation
);
3414 preds
[i
]->get_name (kid_opname
);
3415 fprintf_indent (f
, indent
, "{\n");
3417 fprintf_indent (f
, indent
, "tree %s_pops[%d];\n", kid_opname
, p
->nargs
);
3418 fprintf_indent (f
, indent
, "if (%s_%s (%s, %s_pops%s))\n",
3419 gimple
? "gimple" : "tree",
3420 p
->id
, kid_opname
, kid_opname
,
3421 gimple
? ", valueize" : "");
3422 fprintf_indent (f
, indent
, " {\n");
3423 for (int j
= 0; j
< p
->nargs
; ++j
)
3425 char child_opname
[20];
3426 preds
[i
]->gen_opname (child_opname
, j
);
3427 fprintf_indent (f
, indent
+ 4, "tree %s = %s_pops[%d];\n",
3428 child_opname
, kid_opname
, j
);
3430 preds
[i
]->gen_kids (f
, indent
+ 4, gimple
, depth
);
3433 fprintf_indent (f
, indent
, "}\n");
3436 for (unsigned i
= 0; i
< others
.length (); ++i
)
3437 others
[i
]->gen (f
, indent
, gimple
, depth
);
3440 /* Generate matching code for the decision tree operand. */
3443 dt_operand::gen (FILE *f
, int indent
, bool gimple
, int depth
)
3448 unsigned n_braces
= 0;
3450 if (type
== DT_OPERAND
)
3453 case operand::OP_PREDICATE
:
3454 n_braces
= gen_predicate (f
, indent
, opname
, gimple
);
3457 case operand::OP_EXPR
:
3459 n_braces
= gen_gimple_expr (f
, indent
, depth
);
3461 n_braces
= gen_generic_expr (f
, indent
, opname
);
3467 else if (type
== DT_TRUE
)
3469 else if (type
== DT_MATCH
)
3470 n_braces
= gen_match_op (f
, indent
, opname
, gimple
);
3474 indent
+= 4 * n_braces
;
3475 gen_kids (f
, indent
, gimple
, depth
);
3477 for (unsigned i
= 0; i
< n_braces
; ++i
)
3482 fprintf_indent (f
, indent
, " }\n");
3486 /* Emit a logging call to the debug file to the file F, with the INDENT from
3487 either the RESULT location or the S's match location if RESULT is null. */
3489 emit_logging_call (FILE *f
, int indent
, class simplify
*s
, operand
*result
,
3492 fprintf_indent (f
, indent
, "if (UNLIKELY (debug_dump)) "
3493 "%s_dump_logs (", gimple
? "gimple" : "generic");
3494 output_line_directive (f
,
3495 result
? result
->location
: s
->match
->location
,
3497 fprintf (f
, ", __FILE__, __LINE__, %s);\n",
3498 s
->kind
== simplify::SIMPLIFY
? "true" : "false");
3501 /* Generate code for the '(if ...)', '(with ..)' and actual transform
3502 step of a '(simplify ...)' or '(match ...)'. This handles everything
3503 that is not part of the decision tree (simplify->match).
3504 Main recursive worker. */
3507 dt_simplify::gen_1 (FILE *f
, int indent
, bool gimple
, operand
*result
)
3511 if (with_expr
*w
= dyn_cast
<with_expr
*> (result
))
3513 fprintf_indent (f
, indent
, "{\n");
3515 output_line_directive (f
, w
->location
);
3516 w
->with
->gen_transform (f
, indent
, NULL
, true, 1, "type", NULL
);
3517 gen_1 (f
, indent
, gimple
, w
->subexpr
);
3519 fprintf_indent (f
, indent
, "}\n");
3522 else if (if_expr
*ife
= dyn_cast
<if_expr
*> (result
))
3524 output_line_directive (f
, ife
->location
);
3525 fprintf_indent (f
, indent
, "if (");
3526 ife
->cond
->gen_transform (f
, indent
, NULL
, true, 1, "type", NULL
);
3528 fprintf_indent (f
, indent
+ 2, "{\n");
3530 gen_1 (f
, indent
, gimple
, ife
->trueexpr
);
3532 fprintf_indent (f
, indent
+ 2, "}\n");
3535 fprintf_indent (f
, indent
, "else\n");
3536 fprintf_indent (f
, indent
+ 2, "{\n");
3538 gen_1 (f
, indent
, gimple
, ife
->falseexpr
);
3540 fprintf_indent (f
, indent
+ 2, "}\n");
3546 static unsigned fail_label_cnt
;
3547 char local_fail_label
[256];
3548 snprintf (local_fail_label
, 256, "next_after_fail%u", ++fail_label_cnt
);
3549 fail_label
= local_fail_label
;
3550 bool needs_label
= false;
3552 /* Analyze captures and perform early-outs on the incoming arguments
3553 that cover cases we cannot handle. */
3554 capture_info
cinfo (s
, result
, gimple
);
3555 if (s
->kind
== simplify::SIMPLIFY
)
3559 for (unsigned i
= 0; i
< as_a
<expr
*> (s
->match
)->ops
.length (); ++i
)
3560 if (cinfo
.force_no_side_effects
& (1 << i
))
3562 fprintf_indent (f
, indent
,
3563 "if (TREE_SIDE_EFFECTS (_p%d)) goto %s;\n",
3567 warning_at (as_a
<expr
*> (s
->match
)->ops
[i
]->location
,
3568 "forcing toplevel operand to have no "
3571 for (int i
= 0; i
<= s
->capture_max
; ++i
)
3572 if (cinfo
.info
[i
].cse_p
)
3574 else if (cinfo
.info
[i
].force_no_side_effects_p
3575 && (cinfo
.info
[i
].toplevel_msk
3576 & cinfo
.force_no_side_effects
) == 0)
3578 fprintf_indent (f
, indent
,
3579 "if (TREE_SIDE_EFFECTS (captures[%d])) "
3580 "goto %s;\n", i
, fail_label
);
3583 warning_at (cinfo
.info
[i
].c
->location
,
3584 "forcing captured operand to have no "
3587 else if ((cinfo
.info
[i
].toplevel_msk
3588 & cinfo
.force_no_side_effects
) != 0)
3589 /* Mark capture as having no side-effects if we had to verify
3590 that via forced toplevel operand checks. */
3591 cinfo
.info
[i
].force_no_side_effects_p
= true;
3595 /* Force single-use restriction by only allowing simple
3596 results via setting seq to NULL. */
3597 fprintf_indent (f
, indent
, "gimple_seq *lseq = seq;\n");
3598 bool first_p
= true;
3599 for (int i
= 0; i
<= s
->capture_max
; ++i
)
3600 if (cinfo
.info
[i
].force_single_use
)
3604 fprintf_indent (f
, indent
, "if (lseq\n");
3605 fprintf_indent (f
, indent
, " && (");
3611 fprintf_indent (f
, indent
, " || ");
3613 fprintf (f
, "!single_use (captures[%d])", i
);
3617 fprintf (f
, "))\n");
3618 fprintf_indent (f
, indent
, " lseq = NULL;\n");
3623 if (s
->kind
== simplify::SIMPLIFY
)
3625 fprintf_indent (f
, indent
, "if (UNLIKELY (!dbg_cnt (match))) goto %s;\n", fail_label
);
3629 fprintf_indent (f
, indent
, "{\n");
3633 /* If there is no result then this is a predicate implementation. */
3634 emit_logging_call (f
, indent
, s
, result
, gimple
);
3635 fprintf_indent (f
, indent
, "return true;\n");
3639 /* For GIMPLE simply drop NON_LVALUE_EXPR (which only appears
3640 in outermost position). */
3641 if (result
->type
== operand::OP_EXPR
3642 && *as_a
<expr
*> (result
)->operation
== NON_LVALUE_EXPR
)
3643 result
= as_a
<expr
*> (result
)->ops
[0];
3644 if (result
->type
== operand::OP_EXPR
)
3646 expr
*e
= as_a
<expr
*> (result
);
3647 id_base
*opr
= e
->operation
;
3648 bool is_predicate
= false;
3649 /* When we delay operator substituting during lowering of fors we
3650 make sure that for code-gen purposes the effects of each substitute
3651 are the same. Thus just look at that. */
3652 if (user_id
*uid
= dyn_cast
<user_id
*> (opr
))
3653 opr
= uid
->substitutes
[0];
3654 else if (is_a
<predicate_id
*> (opr
))
3655 is_predicate
= true;
3657 fprintf_indent (f
, indent
, "res_op->set_op (%s, type, %d);\n",
3658 *e
->operation
== CONVERT_EXPR
3659 ? "NOP_EXPR" : e
->operation
->id
,
3661 for (unsigned j
= 0; j
< e
->ops
.length (); ++j
)
3665 snprintf (dest
, sizeof (dest
), "res_ops[%d]", j
);
3667 snprintf (dest
, sizeof (dest
), "res_op->ops[%d]", j
);
3669 = get_operand_type (opr
, j
,
3670 "type", e
->expr_type
,
3672 : "TREE_TYPE (res_op->ops[0])");
3673 /* We need to expand GENERIC conditions we captured from
3674 COND_EXPRs and we need to unshare them when substituting
3676 int cond_handling
= 0;
3678 cond_handling
= (*opr
== COND_EXPR
&& j
== 0) ? 1 : 2;
3679 e
->ops
[j
]->gen_transform (f
, indent
, dest
, true, 1, optype
,
3680 &cinfo
, indexes
, cond_handling
);
3683 /* Re-fold the toplevel result. It's basically an embedded
3684 gimple_build w/o actually building the stmt. */
3687 fprintf_indent (f
, indent
,
3688 "res_op->resimplify (%s, valueize);\n",
3689 !e
->force_leaf
? "lseq" : "NULL");
3692 fprintf_indent (f
, indent
,
3693 "if (!maybe_push_res_to_seq (res_op, NULL)) "
3694 "goto %s;\n", fail_label
);
3699 else if (result
->type
== operand::OP_CAPTURE
3700 || result
->type
== operand::OP_C_EXPR
)
3702 fprintf_indent (f
, indent
, "tree tem;\n");
3703 result
->gen_transform (f
, indent
, "tem", true, 1, "type",
3705 fprintf_indent (f
, indent
, "res_op->set_value (tem);\n");
3706 if (is_a
<capture
*> (result
)
3707 && cinfo
.info
[as_a
<capture
*> (result
)->where
].cond_expr_cond_p
)
3709 /* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal
3710 with substituting a capture of that. */
3711 fprintf_indent (f
, indent
,
3712 "if (COMPARISON_CLASS_P (tem))\n");
3713 fprintf_indent (f
, indent
,
3715 fprintf_indent (f
, indent
,
3716 " res_op->ops[0] = TREE_OPERAND (tem, 0);\n");
3717 fprintf_indent (f
, indent
,
3718 " res_op->ops[1] = TREE_OPERAND (tem, 1);\n");
3719 fprintf_indent (f
, indent
,
3725 emit_logging_call (f
, indent
, s
, result
, gimple
);
3726 fprintf_indent (f
, indent
, "return true;\n");
3730 bool is_predicate
= false;
3731 if (result
->type
== operand::OP_EXPR
)
3733 expr
*e
= as_a
<expr
*> (result
);
3734 id_base
*opr
= e
->operation
;
3735 /* When we delay operator substituting during lowering of fors we
3736 make sure that for code-gen purposes the effects of each substitute
3737 are the same. Thus just look at that. */
3738 if (user_id
*uid
= dyn_cast
<user_id
*> (opr
))
3739 opr
= uid
->substitutes
[0];
3740 else if (is_a
<predicate_id
*> (opr
))
3741 is_predicate
= true;
3742 /* Search for captures used multiple times in the result expression
3743 and wrap them in a SAVE_EXPR. Allow as many uses as in the
3744 original expression. */
3746 for (int i
= 0; i
< s
->capture_max
+ 1; ++i
)
3748 if (cinfo
.info
[i
].same_as
!= (unsigned)i
3749 || cinfo
.info
[i
].cse_p
)
3751 if (cinfo
.info
[i
].result_use_count
3752 > cinfo
.info
[i
].match_use_count
)
3754 fprintf_indent (f
, indent
,
3755 "if (! tree_invariant_p (captures[%d])) "
3756 "goto %s;\n", i
, fail_label
);
3760 for (unsigned j
= 0; j
< e
->ops
.length (); ++j
)
3764 snprintf (dest
, sizeof (dest
), "res_ops[%d]", j
);
3767 fprintf_indent (f
, indent
, "tree res_op%d;\n", j
);
3768 snprintf (dest
, sizeof (dest
), "res_op%d", j
);
3771 = get_operand_type (opr
, j
,
3772 "type", e
->expr_type
,
3774 ? NULL
: "TREE_TYPE (res_op0)");
3775 e
->ops
[j
]->gen_transform (f
, indent
, dest
, false, 1, optype
,
3780 emit_logging_call (f
, indent
, s
, result
, gimple
);
3781 fprintf_indent (f
, indent
, "return true;\n");
3785 fprintf_indent (f
, indent
, "tree _r;\n");
3786 /* Re-fold the toplevel result. Use non_lvalue to
3787 build NON_LVALUE_EXPRs so they get properly
3788 ignored when in GIMPLE form. */
3789 if (*opr
== NON_LVALUE_EXPR
)
3790 fprintf_indent (f
, indent
,
3791 "_r = non_lvalue_loc (loc, res_op0);\n");
3794 if (is_a
<operator_id
*> (opr
))
3795 fprintf_indent (f
, indent
,
3796 "_r = fold_build%d_loc (loc, %s, type",
3798 *e
->operation
== CONVERT_EXPR
3799 ? "NOP_EXPR" : e
->operation
->id
);
3801 fprintf_indent (f
, indent
,
3802 "_r = maybe_build_call_expr_loc (loc, "
3803 "%s, type, %d", e
->operation
->id
,
3805 for (unsigned j
= 0; j
< e
->ops
.length (); ++j
)
3806 fprintf (f
, ", res_op%d", j
);
3807 fprintf (f
, ");\n");
3808 if (!is_a
<operator_id
*> (opr
))
3810 fprintf_indent (f
, indent
, "if (!_r)\n");
3811 fprintf_indent (f
, indent
, " goto %s;\n", fail_label
);
3817 else if (result
->type
== operand::OP_CAPTURE
3818 || result
->type
== operand::OP_C_EXPR
)
3821 fprintf_indent (f
, indent
, "tree _r;\n");
3822 result
->gen_transform (f
, indent
, "_r", false, 1, "type",
3829 /* Search for captures not used in the result expression and dependent
3830 on TREE_SIDE_EFFECTS emit omit_one_operand. */
3831 for (int i
= 0; i
< s
->capture_max
+ 1; ++i
)
3833 if (cinfo
.info
[i
].same_as
!= (unsigned)i
)
3835 if (!cinfo
.info
[i
].force_no_side_effects_p
3836 && !cinfo
.info
[i
].expr_p
3837 && cinfo
.info
[i
].result_use_count
== 0)
3839 fprintf_indent (f
, indent
,
3840 "if (TREE_SIDE_EFFECTS (captures[%d]))\n",
3842 fprintf_indent (f
, indent
+ 2,
3843 "_r = build2_loc (loc, COMPOUND_EXPR, type, "
3844 "fold_ignored_result (captures[%d]), _r);\n",
3848 emit_logging_call (f
, indent
, s
, result
, gimple
);
3849 fprintf_indent (f
, indent
, "return _r;\n");
3853 fprintf_indent (f
, indent
, "}\n");
3855 fprintf (f
, "%s:;\n", fail_label
);
3859 /* Generate code for the '(if ...)', '(with ..)' and actual transform
3860 step of a '(simplify ...)' or '(match ...)'. This handles everything
3861 that is not part of the decision tree (simplify->match). */
3864 dt_simplify::gen (FILE *f
, int indent
, bool gimple
, int depth ATTRIBUTE_UNUSED
)
3866 fprintf_indent (f
, indent
, "{\n");
3868 output_line_directive (f
,
3869 s
->result
? s
->result
->location
: s
->match
->location
);
3870 if (s
->capture_max
>= 0)
3873 fprintf_indent (f
, indent
, "tree captures[%u] ATTRIBUTE_UNUSED = { %s",
3874 s
->capture_max
+ 1, indexes
[0]->get_name (opname
));
3876 for (int i
= 1; i
<= s
->capture_max
; ++i
)
3880 fprintf (f
, ", %s", indexes
[i
]->get_name (opname
));
3882 fprintf (f
, " };\n");
3885 /* If we have a split-out function for the actual transform, call it. */
3886 if (info
&& info
->fname
)
3890 fprintf_indent (f
, indent
, "if (%s (res_op, seq, "
3891 "valueize, type, captures", info
->fname
);
3892 for (unsigned i
= 0; i
< s
->for_subst_vec
.length (); ++i
)
3893 if (s
->for_subst_vec
[i
].first
->used
)
3894 fprintf (f
, ", %s", s
->for_subst_vec
[i
].second
->id
);
3895 fprintf (f
, "))\n");
3896 fprintf_indent (f
, indent
, " return true;\n");
3900 fprintf_indent (f
, indent
, "tree res = %s (loc, type",
3902 for (unsigned i
= 0; i
< as_a
<expr
*> (s
->match
)->ops
.length (); ++i
)
3903 fprintf (f
, ", _p%d", i
);
3904 fprintf (f
, ", captures");
3905 for (unsigned i
= 0; i
< s
->for_subst_vec
.length (); ++i
)
3907 if (s
->for_subst_vec
[i
].first
->used
)
3908 fprintf (f
, ", %s", s
->for_subst_vec
[i
].second
->id
);
3910 fprintf (f
, ");\n");
3911 fprintf_indent (f
, indent
, "if (res) return res;\n");
3916 for (unsigned i
= 0; i
< s
->for_subst_vec
.length (); ++i
)
3918 if (! s
->for_subst_vec
[i
].first
->used
)
3920 if (is_a
<operator_id
*> (s
->for_subst_vec
[i
].second
))
3921 fprintf_indent (f
, indent
, "const enum tree_code %s = %s;\n",
3922 s
->for_subst_vec
[i
].first
->id
,
3923 s
->for_subst_vec
[i
].second
->id
);
3924 else if (is_a
<fn_id
*> (s
->for_subst_vec
[i
].second
))
3925 fprintf_indent (f
, indent
, "const combined_fn %s = %s;\n",
3926 s
->for_subst_vec
[i
].first
->id
,
3927 s
->for_subst_vec
[i
].second
->id
);
3931 gen_1 (f
, indent
, gimple
, s
->result
);
3935 fprintf_indent (f
, indent
, "}\n");
3939 /* Hash function for finding equivalent transforms. */
3942 sinfo_hashmap_traits::hash (const key_type
&v
)
3944 /* Only bother to compare those originating from the same source pattern. */
3945 return v
->s
->result
->location
;
3948 /* Compare function for finding equivalent transforms. */
3951 compare_op (operand
*o1
, simplify
*s1
, operand
*o2
, simplify
*s2
)
3953 if (o1
->type
!= o2
->type
)
3958 case operand::OP_IF
:
3960 if_expr
*if1
= as_a
<if_expr
*> (o1
);
3961 if_expr
*if2
= as_a
<if_expr
*> (o2
);
3962 /* ??? Properly compare c-exprs. */
3963 if (if1
->cond
!= if2
->cond
)
3965 if (!compare_op (if1
->trueexpr
, s1
, if2
->trueexpr
, s2
))
3967 if (if1
->falseexpr
!= if2
->falseexpr
3969 && !compare_op (if1
->falseexpr
, s1
, if2
->falseexpr
, s2
)))
3973 case operand::OP_WITH
:
3975 with_expr
*with1
= as_a
<with_expr
*> (o1
);
3976 with_expr
*with2
= as_a
<with_expr
*> (o2
);
3977 if (with1
->with
!= with2
->with
)
3979 return compare_op (with1
->subexpr
, s1
, with2
->subexpr
, s2
);
3984 /* We've hit a result. Time to compare capture-infos - this is required
3985 in addition to the conservative pointer-equivalency of the result IL. */
3986 capture_info
cinfo1 (s1
, o1
, true);
3987 capture_info
cinfo2 (s2
, o2
, true);
3989 if (cinfo1
.force_no_side_effects
!= cinfo2
.force_no_side_effects
3990 || cinfo1
.info
.length () != cinfo2
.info
.length ())
3993 for (unsigned i
= 0; i
< cinfo1
.info
.length (); ++i
)
3995 if (cinfo1
.info
[i
].expr_p
!= cinfo2
.info
[i
].expr_p
3996 || cinfo1
.info
[i
].cse_p
!= cinfo2
.info
[i
].cse_p
3997 || (cinfo1
.info
[i
].force_no_side_effects_p
3998 != cinfo2
.info
[i
].force_no_side_effects_p
)
3999 || cinfo1
.info
[i
].force_single_use
!= cinfo2
.info
[i
].force_single_use
4000 || cinfo1
.info
[i
].cond_expr_cond_p
!= cinfo2
.info
[i
].cond_expr_cond_p
4001 /* toplevel_msk is an optimization */
4002 || cinfo1
.info
[i
].result_use_count
!= cinfo2
.info
[i
].result_use_count
4003 || cinfo1
.info
[i
].same_as
!= cinfo2
.info
[i
].same_as
4004 /* the pointer back to the capture is for diagnostics only */)
4008 /* ??? Deep-compare the actual result. */
4013 sinfo_hashmap_traits::equal_keys (const key_type
&v
,
4014 const key_type
&candidate
)
4016 return compare_op (v
->s
->result
, v
->s
, candidate
->s
->result
, candidate
->s
);
4020 /* Main entry to generate code for matching GIMPLE IL off the decision
4024 decision_tree::gen (vec
<FILE *> &files
, bool gimple
)
4030 fprintf (stderr
, "%s decision tree has %u leafs, maximum depth %u and "
4031 "a total number of %u nodes\n",
4032 gimple
? "GIMPLE" : "GENERIC",
4033 root
->num_leafs
, root
->max_level
, root
->total_size
);
4035 /* First split out the transform part of equal leafs. */
4038 for (sinfo_map_t::iterator iter
= si
.begin ();
4039 iter
!= si
.end (); ++iter
)
4041 sinfo
*s
= (*iter
).second
;
4042 /* Do not split out single uses. */
4049 fprintf (stderr
, "found %u uses of", s
->cnt
);
4050 output_line_directive (stderr
, s
->s
->s
->result
->location
);
4053 /* Cycle the file buffers. */
4054 FILE *f
= choose_output (files
);
4056 /* Generate a split out function with the leaf transform code. */
4057 s
->fname
= xasprintf ("%s_simplify_%u", gimple
? "gimple" : "generic",
4060 fp_decl (f
, "\nbool\n"
4061 "%s (gimple_match_op *res_op, gimple_seq *seq,\n"
4062 " tree (*valueize)(tree) ATTRIBUTE_UNUSED,\n"
4063 " const tree ARG_UNUSED (type), tree *ARG_UNUSED "
4068 fp_decl (f
, "\ntree\n"
4069 "%s (location_t ARG_UNUSED (loc), const tree ARG_UNUSED (type),\n",
4070 (*iter
).second
->fname
);
4071 for (unsigned i
= 0;
4072 i
< as_a
<expr
*>(s
->s
->s
->match
)->ops
.length (); ++i
)
4073 fp_decl (f
, " tree ARG_UNUSED (_p%d),", i
);
4074 fp_decl (f
, " tree *captures");
4076 for (unsigned i
= 0; i
< s
->s
->s
->for_subst_vec
.length (); ++i
)
4078 if (! s
->s
->s
->for_subst_vec
[i
].first
->used
)
4080 if (is_a
<operator_id
*> (s
->s
->s
->for_subst_vec
[i
].second
))
4081 fp_decl (f
, ",\n const enum tree_code ARG_UNUSED (%s)",
4082 s
->s
->s
->for_subst_vec
[i
].first
->id
);
4083 else if (is_a
<fn_id
*> (s
->s
->s
->for_subst_vec
[i
].second
))
4084 fp_decl (f
, ",\n const combined_fn ARG_UNUSED (%s)",
4085 s
->s
->s
->for_subst_vec
[i
].first
->id
);
4088 fp_decl_done (f
, ")");
4090 fprintf_indent (f
, 2, "const bool debug_dump = "
4091 "dump_file && (dump_flags & TDF_FOLDING);\n");
4092 s
->s
->gen_1 (f
, 2, gimple
, s
->s
->s
->result
);
4094 fprintf (f
, " return false;\n");
4096 fprintf (f
, " return NULL_TREE;\n");
4099 fprintf (stderr
, "removed %u duplicate tails\n", rcnt
);
4101 for (unsigned n
= 1; n
<= 7; ++n
)
4103 bool has_kids_p
= false;
4105 /* First generate split-out functions. */
4106 for (unsigned j
= 0; j
< root
->kids
.length (); j
++)
4108 dt_operand
*dop
= static_cast<dt_operand
*>(root
->kids
[j
]);
4109 expr
*e
= static_cast<expr
*>(dop
->op
);
4110 if (e
->ops
.length () != n
4111 /* Builtin simplifications are somewhat premature on
4112 GENERIC. The following drops patterns with outermost
4113 calls. It's easy to emit overloads for function code
4114 though if necessary. */
4116 && e
->operation
->kind
!= id_base::CODE
))
4120 /* Cycle the file buffers. */
4121 FILE *f
= choose_output (files
);
4124 fp_decl (f
, "\nbool\n"
4125 "gimple_simplify_%s (gimple_match_op *res_op,"
4126 " gimple_seq *seq,\n"
4127 " tree (*valueize)(tree) "
4128 "ATTRIBUTE_UNUSED,\n"
4129 " code_helper ARG_UNUSED (code), tree "
4130 "ARG_UNUSED (type)",
4133 fp_decl (f
, "\ntree\n"
4134 "generic_simplify_%s (location_t ARG_UNUSED (loc), enum "
4135 "tree_code ARG_UNUSED (code), const tree ARG_UNUSED (type)",
4137 for (unsigned i
= 0; i
< n
; ++i
)
4138 fp_decl (f
, ", tree _p%d", i
);
4139 fp_decl_done (f
, ")");
4141 fprintf_indent (f
, 2, "const bool debug_dump = "
4142 "dump_file && (dump_flags & TDF_FOLDING);\n");
4143 dop
->gen_kids (f
, 2, gimple
, 0);
4145 fprintf (f
, " return false;\n");
4147 fprintf (f
, " return NULL_TREE;\n");
4152 /* If this main entry has no children, avoid generating code
4153 with compiler warnings, by generating a simple stub. */
4157 /* Cycle the file buffers. */
4158 FILE *f
= choose_output (files
);
4161 fp_decl (f
, "\nbool\n"
4162 "gimple_simplify (gimple_match_op*, gimple_seq*,\n"
4163 " tree (*)(tree), code_helper,\n"
4166 fp_decl (f
, "\ntree\n"
4167 "generic_simplify (location_t, enum tree_code,\n"
4169 for (unsigned i
= 0; i
< n
; ++i
)
4170 fp_decl (f
, ", tree");
4171 fp_decl_done (f
, ")");
4174 fprintf (f
, " return false;\n");
4176 fprintf (f
, " return NULL_TREE;\n");
4182 /* Cycle the file buffers. */
4183 FILE *f
= choose_output (files
);
4185 /* Then generate the main entry with the outermost switch and
4186 tail-calls to the split-out functions. */
4188 fp_decl (f
, "\nbool\n"
4189 "gimple_simplify (gimple_match_op *res_op, gimple_seq *seq,\n"
4190 " tree (*valueize)(tree) ATTRIBUTE_UNUSED,\n"
4191 " code_helper code, const tree type");
4193 fp_decl (f
, "\ntree\n"
4194 "generic_simplify (location_t loc, enum tree_code code, "
4195 "const tree type ATTRIBUTE_UNUSED");
4196 for (unsigned i
= 0; i
< n
; ++i
)
4197 fp_decl (f
, ", tree _p%d", i
);
4198 fp_decl_done (f
, ")");
4202 fprintf (f
, " switch (code.get_rep())\n"
4205 fprintf (f
, " switch (code)\n"
4207 for (unsigned i
= 0; i
< root
->kids
.length (); i
++)
4209 dt_operand
*dop
= static_cast<dt_operand
*>(root
->kids
[i
]);
4210 expr
*e
= static_cast<expr
*>(dop
->op
);
4211 if (e
->ops
.length () != n
4212 /* Builtin simplifications are somewhat premature on
4213 GENERIC. The following drops patterns with outermost
4214 calls. It's easy to emit overloads for function code
4215 though if necessary. */
4217 && e
->operation
->kind
!= id_base::CODE
))
4220 if (*e
->operation
== CONVERT_EXPR
4221 || *e
->operation
== NOP_EXPR
)
4222 fprintf (f
, " CASE_CONVERT:\n");
4224 fprintf (f
, " case %s%s:\n",
4225 is_a
<fn_id
*> (e
->operation
) ? "-" : "",
4228 fprintf (f
, " return gimple_simplify_%s (res_op, "
4229 "seq, valueize, code, type", e
->operation
->id
);
4231 fprintf (f
, " return generic_simplify_%s (loc, code, type",
4233 for (unsigned j
= 0; j
< n
; ++j
)
4234 fprintf (f
, ", _p%d", j
);
4235 fprintf (f
, ");\n");
4237 fprintf (f
, " default:;\n"
4241 fprintf (f
, " return false;\n");
4243 fprintf (f
, " return NULL_TREE;\n");
4248 /* Output code to implement the predicate P from the decision tree DT. */
4251 write_predicate (FILE *f
, predicate_id
*p
, decision_tree
&dt
, bool gimple
)
4253 fp_decl (f
, "\nbool\n%s%s (tree t%s%s)",
4254 gimple
? "gimple_" : "tree_", p
->id
,
4255 p
->nargs
> 0 ? ", tree *res_ops" : "",
4256 gimple
? ", tree (*valueize)(tree) ATTRIBUTE_UNUSED" : "");
4257 fp_decl_done (f
, "");
4259 /* Conveniently make 'type' available. */
4260 fprintf_indent (f
, 2, "const tree type = TREE_TYPE (t);\n");
4261 fprintf_indent (f
, 2, "const bool debug_dump = "
4262 "dump_file && (dump_flags & TDF_FOLDING);\n");
4265 fprintf_indent (f
, 2, "if (TREE_SIDE_EFFECTS (t)) return false;\n");
4266 dt
.root
->gen_kids (f
, 2, gimple
, 0);
4268 fprintf_indent (f
, 2, "return false;\n"
4272 /* Write the common header for the GIMPLE/GENERIC IL matching routines. */
4275 write_header (FILE *f
, const char *head
)
4277 fprintf (f
, "/* Generated automatically by the program `genmatch' from\n");
4278 fprintf (f
, " a IL pattern matching and simplification description. */\n");
4279 fprintf (f
, "#pragma GCC diagnostic push\n");
4280 fprintf (f
, "#pragma GCC diagnostic ignored \"-Wunused-variable\"\n");
4281 fprintf (f
, "#pragma GCC diagnostic ignored \"-Wunused-function\"\n");
4283 /* Include the header instead of writing it awkwardly quoted here. */
4285 fprintf (f
, "\n#include \"%s\"\n", head
);
4295 parser (cpp_reader
*, bool gimple
);
4298 const cpp_token
*next ();
4299 const cpp_token
*peek (unsigned = 1);
4300 const cpp_token
*peek_ident (const char * = NULL
, unsigned = 1);
4301 const cpp_token
*expect (enum cpp_ttype
);
4302 const cpp_token
*eat_token (enum cpp_ttype
);
4303 const char *get_string ();
4304 const char *get_ident ();
4305 const cpp_token
*eat_ident (const char *);
4306 const char *get_number ();
4308 unsigned get_internal_capture_id ();
4310 id_base
*parse_operation (unsigned char &);
4311 operand
*parse_capture (operand
*, bool);
4312 operand
*parse_expr ();
4313 c_expr
*parse_c_expr (cpp_ttype
);
4314 operand
*parse_op ();
4316 void record_operlist (location_t
, user_id
*);
4318 void parse_pattern ();
4319 operand
*parse_result (operand
*, predicate_id
*);
4320 void push_simplify (simplify::simplify_kind
,
4321 vec
<simplify
*>&, operand
*, operand
*);
4322 void parse_simplify (simplify::simplify_kind
,
4323 vec
<simplify
*>&, predicate_id
*, operand
*);
4324 void parse_for (location_t
);
4325 void parse_if (location_t
);
4326 void parse_predicates (location_t
);
4327 void parse_operator_list (location_t
);
4329 void finish_match_operand (operand
*);
4333 vec
<c_expr
*> active_ifs
;
4334 vec
<vec
<user_id
*> > active_fors
;
4335 hash_set
<user_id
*> *oper_lists_set
;
4336 vec
<user_id
*> oper_lists
;
4338 cid_map_t
*capture_ids
;
4342 vec
<simplify
*> simplifiers
;
4343 vec
<predicate_id
*> user_predicates
;
4344 bool parsing_match_operand
;
4347 /* Lexing helpers. */
4349 /* Read the next non-whitespace token from R. */
4354 const cpp_token
*token
;
4357 token
= cpp_get_token (r
);
4359 while (token
->type
== CPP_PADDING
);
4363 /* Peek at the next non-whitespace token from R. */
4366 parser::peek (unsigned num
)
4368 const cpp_token
*token
;
4372 token
= cpp_peek_token (r
, i
++);
4374 while (token
->type
== CPP_PADDING
4376 /* If we peek at EOF this is a fatal error as it leaves the
4377 cpp_reader in unusable state. Assume we really wanted a
4378 token and thus this EOF is unexpected. */
4379 if (token
->type
== CPP_EOF
)
4380 fatal_at (token
, "unexpected end of file");
4384 /* Peek at the next identifier token (or return NULL if the next
4385 token is not an identifier or equal to ID if supplied). */
4388 parser::peek_ident (const char *id
, unsigned num
)
4390 const cpp_token
*token
= peek (num
);
4391 if (token
->type
!= CPP_NAME
)
4397 const char *t
= (const char *) CPP_HASHNODE (token
->val
.node
.node
)->ident
.str
;
4398 if (strcmp (id
, t
) == 0)
4404 /* Read the next token from R and assert it is of type TK. */
4407 parser::expect (enum cpp_ttype tk
)
4409 const cpp_token
*token
= next ();
4410 if (token
->type
!= tk
)
4411 fatal_at (token
, "expected %s, got %s",
4412 cpp_type2name (tk
, 0), cpp_type2name (token
->type
, 0));
4417 /* Consume the next token from R and assert it is of type TK. */
4420 parser::eat_token (enum cpp_ttype tk
)
4425 /* Read the next token from R and assert it is of type CPP_STRING and
4426 return its value. */
4429 parser::get_string ()
4431 const cpp_token
*token
= expect (CPP_STRING
);
4432 return (const char *)token
->val
.str
.text
;
4435 /* Read the next token from R and assert it is of type CPP_NAME and
4436 return its value. */
4439 parser::get_ident ()
4441 const cpp_token
*token
= expect (CPP_NAME
);
4442 return (const char *)CPP_HASHNODE (token
->val
.node
.node
)->ident
.str
;
4445 /* Eat an identifier token with value S from R. */
4448 parser::eat_ident (const char *s
)
4450 const cpp_token
*token
= peek ();
4451 const char *t
= get_ident ();
4452 if (strcmp (s
, t
) != 0)
4453 fatal_at (token
, "expected '%s' got '%s'\n", s
, t
);
4457 /* Read the next token from R and assert it is of type CPP_NUMBER and
4458 return its value. */
4461 parser::get_number ()
4463 const cpp_token
*token
= expect (CPP_NUMBER
);
4464 return (const char *)token
->val
.str
.text
;
4467 /* Return a capture ID that can be used internally. */
4470 parser::get_internal_capture_id ()
4472 unsigned newid
= capture_ids
->elements ();
4473 /* Big enough for a 32-bit UINT_MAX plus prefix. */
4476 snprintf (id
, sizeof (id
), "__%u", newid
);
4477 capture_ids
->get_or_insert (xstrdup (id
), &existed
);
4479 fatal ("reserved capture id '%s' already used", id
);
4483 /* Record an operator-list use for transparent for handling. */
4486 parser::record_operlist (location_t loc
, user_id
*p
)
4488 if (!oper_lists_set
->add (p
))
4490 if (!oper_lists
.is_empty ()
4491 && oper_lists
[0]->substitutes
.length () != p
->substitutes
.length ())
4492 fatal_at (loc
, "User-defined operator list does not have the "
4493 "same number of entries as others used in the pattern");
4494 oper_lists
.safe_push (p
);
4498 /* Parse the operator ID, special-casing convert?, convert1? and
4502 parser::parse_operation (unsigned char &opt_grp
)
4504 const cpp_token
*id_tok
= peek ();
4505 char *alt_id
= NULL
;
4506 const char *id
= get_ident ();
4507 const cpp_token
*token
= peek ();
4509 if (token
->type
== CPP_QUERY
4510 && !(token
->flags
& PREV_WHITE
))
4512 if (!parsing_match_operand
)
4513 fatal_at (id_tok
, "conditional convert can only be used in "
4514 "match expression");
4515 if (ISDIGIT (id
[strlen (id
) - 1]))
4517 opt_grp
= id
[strlen (id
) - 1] - '0' + 1;
4518 alt_id
= xstrdup (id
);
4519 alt_id
[strlen (id
) - 1] = '\0';
4521 fatal_at (id_tok
, "use '%s?' here", alt_id
);
4525 eat_token (CPP_QUERY
);
4527 id_base
*op
= get_operator (alt_id
? alt_id
: id
);
4529 fatal_at (id_tok
, "unknown operator %s", alt_id
? alt_id
: id
);
4532 user_id
*p
= dyn_cast
<user_id
*> (op
);
4533 if (p
&& p
->is_oper_list
)
4535 if (active_fors
.length() == 0)
4536 record_operlist (id_tok
->src_loc
, p
);
4538 fatal_at (id_tok
, "operator-list %s cannot be expanded inside 'for'", id
);
4544 capture = '@'<number> */
4547 parser::parse_capture (operand
*op
, bool require_existing
)
4549 location_t src_loc
= eat_token (CPP_ATSIGN
)->src_loc
;
4550 const cpp_token
*token
= peek ();
4551 const char *id
= NULL
;
4552 bool value_match
= false;
4553 /* For matches parse @@ as a value-match denoting the prevailing operand. */
4554 if (token
->type
== CPP_ATSIGN
4555 && ! (token
->flags
& PREV_WHITE
)
4556 && parsing_match_operand
)
4558 eat_token (CPP_ATSIGN
);
4562 if (token
->type
== CPP_NUMBER
)
4564 else if (token
->type
== CPP_NAME
)
4567 fatal_at (token
, "expected number or identifier");
4568 unsigned next_id
= capture_ids
->elements ();
4570 unsigned &num
= capture_ids
->get_or_insert (id
, &existed
);
4573 if (require_existing
)
4574 fatal_at (src_loc
, "unknown capture id");
4577 return new capture (src_loc
, num
, op
, value_match
);
4580 /* Parse an expression
4581 expr = '(' <operation>[capture][flag][type] <operand>... ')' */
4584 parser::parse_expr ()
4586 const cpp_token
*token
= peek ();
4587 unsigned char opt_grp
;
4588 expr
*e
= new expr (parse_operation (opt_grp
), token
->src_loc
);
4591 bool is_commutative
= false;
4592 bool force_capture
= false;
4593 const char *expr_type
= NULL
;
4595 if (!parsing_match_operand
4596 && token
->type
== CPP_NOT
4597 && !(token
->flags
& PREV_WHITE
))
4599 eat_token (CPP_NOT
);
4600 e
->force_leaf
= true;
4603 if (token
->type
== CPP_COLON
4604 && !(token
->flags
& PREV_WHITE
))
4606 eat_token (CPP_COLON
);
4608 if (token
->type
== CPP_NAME
4609 && !(token
->flags
& PREV_WHITE
))
4611 const char *s
= get_ident ();
4612 if (!parsing_match_operand
)
4622 = dyn_cast
<operator_id
*> (e
->operation
))
4624 if (!commutative_tree_code (o
->code
)
4625 && !comparison_code_p (o
->code
))
4626 fatal_at (token
, "operation is not commutative");
4628 else if (user_id
*p
= dyn_cast
<user_id
*> (e
->operation
))
4629 for (unsigned i
= 0;
4630 i
< p
->substitutes
.length (); ++i
)
4633 = dyn_cast
<operator_id
*> (p
->substitutes
[i
]))
4635 if (!commutative_tree_code (q
->code
)
4636 && !comparison_code_p (q
->code
))
4637 fatal_at (token
, "operation %s is not "
4638 "commutative", q
->id
);
4641 is_commutative
= true;
4643 else if (*sp
== 'C')
4644 is_commutative
= true;
4645 else if (*sp
== 's')
4647 e
->force_single_use
= true;
4648 force_capture
= true;
4651 fatal_at (token
, "flag %c not recognized", *sp
);
4658 fatal_at (token
, "expected flag or type specifying identifier");
4661 if (token
->type
== CPP_ATSIGN
4662 && !(token
->flags
& PREV_WHITE
))
4663 op
= parse_capture (e
, false);
4664 else if (force_capture
)
4666 unsigned num
= get_internal_capture_id ();
4667 op
= new capture (token
->src_loc
, num
, e
, false);
4674 if (token
->type
== CPP_CLOSE_PAREN
)
4676 if (e
->operation
->nargs
!= -1
4677 && e
->operation
->nargs
!= (int) e
->ops
.length ())
4678 fatal_at (token
, "'%s' expects %u operands, not %u",
4679 e
->operation
->id
, e
->operation
->nargs
, e
->ops
.length ());
4682 if (e
->ops
.length () == 2
4683 || commutative_op (e
->operation
) >= 0)
4684 e
->is_commutative
= true;
4686 fatal_at (token
, "only binary operators or functions with "
4687 "two arguments can be marked commutative, "
4688 "unless the operation is known to be inherently "
4691 e
->expr_type
= expr_type
;
4694 if (e
->ops
.length () != 1)
4695 fatal_at (token
, "only unary operations can be conditional");
4696 e
->opt_grp
= opt_grp
;
4700 else if (!(token
->flags
& PREV_WHITE
))
4701 fatal_at (token
, "expected expression operand");
4703 e
->append_op (parse_op ());
4708 /* Lex native C code delimited by START recording the preprocessing tokens
4709 for later processing.
4710 c_expr = ('{'|'(') <pp token>... ('}'|')') */
4713 parser::parse_c_expr (cpp_ttype start
)
4715 const cpp_token
*token
;
4718 vec
<cpp_token
> code
= vNULL
;
4719 unsigned nr_stmts
= 0;
4720 location_t loc
= eat_token (start
)->src_loc
;
4721 if (start
== CPP_OPEN_PAREN
)
4722 end
= CPP_CLOSE_PAREN
;
4723 else if (start
== CPP_OPEN_BRACE
)
4724 end
= CPP_CLOSE_BRACE
;
4732 /* Count brace pairs to find the end of the expr to match. */
4733 if (token
->type
== start
)
4735 else if (token
->type
== end
4738 else if (token
->type
== CPP_EOF
)
4739 fatal_at (token
, "unexpected end of file");
4741 /* This is a lame way of counting the number of statements. */
4742 if (token
->type
== CPP_SEMICOLON
)
4745 /* If this is possibly a user-defined identifier mark it used. */
4746 if (token
->type
== CPP_NAME
)
4749 = (const char *)CPP_HASHNODE (token
->val
.node
.node
)->ident
.str
;
4750 if (strcmp (str
, "return") == 0)
4751 fatal_at (token
, "return statement not allowed in C expression");
4752 id_base
*idb
= get_operator (str
);
4754 if (idb
&& (p
= dyn_cast
<user_id
*> (idb
)) && p
->is_oper_list
)
4755 record_operlist (token
->src_loc
, p
);
4758 /* Record the token. */
4759 code
.safe_push (*token
);
4762 return new c_expr (r
, loc
, code
, nr_stmts
, vNULL
, capture_ids
);
4765 /* Parse an operand which is either an expression, a predicate or
4766 a standalone capture.
4767 op = predicate | expr | c_expr | capture */
4772 const cpp_token
*token
= peek ();
4773 class operand
*op
= NULL
;
4774 if (token
->type
== CPP_OPEN_PAREN
)
4776 eat_token (CPP_OPEN_PAREN
);
4778 eat_token (CPP_CLOSE_PAREN
);
4780 else if (token
->type
== CPP_OPEN_BRACE
)
4782 op
= parse_c_expr (CPP_OPEN_BRACE
);
4786 /* Remaining ops are either empty or predicates */
4787 if (token
->type
== CPP_NAME
)
4789 const char *id
= get_ident ();
4790 id_base
*opr
= get_operator (id
);
4792 fatal_at (token
, "expected predicate name");
4793 if (operator_id
*code1
= dyn_cast
<operator_id
*> (opr
))
4795 if (code1
->nargs
!= 0)
4796 fatal_at (token
, "using an operator with operands as predicate");
4797 /* Parse the zero-operand operator "predicates" as
4799 op
= new expr (opr
, token
->src_loc
);
4801 else if (user_id
*code2
= dyn_cast
<user_id
*> (opr
))
4803 if (code2
->nargs
!= 0)
4804 fatal_at (token
, "using an operator with operands as predicate");
4805 /* Parse the zero-operand operator "predicates" as
4807 op
= new expr (opr
, token
->src_loc
);
4809 else if (predicate_id
*p
= dyn_cast
<predicate_id
*> (opr
))
4810 op
= new predicate (p
, token
->src_loc
);
4812 fatal_at (token
, "using an unsupported operator as predicate");
4813 if (!parsing_match_operand
)
4814 fatal_at (token
, "predicates are only allowed in match expression");
4816 if (token
->flags
& PREV_WHITE
)
4819 else if (token
->type
!= CPP_COLON
4820 && token
->type
!= CPP_ATSIGN
)
4821 fatal_at (token
, "expected expression or predicate");
4822 /* optionally followed by a capture and a predicate. */
4823 if (token
->type
== CPP_COLON
)
4824 fatal_at (token
, "not implemented: predicate on leaf operand");
4825 if (token
->type
== CPP_ATSIGN
)
4826 op
= parse_capture (op
, !parsing_match_operand
);
4832 /* Create a new simplify from the current parsing state and MATCH,
4833 MATCH_LOC, RESULT and RESULT_LOC and push it to SIMPLIFIERS. */
4836 parser::push_simplify (simplify::simplify_kind kind
,
4837 vec
<simplify
*>& simplifiers
,
4838 operand
*match
, operand
*result
)
4840 /* Build and push a temporary for operator list uses in expressions. */
4841 if (!oper_lists
.is_empty ())
4842 active_fors
.safe_push (oper_lists
);
4844 simplifiers
.safe_push
4845 (new simplify (kind
, last_id
++, match
, result
,
4846 active_fors
.copy (), capture_ids
));
4848 if (!oper_lists
.is_empty ())
4853 <result-op> = <op> | <if> | <with>
4854 <if> = '(' 'if' '(' <c-expr> ')' <result-op> ')'
4855 <with> = '(' 'with' '{' <c-expr> '}' <result-op> ')'
4859 parser::parse_result (operand
*result
, predicate_id
*matcher
)
4861 const cpp_token
*token
= peek ();
4862 if (token
->type
!= CPP_OPEN_PAREN
)
4865 eat_token (CPP_OPEN_PAREN
);
4866 if (peek_ident ("if"))
4869 if_expr
*ife
= new if_expr (token
->src_loc
);
4870 ife
->cond
= parse_c_expr (CPP_OPEN_PAREN
);
4871 if (peek ()->type
== CPP_OPEN_PAREN
)
4873 ife
->trueexpr
= parse_result (result
, matcher
);
4874 if (peek ()->type
== CPP_OPEN_PAREN
)
4875 ife
->falseexpr
= parse_result (result
, matcher
);
4876 else if (peek ()->type
!= CPP_CLOSE_PAREN
)
4877 ife
->falseexpr
= parse_op ();
4879 else if (peek ()->type
!= CPP_CLOSE_PAREN
)
4881 ife
->trueexpr
= parse_op ();
4882 if (peek ()->type
== CPP_OPEN_PAREN
)
4883 ife
->falseexpr
= parse_result (result
, matcher
);
4884 else if (peek ()->type
!= CPP_CLOSE_PAREN
)
4885 ife
->falseexpr
= parse_op ();
4887 /* If this if is immediately closed then it contains a
4888 manual matcher or is part of a predicate definition. */
4889 else /* if (peek ()->type == CPP_CLOSE_PAREN) */
4892 fatal_at (peek (), "manual transform not implemented");
4893 ife
->trueexpr
= result
;
4895 eat_token (CPP_CLOSE_PAREN
);
4898 else if (peek_ident ("with"))
4901 with_expr
*withe
= new with_expr (token
->src_loc
);
4902 /* Parse (with c-expr expr) as (if-with (true) expr). */
4903 withe
->with
= parse_c_expr (CPP_OPEN_BRACE
);
4904 withe
->with
->nr_stmts
= 0;
4905 withe
->subexpr
= parse_result (result
, matcher
);
4906 eat_token (CPP_CLOSE_PAREN
);
4909 else if (peek_ident ("switch"))
4911 token
= eat_ident ("switch");
4912 location_t ifloc
= eat_token (CPP_OPEN_PAREN
)->src_loc
;
4914 if_expr
*ife
= new if_expr (ifloc
);
4916 ife
->cond
= parse_c_expr (CPP_OPEN_PAREN
);
4917 if (peek ()->type
== CPP_OPEN_PAREN
)
4918 ife
->trueexpr
= parse_result (result
, matcher
);
4920 ife
->trueexpr
= parse_op ();
4921 eat_token (CPP_CLOSE_PAREN
);
4922 if (peek ()->type
!= CPP_OPEN_PAREN
4923 || !peek_ident ("if", 2))
4924 fatal_at (token
, "switch can be implemented with a single if");
4925 while (peek ()->type
!= CPP_CLOSE_PAREN
)
4927 if (peek ()->type
== CPP_OPEN_PAREN
)
4929 if (peek_ident ("if", 2))
4931 ifloc
= eat_token (CPP_OPEN_PAREN
)->src_loc
;
4933 ife
->falseexpr
= new if_expr (ifloc
);
4934 ife
= as_a
<if_expr
*> (ife
->falseexpr
);
4935 ife
->cond
= parse_c_expr (CPP_OPEN_PAREN
);
4936 if (peek ()->type
== CPP_OPEN_PAREN
)
4937 ife
->trueexpr
= parse_result (result
, matcher
);
4939 ife
->trueexpr
= parse_op ();
4940 if (peek ()->type
== CPP_OPEN_PAREN
)
4941 fatal_at (peek(), "if inside switch cannot have an else");
4942 eat_token (CPP_CLOSE_PAREN
);
4946 /* switch default clause */
4947 ife
->falseexpr
= parse_result (result
, matcher
);
4948 eat_token (CPP_CLOSE_PAREN
);
4954 /* switch default clause */
4955 ife
->falseexpr
= parse_op ();
4956 eat_token (CPP_CLOSE_PAREN
);
4960 eat_token (CPP_CLOSE_PAREN
);
4965 operand
*op
= result
;
4968 eat_token (CPP_CLOSE_PAREN
);
4974 simplify = 'simplify' <expr> <result-op>
4976 match = 'match' <ident> <expr> [<result-op>]
4977 and fill SIMPLIFIERS with the results. */
4980 parser::parse_simplify (simplify::simplify_kind kind
,
4981 vec
<simplify
*>& simplifiers
, predicate_id
*matcher
,
4984 /* Reset the capture map. */
4986 capture_ids
= new cid_map_t
;
4987 /* Reset oper_lists and set. */
4988 hash_set
<user_id
*> olist
;
4989 oper_lists_set
= &olist
;
4992 const cpp_token
*loc
= peek ();
4993 parsing_match_operand
= true;
4994 class operand
*match
= parse_op ();
4995 finish_match_operand (match
);
4996 parsing_match_operand
= false;
4997 if (match
->type
== operand::OP_CAPTURE
&& !matcher
)
4998 fatal_at (loc
, "outermost expression cannot be captured");
4999 if (match
->type
== operand::OP_EXPR
5000 && is_a
<predicate_id
*> (as_a
<expr
*> (match
)->operation
))
5001 fatal_at (loc
, "outermost expression cannot be a predicate");
5003 /* Splice active_ifs onto result and continue parsing the
5005 if_expr
*active_if
= NULL
;
5006 for (int i
= active_ifs
.length (); i
> 0; --i
)
5008 if_expr
*ifc
= new if_expr (active_ifs
[i
-1]->location
);
5009 ifc
->cond
= active_ifs
[i
-1];
5010 ifc
->trueexpr
= active_if
;
5013 if_expr
*outermost_if
= active_if
;
5014 while (active_if
&& active_if
->trueexpr
)
5015 active_if
= as_a
<if_expr
*> (active_if
->trueexpr
);
5017 const cpp_token
*token
= peek ();
5019 /* If this if is immediately closed then it is part of a predicate
5020 definition. Push it. */
5021 if (token
->type
== CPP_CLOSE_PAREN
)
5024 fatal_at (token
, "expected transform expression");
5027 active_if
->trueexpr
= result
;
5028 result
= outermost_if
;
5030 push_simplify (kind
, simplifiers
, match
, result
);
5034 operand
*tem
= parse_result (result
, matcher
);
5037 active_if
->trueexpr
= tem
;
5038 result
= outermost_if
;
5043 push_simplify (kind
, simplifiers
, match
, result
);
5046 /* Parsing of the outer control structures. */
5048 /* Parse a for expression
5049 for = '(' 'for' <subst>... <pattern> ')'
5050 subst = <ident> '(' <ident>... ')' */
5053 parser::parse_for (location_t
)
5055 auto_vec
<const cpp_token
*> user_id_tokens
;
5056 vec
<user_id
*> user_ids
= vNULL
;
5057 const cpp_token
*token
;
5058 unsigned min_n_opers
= 0, max_n_opers
= 0;
5063 if (token
->type
!= CPP_NAME
)
5066 /* Insert the user defined operators into the operator hash. */
5067 const char *id
= get_ident ();
5068 if (get_operator (id
, true) != NULL
)
5069 fatal_at (token
, "operator already defined");
5070 user_id
*op
= new user_id (id
);
5071 id_base
**slot
= operators
->find_slot_with_hash (op
, op
->hashval
, INSERT
);
5073 user_ids
.safe_push (op
);
5074 user_id_tokens
.safe_push (token
);
5076 eat_token (CPP_OPEN_PAREN
);
5079 while ((token
= peek_ident ()) != 0)
5081 const char *oper
= get_ident ();
5082 id_base
*idb
= get_operator (oper
, true);
5084 fatal_at (token
, "no such operator '%s'", oper
);
5088 else if (idb
->nargs
== -1)
5090 else if (idb
->nargs
!= arity
)
5091 fatal_at (token
, "operator '%s' with arity %d does not match "
5092 "others with arity %d", oper
, idb
->nargs
, arity
);
5094 user_id
*p
= dyn_cast
<user_id
*> (idb
);
5097 if (p
->is_oper_list
)
5098 op
->substitutes
.safe_splice (p
->substitutes
);
5100 fatal_at (token
, "iterator cannot be used as operator-list");
5103 op
->substitutes
.safe_push (idb
);
5106 token
= expect (CPP_CLOSE_PAREN
);
5108 unsigned nsubstitutes
= op
->substitutes
.length ();
5109 if (nsubstitutes
== 0)
5110 fatal_at (token
, "A user-defined operator must have at least "
5111 "one substitution");
5112 if (max_n_opers
== 0)
5114 min_n_opers
= nsubstitutes
;
5115 max_n_opers
= nsubstitutes
;
5119 if (nsubstitutes
% min_n_opers
!= 0
5120 && min_n_opers
% nsubstitutes
!= 0)
5121 fatal_at (token
, "All user-defined identifiers must have a "
5122 "multiple number of operator substitutions of the "
5123 "smallest number of substitutions");
5124 if (nsubstitutes
< min_n_opers
)
5125 min_n_opers
= nsubstitutes
;
5126 else if (nsubstitutes
> max_n_opers
)
5127 max_n_opers
= nsubstitutes
;
5131 unsigned n_ids
= user_ids
.length ();
5133 fatal_at (token
, "for requires at least one user-defined identifier");
5136 if (token
->type
== CPP_CLOSE_PAREN
)
5137 fatal_at (token
, "no pattern defined in for");
5139 active_fors
.safe_push (user_ids
);
5143 if (token
->type
== CPP_CLOSE_PAREN
)
5149 /* Remove user-defined operators from the hash again. */
5150 for (unsigned i
= 0; i
< user_ids
.length (); ++i
)
5152 if (!user_ids
[i
]->used
)
5153 warning_at (user_id_tokens
[i
],
5154 "operator %s defined but not used", user_ids
[i
]->id
);
5155 operators
->remove_elt (user_ids
[i
]);
5159 /* Parse an identifier associated with a list of operators.
5160 oprs = '(' 'define_operator_list' <ident> <ident>... ')' */
5163 parser::parse_operator_list (location_t
)
5165 const cpp_token
*token
= peek ();
5166 const char *id
= get_ident ();
5168 if (get_operator (id
, true) != 0)
5169 fatal_at (token
, "operator %s already defined", id
);
5171 user_id
*op
= new user_id (id
, true);
5174 while ((token
= peek_ident ()) != 0)
5177 const char *oper
= get_ident ();
5178 id_base
*idb
= get_operator (oper
, true);
5181 fatal_at (token
, "no such operator '%s'", oper
);
5185 else if (idb
->nargs
== -1)
5187 else if (arity
!= idb
->nargs
)
5188 fatal_at (token
, "operator '%s' with arity %d does not match "
5189 "others with arity %d", oper
, idb
->nargs
, arity
);
5191 /* We allow composition of multiple operator lists. */
5192 if (user_id
*p
= dyn_cast
<user_id
*> (idb
))
5193 op
->substitutes
.safe_splice (p
->substitutes
);
5195 op
->substitutes
.safe_push (idb
);
5198 // Check that there is no junk after id-list
5200 if (token
->type
!= CPP_CLOSE_PAREN
)
5201 fatal_at (token
, "expected identifier got %s", cpp_type2name (token
->type
, 0));
5203 if (op
->substitutes
.length () == 0)
5204 fatal_at (token
, "operator-list cannot be empty");
5207 id_base
**slot
= operators
->find_slot_with_hash (op
, op
->hashval
, INSERT
);
5211 /* Parse an outer if expression.
5212 if = '(' 'if' '(' <c-expr> ')' <pattern> ')' */
5215 parser::parse_if (location_t
)
5217 c_expr
*ifexpr
= parse_c_expr (CPP_OPEN_PAREN
);
5219 const cpp_token
*token
= peek ();
5220 if (token
->type
== CPP_CLOSE_PAREN
)
5221 fatal_at (token
, "no pattern defined in if");
5223 active_ifs
.safe_push (ifexpr
);
5227 if (token
->type
== CPP_CLOSE_PAREN
)
5235 /* Parse a list of predefined predicate identifiers.
5236 preds = '(' 'define_predicates' <ident>... ')' */
5239 parser::parse_predicates (location_t
)
5243 const cpp_token
*token
= peek ();
5244 if (token
->type
!= CPP_NAME
)
5247 add_predicate (get_ident ());
5252 /* Parse outer control structures.
5253 pattern = <preds>|<for>|<if>|<simplify>|<match> */
5256 parser::parse_pattern ()
5258 /* All clauses start with '('. */
5259 eat_token (CPP_OPEN_PAREN
);
5260 const cpp_token
*token
= peek ();
5261 const char *id
= get_ident ();
5262 if (strcmp (id
, "simplify") == 0)
5264 parse_simplify (simplify::SIMPLIFY
, simplifiers
, NULL
, NULL
);
5267 else if (strcmp (id
, "match") == 0)
5269 bool with_args
= false;
5270 location_t e_loc
= peek ()->src_loc
;
5271 if (peek ()->type
== CPP_OPEN_PAREN
)
5273 eat_token (CPP_OPEN_PAREN
);
5276 const char *name
= get_ident ();
5277 id_base
*id1
= get_operator (name
);
5281 p
= add_predicate (name
);
5282 user_predicates
.safe_push (p
);
5284 else if ((p
= dyn_cast
<predicate_id
*> (id1
)))
5287 fatal_at (token
, "cannot add a match to a non-predicate ID");
5288 /* Parse (match <id> <arg>... (match-expr)) here. */
5292 capture_ids
= new cid_map_t
;
5293 e
= new expr (p
, e_loc
);
5294 while (peek ()->type
== CPP_ATSIGN
)
5295 e
->append_op (parse_capture (NULL
, false));
5296 eat_token (CPP_CLOSE_PAREN
);
5299 && ((e
&& e
->ops
.length () != (unsigned)p
->nargs
)
5300 || (!e
&& p
->nargs
!= 0)))
5301 fatal_at (token
, "non-matching number of match operands");
5302 p
->nargs
= e
? e
->ops
.length () : 0;
5303 parse_simplify (simplify::MATCH
, p
->matchers
, p
, e
);
5306 else if (strcmp (id
, "for") == 0)
5307 parse_for (token
->src_loc
);
5308 else if (strcmp (id
, "if") == 0)
5309 parse_if (token
->src_loc
);
5310 else if (strcmp (id
, "define_predicates") == 0)
5312 if (active_ifs
.length () > 0
5313 || active_fors
.length () > 0)
5314 fatal_at (token
, "define_predicates inside if or for is not supported");
5315 parse_predicates (token
->src_loc
);
5317 else if (strcmp (id
, "define_operator_list") == 0)
5319 if (active_ifs
.length () > 0
5320 || active_fors
.length () > 0)
5321 fatal_at (token
, "operator-list inside if or for is not supported");
5322 parse_operator_list (token
->src_loc
);
5325 fatal_at (token
, "expected %s'simplify', 'match', 'for' or 'if'",
5326 active_ifs
.length () == 0 && active_fors
.length () == 0
5327 ? "'define_predicates', " : "");
5329 eat_token (CPP_CLOSE_PAREN
);
5332 /* Helper for finish_match_operand, collecting captures of OP in CPTS
5336 walk_captures (operand
*op
, vec
<vec
<capture
*> > &cpts
)
5341 if (capture
*c
= dyn_cast
<capture
*> (op
))
5343 cpts
[c
->where
].safe_push (c
);
5344 walk_captures (c
->what
, cpts
);
5346 else if (expr
*e
= dyn_cast
<expr
*> (op
))
5347 for (unsigned i
= 0; i
< e
->ops
.length (); ++i
)
5348 walk_captures (e
->ops
[i
], cpts
);
5351 /* Finish up OP which is a match operand. */
5354 parser::finish_match_operand (operand
*op
)
5356 /* Look for matching captures, diagnose mis-uses of @@ and apply
5357 early lowering and distribution of value_match. */
5358 auto_vec
<vec
<capture
*> > cpts
;
5359 cpts
.safe_grow_cleared (capture_ids
->elements (), true);
5360 walk_captures (op
, cpts
);
5361 for (unsigned i
= 0; i
< cpts
.length (); ++i
)
5363 capture
*value_match
= NULL
;
5364 for (unsigned j
= 0; j
< cpts
[i
].length (); ++j
)
5366 if (cpts
[i
][j
]->value_match
)
5369 fatal_at (cpts
[i
][j
]->location
, "duplicate @@");
5370 value_match
= cpts
[i
][j
];
5373 if (cpts
[i
].length () == 1 && value_match
)
5374 fatal_at (value_match
->location
, "@@ without a matching capture");
5377 /* Duplicate prevailing capture with the existing ID, create
5378 a fake ID and rewrite all captures to use it. This turns
5379 @@1 into @__<newid>@1 and @1 into @__<newid>. */
5380 value_match
->what
= new capture (value_match
->location
,
5382 value_match
->what
, false);
5383 /* Create a fake ID and rewrite all captures to use it. */
5384 unsigned newid
= get_internal_capture_id ();
5385 for (unsigned j
= 0; j
< cpts
[i
].length (); ++j
)
5387 cpts
[i
][j
]->where
= newid
;
5388 cpts
[i
][j
]->value_match
= true;
5395 /* Main entry of the parser. Repeatedly parse outer control structures. */
5397 parser::parser (cpp_reader
*r_
, bool gimple_
)
5402 active_fors
= vNULL
;
5403 simplifiers
= vNULL
;
5404 oper_lists_set
= NULL
;
5407 user_predicates
= vNULL
;
5408 parsing_match_operand
= false;
5411 const cpp_token
*token
= next ();
5412 while (token
->type
!= CPP_EOF
)
5414 _cpp_backup_tokens (r
, 1);
5421 /* Helper for the linemap code. */
5424 round_alloc_size (size_t s
)
5430 /* Construct and display the help menu. */
5435 const char *usage
= "Usage:\n"
5436 " %s [--gimple|--generic] [-v[v]] <input>\n"
5437 " %s [options] [--include=FILE] --header=FILE <input> <output>...\n";
5438 fprintf (stderr
, usage
, progname
, progname
);
5441 /* Write out the correct include to the match-head fle containing the helper
5445 write_header_includes (bool gimple
, FILE *header_file
)
5448 fprintf (header_file
, "#include \"gimple-match-head.cc\"\n");
5450 fprintf (header_file
, "#include \"generic-match-head.cc\"\n");
5453 /* The genmatch generator program. It reads from a pattern description
5454 and outputs GIMPLE or GENERIC IL matching and simplification routines. */
5457 main (int argc
, char **argv
)
5461 progname
= "genmatch";
5464 char *s_header_file
= NULL
;
5465 char *s_include_file
= NULL
;
5466 auto_vec
<char *> files
;
5468 int last_file
= argc
- 1;
5469 for (int i
= argc
- 1; i
>= 1; --i
)
5471 if (strcmp (argv
[i
], "--gimple") == 0)
5473 else if (strcmp (argv
[i
], "--generic") == 0)
5475 else if (strncmp (argv
[i
], "--header=", 9) == 0)
5476 s_header_file
= &argv
[i
][9];
5477 else if (strncmp (argv
[i
], "--include=", 10) == 0)
5478 s_include_file
= &argv
[i
][10];
5479 else if (strcmp (argv
[i
], "-v") == 0)
5481 else if (strcmp (argv
[i
], "-vv") == 0)
5483 else if (strncmp (argv
[i
], "--", 2) != 0 && last_file
-- == i
)
5484 files
.safe_push (argv
[i
]);
5492 /* Validate if the combinations are valid. */
5493 if ((files
.length () > 1 && !s_header_file
) || files
.is_empty ())
5499 if (!s_include_file
)
5500 s_include_file
= s_header_file
;
5502 /* Input file is the last in the reverse list. */
5503 input
= files
.pop ();
5505 line_table
= XCNEW (class line_maps
);
5506 linemap_init (line_table
, 0);
5507 line_table
->m_reallocator
= xrealloc
;
5508 line_table
->m_round_alloc_size
= round_alloc_size
;
5510 r
= cpp_create_reader (CLK_GNUC99
, NULL
, line_table
);
5511 cpp_callbacks
*cb
= cpp_get_callbacks (r
);
5512 cb
->diagnostic
= diagnostic_cb
;
5514 /* Add the build directory to the #include "" search path. */
5515 cpp_dir
*dir
= XCNEW (cpp_dir
);
5516 dir
->name
= getpwd ();
5518 dir
->name
= ASTRDUP (".");
5519 cpp_set_include_chains (r
, dir
, NULL
, false);
5521 if (!cpp_read_main_file (r
, input
))
5523 cpp_define (r
, gimple
? "GIMPLE=1": "GENERIC=1");
5524 cpp_define (r
, gimple
? "GENERIC=0": "GIMPLE=0");
5526 null_id
= new id_base (id_base::NULL_ID
, "null");
5528 /* Pre-seed operators. */
5529 operators
= new hash_table
<id_base
> (1024);
5530 #define DEFTREECODE(SYM, STRING, TYPE, NARGS) \
5531 add_operator (SYM, # SYM, # TYPE, NARGS);
5532 #define END_OF_BASE_TREE_CODES
5534 #undef END_OF_BASE_TREE_CODES
5537 /* Pre-seed builtin functions.
5538 ??? Cannot use N (name) as that is targetm.emultls.get_address
5539 for BUILT_IN_EMUTLS_GET_ADDRESS ... */
5540 #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \
5541 add_function (ENUM, "CFN_" # ENUM);
5542 #include "builtins.def"
5544 #define DEF_INTERNAL_FN(CODE, NAME, FNSPEC) \
5545 add_function (IFN_##CODE, "CFN_" #CODE);
5546 #include "internal-fn.def"
5549 parser
p (r
, gimple
);
5551 /* Create file buffers. */
5552 int n_parts
= files
.is_empty () ? 1 : files
.length ();
5553 auto_vec
<FILE *> parts (n_parts
);
5554 if (files
.is_empty ())
5556 parts
.quick_push (stdout
);
5557 write_header (stdout
, s_include_file
);
5558 write_header_includes (gimple
, stdout
);
5559 write_header_declarations (gimple
, stdout
);
5563 for (char *s_file
: files
)
5565 parts
.quick_push (fopen (s_file
, "w"));
5566 write_header (parts
.last (), s_include_file
);
5569 header_file
= fopen (s_header_file
, "w");
5570 fprintf (header_file
, "#ifndef GCC_GIMPLE_MATCH_AUTO_H\n"
5571 "#define GCC_GIMPLE_MATCH_AUTO_H\n");
5572 write_header_includes (gimple
, header_file
);
5573 write_header_declarations (gimple
, header_file
);
5576 /* Go over all predicates defined with patterns and perform
5577 lowering and code generation. */
5578 for (unsigned i
= 0; i
< p
.user_predicates
.length (); ++i
)
5580 predicate_id
*pred
= p
.user_predicates
[i
];
5581 lower (pred
->matchers
, gimple
);
5584 for (unsigned j
= 0; j
< pred
->matchers
.length (); ++j
)
5585 print_matches (pred
->matchers
[j
]);
5588 for (unsigned j
= 0; j
< pred
->matchers
.length (); ++j
)
5589 dt
.insert (pred
->matchers
[j
], j
);
5594 /* Cycle the file buffers. */
5595 FILE *f
= choose_output (parts
);
5597 write_predicate (f
, pred
, dt
, gimple
);
5600 /* Lower the main simplifiers and generate code for them. */
5601 lower (p
.simplifiers
, gimple
);
5604 for (unsigned i
= 0; i
< p
.simplifiers
.length (); ++i
)
5605 print_matches (p
.simplifiers
[i
]);
5608 for (unsigned i
= 0; i
< p
.simplifiers
.length (); ++i
)
5609 dt
.insert (p
.simplifiers
[i
], i
);
5614 dt
.gen (parts
, gimple
);
5616 define_dump_logs (gimple
, choose_output (parts
));
5618 for (FILE *f
: parts
)
5620 fprintf (f
, "#pragma GCC diagnostic pop\n");
5626 fprintf (header_file
, "\n#endif /* GCC_GIMPLE_MATCH_AUTO_H. */\n");
5627 fclose (header_file
);
5631 cpp_finish (r
, NULL
);