This is the mail archive of the gcc@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]

[dataflow] partial register handling


Hi,

I have a few problems with the m68k mulsidi3 pattern on the dataflow
branch.
Currently incorrect code is generated as the DF_REF_PARTIAL bit isn't
set for its destinations and dataflow thinks both set the register
completely, thus one destination is set to unused. I could change the
pattern to include a strict_low_part, but that still wouldn't help due
to a bug in df_def_record_1().
Looking closer at this I don't think strict_low_part should be required
as splitting DI registers produces a lot of (subreg:SI (reg:DI)) even as
destination, but they only set strictly part of the register. If I look
through i386/m68k I don't see a single (strict_low_part (subreg:SI)).
I also think that ZERO_EXTRACT should set DF_REF_PARTIAL as well, since
e.g. these two patterns are equivalent:

(set (strict_low_part (subreg:HI (reg:SI))) ...)
(set (zero_extract:SI (reg:SI) (const_int 16) (const_int 16)) ...)

Below is the first attempt at fixing this, the subreg handling might
need further improvement. df_ref_record sets the partial bit for hard
registers but not for virtual registers?
I also removed one check from df_read_modify_subreg_p, why should
(subreg:QI (reg:DI)) be treated differently than (subreg:QI (reg:SI))? 
The df_read_modify_subreg_p might be taken out of the loop, as currently
df_ref_record sees only a fraction of all subregs and thus I'm not sure
the subreg check always works.

bye, Roman

---
 gcc/df-scan.c |   28 ------------!!!!!!!!!!!!!!!!
 1 file changed, 12 deletions(-), 16 modifications(!)

Index: gcc-dataflow/gcc/df-scan.c
===================================================================
*** gcc-dataflow.orig/gcc/df-scan.c
--- gcc-dataflow/gcc/df-scan.c
*************** df_read_modify_subreg_p (rtx x)
*** 2702,2708 ****
      return false;
    isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
    osize = GET_MODE_SIZE (GET_MODE (x));
!   return (isize > osize && isize > UNITS_PER_WORD);
  }
  
  
--- 2702,2708 ----
      return false;
    isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
    osize = GET_MODE_SIZE (GET_MODE (x));
!   return isize > osize;
  }
  
  
*************** df_def_record_1 (struct df_collection_re
*** 2717,2723 ****
  {
    rtx *loc;
    rtx dst;
-   bool dst_in_strict_lowpart = false;
  
   /* We may recursively call ourselves on EXPR_LIST when dealing with PARALLEL
       construct.  */
--- 2717,2722 ----
*************** df_def_record_1 (struct df_collection_re
*** 2751,2780 ****
  	 || GET_CODE (dst) == ZERO_EXTRACT
  	 || df_read_modify_subreg_p (dst))
      {
! #if 0
!       /* Strict low part always contains SUBREG, but we do not want to make
! 	 it appear outside, as whole register is always considered.  */
!       if (GET_CODE (dst) == STRICT_LOW_PART)
! 	{
! 	  loc = &XEXP (dst, 0);
! 	  dst = *loc;
! 	}
! #endif
        loc = &XEXP (dst, 0);
-       if (GET_CODE (dst) == STRICT_LOW_PART)
- 	dst_in_strict_lowpart = true;
        dst = *loc;
-       flags |= DF_REF_READ_WRITE;
- 
      }
  
-   /* Sets to a subreg of a single word register are partial sets if
-      they are wrapped in a strict lowpart, and not partial otherwise.
-   */
-   if (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst))
-       && dst_in_strict_lowpart)
-     flags |= DF_REF_PARTIAL;
-     
    if (REG_P (dst)
        || (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst))))
      df_ref_record (collection_rec, 
--- 2750,2764 ----
  	 || GET_CODE (dst) == ZERO_EXTRACT
  	 || df_read_modify_subreg_p (dst))
      {
!       flags |= DF_REF_READ_WRITE;
!       if (GET_CODE (dst) != SUBREG
! 	  || GET_MODE_SIZE (GET_MODE (dst))
! 	     >= REGMODE_NATURAL_SIZE (GET_MODE (dst)))
! 	flags |= DF_REF_PARTIAL;
        loc = &XEXP (dst, 0);
        dst = *loc;
      }
  
    if (REG_P (dst)
        || (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst))))
      df_ref_record (collection_rec, 


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