rtl.texi (SET, CLOBBER): Document PARALLEL as SET_DEST possibility.

* rtl.texi (SET, CLOBBER): Document PARALLEL as SET_DEST possibility.
	* flow.c (mark_set_1, case PARALLEL): Don't require BLKmode, allow
	element to be null, and always expect an EXPR_LIST.
	* rtlanal.c (reg_overlap_mentioned_p, note_stores): Likewise.
	* sched-deps.c (sched_analyze_1): Likewise.
	* sched-rgn.c (check_live_1, update_live_1): Likewise.

From-SVN: r39141
This commit is contained in:
Richard Kenner 2001-01-19 18:28:58 +00:00 committed by Richard Kenner
parent 79b9ec0ddb
commit 7193d1dc3d
6 changed files with 53 additions and 68 deletions

View File

@ -1,5 +1,12 @@
Fri Jan 19 13:02:56 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* rtl.texi (SET, CLOBBER): Document PARALLEL as SET_DEST possibility.
* flow.c (mark_set_1, case PARALLEL): Don't require BLKmode, allow
element to be null, and always expect an EXPR_LIST.
* rtlanal.c (reg_overlap_mentioned_p, note_stores): Likewise.
* sched-deps.c (sched_analyze_1): Likewise.
* sched-rgn.c (check_live_1, update_live_1): Likewise.
* regclass.c (max_set_parallel): New variable.
(reg_scan): Take it into account in computation of max_parallel.
(reg_scan_mark_refs, case SET): Compute it.

View File

@ -4660,19 +4660,11 @@ mark_set_1 (pbi, code, reg, cond, insn, flags)
case PARALLEL:
/* Some targets place small structures in registers for return values of
functions. We have to detect this case specially here to get correct
flow information. Note that each element might be either a REG
or an EXPR_LIST whose first operand is a REG. */
if (GET_MODE (reg) != BLKmode)
abort ();
flow information. */
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
{
rtx elmt = XVECEXP (reg, 0, i);
mark_set_1 (pbi, code,
GET_CODE (elmt) == EXPR_LIST ? XEXP (elmt, 0) : elmt,
cond, insn, flags);
}
if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
mark_set_1 (pbi, code, XEXP (XVECEXP (reg, 0, i), 0), cond, insn,
flags);
return;
case ZERO_EXTRACT:

View File

@ -1923,8 +1923,8 @@ the operands of these.
@item (set @var{lval} @var{x})
Represents the action of storing the value of @var{x} into the place
represented by @var{lval}. @var{lval} must be an expression
representing a place that can be stored in: @code{reg} (or
@code{subreg} or @code{strict_low_part}), @code{mem}, @code{pc} or
representing a place that can be stored in: @code{reg} (or @code{subreg}
or @code{strict_low_part}), @code{mem}, @code{pc}, @code{parallel}, or
@code{cc0}.@refill
If @var{lval} is a @code{reg}, @code{subreg} or @code{mem}, it has a
@ -1950,6 +1950,14 @@ The latter case represents a ``test'' instruction. The expression
@code{(set (cc0) (compare (reg:@var{m} @var{n}) (const_int 0)))}.
Use the former expression to save space during the compilation.
If @var{lval} is a @code{parallel}, it is used to represent the case of
a function returning a structure in multiple registers. Each element
of the @code{paralllel} is an @code{expr_list} whose first operand is a
@code{reg} and whose second operand is a @code{const_int} representing the
offset (in bytes) into the structure at which the data in that register
corresponds. The first element may be null to indicate that the structure
is also passed partly in memory.
@cindex jump instructions and @code{set}
@cindex @code{if_then_else} usage
If @var{lval} is @code{(pc)}, we have a jump instruction, and the
@ -2006,7 +2014,7 @@ addressed.
@item (clobber @var{x})
Represents the storing or possible storing of an unpredictable,
undescribed value into @var{x}, which must be a @code{reg},
@code{scratch} or @code{mem} expression.
@code{scratch}, @code{parallel} or @code{mem} expression.
One place this is used is in string instructions that store standard
values into particular hard registers. It may not be worth the
@ -2015,7 +2023,8 @@ inform the compiler that the registers will be altered, lest it
attempt to keep data in them across the string instruction.
If @var{x} is @code{(mem:BLK (const_int 0))}, it means that all memory
locations must be presumed clobbered.
locations must be presumed clobbered. If @var{x} is a @code{parallel},
it has the same meaning as a @code{parallel} in a @code{set} expression.
Note that the machine description classifies certain hard registers as
``call-clobbered''. All function call instructions are assumed by

