]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR rtl-optimization/110587: Reduce useless moves in compile-time hog.
authorRoger Sayle <roger@nextmovesoftware.com>
Fri, 28 Jul 2023 08:39:46 +0000 (09:39 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Fri, 28 Jul 2023 08:39:46 +0000 (09:39 +0100)
This patch is one of a series of fixes for PR rtl-optimization/110587,
a compile-time regression with -O0, that attempts to address the underlying
cause.  As noted previously, the pathological test case pr28071.c contains
a large number of useless register-to-register moves that can produce
quadratic behaviour (in LRA).  These moves are generated during RTL
expansion in emit_group_load_1, where the middle-end attempts to simplify
the source before calling extract_bit_field.  This is reasonable if the
source is a complex expression (from before the tree-ssa optimizers), or
a SUBREG, or a hard register, but it's not particularly useful to copy
a pseudo register into a new pseudo register.  This patch eliminates that
redundancy.

The -fdump-tree-expand for pr28071.c compiled with -O0 currently contains
777K lines, with this patch it contains 717K lines, i.e. saving about 60K
lines (admittedly of debugging text output, but it makes the point).

2023-07-28  Roger Sayle  <roger@nextmovesoftware.com>
    Richard Biener  <rguenther@suse.de>

gcc/ChangeLog
PR middle-end/28071
PR rtl-optimization/110587
* expr.cc (emit_group_load_1): Simplify logic for calling
force_reg on ORIG_SRC, to avoid making a copy if the source
is already in a pseudo register.

gcc/expr.cc

index fff09dc995107db448370331e8b06d562a4b3542..174f8acb269ab5450fc799516471d5a2bd9b9efa 100644 (file)
@@ -2622,16 +2622,11 @@ emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type,
         be loaded directly into the destination.  */
       src = orig_src;
       if (!MEM_P (orig_src)
-         && (!CONSTANT_P (orig_src)
-             || (GET_MODE (orig_src) != mode
-                 && GET_MODE (orig_src) != VOIDmode)))
+         && (!REG_P (orig_src) || HARD_REGISTER_P (orig_src))
+         && !CONSTANT_P (orig_src))
        {
-         if (GET_MODE (orig_src) == VOIDmode)
-           src = gen_reg_rtx (mode);
-         else
-           src = gen_reg_rtx (GET_MODE (orig_src));
-
-         emit_move_insn (src, orig_src);
+         gcc_assert (GET_MODE (orig_src) != VOIDmode);
+         src = force_reg (GET_MODE (orig_src), orig_src);
        }
 
       /* Optimize the access just a bit.  */