===================================================================
@@ -110,6 +110,18 @@
#if GCC_VERSION >= 4001
__attribute__((format (printf, 2, 3)))
#endif
+fatal_at (source_location loc, const char *msg, ...)
+{
+ va_list ap;
+ va_start (ap, msg);
+ error_cb (NULL, CPP_DL_FATAL, 0, loc, 0, msg, &ap);
+ 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;
@@ -549,11 +561,11 @@
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_,
- cid_map_t *capture_ids_)
+ cid_map_t *capture_ids_, vec<user_id *> oper_lists_ = vNULL)
: match (match_), match_location (match_location_),
result (result_), result_location (result_location_),
ifexpr_vec (ifexpr_vec_), for_vec (for_vec_),
- capture_ids (capture_ids_), capture_max (capture_ids_->elements () - 1) {}
+ capture_ids (capture_ids_), capture_max (capture_ids_->elements () - 1), oper_lists (oper_lists_) {}
/* The expression that is matched against the GENERIC or GIMPLE IL. */
operand *match;
@@ -572,6 +584,8 @@
/* A map of capture identifiers to indexes. */
cid_map_t *capture_ids;
int capture_max;
+ /* collected operator-list used in expression */
+ vec<user_id *> oper_lists;
};
/* Debugging routines for dumping the AST. */
@@ -721,7 +735,7 @@
{
simplify *ns = new simplify (matchers[i], s->match_location,
s->result, s->result_location, s->ifexpr_vec,
- s->for_vec, s->capture_ids);
+ s->for_vec, s->capture_ids, s->oper_lists);
simplifiers.safe_push (ns);
}
}
@@ -837,7 +851,7 @@
{
simplify *ns = new simplify (matchers[i], s->match_location,
s->result, s->result_location, s->ifexpr_vec,
- s->for_vec, s->capture_ids);
+ s->for_vec, s->capture_ids, s->oper_lists);
simplifiers.safe_push (ns);
}
}
@@ -934,6 +948,38 @@
simplifiers.safe_push (worklist[i]);
}
+static void
+lower_operator_list (simplify *s, vec<simplify *>& simplifiers)
+{
+ vec<user_id *> oper_lists = s->oper_lists;
+ if (oper_lists == vNULL)
+ {
+ simplifiers.safe_push (s);
+ return;
+ }
+
+ unsigned min = oper_lists[0]->substitutes.length ();
+ for (unsigned i = 1; i < oper_lists.length (); ++i)
+ if (min > oper_lists[i]->substitutes.length ())
+ min = oper_lists[i]->substitutes.length ();
+
+ for (unsigned i = 0; i < oper_lists.length (); ++i)
+ if (oper_lists[i]->substitutes.length () % min != 0)
+ fatal_at (s->match_location, "All user-defined identifiers must have a multiple number "
+ "of operator substittions of the smallest number of substitutions");
+
+ vec< vec<user_id *> > for_vec = vNULL;
+ for_vec.safe_push (oper_lists);
+
+ simplify ns (s->match, s->match_location,
+ s->result, s->result_location,
+ s->ifexpr_vec, for_vec,
+ s->capture_ids);
+
+ lower_for (&ns, simplifiers);
+}
+
+
/* Lower the AST for everything in SIMPLIFIERS. */
static void
@@ -947,14 +993,15 @@
for (unsigned i = 0; i < out_simplifiers0.length (); ++i)
lower_commutative (out_simplifiers0[i], out_simplifiers1);
+ auto_vec<simplify *> out_simplifiers2;
+ for (unsigned i = 0; i < out_simplifiers1.length (); ++i)
+ lower_operator_list (out_simplifiers1[i], out_simplifiers2);
+
simplifiers.truncate (0);
- for (unsigned i = 0; i < out_simplifiers1.length (); ++i)
- lower_for (out_simplifiers1[i], simplifiers);
+ for (unsigned i = 0; i < out_simplifiers2.length (); ++i)
+ lower_for (out_simplifiers2[i], simplifiers);
}
-
-
-
/* The decision tree built for generating GIMPLE and GENERIC pattern
matching code. It represents the 'match' expression of all
simplifies and has those as its leafs. */
@@ -2498,10 +2545,13 @@
void parse_if (source_location);
void parse_predicates (source_location);
void parse_operator_list (source_location);
+
+ bool parsing_for_p () { return active_fors.length () != 0; }
cpp_reader *r;
vec<if_or_with> active_ifs;
vec<vec<user_id *> > active_fors;
+ vec<user_id *> oper_lists;
cid_map_t *capture_ids;
@@ -2669,8 +2719,11 @@
user_id *p = dyn_cast<user_id *> (op);
if (p && p->is_oper_list)
- fatal_at (id_tok, "operator-list not allowed in expression");
-
+ {
+ if (parsing_for_p ())
+ fatal_at (id_tok, "operator-list not allowed in expression enclosed in 'for'");
+ oper_lists.safe_push (p);
+ }
return op;
}
@@ -2807,8 +2860,13 @@
/* 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);
+ {
+ id_base *idb = get_operator ((const char *)CPP_HASHNODE
+ (token->val.node.node)->ident.str);
+ user_id *p;
+ if (idb && (p = dyn_cast<user_id *> (idb)) && p->is_oper_list)
+ oper_lists.safe_push (p);
+ }
/* Record the token. */
code.safe_push (*token);
@@ -2893,6 +2951,8 @@
{
/* Reset the capture map. */
capture_ids = new cid_map_t;
+ /* Reset oper_lists */
+ oper_lists = vNULL;
const cpp_token *loc = peek ();
parsing_match_operand = true;
@@ -2915,7 +2975,7 @@
simplifiers.safe_push
(new simplify (match, match_location, result, token->src_loc,
active_ifs.copy (), active_fors.copy (),
- capture_ids));
+ capture_ids, oper_lists.copy ()));
return;
}
@@ -2941,7 +3001,7 @@
simplifiers.safe_push
(new simplify (match, match_location, result,
paren_loc, active_ifs.copy (),
- active_fors.copy (), capture_ids));
+ active_fors.copy (), capture_ids, oper_lists.copy ()));
}
}
else if (peek_ident ("with"))
@@ -2960,7 +3020,7 @@
simplifiers.safe_push
(new simplify (match, match_location, op,
token->src_loc, active_ifs.copy (),
- active_fors.copy (), capture_ids));
+ active_fors.copy (), capture_ids, oper_lists.copy ()));
eat_token (CPP_CLOSE_PAREN);
/* A "default" result closes the enclosing scope. */
if (active_ifs.length () > active_ifs_len)
@@ -2992,7 +3052,7 @@
(new simplify (match, match_location,
matcher ? result : parse_op (),
token->src_loc, active_ifs.copy (),
- active_fors.copy (), capture_ids));
+ active_fors.copy (), capture_ids, oper_lists.copy ()));
/* A "default" result closes the enclosing scope. */
if (active_ifs.length () > active_ifs_len)
{
@@ -3286,6 +3346,7 @@
active_ifs = vNULL;
active_fors = vNULL;
simplifiers = vNULL;
+ oper_lists = vNULL;
user_predicates = vNULL;
parsing_match_operand = false;
===================================================================
@@ -147,8 +147,6 @@
dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); }
(POW @0 { build_real (type, dconstroot); }))))
/* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
- (for SQRT (BUILT_IN_SQRTF BUILT_IN_SQRT BUILT_IN_SQRTL)
- POW (BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL)
(simplify
- (SQRT (POW @0 @1))
- (POW (abs @0) (mult @1 { build_real (TREE_TYPE (@1), dconsthalf); })))))
+ (SQRTs (POWs @0 @1))
+ (POWs (abs @0) (mult @1 { build_real (TREE_TYPE (@1), dconsthalf); }))))