[multiple changes]
2014-11-12 Richard Biener <rguenther@suse.de> Merge from match-and-simplify branch 2014-11-04 Prathamesh Kulkarni <bilbotheelffriend@gmail.com> * genmatch.c (user_id): Add new member is_oper_list. (user_id::user_id): Add new default argument. (parser::parse_operator_list): New function. (parser::parse_for): Allow operator-list. (parser::parse_pattern): Call parser::parse_operator_list. (parser::parse_operation): Reject operator-list. * match-builtin.pd: Define operator lists POWs, CBRTs and SQRTs. 2014-10-31 Prathamesh Kulkarni <bilbotheelffriend@gmail.com> * genmatch.c (parser::parse_c_expr): Mark user-defined ops as used. 2014-10-30 Prathamesh Kulkarni <bilbotheelffriend@gmail.com> * genmatch.c (parser::parse_op): Check if predicate is used in result operand. 2014-10-29 Prathamesh Kulkarni <bilbotheelffriend@gmail.com> * genmatch.c (parser::parse_for): Make sure to have a valid token to report errors at. 2014-10-28 Prathamesh Kulkarni <bilbotheelffriend@gmail.com> * genmatch.c (parser): Add new member parsing_match_operand. (parser::parse_operation): Check for conditional convert in result operand. (parser::parse_expr): Check for commutative operator in result operand. Check for :type in match operand. (parser::parse_simplify): Set/unset parsing_match_operand. (parser::parser): Initialize parsing_match_operand. 2014-10-28 Richard Biener <rguenther@suse.de> * genmatch.c (parser::parse_for): Properly check for already defined operators. 2014-10-28 Prathamesh Kulkarni <bilbotheelffriend@gmail.com> * genmatch.c (error_cb): Adjust for printing warnings. (warning_at): New function. (user_id): Add new member used. (get_operator): Mark user_id as used. (parse_for): Warn for unused operators. From-SVN: r217422
This commit is contained in:
parent
eaeba53a03
commit
72eb311da1
@ -1,3 +1,53 @@
|
||||
2014-11-12 Richard Biener <rguenther@suse.de>
|
||||
|
||||
Merge from match-and-simplify branch
|
||||
2014-11-04 Prathamesh Kulkarni <bilbotheelffriend@gmail.com>
|
||||
|
||||
* genmatch.c (user_id): Add new member is_oper_list.
|
||||
(user_id::user_id): Add new default argument.
|
||||
(parser::parse_operator_list): New function.
|
||||
(parser::parse_for): Allow operator-list.
|
||||
(parser::parse_pattern): Call parser::parse_operator_list.
|
||||
(parser::parse_operation): Reject operator-list.
|
||||
* match-builtin.pd: Define operator lists POWs, CBRTs and SQRTs.
|
||||
|
||||
2014-10-31 Prathamesh Kulkarni <bilbotheelffriend@gmail.com>
|
||||
|
||||
* genmatch.c (parser::parse_c_expr): Mark user-defined ops as used.
|
||||
|
||||
2014-10-30 Prathamesh Kulkarni <bilbotheelffriend@gmail.com>
|
||||
|
||||
* genmatch.c (parser::parse_op): Check if predicate is used in
|
||||
result operand.
|
||||
|
||||
2014-10-29 Prathamesh Kulkarni <bilbotheelffriend@gmail.com>
|
||||
|
||||
* genmatch.c (parser::parse_for): Make sure to have a valid
|
||||
token to report errors at.
|
||||
|
||||
2014-10-28 Prathamesh Kulkarni <bilbotheelffriend@gmail.com>
|
||||
|
||||
* genmatch.c (parser): Add new member parsing_match_operand.
|
||||
(parser::parse_operation): Check for conditional convert in result
|
||||
operand.
|
||||
(parser::parse_expr): Check for commutative operator in result operand.
|
||||
Check for :type in match operand.
|
||||
(parser::parse_simplify): Set/unset parsing_match_operand.
|
||||
(parser::parser): Initialize parsing_match_operand.
|
||||
|
||||
2014-10-28 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* genmatch.c (parser::parse_for): Properly check for already
|
||||
defined operators.
|
||||
|
||||
2014-10-28 Prathamesh Kulkarni <bilbotheelffriend@gmail.com>
|
||||
|
||||
* genmatch.c (error_cb): Adjust for printing warnings.
|
||||
(warning_at): New function.
|
||||
(user_id): Add new member used.
|
||||
(get_operator): Mark user_id as used.
|
||||
(parse_for): Warn for unused operators.
|
||||
|
||||
2014-11-12 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* match.pd: Implement simple complex operations cancelling.
|
||||
|
150
gcc/genmatch.c
150
gcc/genmatch.c
@ -54,13 +54,14 @@ static bool
|
||||
#if GCC_VERSION >= 4001
|
||||
__attribute__((format (printf, 6, 0)))
|
||||
#endif
|
||||
error_cb (cpp_reader *, int, int, source_location location,
|
||||
error_cb (cpp_reader *, int errtype, int, source_location location,
|
||||
unsigned int, const char *msg, va_list *ap)
|
||||
{
|
||||
const line_map *map;
|
||||
linemap_resolve_location (line_table, location, LRK_SPELLING_LOCATION, &map);
|
||||
expanded_location loc = linemap_expand_location (line_table, map, location);
|
||||
fprintf (stderr, "%s:%d:%d error: ", loc.file, loc.line, loc.column);
|
||||
fprintf (stderr, "%s:%d:%d %s: ", loc.file, loc.line, loc.column,
|
||||
(errtype == CPP_DL_WARNING) ? "warning" : "error");
|
||||
vfprintf (stderr, msg, *ap);
|
||||
fprintf (stderr, "\n");
|
||||
FILE *f = fopen (loc.file, "r");
|
||||
@ -86,7 +87,10 @@ error_cb (cpp_reader *, int, int, source_location location,
|
||||
notfound:
|
||||
fclose (f);
|
||||
}
|
||||
exit (1);
|
||||
|
||||
if (errtype == CPP_DL_FATAL)
|
||||
exit (1);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -101,6 +105,18 @@ fatal_at (const cpp_token *tk, const char *msg, ...)
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
static void
|
||||
#if GCC_VERSION >= 4001
|
||||
__attribute__((format (printf, 2, 3)))
|
||||
#endif
|
||||
warning_at (const cpp_token *tk, const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, msg);
|
||||
error_cb (NULL, CPP_DL_WARNING, 0, tk->src_loc, 0, msg, &ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
static void
|
||||
output_line_directive (FILE *f, source_location location,
|
||||
bool dumpfile = false)
|
||||
@ -228,9 +244,12 @@ struct predicate_id : public id_base
|
||||
|
||||
struct user_id : public id_base
|
||||
{
|
||||
user_id (const char *id_)
|
||||
: id_base (id_base::USER, id_), substitutes (vNULL) {}
|
||||
user_id (const char *id_, bool is_oper_list_ = false)
|
||||
: id_base (id_base::USER, id_), substitutes (vNULL),
|
||||
used (false), is_oper_list (is_oper_list_) {}
|
||||
vec<id_base *> substitutes;
|
||||
bool used;
|
||||
bool is_oper_list;
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -331,7 +350,12 @@ get_operator (const char *id)
|
||||
|
||||
id_base *op = operators->find_with_hash (&tem, tem.hashval);
|
||||
if (op)
|
||||
return op;
|
||||
{
|
||||
/* If this is a user-defined identifier track whether it was used. */
|
||||
if (user_id *uid = dyn_cast<user_id *> (op))
|
||||
uid->used = true;
|
||||
return op;
|
||||
}
|
||||
|
||||
/* Try all-uppercase. */
|
||||
char *id2 = xstrdup (id);
|
||||
@ -2650,6 +2674,7 @@ private:
|
||||
void parse_for (source_location);
|
||||
void parse_if (source_location);
|
||||
void parse_predicates (source_location);
|
||||
void parse_operator_list (source_location);
|
||||
|
||||
cpp_reader *r;
|
||||
vec<if_or_with> active_ifs;
|
||||
@ -2660,6 +2685,7 @@ private:
|
||||
public:
|
||||
vec<simplify *> simplifiers;
|
||||
vec<predicate_id *> user_predicates;
|
||||
bool parsing_match_operand;
|
||||
};
|
||||
|
||||
/* Lexing helpers. */
|
||||
@ -2805,6 +2831,10 @@ parser::parse_operation ()
|
||||
;
|
||||
else
|
||||
fatal_at (id_tok, "non-convert operator conditionalized");
|
||||
|
||||
if (!parsing_match_operand)
|
||||
fatal_at (id_tok, "conditional convert can only be used in "
|
||||
"match expression");
|
||||
eat_token (CPP_QUERY);
|
||||
}
|
||||
else if (strcmp (id, "convert1") == 0
|
||||
@ -2813,6 +2843,11 @@ parser::parse_operation ()
|
||||
id_base *op = get_operator (id);
|
||||
if (!op)
|
||||
fatal_at (id_tok, "unknown operator %s", id);
|
||||
|
||||
user_id *p = dyn_cast<user_id *> (op);
|
||||
if (p && p->is_oper_list)
|
||||
fatal_at (id_tok, "operator-list not allowed in expression");
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
@ -2824,7 +2859,7 @@ parser::parse_capture (operand *op)
|
||||
{
|
||||
eat_token (CPP_ATSIGN);
|
||||
const cpp_token *token = peek ();
|
||||
const char *id;
|
||||
const char *id = NULL;
|
||||
if (token->type == CPP_NUMBER)
|
||||
id = get_number ();
|
||||
else if (token->type == CPP_NAME)
|
||||
@ -2861,11 +2896,21 @@ parser::parse_expr ()
|
||||
{
|
||||
const char *s = get_ident ();
|
||||
if (s[0] == 'c' && !s[1])
|
||||
is_commutative = true;
|
||||
{
|
||||
if (!parsing_match_operand)
|
||||
fatal_at (token,
|
||||
"flag 'c' can only be used in match expression");
|
||||
is_commutative = true;
|
||||
}
|
||||
else if (s[1] != '\0')
|
||||
expr_type = s;
|
||||
{
|
||||
if (parsing_match_operand)
|
||||
fatal_at (token, "type can only be used in result expression");
|
||||
expr_type = s;
|
||||
}
|
||||
else
|
||||
fatal_at (token, "flag %s not recognized", s);
|
||||
|
||||
token = peek ();
|
||||
}
|
||||
else
|
||||
@ -2937,6 +2982,11 @@ parser::parse_c_expr (cpp_ttype start)
|
||||
if (token->type == CPP_SEMICOLON)
|
||||
nr_stmts++;
|
||||
|
||||
/* If this is possibly a user-defined identifier mark it used. */
|
||||
if (token->type == CPP_NAME)
|
||||
get_operator ((const char *)CPP_HASHNODE
|
||||
(token->val.node.node)->ident.str);
|
||||
|
||||
/* Record the token. */
|
||||
code.safe_push (*token);
|
||||
}
|
||||
@ -2984,6 +3034,8 @@ parser::parse_op ()
|
||||
op = new predicate (p);
|
||||
else
|
||||
fatal_at (token, "using an unsupported operator as predicate");
|
||||
if (!parsing_match_operand)
|
||||
fatal_at (token, "predicates are only allowed in match expression");
|
||||
token = peek ();
|
||||
if (token->flags & PREV_WHITE)
|
||||
return op;
|
||||
@ -3020,7 +3072,9 @@ parser::parse_simplify (source_location match_location,
|
||||
capture_ids = new cid_map_t;
|
||||
|
||||
const cpp_token *loc = peek ();
|
||||
parsing_match_operand = true;
|
||||
struct operand *match = parse_op ();
|
||||
parsing_match_operand = false;
|
||||
if (match->type == operand::OP_CAPTURE && !matcher)
|
||||
fatal_at (loc, "outermost expression cannot be captured");
|
||||
if (match->type == operand::OP_EXPR
|
||||
@ -3138,24 +3192,26 @@ parser::parse_simplify (source_location match_location,
|
||||
void
|
||||
parser::parse_for (source_location)
|
||||
{
|
||||
auto_vec<const cpp_token *> user_id_tokens;
|
||||
vec<user_id *> user_ids = vNULL;
|
||||
const cpp_token *token;
|
||||
unsigned min_n_opers = 0, max_n_opers = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
token = peek_ident ();
|
||||
if (token == 0)
|
||||
token = peek ();
|
||||
if (token->type != CPP_NAME)
|
||||
break;
|
||||
|
||||
/* Insert the user defined operators into the operator hash. */
|
||||
const char *id = get_ident ();
|
||||
if (get_operator (id) != NULL)
|
||||
fatal_at (token, "operator already defined");
|
||||
user_id *op = new user_id (id);
|
||||
id_base **slot = operators->find_slot_with_hash (op, op->hashval, INSERT);
|
||||
if (*slot)
|
||||
fatal_at (token, "operator already defined");
|
||||
*slot = op;
|
||||
user_ids.safe_push (op);
|
||||
user_id_tokens.safe_push (token);
|
||||
|
||||
eat_token (CPP_OPEN_PAREN);
|
||||
|
||||
@ -3177,7 +3233,11 @@ parser::parse_for (source_location)
|
||||
fatal_at (token, "operator '%s' with arity %d does not match "
|
||||
"others with arity %d", oper, idb->nargs, arity);
|
||||
|
||||
op->substitutes.safe_push (idb);
|
||||
user_id *p = dyn_cast<user_id *> (idb);
|
||||
if (p && p->is_oper_list)
|
||||
op->substitutes.safe_splice (p->substitutes);
|
||||
else
|
||||
op->substitutes.safe_push (idb);
|
||||
}
|
||||
op->nargs = arity;
|
||||
token = expect (CPP_CLOSE_PAREN);
|
||||
@ -3225,7 +3285,59 @@ parser::parse_for (source_location)
|
||||
|
||||
/* Remove user-defined operators from the hash again. */
|
||||
for (unsigned i = 0; i < user_ids.length (); ++i)
|
||||
operators->remove_elt (user_ids[i]);
|
||||
{
|
||||
if (!user_ids[i]->used)
|
||||
warning_at (user_id_tokens[i],
|
||||
"operator %s defined but not used", user_ids[i]->id);
|
||||
operators->remove_elt (user_ids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse an identifier associated with a list of operators.
|
||||
oprs = '(' 'define_operator_list' <ident> <ident>... ')' */
|
||||
|
||||
void
|
||||
parser::parse_operator_list (source_location)
|
||||
{
|
||||
const cpp_token *token = peek ();
|
||||
const char *id = get_ident ();
|
||||
|
||||
if (get_operator (id) != 0)
|
||||
fatal_at (token, "operator %s already defined", id);
|
||||
|
||||
user_id *op = new user_id (id, true);
|
||||
int arity = -1;
|
||||
|
||||
while ((token = peek_ident ()) != 0)
|
||||
{
|
||||
token = peek ();
|
||||
const char *oper = get_ident ();
|
||||
id_base *idb = get_operator (oper);
|
||||
|
||||
if (idb == 0)
|
||||
fatal_at (token, "no such operator '%s'", oper);
|
||||
|
||||
if (arity == -1)
|
||||
arity = idb->nargs;
|
||||
else if (idb->nargs == -1)
|
||||
;
|
||||
else if (arity != idb->nargs)
|
||||
fatal_at (token, "operator '%s' with arity %d does not match "
|
||||
"others with arity %d", oper, idb->nargs, arity);
|
||||
|
||||
/* We allow composition of multiple operator lists. */
|
||||
if (user_id *p = dyn_cast<user_id *> (idb))
|
||||
op->substitutes.safe_splice (p->substitutes);
|
||||
else
|
||||
op->substitutes.safe_push (idb);
|
||||
}
|
||||
|
||||
if (op->substitutes.length () == 0)
|
||||
fatal_at (token, "operator-list cannot be empty");
|
||||
|
||||
op->nargs = arity;
|
||||
id_base **slot = operators->find_slot_with_hash (op, op->hashval, INSERT);
|
||||
*slot = op;
|
||||
}
|
||||
|
||||
/* Parse an outer if expression.
|
||||
@ -3328,6 +3440,13 @@ parser::parse_pattern ()
|
||||
fatal_at (token, "define_predicates inside if or for is not supported");
|
||||
parse_predicates (token->src_loc);
|
||||
}
|
||||
else if (strcmp (id, "define_operator_list") == 0)
|
||||
{
|
||||
if (active_ifs.length () > 0
|
||||
|| active_fors.length () > 0)
|
||||
fatal_at (token, "operator-list inside if or for is not supported");
|
||||
parse_operator_list (token->src_loc);
|
||||
}
|
||||
else
|
||||
fatal_at (token, "expected %s'simplify', 'match', 'for' or 'if'",
|
||||
active_ifs.length () == 0 && active_fors.length () == 0
|
||||
@ -3345,6 +3464,7 @@ parser::parser (cpp_reader *r_)
|
||||
active_fors = vNULL;
|
||||
simplifiers = vNULL;
|
||||
user_predicates = vNULL;
|
||||
parsing_match_operand = false;
|
||||
|
||||
const cpp_token *token = next ();
|
||||
while (token->type != CPP_EOF)
|
||||
|
Loading…
Reference in New Issue
Block a user