View File

@ -1185,18 +1185,11 @@ reg_overlap_mentioned_p (x, in)
int i;
/* If any register in here refers to it we return true. */
for (i = XVECLEN (x, 0); i >= 0; i--)
{
rtx reg = XVECEXP (x, 0, i);
if (GET_CODE (reg) == EXPR_LIST)
reg = XEXP (reg, 0);
if (reg_overlap_mentioned_p (reg, in))
for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
if (XEXP (XVECEXP (x, 0, i), 0) != 0
&& reg_overlap_mentioned_p (XEXP (XVECEXP (x, 0, i), 0), in))
return 1;
return 0;
}
return 0;
}
default:
@ -1288,20 +1281,19 @@ note_stores (x, fun, data)
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
/* If we have a PARALLEL, SET_DEST is a list of registers or
EXPR_LIST expressions, each of whose first operand is a register.
We can't know what precisely is being set in these cases, so
make up a CLOBBER to pass to the function. */
if (GET_CODE (dest) == PARALLEL && GET_MODE (dest) == BLKmode)
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
{
rtx reg = XVECEXP (dest, 0, i);
if (GET_CODE (reg) == EXPR_LIST)
reg = XEXP (reg, 0);
(*fun) (reg, gen_rtx_CLOBBER (VOIDmode, reg), data);
}
/* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
each of whose first operand is a register. We can't know what
precisely is being set in these cases, so make up a CLOBBER to pass
to the function. */
if (GET_CODE (dest) == PARALLEL)
{
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
(*fun) (XEXP (XVECEXP (dest, 0, i), 0),
gen_rtx_CLOBBER (VOIDmode,
XEXP (XVECEXP (dest, 0, i), 0)),
data);
}
else
(*fun) (dest, x, data);
}

View File

@ -551,19 +551,16 @@ sched_analyze_1 (deps, x, insn)
if (dest == 0)
return;
if (GET_CODE (dest) == PARALLEL && GET_MODE (dest) == BLKmode)
if (GET_CODE (dest) == PARALLEL)
{
register int i;
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
{
rtx reg = XVECEXP (dest, 0, i);
if (GET_CODE (reg) == EXPR_LIST)
reg = XEXP (reg, 0);
sched_analyze_1 (deps, reg, insn);
}
if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
sched_analyze_1 (deps,
gen_rtx_CLOBBER (VOIDmode,
XEXP (XVECEXP (dest, 0, i), 0)),
insn);
if (GET_CODE (x) == SET)
sched_analyze_2 (deps, SET_SRC (x), insn);

View File

@ -1396,20 +1396,14 @@ check_live_1 (src, x)
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
if (GET_CODE (reg) == PARALLEL && GET_MODE (reg) == BLKmode)
if (GET_CODE (reg) == PARALLEL)
{
register int i;
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
{
rtx dest = XVECEXP (reg, 0, i);
if (GET_CODE (dest) == EXPR_LIST)
dest = XEXP (dest, 0);
if (check_live_1 (src, dest))
if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
if (check_live_1 (src, XEXP (XVECEXP (reg, 0, i), 0)))
return 1;
}
return 0;
}
@ -1482,19 +1476,13 @@ update_live_1 (src, x)
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
if (GET_CODE (reg) == PARALLEL && GET_MODE (reg) == BLKmode)
if (GET_CODE (reg) == PARALLEL)
{
register int i;
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
{
rtx dest = XVECEXP (reg, 0, i);
if (GET_CODE (dest) == EXPR_LIST)
dest = XEXP (dest, 0);
update_live_1 (src, dest);
}
if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
update_live_1 (src, XEXP (XVECEXP (reg, 0, i), 0));
return;
}