Commit 47841d1b by Jakub Jelinek Committed by David S. Miller

sparc.h (PROMOTE_FOR_CALL_ONLY): Define.

	* config/sparc/sparc.h (PROMOTE_FOR_CALL_ONLY): Define.

	* calls.c (precompute_arguments): Make sure initial_value contains
	value pseudo which CSE expects.
	* cse.c (struct set): New entry orig_src.
	(cse_insn): Set it early on entry, use it for libcall EQUIV note
	replacement.

From-SVN: r30846
parent 1684f874
...@@ -17,6 +17,14 @@ Thu Dec 9 11:36:24 MET 1999 Jan Hubicka <hubicka@freesoft.cz> ...@@ -17,6 +17,14 @@ Thu Dec 9 11:36:24 MET 1999 Jan Hubicka <hubicka@freesoft.cz>
* genmultilib: Accept | as alternative separator within a set in * genmultilib: Accept | as alternative separator within a set in
MULTILIB_OPTIONS. MULTILIB_OPTIONS.
* config/sparc/sparc.h (PROMOTE_FOR_CALL_ONLY): Define.
* calls.c (precompute_arguments): Make sure initial_value contains
value pseudo which CSE expects.
* cse.c (struct set): New entry orig_src.
(cse_insn): Set it early on entry, use it for libcall EQUIV note
replacement.
Wed Dec 8 22:24:15 1999 Richard Henderson <rth@cygnus.com> Wed Dec 8 22:24:15 1999 Richard Henderson <rth@cygnus.com>
* flow.c (count_basic_blocks): Don't add (use (const_int 0)) insns. * flow.c (count_basic_blocks): Don't add (use (const_int 0)) insns.
......
...@@ -1267,7 +1267,7 @@ precompute_arguments (is_const, must_preallocate, num_actuals, args, args_size) ...@@ -1267,7 +1267,7 @@ precompute_arguments (is_const, must_preallocate, num_actuals, args, args_size)
push_temp_slots (); push_temp_slots ();
args[i].initial_value = args[i].value args[i].value
= expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0); = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0);
preserve_temp_slots (args[i].value); preserve_temp_slots (args[i].value);
...@@ -1278,13 +1278,30 @@ precompute_arguments (is_const, must_preallocate, num_actuals, args, args_size) ...@@ -1278,13 +1278,30 @@ precompute_arguments (is_const, must_preallocate, num_actuals, args, args_size)
emit_queue (); emit_queue ();
args[i].initial_value = args[i].value args[i].initial_value = args[i].value
= protect_from_queue (args[i].initial_value, 0); = protect_from_queue (args[i].value, 0);
if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) != args[i].mode) if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) != args[i].mode)
args[i].value {
= convert_modes (args[i].mode, args[i].value
TYPE_MODE (TREE_TYPE (args[i].tree_value)), = convert_modes (args[i].mode,
args[i].value, args[i].unsignedp); TYPE_MODE (TREE_TYPE (args[i].tree_value)),
args[i].value, args[i].unsignedp);
#ifdef PROMOTE_FOR_CALL_ONLY
/* CSE will replace this only if it contains args[i].value
pseudo, so convert it down to the declared mode using
a SUBREG. */
if (GET_CODE (args[i].value) == REG
&& GET_MODE_CLASS (args[i].mode) == MODE_INT)
{
args[i].initial_value
= gen_rtx_SUBREG (TYPE_MODE (TREE_TYPE (args[i].tree_value)),
args[i].value, 0);
SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1;
SUBREG_PROMOTED_UNSIGNED_P (args[i].initial_value)
= args[i].unsignedp;
}
#endif
}
} }
} }
......
...@@ -777,6 +777,18 @@ if (TARGET_ARCH64 \ ...@@ -777,6 +777,18 @@ if (TARGET_ARCH64 \
for this value. */ for this value. */
#define PROMOTE_FUNCTION_RETURN #define PROMOTE_FUNCTION_RETURN
/* Define this macro if the promotion described by PROMOTE_MODE
should _only_ be performed for outgoing function arguments or
function return values, as specified by PROMOTE_FUNCTION_ARGS
and PROMOTE_FUNCTION_RETURN, respectively. */
/* This is only needed for TARGET_ARCH64, but since PROMOTE_MODE is a no-op
for TARGET_ARCH32 this is ok. Otherwise we'd need to add a runtime test
for this value. For TARGET_ARCH64 we need it, as we don't have instructions
for arithmetic operations which do zero/sign extension at the same time,
so without this we end up with a srl/sra after every assignment to an
user variable, which means very very bad code. */
#define PROMOTE_FOR_CALL_ONLY
/* Allocation boundary (in *bits*) for storing arguments in argument list. */ /* Allocation boundary (in *bits*) for storing arguments in argument list. */
#define PARM_BOUNDARY (TARGET_ARCH64 ? 64 : 32) #define PARM_BOUNDARY (TARGET_ARCH64 ? 64 : 32)
......
...@@ -4426,6 +4426,8 @@ struct set ...@@ -4426,6 +4426,8 @@ struct set
enum machine_mode mode; enum machine_mode mode;
/* A constant equivalent for SET_SRC, if any. */ /* A constant equivalent for SET_SRC, if any. */
rtx src_const; rtx src_const;
/* Original SET_SRC value used for libcall notes. */
rtx orig_src;
/* Hash value of constant equivalent for SET_SRC. */ /* Hash value of constant equivalent for SET_SRC. */
unsigned src_const_hash; unsigned src_const_hash;
/* Table entry for constant equivalent for SET_SRC, if any. */ /* Table entry for constant equivalent for SET_SRC, if any. */
...@@ -4624,6 +4626,7 @@ cse_insn (insn, libcall_insn) ...@@ -4624,6 +4626,7 @@ cse_insn (insn, libcall_insn)
rtx new = canon_reg (src, insn); rtx new = canon_reg (src, insn);
int insn_code; int insn_code;
sets[i].orig_src = src;
if ((GET_CODE (new) == REG && GET_CODE (src) == REG if ((GET_CODE (new) == REG && GET_CODE (src) == REG
&& ((REGNO (new) < FIRST_PSEUDO_REGISTER) && ((REGNO (new) < FIRST_PSEUDO_REGISTER)
!= (REGNO (src) < FIRST_PSEUDO_REGISTER))) != (REGNO (src) < FIRST_PSEUDO_REGISTER)))
...@@ -5123,7 +5126,7 @@ cse_insn (insn, libcall_insn) ...@@ -5123,7 +5126,7 @@ cse_insn (insn, libcall_insn)
the current contents will be tested and will always be valid. */ the current contents will be tested and will always be valid. */
while (1) while (1)
{ {
rtx trial, old_src; rtx trial;
/* Skip invalid entries. */ /* Skip invalid entries. */
while (elt && GET_CODE (elt->exp) != REG while (elt && GET_CODE (elt->exp) != REG
...@@ -5189,10 +5192,6 @@ cse_insn (insn, libcall_insn) ...@@ -5189,10 +5192,6 @@ cse_insn (insn, libcall_insn)
insert the substitution here and we will delete and re-emit insert the substitution here and we will delete and re-emit
the insn later. */ the insn later. */
/* Keep track of the original SET_SRC so that we can fix notes
on libcall instructions. */
old_src = SET_SRC (sets[i].rtl);
if (n_sets == 1 && dest == pc_rtx if (n_sets == 1 && dest == pc_rtx
&& (trial == pc_rtx && (trial == pc_rtx
|| (GET_CODE (trial) == LABEL_REF || (GET_CODE (trial) == LABEL_REF
...@@ -5221,10 +5220,10 @@ cse_insn (insn, libcall_insn) ...@@ -5221,10 +5220,10 @@ cse_insn (insn, libcall_insn)
need to make the same substitution in any notes attached need to make the same substitution in any notes attached
to the RETVAL insn. */ to the RETVAL insn. */
if (libcall_insn if (libcall_insn
&& (GET_CODE (old_src) == REG && (GET_CODE (sets[i].orig_src) == REG
|| GET_CODE (old_src) == SUBREG || GET_CODE (sets[i].orig_src) == SUBREG
|| GET_CODE (old_src) == MEM)) || GET_CODE (sets[i].orig_src) == MEM))
replace_rtx (REG_NOTES (libcall_insn), old_src, replace_rtx (REG_NOTES (libcall_insn), sets[i].orig_src,
canon_reg (SET_SRC (sets[i].rtl), insn)); canon_reg (SET_SRC (sets[i].rtl), insn));
/* The result of apply_change_group can be ignored; see /* The result of apply_change_group can be ignored; see
......
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