diff options
author | Maxim Kuznetsov <maxim.kuznetsov@intel.com> | 2012-11-19 10:19:20 +0000 |
---|---|---|
committer | Kirill Yukhin <kyukhin@gcc.gnu.org> | 2012-11-19 10:19:20 +0000 |
commit | 477c104eafcc18e49eb5779d06dad8a8f02c84f6 (patch) | |
tree | 752f646619b03ca24f6fb4099068b498294501fe /gcc/read-rtl.c | |
parent | d826d5c2092961ffe84e1eb9bf89a8fc894ca9b4 (diff) | |
download | gcc-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.c | 277 |
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 |