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: Your flow.c change on 4/8


On Mon, Apr 10, 2000 at 04:32:14PM -0700, Richard Henderson wrote:
> I'll get it fixed this evening.

So much for Monday evening.

I still think that the original logic is flawed even though by
some twisted means it functions correctly.  However, I've given
up temporarily and reverted the logic changes (though not the
structural ones) to the pre 0407 state.

I'll get this all worked out on condexec-branch before addressing
it again in mainline.


r~


        * flow.c (struct propagate_block_info): Add new_dead, new_live.
        (propagate_block): Initialize them.  Use them in parallel instead
        of one tmp variable, ie revert much of the 0408 and 0407 functional
        changes, but keep the structural changes.
        (mark_set_regs): Take new_dead from propagate_block_info instead.
        (mark_set_1, mark_set_reg): Likewise.
        (mark_used_regs): Likewise with new_live.
        (mark_used_reg): Likewise.  Revert 0408 change.

Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.250
diff -c -p -d -r1.250 flow.c
*** flow.c	2000/04/09 01:16:44	1.250
--- flow.c	2000/04/12 01:32:37
*************** struct propagate_block_info
*** 268,273 ****
--- 268,279 ----
    /* Bit N is set if register N is conditionally or unconditionally live.  */
    regset reg_live;
  
+   /* Bit N is set if register N is unconditionally dead this insn.  */
+   regset new_dead;
+ 
+   /* Bit N is set if register N is live this insn.  */
+   regset new_live;
+ 
    /* Element N is the next insn that uses (hard or pseudo) register N
       within the current basic block; or zero, if there is no such insn.  */
    rtx *reg_next_use;
