This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
RFC: eliminate some dead stores
- From: Dan Nicolaescu <dann at godzilla dot ICS dot UCI dot EDU>
- To: gcc at gcc dot gnu dot org
- Date: Mon, 03 Jun 2002 00:38:18 -0700
- Subject: RFC: eliminate some dead stores
Stores to structs that are passed by value, or to struct local vars
are dead, but they are not eliminated currently.
For example:
struct first { double d; char f1;};
struct second { char f2; short a;};
void
baz (struct first parmf, struct second parms)
{
struct first varf;
parmf.f1 = 0;
parms.f2 = 0;
parmf.f1++;
parms.f2++;
parmf.f1++;
parms.f2++;
varf.f1 = parms.f2 + parmf.f1;
}
is compile on SPARC to:
(gcc -O1)
baz:
!#PROLOGUE# 0
add %sp, -128, %sp
!#PROLOGUE# 1
stb %g0, [%o0+8]
stb %g0, [%o1]
ldub [%o0+8], %g1
add %g1, 1, %g1
stb %g1, [%o0+8]
ldub [%o1], %g1
add %g1, 1, %g1
stb %g1, [%o1]
ldub [%o0+8], %g1
add %g1, 1, %g1
stb %g1, [%o0+8]
ldub [%o1], %g1
add %g1, 1, %g1
stb %g1, [%o1]
nop
retl
sub %sp, -128, %sp
The patch below tries the dead stores. The code generated after the
patch is:
baz:
!#PROLOGUE# 0
add %sp, -128, %sp
!#PROLOGUE# 1
nop
retl
sub %sp, -128, %sp ;;; the stack ajustments are
;;; redundant, probably an
;;; unrelated issue
It boostraps/regchecks OK on sparc-solaris, but I've never hacked flow
before, so I would like to get some comments. Does it look correct?
Any suggestions on how to further improve the patch?
Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.524
diff -c -3 -p -c -r1.524 flow.c
*** flow.c 23 May 2002 19:23:40 -0000 1.524
--- flow.c 3 Jun 2002 07:19:44 -0000
*************** init_propagate_block_info (bb, live, loc
*** 1936,1942 ****
{
rtx mem = SET_DEST (set);
rtx canon_mem = canon_rtx (mem);
!
/* This optimization is performed by faking a store to the
memory at the end of the block. This doesn't work for
unchanging memories because multiple stores to unchanging
--- 1936,1943 ----
{
rtx mem = SET_DEST (set);
rtx canon_mem = canon_rtx (mem);
! tree expr_canon_mem;
!
/* This optimization is performed by faking a store to the
memory at the end of the block. This doesn't work for
unchanging memories because multiple stores to unchanging
*************** init_propagate_block_info (bb, live, loc
*** 1944,1954 ****
if (RTX_UNCHANGING_P (canon_mem))
continue;
if (XEXP (canon_mem, 0) == frame_pointer_rtx
|| (GET_CODE (XEXP (canon_mem, 0)) == PLUS
&& XEXP (XEXP (canon_mem, 0), 0) == frame_pointer_rtx
&& GET_CODE (XEXP (XEXP (canon_mem, 0), 1)) == CONST_INT))
! add_to_mem_set_list (pbi, canon_mem);
}
}
--- 1945,1986 ----
if (RTX_UNCHANGING_P (canon_mem))
continue;
+ expr_canon_mem = MEM_EXPR (canon_mem);
+
if (XEXP (canon_mem, 0) == frame_pointer_rtx
|| (GET_CODE (XEXP (canon_mem, 0)) == PLUS
&& XEXP (XEXP (canon_mem, 0), 0) == frame_pointer_rtx
&& GET_CODE (XEXP (XEXP (canon_mem, 0), 1)) == CONST_INT))
! add_to_mem_set_list (pbi, canon_mem);
!
!
! {
! extern tree decl_for_component_ref (tree);
! if (expr_canon_mem)
! {
! /* Stores to structures passed by value, or to
! local vars are dead. */
! if (DECL_P (expr_canon_mem))
! ;
! else if (TREE_CODE (expr_canon_mem) == COMPONENT_REF)
! expr_canon_mem = decl_for_component_ref (expr_canon_mem);
!
! if (expr_canon_mem
!
! && ((TREE_CODE (expr_canon_mem) == PARM_DECL)
! || ( !current_function_returns_struct
! /* If the curent function returns a
! struct, we can't guarantee that
! all stores to structures are
! dead. */
! && (TREE_CODE (expr_canon_mem) == VAR_DECL)
! /* Stores to static vars are not dead. */
! && ! (TREE_STATIC (expr_canon_mem))
! && (DECL_CONTEXT (expr_canon_mem)
! == current_function_decl))))
! add_to_mem_set_list (pbi, canon_mem);
! }
! }
}
}