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]

[PATCH][RFC] Fix PR54201, share constant pool entries for CONST_VECTORs


This implements constant pool entry sharing for CONST_VECTORs with the
same bit-pattern by canonicalizing them to the same-sized mode with
the least number of elements.  Ideally we would be able to hash and
compare the in-memory representation of a constant (together with
its alignment requirement), but I'm not aware of any RTL facility
that would be equivalent to native_{interpret,encode}_expr.  So this
just handles CONST_VECTORs as requested in the bugreport.

Bootstrap and regtest pending on x86_64-unknown-linux-gnu.

Any comments?

It would be interesting to pursue a way to share constant parts
(beware of endian and odd alignment issues) by means of simply
inserting more entries into the hashtable.  Not sure if
offsetted .LC references are valid as result of force_const_mem
though (well, we could try to share the part at offset zero).

Thanks,
Richard.

2012-08-14  Richard Guenther  <rguenther@suse.de>

	PR middle-end/54201
	* varasm.c (force_const_mem): Canonicalize CONST_VECTORs
	to the same-sized mode with the least number of elements
	for the purpose of constant slot sharing.

	* gcc.target/i386/pr54201.c: New testcase.

Index: gcc/varasm.c
===================================================================
*** gcc/varasm.c	(revision 190381)
--- gcc/varasm.c	(working copy)
*************** force_const_mem (enum machine_mode mode,
*** 3482,3489 ****
  {
    struct constant_descriptor_rtx *desc, tmp;
    struct rtx_constant_pool *pool;
    char label[256];
!   rtx def, symbol;
    hashval_t hash;
    unsigned int align;
    void **slot;
--- 3482,3490 ----
  {
    struct constant_descriptor_rtx *desc, tmp;
    struct rtx_constant_pool *pool;
+   enum machine_mode orig_mode = mode;
    char label[256];
!   rtx def, symbol, res;
    hashval_t hash;
    unsigned int align;
    void **slot;
*************** force_const_mem (enum machine_mode mode,
*** 3500,3505 ****
--- 3501,3518 ----
  	  ? shared_constant_pool
  	  : crtl->varasm.pool);
  
+   /* Canonicalize CONST_VECTORs to the mode with the least number of
+      elements assuming that alignment requirements are not worse
+      for the original mode.  */
+   if (GET_CODE (x) == CONST_VECTOR)
+     {
+       while (GET_MODE_SIZE (mode)
+ 	     == GET_MODE_SIZE (GET_MODE_WIDER_MODE (mode)))
+ 	mode = GET_MODE_WIDER_MODE (mode);
+       x = simplify_subreg (mode, x, orig_mode, 0);
+       gcc_assert (x != NULL_RTX);
+     }
+ 
    /* Lookup the value in the hashtable.  */
    tmp.constant = x;
    tmp.mode = mode;
*************** force_const_mem (enum machine_mode mode,
*** 3509,3515 ****
  
    /* If the constant was already present, return its memory.  */
    if (desc)
!     return copy_rtx (desc->mem);
  
    /* Otherwise, create a new descriptor.  */
    desc = ggc_alloc_constant_descriptor_rtx ();
--- 3522,3532 ----
  
    /* If the constant was already present, return its memory.  */
    if (desc)
!     {
!       res = copy_rtx (desc->mem);
!       PUT_MODE (res, orig_mode);
!       return res;
!     }
  
    /* Otherwise, create a new descriptor.  */
    desc = ggc_alloc_constant_descriptor_rtx ();
*************** force_const_mem (enum machine_mode mode,
*** 3573,3579 ****
    if (GET_CODE (x) == LABEL_REF)
      LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
  
!   return copy_rtx (def);
  }
  
  /* Given a constant pool SYMBOL_REF, return the corresponding constant.  */
--- 3590,3598 ----
    if (GET_CODE (x) == LABEL_REF)
      LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
  
!   res = copy_rtx (def);
!   PUT_MODE (res, orig_mode);
!   return res;
  }
  
  /* Given a constant pool SYMBOL_REF, return the corresponding constant.  */
Index: gcc/testsuite/gcc.target/i386/pr54201.c
===================================================================
*** gcc/testsuite/gcc.target/i386/pr54201.c	(revision 0)
--- gcc/testsuite/gcc.target/i386/pr54201.c	(working copy)
***************
*** 0 ****
--- 1,15 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -msse2" } */
+ 
+ #include <emmintrin.h>
+ 
+ __m128i test(__m128i value)
+ {
+   __m128i mask = _mm_set1_epi8(1);
+   return _mm_cmpeq_epi8(_mm_and_si128(value, mask), mask);
+ }
+ 
+ /* We should share constant slots for V16QI { 1, ... 1 } and its V2DI 
+    representation.  */
+ 
+ /* { dg-final { scan-assembler-not "LC1" } } */


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