https://gcc.gnu.org/g:a7cce1afee8ba28c524a4a43f0081e36e5501cf2

commit r16-7880-ga7cce1afee8ba28c524a4a43f0081e36e5501cf2
Author: H.J. Lu <[email protected]>
Date:   Sun Feb 22 10:32:30 2026 +0800

    x86: Call ix86_access_stack_p only with symbolic constant load
    
    ix86_access_stack_p can be quite expensive.  Cache the result and call it
    only if there are symbolic constant loads.  This reduces the compile time
    of PR target/124165 test from 202 seconds to 55 seconds.
    
    gcc/
    
            PR target/124165
            * config/i386/i386-protos.h (symbolic_reference_mentioned_p):
            Change the argument type from rtx to const_rtx.
            * config/i386/i386.cc (symbolic_reference_mentioned_p): Likewise.
            (ix86_access_stack_p): Add 2 auto_bitmap[] arguments.  Cache
            the register BB domination result.
            (ix86_symbolic_const_load_p_1): New.
            (ix86_symbolic_const_load_p): Likewise.
            (ix86_find_max_used_stack_alignment): If there is no symbolic
            constant load into the register, don't call ix86_access_stack_p.
    
    Signed-off-by: H.J. Lu <[email protected]>

Diff:
---
 gcc/config/i386/i386-protos.h |   2 +-
 gcc/config/i386/i386.cc       | 144 +++++++++++++++++++++++++++++++++++-------
 2 files changed, 123 insertions(+), 23 deletions(-)

diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 20b964748581..4ba4fb08556e 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -60,7 +60,7 @@ extern int standard_sse_constant_p (rtx, machine_mode);
 extern const char *standard_sse_constant_opcode (rtx_insn *, rtx *);
 extern bool ix86_standard_x87sse_constant_load_p (const rtx_insn *, rtx);
 extern bool ix86_pre_reload_split (void);
-extern bool symbolic_reference_mentioned_p (rtx);
+extern bool symbolic_reference_mentioned_p (const_rtx);
 extern bool extended_reg_mentioned_p (rtx);
 extern bool x86_extended_QIreg_mentioned_p (rtx_insn *);
 extern bool x86_extended_reg_mentioned_p (rtx);
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 428b68aff471..c43c3ac18acf 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -5990,7 +5990,7 @@ ix86_output_ssemov (rtx_insn *insn, rtx *operands)
 /* Returns true if OP contains a symbol reference */
 
 bool
