Commit 772040f7 by Andreas Krebbel Committed by Andreas Krebbel

gensupport: Fix define_subst operand renumbering.

When processing substitutions the operands are renumbered.  To find a
free operand number the array used_operands_numbers is used.
Currently this array is used to assign new numbers before all the
RTXes in the vector have been processed.  I did run into problems with
this for insns where a match_dup occurred in a later (use ...) operand
referring to an earlier operand (e.g. s390.md "setmem_long").

The patch splits the loop doing the processing into two in order to
have all the operand numbers collected already when assigning new
numbers.

gcc/ChangeLog:

2016-03-01  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>

	* gensupport.c (process_substs_on_one_elem): Split loop to
	complete mark_operands_used_in_match_dup on all expressions in the
	vector first.
	(adjust_operands_numbers): Inline into process_substs_on_one_elem
	and remove function.

From-SVN: r233841
parent 0f09ab88
2016-03-01 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* gensupport.c (process_substs_on_one_elem): Split loop to
complete mark_operands_used_in_match_dup on all expressions in the
vector first.
(adjust_operands_numbers): Inline into process_substs_on_one_elem
and remove function.
2016-02-29 Eric Botcazou <ebotcazou@adacore.com> 2016-02-29 Eric Botcazou <ebotcazou@adacore.com>
PR target/69706 PR target/69706
......
...@@ -126,7 +126,10 @@ static const char * duplicate_each_alternative (const char * str, int n_dup); ...@@ -126,7 +126,10 @@ static const char * duplicate_each_alternative (const char * str, int n_dup);
typedef const char * (*constraints_handler_t) (const char *, int); typedef const char * (*constraints_handler_t) (const char *, int);
static rtx alter_constraints (rtx, int, constraints_handler_t); static rtx alter_constraints (rtx, int, constraints_handler_t);
static rtx adjust_operands_numbers (rtx);
static void mark_operands_used_in_match_dup (rtx);
static void renumerate_operands_in_pattern (rtx);
static rtx replace_duplicating_operands_in_pattern (rtx); static rtx replace_duplicating_operands_in_pattern (rtx);
/* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
...@@ -1844,7 +1847,18 @@ process_substs_on_one_elem (struct queue_elem *elem, ...@@ -1844,7 +1847,18 @@ process_substs_on_one_elem (struct queue_elem *elem,
subst_pattern = alter_constraints (subst_pattern, alternatives, subst_pattern = alter_constraints (subst_pattern, alternatives,
duplicate_each_alternative); duplicate_each_alternative);
subst_pattern = adjust_operands_numbers (subst_pattern); mark_operands_used_in_match_dup (subst_pattern);
RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
}
for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
{
subst_pattern = RTVEC_ELT (subst_pattern_vec, j);
/* The number of MATCH_OPERANDs in the output pattern might
change. This routine assigns new numbers to the
MATCH_OPERAND expressions to avoid collisions. */
renumerate_operands_in_pattern (subst_pattern);
/* Substitute match_dup and match_op_dup in the new pattern and /* Substitute match_dup and match_op_dup in the new pattern and
duplicate constraints. */ duplicate constraints. */
...@@ -1857,7 +1871,6 @@ process_substs_on_one_elem (struct queue_elem *elem, ...@@ -1857,7 +1871,6 @@ process_substs_on_one_elem (struct queue_elem *elem,
if (GET_CODE (elem->data) == DEFINE_EXPAND) if (GET_CODE (elem->data) == DEFINE_EXPAND)
remove_constraints (subst_pattern); remove_constraints (subst_pattern);
RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
} }
XVEC (elem->data, 1) = subst_pattern_vec; XVEC (elem->data, 1) = subst_pattern_vec;
...@@ -1927,7 +1940,7 @@ mark_operands_from_match_dup (rtx pattern) ...@@ -1927,7 +1940,7 @@ mark_operands_from_match_dup (rtx pattern)
} }
} }
/* This is a subroutine of adjust_operands_numbers. /* This is a subroutine of process_substs_on_one_elem.
It goes through all expressions in PATTERN and when MATCH_DUP is It goes through all expressions in PATTERN and when MATCH_DUP is
met, all MATCH_OPERANDs inside it is marked as occupied. The met, all MATCH_OPERANDs inside it is marked as occupied. The
process of marking is done by routin mark_operands_from_match_dup. */ process of marking is done by routin mark_operands_from_match_dup. */
...@@ -1973,10 +1986,9 @@ find_first_unused_number_of_operand () ...@@ -1973,10 +1986,9 @@ find_first_unused_number_of_operand ()
return MAX_OPERANDS; return MAX_OPERANDS;
} }
/* This is subroutine of adjust_operands_numbers. /* This is a subroutine of process_substs_on_one_elem. It visits all
It visits all expressions in PATTERN and assigns not-occupied expressions in PATTERN and assigns not-occupied operand indexes to
operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this MATCH_OPERANDs and MATCH_OPERATORs of this PATTERN. */
PATTERN. */
static void static void
renumerate_operands_in_pattern (rtx pattern) renumerate_operands_in_pattern (rtx pattern)
{ {
...@@ -2011,23 +2023,6 @@ renumerate_operands_in_pattern (rtx pattern) ...@@ -2011,23 +2023,6 @@ renumerate_operands_in_pattern (rtx pattern)
} }
} }
/* If output pattern of define_subst contains MATCH_DUP, then this
expression would be replaced with the pattern, matched with
MATCH_OPERAND from input pattern. This pattern could contain any
number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
that a MATCH_OPERAND from output_pattern (if any) would have the
same number, as MATCH_OPERAND from copied pattern. To avoid such
indexes overlapping, we assign new indexes to MATCH_OPERANDs,
laying in the output pattern outside of MATCH_DUPs. */
static rtx
adjust_operands_numbers (rtx pattern)
{
mark_operands_used_in_match_dup (pattern);
renumerate_operands_in_pattern (pattern);
return pattern;
}
/* Generate RTL expression /* Generate RTL expression
(match_dup OPNO) (match_dup OPNO)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment