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]

Re: Update for cprop patch


  In message <Pine.LNX.4.10.9907161109590.17496-100000@biriani.cygnus.co.uk>you
 write:
  > Here's a new version of the patch.  Changes since the last one:
  >   - try to avoid entering obvious no-ops into the hash table
I installed this a while ago.

  >   - move the second oprs_not_set_p call into find_avail_set.  This function
  >     now guarantees that the rtx it returns can safely be substituted.
I'm going to look at this shortly.

  > 	* gcse.c 
  > 	(find_avail_set): Follow chains of register-register copies.
  > 	Use oprs_not_set_p to guarantee that the returned value can be
  > 	substituted.
  > 	(cprop_jump): New function, broken out of cprop_insn.
  > 	(cprop_cc0_jump): New function.
  > 	(cprop_insn): 
  > 	Break out new function cprop_jump and use it.
  > 	Also use cprop_cc0_jump for machines with CC0.
  > 	Don't verify the return value of find_avail_set with oprs_not_set_p.
  > 	(cprop): Don't crash if cprop_insn turned the insn into a NOTE.
I installed the code which deals with cprop into conditional jumps on cc0
machines.  Attached is a copy of the patch that was installed.

        * gcse.c (cprop_jump): New function, broken out of cprop_insn.
        (cprop_cc0_jump): New function.
        (cprop_insn): Break out new function cprop_jump and use it.
        Also use cprop_cc0_jump for machines with CC0.
        (cprop): Don't crash if cprop_insn turned the insn into a NOTE.

