This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][match-and-simplify] Allow @foo captures
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 25 Sep 2014 15:00:36 +0200 (CEST)
- Subject: [PATCH][match-and-simplify] Allow @foo captures
- Authentication-results: sourceware.org; auth=none
The following makes us assign capture indexes dynamically which
easily allows handling of identifiers. I've used std::map
for this.
Applied.
Note that this may make debugging a little bit harder as
@0 now no longer necessarily corresponds to captures[0]
(I don't think it necessarily did before btw, not 100% sure).
Richard.
2014-09-25 Richard Biener <rguenther@suse.de>
* genmatch.c: Include <map>, <utility> and <string>.
Allow identifiers for captures, assign capture indexes
dynamically.
Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c (revision 215595)
+++ gcc/genmatch.c (working copy)
@@ -22,6 +22,9 @@ along with GCC; see the file COPYING3.
#include "bconfig.h"
#include <new>
+#include <map>
+#include <utility>
+#include <string>
#include "system.h"
#include "coretypes.h"
#include <cpplib.h>
@@ -422,10 +425,10 @@ struct c_expr : public operand
struct capture : public operand
{
- capture (const char *where_, operand *what_)
+ capture (unsigned where_, operand *what_)
: operand (OP_CAPTURE), where (where_), what (what_) {}
- /* Identifier for the value. */
- const char *where;
+ /* Identifier index for the value. */
+ unsigned where;
/* The captured value. */
operand *what;
virtual void gen_transform (FILE *f, const char *, bool, int, const char *, dt_operand ** = 0);
@@ -484,7 +487,7 @@ struct simplify
simplify (operand *match_, source_location match_location_,
struct operand *result_, source_location result_location_,
vec<if_or_with> ifexpr_vec_, vec<vec<user_id *> > for_vec_,
- unsigned capture_max_)
+ int capture_max_)
: match (match_), match_location (match_location_),
result (result_), result_location (result_location_),
ifexpr_vec (ifexpr_vec_), for_vec (for_vec_),
@@ -505,7 +508,7 @@ struct simplify
in the lowering phase. */
vec<vec<user_id *> > for_vec;
/* The maximum capture index seen. */
- unsigned capture_max;
+ int capture_max;
};
/* Debugging routines for dumping the AST. */
@@ -515,7 +518,7 @@ print_operand (operand *o, FILE *f = std
{
if (capture *c = dyn_cast<capture *> (o))
{
- fprintf (f, "@%s", c->where);
+ fprintf (f, "@%u", c->where);
if (c->what && flattened == false)
{
putc (':', f);
@@ -1122,7 +1125,7 @@ decision_tree::insert_operand (dt_node *
if (capture *c = dyn_cast<capture *> (o))
{
- unsigned capt_index = atoi (c->where);
+ unsigned capt_index = c->where;
if (indexes[capt_index] == 0)
{
@@ -1141,7 +1144,7 @@ decision_tree::insert_operand (dt_node *
if (!c->what)
{
- unsigned cc_index = atoi (c->where);
+ unsigned cc_index = c->where;
dt_operand *match_op = indexes[cc_index];
dt_operand temp (dt_node::DT_TRUE, 0, 0);
@@ -1224,7 +1227,7 @@ decision_tree::print_node (dt_node *p, F
{
dt_simplify *s = static_cast<dt_simplify *> (p);
fprintf (f, "simplify_%u { ", s->pattern_no);
- for (unsigned i = 0; i <= s->s->capture_max; ++i)
+ for (int i = 0; i <= s->s->capture_max; ++i)
fprintf (f, "%p, ", (void *) s->indexes[i]);
fprintf (f, " } ");
}
@@ -1446,16 +1449,15 @@ capture::gen_transform (FILE *f, const c
{
if (what && is_a<expr *> (what))
{
- int index = atoi (where);
- if (indexes[index] == 0)
+ if (indexes[where] == 0)
{
char buf[20];
- sprintf (buf, "captures[%s]", where);
+ sprintf (buf, "captures[%u]", where);
what->gen_transform (f, buf, gimple, depth, in_type, NULL);
}
}
- fprintf (f, "%s = captures[%s];\n", dest, where);
+ fprintf (f, "%s = captures[%u];\n", dest, where);
}
char *
@@ -1940,10 +1942,11 @@ dt_simplify::gen (FILE *f, bool gimple)
{
fprintf (f, "{\n");
output_line_directive (f, s->result_location);
- fprintf (f, "tree captures[%u] ATTRIBUTE_UNUSED = {};\n",
- s->capture_max + 1);
+ if (s->capture_max >= 0)
+ fprintf (f, "tree captures[%u] ATTRIBUTE_UNUSED = {};\n",
+ s->capture_max + 1);
- for (unsigned i = 0; i <= s->capture_max; ++i)
+ for (int i = 0; i <= s->capture_max; ++i)
if (indexes[i])
{
char opname[20];
@@ -2280,7 +2283,9 @@ private:
cpp_reader *r;
vec<if_or_with> active_ifs;
vec<vec<user_id *> > active_fors;
- unsigned capture_max;
+
+ int capture_max;
+ std::map<std::string, unsigned> *capture_ids;
public:
vec<simplify *> simplifiers;
@@ -2448,12 +2453,20 @@ struct operand *
parser::parse_capture (operand *op)
{
eat_token (CPP_ATSIGN);
- /* ??? Ideally we'd accept any identifier or number here
- and dynamically assign an index to them. */
- const char *id = get_number ();
- if ((unsigned) atoi (id) > capture_max)
- capture_max = atoi (id);
- return new capture (id, op);
+ const cpp_token *token = peek ();
+ const char *id;
+ if (token->type == CPP_NUMBER)
+ id = get_number ();
+ else if (token->type == CPP_NAME)
+ id = get_ident ();
+ else
+ fatal_at (token, "expected number or identifier");
+ std::pair<std::map<std::string, unsigned>::iterator, bool> res
+ = capture_ids->insert
+ (std::pair<std::string, unsigned>(id, capture_max + 1));
+ if (res.second)
+ capture_max++;
+ return new capture ((*res.first).second, op);
}
/* Parse an expression
@@ -2633,7 +2646,9 @@ parser::parse_simplify (source_location
vec<simplify *>& simplifiers, predicate_id *matcher)
{
/* Reset the maximum capture number seen. */
- capture_max = 0;
+ std::map<std::string, unsigned> cids;
+ capture_max = -1;
+ capture_ids = &cids;
const cpp_token *loc = peek ();
struct operand *match = parse_op ();