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]

Improvement for ssa-dce.c



This is a minor improvement for ssa-dce.c.

Basically it was considering things like notes, code labels and barriers
as important.  It also had an overly simplistic notion of how to look for
writes into memory.

This patch tweaks things so ssa-dce only deals with INSNs, JUMP_INSNs,
and CALL_INSNs (everything else is basically ignored).

It changes the INSN handling to use note_stores to search for writes into
memory and tries to handle UNSPECs and various ASM stuff a little better.

I've bootstrapped this on ia64-linux in a private tree with ssa-dce enabled
by default.

	* ssa-dce.c (note_inherently_necessary_set): New function.
	(find_inherently_necessary): Use it.  Do not consider
	NOTEs, CODE_LABELs or BARRIERS are necessary.  Improve
	handling of asms and unspecs.
	(delete_insn_bb): Only delete INSNs, CALL_INSNs or JUMP_INSNs.

Index: ssa-dce.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ssa-dce.c,v
retrieving revision 1.3
diff -c -3 -p -r1.3 ssa-dce.c
*** ssa-dce.c	2001/06/28 18:24:55	1.3
--- ssa-dce.c	2001/06/29 17:59:16
*************** static int find_inherently_necessary
*** 113,118 ****
--- 113,120 ----
    PARAMS ((rtx current_rtx));
  static int propagate_necessity_through_operand
    PARAMS ((rtx *current_rtx, void *data));
+ static void note_inherently_necessary_set
+   PARAMS ((rtx, rtx, void *));
  
  /* Unnecessary insns are indicated using insns' in_struct bit.  */
  
*************** inherently_necessary_register (current_r
*** 328,333 ****
--- 330,360 ----
  		       &inherently_necessary_register_1, NULL);
  }
  
+ 
+ /* Called via note_stores for each store in an insn.  Note whether
+    or not a particular store is inherently necessary.  Store a
+    nonzero value in inherently_necessary_p if such a storeis found.  */
+    
+ static void
+ note_inherently_necessary_set (dest, set, data)
+      rtx set;
+      rtx dest;
+      void *data;
+ {
+   int *inherently_necessary_set_p = (int *)data;
+ 
+   while (GET_CODE (dest) == SUBREG
+ 	 || GET_CODE (dest) == STRICT_LOW_PART
+ 	 || GET_CODE (dest) == ZERO_EXTRACT
+ 	 || GET_CODE (dest) == SIGN_EXTRACT)
+     dest = XEXP (dest, 0);
+ 
+   if (GET_CODE (dest) == MEM
+       || GET_CODE (dest) == UNSPEC
+       || GET_CODE (dest) == UNSPEC_VOLATILE)
+     *inherently_necessary_set_p = 1;
+ }
+ 
  /* Mark X as inherently necessary if appropriate.  For example,
     function calls and storing values into memory are inherently
     necessary.  This function is to be used with for_each_rtx ().
*************** find_inherently_necessary (x)
*** 346,384 ****
      switch (GET_CODE (x))
        {  
        case CALL_INSN:
        case CODE_LABEL:
        case NOTE:
        case BARRIER:
! 	return !0;
  	break;
        case JUMP_INSN:
  	return JUMP_TABLE_DATA_P (x) || computed_jump_p (x) != 0;
  	break;
        case INSN:
! 	pattern = PATTERN (x);
! 	switch (GET_CODE (pattern))
! 	  {
! 	  case SET:
! 	  case PRE_DEC:
! 	  case PRE_INC:
! 	  case POST_DEC:
! 	  case POST_INC:
! 	    return GET_CODE (SET_DEST (pattern)) == MEM;
! 	  case CALL:
! 	  case RETURN:
! 	  case USE:
! 	  case CLOBBER:
! 	    return !0;
! 	    break;
! 	  case ASM_INPUT:
! 	    /* We treat assembler instructions as inherently
! 	       necessary, and we hope that its operands do not need to
! 	       be propagated.  */
! 	    return !0;
! 	    break;
! 	  default:
! 	    return 0;
! 	  }
        default:
  	/* Found an impossible insn type.  */
  	abort();
--- 373,401 ----
      switch (GET_CODE (x))
        {  
        case CALL_INSN:
+ 	return !0;
        case CODE_LABEL:
        case NOTE:
        case BARRIER:
! 	return 0;
  	break;
        case JUMP_INSN:
  	return JUMP_TABLE_DATA_P (x) || computed_jump_p (x) != 0;
  	break;
        case INSN:
! 	{
! 	  int inherently_necessary_set = 0;
! 	  note_stores (PATTERN (x),
! 		       note_inherently_necessary_set,
! 		       &inherently_necessary_set);
! 
! 	  /* If we found an inherently necessary set or an asm
! 	     instruction, then we consider this insn inherently
! 	     necessary.  */
! 	  return (inherently_necessary_set
! 		  || GET_CODE (PATTERN (x)) == ASM_INPUT
! 		  || asm_noperands (PATTERN (x)) >= 0);
! 	}
        default:
  	/* Found an impossible insn type.  */
  	abort();
*************** delete_insn_bb (insn)
*** 457,462 ****
--- 474,488 ----
    basic_block bb;
    if (!insn)
      abort ();
+ 
+   /* Do not actually delete anything that is not an INSN.
+ 
+      We can get here because we only consider INSNs as
+      potentially necessary.  We leave it to later passes
+      to remove unnecessary notes, unused labels, etc.  */
+   if (! INSN_P (insn))
+     return;
+ 
    bb = BLOCK_FOR_INSN (insn);
    if (!bb)
      abort ();








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