OSDN Git Service

* config/sparc/sparc.h (PROMOTE_FOR_CALL_ONLY): Define.
authordavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Dec 1999 14:38:11 +0000 (14:38 +0000)
committerdavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Dec 1999 14:38:11 +0000 (14:38 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30846 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/calls.c
gcc/config/sparc/sparc.h
gcc/cse.c

index 39323ee..b3f3f84 100644 (file)
@@ -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
        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>
 
        * flow.c (count_basic_blocks): Don't add (use (const_int 0)) insns.
index 33b425d..e19f787 100644 (file)
@@ -1267,7 +1267,7 @@ precompute_arguments (is_const, must_preallocate, num_actuals, args, args_size)
 
        push_temp_slots ();
 
-       args[i].initial_value = args[i].value
+       args[i].value
          = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0);
 
        preserve_temp_slots (args[i].value);
@@ -1278,13 +1278,30 @@ precompute_arguments (is_const, must_preallocate, num_actuals, args, args_size)
        emit_queue ();
 
        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)
-         args[i].value
-           = convert_modes (args[i].mode, 
-                            TYPE_MODE (TREE_TYPE (args[i].tree_value)),
-                            args[i].value, args[i].unsignedp);
+         {
+           args[i].value
+             = convert_modes (args[i].mode, 
+                              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
+         }
       }
 }
 
index 1a44547..4387fc8 100644 (file)
@@ -777,6 +777,18 @@ if (TARGET_ARCH64                          \
    for this value.  */
 #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.  */
 #define PARM_BOUNDARY (TARGET_ARCH64 ? 64 : 32)
 
index 8679708..bc9e7b6 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4426,6 +4426,8 @@ struct set
   enum machine_mode mode;
   /* A constant equivalent for SET_SRC, if any.  */
   rtx src_const;
+  /* Original SET_SRC value used for libcall notes.  */
+  rtx orig_src;
   /* Hash value of constant equivalent for SET_SRC.  */
   unsigned src_const_hash;
   /* Table entry for constant equivalent for SET_SRC, if any.  */
@@ -4624,6 +4626,7 @@ cse_insn (insn, libcall_insn)
       rtx new = canon_reg (src, insn);
       int insn_code;
 
+      sets[i].orig_src = src;
       if ((GET_CODE (new) == REG && GET_CODE (src) == REG
           && ((REGNO (new) < FIRST_PSEUDO_REGISTER)
               != (REGNO (src) < FIRST_PSEUDO_REGISTER)))
@@ -5123,7 +5126,7 @@ cse_insn (insn, libcall_insn)
          the current contents will be tested and will always be valid.  */
       while (1)
         {
-          rtx trial, old_src;
+          rtx trial;
 
           /* Skip invalid entries.  */
           while (elt && GET_CODE (elt->exp) != REG
@@ -5189,10 +5192,6 @@ cse_insn (insn, libcall_insn)
             insert the substitution here and we will delete and re-emit
             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
              && (trial == pc_rtx
                  || (GET_CODE (trial) == LABEL_REF
@@ -5221,10 +5220,10 @@ cse_insn (insn, libcall_insn)
                 need to make the same substitution in any notes attached
                 to the RETVAL insn.  */
              if (libcall_insn
-                 && (GET_CODE (old_src) == REG
-                     || GET_CODE (old_src) == SUBREG
-                     ||  GET_CODE (old_src) == MEM))
-               replace_rtx (REG_NOTES (libcall_insn), old_src, 
+                 && (GET_CODE (sets[i].orig_src) == REG
+                     || GET_CODE (sets[i].orig_src) == SUBREG
+                     ||  GET_CODE (sets[i].orig_src) == MEM))
+               replace_rtx (REG_NOTES (libcall_insn), sets[i].orig_src, 
                             canon_reg (SET_SRC (sets[i].rtl), insn));
 
              /* The result of apply_change_group can be ignored; see