Message ID | 1407970886.3063.192.camel@gnopaine |
---|---|
State | New |
Headers | show |
Ping -- the patch that depends on this one has been approved, but I am still waiting for approval on these target-independent bits. Thanks, Bill On Wed, 2014-08-13 at 18:01 -0500, Bill Schmidt wrote: > 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 <wschmidt@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) > >
On Wed, Aug 20, 2014 at 4:30 PM, Bill Schmidt <wschmidt@linux.vnet.ibm.com> wrote: > Ping -- the patch that depends on this one has been approved, but I am > still waiting for approval on these target-independent bits. Ok. Thanks, Richard. > Thanks, > Bill > > On Wed, 2014-08-13 at 18:01 -0500, Bill Schmidt wrote: >> 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 <wschmidt@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) >> >> > >
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)