This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Elimination of duplicate sign extensions


This patch, based on one by Nigel Stephens of MIPS Technologies,
eliminates some duplicate sign extensions upon function calls.
Currently, if we have something such as:

static int f(short foobar)
{
  return foobar > 0;
}

then on the MIPS, where foobar is passed in a 32-bit container, we
end up with a sign extension both at the call site and also one
at the head of f.  The generated code for f originally looks like:

        sll     $2,$4,16
        sra     $2,$2,16
        j       $31
        slt     $2,$0,$2

After this patch, we end up with just:

        j       $31
        slt     $2,$0,$4

Before this patch, combine only causes such sign extensions to be
eliminated when the TYPE_MODEs of the container and argument types
match.  This patch relaxes that restriction, insisting instead
that just the TREE_CODEs of those types match, but only when we can
deduce that the function is only called from the current compilation
unit (and so when -fno-unit-at-a-time is not in effect).

In the code below, if strictly_local ends up false, then we still
compare the TYPE_MODEs: I could not convince myself that there
would never (in the unpatched compiler) have arisen a situation
where the TYPE_MODEs would be equal but the TREE_CODEs were not equal.
Perhaps someone knowledgeable could advise here...

This patch has been tested with cross to mips64el-linux-gnu and
bootstrapped on x86_64-unknown-linux-gnu with no changes in test
results on either.  OK to apply to trunk?

Mark

--


2007-09-11 Mark Shinwell <shinwell@codesourcery.com> Nigel Stephens <nigel@mips.com>

	gcc/
	* combine.c: Include cgraph.h.
	(setup_incoming_promotions): Eliminate sign extension at the
	head of the function if we can prove it unnecessary.


Index: gcc/combine.c =================================================================== --- gcc/combine.c (revision 128363) +++ gcc/combine.c (working copy) @@ -104,6 +104,7 @@ along with GCC; see the file COPYING3. #include "timevar.h" #include "tree-pass.h" #include "df.h" +#include "cgraph.h"

/* Number of attempts to combine instructions in this function. */

@@ -1320,19 +1321,40 @@ static void
 setup_incoming_promotions (rtx first)
 {
   tree arg;
+  bool strictly_local = false;

   if (!targetm.calls.promote_function_args (TREE_TYPE (cfun->decl)))
     return;

+  /* If all call sites of the current function lie within the
+     current compilation unit, and we know the argument types of the
+     function, then try to prevent arguments that require sign extensions
+     from being sign extended twice (at call sites and again upon entry
+     to the function).  */
+  if (flag_unit_at_a_time)
+    strictly_local = cgraph_local_info (current_function_decl)->local;
+
   for (arg = DECL_ARGUMENTS (current_function_decl); arg;
        arg = TREE_CHAIN (arg))
     {
       rtx reg = DECL_INCOMING_RTL (arg);
+      tree container_type = DECL_ARG_TYPE (arg);
+      tree arg_type = TREE_TYPE (arg);

       if (!REG_P (reg))
        continue;

-      if (TYPE_MODE (DECL_ARG_TYPE (arg)) == TYPE_MODE (TREE_TYPE (arg)))
+      /* At this point, if all call sites to this function are known to be
+        within the current compilation unit, then eliminate unnecessary
+        sign extensions when the container type is of the same kind of
+        type as the argument type.  In such cases, the necessary
+        extension will already have been inserted by the compiler at
+        the call site.  */
+      if ((strictly_local
+           && TREE_CODE (container_type) == TREE_CODE (arg_type))
+          ||
+         (!strictly_local
+          && TYPE_MODE (container_type) == TYPE_MODE (arg_type)))
        {
          enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg));
          int uns = TYPE_UNSIGNED (TREE_TYPE (arg));


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]