https://gcc.gnu.org/g:414ce41976ae9ffe0349be181ae333e1616ece1c

commit 414ce41976ae9ffe0349be181ae333e1616ece1c
Author: Ondřej Machota <ondrejmach...@gmail.com>
Date:   Tue Jun 24 09:54:54 2025 +0200

    rtl-ssa-web: init pass, rtl-ssa accesses support uid

Diff:
---
 gcc/passes.def            |   1 +
 gcc/rtl-ssa/accesses.h    |  17 ++++++-
 gcc/rtl-ssa/internals.inl |   4 ++
 gcc/rtlanal.cc            |   4 +-
 gcc/rtlanal.h             |  16 ++++--
 gcc/tree-pass.h           |   1 +
 gcc/web.cc                | 122 ++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 159 insertions(+), 6 deletions(-)

diff --git a/gcc/passes.def b/gcc/passes.def
index 3b251052e53a..777f1dc7e075 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -482,6 +482,7 @@ along with GCC; see the file COPYING3.  If not see
          NEXT_PASS (pass_rtl_loop_done);
       POP_INSERT_PASSES ()
       NEXT_PASS (pass_lower_subreg2);
+      NEXT_PASS (pass_web_ssa);
       NEXT_PASS (pass_web);
       NEXT_PASS (pass_rtl_cprop);
       NEXT_PASS (pass_cse2);
diff --git a/gcc/rtl-ssa/accesses.h b/gcc/rtl-ssa/accesses.h
index 98403f78b37b..318fde10ee05 100644
--- a/gcc/rtl-ssa/accesses.h
+++ b/gcc/rtl-ssa/accesses.h
@@ -19,6 +19,8 @@
 
 namespace rtl_ssa {
 
+#include "coretypes.h"
+
 // Forward declarations.
 class bb_info;
 class clobber_group;
@@ -131,6 +133,8 @@ public:
   // otherwise return MEM_REGNO.
   unsigned int regno () const { return m_regno; }
 
+  const_rtx reg () const { return m_reg; }
+
   // For sets, return the mode of the value to which the resource is being set.
   // For uses, return the mode in which the resource is being used (which for
   // hard registers might be different from the mode in which the resource
@@ -208,6 +212,11 @@ public:
   // an insn that is about to be inserted.
   bool is_temporary () const { return m_is_temp; }
 
+    // User definable uid for use_info
+  unsigned int& uid () { return m_uid; }
+
+  unsigned int uid () const { return m_uid; }
+
 protected:
   access_info (resource_info, access_kind);
 
@@ -246,6 +255,12 @@ protected:
   // a phi node.
   unsigned int m_is_in_debug_insn_or_phi : 1;
 
+  // Not null if is_reg is true. In that case it points to the reg.
+  const_rtx m_reg;
+
+  // The value of uid ().
+  unsigned int m_uid;
+
 private:
   // Used as a flag during various update routines; has no long-lasting
   // meaning.
@@ -285,7 +300,7 @@ public:
 // resource's value.
 class use_info : public access_info
 {
-  // Overall size: 5 LP64 words.
+  // Overall size: 6 LP64 words.
   friend class set_info;
   friend class function_info;
 
diff --git a/gcc/rtl-ssa/internals.inl b/gcc/rtl-ssa/internals.inl
index 0de18bbefe67..b4b3e2da6b4a 100644
--- a/gcc/rtl-ssa/internals.inl
+++ b/gcc/rtl-ssa/internals.inl
@@ -95,6 +95,8 @@ use_info::record_reference (rtx_obj_reference ref, bool 
is_first)
       m_includes_multiregs |= ref.is_multireg ();
       m_only_occurs_in_notes &= ref.in_note ();
     }
+
+  m_reg = ref.reg ();
 }
 
 // Change the value of insn () to INSN.
@@ -208,6 +210,8 @@ def_info::record_reference (rtx_obj_reference ref, bool 
is_first)
       m_includes_subregs |= ref.in_subreg ();
       m_includes_multiregs |= ref.is_multireg ();
     }
+
+  m_reg = ref.reg ();
 }
 
 // Return the last definition in the list.  Only valid when is_first ()
diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc
index 86a5e4733088..3963fd14ce5e 100644
--- a/gcc/rtlanal.cc
+++ b/gcc/rtlanal.cc
@@ -2102,7 +2102,7 @@ rtx_properties::try_to_add_reg (const_rtx x, unsigned int 
flags)
   for (unsigned int regno = start_regno; regno < end_regno; ++regno)
     if (ref_iter != ref_end)
       *ref_iter++ = rtx_obj_reference (regno, flags, mode,
-                                      regno - start_regno);
+                                      regno - start_regno, x);
 }
 
 /* Add a description of destination X to this object.  FLAGS is a bitmask
@@ -2169,7 +2169,7 @@ rtx_properties::try_to_add_dest (const_rtx x, unsigned 
int flags)
             anti-dependent on later deallocations, so both types of
             stack operation are akin to a memory write.  */
          if (ref_iter != ref_end)
-           *ref_iter++ = rtx_obj_reference (MEM_REGNO, flags, BLKmode);
+           *ref_iter++ = rtx_obj_reference (MEM_REGNO, flags, BLKmode, 0, x);
 
          /* We want to keep sp alive everywhere - by making all
             writes to sp also use sp.  */
diff --git a/gcc/rtlanal.h b/gcc/rtlanal.h
index 33f171624c92..3c4c1747891c 100644
--- a/gcc/rtlanal.h
+++ b/gcc/rtlanal.h
@@ -23,6 +23,9 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_RTLANAL_H
 #define GCC_RTLANAL_H
 
+#include "coretypes.h"
+#include "rtl.h"
+
 /* A dummy register value that represents the whole of variable memory.
    Using ~0U means that arrays that track both registers and memory can
    be indexed by regno + 1.  */
@@ -53,11 +56,14 @@ class rtx_obj_reference
 public:
   rtx_obj_reference () = default;
   rtx_obj_reference (unsigned int regno, uint16_t flags,
-                    machine_mode mode, unsigned int multireg_offset = 0);
+                    machine_mode mode, unsigned int multireg_offset = 0,
+         const_rtx reg = nullptr);
 
   bool is_reg () const { return regno != MEM_REGNO; }
   bool is_mem () const { return regno == MEM_REGNO; }
 
+  const_rtx reg () const { return m_reg; }
+
   /* True if the reference is a read or a write respectively.
      Both flags are set in a read-modify-write context, such as
      for read_modify_subreg_p.  */
@@ -95,6 +101,9 @@ public:
   /* The referenced register, or MEM_REGNO for variable memory.  */
   unsigned int regno;
 
+  /* The referenced the register, subregister or memory */
+  const_rtx m_reg;
+
   /* A bitmask of rtx_obj_flags.  */
   unsigned int flags : 16;
 
@@ -109,9 +118,10 @@ public:
 /* Construct a reference with the given fields.  */
 
 inline rtx_obj_reference::rtx_obj_reference (unsigned int regno, uint16_t 
flags,
-                                            machine_mode mode,
-                                            unsigned int multireg_offset)
+                                            machine_mode mode, unsigned int 
multireg_offset,
+               const_rtx reg)
   : regno (regno),
+    m_reg (reg),
     flags (flags),
     mode (mode),
     multireg_offset (multireg_offset)
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 7cb5a128899a..36a8d4aaa8e1 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -592,6 +592,7 @@ extern rtl_opt_pass *make_pass_rtl_doloop (gcc::context 
*ctxt);
 extern rtl_opt_pass *make_pass_rtl_loop_done (gcc::context *ctxt);
 
 extern rtl_opt_pass *make_pass_lower_subreg2 (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_web_ssa (gcc::context *ctxt);
 extern rtl_opt_pass *make_pass_web (gcc::context *ctxt);
 extern rtl_opt_pass *make_pass_cse2 (gcc::context *ctxt);
 extern rtl_opt_pass *make_pass_df_initialize_opt (gcc::context *ctxt);
diff --git a/gcc/web.cc b/gcc/web.cc
index 9ab4ed62c744..dc9689ab96d9 100644
--- a/gcc/web.cc
+++ b/gcc/web.cc
@@ -29,17 +29,23 @@ along with GCC; see the file COPYING3.  If not see
       we expand only if the induction variable is dead afterward, which
       is often the case).  */
 
