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]

[Committed] Eliminate no-op moves in expand_assignment


Whilst investigating PR middle-end/18041 I discovered that nowhere
in GCC are we eliminating no-op bitfield assignments.  For example,
given the source code:

typedef struct {
  unsigned int bit0 : 1;
  unsigned int bit1 : 1;
  } T;

void foo(T *p)
{
  p->bit1 = p->bit1;
}

on x86 with -O2 -fomit-frame-pointer mainline currently generates:

foo:    movl    4(%esp), %eax
        movzbl  (%eax), %edx
        movl    (%eax), %ecx
        shrb    %dl
        andl    $1, %edx
        andl    $-3, %ecx
        addl    %edx, %edx
        orl     %edx, %ecx
        movl    %ecx, (%eax)
        ret

According to Dan Berlin on IRC, tree-ssa used to have a pass to eliminate
no-op moves, but an analysis of how effective it was showed that it wasn't
worth the effort of a full SSA traversal, so the pass was removed.

With far less overhead, we can avoid creating such dubious code during
RTL expansion, by checking whether the source and destination of an
assignment are equal and free from side-effects (volatile etc...).
This is implemented by the patch below.  For the same test case above
we now generate:

foo:	ret


The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all default languages including Ada, and regression
tested with a top-level "make -k check" with no new failures.

Committed to mainline as revision 113009.



2006-04-17  Roger Sayle  <roger@eyesopen.com>

	* expr.c (expand_assignment): Optimize away no-op moves where the
	source and destination are equal and have no side-effects.


Index: expr.c
===================================================================
*** expr.c	(revision 112982)
--- expr.c	(working copy)
*************** expand_assignment (tree to, tree from)
*** 3984,3996 ****
    rtx result;

    /* Don't crash if the lhs of the assignment was erroneous.  */
-
    if (TREE_CODE (to) == ERROR_MARK)
      {
        result = expand_normal (from);
        return;
      }

    /* Assignment of a structure component needs special treatment
       if the structure component's rtx is not simply a MEM.
       Assignment of an array element at a constant index, and assignment of
--- 3984,3999 ----
    rtx result;

    /* Don't crash if the lhs of the assignment was erroneous.  */
    if (TREE_CODE (to) == ERROR_MARK)
      {
        result = expand_normal (from);
        return;
      }

+   /* Optimize away no-op moves without side-effects.  */
+   if (operand_equal_p (to, from, 0))
+     return;
+
    /* Assignment of a structure component needs special treatment
       if the structure component's rtx is not simply a MEM.
       Assignment of an array element at a constant index, and assignment of


Roger
--


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