Commit 7193d1dc by Richard Kenner Committed by Richard Kenner

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
parent 79b9ec0d
Fri Jan 19 13:02:56 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> 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. * regclass.c (max_set_parallel): New variable.
(reg_scan): Take it into account in computation of max_parallel. (reg_scan): Take it into account in computation of max_parallel.
(reg_scan_mark_refs, case SET): Compute it. (reg_scan_mark_refs, case SET): Compute it.
......
...@@ -4660,19 +4660,11 @@ mark_set_1 (pbi, code, reg, cond, insn, flags) ...@@ -4660,19 +4660,11 @@ mark_set_1 (pbi, code, reg, cond, insn, flags)
case PARALLEL: case PARALLEL:
/* Some targets place small structures in registers for return values of /* Some targets place small structures in registers for return values of
functions. We have to detect this case specially here to get correct functions. We have to detect this case specially here to get correct
flow information. Note that each element might be either a REG flow information. */
or an EXPR_LIST whose first operand is a REG. */
if (GET_MODE (reg) != BLKmode)
abort ();
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--) for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
{ if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
rtx elmt = XVECEXP (reg, 0, i); mark_set_1 (pbi, code, XEXP (XVECEXP (reg, 0, i), 0), cond, insn,
flags);
mark_set_1 (pbi, code,
GET_CODE (elmt) == EXPR_LIST ? XEXP (elmt, 0) : elmt,
cond, insn, flags);
}
return; return;
case ZERO_EXTRACT: case ZERO_EXTRACT:
......
...@@ -1923,8 +1923,8 @@ the operands of these. ...@@ -1923,8 +1923,8 @@ the operands of these.
@item (set @var{lval} @var{x}) @item (set @var{lval} @var{x})
Represents the action of storing the value of @var{x} into the place Represents the action of storing the value of @var{x} into the place
represented by @var{lval}. @var{lval} must be an expression represented by @var{lval}. @var{lval} must be an expression
representing a place that can be stored in: @code{reg} (or representing a place that can be stored in: @code{reg} (or @code{subreg}
@code{subreg} or @code{strict_low_part}), @code{mem}, @code{pc} or or @code{strict_low_part}), @code{mem}, @code{pc}, @code{parallel}, or
@code{cc0}.@refill @code{cc0}.@refill
If @var{lval} is a @code{reg}, @code{subreg} or @code{mem}, it has a 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 ...@@ -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)))}. @code{(set (cc0) (compare (reg:@var{m} @var{n}) (const_int 0)))}.
Use the former expression to save space during the compilation. 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 jump instructions and @code{set}
@cindex @code{if_then_else} usage @cindex @code{if_then_else} usage
If @var{lval} is @code{(pc)}, we have a jump instruction, and the If @var{lval} is @code{(pc)}, we have a jump instruction, and the
...@@ -2006,7 +2014,7 @@ addressed. ...@@ -2006,7 +2014,7 @@ addressed.
@item (clobber @var{x}) @item (clobber @var{x})
Represents the storing or possible storing of an unpredictable, Represents the storing or possible storing of an unpredictable,
undescribed value into @var{x}, which must be a @code{reg}, 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 One place this is used is in string instructions that store standard
values into particular hard registers. It may not be worth the 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 ...@@ -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. 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 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 Note that the machine description classifies certain hard registers as
``call-clobbered''. All function call instructions are assumed by ``call-clobbered''. All function call instructions are assumed by
......
...@@ -1185,18 +1185,11 @@ reg_overlap_mentioned_p (x, in) ...@@ -1185,18 +1185,11 @@ reg_overlap_mentioned_p (x, in)
int i; int i;
/* If any register in here refers to it we return true. */ /* If any register in here refers to it we return true. */
for (i = XVECLEN (x, 0); i >= 0; i--) for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
{ if (XEXP (XVECEXP (x, 0, i), 0) != 0
rtx reg = XVECEXP (x, 0, i); && reg_overlap_mentioned_p (XEXP (XVECEXP (x, 0, i), 0), in))
if (GET_CODE (reg) == EXPR_LIST)
reg = XEXP (reg, 0);
if (reg_overlap_mentioned_p (reg, in))
return 1; return 1;
return 0; return 0;
}
} }
default: default:
...@@ -1288,20 +1281,19 @@ note_stores (x, fun, data) ...@@ -1288,20 +1281,19 @@ note_stores (x, fun, data)
|| GET_CODE (dest) == STRICT_LOW_PART) || GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0); dest = XEXP (dest, 0);
/* If we have a PARALLEL, SET_DEST is a list of registers or /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
EXPR_LIST expressions, each of whose first operand is a register. each of whose first operand is a register. We can't know what
We can't know what precisely is being set in these cases, so precisely is being set in these cases, so make up a CLOBBER to pass
make up a CLOBBER to pass to the function. */ to the function. */
if (GET_CODE (dest) == PARALLEL && GET_MODE (dest) == BLKmode) if (GET_CODE (dest) == PARALLEL)
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--) {
{ for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
rtx reg = XVECEXP (dest, 0, i); if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
(*fun) (XEXP (XVECEXP (dest, 0, i), 0),
if (GET_CODE (reg) == EXPR_LIST) gen_rtx_CLOBBER (VOIDmode,
reg = XEXP (reg, 0); XEXP (XVECEXP (dest, 0, i), 0)),
data);
(*fun) (reg, gen_rtx_CLOBBER (VOIDmode, reg), data); }
}
else else
(*fun) (dest, x, data); (*fun) (dest, x, data);
} }
......
...@@ -551,19 +551,16 @@ sched_analyze_1 (deps, x, insn) ...@@ -551,19 +551,16 @@ sched_analyze_1 (deps, x, insn)
if (dest == 0) if (dest == 0)
return; return;
if (GET_CODE (dest) == PARALLEL && GET_MODE (dest) == BLKmode) if (GET_CODE (dest) == PARALLEL)
{ {
register int i; register int i;
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--) for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
{ if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
rtx reg = XVECEXP (dest, 0, i); sched_analyze_1 (deps,
gen_rtx_CLOBBER (VOIDmode,
if (GET_CODE (reg) == EXPR_LIST) XEXP (XVECEXP (dest, 0, i), 0)),
reg = XEXP (reg, 0); insn);
sched_analyze_1 (deps, reg, insn);
}
if (GET_CODE (x) == SET) if (GET_CODE (x) == SET)
sched_analyze_2 (deps, SET_SRC (x), insn); sched_analyze_2 (deps, SET_SRC (x), insn);
......
...@@ -1396,20 +1396,14 @@ check_live_1 (src, x) ...@@ -1396,20 +1396,14 @@ check_live_1 (src, x)
|| GET_CODE (reg) == STRICT_LOW_PART) || GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0); reg = XEXP (reg, 0);
if (GET_CODE (reg) == PARALLEL && GET_MODE (reg) == BLKmode) if (GET_CODE (reg) == PARALLEL)
{ {
register int i; register int i;
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--) for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
{ if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
rtx dest = XVECEXP (reg, 0, i); if (check_live_1 (src, XEXP (XVECEXP (reg, 0, i), 0)))
if (GET_CODE (dest) == EXPR_LIST)
dest = XEXP (dest, 0);
if (check_live_1 (src, dest))
return 1; return 1;
}
return 0; return 0;
} }
...@@ -1482,19 +1476,13 @@ update_live_1 (src, x) ...@@ -1482,19 +1476,13 @@ update_live_1 (src, x)
|| GET_CODE (reg) == STRICT_LOW_PART) || GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0); reg = XEXP (reg, 0);
if (GET_CODE (reg) == PARALLEL && GET_MODE (reg) == BLKmode) if (GET_CODE (reg) == PARALLEL)
{ {
register int i; register int i;
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--) for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
{ if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
rtx dest = XVECEXP (reg, 0, i); update_live_1 (src, XEXP (XVECEXP (reg, 0, i), 0));
if (GET_CODE (dest) == EXPR_LIST)
dest = XEXP (dest, 0);
update_live_1 (src, dest);
}
return; return;
} }
......
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