*************** static int insn_dead_p			PARAMS ((struct
*** 335,346 ****
  static int libcall_dead_p		PARAMS ((struct propagate_block_info *,
  						 rtx, rtx, rtx));
  static void mark_set_regs		PARAMS ((struct propagate_block_info *,
! 						 regset, rtx, rtx));
  static void mark_set_1			PARAMS ((struct propagate_block_info *,
! 						 regset, rtx, rtx, rtx));
  static int mark_set_reg			PARAMS ((struct propagate_block_info *,
! 						 regset, rtx, rtx,
! 						 int *, int *));
  #ifdef AUTO_INC_DEC
  static void find_auto_inc		PARAMS ((struct propagate_block_info *,
  						 rtx, rtx));
--- 341,351 ----
  static int libcall_dead_p		PARAMS ((struct propagate_block_info *,
  						 rtx, rtx, rtx));
  static void mark_set_regs		PARAMS ((struct propagate_block_info *,
! 						 rtx, rtx));
  static void mark_set_1			PARAMS ((struct propagate_block_info *,
! 						 rtx, rtx, rtx));
  static int mark_set_reg			PARAMS ((struct propagate_block_info *,
! 						 rtx, rtx, int *, int *));
  #ifdef AUTO_INC_DEC
  static void find_auto_inc		PARAMS ((struct propagate_block_info *,
  						 rtx, rtx));
*************** static int try_pre_increment_1		PARAMS (
*** 349,357 ****
  static int try_pre_increment		PARAMS ((rtx, rtx, HOST_WIDE_INT));
  #endif
  static void mark_used_reg		PARAMS ((struct propagate_block_info *,
! 						 regset, rtx, rtx, rtx));
  static void mark_used_regs		PARAMS ((struct propagate_block_info *,
! 						 regset, rtx, rtx, rtx));
  void dump_flow_info			PARAMS ((FILE *));
  void debug_flow_info			PARAMS ((void));
  static void dump_edge_info		PARAMS ((FILE *, edge, int));
--- 354,362 ----
  static int try_pre_increment		PARAMS ((rtx, rtx, HOST_WIDE_INT));
  #endif
  static void mark_used_reg		PARAMS ((struct propagate_block_info *,
! 						 rtx, rtx, rtx));
  static void mark_used_regs		PARAMS ((struct propagate_block_info *,
! 						 rtx, rtx, rtx));
  void dump_flow_info			PARAMS ((FILE *));
  void debug_flow_info			PARAMS ((void));
  static void dump_edge_info		PARAMS ((FILE *, edge, int));
*************** propagate_block (bb, live, local_set, fl
*** 3313,3320 ****
  {
    struct propagate_block_info pbi;
    rtx insn, prev;
!   regset_head tmp_head;
!   regset tmp;
    
    pbi.bb = bb;
    pbi.reg_live = live;
--- 3318,3324 ----
  {
    struct propagate_block_info pbi;
    rtx insn, prev;
!   regset_head new_live_head, new_dead_head;
    
    pbi.bb = bb;
    pbi.reg_live = live;
*************** propagate_block (bb, live, local_set, fl
*** 3328,3334 ****
    else
      pbi.reg_next_use = NULL;
  
!   tmp = INITIALIZE_REG_SET (tmp_head);
  
    if (flags & PROP_REG_INFO)
      {
--- 3332,3339 ----
    else
      pbi.reg_next_use = NULL;
  
!   pbi.new_live = INITIALIZE_REG_SET (new_live_head);
!   pbi.new_dead = INITIALIZE_REG_SET (new_dead_head);
  
    if (flags & PROP_REG_INFO)
      {
*************** propagate_block (bb, live, local_set, fl
*** 3443,3449 ****
  	  }
  #endif /* AUTO_INC_DEC */
  
! 	  CLEAR_REG_SET (tmp);
  
  	  /* If this is not the final pass, and this insn is copying the
  	     value of a library call and it's dead, don't scan the
--- 3448,3455 ----
  	  }
  #endif /* AUTO_INC_DEC */
  
! 	  CLEAR_REG_SET (pbi.new_live);
! 	  CLEAR_REG_SET (pbi.new_dead);
  
  	  /* If this is not the final pass, and this insn is copying the
  	     value of a library call and it's dead, don't scan the
*************** propagate_block (bb, live, local_set, fl
*** 3452,3459 ****
  	  if (libcall_is_dead)
  	    {
  	      /* Record the death of the dest reg.  */
! 	      mark_set_regs (&pbi, tmp, PATTERN (insn), insn);
! 	      AND_COMPL_REG_SET (pbi.reg_live, tmp);
  
  	      insn = XEXP (note, 0);
  	      prev = PREV_INSN (insn);
--- 3458,3464 ----
  	  if (libcall_is_dead)
  	    {
  	      /* Record the death of the dest reg.  */
! 	      mark_set_regs (&pbi, PATTERN (insn), insn);
  
  	      insn = XEXP (note, 0);
  	      prev = PREV_INSN (insn);
*************** propagate_block (bb, live, local_set, fl
*** 3482,3497 ****
  	      /* Record sets.  Do this even for dead instructions,
  		 since they would have killed the values if they hadn't
  		 been deleted.  */
! 	      mark_set_regs (&pbi, tmp, PATTERN (insn), insn);
  
! 	      /* Each call clobbers all call-clobbered regs that are not
! 		 global or fixed.  Note that the function-value reg is a
! 		 call-clobbered reg, and mark_set_regs has already had
! 		 a chance to handle it.  */
! 	      if (GET_CODE (insn) == CALL_INSN)
  		{
  		  register int i;
! 		  rtx cond;
  
  		  cond = NULL_RTX;
  		  if (GET_CODE (PATTERN (insn)) == COND_EXEC)
--- 3487,3514 ----
  	      /* Record sets.  Do this even for dead instructions,
  		 since they would have killed the values if they hadn't
  		 been deleted.  */
! 	      mark_set_regs (&pbi, PATTERN (insn), insn);
  
! 	      /* If an insn doesn't use CC0, it becomes dead since we 
! 		 assume that every insn clobbers it.  So show it dead here;
! 		 mark_used_regs will set it live if it is referenced.  */
! 	      pbi.cc0_live = 0;
! 
! 	      /* Record uses.  */
! 	      if (! insn_is_dead)
! 		mark_used_regs (&pbi, PATTERN (insn), NULL_RTX, insn);
! 
! 	      /* Sometimes we may have inserted something before INSN
! 		 (such as a move) when we make an auto-inc.  So ensure
! 		 we will scan those insns.  */
! #ifdef AUTO_INC_DEC
! 	      prev = PREV_INSN (insn);
! #endif
! 
! 	      if (! insn_is_dead && GET_CODE (insn) == CALL_INSN)
  		{
  		  register int i;
! 		  rtx note, cond;
  
  		  cond = NULL_RTX;
  		  if (GET_CODE (PATTERN (insn)) == COND_EXEC)
*************** propagate_block (bb, live, local_set, fl
*** 3506,3512 ****
  		       note;
  		       note = XEXP (note, 1))
  		    if (GET_CODE (XEXP (note, 0)) == CLOBBER)
! 		      mark_set_1 (&pbi, tmp, XEXP (XEXP (note, 0), 0),
  				  cond, insn);
  
  		  /* Calls change all call-used and global registers.  */
--- 3523,3529 ----
  		       note;
  		       note = XEXP (note, 1))
  		    if (GET_CODE (XEXP (note, 0)) == CLOBBER)
! 		      mark_set_1 (&pbi, XEXP (XEXP (note, 0), 0),
  				  cond, insn);
  
  		  /* Calls change all call-used and global registers.  */
*************** propagate_block (bb, live, local_set, fl
*** 3515,3578 ****
  			&& ! fixed_regs[i])
  		      {
  			int dummy;
! 		        mark_set_reg (&pbi, tmp,
! 				      gen_rtx_REG (reg_raw_mode[i], i),
  				      cond, &dummy, &dummy);
  		      }
- 		}
- 
- 	      /* Update live for the registers killed.  */
- 	      AND_COMPL_REG_SET (pbi.reg_live, tmp);
- 	      CLEAR_REG_SET (tmp);
- 
- 	      /* If an insn doesn't use CC0, it becomes dead since we 
- 		 assume that every insn clobbers it.  So show it dead here;
- 		 mark_used_regs will set it live if it is referenced.  */
- 	      pbi.cc0_live = 0;
- 
- 	      /* Record uses.  */
- 	      if (! insn_is_dead)
- 		mark_used_regs (&pbi, tmp, PATTERN (insn), NULL_RTX, insn);
- 
- 	      /* Sometimes we may have inserted something before INSN
- 		 (such as a move) when we make an auto-inc.  So ensure
- 		 we will scan those insns.  */
- #ifdef AUTO_INC_DEC
- 	      prev = PREV_INSN (insn);
- #endif
  
! 	      if (! insn_is_dead && GET_CODE (insn) == CALL_INSN)
! 		{
! 		  register int i;
! 		  rtx note, cond;
! 
! 		  cond = NULL_RTX;
! 		  if (GET_CODE (PATTERN (insn)) == COND_EXEC)
! 		    cond = COND_EXEC_TEST (PATTERN (insn));
! 
  	          for (note = CALL_INSN_FUNCTION_USAGE (insn);
  		       note;
  		       note = XEXP (note, 1))
  		    if (GET_CODE (XEXP (note, 0)) == USE)
! 		      mark_used_regs (&pbi, tmp, XEXP (XEXP (note, 0), 0),
  				      cond, insn);
  
  		  /* The stack ptr is used (honorarily) by a CALL insn.  */
! 		  SET_REGNO_REG_SET (tmp, STACK_POINTER_REGNUM);
  
  		  /* Calls may also reference any of the global registers,
  		     so they are made live.  */
  		  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  		    if (global_regs[i])
! 		      mark_used_reg (&pbi, tmp,
! 				     gen_rtx_REG (reg_raw_mode[i], i),
  				     cond, insn);
  		}
- 
- 	      /* Update live for the registers used.  */
- 	      IOR_REG_SET (pbi.reg_live, tmp);
  	    }
  
  	  /* On final pass, update counts of how many insns in which
  	     each reg is live.  */
  	  if (flags & PROP_REG_INFO)
--- 3532,3565 ----
  			&& ! fixed_regs[i])
  		      {
  			int dummy;
! 		        mark_set_reg (&pbi, gen_rtx_REG (reg_raw_mode[i], i),
  				      cond, &dummy, &dummy);
  		      }
  
! 		  /* Calls use their arguments.  */
  	          for (note = CALL_INSN_FUNCTION_USAGE (insn);
  		       note;
  		       note = XEXP (note, 1))
  		    if (GET_CODE (XEXP (note, 0)) == USE)
! 		      mark_used_regs (&pbi, XEXP (XEXP (note, 0), 0),
  				      cond, insn);
  
  		  /* The stack ptr is used (honorarily) by a CALL insn.  */
! 		  SET_REGNO_REG_SET (pbi.new_live, STACK_POINTER_REGNUM);
  
  		  /* Calls may also reference any of the global registers,
  		     so they are made live.  */
  		  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  		    if (global_regs[i])
! 		      mark_used_reg (&pbi, gen_rtx_REG (reg_raw_mode[i], i),
  				     cond, insn);
  		}
  	    }
  
+ 	  /* Update reg_live for the registers killed and used.  */
+ 	  AND_COMPL_REG_SET (pbi.reg_live, pbi.new_dead);
+ 	  IOR_REG_SET (pbi.reg_live, pbi.new_live);
+ 
  	  /* On final pass, update counts of how many insns in which
  	     each reg is live.  */
  	  if (flags & PROP_REG_INFO)
*************** propagate_block (bb, live, local_set, fl
*** 3584,3590 ****
  	break;
      }
  
!   FREE_REG_SET (tmp);
    free_EXPR_LIST_list (&pbi.mem_set_list);
  
    if (pbi.reg_next_use)
--- 3571,3578 ----
  	break;
      }
  
!   FREE_REG_SET (pbi.new_live);
!   FREE_REG_SET (pbi.new_dead);
    free_EXPR_LIST_list (&pbi.mem_set_list);
  
    if (pbi.reg_next_use)
*************** invalidate_mems_from_autoinc (pbi, insn)
*** 3905,3913 ****
     FLAGS is the set of operations to perform.  */
  
  static void
! mark_set_regs (pbi, new_dead, x, insn)
       struct propagate_block_info *pbi;
-      regset new_dead;
       rtx x, insn;
  {
    rtx cond = NULL_RTX;
--- 3893,3900 ----
     FLAGS is the set of operations to perform.  */
  
  static void
! mark_set_regs (pbi, x, insn)
       struct propagate_block_info *pbi;
       rtx x, insn;
  {
    rtx cond = NULL_RTX;
*************** mark_set_regs (pbi, new_dead, x, insn)
*** 3917,3923 ****
      {
      case SET:
      case CLOBBER:
!       mark_set_1 (pbi, new_dead, SET_DEST (x), cond, insn);
        return;
  
      case COND_EXEC:
--- 3904,3910 ----
      {
      case SET:
      case CLOBBER:
!       mark_set_1 (pbi, SET_DEST (x), cond, insn);
        return;
  
      case COND_EXEC:
*************** mark_set_regs (pbi, new_dead, x, insn)
*** 3945,3951 ****
  
  	      case SET:
  	      case CLOBBER:
! 		mark_set_1 (pbi, new_dead, SET_DEST (sub), cond, insn);
  		break;
  
  	      default:
--- 3932,3938 ----
  
  	      case SET:
  	      case CLOBBER:
! 		mark_set_1 (pbi, SET_DEST (sub), cond, insn);
  		break;
  
  	      default:
*************** mark_set_regs (pbi, new_dead, x, insn)
*** 3963,3971 ****
  /* Process a single SET rtx, X.  */
  
  static void
! mark_set_1 (pbi, new_dead, reg, cond, insn)
       struct propagate_block_info *pbi;
-      regset new_dead;
       rtx reg, cond, insn;
  {
    register int regno = -1;
--- 3950,3957 ----
  /* Process a single SET rtx, X.  */
  
  static void
! mark_set_1 (pbi, reg, cond, insn)
       struct propagate_block_info *pbi;
       rtx reg, cond, insn;
  {
    register int regno = -1;
*************** mark_set_1 (pbi, new_dead, reg, cond, in
*** 3980,4000 ****
        register int i;
  
        for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
! 	mark_set_1 (pbi, new_dead, XVECEXP (reg, 0, i), cond, insn);
        return;
      }
  
!   /* Modifying just one hardware register of a multi-reg value
!      or just a byte field of a register
!      does not mean the value from before this insn is now dead.
!      But it does mean liveness of that register at the end of the block
!      is significant.
  
!      Within mark_set_1, however, we treat it as if the register is
!      indeed modified.  mark_used_regs will, however, also treat this
!      register as being used.  Thus, we treat these insns as setting a
!      new value for the register as a function of its old value.  This
!      cases LOG_LINKS to be made appropriately and this will help combine.  */
  
    while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT
  	 || GET_CODE (reg) == SIGN_EXTRACT
--- 3966,3990 ----
        register int i;
  
        for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
! 	mark_set_1 (pbi, XVECEXP (reg, 0, i), cond, insn);
        return;
      }
  
!   /* Modifying just one hardware register of a multi-reg value or just a
!      byte field of a register does not mean the value from before this insn
!      is now dead.  But it does mean liveness of that register at the end of
!      the block is significant.
  
!      Within mark_set_1, however, we treat it as if the register is indeed
!      modified.  mark_used_regs will, however, also treat this register as
!      being used.  Thus, we treat these insns as setting a new value for the
!      register as a function of its old value.  This cases LOG_LINKS to be
!      made appropriately and this will help combine. 
! 
!      ??? This is all done incorrectly.  We should not be setting bits in
!      new_dead for these registers, since, as we just explained, they are
!      not dead.  We should be setting bits in local_set, and updating
!      LOG_LINKS, but that is different.  */
  
    while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT
  	 || GET_CODE (reg) == SIGN_EXTRACT
*************** mark_set_1 (pbi, new_dead, reg, cond, in
*** 4065,4072 ****
        int some_was_live, some_was_dead;
  
        /* Perform the pbi datastructure update.  */
!       if (! mark_set_reg (pbi, new_dead, reg, cond,
! 			  &some_was_live, &some_was_dead))
  	return;
  
        /* Additional data to record if this is the final pass.  */
--- 4055,4061 ----
        int some_was_live, some_was_dead;
  
        /* Perform the pbi datastructure update.  */
!       if (! mark_set_reg (pbi, reg, cond, &some_was_live, &some_was_dead))
  	return;
  
        /* Additional data to record if this is the final pass.  */
*************** mark_set_1 (pbi, new_dead, reg, cond, in
*** 4210,4218 ****
     Return true if REG is now unconditionally dead.  */
  
  static int
! mark_set_reg (pbi, new_dead, reg, cond, p_some_was_live, p_some_was_dead)
       struct propagate_block_info *pbi;
-      regset new_dead;
       rtx reg;
       rtx cond ATTRIBUTE_UNUSED;
       int *p_some_was_live, *p_some_was_dead;
--- 4199,4206 ----
     Return true if REG is now unconditionally dead.  */
  
  static int
! mark_set_reg (pbi, reg, cond, p_some_was_live, p_some_was_dead)
       struct propagate_block_info *pbi;
       rtx reg;
       rtx cond ATTRIBUTE_UNUSED;
       int *p_some_was_live, *p_some_was_dead;
*************** mark_set_reg (pbi, new_dead, reg, cond, 
*** 4252,4263 ****
      return 0;
  
    /* Mark it as dead before this insn.  */
!   SET_REGNO_REG_SET (new_dead, regno);
    if (regno < FIRST_PSEUDO_REGISTER)
      {
        int n = HARD_REGNO_NREGS (regno, GET_MODE (reg));
        while (--n > 0)
! 	SET_REGNO_REG_SET (new_dead, regno + n);
      }
  
    /* Unconditionally dead.  */
--- 4240,4251 ----
      return 0;
  
    /* Mark it as dead before this insn.  */
!   SET_REGNO_REG_SET (pbi->new_dead, regno);
    if (regno < FIRST_PSEUDO_REGISTER)
      {
        int n = HARD_REGNO_NREGS (regno, GET_MODE (reg));
        while (--n > 0)
! 	SET_REGNO_REG_SET (pbi->new_dead, regno + n);
      }
  
    /* Unconditionally dead.  */
*************** find_auto_inc (pbi, x, insn)
*** 4444,4452 ****
  #endif /* AUTO_INC_DEC */
  
  static void
! mark_used_reg (pbi, new_live, reg, cond, insn)
       struct propagate_block_info *pbi;
-      regset new_live;
       rtx reg;
       rtx cond ATTRIBUTE_UNUSED;
       rtx insn;
--- 4432,4439 ----
  #endif /* AUTO_INC_DEC */
  
  static void
! mark_used_reg (pbi, reg, cond, insn)
       struct propagate_block_info *pbi;
       rtx reg;
       rtx cond ATTRIBUTE_UNUSED;
       rtx insn;
*************** mark_used_reg (pbi, new_live, reg, cond,
*** 4455,4461 ****
    int some_was_live = REGNO_REG_SET_P (pbi->reg_live, regno);
    int some_was_dead = ! some_was_live;
  
!   SET_REGNO_REG_SET (new_live, regno);
  
    /* A hard reg in a wide mode may really be multiple registers.
       If so, mark all of them just like the first.  */
--- 4442,4448 ----
    int some_was_live = REGNO_REG_SET_P (pbi->reg_live, regno);
    int some_was_dead = ! some_was_live;
  
!   SET_REGNO_REG_SET (pbi->new_live, regno);
  
    /* A hard reg in a wide mode may really be multiple registers.
       If so, mark all of them just like the first.  */
*************** mark_used_reg (pbi, new_live, reg, cond,
*** 4467,4473 ****
  	  int regno_n = regno + n;
  	  int needed_regno = REGNO_REG_SET_P (pbi->reg_live, regno_n);
  
! 	  SET_REGNO_REG_SET (new_live, regno_n);
  	  some_was_live |= needed_regno;
  	  some_was_dead |= ! needed_regno;
  	}
--- 4454,4460 ----
  	  int regno_n = regno + n;
  	  int needed_regno = REGNO_REG_SET_P (pbi->reg_live, regno_n);
  
! 	  SET_REGNO_REG_SET (pbi->new_live, regno_n);
  	  some_was_live |= needed_regno;
  	  some_was_dead |= ! needed_regno;
  	}
*************** mark_used_reg (pbi, new_live, reg, cond,
*** 4520,4536 ****
  
    /* Record and count the insns in which a reg dies.  If it is used in
       this insn and was dead below the insn then it dies in this insn.
- 
       If it was set in this insn, we do not make a REG_DEAD note;
!      likewise if we already made such a note.  Recall that dead_or_set_p
!      checks for complete overlap, and thus is not suitable for the first
!      case.  But it does handle the existing note case.  Also recall that
!      reg_set_p, when presented with the complete insn, will try to infer
!      things about a call_insn that we do not wish.  */
  
    if ((pbi->flags & PROP_DEATH_NOTES)
        && some_was_dead
-       && ! reg_set_p (reg, PATTERN (insn))
        && ! dead_or_set_p (insn, reg))
      {
        int n;
--- 4507,4530 ----
  
    /* Record and count the insns in which a reg dies.  If it is used in
       this insn and was dead below the insn then it dies in this insn.
       If it was set in this insn, we do not make a REG_DEAD note;
!      likewise if we already made such a note. 
! 
!      ??? This could be done better.  In new_dead we have a record of 
!      which registers are set or clobbered this insn (which in itself is
!      slightly incorrect, see the commentary near strict_low_part in
!      mark_set_1), which should be the set of registers that we do not
!      wish to create death notes for under the above rule.  Note that
!      we have not yet processed the call-clobbered/call-used registers,
!      and they do not quite follow the above rule, since we do want death
!      notes for call-clobbered register arguments.  Which begs the whole
!      question of whether we should in fact have death notes for registers
!      used and clobbered (but not set) in the same insn.  The only useful
!      thing we ought to be getting from dead_or_set_p is detection of
!      duplicate death notes.  */
  
    if ((pbi->flags & PROP_DEATH_NOTES)
        && some_was_dead
        && ! dead_or_set_p (insn, reg))
      {
        int n;
*************** mark_used_reg (pbi, new_live, reg, cond,
*** 4578,4586 ****
     is not called.  */
  
  static void
! mark_used_regs (pbi, new_live, x, cond, insn)
       struct propagate_block_info *pbi;
-      regset new_live;
       rtx x, cond, insn;
  {
    register RTX_CODE code;
--- 4572,4579 ----
     is not called.  */
  
  static void
! mark_used_regs (pbi, x, cond, insn)
       struct propagate_block_info *pbi;
       rtx x, cond, insn;
  {
    register RTX_CODE code;
*************** mark_used_regs (pbi, new_live, x, cond, 
*** 4611,4617 ****
        /* If we are clobbering a MEM, mark any registers inside the address
  	 as being used.  */
        if (GET_CODE (XEXP (x, 0)) == MEM)
! 	mark_used_regs (pbi, new_live, XEXP (XEXP (x, 0), 0), cond, insn);
        return;
  
      case MEM:
--- 4604,4610 ----
        /* If we are clobbering a MEM, mark any registers inside the address
  	 as being used.  */
        if (GET_CODE (XEXP (x, 0)) == MEM)
! 	mark_used_regs (pbi, XEXP (XEXP (x, 0), 0), cond, insn);
        return;
  
      case MEM:
*************** mark_used_regs (pbi, new_live, x, cond, 
*** 4676,4682 ****
  
      case REG:
        /* See a register other than being set => mark it as needed.  */
!       mark_used_reg (pbi, new_live, x, cond, insn);
        return;
  
      case SET:
--- 4669,4675 ----
  
      case REG:
        /* See a register other than being set => mark it as needed.  */
!       mark_used_reg (pbi, x, cond, insn);
        return;
  
      case SET:
*************** mark_used_regs (pbi, new_live, x, cond, 
*** 4692,4699 ****
  	    if (flags & PROP_AUTOINC)
  	      find_auto_inc (pbi, testreg, insn);
  #endif
! 	    mark_used_regs (pbi, new_live, XEXP (testreg, 0), cond, insn);
! 	    mark_used_regs (pbi, new_live, SET_SRC (x), cond, insn);
  	    return;
  	  }
  	    
--- 4685,4692 ----
  	    if (flags & PROP_AUTOINC)
  	      find_auto_inc (pbi, testreg, insn);
  #endif
! 	    mark_used_regs (pbi, XEXP (testreg, 0), cond, insn);
! 	    mark_used_regs (pbi, SET_SRC (x), cond, insn);
  	    return;
  	  }
  	    
*************** mark_used_regs (pbi, new_live, x, cond, 
*** 4745,4756 ****
  		&& ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
  #endif
  		))
- 	  /* We used to exclude global_regs here, but that seems wrong.
- 	     Storing in them is like storing in mem.  */
  	  {
- 	    mark_used_regs (pbi, new_live, SET_SRC (x), cond, insn);
  	    if (mark_dest)
! 	      mark_used_regs (pbi, new_live, SET_DEST (x), cond, insn);
  	    return;
  	  }
        }
--- 4738,4747 ----
  		&& ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
  #endif
  		))
  	  {
  	    if (mark_dest)
! 	      mark_used_regs (pbi, SET_DEST (x), cond, insn);
! 	    mark_used_regs (pbi, SET_SRC (x), cond, insn);
  	    return;
  	  }
        }
*************** mark_used_regs (pbi, new_live, x, cond, 
*** 4787,4794 ****
  	    int j;
  
  	    for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
! 	      mark_used_regs (pbi, new_live, ASM_OPERANDS_INPUT (x, j),
! 			      cond, insn);
  	  }
  	break;
        }
--- 4778,4784 ----
  	    int j;
  
  	    for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
! 	      mark_used_regs (pbi, ASM_OPERANDS_INPUT (x, j), cond, insn);
  	  }
  	break;
        }
*************** mark_used_regs (pbi, new_live, x, cond, 
*** 4797,4803 ****
        if (cond != NULL_RTX)
  	abort ();
  
!       mark_used_regs (pbi, new_live, COND_EXEC_TEST (x), NULL_RTX, insn);
  
        cond = COND_EXEC_TEST (x);
        x = COND_EXEC_CODE (x);
--- 4787,4793 ----
        if (cond != NULL_RTX)
  	abort ();
  
!       mark_used_regs (pbi, COND_EXEC_TEST (x), NULL_RTX, insn);
  
        cond = COND_EXEC_TEST (x);
        x = COND_EXEC_CODE (x);
*************** mark_used_regs (pbi, new_live, x, cond, 
*** 4831,4843 ****
  		x = XEXP (x, 0);
  		goto retry;
  	      }
! 	    mark_used_regs (pbi, new_live, XEXP (x, i), cond, insn);
  	  }
  	else if (fmt[i] == 'E')
  	  {
  	    register int j;
  	    for (j = 0; j < XVECLEN (x, i); j++)
! 	      mark_used_regs (pbi, new_live, XVECEXP (x, i, j), cond, insn);
  	  }
        }
    }
--- 4821,4833 ----
  		x = XEXP (x, 0);
  		goto retry;
  	      }
! 	    mark_used_regs (pbi, XEXP (x, i), cond, insn);
  	  }
  	else if (fmt[i] == 'E')
  	  {
  	    register int j;
  	    for (j = 0; j < XVECLEN (x, i); j++)
! 	      mark_used_regs (pbi, XVECEXP (x, i, j), cond, insn);
  	  }
        }
    }

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