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]
Other format: [Raw text]

Re: RFA: autoincrement patches for gcc 4 - updated patch


I've appended a patch with the simple solution to the 3-address add problem. A quick
re-run of CSiBE after regenerating cc1/cc1plus/cc1obj gives a total size of
3511488, i.e. 8 bytes code size decrease from the baseline. I'm not sure if re-building
the libraries will give a different result, though.
Add this to the ChangeLog:
	* (have_3addr_const_add): New variable.

... and this patch on top:

*** regmove.c-20050518-1	2005-05-18 10:26:14.000000000 +0100
--- regmove.c	2005-05-18 14:43:30.000000000 +0100
*************** static struct obstack related_obstack;
*** 597,602 ****
--- 597,603 ----
     them out.  */
     
  static HOST_WIDE_INT add_limits[NUM_MACHINE_MODES][2];
+ static char have_3addr_const_add[NUM_MACHINE_MODES];
  
  /* Try to find a related value with offset OFFSET from the base
     register belonging to REGNO, using a register with preferred class
*************** link_chains (struct rel_use_chain *pred_
*** 1548,1553 ****
--- 1549,1555 ----
  				pred_chain->uses->class)
        /* add_limits is not valid for MODE_PARTIAL_INT .  */
        && GET_MODE_CLASS (base_mode) == MODE_INT
+       && !have_3addr_const_add[(int) base_mode]
        && (succ_chain->uses->offset - pred_chain->match_offset
  	  >= add_limits[(int) base_mode][0])
        && (succ_chain->uses->offset - pred_chain->match_offset
*************** optimize_related_values_1 (struct relate
*** 1725,1730 ****
--- 1727,1733 ----
  	  struct rel_use_chain *chain = chain_starttab[i];
  	  if (! chain->reg
  	      && chain->start_luid
+ 	      && (!have_3addr_const_add[(int) mode] || !chain->uses->offset)
  	      && chain->uses->offset >= add_limits[(int) mode][0]
  	      && chain->uses->offset <= add_limits[(int) mode][1]
  	      /* Also can't use this chain if its register is clobbered
*************** optimize_related_values_1 (struct relate
*** 1787,1800 ****
       however, if the base register is allocated to a chain
       (i.e. rel_base_reg_user != 0), we don't need a move insn to start
       that chain.
       We do the optimization if we save instructions, or if we
       stay with the same number of instructions, but save registers.
       We also require that we have enough registers available for reuse.
       Moreover, we have to check that we can add the offset for
       rel_base_reg_user, in case it is a mandatory allocated register.  */
!   if ((2 * num_regs
!        > ((2 * num_chains - num_linked - (rel_base_reg_user != 0))
! 	  - (num_linked != 0)))
        && num_av_regs + (rel_base_reg_user != 0) >= num_chains - num_linked
        && rel_base_reg_user_offset >= add_limits[(int) mode][0]
        && rel_base_reg_user_offset <= add_limits[(int) mode][1])
--- 1790,1807 ----
       however, if the base register is allocated to a chain
       (i.e. rel_base_reg_user != 0), we don't need a move insn to start
       that chain.
+      If we have a three-address add, however, the cost per value / chain
+      is just one insn, and linking chains is pointless.
       We do the optimization if we save instructions, or if we
       stay with the same number of instructions, but save registers.
       We also require that we have enough registers available for reuse.
       Moreover, we have to check that we can add the offset for
       rel_base_reg_user, in case it is a mandatory allocated register.  */
!   if ((have_3addr_const_add[(int) mode]
!        ? (num_regs > num_chains - (rel_base_reg_user != 0))
!        : (2 * num_regs
! 	  > ((2 * num_chains - num_linked - (rel_base_reg_user != 0))
! 	     - (num_linked != 0))))
        && num_av_regs + (rel_base_reg_user != 0) >= num_chains - num_linked
        && rel_base_reg_user_offset >= add_limits[(int) mode][0]
        && rel_base_reg_user_offset <= add_limits[(int) mode][1])
*************** init_add_limits (void)
*** 2058,2076 ****
         mode = GET_MODE_WIDER_MODE (mode))
      {
        rtx reg = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER+1);
        int icode = (int) add_optab->handlers[(int) mode].insn_code;
        HOST_WIDE_INT tmp;
        rtx add = NULL, set = NULL;
        int p, p_max;
  
        add_limits[(int) mode][0] = 0;
        add_limits[(int) mode][1] = 0;
        
        if (icode == CODE_FOR_nothing
  	  || ! (*insn_data[icode].operand[0].predicate) (reg, mode)
! 	  || ! (*insn_data[icode].operand[1].predicate) (reg, mode))
  	continue;
        
        p_max = GET_MODE_BITSIZE (mode) - 1;
        
        if (p_max > HOST_BITS_PER_WIDE_INT - 2)
--- 2065,2091 ----
         mode = GET_MODE_WIDER_MODE (mode))
      {
        rtx reg = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER+1);
+       rtx reg2 = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER+2);
        int icode = (int) add_optab->handlers[(int) mode].insn_code;
        HOST_WIDE_INT tmp;
        rtx add = NULL, set = NULL;
        int p, p_max;
+       rtx tmp_add;
  
+       have_3addr_const_add[(int) mode] = 0;
        add_limits[(int) mode][0] = 0;
        add_limits[(int) mode][1] = 0;
        
        if (icode == CODE_FOR_nothing
  	  || ! (*insn_data[icode].operand[0].predicate) (reg, mode)
! 	  || ! (*insn_data[icode].operand[1].predicate) (reg, mode)
! 	  || ! (*insn_data[icode].operand[2].predicate) (const1_rtx, mode))
  	continue;
        
+       tmp_add = GEN_FCN (icode) (reg, reg2, const1_rtx);
+       if (tmp_add != NULL_RTX && !NEXT_INSN (tmp_add))
+ 	have_3addr_const_add[(int) mode] = 1;
+ 
        p_max = GET_MODE_BITSIZE (mode) - 1;
        
        if (p_max > HOST_BITS_PER_WIDE_INT - 2)
*************** init_add_limits (void)
*** 2079,2085 ****
        for (p = 1; p < p_max; p++)
  	{
  	  rtx add_const = GEN_INT (((HOST_WIDE_INT) 1 << p) - 1);
- 	  rtx tmp_add;
  
  	  if (! (*insn_data[icode].operand[2].predicate) (add_const, mode))
  	    break;
--- 2094,2099 ----

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