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)