Hi,

I want to reuse some of the infrastructure in web.c (and df.h) for a
target-specific RTL pass, particularly the union-find stuff.  I could
just copy it, I suppose, but it seems better to make the struct
web_entry into a class so that I can inherit what I need.  That's what
this patch does.

When I talked about this with some other folks, they mentioned that
there has been talk of eliminating the web pass altogether, so that
might be an argument in favor of just copying the logic.  I am happy to
do that if that's deemed preferable.

I've taken the original struct and made it a base class that only
retains the pred field from the original class, along with the
union-find code.  The reg field is something I don't need, so I've moved
that into a subclass that the web code now uses.  I've removed the
extra_info field, which is not used and no longer makes sense with
inheritance available.  The rest of the changes are just adjusting to
these modifications.

I didn't overly "C++ify" anything, to keep the changes as non-invasive
as possible.

I'll post the PowerPC patch that makes use of the subclassing shortly.

Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
regressions.  Is this ok for trunk?

Thanks,
Bill


2014-08-13  Bill Schmidt  <wschm...@linux.vnet.ibm.com>

        * df.h (web_entry_base): Replace existing struct web_entry with a
        new class web_entry_base with only the predecessor member.
        (unionfind_root): Remove declaration and move to class member.
        (unionfind_union): Remove declaration and move to friend
        function.
        (union_defs): Remove declaration.
        * web.c (web_entry_base::unionfind_root): Modify to be member
        function and adjust accessors.
        (unionfind_union): Modify to be friend function and adjust
        accessors.
        (web_entry): New subclass of web_entry_base containing the reg
        member.
        (union_match_dups): Modify for struct -> class changes.
        (union_defs): Likewise.
        (entry_register): Likewise.
        (pass_web::execute): Likewise.


Index: gcc/df.h
===================================================================
--- gcc/df.h    (revision 213923)
+++ gcc/df.h    (working copy)
@@ -1184,20 +1184,22 @@ df_single_use (const df_insn_info *info)
 
 /* web */
 
-/* This entry is allocated for each reference in the insn stream.  */
-struct web_entry
+class web_entry_base
 {
-  /* Pointer to the parent in the union/find tree.  */
-  struct web_entry *pred;
-  /* Newly assigned register to the entry.  Set only for roots.  */
-  rtx reg;
-  void* extra_info;
+ private:
+  /* Reference to the parent in the union/find tree.  */
+  web_entry_base *pred_pvt;
+
+ public:
+  /* Accessors.  */
+  web_entry_base *pred () { return pred_pvt; }
+  void set_pred (web_entry_base *p) { pred_pvt = p; }
+
+  /* Find representative in union-find tree.  */
+  web_entry_base *unionfind_root ();
+
+  /* Union with another set, returning TRUE if they are already unioned.  */
+  friend bool unionfind_union (web_entry_base *first, web_entry_base *second);
 };
 
-extern struct web_entry *unionfind_root (struct web_entry *);
-extern bool unionfind_union (struct web_entry *, struct web_entry *);
-extern void union_defs (df_ref, struct web_entry *,
-                       unsigned int *used, struct web_entry *,
-                       bool (*fun) (struct web_entry *, struct web_entry *));
-
 #endif /* GCC_DF_H */
Index: gcc/web.c
===================================================================
--- gcc/web.c   (revision 213923)
+++ gcc/web.c   (working copy)
@@ -53,17 +53,17 @@ along with GCC; see the file COPYING3.  If not see
 
 /* Find the root of unionfind tree (the representative of set).  */
 