-symbolic_reference_mentioned_p (rtx op)
+symbolic_reference_mentioned_p (const_rtx op)
 {
   const char *fmt;
   int i;
@@ -8717,8 +8717,15 @@ ix86_find_all_reg_uses (HARD_REG_SET &regset,
 static bool
 ix86_access_stack_p (unsigned int regno, basic_block bb,
                     HARD_REG_SET &set_up_by_prologue,
-                    HARD_REG_SET &prologue_used)
+                    HARD_REG_SET &prologue_used,
+                    auto_bitmap reg_dominate_bbs_known[],
+                    auto_bitmap reg_dominate_bbs[])
 {
+  if (bitmap_bit_p (reg_dominate_bbs_known[regno], bb->index))
+    return bitmap_bit_p (reg_dominate_bbs[regno], bb->index);
+
+  bitmap_set_bit (reg_dominate_bbs_known[regno], bb->index);
+
   /* Get all BBs which set REGNO and dominate the current BB from all
      DEFs of REGNO.  */
   for (df_ref def = DF_REG_DEF_CHAIN (regno);
@@ -8735,10 +8742,76 @@ ix86_access_stack_p (unsigned int regno, basic_block bb,
            /* Return true if INSN requires stack.  */
            if (requires_stack_frame_p (insn, prologue_used,
                                        set_up_by_prologue))
-             return true;
+             {
+               bitmap_set_bit (reg_dominate_bbs[regno], bb->index);
+               return true;
+             }
          }
       }
 
+  /* When we get here, REGNO used in the current BB doesn't access
+     stack.  */
+  return false;
+}
+
+/* Helper function for ix86_symbolic_const_load_p.  */
+
+static bool
+ix86_symbolic_const_load_p_1 (rtx set)
+{
+  rtx dest = SET_DEST (set);
+
+  if (!REG_P (dest))
+    return false;
+
+  /* Reject non-Pmode modes.  */
+  if (GET_MODE (dest) != Pmode)
+    return false;
+
+  const_rtx src = SET_SRC (set);
+
+  subrtx_iterator::array_type array;
+  FOR_EACH_SUBRTX (iter, array, src, ALL)
+    {
+      auto op = *iter;
+
+      if (MEM_P (op))
+       iter.skip_subrtxes ();
+      else if (SYMBOLIC_CONST (op))
+       return true;
+    }
+
+  return false;
+}
+
+/* Return true if INSN loads a symbolic constant into register REGNO.  */
+
+static bool
+ix86_symbolic_const_load_p (rtx_insn *insn, unsigned int regno)
+{
+  rtx set = single_set (insn);
+  if (set)
+    return ix86_symbolic_const_load_p_1 (set);
+
+  rtx pat = PATTERN (insn);
+  if (GET_CODE (pat) != PARALLEL)
+    return false;
+
+  for (int i = 0; i < XVECLEN (pat, 0); i++)
+    {
+      rtx exp = XVECEXP (pat, 0, i);
+
+      if (GET_CODE (exp) == SET)
+       {
+         rtx dest = SET_DEST (exp);
+         if (REG_P (dest)
+             && GET_MODE (dest) == Pmode
+             && REGNO (dest) == regno
+             && ix86_symbolic_const_load_p_1 (exp))
+           return true;
+       }
+    }
+
   return false;
 }
 
@@ -8818,32 +8891,59 @@ ix86_find_max_used_stack_alignment (unsigned int 
&stack_alignment,
   hard_reg_set_iterator hrsi;
   stack_access_data data;
 
+  auto_bitmap reg_dominate_bbs_known[FIRST_PSEUDO_REGISTER];
+  auto_bitmap reg_dominate_bbs[FIRST_PSEUDO_REGISTER];
+
   data.stack_alignment = &stack_alignment;
 
   EXECUTE_IF_SET_IN_HARD_REG_SET (stack_slot_access, 0, regno, hrsi)
-    for (df_ref ref = DF_REG_USE_CHAIN (regno);
-        ref != NULL;
-        ref = DF_REF_NEXT_REG (ref))
-      {
-       if (DF_REF_IS_ARTIFICIAL (ref))
-         continue;
+    {
+      /* Set to true if there is a symbolic constant load into REGNO.  */
+      bool symbolic_const_load_p = false;
 
-       rtx_insn *insn = DF_REF_INSN (ref);
+      if (!TEST_HARD_REG_BIT (hard_stack_slot_access, regno))
+       for (df_ref def = DF_REG_DEF_CHAIN (regno);
+            def;
+            def = DF_REF_NEXT_REG (def))
+         if (!DF_REF_IS_ARTIFICIAL (def)
+             && !DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER)
+             && !DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER))
+           {
+             rtx_insn *insn = DF_REF_INSN (def);
+             if (ix86_symbolic_const_load_p (insn, regno))
+               {
+                 symbolic_const_load_p = true;
+                 break;
+               }
+           }
 
-       if (!NONJUMP_INSN_P (insn))
-         continue;
+      for (df_ref ref = DF_REG_USE_CHAIN (regno);
+          ref != NULL;
+          ref = DF_REF_NEXT_REG (ref))
+       {
+         if (DF_REF_IS_ARTIFICIAL (ref))
+           continue;
 
-       if (TEST_HARD_REG_BIT (hard_stack_slot_access, regno)
-           || ix86_access_stack_p (regno, BLOCK_FOR_INSN (insn),
-                                   set_up_by_prologue, prologue_used))
-         {
-           /* Update stack alignment if REGNO is used for stack
-              access.  */
-           data.reg = DF_REF_REG (ref);
-           note_stores (insn, ix86_update_stack_alignment, &data);
+         rtx_insn *insn = DF_REF_INSN (ref);
+
+         if (!NONJUMP_INSN_P (insn))
            continue;
-         }
-      }
+
+         /* If there is no symbolic constant load into the register,
+            don't call ix86_access_stack_p.  */
+         if (!symbolic_const_load_p
+             || ix86_access_stack_p (regno, BLOCK_FOR_INSN (insn),
+                                     set_up_by_prologue, prologue_used,
+                                     reg_dominate_bbs_known,
+                                     reg_dominate_bbs))
+           {
+             /* Update stack alignment if REGNO is used for stack
+                access.  */
+             data.reg = DF_REF_REG (ref);
+             note_stores (insn, ix86_update_stack_alignment, &data);
+           }
+       }
+    }
 
   free_dominance_info (CDI_DOMINATORS);
 }

Reply via email to