Index: gcse.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/gcse.c,v
retrieving revision 1.42
diff -c -3 -p -r1.42 gcse.c
*** gcse.c	1999/08/20 23:05:08	1.42
--- gcse.c	1999/08/25 03:29:56
*************** static char can_copy_p[(int) NUM_MACHINE
*** 310,315 ****
--- 310,319 ----
  /* Non-zero if can_copy_p has been initialized.  */
  static int can_copy_init_p;
  
+ struct reg_use {
+   rtx reg_rtx;
+ };
+ 
  /* Hash table of expressions.  */
  
  struct expr
*************** static void compute_cprop_data	PROTO ((v
*** 572,577 ****
--- 576,583 ----
  static void find_used_regs	    PROTO ((rtx));
  static int try_replace_reg	    PROTO ((rtx, rtx, rtx));
  static struct expr *find_avail_set    PROTO ((int, rtx));
+ static int cprop_jump			PROTO((rtx, rtx, struct reg_use *, rtx));
+ static int cprop_cc0_jump		PROTO((rtx, struct reg_use *, rtx));
  static int cprop_insn		 PROTO ((rtx, int));
  static int cprop		      PROTO ((int));
  static int one_cprop_pass	     PROTO ((int, int));
*************** compute_cprop_data ()
*** 3532,3541 ****
  
  /* Copy/constant propagation.  */
  
- struct reg_use {
-   rtx reg_rtx;
- };
- 
  /* Maximum number of register uses in an insn that we handle.  */
  #define MAX_USES 8
  
--- 3538,3543 ----
*************** find_avail_set (regno, insn)
*** 3666,3671 ****
--- 3668,3781 ----
    return set;
  }
  
+ /* Subroutine of cprop_insn that tries to propagate constants into
+    JUMP_INSNS.  INSN must be a conditional jump; COPY is a copy of it
+    that we can use for substitutions.
+    REG_USED is the use we will try to replace, SRC is the constant we
+    will try to substitute for it.
+    Returns nonzero if a change was made.  */
+ static int
+ cprop_jump (insn, copy, reg_used, src)
+      rtx insn, copy;
+      struct reg_use *reg_used;
+      rtx src;
+ {
+   rtx set = PATTERN (copy);
+   rtx temp;
+ 
+   /* Replace the register with the appropriate constant.  */
+   replace_rtx (SET_SRC (set), reg_used->reg_rtx, src);
+ 
+   temp = simplify_ternary_operation (GET_CODE (SET_SRC (set)),
+ 				     GET_MODE (SET_SRC (set)),
+ 				     GET_MODE (XEXP (SET_SRC (set), 0)),
+ 				     XEXP (SET_SRC (set), 0),
+ 				     XEXP (SET_SRC (set), 1),
+ 				     XEXP (SET_SRC (set), 2));
+ 
+   /* If no simplification can be made, then try the next
+      register.  */
+   if (temp == 0)
+     return 0;
+  
+   SET_SRC (set) = temp;
+ 
+   /* That may have changed the structure of TEMP, so
+      force it to be rerecognized if it has not turned
+      into a nop or unconditional jump.  */
+ 		
+   INSN_CODE (copy) = -1;
+   if ((SET_DEST (set) == pc_rtx
+        && (SET_SRC (set) == pc_rtx
+ 	   || GET_CODE (SET_SRC (set)) == LABEL_REF))
+       || recog (PATTERN (copy), copy, NULL) >= 0)
+     {
+       /* This has either become an unconditional jump
+ 	 or a nop-jump.  We'd like to delete nop jumps
+ 	 here, but doing so confuses gcse.  So we just
+ 	 make the replacement and let later passes
+ 	 sort things out.  */
+       PATTERN (insn) = set;
+       INSN_CODE (insn) = -1;
+ 
+       /* One less use of the label this insn used to jump to
+ 	 if we turned this into a NOP jump.  */
+       if (SET_SRC (set) == pc_rtx && JUMP_LABEL (insn) != 0)
+ 	--LABEL_NUSES (JUMP_LABEL (insn));
+ 
+       /* If this has turned into an unconditional jump,
+ 	 then put a barrier after it so that the unreachable
+ 	 code will be deleted.  */
+       if (GET_CODE (SET_SRC (set)) == LABEL_REF)
+ 	emit_barrier_after (insn);
+ 
+       run_jump_opt_after_gcse = 1;
+ 
+       const_prop_count++;
+       if (gcse_file != NULL)
+ 	{
+ 	  int regno = REGNO (reg_used->reg_rtx);
+ 	  fprintf (gcse_file, "CONST-PROP: Replacing reg %d in insn %d with constant ",
+ 		   regno, INSN_UID (insn));
+ 	  print_rtl (gcse_file, src);
+ 	  fprintf (gcse_file, "\n");
+ 	}
+       return 1;
+     }
+   return 0;
+ }
+ 
+ #ifdef HAVE_cc0
+ /* Subroutine of cprop_insn that tries to propagate constants into
+    JUMP_INSNS for machines that have CC0.  INSN is a single set that
+    stores into CC0; the insn following it is a conditional jump.
+    REG_USED is the use we will try to replace, SRC is the constant we
+    will try to substitute for it.
+    Returns nonzero if a change was made.  */
+ static int
+ cprop_cc0_jump (insn, reg_used, src)
+      rtx insn;
+      struct reg_use *reg_used;
+      rtx src;
+ {
+   rtx jump = NEXT_INSN (insn);
+   rtx copy = copy_rtx (jump);
+   rtx set = PATTERN (copy);
+ 
+   /* We need to copy the source of the cc0 setter, as cprop_jump is going to
+      substitute into it.  */
+   replace_rtx (SET_SRC (set), cc0_rtx, copy_rtx (SET_SRC (PATTERN (insn))));
+   if (! cprop_jump (jump, copy, reg_used, src))
+     return 0;
+ 
+   /* If we succeeded, delete the cc0 setter.  */
+   PUT_CODE (insn, NOTE);
+   NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+   NOTE_SOURCE_FILE (insn) = 0;
+   return 1;
+  }
+ #endif
+  
  /* Perform constant and copy propagation on INSN.
     The result is non-zero if a change was made.  */
  
*************** cprop_insn (insn, alter_jumps)
*** 3743,3822 ****
  	     code, we can extend this as necessary over time.
  
  	     Right now the insn in question must look like
! 
! 	     (set (pc) (if_then_else ...))
! 
! 	     Note this does not currently handle machines which use cc0.  */
  	  else if (alter_jumps
  		   && GET_CODE (insn) == JUMP_INSN
  		   && condjump_p (insn)
  		   && ! simplejump_p (insn))
! 	    {
! 	      /* We want a copy of the JUMP_INSN so we can modify it
! 		 in-place as needed without effecting the original.  */
! 	      rtx copy = copy_rtx (insn);
! 	      rtx set = PATTERN (copy);
! 	      rtx temp;
! 
! 	      /* Replace the register with the appropriate constant.  */
! 	      replace_rtx (SET_SRC (set), reg_used->reg_rtx, src);
! 
! 	      temp = simplify_ternary_operation (GET_CODE (SET_SRC (set)),
! 						 GET_MODE (SET_SRC (set)),
! 						 GET_MODE (XEXP (SET_SRC (set), 0)),
! 						 XEXP (SET_SRC (set), 0),
! 						 XEXP (SET_SRC (set), 1),
! 						 XEXP (SET_SRC (set), 2));
! 
! 	      /* If no simplification can be made, then try the next
! 		 register.  */
! 	      if (temp)
! 		SET_SRC (set) = temp;
! 	      else
! 		continue;
! 
! 	      /* That may have changed the structure of TEMP, so
! 		 force it to be rerecognized if it has not turned
! 		 into a nop or unconditional jump.  */
! 		
! 	      INSN_CODE (copy) = -1;
! 	      if ((SET_DEST (set) == pc_rtx
! 		   && (SET_SRC (set) == pc_rtx
! 		       || GET_CODE (SET_SRC (set)) == LABEL_REF))
! 		  || recog (PATTERN (copy), copy, NULL) >= 0)
! 		{
! 		  /* This has either become an unconditional jump
! 		     or a nop-jump.  We'd like to delete nop jumps
! 		     here, but doing so confuses gcse.  So we just
! 		     make the replacement and let later passes
! 		     sort things out.  */
! 		  PATTERN (insn) = set;
! 		  INSN_CODE (insn) = -1;
! 
! 		  /* One less use of the label this insn used to jump to
! 		     if we turned this into a NOP jump.  */
! 		  if (SET_SRC (set) == pc_rtx && JUMP_LABEL (insn) != 0)
! 		    --LABEL_NUSES (JUMP_LABEL (insn));
! 
! 		  /* If this has turned into an unconditional jump,
! 		     then put a barrier after it so that the unreachable
! 		     code will be deleted.  */
! 		  if (GET_CODE (SET_SRC (set)) == LABEL_REF)
! 		    emit_barrier_after (insn);
! 
! 		  run_jump_opt_after_gcse = 1;
! 
! 		  changed = 1;
! 		  const_prop_count++;
! 		  if (gcse_file != NULL)
! 		    {
! 		      fprintf (gcse_file, "CONST-PROP: Replacing reg %d in insn %d with constant ",
! 			       regno, INSN_UID (insn));
! 		      print_rtl (gcse_file, src);
! 		      fprintf (gcse_file, "\n");
! 		    }
! 		}
! 	    }
  	}
        else if (GET_CODE (src) == REG
  	       && REGNO (src) >= FIRST_PSEUDO_REGISTER
--- 3853,3875 ----
  	     code, we can extend this as necessary over time.
  
  	     Right now the insn in question must look like
! 	     (set (pc) (if_then_else ...))  */
  	  else if (alter_jumps
  		   && GET_CODE (insn) == JUMP_INSN
  		   && condjump_p (insn)
  		   && ! simplejump_p (insn))
! 	    changed |= cprop_jump (insn, copy_rtx (insn), reg_used, src);
! #ifdef HAVE_cc0
! 	  /* Similar code for machines that use a pair of CC0 setter and
! 	     conditional jump insn.  */
! 	  else if (alter_jumps
! 		   && GET_CODE (PATTERN (insn)) == SET
! 		   && SET_DEST (PATTERN (insn)) == cc0_rtx
! 		   && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
! 		   && condjump_p (NEXT_INSN (insn))
! 		   && ! simplejump_p (NEXT_INSN (insn)))
! 	    changed |= cprop_cc0_jump (insn, reg_used, src);
! #endif
  	}
        else if (GET_CODE (src) == REG
  	       && REGNO (src) >= FIRST_PSEUDO_REGISTER
*************** cprop (alter_jumps)
*** 3879,3886 ****
  	      changed |= cprop_insn (insn, alter_jumps);
  
  	      /* Keep track of everything modified by this insn.  */
! 	      /* ??? Need to be careful w.r.t. mods done to INSN.  */
! 	      mark_oprs_set (insn);
  	    }
  	}
      }
--- 3932,3941 ----
  	      changed |= cprop_insn (insn, alter_jumps);
  
  	      /* Keep track of everything modified by this insn.  */
! 	      /* ??? Need to be careful w.r.t. mods done to INSN.  Don't
! 	         call mark_oprs_set if we turned the insn into a NOTE.  */
! 	      if (GET_CODE (insn) != NOTE)
! 		mark_oprs_set (insn);
  	    }
  	}
      }



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