Commit f474c6f8 by Alexandre Oliva Committed by Alexandre Oliva

calls.c (emit_library_call_value_1): Add USEs and CLOBBERs to function usage for…

calls.c (emit_library_call_value_1): Add USEs and CLOBBERs to function usage for arguments passed by reference.

* calls.c (emit_library_call_value_1): Add USEs and CLOBBERs
to function usage for arguments passed by reference.  Optimize
callee-copied arguments.
* regmove.c (find_related_toplev): Find uses in function usage.
(replace_in_call_usage): New function.
(fixup_match_1): Call it.
* cse.c (cse_insn): Canonicalize registers in function usage.
* reload1.c (replace_pseudos_in_call_usage): New function.
(reload): Call it.

From-SVN: r38964
parent 7dd232a8
2001-01-12 Alexandre Oliva <aoliva@redhat.com> 2001-01-12 Alexandre Oliva <aoliva@redhat.com>
* calls.c (emit_library_call_value_1): Add USEs and CLOBBERs
to function usage for arguments passed by reference. Optimize
callee-copied arguments.
* regmove.c (find_related_toplev): Find uses in function usage.
(replace_in_call_usage): New function.
(fixup_match_1): Call it.
* cse.c (cse_insn): Canonicalize registers in function usage.
* reload1.c (replace_pseudos_in_call_usage): New function.
(reload): Call it.
* Makefile.in: Reverted yesterday's wrong patch. Installed the * Makefile.in: Reverted yesterday's wrong patch. Installed the
right version. right version.
......
...@@ -3676,16 +3676,44 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -3676,16 +3676,44 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE #ifdef FUNCTION_ARG_PASS_BY_REFERENCE
if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1)) if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, mode, NULL_TREE, 1))
{ {
/* We do not support FUNCTION_ARG_CALLEE_COPIES here since it can rtx slot;
be viewed as just an efficiency improvement. */ int must_copy = 1
rtx slot = assign_temp (type_for_mode (mode, 0), 0, 1, 1); #ifdef FUNCTION_ARG_CALLEE_COPIES
&& ! FUNCTION_ARG_CALLEE_COPIES (args_so_far, mode,
NULL_TREE, 1)
#endif
;
if (GET_MODE (val) == MEM && ! must_copy)
slot = val;
else if (must_copy)
{
slot = assign_temp (type_for_mode (mode, 0), 0, 1, 1);
emit_move_insn (slot, val);
}
else
{
tree type = type_for_mode (mode, 0);
slot = gen_rtx_MEM (Pmode,
expand_expr (build1 (ADDR_EXPR,
build_pointer_type
(type),
make_tree (type, val)),
NULL_RTX, VOIDmode, 0));
}
call_fusage = gen_rtx_EXPR_LIST (VOIDmode, call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_USE (VOIDmode, slot), gen_rtx_USE (VOIDmode, slot),
call_fusage); call_fusage);
emit_move_insn (slot, val); if (must_copy)
val = force_operand (XEXP (slot, 0), NULL_RTX); call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_CLOBBER (VOIDmode,
slot),
call_fusage);
mode = Pmode; mode = Pmode;
val = force_operand (XEXP (slot, 0), NULL_RTX);
} }
#endif #endif
......
/* Common subexpression elimination for GNU compiler. /* Common subexpression elimination for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
1999, 2000 Free Software Foundation, Inc. 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -4754,8 +4754,11 @@ cse_insn (insn, libcall_insn) ...@@ -4754,8 +4754,11 @@ cse_insn (insn, libcall_insn)
if (GET_CODE (insn) == CALL_INSN) if (GET_CODE (insn) == CALL_INSN)
{ {
for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1)) for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
if (GET_CODE (XEXP (tem, 0)) == CLOBBER) {
invalidate (SET_DEST (XEXP (tem, 0)), VOIDmode); if (GET_CODE (XEXP (tem, 0)) == CLOBBER)
invalidate (SET_DEST (XEXP (tem, 0)), VOIDmode);
XEXP (tem, 0) = canon_reg (XEXP (tem, 0), insn);
}
} }
if (GET_CODE (x) == SET) if (GET_CODE (x) == SET)
......
/* Move registers around to reduce number of move instructions needed. /* Move registers around to reduce number of move instructions needed.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000 Free Software Foundation, Inc. 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -1505,6 +1505,17 @@ find_matches (insn, matchp) ...@@ -1505,6 +1505,17 @@ find_matches (insn, matchp)
int op_no; int op_no;
int any_matches = 0; int any_matches = 0;
if (GET_CODE (insn) == CALL_INSN
&& CALL_INSN_FUNCTION_USAGE (insn))
{
rtx usage;
for (usage = CALL_INSN_FUNCTION_USAGE (insn);
usage;
usage = XEXP (usage, 1))
find_related (&XEXP (usage, 0), insn, luid, call_tally);
}
extract_insn (insn); extract_insn (insn);
if (! constrain_operands (0)) if (! constrain_operands (0))
return 0; return 0;
...@@ -1571,6 +1582,45 @@ find_matches (insn, matchp) ...@@ -1571,6 +1582,45 @@ find_matches (insn, matchp)
return any_matches; return any_matches;
} }
/* Try to replace all occurrences of DST_REG with SRC in LOC, that is
assumed to be in INSN. */
static void
replace_in_call_usage (loc, dst_reg, src, insn)
rtx *loc;
int dst_reg;
rtx src;
rtx insn;
{
rtx x = *loc;
enum rtx_code code;
const char *fmt;
int i, j;
if (! x)
return;
code = GET_CODE (x);
if (code == REG)
{
if (REGNO (x) != dst_reg)
return;
validate_change (insn, loc, src, 1);
return;
}
/* Process each of our operands recursively. */
fmt = GET_RTX_FORMAT (code);
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
if (*fmt == 'e')
replace_in_call_usage (&XEXP (x, i), dst_reg, src, insn);
else if (*fmt == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
replace_in_call_usage (& XVECEXP (x, i, j), dst_reg, src, insn);
}
/* Try to replace output operand DST in SET, with input operand SRC. SET is /* Try to replace output operand DST in SET, with input operand SRC. SET is
the only set in INSN. INSN has just been recognized and constrained. the only set in INSN. INSN has just been recognized and constrained.
SRC is operand number OPERAND_NUMBER in INSN. SRC is operand number OPERAND_NUMBER in INSN.
...@@ -1643,6 +1693,10 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number, ...@@ -1643,6 +1693,10 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
for (length = s_length = 0, p = NEXT_INSN (insn); p; p = NEXT_INSN (p)) for (length = s_length = 0, p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
{ {
if (GET_CODE (p) == CALL_INSN)
replace_in_call_usage (& CALL_INSN_FUNCTION_USAGE (p),
REGNO (dst), src, p);
/* ??? We can't scan past the end of a basic block without updating /* ??? We can't scan past the end of a basic block without updating
the register lifetime info (REG_DEAD/basic_block_live_at_start). */ the register lifetime info (REG_DEAD/basic_block_live_at_start). */
if (perhaps_ends_bb_p (p)) if (perhaps_ends_bb_p (p))
......
...@@ -577,6 +577,63 @@ compute_use_by_pseudos (to, from) ...@@ -577,6 +577,63 @@ compute_use_by_pseudos (to, from)
} }
}); });
} }
/* Replace all pseudos found in LOC with their corresponding
equivalences. */
static void
replace_pseudos_in_call_usage (loc, mem_mode, usage)
rtx *loc;
enum machine_mode mem_mode;
rtx usage;
{
rtx x = *loc;
enum rtx_code code;
const char *fmt;
int i, j;
if (! x)
return;
code = GET_CODE (x);
if (code == REG)
{
if (REGNO (x) < FIRST_PSEUDO_REGISTER)
return;
x = eliminate_regs (x, mem_mode, usage);
if (x != *loc)
{
*loc = x;
replace_pseudos_in_call_usage (loc, mem_mode, usage);
return;
}
if (reg_renumber [REGNO (x)] < 0)
*loc = regno_reg_rtx[REGNO (x)];
else if (reg_equiv_mem[REGNO (x)])
*loc = reg_equiv_mem[REGNO (x)];
else
abort ();
return;
}
else if (code == MEM)
{
replace_pseudos_in_call_usage (& XEXP (x, 0), GET_MODE (x), usage);
return;
}
/* Process each of our operands recursively. */
fmt = GET_RTX_FORMAT (code);
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
if (*fmt == 'e')
replace_pseudos_in_call_usage (&XEXP (x, i), mem_mode, usage);
else if (*fmt == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
replace_pseudos_in_call_usage (& XVECEXP (x, i, j), mem_mode, usage);
}
/* Global variables used by reload and its subroutines. */ /* Global variables used by reload and its subroutines. */
...@@ -1114,6 +1171,11 @@ reload (first, global) ...@@ -1114,6 +1171,11 @@ reload (first, global)
{ {
rtx *pnote; rtx *pnote;
if (GET_CODE (insn) == CALL_INSN)
replace_pseudos_in_call_usage (& CALL_INSN_FUNCTION_USAGE (insn),
VOIDmode,
CALL_INSN_FUNCTION_USAGE (insn));
if ((GET_CODE (PATTERN (insn)) == USE if ((GET_CODE (PATTERN (insn)) == USE
&& find_reg_note (insn, REG_EQUAL, NULL_RTX)) && find_reg_note (insn, REG_EQUAL, NULL_RTX))
|| (GET_CODE (PATTERN (insn)) == CLOBBER || (GET_CODE (PATTERN (insn)) == CLOBBER
......
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