+#define INCLUDE_ALGORITHM
+#define INCLUDE_FUNCTIONAL
+#define INCLUDE_ARRAY
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
 #include "backend.h"
 #include "rtl.h"
 #include "df.h"
+#include "rtl-ssa.h"
+#include "cfgcleanup.h"
 #include "insn-config.h"
 #include "recog.h"
 
 #include "tree-pass.h"
 
+using namespace rtl_ssa;
 
 /* Find the root of unionfind tree (the representative of set).  */
 
@@ -427,3 +433,119 @@ make_pass_web (gcc::context *ctxt)
 {
   return new pass_web (ctxt);
 }
+
+namespace {
+
+#include <functional>
+
+static void
+union_match_dups (insn_info *insn, web_entry *def_entry, web_entry *use_entry,
+      std::function<bool(web_entry_base *, web_entry_base *)> unite)
+{
+  rtx_insn *rtl = insn->rtl ();
+  if (insn->is_phi())
+  {
+    // TODO: we should add phi input to the same web
+    return;
+  }
+
+  if (!rtl)
+    return;
+
+  extract_insn (rtl);
+
+  struct web_entry *dup_entry;
+  for (int i = 0; i < recog_data.n_dups; ++i)
+   {
+    int op = recog_data.dup_num[i];
+    enum op_type type = recog_data.operand_type[op];
+
+    dup_entry = use_entry;
+    // TODO: how to obtain loc from rtl ssa?
+    for (use_info *use : insn->uses ())
+        if (use->reg() == *recog_data.dup_loc[i])
+          break;
+
+    
+   }
+}
+
+const pass_data pass_data_web_ssa =
+{
+  RTL_PASS, /* type */
+  "web-ssa", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  TV_WEB, /* tv_id */
+  0, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  TODO_df_finish, /* todo_flags_finish */
+};
+
+class pass_web_ssa : public rtl_opt_pass
+{
+public:
+  pass_web_ssa (gcc::context *ctxt)
+    : rtl_opt_pass (pass_data_web_ssa, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  bool gate (function *) final override { return (optimize > 0 && flag_web); }
+  unsigned int execute (function *) final override;
+
+}; // class pass_web
+
+unsigned int
+pass_web_ssa::execute (function *fun)
+{
+  crtl->ssa = new rtl_ssa::function_info (fun);
+  unsigned int defs_num = 0;
+  unsigned int uses_num = 0;
+
+  for (insn_info* insn : crtl->ssa->nondebug_insns ())
+  {
+    for (def_info *def : insn->defs ())
+      if (def->is_reg () && def->regno () >= FIRST_PSEUDO_REGISTER)
+        def->uid() = defs_num++;
+
+    for (use_info *use : insn->uses ())
+      if (use->is_reg () && use->regno () >= FIRST_PSEUDO_REGISTER)
+        use->uid() = uses_num++;
+
+    // reg notes (aka eq_uses) - already handled - see 
access_info::only_occurs_in_notes ()
+  }
+
+  web_entry *def_entry = XCNEWVEC(web_entry, defs_num);
+  web_entry *use_entry = XCNEWVEC(web_entry, uses_num);
+
+  const unsigned int max_reg = max_reg_num();
+  unsigned int *used_regs = XCNEWVEC (unsigned, max_reg);
+
+  for (insn_info* insn : crtl->ssa->nondebug_insns ()) 
+  {
+    union_match_dups (insn, def_entry, use_entry, unionfind_union);
+    for (use_info *use : insn->uses ())
+      if (use->regno() >= FIRST_PSEUDO_REGISTER)
+        {}
+  }
+
+  free (def_entry);
+  free (use_entry);
+  free (used_regs);
+
+  free_dominance_info (CDI_DOMINATORS);
+  if (crtl->ssa->perform_pending_updates ())
+    cleanup_cfg (0);
+  
+  delete crtl->ssa;
+  crtl->ssa = nullptr;  
+}
+
+}
+
+rtl_opt_pass *
+make_pass_web_ssa (gcc::context *ctxt)
+{
+  return new pass_web_ssa (ctxt);
+}
\ No newline at end of file

Reply via email to