calls.c (emit_library_call_value_1): Add USEs and CLOBBERs to function usage for...
authorAlexandre Oliva <aoliva@redhat.com>
Fri, 12 Jan 2001 21:58:56 +0000 (21:58 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Fri, 12 Jan 2001 21:58:56 +0000 (21:58 +0000)
* 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

gcc/ChangeLog
gcc/calls.c
gcc/cse.c
gcc/regmove.c
gcc/reload1.c

index a76969679672b3dca2ff3e180bc48d3b43f65c8f..e8d7d15fd000e4d59c350bb0e47f18c786dfa00e 100644 (file)
@@ -1,5 +1,15 @@
 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
        right version.
 
index ab6c5bb40e8e68d702f15d974021e4049438aca1..95dad19f6c1a9ec27d7f2aac804063b24f5ab35d 100644 (file)
@@ -3676,16 +3676,44 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
 #ifdef FUNCTION_ARG_PASS_BY_REFERENCE
       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
-            be viewed as just an efficiency improvement.  */
-         rtx slot = assign_temp (type_for_mode (mode, 0), 0, 1, 1);
+         rtx slot;
+         int must_copy = 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,
                                           gen_rtx_USE (VOIDmode, slot),
                                           call_fusage);
-         emit_move_insn (slot, val);
-         val = force_operand (XEXP (slot, 0), NULL_RTX);
+         if (must_copy)
+           call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
+                                            gen_rtx_CLOBBER (VOIDmode,
+                                                             slot),
+                                            call_fusage);
+
          mode = Pmode;
+         val = force_operand (XEXP (slot, 0), NULL_RTX);
        }
 #endif
 
index 3d0f1a7658c119d8693c388a3f96734bb2fbde51..7b86d51cb82a0d0d67a90cbdbfb557dbebbf462b 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -1,6 +1,6 @@
 /* Common subexpression elimination for GNU compiler.
    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.
 
@@ -4754,8 +4754,11 @@ cse_insn (insn, libcall_insn)
   if (GET_CODE (insn) == CALL_INSN)
     {
       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)
index 008b22cae3ed878f527089db5a160d4ab271dbd8..3c94e18b846504b52e0bedb05b7889552df63e83 100644 (file)
@@ -1,6 +1,6 @@
 /* Move registers around to reduce number of move instructions needed.
    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.
 
@@ -1505,6 +1505,17 @@ find_matches (insn, matchp)
   int op_no;
   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);
   if (! constrain_operands (0))
     return 0;
@@ -1571,6 +1582,45 @@ find_matches (insn, matchp)
   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
    the only set in INSN.  INSN has just been recognized and constrained.
    SRC is operand number OPERAND_NUMBER in INSN.
@@ -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))
     {
+      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
         the register lifetime info (REG_DEAD/basic_block_live_at_start).  */
       if (perhaps_ends_bb_p (p))
index 805fd96829766a8ff2b30a2bc21bea10db21fc76..ace38ef5edac81d9e50108441813a9de9130a842 100644 (file)
@@ -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);
+}
+
 \f
 /* Global variables used by reload and its subroutines.  */
 
@@ -1114,6 +1171,11 @@ reload (first, global)
       {
        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
             && find_reg_note (insn, REG_EQUAL, NULL_RTX))
            || (GET_CODE (PATTERN (insn)) == CLOBBER