-struct web_entry *
-unionfind_root (struct web_entry *element)
+web_entry_base *
+web_entry_base::unionfind_root ()
 {
-  struct web_entry *element1 = element, *element2;
+  web_entry_base *element = this, *element1 = this, *element2;
 
-  while (element->pred)
-    element = element->pred;
-  while (element1->pred)
+  while (element->pred ())
+    element = element->pred ();
+  while (element1->pred ())
     {
-      element2 = element1->pred;
-      element1->pred = element;
+      element2 = element1->pred ();
+      element1->set_pred (element);
       element1 = element2;
     }
   return element;
@@ -74,23 +74,32 @@ along with GCC; see the file COPYING3.  If not see
    nothing is done.  Otherwise, return false.  */
 
 bool
-unionfind_union (struct web_entry *first, struct web_entry *second)
+unionfind_union (web_entry_base *first, web_entry_base *second)
 {
-  first = unionfind_root (first);
-  second = unionfind_root (second);
+  first = first->unionfind_root ();
+  second = second->unionfind_root ();
   if (first == second)
     return true;
-  second->pred = first;
+  second->set_pred (first);
   return false;
 }
 
+class web_entry : public web_entry_base
+{
+ private:
+  rtx reg_pvt;
+
+ public:
+  rtx reg () { return reg_pvt; }
+  void set_reg (rtx r) { reg_pvt = r; }
+};
+
 /* For INSN, union all defs and uses that are linked by match_dup.
    FUN is the function that does the union.  */
 
 static void
-union_match_dups (rtx insn, struct web_entry *def_entry,
-                 struct web_entry *use_entry,
-                 bool (*fun) (struct web_entry *, struct web_entry *))
+union_match_dups (rtx insn, web_entry *def_entry, web_entry *use_entry,
+                 bool (*fun) (web_entry_base *, web_entry_base *))
 {
   struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
   df_ref use_link = DF_INSN_INFO_USES (insn_info);
@@ -169,9 +178,9 @@ static void
    the values 0 and 1 are reserved for use by entry_register.  */
 
 void
-union_defs (df_ref use, struct web_entry *def_entry,
-           unsigned int *used, struct web_entry *use_entry,
-           bool (*fun) (struct web_entry *, struct web_entry *))
+union_defs (df_ref use, web_entry *def_entry,
+           unsigned int *used, web_entry *use_entry,
+           bool (*fun) (web_entry_base *, web_entry_base *))
 {
   struct df_insn_info *insn_info = DF_REF_INSN_INFO (use);
   struct df_link *link = DF_REF_CHAIN (use);
@@ -246,15 +255,15 @@ void
 /* Find the corresponding register for the given entry.  */
 
 static rtx
-entry_register (struct web_entry *entry, df_ref ref, unsigned int *used)
+entry_register (web_entry *entry, df_ref ref, unsigned int *used)
 {
-  struct web_entry *root;
+  web_entry *root;
   rtx reg, newreg;
 
   /* Find the corresponding web and see if it has been visited.  */
-  root = unionfind_root (entry);
-  if (root->reg)
-    return root->reg;
+  root = (web_entry *)entry->unionfind_root ();
+  if (root->reg ())
+    return root->reg ();
 
   /* We are seeing this web for the first time, do the assignment.  */
   reg = DF_REF_REAL_REG (ref);
@@ -278,7 +287,7 @@ static rtx
                 REGNO (newreg));
     }
 
-  root->reg = newreg;
+  root->set_reg (newreg);
   return newreg;
 }
 
@@ -332,8 +341,8 @@ class pass_web : public rtl_opt_pass
 unsigned int
 pass_web::execute (function *fun)
 {
-  struct web_entry *def_entry;
-  struct web_entry *use_entry;
+  web_entry *def_entry;
+  web_entry *use_entry;
   unsigned int max = max_reg_num ();
   unsigned int *used;
   basic_block bb;
@@ -364,9 +373,9 @@ pass_web::execute (function *fun)
     }
 
   /* Record the number of uses and defs at the beginning of the optimization.  
*/
-  def_entry = XCNEWVEC (struct web_entry, DF_DEFS_TABLE_SIZE ());
+  def_entry = XCNEWVEC (web_entry, DF_DEFS_TABLE_SIZE ());
   used = XCNEWVEC (unsigned, max);
-  use_entry = XCNEWVEC (struct web_entry, uses_num);
+  use_entry = XCNEWVEC (web_entry, uses_num);
 
   /* Produce the web.  */
   FOR_ALL_BB_FN (bb, fun)


Reply via email to