Avoid duplicate vector initializations during RTL expansion.

Message ID 00af01d99c7f$e8a7a1e0$b9f6e5a0$@nextmovesoftware.com
State Accepted
Headers
Series Avoid duplicate vector initializations during RTL expansion. |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Roger Sayle June 11, 2023, 4:15 p.m. UTC
  This middle-end patch avoids some redundant RTL for vector initialization
during RTL expansion.  For the simple test case:

typedef __int128 v1ti __attribute__ ((__vector_size__ (16)));
__int128 key;

v1ti foo() {
    return (v1ti){key};
}

the middle-end currently expands:

(set (reg:V1TI 85) (const_vector:V1TI [ (const_int 0) ]))

(set (reg:V1TI 85) (mem/c:V1TI (symbol_ref:DI ("key"))))

where we create a dead instruction that initializes the vector to zero,
immediately followed by a set of the entire vector.  This patch skips
this zeroing instruction when the vector has only a single element.
It also updates the code to indicate when we've cleared the vector,
so that we don't need to initialize zero elements.

Interestingly, this code is very similar to my patch from April 2006:
https://gcc.gnu.org/pipermail/gcc-patches/2006-April/192861.html


This patch has been tested on x86_64-pc-linux-gnu with a make bootstrap
and make -k check, both with and without --target_board=unix{-m32}, with
no new failures.  Ok for mainline?


2023-06-11  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
        * expr.cc (store_constructor) <case VECTOR_TYPE>: Don't bother
        clearing vectors with only a single element.  Set CLEARED if the
        vector was initialized to zero.


Thanks,
Roger
--
  

Comments

Jeff Law June 12, 2023, 10:37 p.m. UTC | #1
On 6/11/23 10:15, Roger Sayle wrote:
> 
> This middle-end patch avoids some redundant RTL for vector initialization
> during RTL expansion.  For the simple test case:
> 
> typedef __int128 v1ti __attribute__ ((__vector_size__ (16)));
> __int128 key;
> 
> v1ti foo() {
>      return (v1ti){key};
> }
> 
> the middle-end currently expands:
> 
> (set (reg:V1TI 85) (const_vector:V1TI [ (const_int 0) ]))
> 
> (set (reg:V1TI 85) (mem/c:V1TI (symbol_ref:DI ("key"))))
> 
> where we create a dead instruction that initializes the vector to zero,
> immediately followed by a set of the entire vector.  This patch skips
> this zeroing instruction when the vector has only a single element.
> It also updates the code to indicate when we've cleared the vector,
> so that we don't need to initialize zero elements.
> 
> Interestingly, this code is very similar to my patch from April 2006:
> https://gcc.gnu.org/pipermail/gcc-patches/2006-April/192861.html
> 
> 
> This patch has been tested on x86_64-pc-linux-gnu with a make bootstrap
> and make -k check, both with and without --target_board=unix{-m32}, with
> no new failures.  Ok for mainline?
> 
> 
> 2023-06-11  Roger Sayle  <roger@nextmovesoftware.com>
> 
> gcc/ChangeLog
>          * expr.cc (store_constructor) <case VECTOR_TYPE>: Don't bother
>          clearing vectors with only a single element.  Set CLEARED if the
>          vector was initialized to zero.
Funny how old (unresolved) issues will often raise their ugly heads again!

OK for the trunk.

jeff
  

Patch

diff --git a/gcc/expr.cc b/gcc/expr.cc
index 868fa6e..62cd8fa 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -7531,8 +7531,11 @@  store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
 	  }
 
 	/* Inform later passes that the old value is dead.  */
-	if (!cleared && !vector && REG_P (target))
-	  emit_move_insn (target, CONST0_RTX (mode));
+	if (!cleared && !vector && REG_P (target) && maybe_gt (n_elts, 1u))
+	  {
+	    emit_move_insn (target, CONST0_RTX (mode));
+	    cleared = 1;
+	  }
 
         if (MEM_P (target))
 	  alias = MEM_ALIAS_SET (target);