aboutsummaryrefslogtreecommitdiff
path: root/gcc/read-rtl.c
diff options
context:
space:
mode:
authorMaxim Kuznetsov <maxim.kuznetsov@intel.com>2012-11-19 10:19:20 +0000
committerKirill Yukhin <kyukhin@gcc.gnu.org>2012-11-19 10:19:20 +0000
commit477c104eafcc18e49eb5779d06dad8a8f02c84f6 (patch)
tree752f646619b03ca24f6fb4099068b498294501fe /gcc/read-rtl.c
parentd826d5c2092961ffe84e1eb9bf89a8fc894ca9b4 (diff)
downloadgcc-477c104eafcc18e49eb5779d06dad8a8f02c84f6.zip
gcc-477c104eafcc18e49eb5779d06dad8a8f02c84f6.tar.gz
gcc-477c104eafcc18e49eb5779d06dad8a8f02c84f6.tar.bz2
md.texi: Document define_subst.
* doc/md.texi: Document define_subst. * gensupport.c (MAX_OPERANDS): New define. (operand_data): New. (match_operand_entries_in_pattern): New. (used_operands_numbers): New. (subst_true): New. (subst_false): New. (define_subst_queue): New. (define_subst_tail): New. (define_subst_attr_queue): New. (define_subst_attr_tail): New. (has_subst_attribute): New. (subst_pattern_match): New. (get_alternatives_number): New. (alter_output_for_subst_insn): New. (alter_attrs_for_subst_insn): New. (process_substs_on_one_elem): New. (subst_dup): New. (process_define_subst): New. (duplicate_alternatives): New. (duplicate_each_alternative): New. (constraints_handler_t): New typedef. (alter_constraints): New. (adjust_operands_numbers): New. (replace_duplicating_operands_in_pattern): New. (remove_from_queue): New. (process_rtx): Handle define_subst and define_subst_attr. (change_subst_attribute): New. (alter_predicate_for_insn): Fix formatting. (alter_attrs_for_insn): Likewise. (alter_output_for_insn): Likewise. (mark_operands_from_match_dup): New. (mark_operands_used_in_match_dup): New. (find_first_unused_number_of_operand): New. (renumerate_operands_in_pattern): New. (generate_match_dup): New. (check_define_attr_duplicates): New. (init_rtx_reader_args_cb): Add checking for duplicated attrs and processing of define_subst. (read_md_rtx): Handle define_subst. * read-rtl.c (struct subst_attr_to_iter_mapping): New. (substs): New global. (apply_subst_iterator): New. (bind_subst_iter_and_attr): New. (find_subst_iter_by_attr): New. (map_attr_string): Handle subst-iterators. (add_condition_to_rtx): Handle define_subst. (apply_iterators): Likewise. (initialize_iterators): Likewise. (add_define_attr_for_define_subst): New. (add_define_subst_attr): New. (read_subst_mapping): New. (read_rtx): Handle define_subst_attr. (read_rtx_code): Add subst-attributes recognition during reading of strings. * rtl.def (DEFINE_EXPAND): Add vector of attributes. (DEFINE_SUBST): New. (DEFINE_SUBST_ATTR): New. Co-Authored-By: Kirill Yukhin <kirill.yukhin@intel.com> Co-Authored-By: Michael Zolotukhin <michael.v.zolotukhin@intel.com> From-SVN: r193618
Diffstat (limited to 'gcc/read-rtl.c')
-rw-r--r--gcc/read-rtl.c277
1 files changed, 270 insertions, 7 deletions
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c
index 027ad91..7da12b5 100644
--- a/gcc/read-rtl.c
+++ b/gcc/read-rtl.c
@@ -102,13 +102,28 @@ struct attribute_use {
/* Vector definitions for the above. */
typedef struct attribute_use attribute_use;
+/* This struct is used to link subst_attr named ATTR_NAME with
+ corresponding define_subst named ITER_NAME. */
+struct subst_attr_to_iter_mapping
+{
+ char *attr_name;
+ char *iter_name;
+};
+
+/* Hash-table to store links between subst-attributes and
+ define_substs. */
+htab_t subst_attr_to_iter_map = NULL;
+/* This global stores name of subst-iterator which is currently being
+ processed. */
+const char *current_iterator_name;
+
static void validate_const_int (const char *);
static rtx read_rtx_code (const char *);
static rtx read_nested_rtx (void);
static rtx read_rtx_variadic (rtx);
/* The mode and code iterator structures. */
-static struct iterator_group modes, codes, ints;
+static struct iterator_group modes, codes, ints, substs;
/* All iterators used in the current rtx. */
static vec<mapping_ptr> current_iterators;
@@ -178,6 +193,91 @@ apply_int_iterator (void *loc, int value)
*(int *)loc = value;
}
+/* This routine adds attribute or does nothing depending on VALUE. When
+ VALUE is 1, it does nothing - the first duplicate of original
+ template is kept untouched when it's subjected to a define_subst.
+ When VALUE isn't 1, the routine modifies RTL-template LOC, adding
+ attribute, named exactly as define_subst, which later will be
+ applied. If such attribute has already been added, then no the
+ routine has no effect. */
+static void
+apply_subst_iterator (void *loc, int value)
+{
+ rtx rt = (rtx)loc;
+ rtx new_attr;
+ rtvec attrs_vec, new_attrs_vec;
+ int i;
+ if (value == 1)
+ return;
+ gcc_assert (GET_CODE (rt) == DEFINE_INSN
+ || GET_CODE (rt) == DEFINE_EXPAND);
+
+ attrs_vec = XVEC (rt, 4);
+
+ /* If we've already added attribute 'current_iterator_name', then we
+ have nothing to do now. */
+ if (attrs_vec)
+ {
+ for (i = 0; i < GET_NUM_ELEM (attrs_vec); i++)
+ {
+ if (strcmp (XSTR (attrs_vec->elem[i], 0), current_iterator_name) == 0)
+ return;
+ }
+ }
+
+ /* Add attribute with subst name - it serves as a mark for
+ define_subst which later would be applied to this pattern. */
+ new_attr = rtx_alloc (SET_ATTR);
+ PUT_CODE (new_attr, SET_ATTR);
+ XSTR (new_attr, 0) = xstrdup (current_iterator_name);
+ XSTR (new_attr, 1) = xstrdup ("yes");
+
+ if (!attrs_vec)
+ {
+ new_attrs_vec = rtvec_alloc (1);
+ new_attrs_vec->elem[0] = new_attr;
+ }
+ else
+ {
+ new_attrs_vec = rtvec_alloc (GET_NUM_ELEM (attrs_vec) + 1);
+ memcpy (&new_attrs_vec->elem[0], &attrs_vec->elem[0],
+ GET_NUM_ELEM (attrs_vec) * sizeof (rtx));
+ new_attrs_vec->elem[GET_NUM_ELEM (attrs_vec)] = new_attr;
+ }
+ XVEC (rt, 4) = new_attrs_vec;
+}
+
+/* Map subst-attribute ATTR to subst iterator ITER. */
+
+static void
+bind_subst_iter_and_attr (const char *iter, const char *attr)
+{
+ struct subst_attr_to_iter_mapping *value;
+ void **slot;
+ if (!subst_attr_to_iter_map)
+ subst_attr_to_iter_map =
+ htab_create (1, leading_string_hash, leading_string_eq_p, 0);
+ value = XNEW (struct subst_attr_to_iter_mapping);
+ value->attr_name = xstrdup (attr);
+ value->iter_name = xstrdup (iter);
+ slot = htab_find_slot (subst_attr_to_iter_map, value, INSERT);
+ *slot = value;
+}
+
+/* Return name of a subst-iterator, corresponding to subst-attribute ATTR. */
+
+static char*
+find_subst_iter_by_attr (const char *attr)
+{
+ char *iter_name = NULL;
+ struct subst_attr_to_iter_mapping *value;
+ value = (struct subst_attr_to_iter_mapping*)
+ htab_find (subst_attr_to_iter_map, &attr);
+ if (value)
+ iter_name = value->iter_name;
+ return iter_name;
+}
+
/* Map attribute string P to its current value. Return null if the attribute
isn't known. */
@@ -216,11 +316,23 @@ map_attr_string (const char *p)
/* Find the attribute specification. */
m = (struct mapping *) htab_find (iterator->group->attrs, &attr);
if (m)
- /* Find the attribute value associated with the current
- iterator value. */
- for (v = m->values; v; v = v->next)
- if (v->number == iterator->current_value->number)
- return v;
+ {
+ /* In contrast to code/mode/int iterators, attributes of subst
+ iterators are linked to one specific subst-iterator. So, if
+ we are dealing with subst-iterator, we should check if it's
+ the one which linked with the given attribute. */
+ if (iterator->group == &substs)
+ {
+ char *iter_name = find_subst_iter_by_attr (attr);
+ if (strcmp (iter_name, iterator->name) != 0)
+ continue;
+ }
+ /* Find the attribute value associated with the current
+ iterator value. */
+ for (v = m->values; v; v = v->next)
+ if (v->number == iterator->current_value->number)
+ return v;
+ }
}
return NULL;
}
@@ -337,6 +449,7 @@ add_condition_to_rtx (rtx x, const char *extra)
{
case DEFINE_INSN:
case DEFINE_EXPAND:
+ case DEFINE_SUBST:
XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra);
break;
@@ -426,6 +539,7 @@ apply_iterators (rtx original, rtx *queue)
htab_traverse (modes.iterators, add_current_iterators, NULL);
htab_traverse (codes.iterators, add_current_iterators, NULL);
htab_traverse (ints.iterators, add_current_iterators, NULL);
+ htab_traverse (substs.iterators, add_current_iterators, NULL);
gcc_assert (!current_iterators.is_empty ());
for (;;)
@@ -435,6 +549,8 @@ apply_iterators (rtx original, rtx *queue)
condition = NULL;
FOR_EACH_VEC_ELT (iterator_uses, i, iuse)
{
+ if (iuse->iterator->group == &substs)
+ continue;
v = iuse->iterator->current_value;
iuse->iterator->group->apply_iterator (iuse->ptr, v->number);
condition = join_c_conditions (condition, v->string);
@@ -443,6 +559,19 @@ apply_iterators (rtx original, rtx *queue)
x = copy_rtx_for_iterators (original);
add_condition_to_rtx (x, condition);
+ /* We apply subst iterator after RTL-template is copied, as during
+ subst-iterator processing, we could add an attribute to the
+ RTL-template, and we don't want to do it in the original one. */
+ FOR_EACH_VEC_ELT (iterator_uses, i, iuse)
+ {
+ v = iuse->iterator->current_value;
+ if (iuse->iterator->group == &substs)
+ {
+ iuse->ptr = x;
+ current_iterator_name = iuse->iterator->name;
+ iuse->iterator->group->apply_iterator (iuse->ptr, v->number);
+ }
+ }
/* Add the new rtx to the end of the queue. */
XEXP (*queue, 0) = x;
XEXP (*queue, 1) = NULL_RTX;
@@ -538,6 +667,12 @@ initialize_iterators (void)
ints.find_builtin = find_int;
ints.apply_iterator = apply_int_iterator;
+ substs.attrs = htab_create (13, leading_string_hash, leading_string_eq_p, 0);
+ substs.iterators = htab_create (13, leading_string_hash,
+ leading_string_eq_p, 0);
+ substs.find_builtin = find_int; /* We don't use it, anyway. */
+ substs.apply_iterator = apply_subst_iterator;
+
lower = add_mapping (&modes, modes.attrs, "mode");
upper = add_mapping (&modes, modes.attrs, "MODE");
lower_ptr = &lower->values;
@@ -780,6 +915,94 @@ read_mapping (struct iterator_group *group, htab_t table)
return m;
}
+/* For iterator with name ATTR_NAME generate define_attr with values
+ 'yes' and 'no'. This attribute is used to mark templates to which
+ define_subst ATTR_NAME should be applied. This attribute is set and
+ defined implicitly and automatically. */
+static void
+add_define_attr_for_define_subst (const char *attr_name, rtx *queue)
+{
+ rtx const_str, return_rtx;
+
+ return_rtx = rtx_alloc (DEFINE_ATTR);
+ PUT_CODE (return_rtx, DEFINE_ATTR);
+
+ const_str = rtx_alloc (CONST_STRING);
+ PUT_CODE (const_str, CONST_STRING);
+ XSTR (const_str, 0) = xstrdup ("no");
+
+ XSTR (return_rtx, 0) = xstrdup (attr_name);
+ XSTR (return_rtx, 1) = xstrdup ("no,yes");
+ XEXP (return_rtx, 2) = const_str;
+
+ XEXP (*queue, 0) = return_rtx;
+ XEXP (*queue, 1) = NULL_RTX;
+}
+
+/* This routine generates DEFINE_SUBST_ATTR expression with operands
+ ATTR_OPERANDS and places it to QUEUE. */
+static void
+add_define_subst_attr (const char **attr_operands, rtx *queue)
+{
+ rtx return_rtx;
+ int i;
+
+ return_rtx = rtx_alloc (DEFINE_SUBST_ATTR);
+ PUT_CODE (return_rtx, DEFINE_SUBST_ATTR);
+
+ for (i = 0; i < 4; i++)
+ XSTR (return_rtx, i) = xstrdup (attr_operands[i]);
+
+ XEXP (*queue, 0) = return_rtx;
+ XEXP (*queue, 1) = NULL_RTX;
+}
+
+/* Read define_subst_attribute construction. It has next form:
+ (define_subst_attribute <attribute_name> <iterator_name> <value1> <value2>)
+ Attribute is substituted with value1 when no subst is applied and with
+ value2 in the opposite case.
+ Attributes are added to SUBST_ATTRS_TABLE.
+ In case the iterator is encountered for the first time, it's added to
+ SUBST_ITERS_TABLE. Also, implicit define_attr is generated. */
+
+static void
+read_subst_mapping (htab_t subst_iters_table, htab_t subst_attrs_table,
+ rtx *queue)
+{
+ struct mapping *m;
+ struct map_value **end_ptr;
+ const char *attr_operands[4];
+ rtx * queue_elem = queue;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ attr_operands[i] = read_string (false);
+
+ add_define_subst_attr (attr_operands, queue_elem);
+
+ bind_subst_iter_and_attr (attr_operands[1], attr_operands[0]);
+
+ m = (struct mapping *) htab_find (substs.iterators, &attr_operands[1]);
+ if (!m)
+ {
+ m = add_mapping (&substs, subst_iters_table, attr_operands[1]);
+ end_ptr = &m->values;
+ end_ptr = add_map_value (end_ptr, 1, "");
+ end_ptr = add_map_value (end_ptr, 2, "");
+
+ /* Add element to the queue. */
+ XEXP (*queue, 1) = rtx_alloc (EXPR_LIST);
+ queue_elem = &XEXP (*queue, 1);
+
+ add_define_attr_for_define_subst (attr_operands[1], queue_elem);
+ }
+
+ m = add_mapping (&substs, subst_attrs_table, attr_operands[0]);
+ end_ptr = &m->values;
+ end_ptr = add_map_value (end_ptr, 1, attr_operands[2]);
+ end_ptr = add_map_value (end_ptr, 2, attr_operands[3]);
+}
+
/* Check newly-created code iterator ITERATOR to see whether every code has the
same format. */
@@ -850,6 +1073,15 @@ read_rtx (const char *rtx_name, rtx *x)
read_mapping (&ints, ints.iterators);
return false;
}
+ if (strcmp (rtx_name, "define_subst_attr") == 0)
+ {
+ read_subst_mapping (substs.iterators, substs.attrs, &queue_head);
+ *x = queue_head;
+
+ /* READ_SUBST_MAPPING could generate a new DEFINE_ATTR. Return
+ TRUE to process it. */
+ return true;
+ }
apply_iterators (read_rtx_code (rtx_name), &queue_head);
iterator_uses.truncate (0);
@@ -868,12 +1100,15 @@ read_rtx_code (const char *code_name)
{
int i;
RTX_CODE code;
- struct mapping *iterator;
+ struct mapping *iterator, *m;
const char *format_ptr;
struct md_name name;
rtx return_rtx;
int c;
HOST_WIDE_INT tmp_wide;
+ char *str;
+ char *start, *end, *ptr;
+ char tmpstr[256];
/* Linked list structure for making RTXs: */
struct rtx_list
@@ -1018,6 +1253,34 @@ read_rtx_code (const char *code_name)
stringbuf = XOBFINISH (&string_obstack, char *);
}
+ /* Find attr-names in the string. */
+ ptr = &tmpstr[0];
+ end = stringbuf;
+ while ((start = strchr (end, '<')) && (end = strchr (start, '>')))
+ {
+ if ((end - start - 1 > 0)
+ && (end - start - 1 < (int)sizeof (tmpstr)))
+ {
+ strncpy (tmpstr, start+1, end-start-1);
+ tmpstr[end-start-1] = 0;
+ end++;
+ }
+ else
+ break;
+ m = (struct mapping *) htab_find (substs.attrs, &ptr);
+ if (m != 0)
+ {
+ /* Here we should find linked subst-iter. */
+ str = find_subst_iter_by_attr (ptr);
+ if (str)
+ m = (struct mapping *) htab_find (substs.iterators, &str);
+ else
+ m = 0;
+ }
+ if (m != 0)
+ record_iterator_use (m, return_rtx);
+ }
+
if (star_if_braced)
XTMPL (return_rtx, i) = stringbuf;
else