This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Committed] Eliminate no-op moves in expand_assignment
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 17 Apr 2006 10:22:30 -0600 (MDT)
- Subject: [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
--