* RFC: gimple.[ch] break apart @ 2013-10-31 5:45 Andrew MacLeod 2013-10-31 6:15 ` Jeff Law ` (2 more replies) 0 siblings, 3 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-10-31 5:45 UTC (permalink / raw) To: gcc-patches Hopefully the other attempts to send this aren't queued up... in any case, maybe I can't even attach a .dot file?... So no attachments this time... instead, the diagram is here: http://gcc.gnu.org/wiki/rearch?action=AttachFile&do=view&target=gimple.png ------------------------------------------------------------- I've made 4 attempts now to split gimple.[ch] into reasonable component parts, and I've finally found something that I can make work and fits my plans. I've attached a diagram to (hopefully :-) clarify things. The original purpose of gimple.[ch] was to provide gimple statements. This replaces the tcc_statement tree kind during the gimplification process. No other tree kinds have been converted to gimple structs/classes. That what the next stage of my project will do. As a result, any gimple queries regarding types, decls, or expressions are actually tree queries. They are sprinkled throughout gimple.[ch] and gimplify.[ch], not to mention tree.[ch] as well as other parts of the compiler where they happened to be needed. This has caused various ordering issues among the inline functions when I tried to split out the stmt, iterator, and gimplification bits from gimple.[ch]. Not to mention a lack of an obvious home for some of these functions. I'd like to move these as I encounter them into a new file, gimple-decl.[ch]. When I'm working on the other gimple classes, this will be further split into gimple-decl, gimple-type and gimple-expr as appropriate but it seems reasonable to create just the one file now to clump them since there is no other formal organization. So any function which is actually querying/setting/building a decl, type, or expression for gimple would go here. I also want to split out the structure and accessing bits of the gimple statement structure into gimple-stmt.[ch]. This would be just the struct decls as well as all the accessing/setting/building functions... The gimple_stmt_iterators (gsi) themselves also break out into their own file quite naturally. I find that gimple_seq does not seem to be a very clearly defined thing. Although a gimple_seq is just a typedef for a gimple stmt (I thought it use to be a container?), it provides some additional statement queuing functionality. Ie, you don't have to worry about next and prev pointers in the stmt's you build, you simply queue them up and attach them where you want. In that sense, its a kind of overlay on top of a gimple-stmt as it provides additional functionality. gimple_seq also utilizes gimple_smt_iterators under the covers. They do not expose the iterators to a function using a gimple_seq but they do need that knowledge to mange the lists under the covers (thus a dashed line in the diagram). Its unclear to me whether gimple_seq's are intended to have a future, or whether their functionality should be rolled right into statements themselves. I believe it may be possible to include gimple-iterator.h in gimple-stmt.c to provide the implementation without affecting the inheritance layout, although I haven't actually tried that path. Or we can treat them as a different layer with their own gimple-seq.[ch] files. Or we could combine gimple_seq and gsi routines in the same file, but that would have the downside of exposing the gsi routines to the gimplifier, which should have no need of. Either of the latter 2 options seem reasonable to me for now. The remnants of gimple.[ch] would contain various general helper routines (walkers, etc), much like tree-ssa.[ch] does for ssa. And finally gimplify.[ch] would contain all the stuff required for the front ends to generate gimple code. This is actually a front end interface. At the moment it isn't obvious since all the current gimple code also uses trees and calls the gimplifier frequently. As I push gimple types and decls into the back end and remove trees, the backend should simply generate gimple directly. Gimplify should slowly become usable only via tree based front ends... (Thus the dotted line from BE to gimplify.. it should be removed eventually) Which means that all the front end files should be including *only* gimplify.h, and getting everything they need from there. Currently a number of them include gimple.h which should not be required. How reasonable or unreasonable does this sound? :-) I've been tearing the file apart in different ways and orders, and this seems to be the most workable solution I have come up with that doesn't involve hacks. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: RFC: gimple.[ch] break apart 2013-10-31 5:45 RFC: gimple.[ch] break apart Andrew MacLeod @ 2013-10-31 6:15 ` Jeff Law 2013-10-31 16:41 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) David Malcolm 2013-11-05 16:58 ` [patch] Create gimple-expr..[ch] ... was Re: RFC: gimple.[ch] break apart Andrew MacLeod 2 siblings, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-10-31 6:15 UTC (permalink / raw) To: Andrew MacLeod, gcc-patches On 10/30/13 21:18, Andrew MacLeod wrote: > Hopefully the other attempts to send this aren't queued up... in any > case, maybe I can't even attach a .dot file?... So no attachments this > time... > > instead, the diagram is here: > http://gcc.gnu.org/wiki/rearch?action=AttachFile&do=view&target=gimple.png One was queued and went through with attachments :-) jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-10-31 5:45 RFC: gimple.[ch] break apart Andrew MacLeod 2013-10-31 6:15 ` Jeff Law @ 2013-10-31 16:41 ` David Malcolm 2013-10-31 16:27 ` [PATCH 2/6] Hand-written port of various accessors within gimple.h David Malcolm ` (9 more replies) 2013-11-05 16:58 ` [patch] Create gimple-expr..[ch] ... was Re: RFC: gimple.[ch] break apart Andrew MacLeod 2 siblings, 10 replies; 116+ messages in thread From: David Malcolm @ 2013-10-31 16:41 UTC (permalink / raw) To: gcc-patches, Andrew MacLeod; +Cc: David Malcolm [Shamelessly hijacking Andrew's thread about gimple.h refactoring, since this seems on-topic for that, and I'm keen to hear from Andrew on how the following would interact with his work - I *think* our two cleanups are orthogonal. [This is a revised version of the patches sent as: http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01788.html and http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01954.html which got bogged down in discussion of hand-written GTY hooks. This patch series updates things to make use of the new support in gengtype for simple inheritance schemes] The gimple statement types are currently implemented using a hand-coded C inheritance scheme, with a "union gimple_statement_d" holding the various possible structs for a statement. The following series of patches convert it to a C++ hierarchy, using the existing structs, eliminating the union. The "gimple" typedef changes from being a (union gimple_statement_d *) to being a: (struct gimple_statement_base *) There are no virtual functions in the new code: the sizes of the various structs are unchanged. It makes use of "is-a.h", using the as_a <T> template function to perform downcasts, which are checked (via gcc_checking_assert) in an ENABLE_CHECKING build, and are simple casts in an unchecked build, albeit it in an inlined function rather than a macro. For example, one can write: gimple_statement_phi *phi = as_a <gimple_statement_phi> (gsi_stmt (gsi)); and then directly access the fields of the phi, as a phi. The existing accessor functions in gimple.h become somewhat redundant in this scheme, but are preserved. The earlier versions of the patches made all of the types GTY((user)) and provided hand-written implementations of the gc and pch marker routines. In this new version we rely on the support for simple inheritance that I recently added to gengtype, by adding a "desc" to the GTY marking for the base class, and a "tag" to the marking for all of the concrete subclasses. (I say "class", but all the types remain structs since their fields are all publicly accessible). As noted in the earlier patch, I believe this is a superior scheme to the C implementation: * We can get closer to compile-time type-safety, checking the gimple code once and downcasting with an as_a, then directly accessing fields, rather than going through accessor functions that check each time. In some places we may want to replace a "gimple" with a subclass e.g. phis are always of the phi subclass, to get full compile-time type-safety. * This scheme is likely to be easier for newbies to understand. * Currently in gdb, dereferencing a gimple leads to screenfuls of text, showing all the various union values. With this, you get just the base class, and can cast it to the appropriate subclass. * With this, we're working directly with the language constructs, rather than rolling our own, and thus other tools can better understand the code. (e.g. doxygen). Again, as noted in the earlier patch series, the names of the structs are rather verbose. I would prefer to also rename them all to eliminate the "_statement" component: "gimple_statement_base" -> "gimple_base" "gimple_statement_phi" -> "gimple_phi" "gimple_statement_omp" -> "gimple_omp" etc, but I didn't do this to mimimize the patch size. But if the core maintainers are up for that, I can redo the patch series with that change also, or do that as a followup. The patch is in 6 parts; all of them are needed together. * Patch 1 of 6: This patch adds inheritance to the various gimple types, eliminating the initial baseclass fields, and eliminating the union gimple_statement_d. All the types remain structs. They become marked with GTY(()), gaining GSS_ tag values. * Patch 2 of 6: This patch ports various accessor functions within gimple.h to the new scheme. * Patch 3 of 6: This patch is autogenerated by "refactor_gimple.py" from https://github.com/davidmalcolm/gcc-refactoring-scripts There is a test suite "test_refactor_gimple.py" which may give a clearer idea of the changes that the script makes (and add confidence that it's doing the right thing). The patch converts code of the form: { GIMPLE_CHECK (gs, SOME_CODE); gimple_subclass_get/set_some_field (gs, value); } to code of this form: { some_subclass *stmt = as_a <some_subclass> (gs); stmt->some_field = value; } It also autogenerates specializations of is_a_helper <T>::test equivalent to a GIMPLE_CHECK() for use by is_a and as_a. * Patch 4 of 6: This patch implement further specializations of is_a_helper <T>::test, for gimple_has_ops and gimple_has_mem_ops. * Patch 5 of 6: This patch does the rest of porting from union access to subclass access (all the fiddly places that the script in patch 3 couldn't handle). * Patch 6 of 6: This patch updates the gdb python pretty-printing hook. Successfully bootstrapped and tested on x86_64-unknown-linux-gnu: all testcases show the same results as an unpatched build (relative to r204230). OK for trunk? David Malcolm (6): Convert gimple types from a union to C++ inheritance Hand-written port of various accessors within gimple.h Automated part of conversion of gimple types to use C++ inheritance Implement is_a_helper <>::test specializations for various gimple types Port various places from union access to subclass access. Update gdb hooks to reflect changes to gimple types gcc/Makefile.in | 2 +- gcc/coretypes.h | 5 +- gcc/gdbhooks.py | 2 +- gcc/ggc.h | 6 +- gcc/gimple-iterator.c | 72 +- gcc/gimple-pretty-print.c | 6 +- gcc/gimple-pretty-print.h | 4 +- gcc/gimple-ssa.h | 16 +- gcc/gimple-streamer-in.c | 19 +- gcc/gimple-streamer-out.c | 2 +- gcc/gimple.c | 76 ++- gcc/gimple.h | 1651 +++++++++++++++++++++++++++++---------------- gcc/gimplify.c | 4 +- gcc/system.h | 2 +- gcc/tree-inline.c | 2 +- gcc/tree-phinodes.c | 39 +- gcc/tree-ssa-ccp.c | 2 +- 17 files changed, 1197 insertions(+), 713 deletions(-) -- 1.7.11.7 ^ permalink raw reply [flat|nested] 116+ messages in thread
* [PATCH 2/6] Hand-written port of various accessors within gimple.h 2013-10-31 16:41 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) David Malcolm @ 2013-10-31 16:27 ` David Malcolm 2013-11-14 9:53 ` Jeff Law 2013-10-31 16:27 ` [PATCH 4/6] Implement is_a_helper <>::test specializations for various gimple types David Malcolm ` (8 subsequent siblings) 9 siblings, 1 reply; 116+ messages in thread From: David Malcolm @ 2013-10-31 16:27 UTC (permalink / raw) To: gcc-patches, Andrew MacLeod; +Cc: David Malcolm * gimple.h (gimple_use_ops): Port from union to usage of dyn_cast. (gimple_set_use_ops): Port from union to usage of as_a. (gimple_set_vuse): Likewise. (gimple_set_vdef): Likewise. (gimple_call_internal_fn): Port from union to a static_cast, given that the type has already been asserted. (gimple_omp_body_ptr): Port from unchecked union usage to a static_cast. (gimple_omp_set_body): Likewise. --- gcc/gimple.h | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/gcc/gimple.h b/gcc/gimple.h index f288e81..6ff7602 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1467,9 +1467,11 @@ gimple_has_mem_ops (const_gimple g) static inline struct use_optype_d * gimple_use_ops (const_gimple g) { - if (!gimple_has_ops (g)) + const gimple_statement_with_ops *ops_stmt = + dyn_cast <const gimple_statement_with_ops> (g); + if (!ops_stmt) return NULL; - return g->gsops.opbase.use_ops; + return ops_stmt->use_ops; } @@ -1478,8 +1480,9 @@ gimple_use_ops (const_gimple g) static inline void gimple_set_use_ops (gimple g, struct use_optype_d *use) { - gcc_gimple_checking_assert (gimple_has_ops (g)); - g->gsops.opbase.use_ops = use; + gimple_statement_with_ops *ops_stmt = + as_a <gimple_statement_with_ops> (g); + ops_stmt->use_ops = use; } @@ -1528,8 +1531,9 @@ gimple_vdef_ptr (gimple g) static inline void gimple_set_vuse (gimple g, tree vuse) { - gcc_gimple_checking_assert (gimple_has_mem_ops (g)); - g->gsmembase.vuse = vuse; + gimple_statement_with_memory_ops *mem_ops_stmt = + as_a <gimple_statement_with_memory_ops> (g); + mem_ops_stmt->vuse = vuse; } /* Set the single VDEF operand of the statement G. */ @@ -1537,8 +1541,9 @@ gimple_set_vuse (gimple g, tree vuse) static inline void gimple_set_vdef (gimple g, tree vdef) { - gcc_gimple_checking_assert (gimple_has_mem_ops (g)); - g->gsmembase.vdef = vdef; + gimple_statement_with_memory_ops *mem_ops_stmt = + as_a <gimple_statement_with_memory_ops> (g); + mem_ops_stmt->vdef = vdef; } @@ -2226,7 +2231,7 @@ static inline enum internal_fn gimple_call_internal_fn (const_gimple gs) { gcc_gimple_checking_assert (gimple_call_internal_p (gs)); - return gs->gimple_call.u.internal_fn; + return static_cast <const gimple_statement_call *> (gs)->u.internal_fn; } @@ -4031,7 +4036,7 @@ get_lineno (const_gimple stmt) static inline gimple_seq * gimple_omp_body_ptr (gimple gs) { - return &gs->omp.body; + return &static_cast <gimple_statement_omp *> (gs)->body; } /* Return the body for the OMP statement GS. */ @@ -4047,7 +4052,7 @@ gimple_omp_body (gimple gs) static inline void gimple_omp_set_body (gimple gs, gimple_seq body) { - gs->omp.body = body; + static_cast <gimple_statement_omp *> (gs)->body = body; } -- 1.7.11.7 ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 2/6] Hand-written port of various accessors within gimple.h 2013-10-31 16:27 ` [PATCH 2/6] Hand-written port of various accessors within gimple.h David Malcolm @ 2013-11-14 9:53 ` Jeff Law 0 siblings, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-14 9:53 UTC (permalink / raw) To: David Malcolm, gcc-patches, Andrew MacLeod On 10/31/13 10:26, David Malcolm wrote: > * gimple.h (gimple_use_ops): Port from union to usage of > dyn_cast. > (gimple_set_use_ops): Port from union to usage of as_a. > (gimple_set_vuse): Likewise. > (gimple_set_vdef): Likewise. > (gimple_call_internal_fn): Port from union to a static_cast, > given that the type has already been asserted. > (gimple_omp_body_ptr): Port from unchecked union usage to > a static_cast. > (gimple_omp_set_body): Likewise. OK with usual conditions. It's getting late and I just fired off my overnight regression tests. So I'll have to look at 1/6 tomorrow. jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* [PATCH 4/6] Implement is_a_helper <>::test specializations for various gimple types 2013-10-31 16:41 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) David Malcolm 2013-10-31 16:27 ` [PATCH 2/6] Hand-written port of various accessors within gimple.h David Malcolm @ 2013-10-31 16:27 ` David Malcolm 2013-11-14 9:41 ` Jeff Law 2013-10-31 16:27 ` [PATCH 1/6] Convert gimple types from a union to C++ inheritance David Malcolm ` (7 subsequent siblings) 9 siblings, 1 reply; 116+ messages in thread From: David Malcolm @ 2013-10-31 16:27 UTC (permalink / raw) To: gcc-patches, Andrew MacLeod; +Cc: David Malcolm * gimple.h (is_a_helper <const gimple_statement_with_ops>::test): New. (is_a_helper <gimple_statement_with_ops>::test): New. (is_a_helper <const gimple_statement_with_memory_ops>::test): New. (is_a_helper <gimple_statement_with_memory_ops>::test): New. --- gcc/gimple.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/gcc/gimple.h b/gcc/gimple.h index f258992..710ce04 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1756,6 +1756,21 @@ gimple_has_ops (const_gimple g) return gimple_code (g) >= GIMPLE_COND && gimple_code (g) <= GIMPLE_RETURN; } +template <> +template <> +inline bool +is_a_helper <const gimple_statement_with_ops>::test (const_gimple gs) +{ + return gimple_has_ops (gs); +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_with_ops>::test (gimple gs) +{ + return gimple_has_ops (gs); +} /* Return true if GIMPLE statement G has memory operands. */ @@ -1765,6 +1780,21 @@ gimple_has_mem_ops (const_gimple g) return gimple_code (g) >= GIMPLE_ASSIGN && gimple_code (g) <= GIMPLE_RETURN; } +template <> +template <> +inline bool +is_a_helper <const gimple_statement_with_memory_ops>::test (const_gimple gs) +{ + return gimple_has_mem_ops (gs); +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_with_memory_ops>::test (gimple gs) +{ + return gimple_has_mem_ops (gs); +} /* Return the set of USE operands for statement G. */ -- 1.7.11.7 ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 4/6] Implement is_a_helper <>::test specializations for various gimple types 2013-10-31 16:27 ` [PATCH 4/6] Implement is_a_helper <>::test specializations for various gimple types David Malcolm @ 2013-11-14 9:41 ` Jeff Law 2013-11-18 19:51 ` David Malcolm 0 siblings, 1 reply; 116+ messages in thread From: Jeff Law @ 2013-11-14 9:41 UTC (permalink / raw) To: David Malcolm, gcc-patches, Andrew MacLeod On 10/31/13 10:26, David Malcolm wrote: > * gimple.h (is_a_helper <const gimple_statement_with_ops>::test): New. > (is_a_helper <gimple_statement_with_ops>::test): New. > (is_a_helper <const gimple_statement_with_memory_ops>::test): New. > (is_a_helper <gimple_statement_with_memory_ops>::test): New. OK with the usual conditions. Check with Andrew as to the location of these helpers since he's in the middle of ripping apart gimple.h. jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 4/6] Implement is_a_helper <>::test specializations for various gimple types 2013-11-14 9:41 ` Jeff Law @ 2013-11-18 19:51 ` David Malcolm 2013-11-18 20:10 ` Andrew MacLeod 2013-11-18 20:15 ` Jeff Law 0 siblings, 2 replies; 116+ messages in thread From: David Malcolm @ 2013-11-18 19:51 UTC (permalink / raw) To: Jeff Law; +Cc: gcc-patches, Andrew MacLeod On Thu, 2013-11-14 at 00:37 -0700, Jeff Law wrote: > On 10/31/13 10:26, David Malcolm wrote: > > * gimple.h (is_a_helper <const gimple_statement_with_ops>::test): New. > > (is_a_helper <gimple_statement_with_ops>::test): New. > > (is_a_helper <const gimple_statement_with_memory_ops>::test): New. > > (is_a_helper <gimple_statement_with_memory_ops>::test): New. > OK with the usual conditions. Check with Andrew as to the location of > these helpers since he's in the middle of ripping apart gimple.h. The helpers become used in accessors such as gimple_use_ops, gimple_vuse, gimple_vdef etc as of the automated patch (patch 3 in the series [1]), so presumably the helpers need to be in the same file as those accessors. The accessors are currently in gimple.h, and hence I also put the helpers within gimple.h (earlier within the header). Andrew, do you plan to move the accessor functions out of gimple.h? If so, where should the is_a_helper fns land? Dave [1] hence these patches need to be committed at the same time, whether than means a single "revision" or not; I split them up conceptually for ease of review. ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 4/6] Implement is_a_helper <>::test specializations for various gimple types 2013-11-18 19:51 ` David Malcolm @ 2013-11-18 20:10 ` Andrew MacLeod 2013-11-18 20:15 ` Jeff Law 1 sibling, 0 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-11-18 20:10 UTC (permalink / raw) To: David Malcolm; +Cc: Jeff Law, gcc-patches On 11/18/2013 01:54 PM, David Malcolm wrote: > On Thu, 2013-11-14 at 00:37 -0700, Jeff Law wrote: >> On 10/31/13 10:26, David Malcolm wrote: >>> * gimple.h (is_a_helper <const gimple_statement_with_ops>::test): New. >>> (is_a_helper <gimple_statement_with_ops>::test): New. >>> (is_a_helper <const gimple_statement_with_memory_ops>::test): New. >>> (is_a_helper <gimple_statement_with_memory_ops>::test): New. >> OK with the usual conditions. Check with Andrew as to the location of >> these helpers since he's in the middle of ripping apart gimple.h. > The helpers become used in accessors such as gimple_use_ops, > gimple_vuse, gimple_vdef etc as of the automated patch (patch 3 in the > series [1]), so presumably the helpers need to be in the same file as > those accessors. The accessors are currently in gimple.h, and hence I > also put the helpers within gimple.h (earlier within the header). > > Andrew, do you plan to move the accessor functions out of gimple.h? If > so, where should the is_a_helper fns land? > Not currently. They are a component of the gimple statement, and gimple.[ch] is now just the statement and related accessors. Since your changes are just for gimple-stmt, in theory everything should go there. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 4/6] Implement is_a_helper <>::test specializations for various gimple types 2013-11-18 19:51 ` David Malcolm 2013-11-18 20:10 ` Andrew MacLeod @ 2013-11-18 20:15 ` Jeff Law 1 sibling, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-18 20:15 UTC (permalink / raw) To: David Malcolm; +Cc: gcc-patches, Andrew MacLeod On 11/18/13 11:54, David Malcolm wrote: > On Thu, 2013-11-14 at 00:37 -0700, Jeff Law wrote: >> On 10/31/13 10:26, David Malcolm wrote: >>> * gimple.h (is_a_helper <const gimple_statement_with_ops>::test): New. >>> (is_a_helper <gimple_statement_with_ops>::test): New. >>> (is_a_helper <const gimple_statement_with_memory_ops>::test): New. >>> (is_a_helper <gimple_statement_with_memory_ops>::test): New. >> OK with the usual conditions. Check with Andrew as to the location of >> these helpers since he's in the middle of ripping apart gimple.h. > > The helpers become used in accessors such as gimple_use_ops, > gimple_vuse, gimple_vdef etc as of the automated patch (patch 3 in the > series [1]), so presumably the helpers need to be in the same file as > those accessors. The accessors are currently in gimple.h, and hence I > also put the helpers within gimple.h (earlier within the header). > > Andrew, do you plan to move the accessor functions out of gimple.h? If > so, where should the is_a_helper fns land? > > Dave > > [1] hence these patches need to be committed at the same time, whether > than means a single "revision" or not; I split them up conceptually for > ease of review. I'd say single commit since they are dependent upon each other. jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* [PATCH 1/6] Convert gimple types from a union to C++ inheritance 2013-10-31 16:41 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) David Malcolm 2013-10-31 16:27 ` [PATCH 2/6] Hand-written port of various accessors within gimple.h David Malcolm 2013-10-31 16:27 ` [PATCH 4/6] Implement is_a_helper <>::test specializations for various gimple types David Malcolm @ 2013-10-31 16:27 ` David Malcolm 2013-11-14 23:00 ` Jeff Law 2013-10-31 16:31 ` [PATCH 3/6] Automated part of conversion of gimple types to use " David Malcolm ` (6 subsequent siblings) 9 siblings, 1 reply; 116+ messages in thread From: David Malcolm @ 2013-10-31 16:27 UTC (permalink / raw) To: gcc-patches, Andrew MacLeod; +Cc: David Malcolm * Makefile.in (GIMPLE_H): Add dep on is-a.h. * coretypes.h (union gimple_statement_d): Remove declaration. (gimple): Convert from being a "union gimple_statement_d *" to a "struct gimple_statement_base *". (const_gimple): Likewise (with "const"). * ggc.h (ggc_alloc_cleared_gimple_statement_d_stat): Replace with... (ggc_alloc_cleared_gimple_statement_stat): ...this. * gimple-pretty-print.c (debug): Change parameter from a "gimple_statement_d &" to a "gimple_statement_base &". (debug): Change parameter from a "gimple_statement_d *" to a "gimple_statement_base *". * gimple-pretty-print.h (debug): Update declarations as above. * gimple.c (gimple_alloc_stat): Update for renaming of ggc_alloc_cleared_gimple_statement_d_stat to ggc_alloc_cleared_gimple_statement_stat. * gimple.h: Include "is-a.h" for use by is_a_helper specializations in followup autogenerated patch. (struct gimple statement_base): Make this type usable as a base class by adding "desc", "tag" and "variable_size" to GTY, thus using opting-in to gengtype's support for simple inheritance. (gimple_statement_with_ops_base): Convert to a subclass of gimple_statement_base, dropping initial "gsbase" field. Note that this type is abstract, with no GSS_ value, and thus no GTY tag value. (gimple_statement_with_ops): Convert to a subclass of gimple_statement_with_ops_base, dropping initial "opbase" field. Add tag value to GTY marking. Update marking of op field to reflect how num_ops field is accessed via inheritance. (gimple_statement_with_memory_ops_base): Convert to a subclass of gimple_statement_with_ops_base, dropping initial "opbase" field. Add tag value to GTY marking. (gimple_statement_with_memory_ops): Convert to a subclass of public gimple_statement_with_memory_ops_base, dropping initial "membase" field. Add tag value to GTY marking. Update marking of op field to reflect how num_ops field is accessed via inheritance. (gimple_statement_call): Analogous changes that also update the marking of the "u" union. (gimple_statement_omp): Convert to a subclass of gimple_statement_base, dropping initial "gsbase" field, adding tag value to GTY marking. (gimple_statement_bind): Likewise. (gimple_statement_catch): Likewise. (gimple_statement_eh_filter): Likewise. (gimple_statement_eh_else): Likewise. (gimple_statement_eh_mnt): Likewise. (gimple_statement_phi): Likewise. (gimple_statement_eh_ctrl): Likewise. (gimple_statement_try): Likewise. (gimple_statement_wce): Likewise. (gimple_statement_asm): Convert to a subclass of gimple_statement_with_memory_ops_base, dropping initial "membase" field, adding tag value to GTY marking, and updating marking of op field. (gimple_statement_omp_critical): Convert to a subclass of gimple_statement_omp, dropping initial "omp" field, adding tag value to GTY marking. (gimple_statement_omp_for): Likewise. (gimple_statement_omp_parallel): Likewise. (gimple_statement_omp_task): Convert to a subclass of gimple_statement_omp_parallel, dropping initial "par" field, adding tag value to GTY marking. (gimple_statement_omp_sections): Convert to a subclass of gimple_statement_omp, dropping initial "omp" field, adding tag value to GTY marking. (gimple_statement_omp_continue): Convert to a subclass of gimple_statement_base, dropping initial "gsbase" field, adding tag value to GTY marking. (gimple_statement_omp_single): Convert to a subclass of gimple_statement_omp, dropping initial "omp" field, adding tag value to GTY marking. (gimple_statement_omp_atomic_load): Convert to a subclass of gimple_statement_base, dropping initial "gsbase" field, adding tag value to GTY marking. (gimple_statement_omp_atomic_store): Convert to a subclass of gimple_statement_base, dropping initial "gsbase" field, adding tag value to GTY marking. (gimple_statement_transaction): Convert to a subclass of gimple_statement_with_memory_ops_base, dropping initial "gsbase" field, adding tag value to GTY marking. (union gimple_statement_d): Remove. * system.h (CONST_CAST_GIMPLE): Update to use "struct gimple_statement_base *" rather than "union gimple_statement_d *". * tree-ssa-ccp.c (gimple_htab): Convert underlying type from gimple_statement_d to gimple_statement_base. --- gcc/Makefile.in | 2 +- gcc/coretypes.h | 5 +- gcc/ggc.h | 6 +- gcc/gimple-pretty-print.c | 4 +- gcc/gimple-pretty-print.h | 4 +- gcc/gimple.c | 2 +- gcc/gimple.h | 226 ++++++++++++++++++++++------------------------ gcc/system.h | 2 +- gcc/tree-ssa-ccp.c | 2 +- 9 files changed, 121 insertions(+), 132 deletions(-) diff --git a/gcc/Makefile.in b/gcc/Makefile.in index cc88fb8..7fbb533 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -887,7 +887,7 @@ BASIC_BLOCK_H = basic-block.h $(PREDICT_H) $(VEC_H) $(FUNCTION_H) \ cfg-flags.def cfghooks.h GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h $(VEC_H) \ $(GGC_H) $(BASIC_BLOCK_H) $(TREE_H) tree-ssa-operands.h \ - tree-ssa-alias.h $(INTERNAL_FN_H) $(HASH_TABLE_H) + tree-ssa-alias.h $(INTERNAL_FN_H) $(HASH_TABLE_H) is-a.h GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h RECOG_H = recog.h EMIT_RTL_H = emit-rtl.h diff --git a/gcc/coretypes.h b/gcc/coretypes.h index f7ef8d7..5d60240 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -61,9 +61,8 @@ typedef const struct rtvec_def *const_rtvec; union tree_node; typedef union tree_node *tree; typedef const union tree_node *const_tree; -union gimple_statement_d; -typedef union gimple_statement_d *gimple; -typedef const union gimple_statement_d *const_gimple; +typedef struct gimple_statement_base *gimple; +typedef const struct gimple_statement_base *const_gimple; typedef gimple gimple_seq; struct gimple_stmt_iterator_d; typedef struct gimple_stmt_iterator_d gimple_stmt_iterator; diff --git a/gcc/ggc.h b/gcc/ggc.h index b31bc80..bb8f939 100644 --- a/gcc/ggc.h +++ b/gcc/ggc.h @@ -269,10 +269,10 @@ ggc_alloc_cleared_tree_node_stat (size_t s MEM_STAT_DECL) return (union tree_node *) ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT); } -static inline union gimple_statement_d * -ggc_alloc_cleared_gimple_statement_d_stat (size_t s MEM_STAT_DECL) +static inline struct gimple_statement_base * +ggc_alloc_cleared_gimple_statement_stat (size_t s MEM_STAT_DECL) { - return (union gimple_statement_d *) + return (struct gimple_statement_base *) ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT); } diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 248dfea..881ff04 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -86,13 +86,13 @@ print_gimple_stmt (FILE *file, gimple g, int spc, int flags) } DEBUG_FUNCTION void -debug (gimple_statement_d &ref) +debug (gimple_statement_base &ref) { print_gimple_stmt (stderr, &ref, 0, 0); } DEBUG_FUNCTION void -debug (gimple_statement_d *ptr) +debug (gimple_statement_base *ptr) { if (ptr) debug (*ptr); diff --git a/gcc/gimple-pretty-print.h b/gcc/gimple-pretty-print.h index 5227eb8..edb23e6 100644 --- a/gcc/gimple-pretty-print.h +++ b/gcc/gimple-pretty-print.h @@ -29,8 +29,8 @@ extern void debug_gimple_stmt (gimple); extern void debug_gimple_seq (gimple_seq); extern void print_gimple_seq (FILE *, gimple_seq, int, int); extern void print_gimple_stmt (FILE *, gimple, int, int); -extern void debug (gimple_statement_d &ref); -extern void debug (gimple_statement_d *ptr); +extern void debug (gimple_statement_base &ref); +extern void debug (gimple_statement_base *ptr); extern void print_gimple_expr (FILE *, gimple, int, int); extern void pp_gimple_stmt_1 (pretty_printer *, gimple, int, int); extern void gimple_dump_bb (FILE *, basic_block, int, int); diff --git a/gcc/gimple.c b/gcc/gimple.c index 20f6010..958514c 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -126,7 +126,7 @@ gimple_alloc_stat (enum gimple_code code, unsigned num_ops MEM_STAT_DECL) gimple_alloc_sizes[(int) kind] += size; } - stmt = ggc_alloc_cleared_gimple_statement_d_stat (size PASS_MEM_STAT); + stmt = ggc_alloc_cleared_gimple_statement_stat (size PASS_MEM_STAT); gimple_set_code (stmt, code); gimple_set_num_ops (stmt, num_ops); diff --git a/gcc/gimple.h b/gcc/gimple.h index b34424c..f288e81 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "internal-fn.h" #include "gimple-fold.h" #include "tree-eh.h" +#include "is-a.h" typedef gimple gimple_seq_node; @@ -158,7 +159,10 @@ struct gimple_stmt_iterator_d /* Data structure definitions for GIMPLE tuples. NOTE: word markers are for 64 bit hosts. */ -struct GTY((chain_next ("%h.next"))) gimple_statement_base { +struct GTY((desc ("gimple_statement_structure (&%h)"), tag ("GSS_BASE"), + chain_next ("%h.next"), variable_size)) + gimple_statement_base +{ /* [ WORD 1 ] Main identifying code for a tuple. */ ENUM_BITFIELD(gimple_code) code : 8; @@ -222,10 +226,11 @@ struct GTY((chain_next ("%h.next"))) gimple_statement_base { /* Base structure for tuples with operands. */ -struct GTY(()) gimple_statement_with_ops_base +/* This gimple subclass has no tag value. */ +struct GTY(()) + gimple_statement_with_ops_base : public gimple_statement_base { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; + /* [ WORD 1-6 ] : base class */ /* [ WORD 7 ] SSA operand vectors. NOTE: It should be possible to @@ -238,25 +243,25 @@ struct GTY(()) gimple_statement_with_ops_base /* Statements that take register operands. */ -struct GTY(()) gimple_statement_with_ops +struct GTY((tag("GSS_WITH_OPS"))) + gimple_statement_with_ops : public gimple_statement_with_ops_base { - /* [ WORD 1-7 ] */ - struct gimple_statement_with_ops_base opbase; + /* [ WORD 1-7 ] : base class */ /* [ WORD 8 ] Operand vector. NOTE! This must always be the last field of this structure. In particular, this means that this structure cannot be embedded inside another one. */ - tree GTY((length ("%h.opbase.gsbase.num_ops"))) op[1]; + tree GTY((length ("%h.num_ops"))) op[1]; }; /* Base for statements that take both memory and register operands. */ -struct GTY(()) gimple_statement_with_memory_ops_base +struct GTY((tag("GSS_WITH_MEM_OPS_BASE"))) + gimple_statement_with_memory_ops_base : public gimple_statement_with_ops_base { - /* [ WORD 1-7 ] */ - struct gimple_statement_with_ops_base opbase; + /* [ WORD 1-7 ] : base class */ /* [ WORD 8-9 ] Virtual operands for this statement. The GC will pick them @@ -268,32 +273,33 @@ struct GTY(()) gimple_statement_with_memory_ops_base /* Statements that take both memory and register operands. */ -struct GTY(()) gimple_statement_with_memory_ops +struct GTY((tag("GSS_WITH_MEM_OPS"))) + gimple_statement_with_memory_ops : + public gimple_statement_with_memory_ops_base { - /* [ WORD 1-9 ] */ - struct gimple_statement_with_memory_ops_base membase; + /* [ WORD 1-9 ] : base class */ /* [ WORD 10 ] Operand vector. NOTE! This must always be the last field of this structure. In particular, this means that this structure cannot be embedded inside another one. */ - tree GTY((length ("%h.membase.opbase.gsbase.num_ops"))) op[1]; + tree GTY((length ("%h.num_ops"))) op[1]; }; /* Call statements that take both memory and register operands. */ -struct GTY(()) gimple_statement_call +struct GTY((tag("GSS_CALL"))) + gimple_statement_call : public gimple_statement_with_memory_ops_base { - /* [ WORD 1-9 ] */ - struct gimple_statement_with_memory_ops_base membase; + /* [ WORD 1-9 ] : base class */ /* [ WORD 10-13 ] */ struct pt_solution call_used; struct pt_solution call_clobbered; /* [ WORD 14 ] */ - union GTY ((desc ("%1.membase.opbase.gsbase.subcode & GF_CALL_INTERNAL"))) { + union GTY ((desc ("%1.subcode & GF_CALL_INTERNAL"))) { tree GTY ((tag ("0"))) fntype; enum internal_fn GTY ((tag ("GF_CALL_INTERNAL"))) internal_fn; } u; @@ -302,15 +308,16 @@ struct GTY(()) gimple_statement_call Operand vector. NOTE! This must always be the last field of this structure. In particular, this means that this structure cannot be embedded inside another one. */ - tree GTY((length ("%h.membase.opbase.gsbase.num_ops"))) op[1]; + tree GTY((length ("%h.num_ops"))) op[1]; }; /* OpenMP statements (#pragma omp). */ -struct GTY(()) gimple_statement_omp { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; +struct GTY((tag("GSS_OMP"))) + gimple_statement_omp : public gimple_statement_base +{ + /* [ WORD 1-6 ] : base class */ /* [ WORD 7 ] */ gimple_seq body; @@ -319,9 +326,10 @@ struct GTY(()) gimple_statement_omp { /* GIMPLE_BIND */ -struct GTY(()) gimple_statement_bind { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; +struct GTY((tag("GSS_BIND"))) + gimple_statement_bind : public gimple_statement_base +{ + /* [ WORD 1-6 ] : base class */ /* [ WORD 7 ] Variables declared in this scope. */ @@ -342,9 +350,10 @@ struct GTY(()) gimple_statement_bind { /* GIMPLE_CATCH */ -struct GTY(()) gimple_statement_catch { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; +struct GTY((tag("GSS_CATCH"))) + gimple_statement_catch : public gimple_statement_base +{ + /* [ WORD 1-6 ] : base class */ /* [ WORD 7 ] */ tree types; @@ -356,9 +365,10 @@ struct GTY(()) gimple_statement_catch { /* GIMPLE_EH_FILTER */ -struct GTY(()) gimple_statement_eh_filter { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; +struct GTY((tag("GSS_EH_FILTER"))) + gimple_statement_eh_filter : public gimple_statement_base +{ + /* [ WORD 1-6 ] : base class */ /* [ WORD 7 ] Filter types. */ @@ -371,9 +381,10 @@ struct GTY(()) gimple_statement_eh_filter { /* GIMPLE_EH_ELSE */ -struct GTY(()) gimple_statement_eh_else { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; +struct GTY((tag("GSS_EH_ELSE"))) + gimple_statement_eh_else : public gimple_statement_base +{ + /* [ WORD 1-6 ] : base class */ /* [ WORD 7,8 ] */ gimple_seq n_body, e_body; @@ -381,9 +392,10 @@ struct GTY(()) gimple_statement_eh_else { /* GIMPLE_EH_MUST_NOT_THROW */ -struct GTY(()) gimple_statement_eh_mnt { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; +struct GTY((tag("GSS_EH_MNT"))) + gimple_statement_eh_mnt : public gimple_statement_base +{ + /* [ WORD 1-6 ] : base class */ /* [ WORD 7 ] Abort function decl. */ tree fndecl; @@ -391,9 +403,10 @@ struct GTY(()) gimple_statement_eh_mnt { /* GIMPLE_PHI */ -struct GTY(()) gimple_statement_phi { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; +struct GTY((tag("GSS_PHI"))) + gimple_statement_phi : public gimple_statement_base +{ + /* [ WORD 1-6 ] : base class */ /* [ WORD 7 ] */ unsigned capacity; @@ -409,10 +422,10 @@ struct GTY(()) gimple_statement_phi { /* GIMPLE_RESX, GIMPLE_EH_DISPATCH */ -struct GTY(()) gimple_statement_eh_ctrl +struct GTY((tag("GSS_EH_CTRL"))) + gimple_statement_eh_ctrl : public gimple_statement_base { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; + /* [ WORD 1-6 ] : base class */ /* [ WORD 7 ] Exception region number. */ @@ -422,9 +435,10 @@ struct GTY(()) gimple_statement_eh_ctrl /* GIMPLE_TRY */ -struct GTY(()) gimple_statement_try { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; +struct GTY((tag("GSS_TRY"))) + gimple_statement_try : public gimple_statement_base +{ + /* [ WORD 1-6 ] : base class */ /* [ WORD 7 ] Expression to evaluate. */ @@ -451,9 +465,10 @@ enum gimple_try_flags /* GIMPLE_WITH_CLEANUP_EXPR */ -struct GTY(()) gimple_statement_wce { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; +struct GTY((tag("GSS_WCE"))) + gimple_statement_wce : public gimple_statement_base +{ + /* [ WORD 1-6 ] : base class */ /* Subcode: CLEANUP_EH_ONLY. True if the cleanup should only be executed if an exception is thrown, not on normal exit of its @@ -468,10 +483,10 @@ struct GTY(()) gimple_statement_wce { /* GIMPLE_ASM */ -struct GTY(()) gimple_statement_asm +struct GTY((tag("GSS_ASM"))) + gimple_statement_asm : public gimple_statement_with_memory_ops_base { - /* [ WORD 1-9 ] */ - struct gimple_statement_with_memory_ops_base membase; + /* [ WORD 1-9 ] : base class */ /* [ WORD 10 ] __asm__ statement. */ @@ -488,14 +503,15 @@ struct GTY(()) gimple_statement_asm Operand vector. NOTE! This must always be the last field of this structure. In particular, this means that this structure cannot be embedded inside another one. */ - tree GTY((length ("%h.membase.opbase.gsbase.num_ops"))) op[1]; + tree GTY((length ("%h.num_ops"))) op[1]; }; /* GIMPLE_OMP_CRITICAL */ -struct GTY(()) gimple_statement_omp_critical { - /* [ WORD 1-7 ] */ - struct gimple_statement_omp omp; +struct GTY((tag("GSS_OMP_CRITICAL"))) + gimple_statement_omp_critical : public gimple_statement_omp +{ + /* [ WORD 1-7 ] : base class */ /* [ WORD 8 ] Critical section name. */ @@ -522,9 +538,10 @@ struct GTY(()) gimple_omp_for_iter { /* GIMPLE_OMP_FOR */ -struct GTY(()) gimple_statement_omp_for { - /* [ WORD 1-7 ] */ - struct gimple_statement_omp omp; +struct GTY((tag("GSS_OMP_FOR"))) + gimple_statement_omp_for : public gimple_statement_omp +{ + /* [ WORD 1-7 ] : base class */ /* [ WORD 8 ] */ tree clauses; @@ -544,9 +561,10 @@ struct GTY(()) gimple_statement_omp_for { /* GIMPLE_OMP_PARALLEL */ -struct GTY(()) gimple_statement_omp_parallel { - /* [ WORD 1-7 ] */ - struct gimple_statement_omp omp; +struct GTY((tag("GSS_OMP_PARALLEL"))) + gimple_statement_omp_parallel : public gimple_statement_omp +{ + /* [ WORD 1-7 ] : base class */ /* [ WORD 8 ] Clauses. */ @@ -564,9 +582,10 @@ struct GTY(()) gimple_statement_omp_parallel { /* GIMPLE_OMP_TASK */ -struct GTY(()) gimple_statement_omp_task { - /* [ WORD 1-10 ] */ - struct gimple_statement_omp_parallel par; +struct GTY((tag("GSS_OMP_TASK"))) + gimple_statement_omp_task : public gimple_statement_omp_parallel +{ + /* [ WORD 1-10 ] : base class */ /* [ WORD 11 ] Child function holding firstprivate initialization if needed. */ @@ -585,9 +604,10 @@ struct GTY(()) gimple_statement_omp_task { /* GIMPLE_OMP_SECTIONS */ -struct GTY(()) gimple_statement_omp_sections { - /* [ WORD 1-7 ] */ - struct gimple_statement_omp omp; +struct GTY((tag("GSS_OMP_SECTIONS"))) + gimple_statement_omp_sections : public gimple_statement_omp +{ + /* [ WORD 1-7 ] : base class */ /* [ WORD 8 ] */ tree clauses; @@ -603,9 +623,10 @@ struct GTY(()) gimple_statement_omp_sections { Note: This does not inherit from gimple_statement_omp, because we do not need the body field. */ -struct GTY(()) gimple_statement_omp_continue { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; +struct GTY((tag("GSS_OMP_CONTINUE"))) + gimple_statement_omp_continue : public gimple_statement_base +{ + /* [ WORD 1-6 ] : base class */ /* [ WORD 7 ] */ tree control_def; @@ -616,9 +637,10 @@ struct GTY(()) gimple_statement_omp_continue { /* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS */ -struct GTY(()) gimple_statement_omp_single { - /* [ WORD 1-7 ] */ - struct gimple_statement_omp omp; +struct GTY((tag("GSS_OMP_SINGLE"))) + gimple_statement_omp_single : public gimple_statement_omp +{ + /* [ WORD 1-7 ] : base class */ /* [ WORD 7 ] */ tree clauses; @@ -629,9 +651,10 @@ struct GTY(()) gimple_statement_omp_single { Note: This is based on gimple_statement_base, not g_s_omp, because g_s_omp contains a sequence, which we don't need here. */ -struct GTY(()) gimple_statement_omp_atomic_load { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; +struct GTY((tag("GSS_OMP_ATOMIC_LOAD"))) + gimple_statement_omp_atomic_load : public gimple_statement_base +{ + /* [ WORD 1-6 ] : base class */ /* [ WORD 7-8 ] */ tree rhs, lhs; @@ -640,9 +663,10 @@ struct GTY(()) gimple_statement_omp_atomic_load { /* GIMPLE_OMP_ATOMIC_STORE. See note on GIMPLE_OMP_ATOMIC_LOAD. */ -struct GTY(()) gimple_statement_omp_atomic_store { - /* [ WORD 1-6 ] */ - struct gimple_statement_base gsbase; +struct GTY((tag("GSS_OMP_ATOMIC_STORE"))) + gimple_statement_omp_atomic_store : public gimple_statement_base +{ + /* [ WORD 1-6 ] : base class */ /* [ WORD 7 ] */ tree val; @@ -676,10 +700,10 @@ struct GTY(()) gimple_statement_omp_atomic_store { likely because it is guaranteed to go irrevocable upon entry. */ #define GTMA_HAS_NO_INSTRUMENTATION (1u << 7) -struct GTY(()) gimple_statement_transaction +struct GTY((tag("GSS_TRANSACTION"))) + gimple_statement_transaction : public gimple_statement_with_memory_ops_base { - /* [ WORD 1-9 ] */ - struct gimple_statement_with_memory_ops_base gsbase; + /* [ WORD 1-9 ] : base class */ /* [ WORD 10 ] */ gimple_seq body; @@ -695,40 +719,6 @@ enum gimple_statement_structure_enum { }; #undef DEFGSSTRUCT - -/* Define the overall contents of a gimple tuple. It may be any of the - structures declared above for various types of tuples. */ - -union GTY ((desc ("gimple_statement_structure (&%h)"), - chain_next ("%h.gsbase.next"), variable_size)) gimple_statement_d { - struct gimple_statement_base GTY ((tag ("GSS_BASE"))) gsbase; - struct gimple_statement_with_ops GTY ((tag ("GSS_WITH_OPS"))) gsops; - struct gimple_statement_with_memory_ops_base GTY ((tag ("GSS_WITH_MEM_OPS_BASE"))) gsmembase; - struct gimple_statement_with_memory_ops GTY ((tag ("GSS_WITH_MEM_OPS"))) gsmem; - struct gimple_statement_call GTY ((tag ("GSS_CALL"))) gimple_call; - struct gimple_statement_omp GTY ((tag ("GSS_OMP"))) omp; - struct gimple_statement_bind GTY ((tag ("GSS_BIND"))) gimple_bind; - struct gimple_statement_catch GTY ((tag ("GSS_CATCH"))) gimple_catch; - struct gimple_statement_eh_filter GTY ((tag ("GSS_EH_FILTER"))) gimple_eh_filter; - struct gimple_statement_eh_mnt GTY ((tag ("GSS_EH_MNT"))) gimple_eh_mnt; - struct gimple_statement_eh_else GTY ((tag ("GSS_EH_ELSE"))) gimple_eh_else; - struct gimple_statement_phi GTY ((tag ("GSS_PHI"))) gimple_phi; - struct gimple_statement_eh_ctrl GTY ((tag ("GSS_EH_CTRL"))) gimple_eh_ctrl; - struct gimple_statement_try GTY ((tag ("GSS_TRY"))) gimple_try; - struct gimple_statement_wce GTY ((tag ("GSS_WCE"))) gimple_wce; - struct gimple_statement_asm GTY ((tag ("GSS_ASM"))) gimple_asm; - struct gimple_statement_omp_critical GTY ((tag ("GSS_OMP_CRITICAL"))) gimple_omp_critical; - struct gimple_statement_omp_for GTY ((tag ("GSS_OMP_FOR"))) gimple_omp_for; - struct gimple_statement_omp_parallel GTY ((tag ("GSS_OMP_PARALLEL"))) gimple_omp_parallel; - struct gimple_statement_omp_task GTY ((tag ("GSS_OMP_TASK"))) gimple_omp_task; - struct gimple_statement_omp_sections GTY ((tag ("GSS_OMP_SECTIONS"))) gimple_omp_sections; - struct gimple_statement_omp_single GTY ((tag ("GSS_OMP_SINGLE"))) gimple_omp_single; - struct gimple_statement_omp_continue GTY ((tag ("GSS_OMP_CONTINUE"))) gimple_omp_continue; - struct gimple_statement_omp_atomic_load GTY ((tag ("GSS_OMP_ATOMIC_LOAD"))) gimple_omp_atomic_load; - struct gimple_statement_omp_atomic_store GTY ((tag ("GSS_OMP_ATOMIC_STORE"))) gimple_omp_atomic_store; - struct gimple_statement_transaction GTY((tag ("GSS_TRANSACTION"))) gimple_transaction; -}; - /* Offset in bytes to the location of the operand vector. Zero if there is no operand vector for this tuple structure. */ extern size_t const gimple_ops_offset_[]; diff --git a/gcc/system.h b/gcc/system.h index a1fc6de..87ebe3c 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -1013,7 +1013,7 @@ helper_const_non_const_cast (const char *p) #define CONST_CAST_TREE(X) CONST_CAST (union tree_node *, (X)) #define CONST_CAST_RTX(X) CONST_CAST (struct rtx_def *, (X)) #define CONST_CAST_BB(X) CONST_CAST (struct basic_block_def *, (X)) -#define CONST_CAST_GIMPLE(X) CONST_CAST (union gimple_statement_d *, (X)) +#define CONST_CAST_GIMPLE(X) CONST_CAST (struct gimple_statement_base *, (X)) /* Activate certain diagnostics as warnings (not errors via the -Werror flag). */ diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index d30bd8b..c01af60 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1693,7 +1693,7 @@ evaluate_stmt (gimple stmt) return val; } -typedef hash_table <pointer_hash <gimple_statement_d> > gimple_htab; +typedef hash_table <pointer_hash <gimple_statement_base> > gimple_htab; /* Given a BUILT_IN_STACK_SAVE value SAVED_VAL, insert a clobber of VAR before each matching BUILT_IN_STACK_RESTORE. Mark visited phis in VISITED. */ -- 1.7.11.7 ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 1/6] Convert gimple types from a union to C++ inheritance 2013-10-31 16:27 ` [PATCH 1/6] Convert gimple types from a union to C++ inheritance David Malcolm @ 2013-11-14 23:00 ` Jeff Law 2013-11-19 0:22 ` David Malcolm 0 siblings, 1 reply; 116+ messages in thread From: Jeff Law @ 2013-11-14 23:00 UTC (permalink / raw) To: David Malcolm, gcc-patches, Andrew MacLeod On 10/31/13 10:26, David Malcolm wrote: > * Makefile.in (GIMPLE_H): Add dep on is-a.h. Not asking you, but I'd like to hope many of the *_H things in Makefile.in should be going away... > > diff --git a/gcc/Makefile.in b/gcc/Makefile.in > index cc88fb8..7fbb533 100644 > --- a/gcc/Makefile.in > +++ b/gcc/Makefile.in > @@ -887,7 +887,7 @@ BASIC_BLOCK_H = basic-block.h $(PREDICT_H) $(VEC_H) $(FUNCTION_H) \ > cfg-flags.def cfghooks.h > GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h $(VEC_H) \ > $(GGC_H) $(BASIC_BLOCK_H) $(TREE_H) tree-ssa-operands.h \ > - tree-ssa-alias.h $(INTERNAL_FN_H) $(HASH_TABLE_H) > + tree-ssa-alias.h $(INTERNAL_FN_H) $(HASH_TABLE_H) is-a.h > GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h > RECOG_H = recog.h > EMIT_RTL_H = emit-rtl.h Ugh. OK I guess. I hate all these _H thingies. Ideally they'll go away at some point. I think their biggest use now is for PLUGIN_HEADERS. But that's not an issue for this patch to go forward. > diff --git a/gcc/ggc.h b/gcc/ggc.h > index b31bc80..bb8f939 100644 > --- a/gcc/ggc.h > +++ b/gcc/ggc.h > @@ -269,10 +269,10 @@ ggc_alloc_cleared_tree_node_stat (size_t s MEM_STAT_DECL) > return (union tree_node *) ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT); > } > > -static inline union gimple_statement_d * > -ggc_alloc_cleared_gimple_statement_d_stat (size_t s MEM_STAT_DECL) > +static inline struct gimple_statement_base * > +ggc_alloc_cleared_gimple_statement_stat (size_t s MEM_STAT_DECL) > { > - return (union gimple_statement_d *) > + return (struct gimple_statement_base *) > ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT); > } Didn't I see something in the last 48hrs indicating that we don't need "static inline" anymore, just "inline"? If so, can you drop the static here since you're changing it already. With that, this, IMO is OK and a definite step forward. Given the contention over this, please give other maintainers 24hrs to object before installing the set. jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 1/6] Convert gimple types from a union to C++ inheritance 2013-11-14 23:00 ` Jeff Law @ 2013-11-19 0:22 ` David Malcolm 2013-11-19 8:49 ` Jeff Law 0 siblings, 1 reply; 116+ messages in thread From: David Malcolm @ 2013-11-19 0:22 UTC (permalink / raw) To: Jeff Law; +Cc: gcc-patches, Andrew MacLeod On Thu, 2013-11-14 at 14:51 -0700, Jeff Law wrote: > On 10/31/13 10:26, David Malcolm wrote: > > * Makefile.in (GIMPLE_H): Add dep on is-a.h. > Not asking you, but I'd like to hope many of the *_H things in > Makefile.in should be going away... > > > > > > > diff --git a/gcc/Makefile.in b/gcc/Makefile.in > > index cc88fb8..7fbb533 100644 > > --- a/gcc/Makefile.in > > +++ b/gcc/Makefile.in > > @@ -887,7 +887,7 @@ BASIC_BLOCK_H = basic-block.h $(PREDICT_H) $(VEC_H) $(FUNCTION_H) \ > > cfg-flags.def cfghooks.h > > GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h $(VEC_H) \ > > $(GGC_H) $(BASIC_BLOCK_H) $(TREE_H) tree-ssa-operands.h \ > > - tree-ssa-alias.h $(INTERNAL_FN_H) $(HASH_TABLE_H) > > + tree-ssa-alias.h $(INTERNAL_FN_H) $(HASH_TABLE_H) is-a.h > > GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h > > RECOG_H = recog.h > > EMIT_RTL_H = emit-rtl.h > Ugh. OK I guess. I hate all these _H thingies. Ideally they'll go > away at some point. I think their biggest use now is for > PLUGIN_HEADERS. But that's not an issue for this patch to go forward. > > > > > diff --git a/gcc/ggc.h b/gcc/ggc.h > > index b31bc80..bb8f939 100644 > > --- a/gcc/ggc.h > > +++ b/gcc/ggc.h > > @@ -269,10 +269,10 @@ ggc_alloc_cleared_tree_node_stat (size_t s MEM_STAT_DECL) > > return (union tree_node *) ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT); > > } > > > > -static inline union gimple_statement_d * > > -ggc_alloc_cleared_gimple_statement_d_stat (size_t s MEM_STAT_DECL) > > +static inline struct gimple_statement_base * > > +ggc_alloc_cleared_gimple_statement_stat (size_t s MEM_STAT_DECL) > > { > > - return (union gimple_statement_d *) > > + return (struct gimple_statement_base *) > > ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT); > > } > Didn't I see something in the last 48hrs indicating that we don't need > "static inline" anymore, just "inline"? If so, can you drop the static > here since you're changing it already. I looked, but I'm not sure which change you're referring to; sorry. Note that all 7 of the inline functions in ggc.h are "static inline", not just this one; it feels like a separate change to be touching the "static"ness of them IMHO. > With that, this, IMO is OK and a definite step forward. > > Given the contention over this, please give other maintainers 24hrs to > object before installing the set. Thanks. It's now been a few days. Patch 3 (the autogenerated one) has bitrotted somewhat due to the reorganization of gimple.h, so I'm rebootstrapping an updated version of it now; I've posted it for review as http://gcc.gnu.org/ml/gcc-patches/2013-11/msg02156.html ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 1/6] Convert gimple types from a union to C++ inheritance 2013-11-19 0:22 ` David Malcolm @ 2013-11-19 8:49 ` Jeff Law 0 siblings, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-19 8:49 UTC (permalink / raw) To: David Malcolm; +Cc: gcc-patches, Andrew MacLeod On 11/18/13 14:00, David Malcolm wrote: >>> @@ -269,10 +269,10 @@ ggc_alloc_cleared_tree_node_stat (size_t s MEM_STAT_DECL) >>> return (union tree_node *) ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT); >>> } >>> >>> -static inline union gimple_statement_d * >>> -ggc_alloc_cleared_gimple_statement_d_stat (size_t s MEM_STAT_DECL) >>> +static inline struct gimple_statement_base * >>> +ggc_alloc_cleared_gimple_statement_stat (size_t s MEM_STAT_DECL) >>> { >>> - return (union gimple_statement_d *) >>> + return (struct gimple_statement_base *) >>> ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT); >>> } >> Didn't I see something in the last 48hrs indicating that we don't need >> "static inline" anymore, just "inline"? If so, can you drop the static >> here since you're changing it already. > I looked, but I'm not sure which change you're referring to; sorry. > > Note that all 7 of the inline functions in ggc.h are "static inline", > not just this one; it feels like a separate change to be touching the > "static"ness of them IMHO. Don't stress about it. If I find the reference, I'll pass it along and/or just fix them myself :-) > > Thanks. It's now been a few days. Patch 3 (the autogenerated one) has > bitrotted somewhat due to the reorganization of gimple.h, so I'm > rebootstrapping an updated version of it now; I've posted it for review > as http://gcc.gnu.org/ml/gcc-patches/2013-11/msg02156.html I'll give it another look shortly. jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance 2013-10-31 16:41 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) David Malcolm ` (2 preceding siblings ...) 2013-10-31 16:27 ` [PATCH 1/6] Convert gimple types from a union to C++ inheritance David Malcolm @ 2013-10-31 16:31 ` David Malcolm 2013-11-14 9:43 ` Jeff Law 2013-10-31 16:46 ` [PATCH 6/6] Update gdb hooks to reflect changes to " David Malcolm ` (5 subsequent siblings) 9 siblings, 1 reply; 116+ messages in thread From: David Malcolm @ 2013-10-31 16:31 UTC (permalink / raw) To: gcc-patches, Andrew MacLeod; +Cc: David Malcolm gcc/ Patch autogenerated by refactor_gimple.py from https://github.com/davidmalcolm/gcc-refactoring-scripts revision 74cd3d5f06565c318749d0fb9f35b565dae28daa * gimple-iterator.c (update_bb_for_stmts): Update for conversion of gimple types to a true class hierarchy. (update_call_edge_frequencies): Likewise. (gsi_insert_seq_nodes_before): Likewise. (gsi_insert_seq_nodes_after): Likewise. (gsi_split_seq_after): Likewise. (gsi_set_stmt): Likewise. (gsi_split_seq_before): Likewise. (gsi_remove): Likewise. * gimple-pretty-print.c (dump_gimple_debug): Likewise. * gimple-ssa.h (gimple_vuse_op): Likewise. (gimple_vdef_op): Likewise. * gimple-streamer-in.c (input_gimple_stmt): Likewise. * gimple-streamer-out.c (output_gimple_stmt): Likewise. * gimple.c (gimple_set_code): Likewise. (gimple_alloc_stat): Likewise. (gimple_set_subcode): Likewise. (gimple_build_call_internal_1): Likewise. (gimple_check_failed): Likewise. (gimple_call_flags): Likewise. (gimple_set_bb): Likewise. * gimple.h (is_a_helper <gimple_statement_asm> (gimple)): New. (is_a_helper <gimple_statement_bind> (gimple)): Likewise. (is_a_helper <gimple_statement_call> (gimple)): Likewise. (is_a_helper <gimple_statement_catch> (gimple)): Likewise. (is_a_helper <gimple_statement_eh_ctrl> (gimple)): Likewise. (is_a_helper <gimple_statement_eh_else> (gimple)): Likewise. (is_a_helper <gimple_statement_eh_filter> (gimple)): Likewise. (is_a_helper <gimple_statement_eh_mnt> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_atomic_load> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_atomic_store> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_continue> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_critical> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_for> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_parallel> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_sections> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_single> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_task> (gimple)): Likewise. (is_a_helper <gimple_statement_phi> (gimple)): Likewise. (is_a_helper <gimple_statement_transaction> (gimple)): Likewise. (is_a_helper <gimple_statement_try> (gimple)): Likewise. (is_a_helper <gimple_statement_wce> (gimple)): Likewise. (is_a_helper <const gimple_statement_asm> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_bind> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_call> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_catch> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_eh_ctrl> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_eh_filter> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_atomic_load> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_atomic_store> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_continue> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_critical> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_for> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_parallel> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_sections> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_single> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_task> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_phi> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_transaction> (const_gimple)): Likewise. (gimple_seq_last): Update for conversion of gimple types to a true class hierarchy. (gimple_seq_set_last): Likewise. (gimple_code): Likewise. (gimple_bb): Likewise. (gimple_block): Likewise. (gimple_set_block): Likewise. (gimple_location): Likewise. (gimple_location_ptr): Likewise. (gimple_set_location): Likewise. (gimple_no_warning_p): Likewise. (gimple_set_no_warning): Likewise. (gimple_set_visited): Likewise. (gimple_visited_p): Likewise. (gimple_set_plf): Likewise. (gimple_plf): Likewise. (gimple_set_uid): Likewise. (gimple_uid): Likewise. (gimple_init_singleton): Likewise. (gimple_modified_p): Likewise. (gimple_set_modified): Likewise. (gimple_expr_code): Likewise. (gimple_has_volatile_ops): Likewise. (gimple_set_has_volatile_ops): Likewise. (gimple_omp_subcode): Likewise. (gimple_omp_set_subcode): Likewise. (gimple_omp_return_set_nowait): Likewise. (gimple_omp_section_set_last): Likewise. (gimple_omp_parallel_set_combined_p): Likewise. (gimple_omp_atomic_set_need_value): Likewise. (gimple_omp_atomic_set_seq_cst): Likewise. (gimple_num_ops): Likewise. (gimple_set_num_ops): Likewise. (gimple_assign_nontemporal_move_p): Likewise. (gimple_assign_set_nontemporal_move): Likewise. (gimple_assign_rhs_code): Likewise. (gimple_assign_set_rhs_code): Likewise. (gimple_call_internal_p): Likewise. (gimple_call_set_tail): Likewise. (gimple_call_tail_p): Likewise. (gimple_call_set_return_slot_opt): Likewise. (gimple_call_return_slot_opt_p): Likewise. (gimple_call_set_from_thunk): Likewise. (gimple_call_from_thunk_p): Likewise. (gimple_call_set_va_arg_pack): Likewise. (gimple_call_va_arg_pack_p): Likewise. (gimple_call_set_nothrow): Likewise. (gimple_call_set_alloca_for_var): Likewise. (gimple_call_alloca_for_var_p): Likewise. (gimple_call_copy_flags): Likewise. (gimple_cond_code): Likewise. (gimple_cond_set_code): Likewise. (gimple_cond_make_false): Likewise. (gimple_cond_make_true): Likewise. (gimple_asm_volatile_p): Likewise. (gimple_asm_set_volatile): Likewise. (gimple_asm_set_input): Likewise. (gimple_asm_input_p): Likewise. (gimple_try_kind): Likewise. (gimple_try_set_kind): Likewise. (gimple_try_catch_is_cleanup): Likewise. (gimple_try_set_catch_is_cleanup): Likewise. (gimple_wce_cleanup_eh_only): Likewise. (gimple_wce_set_cleanup_eh_only): Likewise. (gimple_debug_bind_p): Likewise. (gimple_debug_source_bind_p): Likewise. (gimple_omp_for_set_kind): Likewise. (gimple_omp_for_set_combined_p): Likewise. (gimple_omp_for_set_combined_into_p): Likewise. (gimple_omp_target_set_kind): Likewise. (gimple_transaction_subcode): Likewise. (gimple_transaction_set_subcode): Likewise. (gimple_predict_predictor): Likewise. (gimple_predict_set_predictor): Likewise. (gimple_predict_outcome): Likewise. (gimple_predict_set_outcome): Likewise. (gsi_one_before_end_p): Likewise. (gsi_next): Likewise. (gsi_prev): Likewise. (gimple_transaction_set_label): Likewise. (gimple_transaction_set_body): Likewise. (gimple_transaction_label_ptr): Likewise. (gimple_transaction_label): Likewise. (gimple_transaction_body_ptr): Likewise. (gimple_omp_continue_set_control_use): Likewise. (gimple_omp_continue_control_use_ptr): Likewise. (gimple_omp_continue_control_use): Likewise. (gimple_omp_continue_set_control_def): Likewise. (gimple_omp_continue_control_def_ptr): Likewise. (gimple_omp_continue_control_def): Likewise. (gimple_omp_atomic_load_rhs_ptr): Likewise. (gimple_omp_atomic_load_rhs): Likewise. (gimple_omp_atomic_load_set_rhs): Likewise. (gimple_omp_atomic_load_lhs_ptr): Likewise. (gimple_omp_atomic_load_lhs): Likewise. (gimple_omp_atomic_load_set_lhs): Likewise. (gimple_omp_atomic_store_val_ptr): Likewise. (gimple_omp_atomic_store_val): Likewise. (gimple_omp_atomic_store_set_val): Likewise. (gimple_omp_for_cond): Likewise. (gimple_omp_for_set_cond): Likewise. (gimple_omp_sections_set_control): Likewise. (gimple_omp_sections_control_ptr): Likewise. (gimple_omp_sections_control): Likewise. (gimple_omp_sections_set_clauses): Likewise. (gimple_omp_sections_clauses_ptr): Likewise. (gimple_omp_sections_clauses): Likewise. (gimple_omp_teams_set_clauses): Likewise. (gimple_omp_teams_clauses_ptr): Likewise. (gimple_omp_teams_clauses): Likewise. (gimple_omp_target_set_data_arg): Likewise. (gimple_omp_target_data_arg_ptr): Likewise. (gimple_omp_target_data_arg): Likewise. (gimple_omp_target_set_child_fn): Likewise. (gimple_omp_target_child_fn_ptr): Likewise. (gimple_omp_target_child_fn): Likewise. (gimple_omp_target_set_clauses): Likewise. (gimple_omp_target_clauses_ptr): Likewise. (gimple_omp_target_clauses): Likewise. (gimple_omp_single_set_clauses): Likewise. (gimple_omp_single_clauses_ptr): Likewise. (gimple_omp_single_clauses): Likewise. (gimple_omp_task_set_arg_align): Likewise. (gimple_omp_task_arg_align_ptr): Likewise. (gimple_omp_task_arg_align): Likewise. (gimple_omp_task_set_arg_size): Likewise. (gimple_omp_task_arg_size_ptr): Likewise. (gimple_omp_task_arg_size): Likewise. (gimple_omp_task_set_copy_fn): Likewise. (gimple_omp_task_copy_fn_ptr): Likewise. (gimple_omp_task_copy_fn): Likewise. (gimple_omp_task_set_data_arg): Likewise. (gimple_omp_task_data_arg_ptr): Likewise. (gimple_omp_task_data_arg): Likewise. (gimple_omp_task_set_child_fn): Likewise. (gimple_omp_task_child_fn_ptr): Likewise. (gimple_omp_task_child_fn): Likewise. (gimple_omp_task_set_clauses): Likewise. (gimple_omp_task_clauses_ptr): Likewise. (gimple_omp_task_clauses): Likewise. (gimple_omp_parallel_set_data_arg): Likewise. (gimple_omp_parallel_data_arg_ptr): Likewise. (gimple_omp_parallel_data_arg): Likewise. (gimple_omp_parallel_set_child_fn): Likewise. (gimple_omp_parallel_child_fn_ptr): Likewise. (gimple_omp_parallel_child_fn): Likewise. (gimple_omp_parallel_set_clauses): Likewise. (gimple_omp_parallel_clauses_ptr): Likewise. (gimple_omp_parallel_clauses): Likewise. (gimple_omp_for_set_pre_body): Likewise. (gimple_omp_for_pre_body_ptr): Likewise. (gimple_omp_for_set_incr): Likewise. (gimple_omp_for_incr_ptr): Likewise. (gimple_omp_for_incr): Likewise. (gimple_omp_for_set_final): Likewise. (gimple_omp_for_final_ptr): Likewise. (gimple_omp_for_final): Likewise. (gimple_omp_for_set_initial): Likewise. (gimple_omp_for_initial_ptr): Likewise. (gimple_omp_for_initial): Likewise. (gimple_omp_for_set_index): Likewise. (gimple_omp_for_index_ptr): Likewise. (gimple_omp_for_index): Likewise. (gimple_omp_for_collapse): Likewise. (gimple_omp_for_set_clauses): Likewise. (gimple_omp_for_clauses_ptr): Likewise. (gimple_omp_for_clauses): Likewise. (gimple_omp_critical_set_name): Likewise. (gimple_omp_critical_name_ptr): Likewise. (gimple_omp_critical_name): Likewise. (gimple_eh_dispatch_set_region): Likewise. (gimple_eh_dispatch_region): Likewise. (gimple_resx_set_region): Likewise. (gimple_resx_region): Likewise. (gimple_phi_set_arg): Likewise. (gimple_phi_arg): Likewise. (gimple_phi_set_result): Likewise. (gimple_phi_result_ptr): Likewise. (gimple_phi_result): Likewise. (gimple_phi_num_args): Likewise. (gimple_phi_capacity): Likewise. (gimple_wce_set_cleanup): Likewise. (gimple_wce_cleanup_ptr): Likewise. (gimple_try_set_cleanup): Likewise. (gimple_try_set_eval): Likewise. (gimple_try_cleanup_ptr): Likewise. (gimple_try_eval_ptr): Likewise. (gimple_eh_else_set_e_body): Likewise. (gimple_eh_else_set_n_body): Likewise. (gimple_eh_else_e_body_ptr): Likewise. (gimple_eh_else_n_body_ptr): Likewise. (gimple_eh_must_not_throw_set_fndecl): Likewise. (gimple_eh_must_not_throw_fndecl): Likewise. (gimple_eh_filter_set_failure): Likewise. (gimple_eh_filter_set_types): Likewise. (gimple_eh_filter_failure_ptr): Likewise. (gimple_eh_filter_types_ptr): Likewise. (gimple_eh_filter_types): Likewise. (gimple_catch_set_handler): Likewise. (gimple_catch_set_types): Likewise. (gimple_catch_handler_ptr): Likewise. (gimple_catch_types_ptr): Likewise. (gimple_catch_types): Likewise. (gimple_asm_string): Likewise. (gimple_asm_set_label_op): Likewise. (gimple_asm_label_op): Likewise. (gimple_asm_set_clobber_op): Likewise. (gimple_asm_clobber_op): Likewise. (gimple_asm_set_output_op): Likewise. (gimple_asm_output_op_ptr): Likewise. (gimple_asm_output_op): Likewise. (gimple_asm_set_input_op): Likewise. (gimple_asm_input_op_ptr): Likewise. (gimple_asm_input_op): Likewise. (gimple_asm_nlabels): Likewise. (gimple_asm_nclobbers): Likewise. (gimple_asm_noutputs): Likewise. (gimple_asm_ninputs): Likewise. (gimple_bind_set_block): Likewise. (gimple_bind_block): Likewise. (gimple_bind_add_seq): Likewise. (gimple_bind_add_stmt): Likewise. (gimple_bind_set_body): Likewise. (gimple_bind_body_ptr): Likewise. (gimple_bind_append_vars): Likewise. (gimple_bind_set_vars): Likewise. (gimple_bind_vars): Likewise. (gimple_call_clobber_set): Likewise. (gimple_call_use_set): Likewise. (gimple_call_set_internal_fn): Likewise. (gimple_call_set_fntype): Likewise. (gimple_call_fntype): Likewise. (gimple_omp_return_lhs_ptr): Likewise. (gimple_omp_return_lhs): Likewise. (gimple_omp_return_set_lhs): Likewise. (gimple_omp_taskreg_set_data_arg): Likewise. (gimple_omp_taskreg_data_arg_ptr): Likewise. (gimple_omp_taskreg_data_arg): Likewise. (gimple_omp_taskreg_set_child_fn): Likewise. (gimple_omp_taskreg_child_fn_ptr): Likewise. (gimple_omp_taskreg_child_fn): Likewise. (gimple_omp_taskreg_set_clauses): Likewise. (gimple_omp_taskreg_clauses_ptr): Likewise. (gimple_omp_taskreg_clauses): Likewise. (gimple_vuse): Likewise. (gimple_vdef): Likewise. (gimple_vuse_ptr): Likewise. (gimple_vdef_ptr): Likewise. * tree-inline.c (copy_debug_stmt): Likewise. * tree-phinodes.c (make_phi_node): Likewise. --- gcc/gimple-iterator.c | 72 +-- gcc/gimple-pretty-print.c | 2 +- gcc/gimple-ssa.h | 16 +- gcc/gimple-streamer-in.c | 8 +- gcc/gimple-streamer-out.c | 2 +- gcc/gimple.c | 16 +- gcc/gimple.h | 1369 ++++++++++++++++++++++++++++++--------------- gcc/tree-inline.c | 2 +- gcc/tree-phinodes.c | 2 +- 9 files changed, 965 insertions(+), 524 deletions(-) diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c index e430050..ed0d6df 100644 --- a/gcc/gimple-iterator.c +++ b/gcc/gimple-iterator.c @@ -67,7 +67,7 @@ update_bb_for_stmts (gimple_seq_node first, gimple_seq_node last, { gimple_seq_node n; - for (n = first; n; n = n->gsbase.next) + for (n = first; n; n = n->next) { gimple_set_bb (n, bb); if (n == last) @@ -85,7 +85,7 @@ update_call_edge_frequencies (gimple_seq_node first, basic_block bb) int bb_freq = 0; gimple_seq_node n; - for (n = first; n ; n = n->gsbase.next) + for (n = first; n ; n = n->next) if (is_gimple_call (n)) { struct cgraph_edge *e; @@ -123,7 +123,7 @@ gsi_insert_seq_nodes_before (gimple_stmt_iterator *i, basic_block bb; gimple_seq_node cur = i->ptr; - gcc_assert (!cur || cur->gsbase.prev); + gcc_assert (!cur || cur->prev); if ((bb = gsi_bb (*i)) != NULL) update_bb_for_stmts (first, last, bb); @@ -131,13 +131,13 @@ gsi_insert_seq_nodes_before (gimple_stmt_iterator *i, /* Link SEQ before CUR in the sequence. */ if (cur) { - first->gsbase.prev = cur->gsbase.prev; - if (first->gsbase.prev->gsbase.next) - first->gsbase.prev->gsbase.next = first; + first->prev = cur->prev; + if (first->prev->next) + first->prev->next = first; else gimple_seq_set_first (i->seq, first); - last->gsbase.next = cur; - cur->gsbase.prev = last; + last->next = cur; + cur->prev = last; } else { @@ -148,11 +148,11 @@ gsi_insert_seq_nodes_before (gimple_stmt_iterator *i, labels, so it returns an iterator after the end of the block, and we need to insert before it; it might be cleaner to add a flag to the iterator saying whether we are at the start or end of the list). */ - last->gsbase.next = NULL; + last->next = NULL; if (itlast) { - first->gsbase.prev = itlast; - itlast->gsbase.next = first; + first->prev = itlast; + itlast->next = first; } else gimple_seq_set_first (i->seq, first); @@ -241,7 +241,7 @@ gsi_insert_seq_nodes_after (gimple_stmt_iterator *i, basic_block bb; gimple_seq_node cur = i->ptr; - gcc_assert (!cur || cur->gsbase.prev); + gcc_assert (!cur || cur->prev); /* If the iterator is inside a basic block, we need to update the basic block information for all the nodes between FIRST and LAST. */ @@ -251,20 +251,20 @@ gsi_insert_seq_nodes_after (gimple_stmt_iterator *i, /* Link SEQ after CUR. */ if (cur) { - last->gsbase.next = cur->gsbase.next; - if (last->gsbase.next) + last->next = cur->next; + if (last->next) { - last->gsbase.next->gsbase.prev = last; + last->next->prev = last; } else gimple_seq_set_last (i->seq, last); - first->gsbase.prev = cur; - cur->gsbase.next = first; + first->prev = cur; + cur->next = first; } else { gcc_assert (!gimple_seq_last (*i->seq)); - last->gsbase.next = NULL; + last->next = NULL; gimple_seq_set_first (i->seq, first); gimple_seq_set_last (i->seq, last); } @@ -346,15 +346,15 @@ gsi_split_seq_after (gimple_stmt_iterator i) cur = i.ptr; /* How can we possibly split after the end, or before the beginning? */ - gcc_assert (cur && cur->gsbase.next); - next = cur->gsbase.next; + gcc_assert (cur && cur->next); + next = cur->next; pold_seq = i.seq; gimple_seq_set_first (&new_seq, next); gimple_seq_set_last (&new_seq, gimple_seq_last (*pold_seq)); gimple_seq_set_last (pold_seq, cur); - cur->gsbase.next = NULL; + cur->next = NULL; return new_seq; } @@ -370,17 +370,17 @@ gsi_set_stmt (gimple_stmt_iterator *gsi, gimple stmt) gimple orig_stmt = gsi_stmt (*gsi); gimple prev, next; - stmt->gsbase.next = next = orig_stmt->gsbase.next; - stmt->gsbase.prev = prev = orig_stmt->gsbase.prev; + stmt->next = next = orig_stmt->next; + stmt->prev = prev = orig_stmt->prev; /* Note how we don't clear next/prev of orig_stmt. This is so that copies of *GSI our callers might still hold (to orig_stmt) can be advanced as if they too were replaced. */ - if (prev->gsbase.next) - prev->gsbase.next = stmt; + if (prev->next) + prev->next = stmt; else gimple_seq_set_first (gsi->seq, stmt); if (next) - next->gsbase.prev = stmt; + next->prev = stmt; else gimple_seq_set_last (gsi->seq, stmt); @@ -401,10 +401,10 @@ gsi_split_seq_before (gimple_stmt_iterator *i, gimple_seq *pnew_seq) /* How can we possibly split after the end? */ gcc_assert (cur); - prev = cur->gsbase.prev; + prev = cur->prev; old_seq = *i->seq; - if (!prev->gsbase.next) + if (!prev->next) *i->seq = NULL; i->seq = pnew_seq; @@ -414,8 +414,8 @@ gsi_split_seq_before (gimple_stmt_iterator *i, gimple_seq *pnew_seq) /* Cut OLD_SEQ before I. */ gimple_seq_set_last (&old_seq, prev); - if (prev->gsbase.next) - prev->gsbase.next = NULL; + if (prev->next) + prev->next = NULL; } @@ -575,20 +575,20 @@ gsi_remove (gimple_stmt_iterator *i, bool remove_permanently) /* Update the iterator and re-wire the links in I->SEQ. */ cur = i->ptr; - next = cur->gsbase.next; - prev = cur->gsbase.prev; + next = cur->next; + prev = cur->prev; /* See gsi_set_stmt for why we don't reset prev/next of STMT. */ if (next) /* Cur is not last. */ - next->gsbase.prev = prev; - else if (prev->gsbase.next) + next->prev = prev; + else if (prev->next) /* Cur is last but not first. */ gimple_seq_set_last (i->seq, prev); - if (prev->gsbase.next) + if (prev->next) /* Cur is not first. */ - prev->gsbase.next = next; + prev->next = next; else /* Cur is first. */ *i->seq = next; diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 881ff04..b9bbdc7 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -1061,7 +1061,7 @@ dump_gimple_eh_dispatch (pretty_printer *buffer, gimple gs, int spc, int flags) static void dump_gimple_debug (pretty_printer *buffer, gimple gs, int spc, int flags) { - switch (gs->gsbase.subcode) + switch (gs->subcode) { case GIMPLE_DEBUG_BIND: if (flags & TDF_RAW) diff --git a/gcc/gimple-ssa.h b/gcc/gimple-ssa.h index 23aa099..50b48bb 100644 --- a/gcc/gimple-ssa.h +++ b/gcc/gimple-ssa.h @@ -108,11 +108,13 @@ static inline use_operand_p gimple_vuse_op (const_gimple g) { struct use_optype_d *ops; - if (!gimple_has_mem_ops (g)) + const gimple_statement_with_memory_ops *mem_ops_stmt = + dyn_cast <const gimple_statement_with_memory_ops> (g); + if (!mem_ops_stmt) return NULL_USE_OPERAND_P; - ops = g->gsops.opbase.use_ops; + ops = mem_ops_stmt->use_ops; if (ops - && USE_OP_PTR (ops)->use == &g->gsmembase.vuse) + && USE_OP_PTR (ops)->use == &mem_ops_stmt->vuse) return USE_OP_PTR (ops); return NULL_USE_OPERAND_P; } @@ -122,10 +124,12 @@ gimple_vuse_op (const_gimple g) static inline def_operand_p gimple_vdef_op (gimple g) { - if (!gimple_has_mem_ops (g)) + gimple_statement_with_memory_ops *mem_ops_stmt = + dyn_cast <gimple_statement_with_memory_ops> (g); + if (!mem_ops_stmt) return NULL_DEF_OPERAND_P; - if (g->gsmembase.vdef) - return &g->gsmembase.vdef; + if (mem_ops_stmt->vdef) + return &mem_ops_stmt->vdef; return NULL_DEF_OPERAND_P; } diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c index 2a19aab..4f31b83 100644 --- a/gcc/gimple-streamer-in.c +++ b/gcc/gimple-streamer-in.c @@ -98,12 +98,12 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, bp = streamer_read_bitpack (ib); num_ops = bp_unpack_var_len_unsigned (&bp); stmt = gimple_alloc (code, num_ops); - stmt->gsbase.no_warning = bp_unpack_value (&bp, 1); + stmt->no_warning = bp_unpack_value (&bp, 1); if (is_gimple_assign (stmt)) - stmt->gsbase.nontemporal_move = bp_unpack_value (&bp, 1); - stmt->gsbase.has_volatile_ops = bp_unpack_value (&bp, 1); + stmt->nontemporal_move = bp_unpack_value (&bp, 1); + stmt->has_volatile_ops = bp_unpack_value (&bp, 1); has_hist = bp_unpack_value (&bp, 1); - stmt->gsbase.subcode = bp_unpack_var_len_unsigned (&bp); + stmt->subcode = bp_unpack_var_len_unsigned (&bp); /* Read location information. */ gimple_set_location (stmt, stream_input_location (&bp, data_in)); diff --git a/gcc/gimple-streamer-out.c b/gcc/gimple-streamer-out.c index 976f57e..e7a7de0 100644 --- a/gcc/gimple-streamer-out.c +++ b/gcc/gimple-streamer-out.c @@ -77,7 +77,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt) bp_pack_value (&bp, gimple_has_volatile_ops (stmt), 1); hist = gimple_histogram_value (cfun, stmt); bp_pack_value (&bp, hist != NULL, 1); - bp_pack_var_len_unsigned (&bp, stmt->gsbase.subcode); + bp_pack_var_len_unsigned (&bp, stmt->subcode); /* Emit location information for the statement. */ stream_output_location (ob, &bp, LOCATION_LOCUS (gimple_location (stmt))); diff --git a/gcc/gimple.c b/gcc/gimple.c index 958514c..9b1337a 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -94,7 +94,7 @@ extern void gimple_set_loaded_syms (gimple, bitmap, bitmap_obstack *); static inline void gimple_set_code (gimple g, enum gimple_code code) { - g->gsbase.code = code; + g->code = code; } /* Return the number of bytes needed to hold a GIMPLE statement with @@ -132,7 +132,7 @@ gimple_alloc_stat (enum gimple_code code, unsigned num_ops MEM_STAT_DECL) /* Do not call gimple_set_modified here as it has other side effects and this tuple is still not completely built. */ - stmt->gsbase.modified = 1; + stmt->modified = 1; gimple_init_singleton (stmt); return stmt; @@ -146,7 +146,7 @@ gimple_set_subcode (gimple g, unsigned subcode) /* We only have 16 bits for the RHS code. Assert that we are not overflowing it. */ gcc_assert (subcode < (1 << 16)); - g->gsbase.subcode = subcode; + g->subcode = subcode; } @@ -281,7 +281,7 @@ static inline gimple gimple_build_call_internal_1 (enum internal_fn fn, unsigned nargs) { gimple s = gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK, nargs + 3); - s->gsbase.subcode |= GF_CALL_INTERNAL; + s->subcode |= GF_CALL_INTERNAL; gimple_call_set_internal_fn (s, fn); gimple_call_reset_alias_info (s); return s; @@ -1222,8 +1222,8 @@ gimple_check_failed (const_gimple gs, const char *file, int line, gimple_code_name[code], get_tree_code_name (subcode), gimple_code_name[gimple_code (gs)], - gs->gsbase.subcode > 0 - ? get_tree_code_name ((enum tree_code) gs->gsbase.subcode) + gs->subcode > 0 + ? get_tree_code_name ((enum tree_code) gs->subcode) : "", function, trim_filename (file), line); } @@ -1975,7 +1975,7 @@ gimple_call_flags (const_gimple stmt) else flags = flags_from_decl_or_type (gimple_call_fntype (stmt)); - if (stmt->gsbase.subcode & GF_CALL_NOTHROW) + if (stmt->subcode & GF_CALL_NOTHROW) flags |= ECF_NOTHROW; return flags; @@ -2116,7 +2116,7 @@ gimple_assign_unary_nop_p (gimple gs) void gimple_set_bb (gimple stmt, basic_block bb) { - stmt->gsbase.bb = bb; + stmt->bb = bb; /* If the statement is a label, add the label to block-to-labels map so that we can speed up edge creation for GIMPLE_GOTOs. */ diff --git a/gcc/gimple.h b/gcc/gimple.h index 6ff7602..f258992 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -719,6 +719,310 @@ enum gimple_statement_structure_enum { }; #undef DEFGSSTRUCT +template <> +template <> +inline bool +is_a_helper <gimple_statement_asm>::test (gimple gs) +{ + return gs->code == GIMPLE_ASM; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_bind>::test (gimple gs) +{ + return gs->code == GIMPLE_BIND; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_call>::test (gimple gs) +{ + return gs->code == GIMPLE_CALL; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_catch>::test (gimple gs) +{ + return gs->code == GIMPLE_CATCH; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_eh_ctrl>::test (gimple gs) +{ + return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_eh_else>::test (gimple gs) +{ + return gs->code == GIMPLE_EH_ELSE; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_eh_filter>::test (gimple gs) +{ + return gs->code == GIMPLE_EH_FILTER; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_eh_mnt>::test (gimple gs) +{ + return gs->code == GIMPLE_EH_MUST_NOT_THROW; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_atomic_load>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_ATOMIC_LOAD; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_atomic_store>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_continue>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_CONTINUE; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_critical>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_CRITICAL; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_for>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_FOR; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_parallel>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_sections>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_SECTIONS; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_single>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_task>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_TASK; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_phi>::test (gimple gs) +{ + return gs->code == GIMPLE_PHI; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_transaction>::test (gimple gs) +{ + return gs->code == GIMPLE_TRANSACTION; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_try>::test (gimple gs) +{ + return gs->code == GIMPLE_TRY; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_wce>::test (gimple gs) +{ + return gs->code == GIMPLE_WITH_CLEANUP_EXPR; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_asm>::test (const_gimple gs) +{ + return gs->code == GIMPLE_ASM; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_bind>::test (const_gimple gs) +{ + return gs->code == GIMPLE_BIND; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_call>::test (const_gimple gs) +{ + return gs->code == GIMPLE_CALL; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_catch>::test (const_gimple gs) +{ + return gs->code == GIMPLE_CATCH; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_eh_ctrl>::test (const_gimple gs) +{ + return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_eh_filter>::test (const_gimple gs) +{ + return gs->code == GIMPLE_EH_FILTER; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_atomic_load>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_ATOMIC_LOAD; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_atomic_store>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_continue>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_CONTINUE; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_critical>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_CRITICAL; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_for>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_FOR; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_parallel>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_sections>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_SECTIONS; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_single>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_task>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_TASK; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_phi>::test (const_gimple gs) +{ + return gs->code == GIMPLE_PHI; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_transaction>::test (const_gimple gs) +{ + return gs->code == GIMPLE_TRANSACTION; +} + /* Offset in bytes to the location of the operand vector. Zero if there is no operand vector for this tuple structure. */ extern size_t const gimple_ops_offset_[]; @@ -1121,7 +1425,7 @@ gimple_seq_first_stmt (gimple_seq s) static inline gimple_seq_node gimple_seq_last (gimple_seq s) { - return s ? s->gsbase.prev : NULL; + return s ? s->prev : NULL; } @@ -1140,7 +1444,7 @@ gimple_seq_last_stmt (gimple_seq s) static inline void gimple_seq_set_last (gimple_seq *ps, gimple_seq_node last) { - (*ps)->gsbase.prev = last; + (*ps)->prev = last; } @@ -1210,7 +1514,7 @@ set_bb_seq (basic_block bb, gimple_seq seq) static inline enum gimple_code gimple_code (const_gimple g) { - return g->gsbase.code; + return g->code; } @@ -1273,7 +1577,7 @@ gimple_has_substatements (gimple g) static inline basic_block gimple_bb (const_gimple g) { - return g->gsbase.bb; + return g->bb; } @@ -1282,7 +1586,7 @@ gimple_bb (const_gimple g) static inline tree gimple_block (const_gimple g) { - return LOCATION_BLOCK (g->gsbase.location); + return LOCATION_BLOCK (g->location); } @@ -1292,10 +1596,10 @@ static inline void gimple_set_block (gimple g, tree block) { if (block) - g->gsbase.location = - COMBINE_LOCATION_DATA (line_table, g->gsbase.location, block); + g->location = + COMBINE_LOCATION_DATA (line_table, g->location, block); else - g->gsbase.location = LOCATION_LOCUS (g->gsbase.location); + g->location = LOCATION_LOCUS (g->location); } @@ -1304,7 +1608,7 @@ gimple_set_block (gimple g, tree block) static inline location_t gimple_location (const_gimple g) { - return g->gsbase.location; + return g->location; } /* Return pointer to location information for statement G. */ @@ -1312,7 +1616,7 @@ gimple_location (const_gimple g) static inline const location_t * gimple_location_ptr (const_gimple g) { - return &g->gsbase.location; + return &g->location; } @@ -1321,7 +1625,7 @@ gimple_location_ptr (const_gimple g) static inline void gimple_set_location (gimple g, location_t location) { - g->gsbase.location = location; + g->location = location; } @@ -1366,7 +1670,7 @@ gimple_seq_singleton_p (gimple_seq seq) static inline bool gimple_no_warning_p (const_gimple stmt) { - return stmt->gsbase.no_warning; + return stmt->no_warning; } /* Set the no_warning flag of STMT to NO_WARNING. */ @@ -1374,7 +1678,7 @@ gimple_no_warning_p (const_gimple stmt) static inline void gimple_set_no_warning (gimple stmt, bool no_warning) { - stmt->gsbase.no_warning = (unsigned) no_warning; + stmt->no_warning = (unsigned) no_warning; } /* Set the visited status on statement STMT to VISITED_P. */ @@ -1382,7 +1686,7 @@ gimple_set_no_warning (gimple stmt, bool no_warning) static inline void gimple_set_visited (gimple stmt, bool visited_p) { - stmt->gsbase.visited = (unsigned) visited_p; + stmt->visited = (unsigned) visited_p; } @@ -1391,7 +1695,7 @@ gimple_set_visited (gimple stmt, bool visited_p) static inline bool gimple_visited_p (gimple stmt) { - return stmt->gsbase.visited; + return stmt->visited; } @@ -1401,9 +1705,9 @@ static inline void gimple_set_plf (gimple stmt, enum plf_mask plf, bool val_p) { if (val_p) - stmt->gsbase.plf |= (unsigned int) plf; + stmt->plf |= (unsigned int) plf; else - stmt->gsbase.plf &= ~((unsigned int) plf); + stmt->plf &= ~((unsigned int) plf); } @@ -1412,7 +1716,7 @@ gimple_set_plf (gimple stmt, enum plf_mask plf, bool val_p) static inline unsigned int gimple_plf (gimple stmt, enum plf_mask plf) { - return stmt->gsbase.plf & ((unsigned int) plf); + return stmt->plf & ((unsigned int) plf); } @@ -1421,7 +1725,7 @@ gimple_plf (gimple stmt, enum plf_mask plf) static inline void gimple_set_uid (gimple g, unsigned uid) { - g->gsbase.uid = uid; + g->uid = uid; } @@ -1430,7 +1734,7 @@ gimple_set_uid (gimple g, unsigned uid) static inline unsigned gimple_uid (const_gimple g) { - return g->gsbase.uid; + return g->uid; } @@ -1439,8 +1743,8 @@ gimple_uid (const_gimple g) static inline void gimple_init_singleton (gimple g) { - g->gsbase.next = NULL; - g->gsbase.prev = g; + g->next = NULL; + g->prev = g; } @@ -1491,9 +1795,11 @@ gimple_set_use_ops (gimple g, struct use_optype_d *use) static inline tree gimple_vuse (const_gimple g) { - if (!gimple_has_mem_ops (g)) + const gimple_statement_with_memory_ops *mem_ops_stmt = + dyn_cast <const gimple_statement_with_memory_ops> (g); + if (!mem_ops_stmt) return NULL_TREE; - return g->gsmembase.vuse; + return mem_ops_stmt->vuse; } /* Return the single VDEF operand of the statement G. */ @@ -1501,9 +1807,11 @@ gimple_vuse (const_gimple g) static inline tree gimple_vdef (const_gimple g) { - if (!gimple_has_mem_ops (g)) + const gimple_statement_with_memory_ops *mem_ops_stmt = + dyn_cast <const gimple_statement_with_memory_ops> (g); + if (!mem_ops_stmt) return NULL_TREE; - return g->gsmembase.vdef; + return mem_ops_stmt->vdef; } /* Return the single VUSE operand of the statement G. */ @@ -1511,9 +1819,11 @@ gimple_vdef (const_gimple g) static inline tree * gimple_vuse_ptr (gimple g) { - if (!gimple_has_mem_ops (g)) + gimple_statement_with_memory_ops *mem_ops_stmt = + dyn_cast <gimple_statement_with_memory_ops> (g); + if (!mem_ops_stmt) return NULL; - return &g->gsmembase.vuse; + return &mem_ops_stmt->vuse; } /* Return the single VDEF operand of the statement G. */ @@ -1521,9 +1831,11 @@ gimple_vuse_ptr (gimple g) static inline tree * gimple_vdef_ptr (gimple g) { - if (!gimple_has_mem_ops (g)) + gimple_statement_with_memory_ops *mem_ops_stmt = + dyn_cast <gimple_statement_with_memory_ops> (g); + if (!mem_ops_stmt) return NULL; - return &g->gsmembase.vdef; + return &mem_ops_stmt->vdef; } /* Set the single VUSE operand of the statement G. */ @@ -1553,7 +1865,7 @@ gimple_set_vdef (gimple g, tree vdef) static inline bool gimple_modified_p (const_gimple g) { - return (gimple_has_ops (g)) ? (bool) g->gsbase.modified : false; + return (gimple_has_ops (g)) ? (bool) g->modified : false; } @@ -1564,7 +1876,7 @@ static inline void gimple_set_modified (gimple s, bool modifiedp) { if (gimple_has_ops (s)) - s->gsbase.modified = (unsigned) modifiedp; + s->modified = (unsigned) modifiedp; } @@ -1579,7 +1891,7 @@ gimple_expr_code (const_gimple stmt) { enum gimple_code code = gimple_code (stmt); if (code == GIMPLE_ASSIGN || code == GIMPLE_COND) - return (enum tree_code) stmt->gsbase.subcode; + return (enum tree_code) stmt->subcode; else { gcc_gimple_checking_assert (code == GIMPLE_CALL); @@ -1594,7 +1906,7 @@ static inline bool gimple_has_volatile_ops (const_gimple stmt) { if (gimple_has_mem_ops (stmt)) - return stmt->gsbase.has_volatile_ops; + return stmt->has_volatile_ops; else return false; } @@ -1606,7 +1918,7 @@ static inline void gimple_set_has_volatile_ops (gimple stmt, bool volatilep) { if (gimple_has_mem_ops (stmt)) - stmt->gsbase.has_volatile_ops = (unsigned) volatilep; + stmt->has_volatile_ops = (unsigned) volatilep; } /* Return true if BB is in a transaction. */ @@ -1641,7 +1953,7 @@ gimple_omp_subcode (const_gimple s) { gcc_gimple_checking_assert (gimple_code (s) >= GIMPLE_OMP_ATOMIC_LOAD && gimple_code (s) <= GIMPLE_OMP_TEAMS); - return s->gsbase.subcode; + return s->subcode; } /* Set the subcode for OMP statement S to SUBCODE. */ @@ -1652,7 +1964,7 @@ gimple_omp_set_subcode (gimple s, unsigned int subcode) /* We only have 16 bits for the subcode. Assert that we are not overflowing it. */ gcc_gimple_checking_assert (subcode < (1 << 16)); - s->gsbase.subcode = subcode; + s->subcode = subcode; } /* Set the nowait flag on OMP_RETURN statement S. */ @@ -1661,7 +1973,7 @@ static inline void gimple_omp_return_set_nowait (gimple s) { GIMPLE_CHECK (s, GIMPLE_OMP_RETURN); - s->gsbase.subcode |= GF_OMP_RETURN_NOWAIT; + s->subcode |= GF_OMP_RETURN_NOWAIT; } @@ -1681,8 +1993,9 @@ gimple_omp_return_nowait_p (const_gimple g) static inline void gimple_omp_return_set_lhs (gimple g, tree lhs) { - GIMPLE_CHECK (g, GIMPLE_OMP_RETURN); - g->gimple_omp_atomic_store.val = lhs; + gimple_statement_omp_atomic_store *omp_atomic_store_stmt = + as_a <gimple_statement_omp_atomic_store> (g); + omp_atomic_store_stmt->val = lhs; } @@ -1691,8 +2004,9 @@ gimple_omp_return_set_lhs (gimple g, tree lhs) static inline tree gimple_omp_return_lhs (const_gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_RETURN); - return g->gimple_omp_atomic_store.val; + const gimple_statement_omp_atomic_store *omp_atomic_store_stmt = + as_a <const gimple_statement_omp_atomic_store> (g); + return omp_atomic_store_stmt->val; } @@ -1701,8 +2015,9 @@ gimple_omp_return_lhs (const_gimple g) static inline tree * gimple_omp_return_lhs_ptr (gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_RETURN); - return &g->gimple_omp_atomic_store.val; + gimple_statement_omp_atomic_store *omp_atomic_store_stmt = + as_a <gimple_statement_omp_atomic_store> (g); + return &omp_atomic_store_stmt->val; } @@ -1723,7 +2038,7 @@ static inline void gimple_omp_section_set_last (gimple g) { GIMPLE_CHECK (g, GIMPLE_OMP_SECTION); - g->gsbase.subcode |= GF_OMP_SECTION_LAST; + g->subcode |= GF_OMP_SECTION_LAST; } @@ -1746,9 +2061,9 @@ gimple_omp_parallel_set_combined_p (gimple g, bool combined_p) { GIMPLE_CHECK (g, GIMPLE_OMP_PARALLEL); if (combined_p) - g->gsbase.subcode |= GF_OMP_PARALLEL_COMBINED; + g->subcode |= GF_OMP_PARALLEL_COMBINED; else - g->gsbase.subcode &= ~GF_OMP_PARALLEL_COMBINED; + g->subcode &= ~GF_OMP_PARALLEL_COMBINED; } @@ -1771,7 +2086,7 @@ gimple_omp_atomic_set_need_value (gimple g) { if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD) GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); - g->gsbase.subcode |= GF_OMP_ATOMIC_NEED_VALUE; + g->subcode |= GF_OMP_ATOMIC_NEED_VALUE; } @@ -1794,7 +2109,7 @@ gimple_omp_atomic_set_seq_cst (gimple g) { if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD) GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); - g->gsbase.subcode |= GF_OMP_ATOMIC_SEQ_CST; + g->subcode |= GF_OMP_ATOMIC_SEQ_CST; } @@ -1803,7 +2118,7 @@ gimple_omp_atomic_set_seq_cst (gimple g) static inline unsigned gimple_num_ops (const_gimple gs) { - return gs->gsbase.num_ops; + return gs->num_ops; } @@ -1812,7 +2127,7 @@ gimple_num_ops (const_gimple gs) static inline void gimple_set_num_ops (gimple gs, unsigned num_ops) { - gs->gsbase.num_ops = num_ops; + gs->num_ops = num_ops; } @@ -2055,7 +2370,7 @@ static inline bool gimple_assign_nontemporal_move_p (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_ASSIGN); - return gs->gsbase.nontemporal_move; + return gs->nontemporal_move; } /* Sets nontemporal move flag of GS to NONTEMPORAL. */ @@ -2064,7 +2379,7 @@ static inline void gimple_assign_set_nontemporal_move (gimple gs, bool nontemporal) { GIMPLE_CHECK (gs, GIMPLE_ASSIGN); - gs->gsbase.nontemporal_move = nontemporal; + gs->nontemporal_move = nontemporal; } @@ -2078,7 +2393,7 @@ gimple_assign_rhs_code (const_gimple gs) enum tree_code code; GIMPLE_CHECK (gs, GIMPLE_ASSIGN); - code = (enum tree_code) gs->gsbase.subcode; + code = (enum tree_code) gs->subcode; /* While we initially set subcode to the TREE_CODE of the rhs for GIMPLE_SINGLE_RHS assigns we do not update that subcode to stay in sync when we rewrite stmts into SSA form or do SSA propagations. */ @@ -2096,7 +2411,7 @@ static inline void gimple_assign_set_rhs_code (gimple s, enum tree_code code) { GIMPLE_CHECK (s, GIMPLE_ASSIGN); - s->gsbase.subcode = code; + s->subcode = code; } @@ -2221,7 +2536,7 @@ static inline bool gimple_call_internal_p (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_CALL); - return (gs->gsbase.subcode & GF_CALL_INTERNAL) != 0; + return (gs->subcode & GF_CALL_INTERNAL) != 0; } @@ -2240,10 +2555,11 @@ gimple_call_internal_fn (const_gimple gs) static inline tree gimple_call_fntype (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_CALL); + const gimple_statement_call *call_stmt = + as_a <const gimple_statement_call> (gs); if (gimple_call_internal_p (gs)) return NULL_TREE; - return gs->gimple_call.u.fntype; + return call_stmt->u.fntype; } /* Set the type of the function called by GS to FNTYPE. */ @@ -2251,9 +2567,9 @@ gimple_call_fntype (const_gimple gs) static inline void gimple_call_set_fntype (gimple gs, tree fntype) { - GIMPLE_CHECK (gs, GIMPLE_CALL); + gimple_statement_call *call_stmt = as_a <gimple_statement_call> (gs); gcc_gimple_checking_assert (!gimple_call_internal_p (gs)); - gs->gimple_call.u.fntype = fntype; + call_stmt->u.fntype = fntype; } @@ -2305,9 +2621,9 @@ gimple_call_set_fndecl (gimple gs, tree decl) static inline void gimple_call_set_internal_fn (gimple gs, enum internal_fn fn) { - GIMPLE_CHECK (gs, GIMPLE_CALL); + gimple_statement_call *call_stmt = as_a <gimple_statement_call> (gs); gcc_gimple_checking_assert (gimple_call_internal_p (gs)); - gs->gimple_call.u.internal_fn = fn; + call_stmt->u.internal_fn = fn; } @@ -2465,9 +2781,9 @@ gimple_call_set_tail (gimple s, bool tail_p) { GIMPLE_CHECK (s, GIMPLE_CALL); if (tail_p) - s->gsbase.subcode |= GF_CALL_TAILCALL; + s->subcode |= GF_CALL_TAILCALL; else - s->gsbase.subcode &= ~GF_CALL_TAILCALL; + s->subcode &= ~GF_CALL_TAILCALL; } @@ -2477,7 +2793,7 @@ static inline bool gimple_call_tail_p (gimple s) { GIMPLE_CHECK (s, GIMPLE_CALL); - return (s->gsbase.subcode & GF_CALL_TAILCALL) != 0; + return (s->subcode & GF_CALL_TAILCALL) != 0; } @@ -2490,9 +2806,9 @@ gimple_call_set_return_slot_opt (gimple s, bool return_slot_opt_p) { GIMPLE_CHECK (s, GIMPLE_CALL); if (return_slot_opt_p) - s->gsbase.subcode |= GF_CALL_RETURN_SLOT_OPT; + s->subcode |= GF_CALL_RETURN_SLOT_OPT; else - s->gsbase.subcode &= ~GF_CALL_RETURN_SLOT_OPT; + s->subcode &= ~GF_CALL_RETURN_SLOT_OPT; } @@ -2502,7 +2818,7 @@ static inline bool gimple_call_return_slot_opt_p (gimple s) { GIMPLE_CHECK (s, GIMPLE_CALL); - return (s->gsbase.subcode & GF_CALL_RETURN_SLOT_OPT) != 0; + return (s->subcode & GF_CALL_RETURN_SLOT_OPT) != 0; } @@ -2514,9 +2830,9 @@ gimple_call_set_from_thunk (gimple s, bool from_thunk_p) { GIMPLE_CHECK (s, GIMPLE_CALL); if (from_thunk_p) - s->gsbase.subcode |= GF_CALL_FROM_THUNK; + s->subcode |= GF_CALL_FROM_THUNK; else - s->gsbase.subcode &= ~GF_CALL_FROM_THUNK; + s->subcode &= ~GF_CALL_FROM_THUNK; } @@ -2526,7 +2842,7 @@ static inline bool gimple_call_from_thunk_p (gimple s) { GIMPLE_CHECK (s, GIMPLE_CALL); - return (s->gsbase.subcode & GF_CALL_FROM_THUNK) != 0; + return (s->subcode & GF_CALL_FROM_THUNK) != 0; } @@ -2538,9 +2854,9 @@ gimple_call_set_va_arg_pack (gimple s, bool pass_arg_pack_p) { GIMPLE_CHECK (s, GIMPLE_CALL); if (pass_arg_pack_p) - s->gsbase.subcode |= GF_CALL_VA_ARG_PACK; + s->subcode |= GF_CALL_VA_ARG_PACK; else - s->gsbase.subcode &= ~GF_CALL_VA_ARG_PACK; + s->subcode &= ~GF_CALL_VA_ARG_PACK; } @@ -2551,7 +2867,7 @@ static inline bool gimple_call_va_arg_pack_p (gimple s) { GIMPLE_CHECK (s, GIMPLE_CALL); - return (s->gsbase.subcode & GF_CALL_VA_ARG_PACK) != 0; + return (s->subcode & GF_CALL_VA_ARG_PACK) != 0; } @@ -2573,9 +2889,9 @@ gimple_call_set_nothrow (gimple s, bool nothrow_p) { GIMPLE_CHECK (s, GIMPLE_CALL); if (nothrow_p) - s->gsbase.subcode |= GF_CALL_NOTHROW; + s->subcode |= GF_CALL_NOTHROW; else - s->gsbase.subcode &= ~GF_CALL_NOTHROW; + s->subcode &= ~GF_CALL_NOTHROW; } /* Return true if S is a nothrow call. */ @@ -2597,9 +2913,9 @@ gimple_call_set_alloca_for_var (gimple s, bool for_var) { GIMPLE_CHECK (s, GIMPLE_CALL); if (for_var) - s->gsbase.subcode |= GF_CALL_ALLOCA_FOR_VAR; + s->subcode |= GF_CALL_ALLOCA_FOR_VAR; else - s->gsbase.subcode &= ~GF_CALL_ALLOCA_FOR_VAR; + s->subcode &= ~GF_CALL_ALLOCA_FOR_VAR; } /* Return true of S is a call to builtin_alloca emitted for VLA objects. */ @@ -2608,7 +2924,7 @@ static inline bool gimple_call_alloca_for_var_p (gimple s) { GIMPLE_CHECK (s, GIMPLE_CALL); - return (s->gsbase.subcode & GF_CALL_ALLOCA_FOR_VAR) != 0; + return (s->subcode & GF_CALL_ALLOCA_FOR_VAR) != 0; } /* Copy all the GF_CALL_* flags from ORIG_CALL to DEST_CALL. */ @@ -2618,7 +2934,7 @@ gimple_call_copy_flags (gimple dest_call, gimple orig_call) { GIMPLE_CHECK (dest_call, GIMPLE_CALL); GIMPLE_CHECK (orig_call, GIMPLE_CALL); - dest_call->gsbase.subcode = orig_call->gsbase.subcode; + dest_call->subcode = orig_call->subcode; } @@ -2628,8 +2944,8 @@ gimple_call_copy_flags (gimple dest_call, gimple orig_call) static inline struct pt_solution * gimple_call_use_set (gimple call) { - GIMPLE_CHECK (call, GIMPLE_CALL); - return &call->gimple_call.call_used; + gimple_statement_call *call_stmt = as_a <gimple_statement_call> (call); + return &call_stmt->call_used; } @@ -2639,8 +2955,8 @@ gimple_call_use_set (gimple call) static inline struct pt_solution * gimple_call_clobber_set (gimple call) { - GIMPLE_CHECK (call, GIMPLE_CALL); - return &call->gimple_call.call_clobbered; + gimple_statement_call *call_stmt = as_a <gimple_statement_call> (call); + return &call_stmt->call_clobbered; } @@ -2662,7 +2978,7 @@ static inline enum tree_code gimple_cond_code (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_COND); - return (enum tree_code) gs->gsbase.subcode; + return (enum tree_code) gs->subcode; } @@ -2672,7 +2988,7 @@ static inline void gimple_cond_set_code (gimple gs, enum tree_code code) { GIMPLE_CHECK (gs, GIMPLE_COND); - gs->gsbase.subcode = code; + gs->subcode = code; } @@ -2788,7 +3104,7 @@ gimple_cond_make_false (gimple gs) { gimple_cond_set_lhs (gs, boolean_true_node); gimple_cond_set_rhs (gs, boolean_false_node); - gs->gsbase.subcode = EQ_EXPR; + gs->subcode = EQ_EXPR; } @@ -2799,7 +3115,7 @@ gimple_cond_make_true (gimple gs) { gimple_cond_set_lhs (gs, boolean_true_node); gimple_cond_set_rhs (gs, boolean_true_node); - gs->gsbase.subcode = EQ_EXPR; + gs->subcode = EQ_EXPR; } /* Check if conditional statemente GS is of the form 'if (1 == 1)', @@ -2908,8 +3224,9 @@ gimple_goto_set_dest (gimple gs, tree dest) static inline tree gimple_bind_vars (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - return gs->gimple_bind.vars; + const gimple_statement_bind *bind_stmt = + as_a <const gimple_statement_bind> (gs); + return bind_stmt->vars; } @@ -2919,8 +3236,8 @@ gimple_bind_vars (const_gimple gs) static inline void gimple_bind_set_vars (gimple gs, tree vars) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - gs->gimple_bind.vars = vars; + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); + bind_stmt->vars = vars; } @@ -2930,16 +3247,16 @@ gimple_bind_set_vars (gimple gs, tree vars) static inline void gimple_bind_append_vars (gimple gs, tree vars) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - gs->gimple_bind.vars = chainon (gs->gimple_bind.vars, vars); + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); + bind_stmt->vars = chainon (bind_stmt->vars, vars); } static inline gimple_seq * gimple_bind_body_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - return &gs->gimple_bind.body; + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); + return &bind_stmt->body; } /* Return the GIMPLE sequence contained in the GIMPLE_BIND statement GS. */ @@ -2957,8 +3274,8 @@ gimple_bind_body (gimple gs) static inline void gimple_bind_set_body (gimple gs, gimple_seq seq) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - gs->gimple_bind.body = seq; + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); + bind_stmt->body = seq; } @@ -2967,8 +3284,8 @@ gimple_bind_set_body (gimple gs, gimple_seq seq) static inline void gimple_bind_add_stmt (gimple gs, gimple stmt) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - gimple_seq_add_stmt (&gs->gimple_bind.body, stmt); + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); + gimple_seq_add_stmt (&bind_stmt->body, stmt); } @@ -2977,8 +3294,8 @@ gimple_bind_add_stmt (gimple gs, gimple stmt) static inline void gimple_bind_add_seq (gimple gs, gimple_seq seq) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - gimple_seq_add_seq (&gs->gimple_bind.body, seq); + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); + gimple_seq_add_seq (&bind_stmt->body, seq); } @@ -2988,8 +3305,9 @@ gimple_bind_add_seq (gimple gs, gimple_seq seq) static inline tree gimple_bind_block (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - return gs->gimple_bind.block; + const gimple_statement_bind *bind_stmt = + as_a <const gimple_statement_bind> (gs); + return bind_stmt->block; } @@ -2999,10 +3317,10 @@ gimple_bind_block (const_gimple gs) static inline void gimple_bind_set_block (gimple gs, tree block) { - GIMPLE_CHECK (gs, GIMPLE_BIND); + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); gcc_gimple_checking_assert (block == NULL_TREE || TREE_CODE (block) == BLOCK); - gs->gimple_bind.block = block; + bind_stmt->block = block; } @@ -3011,8 +3329,9 @@ gimple_bind_set_block (gimple gs, tree block) static inline unsigned gimple_asm_ninputs (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - return gs->gimple_asm.ni; + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + return asm_stmt->ni; } @@ -3021,8 +3340,9 @@ gimple_asm_ninputs (const_gimple gs) static inline unsigned gimple_asm_noutputs (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - return gs->gimple_asm.no; + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + return asm_stmt->no; } @@ -3031,8 +3351,9 @@ gimple_asm_noutputs (const_gimple gs) static inline unsigned gimple_asm_nclobbers (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - return gs->gimple_asm.nc; + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + return asm_stmt->nc; } /* Return the number of label operands for GIMPLE_ASM GS. */ @@ -3040,8 +3361,9 @@ gimple_asm_nclobbers (const_gimple gs) static inline unsigned gimple_asm_nlabels (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - return gs->gimple_asm.nl; + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + return asm_stmt->nl; } /* Return input operand INDEX of GIMPLE_ASM GS. */ @@ -3049,9 +3371,10 @@ gimple_asm_nlabels (const_gimple gs) static inline tree gimple_asm_input_op (const_gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.ni); - return gimple_op (gs, index + gs->gimple_asm.no); + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->ni); + return gimple_op (gs, index + asm_stmt->no); } /* Return a pointer to input operand INDEX of GIMPLE_ASM GS. */ @@ -3059,9 +3382,10 @@ gimple_asm_input_op (const_gimple gs, unsigned index) static inline tree * gimple_asm_input_op_ptr (const_gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.ni); - return gimple_op_ptr (gs, index + gs->gimple_asm.no); + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->ni); + return gimple_op_ptr (gs, index + asm_stmt->no); } @@ -3070,10 +3394,10 @@ gimple_asm_input_op_ptr (const_gimple gs, unsigned index) static inline void gimple_asm_set_input_op (gimple gs, unsigned index, tree in_op) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.ni + gimple_statement_asm *asm_stmt = as_a <gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->ni && TREE_CODE (in_op) == TREE_LIST); - gimple_set_op (gs, index + gs->gimple_asm.no, in_op); + gimple_set_op (gs, index + asm_stmt->no, in_op); } @@ -3082,8 +3406,9 @@ gimple_asm_set_input_op (gimple gs, unsigned index, tree in_op) static inline tree gimple_asm_output_op (const_gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.no); + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->no); return gimple_op (gs, index); } @@ -3092,8 +3417,9 @@ gimple_asm_output_op (const_gimple gs, unsigned index) static inline tree * gimple_asm_output_op_ptr (const_gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.no); + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->no); return gimple_op_ptr (gs, index); } @@ -3103,8 +3429,8 @@ gimple_asm_output_op_ptr (const_gimple gs, unsigned index) static inline void gimple_asm_set_output_op (gimple gs, unsigned index, tree out_op) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.no + gimple_statement_asm *asm_stmt = as_a <gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->no && TREE_CODE (out_op) == TREE_LIST); gimple_set_op (gs, index, out_op); } @@ -3115,9 +3441,10 @@ gimple_asm_set_output_op (gimple gs, unsigned index, tree out_op) static inline tree gimple_asm_clobber_op (const_gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.nc); - return gimple_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.no); + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->nc); + return gimple_op (gs, index + asm_stmt->ni + asm_stmt->no); } @@ -3126,10 +3453,10 @@ gimple_asm_clobber_op (const_gimple gs, unsigned index) static inline void gimple_asm_set_clobber_op (gimple gs, unsigned index, tree clobber_op) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.nc + gimple_statement_asm *asm_stmt = as_a <gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->nc && TREE_CODE (clobber_op) == TREE_LIST); - gimple_set_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.no, clobber_op); + gimple_set_op (gs, index + asm_stmt->ni + asm_stmt->no, clobber_op); } /* Return label operand INDEX of GIMPLE_ASM GS. */ @@ -3137,9 +3464,10 @@ gimple_asm_set_clobber_op (gimple gs, unsigned index, tree clobber_op) static inline tree gimple_asm_label_op (const_gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.nl); - return gimple_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.nc); + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->nl); + return gimple_op (gs, index + asm_stmt->ni + asm_stmt->nc); } /* Set LABEL_OP to be label operand INDEX in GIMPLE_ASM GS. */ @@ -3147,10 +3475,10 @@ gimple_asm_label_op (const_gimple gs, unsigned index) static inline void gimple_asm_set_label_op (gimple gs, unsigned index, tree label_op) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.nl + gimple_statement_asm *asm_stmt = as_a <gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->nl && TREE_CODE (label_op) == TREE_LIST); - gimple_set_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.nc, label_op); + gimple_set_op (gs, index + asm_stmt->ni + asm_stmt->nc, label_op); } /* Return the string representing the assembly instruction in @@ -3159,8 +3487,9 @@ gimple_asm_set_label_op (gimple gs, unsigned index, tree label_op) static inline const char * gimple_asm_string (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - return gs->gimple_asm.string; + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + return asm_stmt->string; } @@ -3170,7 +3499,7 @@ static inline bool gimple_asm_volatile_p (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_ASM); - return (gs->gsbase.subcode & GF_ASM_VOLATILE) != 0; + return (gs->subcode & GF_ASM_VOLATILE) != 0; } @@ -3181,9 +3510,9 @@ gimple_asm_set_volatile (gimple gs, bool volatile_p) { GIMPLE_CHECK (gs, GIMPLE_ASM); if (volatile_p) - gs->gsbase.subcode |= GF_ASM_VOLATILE; + gs->subcode |= GF_ASM_VOLATILE; else - gs->gsbase.subcode &= ~GF_ASM_VOLATILE; + gs->subcode &= ~GF_ASM_VOLATILE; } @@ -3194,9 +3523,9 @@ gimple_asm_set_input (gimple gs, bool input_p) { GIMPLE_CHECK (gs, GIMPLE_ASM); if (input_p) - gs->gsbase.subcode |= GF_ASM_INPUT; + gs->subcode |= GF_ASM_INPUT; else - gs->gsbase.subcode &= ~GF_ASM_INPUT; + gs->subcode &= ~GF_ASM_INPUT; } @@ -3206,7 +3535,7 @@ static inline bool gimple_asm_input_p (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_ASM); - return (gs->gsbase.subcode & GF_ASM_INPUT) != 0; + return (gs->subcode & GF_ASM_INPUT) != 0; } @@ -3215,8 +3544,9 @@ gimple_asm_input_p (const_gimple gs) static inline tree gimple_catch_types (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_CATCH); - return gs->gimple_catch.types; + const gimple_statement_catch *catch_stmt = + as_a <const gimple_statement_catch> (gs); + return catch_stmt->types; } @@ -3225,8 +3555,8 @@ gimple_catch_types (const_gimple gs) static inline tree * gimple_catch_types_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_CATCH); - return &gs->gimple_catch.types; + gimple_statement_catch *catch_stmt = as_a <gimple_statement_catch> (gs); + return &catch_stmt->types; } @@ -3236,8 +3566,8 @@ gimple_catch_types_ptr (gimple gs) static inline gimple_seq * gimple_catch_handler_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_CATCH); - return &gs->gimple_catch.handler; + gimple_statement_catch *catch_stmt = as_a <gimple_statement_catch> (gs); + return &catch_stmt->handler; } @@ -3256,8 +3586,8 @@ gimple_catch_handler (gimple gs) static inline void gimple_catch_set_types (gimple gs, tree t) { - GIMPLE_CHECK (gs, GIMPLE_CATCH); - gs->gimple_catch.types = t; + gimple_statement_catch *catch_stmt = as_a <gimple_statement_catch> (gs); + catch_stmt->types = t; } @@ -3266,8 +3596,8 @@ gimple_catch_set_types (gimple gs, tree t) static inline void gimple_catch_set_handler (gimple gs, gimple_seq handler) { - GIMPLE_CHECK (gs, GIMPLE_CATCH); - gs->gimple_catch.handler = handler; + gimple_statement_catch *catch_stmt = as_a <gimple_statement_catch> (gs); + catch_stmt->handler = handler; } @@ -3276,8 +3606,9 @@ gimple_catch_set_handler (gimple gs, gimple_seq handler) static inline tree gimple_eh_filter_types (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); - return gs->gimple_eh_filter.types; + const gimple_statement_eh_filter *eh_filter_stmt = + as_a <const gimple_statement_eh_filter> (gs); + return eh_filter_stmt->types; } @@ -3287,8 +3618,9 @@ gimple_eh_filter_types (const_gimple gs) static inline tree * gimple_eh_filter_types_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); - return &gs->gimple_eh_filter.types; + gimple_statement_eh_filter *eh_filter_stmt = + as_a <gimple_statement_eh_filter> (gs); + return &eh_filter_stmt->types; } @@ -3298,8 +3630,9 @@ gimple_eh_filter_types_ptr (gimple gs) static inline gimple_seq * gimple_eh_filter_failure_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); - return &gs->gimple_eh_filter.failure; + gimple_statement_eh_filter *eh_filter_stmt = + as_a <gimple_statement_eh_filter> (gs); + return &eh_filter_stmt->failure; } @@ -3318,8 +3651,9 @@ gimple_eh_filter_failure (gimple gs) static inline void gimple_eh_filter_set_types (gimple gs, tree types) { - GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); - gs->gimple_eh_filter.types = types; + gimple_statement_eh_filter *eh_filter_stmt = + as_a <gimple_statement_eh_filter> (gs); + eh_filter_stmt->types = types; } @@ -3329,8 +3663,9 @@ gimple_eh_filter_set_types (gimple gs, tree types) static inline void gimple_eh_filter_set_failure (gimple gs, gimple_seq failure) { - GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); - gs->gimple_eh_filter.failure = failure; + gimple_statement_eh_filter *eh_filter_stmt = + as_a <gimple_statement_eh_filter> (gs); + eh_filter_stmt->failure = failure; } /* Get the function decl to be called by the MUST_NOT_THROW region. */ @@ -3338,8 +3673,8 @@ gimple_eh_filter_set_failure (gimple gs, gimple_seq failure) static inline tree gimple_eh_must_not_throw_fndecl (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_MUST_NOT_THROW); - return gs->gimple_eh_mnt.fndecl; + gimple_statement_eh_mnt *eh_mnt_stmt = as_a <gimple_statement_eh_mnt> (gs); + return eh_mnt_stmt->fndecl; } /* Set the function decl to be called by GS to DECL. */ @@ -3347,8 +3682,8 @@ gimple_eh_must_not_throw_fndecl (gimple gs) static inline void gimple_eh_must_not_throw_set_fndecl (gimple gs, tree decl) { - GIMPLE_CHECK (gs, GIMPLE_EH_MUST_NOT_THROW); - gs->gimple_eh_mnt.fndecl = decl; + gimple_statement_eh_mnt *eh_mnt_stmt = as_a <gimple_statement_eh_mnt> (gs); + eh_mnt_stmt->fndecl = decl; } /* GIMPLE_EH_ELSE accessors. */ @@ -3356,8 +3691,9 @@ gimple_eh_must_not_throw_set_fndecl (gimple gs, tree decl) static inline gimple_seq * gimple_eh_else_n_body_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_ELSE); - return &gs->gimple_eh_else.n_body; + gimple_statement_eh_else *eh_else_stmt = + as_a <gimple_statement_eh_else> (gs); + return &eh_else_stmt->n_body; } static inline gimple_seq @@ -3369,8 +3705,9 @@ gimple_eh_else_n_body (gimple gs) static inline gimple_seq * gimple_eh_else_e_body_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_ELSE); - return &gs->gimple_eh_else.e_body; + gimple_statement_eh_else *eh_else_stmt = + as_a <gimple_statement_eh_else> (gs); + return &eh_else_stmt->e_body; } static inline gimple_seq @@ -3382,15 +3719,17 @@ gimple_eh_else_e_body (gimple gs) static inline void gimple_eh_else_set_n_body (gimple gs, gimple_seq seq) { - GIMPLE_CHECK (gs, GIMPLE_EH_ELSE); - gs->gimple_eh_else.n_body = seq; + gimple_statement_eh_else *eh_else_stmt = + as_a <gimple_statement_eh_else> (gs); + eh_else_stmt->n_body = seq; } static inline void gimple_eh_else_set_e_body (gimple gs, gimple_seq seq) { - GIMPLE_CHECK (gs, GIMPLE_EH_ELSE); - gs->gimple_eh_else.e_body = seq; + gimple_statement_eh_else *eh_else_stmt = + as_a <gimple_statement_eh_else> (gs); + eh_else_stmt->e_body = seq; } /* GIMPLE_TRY accessors. */ @@ -3402,7 +3741,7 @@ static inline enum gimple_try_flags gimple_try_kind (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_TRY); - return (enum gimple_try_flags) (gs->gsbase.subcode & GIMPLE_TRY_KIND); + return (enum gimple_try_flags) (gs->subcode & GIMPLE_TRY_KIND); } @@ -3415,7 +3754,7 @@ gimple_try_set_kind (gimple gs, enum gimple_try_flags kind) gcc_gimple_checking_assert (kind == GIMPLE_TRY_CATCH || kind == GIMPLE_TRY_FINALLY); if (gimple_try_kind (gs) != kind) - gs->gsbase.subcode = (unsigned int) kind; + gs->subcode = (unsigned int) kind; } @@ -3425,7 +3764,7 @@ static inline bool gimple_try_catch_is_cleanup (const_gimple gs) { gcc_gimple_checking_assert (gimple_try_kind (gs) == GIMPLE_TRY_CATCH); - return (gs->gsbase.subcode & GIMPLE_TRY_CATCH_IS_CLEANUP) != 0; + return (gs->subcode & GIMPLE_TRY_CATCH_IS_CLEANUP) != 0; } @@ -3435,8 +3774,8 @@ gimple_try_catch_is_cleanup (const_gimple gs) static inline gimple_seq * gimple_try_eval_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_TRY); - return &gs->gimple_try.eval; + gimple_statement_try *try_stmt = as_a <gimple_statement_try> (gs); + return &try_stmt->eval; } @@ -3455,8 +3794,8 @@ gimple_try_eval (gimple gs) static inline gimple_seq * gimple_try_cleanup_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_TRY); - return &gs->gimple_try.cleanup; + gimple_statement_try *try_stmt = as_a <gimple_statement_try> (gs); + return &try_stmt->cleanup; } @@ -3477,9 +3816,9 @@ gimple_try_set_catch_is_cleanup (gimple g, bool catch_is_cleanup) { gcc_gimple_checking_assert (gimple_try_kind (g) == GIMPLE_TRY_CATCH); if (catch_is_cleanup) - g->gsbase.subcode |= GIMPLE_TRY_CATCH_IS_CLEANUP; + g->subcode |= GIMPLE_TRY_CATCH_IS_CLEANUP; else - g->gsbase.subcode &= ~GIMPLE_TRY_CATCH_IS_CLEANUP; + g->subcode &= ~GIMPLE_TRY_CATCH_IS_CLEANUP; } @@ -3489,8 +3828,8 @@ gimple_try_set_catch_is_cleanup (gimple g, bool catch_is_cleanup) static inline void gimple_try_set_eval (gimple gs, gimple_seq eval) { - GIMPLE_CHECK (gs, GIMPLE_TRY); - gs->gimple_try.eval = eval; + gimple_statement_try *try_stmt = as_a <gimple_statement_try> (gs); + try_stmt->eval = eval; } @@ -3500,8 +3839,8 @@ gimple_try_set_eval (gimple gs, gimple_seq eval) static inline void gimple_try_set_cleanup (gimple gs, gimple_seq cleanup) { - GIMPLE_CHECK (gs, GIMPLE_TRY); - gs->gimple_try.cleanup = cleanup; + gimple_statement_try *try_stmt = as_a <gimple_statement_try> (gs); + try_stmt->cleanup = cleanup; } @@ -3510,8 +3849,8 @@ gimple_try_set_cleanup (gimple gs, gimple_seq cleanup) static inline gimple_seq * gimple_wce_cleanup_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR); - return &gs->gimple_wce.cleanup; + gimple_statement_wce *wce_stmt = as_a <gimple_statement_wce> (gs); + return &wce_stmt->cleanup; } @@ -3529,8 +3868,8 @@ gimple_wce_cleanup (gimple gs) static inline void gimple_wce_set_cleanup (gimple gs, gimple_seq cleanup) { - GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR); - gs->gimple_wce.cleanup = cleanup; + gimple_statement_wce *wce_stmt = as_a <gimple_statement_wce> (gs); + wce_stmt->cleanup = cleanup; } @@ -3540,7 +3879,7 @@ static inline bool gimple_wce_cleanup_eh_only (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR); - return gs->gsbase.subcode != 0; + return gs->subcode != 0; } @@ -3550,7 +3889,7 @@ static inline void gimple_wce_set_cleanup_eh_only (gimple gs, bool eh_only_p) { GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR); - gs->gsbase.subcode = (unsigned int) eh_only_p; + gs->subcode = (unsigned int) eh_only_p; } @@ -3559,8 +3898,9 @@ gimple_wce_set_cleanup_eh_only (gimple gs, bool eh_only_p) static inline unsigned gimple_phi_capacity (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - return gs->gimple_phi.capacity; + const gimple_statement_phi *phi_stmt = + as_a <const gimple_statement_phi> (gs); + return phi_stmt->capacity; } @@ -3571,8 +3911,9 @@ gimple_phi_capacity (const_gimple gs) static inline unsigned gimple_phi_num_args (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - return gs->gimple_phi.nargs; + const gimple_statement_phi *phi_stmt = + as_a <const gimple_statement_phi> (gs); + return phi_stmt->nargs; } @@ -3581,8 +3922,9 @@ gimple_phi_num_args (const_gimple gs) static inline tree gimple_phi_result (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - return gs->gimple_phi.result; + const gimple_statement_phi *phi_stmt = + as_a <const gimple_statement_phi> (gs); + return phi_stmt->result; } /* Return a pointer to the SSA name created by GIMPLE_PHI GS. */ @@ -3590,8 +3932,8 @@ gimple_phi_result (const_gimple gs) static inline tree * gimple_phi_result_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - return &gs->gimple_phi.result; + gimple_statement_phi *phi_stmt = as_a <gimple_statement_phi> (gs); + return &phi_stmt->result; } /* Set RESULT to be the SSA name created by GIMPLE_PHI GS. */ @@ -3599,8 +3941,8 @@ gimple_phi_result_ptr (gimple gs) static inline void gimple_phi_set_result (gimple gs, tree result) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - gs->gimple_phi.result = result; + gimple_statement_phi *phi_stmt = as_a <gimple_statement_phi> (gs); + phi_stmt->result = result; if (result && TREE_CODE (result) == SSA_NAME) SSA_NAME_DEF_STMT (result) = gs; } @@ -3612,9 +3954,9 @@ gimple_phi_set_result (gimple gs, tree result) static inline struct phi_arg_d * gimple_phi_arg (gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - gcc_gimple_checking_assert (index <= gs->gimple_phi.capacity); - return &(gs->gimple_phi.args[index]); + gimple_statement_phi *phi_stmt = as_a <gimple_statement_phi> (gs); + gcc_gimple_checking_assert (index <= phi_stmt->capacity); + return &(phi_stmt->args[index]); } /* Set PHIARG to be the argument corresponding to incoming edge INDEX @@ -3623,9 +3965,9 @@ gimple_phi_arg (gimple gs, unsigned index) static inline void gimple_phi_set_arg (gimple gs, unsigned index, struct phi_arg_d * phiarg) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - gcc_gimple_checking_assert (index <= gs->gimple_phi.nargs); - gs->gimple_phi.args[index] = *phiarg; + gimple_statement_phi *phi_stmt = as_a <gimple_statement_phi> (gs); + gcc_gimple_checking_assert (index <= phi_stmt->nargs); + phi_stmt->args[index] = *phiarg; } /* PHI nodes should contain only ssa_names and invariants. A test @@ -3723,8 +4065,9 @@ gimple_phi_arg_has_location (gimple gs, size_t i) static inline int gimple_resx_region (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_RESX); - return gs->gimple_eh_ctrl.region; + const gimple_statement_eh_ctrl *eh_ctrl_stmt = + as_a <const gimple_statement_eh_ctrl> (gs); + return eh_ctrl_stmt->region; } /* Set REGION to be the region number for GIMPLE_RESX GS. */ @@ -3732,8 +4075,9 @@ gimple_resx_region (const_gimple gs) static inline void gimple_resx_set_region (gimple gs, int region) { - GIMPLE_CHECK (gs, GIMPLE_RESX); - gs->gimple_eh_ctrl.region = region; + gimple_statement_eh_ctrl *eh_ctrl_stmt = + as_a <gimple_statement_eh_ctrl> (gs); + eh_ctrl_stmt->region = region; } /* Return the region number for GIMPLE_EH_DISPATCH GS. */ @@ -3741,8 +4085,9 @@ gimple_resx_set_region (gimple gs, int region) static inline int gimple_eh_dispatch_region (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_DISPATCH); - return gs->gimple_eh_ctrl.region; + const gimple_statement_eh_ctrl *eh_ctrl_stmt = + as_a <const gimple_statement_eh_ctrl> (gs); + return eh_ctrl_stmt->region; } /* Set REGION to be the region number for GIMPLE_EH_DISPATCH GS. */ @@ -3750,8 +4095,9 @@ gimple_eh_dispatch_region (const_gimple gs) static inline void gimple_eh_dispatch_set_region (gimple gs, int region) { - GIMPLE_CHECK (gs, GIMPLE_EH_DISPATCH); - gs->gimple_eh_ctrl.region = region; + gimple_statement_eh_ctrl *eh_ctrl_stmt = + as_a <gimple_statement_eh_ctrl> (gs); + eh_ctrl_stmt->region = region; } /* Return the number of labels associated with the switch statement GS. */ @@ -3864,7 +4210,7 @@ static inline bool gimple_debug_bind_p (const_gimple s) { if (is_gimple_debug (s)) - return s->gsbase.subcode == GIMPLE_DEBUG_BIND; + return s->subcode == GIMPLE_DEBUG_BIND; return false; } @@ -3956,7 +4302,7 @@ static inline bool gimple_debug_source_bind_p (const_gimple s) { if (is_gimple_debug (s)) - return s->gsbase.subcode == GIMPLE_DEBUG_SOURCE_BIND; + return s->subcode == GIMPLE_DEBUG_SOURCE_BIND; return false; } @@ -4061,8 +4407,9 @@ gimple_omp_set_body (gimple gs, gimple_seq body) static inline tree gimple_omp_critical_name (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_CRITICAL); - return gs->gimple_omp_critical.name; + const gimple_statement_omp_critical *omp_critical_stmt = + as_a <const gimple_statement_omp_critical> (gs); + return omp_critical_stmt->name; } @@ -4071,8 +4418,9 @@ gimple_omp_critical_name (const_gimple gs) static inline tree * gimple_omp_critical_name_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_CRITICAL); - return &gs->gimple_omp_critical.name; + gimple_statement_omp_critical *omp_critical_stmt = + as_a <gimple_statement_omp_critical> (gs); + return &omp_critical_stmt->name; } @@ -4081,8 +4429,9 @@ gimple_omp_critical_name_ptr (gimple gs) static inline void gimple_omp_critical_set_name (gimple gs, tree name) { - GIMPLE_CHECK (gs, GIMPLE_OMP_CRITICAL); - gs->gimple_omp_critical.name = name; + gimple_statement_omp_critical *omp_critical_stmt = + as_a <gimple_statement_omp_critical> (gs); + omp_critical_stmt->name = name; } @@ -4102,7 +4451,7 @@ static inline void gimple_omp_for_set_kind (gimple g, int kind) { GIMPLE_CHECK (g, GIMPLE_OMP_FOR); - g->gsbase.subcode = (g->gsbase.subcode & ~GF_OMP_FOR_KIND_MASK) + g->subcode = (g->subcode & ~GF_OMP_FOR_KIND_MASK) | (kind & GF_OMP_FOR_KIND_MASK); } @@ -4126,9 +4475,9 @@ gimple_omp_for_set_combined_p (gimple g, bool combined_p) { GIMPLE_CHECK (g, GIMPLE_OMP_FOR); if (combined_p) - g->gsbase.subcode |= GF_OMP_FOR_COMBINED; + g->subcode |= GF_OMP_FOR_COMBINED; else - g->gsbase.subcode &= ~GF_OMP_FOR_COMBINED; + g->subcode &= ~GF_OMP_FOR_COMBINED; } @@ -4151,9 +4500,9 @@ gimple_omp_for_set_combined_into_p (gimple g, bool combined_p) { GIMPLE_CHECK (g, GIMPLE_OMP_FOR); if (combined_p) - g->gsbase.subcode |= GF_OMP_FOR_COMBINED_INTO; + g->subcode |= GF_OMP_FOR_COMBINED_INTO; else - g->gsbase.subcode &= ~GF_OMP_FOR_COMBINED_INTO; + g->subcode &= ~GF_OMP_FOR_COMBINED_INTO; } @@ -4162,8 +4511,9 @@ gimple_omp_for_set_combined_into_p (gimple g, bool combined_p) static inline tree gimple_omp_for_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - return gs->gimple_omp_for.clauses; + const gimple_statement_omp_for *omp_for_stmt = + as_a <const gimple_statement_omp_for> (gs); + return omp_for_stmt->clauses; } @@ -4172,8 +4522,9 @@ gimple_omp_for_clauses (const_gimple gs) static inline tree * gimple_omp_for_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - return &gs->gimple_omp_for.clauses; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + return &omp_for_stmt->clauses; } @@ -4182,8 +4533,9 @@ gimple_omp_for_clauses_ptr (gimple gs) static inline void gimple_omp_for_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gs->gimple_omp_for.clauses = clauses; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + omp_for_stmt->clauses = clauses; } @@ -4192,8 +4544,9 @@ gimple_omp_for_set_clauses (gimple gs, tree clauses) static inline size_t gimple_omp_for_collapse (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - return gs->gimple_omp_for.collapse; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + return omp_for_stmt->collapse; } @@ -4202,9 +4555,10 @@ gimple_omp_for_collapse (gimple gs) static inline tree gimple_omp_for_index (const_gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return gs->gimple_omp_for.iter[i].index; + const gimple_statement_omp_for *omp_for_stmt = + as_a <const gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return omp_for_stmt->iter[i].index; } @@ -4213,9 +4567,10 @@ gimple_omp_for_index (const_gimple gs, size_t i) static inline tree * gimple_omp_for_index_ptr (gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return &gs->gimple_omp_for.iter[i].index; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return &omp_for_stmt->iter[i].index; } @@ -4224,9 +4579,10 @@ gimple_omp_for_index_ptr (gimple gs, size_t i) static inline void gimple_omp_for_set_index (gimple gs, size_t i, tree index) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - gs->gimple_omp_for.iter[i].index = index; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + omp_for_stmt->iter[i].index = index; } @@ -4235,9 +4591,10 @@ gimple_omp_for_set_index (gimple gs, size_t i, tree index) static inline tree gimple_omp_for_initial (const_gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return gs->gimple_omp_for.iter[i].initial; + const gimple_statement_omp_for *omp_for_stmt = + as_a <const gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return omp_for_stmt->iter[i].initial; } @@ -4246,9 +4603,10 @@ gimple_omp_for_initial (const_gimple gs, size_t i) static inline tree * gimple_omp_for_initial_ptr (gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return &gs->gimple_omp_for.iter[i].initial; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return &omp_for_stmt->iter[i].initial; } @@ -4257,9 +4615,10 @@ gimple_omp_for_initial_ptr (gimple gs, size_t i) static inline void gimple_omp_for_set_initial (gimple gs, size_t i, tree initial) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - gs->gimple_omp_for.iter[i].initial = initial; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + omp_for_stmt->iter[i].initial = initial; } @@ -4268,9 +4627,10 @@ gimple_omp_for_set_initial (gimple gs, size_t i, tree initial) static inline tree gimple_omp_for_final (const_gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return gs->gimple_omp_for.iter[i].final; + const gimple_statement_omp_for *omp_for_stmt = + as_a <const gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return omp_for_stmt->iter[i].final; } @@ -4279,9 +4639,10 @@ gimple_omp_for_final (const_gimple gs, size_t i) static inline tree * gimple_omp_for_final_ptr (gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return &gs->gimple_omp_for.iter[i].final; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return &omp_for_stmt->iter[i].final; } @@ -4290,9 +4651,10 @@ gimple_omp_for_final_ptr (gimple gs, size_t i) static inline void gimple_omp_for_set_final (gimple gs, size_t i, tree final) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - gs->gimple_omp_for.iter[i].final = final; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + omp_for_stmt->iter[i].final = final; } @@ -4301,9 +4663,10 @@ gimple_omp_for_set_final (gimple gs, size_t i, tree final) static inline tree gimple_omp_for_incr (const_gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return gs->gimple_omp_for.iter[i].incr; + const gimple_statement_omp_for *omp_for_stmt = + as_a <const gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return omp_for_stmt->iter[i].incr; } @@ -4312,9 +4675,10 @@ gimple_omp_for_incr (const_gimple gs, size_t i) static inline tree * gimple_omp_for_incr_ptr (gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return &gs->gimple_omp_for.iter[i].incr; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return &omp_for_stmt->iter[i].incr; } @@ -4323,9 +4687,10 @@ gimple_omp_for_incr_ptr (gimple gs, size_t i) static inline void gimple_omp_for_set_incr (gimple gs, size_t i, tree incr) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - gs->gimple_omp_for.iter[i].incr = incr; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + omp_for_stmt->iter[i].incr = incr; } @@ -4335,8 +4700,9 @@ gimple_omp_for_set_incr (gimple gs, size_t i, tree incr) static inline gimple_seq * gimple_omp_for_pre_body_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - return &gs->gimple_omp_for.pre_body; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + return &omp_for_stmt->pre_body; } @@ -4356,8 +4722,9 @@ gimple_omp_for_pre_body (gimple gs) static inline void gimple_omp_for_set_pre_body (gimple gs, gimple_seq pre_body) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gs->gimple_omp_for.pre_body = pre_body; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + omp_for_stmt->pre_body = pre_body; } @@ -4366,8 +4733,9 @@ gimple_omp_for_set_pre_body (gimple gs, gimple_seq pre_body) static inline tree gimple_omp_parallel_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - return gs->gimple_omp_parallel.clauses; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->clauses; } @@ -4376,8 +4744,9 @@ gimple_omp_parallel_clauses (const_gimple gs) static inline tree * gimple_omp_parallel_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - return &gs->gimple_omp_parallel.clauses; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->clauses; } @@ -4387,8 +4756,9 @@ gimple_omp_parallel_clauses_ptr (gimple gs) static inline void gimple_omp_parallel_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - gs->gimple_omp_parallel.clauses = clauses; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->clauses = clauses; } @@ -4397,8 +4767,9 @@ gimple_omp_parallel_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_parallel_child_fn (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - return gs->gimple_omp_parallel.child_fn; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->child_fn; } /* Return a pointer to the child function used to hold the body of @@ -4407,8 +4778,9 @@ gimple_omp_parallel_child_fn (const_gimple gs) static inline tree * gimple_omp_parallel_child_fn_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - return &gs->gimple_omp_parallel.child_fn; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->child_fn; } @@ -4417,8 +4789,9 @@ gimple_omp_parallel_child_fn_ptr (gimple gs) static inline void gimple_omp_parallel_set_child_fn (gimple gs, tree child_fn) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - gs->gimple_omp_parallel.child_fn = child_fn; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->child_fn = child_fn; } @@ -4428,8 +4801,9 @@ gimple_omp_parallel_set_child_fn (gimple gs, tree child_fn) static inline tree gimple_omp_parallel_data_arg (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - return gs->gimple_omp_parallel.data_arg; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->data_arg; } @@ -4438,8 +4812,9 @@ gimple_omp_parallel_data_arg (const_gimple gs) static inline tree * gimple_omp_parallel_data_arg_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - return &gs->gimple_omp_parallel.data_arg; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->data_arg; } @@ -4448,8 +4823,9 @@ gimple_omp_parallel_data_arg_ptr (gimple gs) static inline void gimple_omp_parallel_set_data_arg (gimple gs, tree data_arg) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - gs->gimple_omp_parallel.data_arg = data_arg; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->data_arg = data_arg; } @@ -4458,8 +4834,9 @@ gimple_omp_parallel_set_data_arg (gimple gs, tree data_arg) static inline tree gimple_omp_task_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_parallel.clauses; + const gimple_statement_omp_task *omp_task_stmt = + as_a <const gimple_statement_omp_task> (gs); + return omp_task_stmt->clauses; } @@ -4468,8 +4845,9 @@ gimple_omp_task_clauses (const_gimple gs) static inline tree * gimple_omp_task_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_parallel.clauses; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + return &omp_task_stmt->clauses; } @@ -4479,8 +4857,9 @@ gimple_omp_task_clauses_ptr (gimple gs) static inline void gimple_omp_task_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_parallel.clauses = clauses; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + omp_task_stmt->clauses = clauses; } @@ -4489,8 +4868,9 @@ gimple_omp_task_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_task_child_fn (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_parallel.child_fn; + const gimple_statement_omp_task *omp_task_stmt = + as_a <const gimple_statement_omp_task> (gs); + return omp_task_stmt->child_fn; } /* Return a pointer to the child function used to hold the body of @@ -4499,8 +4879,9 @@ gimple_omp_task_child_fn (const_gimple gs) static inline tree * gimple_omp_task_child_fn_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_parallel.child_fn; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + return &omp_task_stmt->child_fn; } @@ -4509,8 +4890,9 @@ gimple_omp_task_child_fn_ptr (gimple gs) static inline void gimple_omp_task_set_child_fn (gimple gs, tree child_fn) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_parallel.child_fn = child_fn; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + omp_task_stmt->child_fn = child_fn; } @@ -4520,8 +4902,9 @@ gimple_omp_task_set_child_fn (gimple gs, tree child_fn) static inline tree gimple_omp_task_data_arg (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_parallel.data_arg; + const gimple_statement_omp_task *omp_task_stmt = + as_a <const gimple_statement_omp_task> (gs); + return omp_task_stmt->data_arg; } @@ -4530,8 +4913,9 @@ gimple_omp_task_data_arg (const_gimple gs) static inline tree * gimple_omp_task_data_arg_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_parallel.data_arg; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + return &omp_task_stmt->data_arg; } @@ -4540,8 +4924,9 @@ gimple_omp_task_data_arg_ptr (gimple gs) static inline void gimple_omp_task_set_data_arg (gimple gs, tree data_arg) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_parallel.data_arg = data_arg; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + omp_task_stmt->data_arg = data_arg; } @@ -4550,9 +4935,9 @@ gimple_omp_task_set_data_arg (gimple gs, tree data_arg) static inline tree gimple_omp_taskreg_clauses (const_gimple gs) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_parallel.clauses; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->clauses; } @@ -4561,9 +4946,9 @@ gimple_omp_taskreg_clauses (const_gimple gs) static inline tree * gimple_omp_taskreg_clauses_ptr (gimple gs) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_parallel.clauses; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->clauses; } @@ -4573,9 +4958,9 @@ gimple_omp_taskreg_clauses_ptr (gimple gs) static inline void gimple_omp_taskreg_set_clauses (gimple gs, tree clauses) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_parallel.clauses = clauses; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->clauses = clauses; } @@ -4584,9 +4969,9 @@ gimple_omp_taskreg_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_taskreg_child_fn (const_gimple gs) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_parallel.child_fn; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->child_fn; } /* Return a pointer to the child function used to hold the body of @@ -4595,9 +4980,9 @@ gimple_omp_taskreg_child_fn (const_gimple gs) static inline tree * gimple_omp_taskreg_child_fn_ptr (gimple gs) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_parallel.child_fn; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->child_fn; } @@ -4606,9 +4991,9 @@ gimple_omp_taskreg_child_fn_ptr (gimple gs) static inline void gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_parallel.child_fn = child_fn; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->child_fn = child_fn; } @@ -4618,9 +5003,9 @@ gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn) static inline tree gimple_omp_taskreg_data_arg (const_gimple gs) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_parallel.data_arg; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->data_arg; } @@ -4629,9 +5014,9 @@ gimple_omp_taskreg_data_arg (const_gimple gs) static inline tree * gimple_omp_taskreg_data_arg_ptr (gimple gs) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_parallel.data_arg; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->data_arg; } @@ -4640,9 +5025,9 @@ gimple_omp_taskreg_data_arg_ptr (gimple gs) static inline void gimple_omp_taskreg_set_data_arg (gimple gs, tree data_arg) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_parallel.data_arg = data_arg; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->data_arg = data_arg; } @@ -4651,8 +5036,9 @@ gimple_omp_taskreg_set_data_arg (gimple gs, tree data_arg) static inline tree gimple_omp_task_copy_fn (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_task.copy_fn; + const gimple_statement_omp_task *omp_task_stmt = + as_a <const gimple_statement_omp_task> (gs); + return omp_task_stmt->copy_fn; } /* Return a pointer to the copy function used to hold the body of @@ -4661,8 +5047,9 @@ gimple_omp_task_copy_fn (const_gimple gs) static inline tree * gimple_omp_task_copy_fn_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_task.copy_fn; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + return &omp_task_stmt->copy_fn; } @@ -4671,8 +5058,9 @@ gimple_omp_task_copy_fn_ptr (gimple gs) static inline void gimple_omp_task_set_copy_fn (gimple gs, tree copy_fn) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_task.copy_fn = copy_fn; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + omp_task_stmt->copy_fn = copy_fn; } @@ -4681,8 +5069,9 @@ gimple_omp_task_set_copy_fn (gimple gs, tree copy_fn) static inline tree gimple_omp_task_arg_size (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_task.arg_size; + const gimple_statement_omp_task *omp_task_stmt = + as_a <const gimple_statement_omp_task> (gs); + return omp_task_stmt->arg_size; } @@ -4691,8 +5080,9 @@ gimple_omp_task_arg_size (const_gimple gs) static inline tree * gimple_omp_task_arg_size_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_task.arg_size; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + return &omp_task_stmt->arg_size; } @@ -4701,8 +5091,9 @@ gimple_omp_task_arg_size_ptr (gimple gs) static inline void gimple_omp_task_set_arg_size (gimple gs, tree arg_size) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_task.arg_size = arg_size; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + omp_task_stmt->arg_size = arg_size; } @@ -4711,8 +5102,9 @@ gimple_omp_task_set_arg_size (gimple gs, tree arg_size) static inline tree gimple_omp_task_arg_align (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_task.arg_align; + const gimple_statement_omp_task *omp_task_stmt = + as_a <const gimple_statement_omp_task> (gs); + return omp_task_stmt->arg_align; } @@ -4721,8 +5113,9 @@ gimple_omp_task_arg_align (const_gimple gs) static inline tree * gimple_omp_task_arg_align_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_task.arg_align; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + return &omp_task_stmt->arg_align; } @@ -4731,8 +5124,9 @@ gimple_omp_task_arg_align_ptr (gimple gs) static inline void gimple_omp_task_set_arg_align (gimple gs, tree arg_align) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_task.arg_align = arg_align; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + omp_task_stmt->arg_align = arg_align; } @@ -4741,8 +5135,9 @@ gimple_omp_task_set_arg_align (gimple gs, tree arg_align) static inline tree gimple_omp_single_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SINGLE); - return gs->gimple_omp_single.clauses; + const gimple_statement_omp_single *omp_single_stmt = + as_a <const gimple_statement_omp_single> (gs); + return omp_single_stmt->clauses; } @@ -4751,8 +5146,9 @@ gimple_omp_single_clauses (const_gimple gs) static inline tree * gimple_omp_single_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SINGLE); - return &gs->gimple_omp_single.clauses; + gimple_statement_omp_single *omp_single_stmt = + as_a <gimple_statement_omp_single> (gs); + return &omp_single_stmt->clauses; } @@ -4761,8 +5157,9 @@ gimple_omp_single_clauses_ptr (gimple gs) static inline void gimple_omp_single_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SINGLE); - gs->gimple_omp_single.clauses = clauses; + gimple_statement_omp_single *omp_single_stmt = + as_a <gimple_statement_omp_single> (gs); + omp_single_stmt->clauses = clauses; } @@ -4771,8 +5168,9 @@ gimple_omp_single_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_target_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - return gs->gimple_omp_parallel.clauses; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->clauses; } @@ -4781,8 +5179,9 @@ gimple_omp_target_clauses (const_gimple gs) static inline tree * gimple_omp_target_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - return &gs->gimple_omp_parallel.clauses; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->clauses; } @@ -4791,8 +5190,9 @@ gimple_omp_target_clauses_ptr (gimple gs) static inline void gimple_omp_target_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - gs->gimple_omp_parallel.clauses = clauses; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->clauses = clauses; } @@ -4812,7 +5212,7 @@ static inline void gimple_omp_target_set_kind (gimple g, int kind) { GIMPLE_CHECK (g, GIMPLE_OMP_TARGET); - g->gsbase.subcode = (g->gsbase.subcode & ~GF_OMP_TARGET_KIND_MASK) + g->subcode = (g->subcode & ~GF_OMP_TARGET_KIND_MASK) | (kind & GF_OMP_TARGET_KIND_MASK); } @@ -4822,8 +5222,9 @@ gimple_omp_target_set_kind (gimple g, int kind) static inline tree gimple_omp_target_child_fn (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - return gs->gimple_omp_parallel.child_fn; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->child_fn; } /* Return a pointer to the child function used to hold the body of @@ -4832,8 +5233,9 @@ gimple_omp_target_child_fn (const_gimple gs) static inline tree * gimple_omp_target_child_fn_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - return &gs->gimple_omp_parallel.child_fn; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->child_fn; } @@ -4842,8 +5244,9 @@ gimple_omp_target_child_fn_ptr (gimple gs) static inline void gimple_omp_target_set_child_fn (gimple gs, tree child_fn) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - gs->gimple_omp_parallel.child_fn = child_fn; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->child_fn = child_fn; } @@ -4853,8 +5256,9 @@ gimple_omp_target_set_child_fn (gimple gs, tree child_fn) static inline tree gimple_omp_target_data_arg (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - return gs->gimple_omp_parallel.data_arg; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->data_arg; } @@ -4863,8 +5267,9 @@ gimple_omp_target_data_arg (const_gimple gs) static inline tree * gimple_omp_target_data_arg_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - return &gs->gimple_omp_parallel.data_arg; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->data_arg; } @@ -4873,8 +5278,9 @@ gimple_omp_target_data_arg_ptr (gimple gs) static inline void gimple_omp_target_set_data_arg (gimple gs, tree data_arg) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - gs->gimple_omp_parallel.data_arg = data_arg; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->data_arg = data_arg; } @@ -4883,8 +5289,9 @@ gimple_omp_target_set_data_arg (gimple gs, tree data_arg) static inline tree gimple_omp_teams_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TEAMS); - return gs->gimple_omp_single.clauses; + const gimple_statement_omp_single *omp_single_stmt = + as_a <const gimple_statement_omp_single> (gs); + return omp_single_stmt->clauses; } @@ -4893,8 +5300,9 @@ gimple_omp_teams_clauses (const_gimple gs) static inline tree * gimple_omp_teams_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TEAMS); - return &gs->gimple_omp_single.clauses; + gimple_statement_omp_single *omp_single_stmt = + as_a <gimple_statement_omp_single> (gs); + return &omp_single_stmt->clauses; } @@ -4903,8 +5311,9 @@ gimple_omp_teams_clauses_ptr (gimple gs) static inline void gimple_omp_teams_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TEAMS); - gs->gimple_omp_single.clauses = clauses; + gimple_statement_omp_single *omp_single_stmt = + as_a <gimple_statement_omp_single> (gs); + omp_single_stmt->clauses = clauses; } @@ -4913,8 +5322,9 @@ gimple_omp_teams_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_sections_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); - return gs->gimple_omp_sections.clauses; + const gimple_statement_omp_sections *omp_sections_stmt = + as_a <const gimple_statement_omp_sections> (gs); + return omp_sections_stmt->clauses; } @@ -4923,8 +5333,9 @@ gimple_omp_sections_clauses (const_gimple gs) static inline tree * gimple_omp_sections_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); - return &gs->gimple_omp_sections.clauses; + gimple_statement_omp_sections *omp_sections_stmt = + as_a <gimple_statement_omp_sections> (gs); + return &omp_sections_stmt->clauses; } @@ -4934,8 +5345,9 @@ gimple_omp_sections_clauses_ptr (gimple gs) static inline void gimple_omp_sections_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); - gs->gimple_omp_sections.clauses = clauses; + gimple_statement_omp_sections *omp_sections_stmt = + as_a <gimple_statement_omp_sections> (gs); + omp_sections_stmt->clauses = clauses; } @@ -4945,8 +5357,9 @@ gimple_omp_sections_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_sections_control (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); - return gs->gimple_omp_sections.control; + const gimple_statement_omp_sections *omp_sections_stmt = + as_a <const gimple_statement_omp_sections> (gs); + return omp_sections_stmt->control; } @@ -4956,8 +5369,9 @@ gimple_omp_sections_control (const_gimple gs) static inline tree * gimple_omp_sections_control_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); - return &gs->gimple_omp_sections.control; + gimple_statement_omp_sections *omp_sections_stmt = + as_a <gimple_statement_omp_sections> (gs); + return &omp_sections_stmt->control; } @@ -4967,8 +5381,9 @@ gimple_omp_sections_control_ptr (gimple gs) static inline void gimple_omp_sections_set_control (gimple gs, tree control) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); - gs->gimple_omp_sections.control = control; + gimple_statement_omp_sections *omp_sections_stmt = + as_a <gimple_statement_omp_sections> (gs); + omp_sections_stmt->control = control; } @@ -4977,10 +5392,11 @@ gimple_omp_sections_set_control (gimple gs, tree control) static inline void gimple_omp_for_set_cond (gimple gs, size_t i, enum tree_code cond) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); gcc_gimple_checking_assert (TREE_CODE_CLASS (cond) == tcc_comparison - && i < gs->gimple_omp_for.collapse); - gs->gimple_omp_for.iter[i].cond = cond; + && i < omp_for_stmt->collapse); + omp_for_stmt->iter[i].cond = cond; } @@ -4989,9 +5405,10 @@ gimple_omp_for_set_cond (gimple gs, size_t i, enum tree_code cond) static inline enum tree_code gimple_omp_for_cond (const_gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return gs->gimple_omp_for.iter[i].cond; + const gimple_statement_omp_for *omp_for_stmt = + as_a <const gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return omp_for_stmt->iter[i].cond; } @@ -5000,8 +5417,9 @@ gimple_omp_for_cond (const_gimple gs, size_t i) static inline void gimple_omp_atomic_store_set_val (gimple g, tree val) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); - g->gimple_omp_atomic_store.val = val; + gimple_statement_omp_atomic_store *omp_atomic_store_stmt = + as_a <gimple_statement_omp_atomic_store> (g); + omp_atomic_store_stmt->val = val; } @@ -5010,8 +5428,9 @@ gimple_omp_atomic_store_set_val (gimple g, tree val) static inline tree gimple_omp_atomic_store_val (const_gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); - return g->gimple_omp_atomic_store.val; + const gimple_statement_omp_atomic_store *omp_atomic_store_stmt = + as_a <const gimple_statement_omp_atomic_store> (g); + return omp_atomic_store_stmt->val; } @@ -5020,8 +5439,9 @@ gimple_omp_atomic_store_val (const_gimple g) static inline tree * gimple_omp_atomic_store_val_ptr (gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); - return &g->gimple_omp_atomic_store.val; + gimple_statement_omp_atomic_store *omp_atomic_store_stmt = + as_a <gimple_statement_omp_atomic_store> (g); + return &omp_atomic_store_stmt->val; } @@ -5030,8 +5450,9 @@ gimple_omp_atomic_store_val_ptr (gimple g) static inline void gimple_omp_atomic_load_set_lhs (gimple g, tree lhs) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); - g->gimple_omp_atomic_load.lhs = lhs; + gimple_statement_omp_atomic_load *omp_atomic_load_stmt = + as_a <gimple_statement_omp_atomic_load> (g); + omp_atomic_load_stmt->lhs = lhs; } @@ -5040,8 +5461,9 @@ gimple_omp_atomic_load_set_lhs (gimple g, tree lhs) static inline tree gimple_omp_atomic_load_lhs (const_gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); - return g->gimple_omp_atomic_load.lhs; + const gimple_statement_omp_atomic_load *omp_atomic_load_stmt = + as_a <const gimple_statement_omp_atomic_load> (g); + return omp_atomic_load_stmt->lhs; } @@ -5050,8 +5472,9 @@ gimple_omp_atomic_load_lhs (const_gimple g) static inline tree * gimple_omp_atomic_load_lhs_ptr (gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); - return &g->gimple_omp_atomic_load.lhs; + gimple_statement_omp_atomic_load *omp_atomic_load_stmt = + as_a <gimple_statement_omp_atomic_load> (g); + return &omp_atomic_load_stmt->lhs; } @@ -5060,8 +5483,9 @@ gimple_omp_atomic_load_lhs_ptr (gimple g) static inline void gimple_omp_atomic_load_set_rhs (gimple g, tree rhs) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); - g->gimple_omp_atomic_load.rhs = rhs; + gimple_statement_omp_atomic_load *omp_atomic_load_stmt = + as_a <gimple_statement_omp_atomic_load> (g); + omp_atomic_load_stmt->rhs = rhs; } @@ -5070,8 +5494,9 @@ gimple_omp_atomic_load_set_rhs (gimple g, tree rhs) static inline tree gimple_omp_atomic_load_rhs (const_gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); - return g->gimple_omp_atomic_load.rhs; + const gimple_statement_omp_atomic_load *omp_atomic_load_stmt = + as_a <const gimple_statement_omp_atomic_load> (g); + return omp_atomic_load_stmt->rhs; } @@ -5080,8 +5505,9 @@ gimple_omp_atomic_load_rhs (const_gimple g) static inline tree * gimple_omp_atomic_load_rhs_ptr (gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); - return &g->gimple_omp_atomic_load.rhs; + gimple_statement_omp_atomic_load *omp_atomic_load_stmt = + as_a <gimple_statement_omp_atomic_load> (g); + return &omp_atomic_load_stmt->rhs; } @@ -5090,8 +5516,9 @@ gimple_omp_atomic_load_rhs_ptr (gimple g) static inline tree gimple_omp_continue_control_def (const_gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); - return g->gimple_omp_continue.control_def; + const gimple_statement_omp_continue *omp_continue_stmt = + as_a <const gimple_statement_omp_continue> (g); + return omp_continue_stmt->control_def; } /* The same as above, but return the address. */ @@ -5099,8 +5526,9 @@ gimple_omp_continue_control_def (const_gimple g) static inline tree * gimple_omp_continue_control_def_ptr (gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); - return &g->gimple_omp_continue.control_def; + gimple_statement_omp_continue *omp_continue_stmt = + as_a <gimple_statement_omp_continue> (g); + return &omp_continue_stmt->control_def; } /* Set the definition of the control variable in a GIMPLE_OMP_CONTINUE. */ @@ -5108,8 +5536,9 @@ gimple_omp_continue_control_def_ptr (gimple g) static inline void gimple_omp_continue_set_control_def (gimple g, tree def) { - GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); - g->gimple_omp_continue.control_def = def; + gimple_statement_omp_continue *omp_continue_stmt = + as_a <gimple_statement_omp_continue> (g); + omp_continue_stmt->control_def = def; } @@ -5118,8 +5547,9 @@ gimple_omp_continue_set_control_def (gimple g, tree def) static inline tree gimple_omp_continue_control_use (const_gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); - return g->gimple_omp_continue.control_use; + const gimple_statement_omp_continue *omp_continue_stmt = + as_a <const gimple_statement_omp_continue> (g); + return omp_continue_stmt->control_use; } @@ -5128,8 +5558,9 @@ gimple_omp_continue_control_use (const_gimple g) static inline tree * gimple_omp_continue_control_use_ptr (gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); - return &g->gimple_omp_continue.control_use; + gimple_statement_omp_continue *omp_continue_stmt = + as_a <gimple_statement_omp_continue> (g); + return &omp_continue_stmt->control_use; } @@ -5138,8 +5569,9 @@ gimple_omp_continue_control_use_ptr (gimple g) static inline void gimple_omp_continue_set_control_use (gimple g, tree use) { - GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); - g->gimple_omp_continue.control_use = use; + gimple_statement_omp_continue *omp_continue_stmt = + as_a <gimple_statement_omp_continue> (g); + omp_continue_stmt->control_use = use; } /* Return a pointer to the body for the GIMPLE_TRANSACTION statement GS. */ @@ -5147,8 +5579,9 @@ gimple_omp_continue_set_control_use (gimple g, tree use) static inline gimple_seq * gimple_transaction_body_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - return &gs->gimple_transaction.body; + gimple_statement_transaction *transaction_stmt = + as_a <gimple_statement_transaction> (gs); + return &transaction_stmt->body; } /* Return the body for the GIMPLE_TRANSACTION statement GS. */ @@ -5164,15 +5597,17 @@ gimple_transaction_body (gimple gs) static inline tree gimple_transaction_label (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - return gs->gimple_transaction.label; + const gimple_statement_transaction *transaction_stmt = + as_a <const gimple_statement_transaction> (gs); + return transaction_stmt->label; } static inline tree * gimple_transaction_label_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - return &gs->gimple_transaction.label; + gimple_statement_transaction *transaction_stmt = + as_a <gimple_statement_transaction> (gs); + return &transaction_stmt->label; } /* Return the subcode associated with a GIMPLE_TRANSACTION. */ @@ -5181,7 +5616,7 @@ static inline unsigned int gimple_transaction_subcode (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - return gs->gsbase.subcode; + return gs->subcode; } /* Set BODY to be the body for the GIMPLE_TRANSACTION statement GS. */ @@ -5189,8 +5624,9 @@ gimple_transaction_subcode (const_gimple gs) static inline void gimple_transaction_set_body (gimple gs, gimple_seq body) { - GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - gs->gimple_transaction.body = body; + gimple_statement_transaction *transaction_stmt = + as_a <gimple_statement_transaction> (gs); + transaction_stmt->body = body; } /* Set the label associated with a GIMPLE_TRANSACTION. */ @@ -5198,8 +5634,9 @@ gimple_transaction_set_body (gimple gs, gimple_seq body) static inline void gimple_transaction_set_label (gimple gs, tree label) { - GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - gs->gimple_transaction.label = label; + gimple_statement_transaction *transaction_stmt = + as_a <gimple_statement_transaction> (gs); + transaction_stmt->label = label; } /* Set the subcode associated with a GIMPLE_TRANSACTION. */ @@ -5208,7 +5645,7 @@ static inline void gimple_transaction_set_subcode (gimple gs, unsigned int subcode) { GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - gs->gsbase.subcode = subcode; + gs->subcode = subcode; } @@ -5318,7 +5755,7 @@ static inline enum br_predictor gimple_predict_predictor (gimple gs) { GIMPLE_CHECK (gs, GIMPLE_PREDICT); - return (enum br_predictor) (gs->gsbase.subcode & ~GF_PREDICT_TAKEN); + return (enum br_predictor) (gs->subcode & ~GF_PREDICT_TAKEN); } @@ -5328,7 +5765,7 @@ static inline void gimple_predict_set_predictor (gimple gs, enum br_predictor predictor) { GIMPLE_CHECK (gs, GIMPLE_PREDICT); - gs->gsbase.subcode = (gs->gsbase.subcode & GF_PREDICT_TAKEN) + gs->subcode = (gs->subcode & GF_PREDICT_TAKEN) | (unsigned) predictor; } @@ -5339,7 +5776,7 @@ static inline enum prediction gimple_predict_outcome (gimple gs) { GIMPLE_CHECK (gs, GIMPLE_PREDICT); - return (gs->gsbase.subcode & GF_PREDICT_TAKEN) ? TAKEN : NOT_TAKEN; + return (gs->subcode & GF_PREDICT_TAKEN) ? TAKEN : NOT_TAKEN; } @@ -5350,9 +5787,9 @@ gimple_predict_set_outcome (gimple gs, enum prediction outcome) { GIMPLE_CHECK (gs, GIMPLE_PREDICT); if (outcome == TAKEN) - gs->gsbase.subcode |= GF_PREDICT_TAKEN; + gs->subcode |= GF_PREDICT_TAKEN; else - gs->gsbase.subcode &= ~GF_PREDICT_TAKEN; + gs->subcode &= ~GF_PREDICT_TAKEN; } @@ -5491,7 +5928,7 @@ gsi_end_p (gimple_stmt_iterator i) static inline bool gsi_one_before_end_p (gimple_stmt_iterator i) { - return i.ptr != NULL && i.ptr->gsbase.next == NULL; + return i.ptr != NULL && i.ptr->next == NULL; } @@ -5500,7 +5937,7 @@ gsi_one_before_end_p (gimple_stmt_iterator i) static inline void gsi_next (gimple_stmt_iterator *i) { - i->ptr = i->ptr->gsbase.next; + i->ptr = i->ptr->next; } /* Advance the iterator to the previous gimple statement. */ @@ -5508,8 +5945,8 @@ gsi_next (gimple_stmt_iterator *i) static inline void gsi_prev (gimple_stmt_iterator *i) { - gimple prev = i->ptr->gsbase.prev; - if (prev->gsbase.next) + gimple prev = i->ptr->prev; + if (prev->next) i->ptr = prev; else i->ptr = NULL; diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 74f333b..a600d3c 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -2586,7 +2586,7 @@ copy_debug_stmt (gimple stmt, copy_body_data *id) && TREE_CODE ((**debug_args)[i + 1]) == DEBUG_EXPR_DECL) { t = (**debug_args)[i + 1]; - stmt->gsbase.subcode = GIMPLE_DEBUG_BIND; + stmt->subcode = GIMPLE_DEBUG_BIND; gimple_debug_bind_set_value (stmt, t); break; } diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c index 2cef1c4..65c636c 100644 --- a/gcc/tree-phinodes.c +++ b/gcc/tree-phinodes.c @@ -183,7 +183,7 @@ make_phi_node (tree var, int len) memset (phi, 0, (sizeof (struct gimple_statement_phi) - sizeof (struct phi_arg_d) + sizeof (struct phi_arg_d) * len)); - phi->gsbase.code = GIMPLE_PHI; + phi->code = GIMPLE_PHI; gimple_init_singleton (phi); phi->gimple_phi.nargs = len; phi->gimple_phi.capacity = capacity; -- 1.7.11.7 ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance 2013-10-31 16:31 ` [PATCH 3/6] Automated part of conversion of gimple types to use " David Malcolm @ 2013-11-14 9:43 ` Jeff Law 2013-11-18 22:17 ` [PATCH] Updated automated patch (was Re: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance) David Malcolm 0 siblings, 1 reply; 116+ messages in thread From: Jeff Law @ 2013-11-14 9:43 UTC (permalink / raw) To: David Malcolm, gcc-patches, Andrew MacLeod On 10/31/13 10:26, David Malcolm wrote: > gcc/ > > Patch autogenerated by refactor_gimple.py from > https://github.com/davidmalcolm/gcc-refactoring-scripts > revision 74cd3d5f06565c318749d0fb9f35b565dae28daa [ ... ] This is fine with the usual conditions. diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c > index e430050..ed0d6df 100644 > --- a/gcc/gimple-iterator.c > +++ b/gcc/gimple-iterator.c > @@ -67,7 +67,7 @@ update_bb_for_stmts (gimple_seq_node first, gimple_seq_node last, > { > gimple_seq_node n; > > - for (n = first; n; n = n->gsbase.next) > + for (n = first; n; n = n->next) So just a quite note. If I'm reading this corectly, this should make things marginally easier in the debugger when looking at objects? It drives me absolutely nuts having to figure out how to get through the base class to the fields I care about. I didn't look at every hunk in this patch carefully. Just spot checked thigns. > } > > /* Set the nowait flag on OMP_RETURN statement S. */ > @@ -1661,7 +1973,7 @@ static inline void > gimple_omp_return_set_nowait (gimple s) > { > GIMPLE_CHECK (s, GIMPLE_OMP_RETURN); > - s->gsbase.subcode |= GF_OMP_RETURN_NOWAIT; > + s->subcode |= GF_OMP_RETURN_NOWAIT; So is there some reason the GIMPLE_CHECK was left in here rather than doing the downcasting? This happens in other places. > } > > > @@ -1681,8 +1993,9 @@ gimple_omp_return_nowait_p (const_gimple g) > static inline void > gimple_omp_return_set_lhs (gimple g, tree lhs) > { > - GIMPLE_CHECK (g, GIMPLE_OMP_RETURN); > - g->gimple_omp_atomic_store.val = lhs; > + gimple_statement_omp_atomic_store *omp_atomic_store_stmt = > + as_a <gimple_statement_omp_atomic_store> (g); > + omp_atomic_store_stmt->val = lhs; Contrast to prior hunk. This one, AFAICT elimates the GIMPLE_CHECK here and does it as part of the downcasting, right? I wonder how far we have to go with this before GIMPLE_CHECK goes away :-) > > @@ -1723,7 +2038,7 @@ static inline void > gimple_omp_section_set_last (gimple g) > { > GIMPLE_CHECK (g, GIMPLE_OMP_SECTION); > - g->gsbase.subcode |= GF_OMP_SECTION_LAST; > + g->subcode |= GF_OMP_SECTION_LAST; Another example of the GIMPLE_CHECK hanging around. On purpose? > } > > > @@ -1746,9 +2061,9 @@ gimple_omp_parallel_set_combined_p (gimple g, bool combined_p) > { > GIMPLE_CHECK (g, GIMPLE_OMP_PARALLEL); > if (combined_p) > - g->gsbase.subcode |= GF_OMP_PARALLEL_COMBINED; > + g->subcode |= GF_OMP_PARALLEL_COMBINED; > else > - g->gsbase.subcode &= ~GF_OMP_PARALLEL_COMBINED; > + g->subcode &= ~GF_OMP_PARALLEL_COMBINED; Likewise. > } > > > @@ -1771,7 +2086,7 @@ gimple_omp_atomic_set_need_value (gimple g) > { > if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD) > GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); > - g->gsbase.subcode |= GF_OMP_ATOMIC_NEED_VALUE; > + g->subcode |= GF_OMP_ATOMIC_NEED_VALUE; Likewise. And so-on. I don't see anything objectionable. Just want to make sure the script and/or the by-hand stuff didn't miss some of the conversions. Jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* [PATCH] Updated automated patch (was Re: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance) 2013-11-14 9:43 ` Jeff Law @ 2013-11-18 22:17 ` David Malcolm 2013-11-19 8:49 ` Jeff Law 2013-11-22 0:27 ` Jakub Jelinek 0 siblings, 2 replies; 116+ messages in thread From: David Malcolm @ 2013-11-18 22:17 UTC (permalink / raw) To: Jeff Law; +Cc: gcc-patches, Andrew MacLeod [-- Attachment #1: Type: text/plain, Size: 6622 bytes --] On Thu, 2013-11-14 at 00:48 -0700, Jeff Law wrote: > On 10/31/13 10:26, David Malcolm wrote: > > gcc/ > > > > Patch autogenerated by refactor_gimple.py from > > https://github.com/davidmalcolm/gcc-refactoring-scripts > > revision 74cd3d5f06565c318749d0fb9f35b565dae28daa > [ ... ] > This is fine with the usual conditions. This patch has bitrotten somewhat against trunk due to the reorganization of gimple.h and related headers. I regenerated it and am bootstrapping now. I glanced over it and nothing major seems to have changed; just changes due to the movement of code between files. Am attaching the changed patch. > diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c > > index e430050..ed0d6df 100644 > > --- a/gcc/gimple-iterator.c > > +++ b/gcc/gimple-iterator.c > > @@ -67,7 +67,7 @@ update_bb_for_stmts (gimple_seq_node first, gimple_seq_node last, > > { > > gimple_seq_node n; > > > > - for (n = first; n; n = n->gsbase.next) > > + for (n = first; n; n = n->next) > So just a quite note. If I'm reading this corectly, this should make > things marginally easier in the debugger when looking at objects? It > drives me absolutely nuts having to figure out how to get through the > base class to the fields I care about. I think so, yes, though you'll have to cast it to the appropriate subclass by hand; rather than the status quo of getting multiple screenfuls of text, you'll just get the gimple_statement_base fields: (gdb) p stmt $9 = <gimple_assign 0x7ffff0450000> (gdb) p *(gimple_statement_with_memory_ops*)stmt $10 = {<gimple_statement_with_memory_ops_base> = {<gimple_statement_with_ops_base> = {<gimple_statement_base> = {code = GIMPLE_ASSIGN, no_warning = 0, visited = 0, nontemporal_move = 0, plf = 1, modified = 0, has_volatile_ops = 0, subcode = 67, uid = 0, location = 2147483648, num_ops = 3, bb = <basic_block 0x7ffff042a1a0 (2)>, next = <gimple 0x0>, prev = <gimple_assign 0x7ffff0450000>}, use_ops = 0x7ffff0452008}, vdef = <tree 0x0>, vuse = <tree 0x0>}, op = {0x7ffff030acf0}} This would clearly be nicer with the followup of having an (empty) subclass for assignments, so that one could do: (gdb) p *(gimple_statement_assign*)stmt We may be able to automate printing the appropriate subclass in gdbhooks.py > I didn't look at every hunk in this patch carefully. Just spot checked > thigns. > > > > } > > > > /* Set the nowait flag on OMP_RETURN statement S. */ > > @@ -1661,7 +1973,7 @@ static inline void > > gimple_omp_return_set_nowait (gimple s) > > { > > GIMPLE_CHECK (s, GIMPLE_OMP_RETURN); > > - s->gsbase.subcode |= GF_OMP_RETURN_NOWAIT; > > + s->subcode |= GF_OMP_RETURN_NOWAIT; > So is there some reason the GIMPLE_CHECK was left in here rather than > doing the downcasting? This happens in other places. The script isn't particularly smart, and here it's only removing the "->gsbase." part. It doesn't automatically remove GIMPLE_CHECK uses: it only introduces a downcast if it needs to, and given that this accessor only pokes at base class things it didn't. Hence the existing typechecking is preserved. I want to convert accessors like this into taking a subclass ptr, hence it could eventually become: gimple_omp_return_set_nowait (gimple_omp_return *s) (there are only two uses of it in the tree) and at that point, the GIMPLE_CHECK can be removed (with the type-checking enforced at compile time). > > @@ -1681,8 +1993,9 @@ gimple_omp_return_nowait_p (const_gimple g) > > static inline void > > gimple_omp_return_set_lhs (gimple g, tree lhs) > > { > > - GIMPLE_CHECK (g, GIMPLE_OMP_RETURN); > > - g->gimple_omp_atomic_store.val = lhs; > > + gimple_statement_omp_atomic_store *omp_atomic_store_stmt = > > + as_a <gimple_statement_omp_atomic_store> (g); > > + omp_atomic_store_stmt->val = lhs; > Contrast to prior hunk. This one, AFAICT elimates the GIMPLE_CHECK here > and does it as part of the downcasting, right? Yes: this accessor make use of fields of the subclass: specifically the val within the omp_atomic_store, and hence needs to do the checked downcast ("as_a"). Given that as_a performs equivalent runtime checking to GIMPLE_CHECK, I opted for the script to remove the GIMPLE_CHECK in such cases. > I wonder how far we have to go with this before GIMPLE_CHECK goes away :-) > > > > > @@ -1723,7 +2038,7 @@ static inline void > > gimple_omp_section_set_last (gimple g) > > { > > GIMPLE_CHECK (g, GIMPLE_OMP_SECTION); > > - g->gsbase.subcode |= GF_OMP_SECTION_LAST; > > + g->subcode |= GF_OMP_SECTION_LAST; > Another example of the GIMPLE_CHECK hanging around. On purpose? Again, given that we only poke at "subcode", no as_a is needed, and hence the script keeps the GIMPLE_CHECK. FWIW, this particular accessor is only used in one place (omp-low.c:lower_omp_sections). > > > > @@ -1746,9 +2061,9 @@ gimple_omp_parallel_set_combined_p (gimple g, bool combined_p) > > { > > GIMPLE_CHECK (g, GIMPLE_OMP_PARALLEL); > > if (combined_p) > > - g->gsbase.subcode |= GF_OMP_PARALLEL_COMBINED; > > + g->subcode |= GF_OMP_PARALLEL_COMBINED; > > else > > - g->gsbase.subcode &= ~GF_OMP_PARALLEL_COMBINED; > > + g->subcode &= ~GF_OMP_PARALLEL_COMBINED; > Likewise. ...and again, this one only pokes at "subcode", which is in the base class. Likewise, this accessor is only used in one place (omp-low.c:lower_omp_taskreg), and could be changed in a followup to accept a gimple_omp_parallel *, dropping the GIMPLE_CHECK. > > @@ -1771,7 +2086,7 @@ gimple_omp_atomic_set_need_value (gimple g) > > { > > if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD) > > GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); > > - g->gsbase.subcode |= GF_OMP_ATOMIC_NEED_VALUE; > > + g->subcode |= GF_OMP_ATOMIC_NEED_VALUE; > Likewise. ...likewise this only looks at subcode and hence doesn't need a downcast. It's used in 2 places, both within gimplify_omp_atomic, both of which can trivially be converted to work on subclass ptrs (the statements in question come directly from gimple_build_omp_atomice_{load|store} calls). > And so-on. > > I don't see anything objectionable. Just want to make sure the script > and/or the by-hand stuff didn't miss some of the conversions. Thanks. I'm attaching the regenerated patch. As noted above, I believe that the only changes are due to functions moving between source files; specifically the move of the following from gimple.h to gimple-iterator.h (quoting the ChangeLog): * gimple-iterator.h (gsi_one_before_end_p): Likewise. (gsi_next): Likewise. (gsi_prev): Likewise. OK for trunk? [-- Attachment #2: 0003-Automated-part-of-conversion-of-gimple-types-to-use-.patch --] [-- Type: text/x-patch, Size: 121671 bytes --] From fe6d5759f00da73ed2d1f62e520bc7ba3f6669c6 Mon Sep 17 00:00:00 2001 From: David Malcolm <dmalcolm@redhat.com> Date: Mon, 18 Nov 2013 11:53:57 -0500 Subject: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance gcc/ Patch autogenerated by refactor_gimple.py from https://github.com/davidmalcolm/gcc-refactoring-scripts revision 05fc808c61bd8ddd2372f29b79ceb2491360d298 * gimple-iterator.c (update_bb_for_stmts): Update for conversion of gimple types to a true class hierarchy. (update_call_edge_frequencies): Likewise. (gsi_insert_seq_nodes_before): Likewise. (gsi_insert_seq_nodes_after): Likewise. (gsi_split_seq_after): Likewise. (gsi_set_stmt): Likewise. (gsi_split_seq_before): Likewise. (gsi_remove): Likewise. * gimple-iterator.h (gsi_one_before_end_p): Likewise. (gsi_next): Likewise. (gsi_prev): Likewise. * gimple-pretty-print.c (dump_gimple_debug): Likewise. * gimple-ssa.h (gimple_vuse_op): Likewise. (gimple_vdef_op): Likewise. * gimple-streamer-in.c (input_gimple_stmt): Likewise. * gimple-streamer-out.c (output_gimple_stmt): Likewise. * gimple.c (gimple_set_code): Likewise. (gimple_alloc_stat): Likewise. (gimple_set_subcode): Likewise. (gimple_build_call_internal_1): Likewise. (gimple_check_failed): Likewise. (gimple_call_flags): Likewise. (gimple_set_bb): Likewise. * gimple.h (is_a_helper <gimple_statement_asm> (gimple)): New. (is_a_helper <gimple_statement_bind> (gimple)): Likewise. (is_a_helper <gimple_statement_call> (gimple)): Likewise. (is_a_helper <gimple_statement_catch> (gimple)): Likewise. (is_a_helper <gimple_statement_eh_ctrl> (gimple)): Likewise. (is_a_helper <gimple_statement_eh_else> (gimple)): Likewise. (is_a_helper <gimple_statement_eh_filter> (gimple)): Likewise. (is_a_helper <gimple_statement_eh_mnt> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_atomic_load> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_atomic_store> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_continue> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_critical> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_for> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_parallel> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_sections> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_single> (gimple)): Likewise. (is_a_helper <gimple_statement_omp_task> (gimple)): Likewise. (is_a_helper <gimple_statement_phi> (gimple)): Likewise. (is_a_helper <gimple_statement_transaction> (gimple)): Likewise. (is_a_helper <gimple_statement_try> (gimple)): Likewise. (is_a_helper <gimple_statement_wce> (gimple)): Likewise. (is_a_helper <const gimple_statement_asm> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_bind> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_call> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_catch> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_eh_ctrl> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_eh_filter> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_atomic_load> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_atomic_store> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_continue> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_critical> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_for> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_parallel> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_sections> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_single> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_omp_task> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_phi> (const_gimple)): Likewise. (is_a_helper <const gimple_statement_transaction> (const_gimple)): Likewise. (gimple_seq_last): Update for conversion of gimple types to a true class hierarchy. (gimple_seq_set_last): Likewise. (gimple_code): Likewise. (gimple_bb): Likewise. (gimple_block): Likewise. (gimple_set_block): Likewise. (gimple_location): Likewise. (gimple_location_ptr): Likewise. (gimple_set_location): Likewise. (gimple_no_warning_p): Likewise. (gimple_set_no_warning): Likewise. (gimple_set_visited): Likewise. (gimple_visited_p): Likewise. (gimple_set_plf): Likewise. (gimple_plf): Likewise. (gimple_set_uid): Likewise. (gimple_uid): Likewise. (gimple_init_singleton): Likewise. (gimple_modified_p): Likewise. (gimple_set_modified): Likewise. (gimple_expr_code): Likewise. (gimple_has_volatile_ops): Likewise. (gimple_set_has_volatile_ops): Likewise. (gimple_omp_subcode): Likewise. (gimple_omp_set_subcode): Likewise. (gimple_omp_return_set_nowait): Likewise. (gimple_omp_section_set_last): Likewise. (gimple_omp_parallel_set_combined_p): Likewise. (gimple_omp_atomic_set_need_value): Likewise. (gimple_omp_atomic_set_seq_cst): Likewise. (gimple_num_ops): Likewise. (gimple_set_num_ops): Likewise. (gimple_assign_nontemporal_move_p): Likewise. (gimple_assign_set_nontemporal_move): Likewise. (gimple_assign_rhs_code): Likewise. (gimple_assign_set_rhs_code): Likewise. (gimple_call_internal_p): Likewise. (gimple_call_with_bounds_p): Likewise. (gimple_call_set_with_bounds): Likewise. (gimple_call_set_tail): Likewise. (gimple_call_tail_p): Likewise. (gimple_call_set_return_slot_opt): Likewise. (gimple_call_return_slot_opt_p): Likewise. (gimple_call_set_from_thunk): Likewise. (gimple_call_from_thunk_p): Likewise. (gimple_call_set_va_arg_pack): Likewise. (gimple_call_va_arg_pack_p): Likewise. (gimple_call_set_nothrow): Likewise. (gimple_call_set_alloca_for_var): Likewise. (gimple_call_alloca_for_var_p): Likewise. (gimple_call_copy_flags): Likewise. (gimple_cond_code): Likewise. (gimple_cond_set_code): Likewise. (gimple_cond_make_false): Likewise. (gimple_cond_make_true): Likewise. (gimple_asm_volatile_p): Likewise. (gimple_asm_set_volatile): Likewise. (gimple_asm_set_input): Likewise. (gimple_asm_input_p): Likewise. (gimple_try_kind): Likewise. (gimple_try_set_kind): Likewise. (gimple_try_catch_is_cleanup): Likewise. (gimple_try_set_catch_is_cleanup): Likewise. (gimple_wce_cleanup_eh_only): Likewise. (gimple_wce_set_cleanup_eh_only): Likewise. (gimple_debug_bind_p): Likewise. (gimple_debug_source_bind_p): Likewise. (gimple_omp_for_set_kind): Likewise. (gimple_omp_for_set_combined_p): Likewise. (gimple_omp_for_set_combined_into_p): Likewise. (gimple_omp_target_set_kind): Likewise. (gimple_transaction_subcode): Likewise. (gimple_transaction_set_subcode): Likewise. (gimple_predict_predictor): Likewise. (gimple_predict_set_predictor): Likewise. (gimple_predict_outcome): Likewise. (gimple_predict_set_outcome): Likewise. (gimple_transaction_set_label): Likewise. (gimple_transaction_set_body): Likewise. (gimple_transaction_label_ptr): Likewise. (gimple_transaction_label): Likewise. (gimple_transaction_body_ptr): Likewise. (gimple_omp_continue_set_control_use): Likewise. (gimple_omp_continue_control_use_ptr): Likewise. (gimple_omp_continue_control_use): Likewise. (gimple_omp_continue_set_control_def): Likewise. (gimple_omp_continue_control_def_ptr): Likewise. (gimple_omp_continue_control_def): Likewise. (gimple_omp_atomic_load_rhs_ptr): Likewise. (gimple_omp_atomic_load_rhs): Likewise. (gimple_omp_atomic_load_set_rhs): Likewise. (gimple_omp_atomic_load_lhs_ptr): Likewise. (gimple_omp_atomic_load_lhs): Likewise. (gimple_omp_atomic_load_set_lhs): Likewise. (gimple_omp_atomic_store_val_ptr): Likewise. (gimple_omp_atomic_store_val): Likewise. (gimple_omp_atomic_store_set_val): Likewise. (gimple_omp_for_cond): Likewise. (gimple_omp_for_set_cond): Likewise. (gimple_omp_sections_set_control): Likewise. (gimple_omp_sections_control_ptr): Likewise. (gimple_omp_sections_control): Likewise. (gimple_omp_sections_set_clauses): Likewise. (gimple_omp_sections_clauses_ptr): Likewise. (gimple_omp_sections_clauses): Likewise. (gimple_omp_teams_set_clauses): Likewise. (gimple_omp_teams_clauses_ptr): Likewise. (gimple_omp_teams_clauses): Likewise. (gimple_omp_target_set_data_arg): Likewise. (gimple_omp_target_data_arg_ptr): Likewise. (gimple_omp_target_data_arg): Likewise. (gimple_omp_target_set_child_fn): Likewise. (gimple_omp_target_child_fn_ptr): Likewise. (gimple_omp_target_child_fn): Likewise. (gimple_omp_target_set_clauses): Likewise. (gimple_omp_target_clauses_ptr): Likewise. (gimple_omp_target_clauses): Likewise. (gimple_omp_single_set_clauses): Likewise. (gimple_omp_single_clauses_ptr): Likewise. (gimple_omp_single_clauses): Likewise. (gimple_omp_task_set_arg_align): Likewise. (gimple_omp_task_arg_align_ptr): Likewise. (gimple_omp_task_arg_align): Likewise. (gimple_omp_task_set_arg_size): Likewise. (gimple_omp_task_arg_size_ptr): Likewise. (gimple_omp_task_arg_size): Likewise. (gimple_omp_task_set_copy_fn): Likewise. (gimple_omp_task_copy_fn_ptr): Likewise. (gimple_omp_task_copy_fn): Likewise. (gimple_omp_task_set_data_arg): Likewise. (gimple_omp_task_data_arg_ptr): Likewise. (gimple_omp_task_data_arg): Likewise. (gimple_omp_task_set_child_fn): Likewise. (gimple_omp_task_child_fn_ptr): Likewise. (gimple_omp_task_child_fn): Likewise. (gimple_omp_task_set_clauses): Likewise. (gimple_omp_task_clauses_ptr): Likewise. (gimple_omp_task_clauses): Likewise. (gimple_omp_parallel_set_data_arg): Likewise. (gimple_omp_parallel_data_arg_ptr): Likewise. (gimple_omp_parallel_data_arg): Likewise. (gimple_omp_parallel_set_child_fn): Likewise. (gimple_omp_parallel_child_fn_ptr): Likewise. (gimple_omp_parallel_child_fn): Likewise. (gimple_omp_parallel_set_clauses): Likewise. (gimple_omp_parallel_clauses_ptr): Likewise. (gimple_omp_parallel_clauses): Likewise. (gimple_omp_for_set_pre_body): Likewise. (gimple_omp_for_pre_body_ptr): Likewise. (gimple_omp_for_set_incr): Likewise. (gimple_omp_for_incr_ptr): Likewise. (gimple_omp_for_incr): Likewise. (gimple_omp_for_set_final): Likewise. (gimple_omp_for_final_ptr): Likewise. (gimple_omp_for_final): Likewise. (gimple_omp_for_set_initial): Likewise. (gimple_omp_for_initial_ptr): Likewise. (gimple_omp_for_initial): Likewise. (gimple_omp_for_set_index): Likewise. (gimple_omp_for_index_ptr): Likewise. (gimple_omp_for_index): Likewise. (gimple_omp_for_collapse): Likewise. (gimple_omp_for_set_clauses): Likewise. (gimple_omp_for_clauses_ptr): Likewise. (gimple_omp_for_clauses): Likewise. (gimple_omp_critical_set_name): Likewise. (gimple_omp_critical_name_ptr): Likewise. (gimple_omp_critical_name): Likewise. (gimple_eh_dispatch_set_region): Likewise. (gimple_eh_dispatch_region): Likewise. (gimple_resx_set_region): Likewise. (gimple_resx_region): Likewise. (gimple_phi_set_arg): Likewise. (gimple_phi_arg): Likewise. (gimple_phi_set_result): Likewise. (gimple_phi_result_ptr): Likewise. (gimple_phi_result): Likewise. (gimple_phi_num_args): Likewise. (gimple_phi_capacity): Likewise. (gimple_wce_set_cleanup): Likewise. (gimple_wce_cleanup_ptr): Likewise. (gimple_try_set_cleanup): Likewise. (gimple_try_set_eval): Likewise. (gimple_try_cleanup_ptr): Likewise. (gimple_try_eval_ptr): Likewise. (gimple_eh_else_set_e_body): Likewise. (gimple_eh_else_set_n_body): Likewise. (gimple_eh_else_e_body_ptr): Likewise. (gimple_eh_else_n_body_ptr): Likewise. (gimple_eh_must_not_throw_set_fndecl): Likewise. (gimple_eh_must_not_throw_fndecl): Likewise. (gimple_eh_filter_set_failure): Likewise. (gimple_eh_filter_set_types): Likewise. (gimple_eh_filter_failure_ptr): Likewise. (gimple_eh_filter_types_ptr): Likewise. (gimple_eh_filter_types): Likewise. (gimple_catch_set_handler): Likewise. (gimple_catch_set_types): Likewise. (gimple_catch_handler_ptr): Likewise. (gimple_catch_types_ptr): Likewise. (gimple_catch_types): Likewise. (gimple_asm_string): Likewise. (gimple_asm_set_label_op): Likewise. (gimple_asm_label_op): Likewise. (gimple_asm_set_clobber_op): Likewise. (gimple_asm_clobber_op): Likewise. (gimple_asm_set_output_op): Likewise. (gimple_asm_output_op_ptr): Likewise. (gimple_asm_output_op): Likewise. (gimple_asm_set_input_op): Likewise. (gimple_asm_input_op_ptr): Likewise. (gimple_asm_input_op): Likewise. (gimple_asm_nlabels): Likewise. (gimple_asm_nclobbers): Likewise. (gimple_asm_noutputs): Likewise. (gimple_asm_ninputs): Likewise. (gimple_bind_set_block): Likewise. (gimple_bind_block): Likewise. (gimple_bind_add_seq): Likewise. (gimple_bind_add_stmt): Likewise. (gimple_bind_set_body): Likewise. (gimple_bind_body_ptr): Likewise. (gimple_bind_append_vars): Likewise. (gimple_bind_set_vars): Likewise. (gimple_bind_vars): Likewise. (gimple_call_clobber_set): Likewise. (gimple_call_use_set): Likewise. (gimple_call_set_internal_fn): Likewise. (gimple_call_set_fntype): Likewise. (gimple_call_fntype): Likewise. (gimple_omp_return_lhs_ptr): Likewise. (gimple_omp_return_lhs): Likewise. (gimple_omp_return_set_lhs): Likewise. (gimple_omp_taskreg_set_data_arg): Likewise. (gimple_omp_taskreg_data_arg_ptr): Likewise. (gimple_omp_taskreg_data_arg): Likewise. (gimple_omp_taskreg_set_child_fn): Likewise. (gimple_omp_taskreg_child_fn_ptr): Likewise. (gimple_omp_taskreg_child_fn): Likewise. (gimple_omp_taskreg_set_clauses): Likewise. (gimple_omp_taskreg_clauses_ptr): Likewise. (gimple_omp_taskreg_clauses): Likewise. (gimple_vuse): Likewise. (gimple_vdef): Likewise. (gimple_vuse_ptr): Likewise. (gimple_vdef_ptr): Likewise. * tree-inline.c (copy_debug_stmt): Likewise. * tree-phinodes.c (make_phi_node): Likewise. --- gcc/gimple-iterator.c | 72 +-- gcc/gimple-iterator.h | 8 +- gcc/gimple-pretty-print.c | 2 +- gcc/gimple-ssa.h | 16 +- gcc/gimple-streamer-in.c | 8 +- gcc/gimple-streamer-out.c | 2 +- gcc/gimple.c | 16 +- gcc/gimple.h | 1367 ++++++++++++++++++++++++++++++--------------- gcc/tree-inline.c | 2 +- gcc/tree-phinodes.c | 2 +- 10 files changed, 968 insertions(+), 527 deletions(-) diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c index b945389..557bf35 100644 --- a/gcc/gimple-iterator.c +++ b/gcc/gimple-iterator.c @@ -68,7 +68,7 @@ update_bb_for_stmts (gimple_seq_node first, gimple_seq_node last, { gimple_seq_node n; - for (n = first; n; n = n->gsbase.next) + for (n = first; n; n = n->next) { gimple_set_bb (n, bb); if (n == last) @@ -86,7 +86,7 @@ update_call_edge_frequencies (gimple_seq_node first, basic_block bb) int bb_freq = 0; gimple_seq_node n; - for (n = first; n ; n = n->gsbase.next) + for (n = first; n ; n = n->next) if (is_gimple_call (n)) { struct cgraph_edge *e; @@ -124,7 +124,7 @@ gsi_insert_seq_nodes_before (gimple_stmt_iterator *i, basic_block bb; gimple_seq_node cur = i->ptr; - gcc_assert (!cur || cur->gsbase.prev); + gcc_assert (!cur || cur->prev); if ((bb = gsi_bb (*i)) != NULL) update_bb_for_stmts (first, last, bb); @@ -132,13 +132,13 @@ gsi_insert_seq_nodes_before (gimple_stmt_iterator *i, /* Link SEQ before CUR in the sequence. */ if (cur) { - first->gsbase.prev = cur->gsbase.prev; - if (first->gsbase.prev->gsbase.next) - first->gsbase.prev->gsbase.next = first; + first->prev = cur->prev; + if (first->prev->next) + first->prev->next = first; else gimple_seq_set_first (i->seq, first); - last->gsbase.next = cur; - cur->gsbase.prev = last; + last->next = cur; + cur->prev = last; } else { @@ -149,11 +149,11 @@ gsi_insert_seq_nodes_before (gimple_stmt_iterator *i, labels, so it returns an iterator after the end of the block, and we need to insert before it; it might be cleaner to add a flag to the iterator saying whether we are at the start or end of the list). */ - last->gsbase.next = NULL; + last->next = NULL; if (itlast) { - first->gsbase.prev = itlast; - itlast->gsbase.next = first; + first->prev = itlast; + itlast->next = first; } else gimple_seq_set_first (i->seq, first); @@ -242,7 +242,7 @@ gsi_insert_seq_nodes_after (gimple_stmt_iterator *i, basic_block bb; gimple_seq_node cur = i->ptr; - gcc_assert (!cur || cur->gsbase.prev); + gcc_assert (!cur || cur->prev); /* If the iterator is inside a basic block, we need to update the basic block information for all the nodes between FIRST and LAST. */ @@ -252,20 +252,20 @@ gsi_insert_seq_nodes_after (gimple_stmt_iterator *i, /* Link SEQ after CUR. */ if (cur) { - last->gsbase.next = cur->gsbase.next; - if (last->gsbase.next) + last->next = cur->next; + if (last->next) { - last->gsbase.next->gsbase.prev = last; + last->next->prev = last; } else gimple_seq_set_last (i->seq, last); - first->gsbase.prev = cur; - cur->gsbase.next = first; + first->prev = cur; + cur->next = first; } else { gcc_assert (!gimple_seq_last (*i->seq)); - last->gsbase.next = NULL; + last->next = NULL; gimple_seq_set_first (i->seq, first); gimple_seq_set_last (i->seq, last); } @@ -347,15 +347,15 @@ gsi_split_seq_after (gimple_stmt_iterator i) cur = i.ptr; /* How can we possibly split after the end, or before the beginning? */ - gcc_assert (cur && cur->gsbase.next); - next = cur->gsbase.next; + gcc_assert (cur && cur->next); + next = cur->next; pold_seq = i.seq; gimple_seq_set_first (&new_seq, next); gimple_seq_set_last (&new_seq, gimple_seq_last (*pold_seq)); gimple_seq_set_last (pold_seq, cur); - cur->gsbase.next = NULL; + cur->next = NULL; return new_seq; } @@ -371,17 +371,17 @@ gsi_set_stmt (gimple_stmt_iterator *gsi, gimple stmt) gimple orig_stmt = gsi_stmt (*gsi); gimple prev, next; - stmt->gsbase.next = next = orig_stmt->gsbase.next; - stmt->gsbase.prev = prev = orig_stmt->gsbase.prev; + stmt->next = next = orig_stmt->next; + stmt->prev = prev = orig_stmt->prev; /* Note how we don't clear next/prev of orig_stmt. This is so that copies of *GSI our callers might still hold (to orig_stmt) can be advanced as if they too were replaced. */ - if (prev->gsbase.next) - prev->gsbase.next = stmt; + if (prev->next) + prev->next = stmt; else gimple_seq_set_first (gsi->seq, stmt); if (next) - next->gsbase.prev = stmt; + next->prev = stmt; else gimple_seq_set_last (gsi->seq, stmt); @@ -402,10 +402,10 @@ gsi_split_seq_before (gimple_stmt_iterator *i, gimple_seq *pnew_seq) /* How can we possibly split after the end? */ gcc_assert (cur); - prev = cur->gsbase.prev; + prev = cur->prev; old_seq = *i->seq; - if (!prev->gsbase.next) + if (!prev->next) *i->seq = NULL; i->seq = pnew_seq; @@ -415,8 +415,8 @@ gsi_split_seq_before (gimple_stmt_iterator *i, gimple_seq *pnew_seq) /* Cut OLD_SEQ before I. */ gimple_seq_set_last (&old_seq, prev); - if (prev->gsbase.next) - prev->gsbase.next = NULL; + if (prev->next) + prev->next = NULL; } @@ -576,20 +576,20 @@ gsi_remove (gimple_stmt_iterator *i, bool remove_permanently) /* Update the iterator and re-wire the links in I->SEQ. */ cur = i->ptr; - next = cur->gsbase.next; - prev = cur->gsbase.prev; + next = cur->next; + prev = cur->prev; /* See gsi_set_stmt for why we don't reset prev/next of STMT. */ if (next) /* Cur is not last. */ - next->gsbase.prev = prev; - else if (prev->gsbase.next) + next->prev = prev; + else if (prev->next) /* Cur is last but not first. */ gimple_seq_set_last (i->seq, prev); - if (prev->gsbase.next) + if (prev->next) /* Cur is not first. */ - prev->gsbase.next = next; + prev->next = next; else /* Cur is first. */ *i->seq = next; diff --git a/gcc/gimple-iterator.h b/gcc/gimple-iterator.h index 24045f5..11b1276 100644 --- a/gcc/gimple-iterator.h +++ b/gcc/gimple-iterator.h @@ -168,7 +168,7 @@ gsi_end_p (gimple_stmt_iterator i) static inline bool gsi_one_before_end_p (gimple_stmt_iterator i) { - return i.ptr != NULL && i.ptr->gsbase.next == NULL; + return i.ptr != NULL && i.ptr->next == NULL; } /* Advance the iterator to the next gimple statement. */ @@ -176,7 +176,7 @@ gsi_one_before_end_p (gimple_stmt_iterator i) static inline void gsi_next (gimple_stmt_iterator *i) { - i->ptr = i->ptr->gsbase.next; + i->ptr = i->ptr->next; } /* Advance the iterator to the previous gimple statement. */ @@ -184,8 +184,8 @@ gsi_next (gimple_stmt_iterator *i) static inline void gsi_prev (gimple_stmt_iterator *i) { - gimple prev = i->ptr->gsbase.prev; - if (prev->gsbase.next) + gimple prev = i->ptr->prev; + if (prev->next) i->ptr = prev; else i->ptr = NULL; diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 711bc75..b14f317 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -1072,7 +1072,7 @@ dump_gimple_eh_dispatch (pretty_printer *buffer, gimple gs, int spc, int flags) static void dump_gimple_debug (pretty_printer *buffer, gimple gs, int spc, int flags) { - switch (gs->gsbase.subcode) + switch (gs->subcode) { case GIMPLE_DEBUG_BIND: if (flags & TDF_RAW) diff --git a/gcc/gimple-ssa.h b/gcc/gimple-ssa.h index 23aa099..50b48bb 100644 --- a/gcc/gimple-ssa.h +++ b/gcc/gimple-ssa.h @@ -108,11 +108,13 @@ static inline use_operand_p gimple_vuse_op (const_gimple g) { struct use_optype_d *ops; - if (!gimple_has_mem_ops (g)) + const gimple_statement_with_memory_ops *mem_ops_stmt = + dyn_cast <const gimple_statement_with_memory_ops> (g); + if (!mem_ops_stmt) return NULL_USE_OPERAND_P; - ops = g->gsops.opbase.use_ops; + ops = mem_ops_stmt->use_ops; if (ops - && USE_OP_PTR (ops)->use == &g->gsmembase.vuse) + && USE_OP_PTR (ops)->use == &mem_ops_stmt->vuse) return USE_OP_PTR (ops); return NULL_USE_OPERAND_P; } @@ -122,10 +124,12 @@ gimple_vuse_op (const_gimple g) static inline def_operand_p gimple_vdef_op (gimple g) { - if (!gimple_has_mem_ops (g)) + gimple_statement_with_memory_ops *mem_ops_stmt = + dyn_cast <gimple_statement_with_memory_ops> (g); + if (!mem_ops_stmt) return NULL_DEF_OPERAND_P; - if (g->gsmembase.vdef) - return &g->gsmembase.vdef; + if (mem_ops_stmt->vdef) + return &mem_ops_stmt->vdef; return NULL_DEF_OPERAND_P; } diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c index 6f8f51a..7fb07d1 100644 --- a/gcc/gimple-streamer-in.c +++ b/gcc/gimple-streamer-in.c @@ -99,12 +99,12 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, bp = streamer_read_bitpack (ib); num_ops = bp_unpack_var_len_unsigned (&bp); stmt = gimple_alloc (code, num_ops); - stmt->gsbase.no_warning = bp_unpack_value (&bp, 1); + stmt->no_warning = bp_unpack_value (&bp, 1); if (is_gimple_assign (stmt)) - stmt->gsbase.nontemporal_move = bp_unpack_value (&bp, 1); - stmt->gsbase.has_volatile_ops = bp_unpack_value (&bp, 1); + stmt->nontemporal_move = bp_unpack_value (&bp, 1); + stmt->has_volatile_ops = bp_unpack_value (&bp, 1); has_hist = bp_unpack_value (&bp, 1); - stmt->gsbase.subcode = bp_unpack_var_len_unsigned (&bp); + stmt->subcode = bp_unpack_var_len_unsigned (&bp); /* Read location information. */ gimple_set_location (stmt, stream_input_location (&bp, data_in)); diff --git a/gcc/gimple-streamer-out.c b/gcc/gimple-streamer-out.c index 4d0664f..0d6b6a6 100644 --- a/gcc/gimple-streamer-out.c +++ b/gcc/gimple-streamer-out.c @@ -78,7 +78,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt) bp_pack_value (&bp, gimple_has_volatile_ops (stmt), 1); hist = gimple_histogram_value (cfun, stmt); bp_pack_value (&bp, hist != NULL, 1); - bp_pack_var_len_unsigned (&bp, stmt->gsbase.subcode); + bp_pack_var_len_unsigned (&bp, stmt->subcode); /* Emit location information for the statement. */ stream_output_location (ob, &bp, LOCATION_LOCUS (gimple_location (stmt))); diff --git a/gcc/gimple.c b/gcc/gimple.c index 1c88b00..758660f 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -93,7 +93,7 @@ static const char * const gimple_alloc_kind_names[] = { static inline void gimple_set_code (gimple g, enum gimple_code code) { - g->gsbase.code = code; + g->code = code; } /* Return the number of bytes needed to hold a GIMPLE statement with @@ -131,7 +131,7 @@ gimple_alloc_stat (enum gimple_code code, unsigned num_ops MEM_STAT_DECL) /* Do not call gimple_set_modified here as it has other side effects and this tuple is still not completely built. */ - stmt->gsbase.modified = 1; + stmt->modified = 1; gimple_init_singleton (stmt); return stmt; @@ -145,7 +145,7 @@ gimple_set_subcode (gimple g, unsigned subcode) /* We only have 16 bits for the RHS code. Assert that we are not overflowing it. */ gcc_assert (subcode < (1 << 16)); - g->gsbase.subcode = subcode; + g->subcode = subcode; } @@ -280,7 +280,7 @@ static inline gimple gimple_build_call_internal_1 (enum internal_fn fn, unsigned nargs) { gimple s = gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK, nargs + 3); - s->gsbase.subcode |= GF_CALL_INTERNAL; + s->subcode |= GF_CALL_INTERNAL; gimple_call_set_internal_fn (s, fn); gimple_call_reset_alias_info (s); return s; @@ -1111,8 +1111,8 @@ gimple_check_failed (const_gimple gs, const char *file, int line, gimple_code_name[code], get_tree_code_name (subcode), gimple_code_name[gimple_code (gs)], - gs->gsbase.subcode > 0 - ? get_tree_code_name ((enum tree_code) gs->gsbase.subcode) + gs->subcode > 0 + ? get_tree_code_name ((enum tree_code) gs->subcode) : "", function, trim_filename (file), line); } @@ -1306,7 +1306,7 @@ gimple_call_flags (const_gimple stmt) else flags = flags_from_decl_or_type (gimple_call_fntype (stmt)); - if (stmt->gsbase.subcode & GF_CALL_NOTHROW) + if (stmt->subcode & GF_CALL_NOTHROW) flags |= ECF_NOTHROW; return flags; @@ -1447,7 +1447,7 @@ gimple_assign_unary_nop_p (gimple gs) void gimple_set_bb (gimple stmt, basic_block bb) { - stmt->gsbase.bb = bb; + stmt->bb = bb; /* If the statement is a label, add the label to block-to-labels map so that we can speed up edge creation for GIMPLE_GOTOs. */ diff --git a/gcc/gimple.h b/gcc/gimple.h index 65c24ee..ed94343 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -707,6 +707,310 @@ enum gimple_statement_structure_enum { }; #undef DEFGSSTRUCT +template <> +template <> +inline bool +is_a_helper <gimple_statement_asm>::test (gimple gs) +{ + return gs->code == GIMPLE_ASM; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_bind>::test (gimple gs) +{ + return gs->code == GIMPLE_BIND; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_call>::test (gimple gs) +{ + return gs->code == GIMPLE_CALL; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_catch>::test (gimple gs) +{ + return gs->code == GIMPLE_CATCH; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_eh_ctrl>::test (gimple gs) +{ + return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_eh_else>::test (gimple gs) +{ + return gs->code == GIMPLE_EH_ELSE; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_eh_filter>::test (gimple gs) +{ + return gs->code == GIMPLE_EH_FILTER; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_eh_mnt>::test (gimple gs) +{ + return gs->code == GIMPLE_EH_MUST_NOT_THROW; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_atomic_load>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_ATOMIC_LOAD; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_atomic_store>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_continue>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_CONTINUE; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_critical>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_CRITICAL; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_for>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_FOR; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_parallel>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_sections>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_SECTIONS; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_single>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_task>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_TASK; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_phi>::test (gimple gs) +{ + return gs->code == GIMPLE_PHI; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_transaction>::test (gimple gs) +{ + return gs->code == GIMPLE_TRANSACTION; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_try>::test (gimple gs) +{ + return gs->code == GIMPLE_TRY; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_wce>::test (gimple gs) +{ + return gs->code == GIMPLE_WITH_CLEANUP_EXPR; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_asm>::test (const_gimple gs) +{ + return gs->code == GIMPLE_ASM; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_bind>::test (const_gimple gs) +{ + return gs->code == GIMPLE_BIND; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_call>::test (const_gimple gs) +{ + return gs->code == GIMPLE_CALL; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_catch>::test (const_gimple gs) +{ + return gs->code == GIMPLE_CATCH; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_eh_ctrl>::test (const_gimple gs) +{ + return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_eh_filter>::test (const_gimple gs) +{ + return gs->code == GIMPLE_EH_FILTER; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_atomic_load>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_ATOMIC_LOAD; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_atomic_store>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_continue>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_CONTINUE; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_critical>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_CRITICAL; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_for>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_FOR; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_parallel>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_sections>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_SECTIONS; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_single>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_task>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_TASK; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_phi>::test (const_gimple gs) +{ + return gs->code == GIMPLE_PHI; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_transaction>::test (const_gimple gs) +{ + return gs->code == GIMPLE_TRANSACTION; +} + /* Offset in bytes to the location of the operand vector. Zero if there is no operand vector for this tuple structure. */ extern size_t const gimple_ops_offset_[]; @@ -880,7 +1184,7 @@ gimple_seq_first_stmt (gimple_seq s) static inline gimple_seq_node gimple_seq_last (gimple_seq s) { - return s ? s->gsbase.prev : NULL; + return s ? s->prev : NULL; } @@ -899,7 +1203,7 @@ gimple_seq_last_stmt (gimple_seq s) static inline void gimple_seq_set_last (gimple_seq *ps, gimple_seq_node last) { - (*ps)->gsbase.prev = last; + (*ps)->prev = last; } @@ -960,7 +1264,7 @@ set_bb_seq (basic_block bb, gimple_seq seq) static inline enum gimple_code gimple_code (const_gimple g) { - return g->gsbase.code; + return g->code; } @@ -1023,7 +1327,7 @@ gimple_has_substatements (gimple g) static inline basic_block gimple_bb (const_gimple g) { - return g->gsbase.bb; + return g->bb; } @@ -1032,7 +1336,7 @@ gimple_bb (const_gimple g) static inline tree gimple_block (const_gimple g) { - return LOCATION_BLOCK (g->gsbase.location); + return LOCATION_BLOCK (g->location); } @@ -1042,10 +1346,10 @@ static inline void gimple_set_block (gimple g, tree block) { if (block) - g->gsbase.location = - COMBINE_LOCATION_DATA (line_table, g->gsbase.location, block); + g->location = + COMBINE_LOCATION_DATA (line_table, g->location, block); else - g->gsbase.location = LOCATION_LOCUS (g->gsbase.location); + g->location = LOCATION_LOCUS (g->location); } @@ -1054,7 +1358,7 @@ gimple_set_block (gimple g, tree block) static inline location_t gimple_location (const_gimple g) { - return g->gsbase.location; + return g->location; } /* Return pointer to location information for statement G. */ @@ -1062,7 +1366,7 @@ gimple_location (const_gimple g) static inline const location_t * gimple_location_ptr (const_gimple g) { - return &g->gsbase.location; + return &g->location; } @@ -1071,7 +1375,7 @@ gimple_location_ptr (const_gimple g) static inline void gimple_set_location (gimple g, location_t location) { - g->gsbase.location = location; + g->location = location; } @@ -1116,7 +1420,7 @@ gimple_seq_singleton_p (gimple_seq seq) static inline bool gimple_no_warning_p (const_gimple stmt) { - return stmt->gsbase.no_warning; + return stmt->no_warning; } /* Set the no_warning flag of STMT to NO_WARNING. */ @@ -1124,7 +1428,7 @@ gimple_no_warning_p (const_gimple stmt) static inline void gimple_set_no_warning (gimple stmt, bool no_warning) { - stmt->gsbase.no_warning = (unsigned) no_warning; + stmt->no_warning = (unsigned) no_warning; } /* Set the visited status on statement STMT to VISITED_P. */ @@ -1132,7 +1436,7 @@ gimple_set_no_warning (gimple stmt, bool no_warning) static inline void gimple_set_visited (gimple stmt, bool visited_p) { - stmt->gsbase.visited = (unsigned) visited_p; + stmt->visited = (unsigned) visited_p; } @@ -1141,7 +1445,7 @@ gimple_set_visited (gimple stmt, bool visited_p) static inline bool gimple_visited_p (gimple stmt) { - return stmt->gsbase.visited; + return stmt->visited; } @@ -1151,9 +1455,9 @@ static inline void gimple_set_plf (gimple stmt, enum plf_mask plf, bool val_p) { if (val_p) - stmt->gsbase.plf |= (unsigned int) plf; + stmt->plf |= (unsigned int) plf; else - stmt->gsbase.plf &= ~((unsigned int) plf); + stmt->plf &= ~((unsigned int) plf); } @@ -1162,7 +1466,7 @@ gimple_set_plf (gimple stmt, enum plf_mask plf, bool val_p) static inline unsigned int gimple_plf (gimple stmt, enum plf_mask plf) { - return stmt->gsbase.plf & ((unsigned int) plf); + return stmt->plf & ((unsigned int) plf); } @@ -1171,7 +1475,7 @@ gimple_plf (gimple stmt, enum plf_mask plf) static inline void gimple_set_uid (gimple g, unsigned uid) { - g->gsbase.uid = uid; + g->uid = uid; } @@ -1180,7 +1484,7 @@ gimple_set_uid (gimple g, unsigned uid) static inline unsigned gimple_uid (const_gimple g) { - return g->gsbase.uid; + return g->uid; } @@ -1189,8 +1493,8 @@ gimple_uid (const_gimple g) static inline void gimple_init_singleton (gimple g) { - g->gsbase.next = NULL; - g->gsbase.prev = g; + g->next = NULL; + g->prev = g; } @@ -1241,9 +1545,11 @@ gimple_set_use_ops (gimple g, struct use_optype_d *use) static inline tree gimple_vuse (const_gimple g) { - if (!gimple_has_mem_ops (g)) + const gimple_statement_with_memory_ops *mem_ops_stmt = + dyn_cast <const gimple_statement_with_memory_ops> (g); + if (!mem_ops_stmt) return NULL_TREE; - return g->gsmembase.vuse; + return mem_ops_stmt->vuse; } /* Return the single VDEF operand of the statement G. */ @@ -1251,9 +1557,11 @@ gimple_vuse (const_gimple g) static inline tree gimple_vdef (const_gimple g) { - if (!gimple_has_mem_ops (g)) + const gimple_statement_with_memory_ops *mem_ops_stmt = + dyn_cast <const gimple_statement_with_memory_ops> (g); + if (!mem_ops_stmt) return NULL_TREE; - return g->gsmembase.vdef; + return mem_ops_stmt->vdef; } /* Return the single VUSE operand of the statement G. */ @@ -1261,9 +1569,11 @@ gimple_vdef (const_gimple g) static inline tree * gimple_vuse_ptr (gimple g) { - if (!gimple_has_mem_ops (g)) + gimple_statement_with_memory_ops *mem_ops_stmt = + dyn_cast <gimple_statement_with_memory_ops> (g); + if (!mem_ops_stmt) return NULL; - return &g->gsmembase.vuse; + return &mem_ops_stmt->vuse; } /* Return the single VDEF operand of the statement G. */ @@ -1271,9 +1581,11 @@ gimple_vuse_ptr (gimple g) static inline tree * gimple_vdef_ptr (gimple g) { - if (!gimple_has_mem_ops (g)) + gimple_statement_with_memory_ops *mem_ops_stmt = + dyn_cast <gimple_statement_with_memory_ops> (g); + if (!mem_ops_stmt) return NULL; - return &g->gsmembase.vdef; + return &mem_ops_stmt->vdef; } /* Set the single VUSE operand of the statement G. */ @@ -1303,7 +1615,7 @@ gimple_set_vdef (gimple g, tree vdef) static inline bool gimple_modified_p (const_gimple g) { - return (gimple_has_ops (g)) ? (bool) g->gsbase.modified : false; + return (gimple_has_ops (g)) ? (bool) g->modified : false; } @@ -1314,7 +1626,7 @@ static inline void gimple_set_modified (gimple s, bool modifiedp) { if (gimple_has_ops (s)) - s->gsbase.modified = (unsigned) modifiedp; + s->modified = (unsigned) modifiedp; } @@ -1329,7 +1641,7 @@ gimple_expr_code (const_gimple stmt) { enum gimple_code code = gimple_code (stmt); if (code == GIMPLE_ASSIGN || code == GIMPLE_COND) - return (enum tree_code) stmt->gsbase.subcode; + return (enum tree_code) stmt->subcode; else { gcc_gimple_checking_assert (code == GIMPLE_CALL); @@ -1344,7 +1656,7 @@ static inline bool gimple_has_volatile_ops (const_gimple stmt) { if (gimple_has_mem_ops (stmt)) - return stmt->gsbase.has_volatile_ops; + return stmt->has_volatile_ops; else return false; } @@ -1356,7 +1668,7 @@ static inline void gimple_set_has_volatile_ops (gimple stmt, bool volatilep) { if (gimple_has_mem_ops (stmt)) - stmt->gsbase.has_volatile_ops = (unsigned) volatilep; + stmt->has_volatile_ops = (unsigned) volatilep; } /* Return true if STMT is in a transaction. */ @@ -1383,7 +1695,7 @@ gimple_omp_subcode (const_gimple s) { gcc_gimple_checking_assert (gimple_code (s) >= GIMPLE_OMP_ATOMIC_LOAD && gimple_code (s) <= GIMPLE_OMP_TEAMS); - return s->gsbase.subcode; + return s->subcode; } /* Set the subcode for OMP statement S to SUBCODE. */ @@ -1394,7 +1706,7 @@ gimple_omp_set_subcode (gimple s, unsigned int subcode) /* We only have 16 bits for the subcode. Assert that we are not overflowing it. */ gcc_gimple_checking_assert (subcode < (1 << 16)); - s->gsbase.subcode = subcode; + s->subcode = subcode; } /* Set the nowait flag on OMP_RETURN statement S. */ @@ -1403,7 +1715,7 @@ static inline void gimple_omp_return_set_nowait (gimple s) { GIMPLE_CHECK (s, GIMPLE_OMP_RETURN); - s->gsbase.subcode |= GF_OMP_RETURN_NOWAIT; + s->subcode |= GF_OMP_RETURN_NOWAIT; } @@ -1423,8 +1735,9 @@ gimple_omp_return_nowait_p (const_gimple g) static inline void gimple_omp_return_set_lhs (gimple g, tree lhs) { - GIMPLE_CHECK (g, GIMPLE_OMP_RETURN); - g->gimple_omp_atomic_store.val = lhs; + gimple_statement_omp_atomic_store *omp_atomic_store_stmt = + as_a <gimple_statement_omp_atomic_store> (g); + omp_atomic_store_stmt->val = lhs; } @@ -1433,8 +1746,9 @@ gimple_omp_return_set_lhs (gimple g, tree lhs) static inline tree gimple_omp_return_lhs (const_gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_RETURN); - return g->gimple_omp_atomic_store.val; + const gimple_statement_omp_atomic_store *omp_atomic_store_stmt = + as_a <const gimple_statement_omp_atomic_store> (g); + return omp_atomic_store_stmt->val; } @@ -1443,8 +1757,9 @@ gimple_omp_return_lhs (const_gimple g) static inline tree * gimple_omp_return_lhs_ptr (gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_RETURN); - return &g->gimple_omp_atomic_store.val; + gimple_statement_omp_atomic_store *omp_atomic_store_stmt = + as_a <gimple_statement_omp_atomic_store> (g); + return &omp_atomic_store_stmt->val; } @@ -1465,7 +1780,7 @@ static inline void gimple_omp_section_set_last (gimple g) { GIMPLE_CHECK (g, GIMPLE_OMP_SECTION); - g->gsbase.subcode |= GF_OMP_SECTION_LAST; + g->subcode |= GF_OMP_SECTION_LAST; } @@ -1488,9 +1803,9 @@ gimple_omp_parallel_set_combined_p (gimple g, bool combined_p) { GIMPLE_CHECK (g, GIMPLE_OMP_PARALLEL); if (combined_p) - g->gsbase.subcode |= GF_OMP_PARALLEL_COMBINED; + g->subcode |= GF_OMP_PARALLEL_COMBINED; else - g->gsbase.subcode &= ~GF_OMP_PARALLEL_COMBINED; + g->subcode &= ~GF_OMP_PARALLEL_COMBINED; } @@ -1513,7 +1828,7 @@ gimple_omp_atomic_set_need_value (gimple g) { if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD) GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); - g->gsbase.subcode |= GF_OMP_ATOMIC_NEED_VALUE; + g->subcode |= GF_OMP_ATOMIC_NEED_VALUE; } @@ -1536,7 +1851,7 @@ gimple_omp_atomic_set_seq_cst (gimple g) { if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD) GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); - g->gsbase.subcode |= GF_OMP_ATOMIC_SEQ_CST; + g->subcode |= GF_OMP_ATOMIC_SEQ_CST; } @@ -1545,7 +1860,7 @@ gimple_omp_atomic_set_seq_cst (gimple g) static inline unsigned gimple_num_ops (const_gimple gs) { - return gs->gsbase.num_ops; + return gs->num_ops; } @@ -1554,7 +1869,7 @@ gimple_num_ops (const_gimple gs) static inline void gimple_set_num_ops (gimple gs, unsigned num_ops) { - gs->gsbase.num_ops = num_ops; + gs->num_ops = num_ops; } @@ -1785,7 +2100,7 @@ static inline bool gimple_assign_nontemporal_move_p (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_ASSIGN); - return gs->gsbase.nontemporal_move; + return gs->nontemporal_move; } /* Sets nontemporal move flag of GS to NONTEMPORAL. */ @@ -1794,7 +2109,7 @@ static inline void gimple_assign_set_nontemporal_move (gimple gs, bool nontemporal) { GIMPLE_CHECK (gs, GIMPLE_ASSIGN); - gs->gsbase.nontemporal_move = nontemporal; + gs->nontemporal_move = nontemporal; } @@ -1808,7 +2123,7 @@ gimple_assign_rhs_code (const_gimple gs) enum tree_code code; GIMPLE_CHECK (gs, GIMPLE_ASSIGN); - code = (enum tree_code) gs->gsbase.subcode; + code = (enum tree_code) gs->subcode; /* While we initially set subcode to the TREE_CODE of the rhs for GIMPLE_SINGLE_RHS assigns we do not update that subcode to stay in sync when we rewrite stmts into SSA form or do SSA propagations. */ @@ -1826,7 +2141,7 @@ static inline void gimple_assign_set_rhs_code (gimple s, enum tree_code code) { GIMPLE_CHECK (s, GIMPLE_ASSIGN); - s->gsbase.subcode = code; + s->subcode = code; } @@ -1951,7 +2266,7 @@ static inline bool gimple_call_internal_p (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_CALL); - return (gs->gsbase.subcode & GF_CALL_INTERNAL) != 0; + return (gs->subcode & GF_CALL_INTERNAL) != 0; } @@ -1962,7 +2277,7 @@ static inline bool gimple_call_with_bounds_p (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_CALL); - return (gs->gsbase.subcode & GF_CALL_WITH_BOUNDS) != 0; + return (gs->subcode & GF_CALL_WITH_BOUNDS) != 0; } @@ -1974,9 +2289,9 @@ gimple_call_set_with_bounds (gimple gs, bool with_bounds) { GIMPLE_CHECK (gs, GIMPLE_CALL); if (with_bounds) - gs->gsbase.subcode |= GF_CALL_WITH_BOUNDS; + gs->subcode |= GF_CALL_WITH_BOUNDS; else - gs->gsbase.subcode &= ~GF_CALL_WITH_BOUNDS; + gs->subcode &= ~GF_CALL_WITH_BOUNDS; } @@ -1995,10 +2310,11 @@ gimple_call_internal_fn (const_gimple gs) static inline tree gimple_call_fntype (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_CALL); + const gimple_statement_call *call_stmt = + as_a <const gimple_statement_call> (gs); if (gimple_call_internal_p (gs)) return NULL_TREE; - return gs->gimple_call.u.fntype; + return call_stmt->u.fntype; } /* Set the type of the function called by GS to FNTYPE. */ @@ -2006,9 +2322,9 @@ gimple_call_fntype (const_gimple gs) static inline void gimple_call_set_fntype (gimple gs, tree fntype) { - GIMPLE_CHECK (gs, GIMPLE_CALL); + gimple_statement_call *call_stmt = as_a <gimple_statement_call> (gs); gcc_gimple_checking_assert (!gimple_call_internal_p (gs)); - gs->gimple_call.u.fntype = fntype; + call_stmt->u.fntype = fntype; } @@ -2060,9 +2376,9 @@ gimple_call_set_fndecl (gimple gs, tree decl) static inline void gimple_call_set_internal_fn (gimple gs, enum internal_fn fn) { - GIMPLE_CHECK (gs, GIMPLE_CALL); + gimple_statement_call *call_stmt = as_a <gimple_statement_call> (gs); gcc_gimple_checking_assert (gimple_call_internal_p (gs)); - gs->gimple_call.u.internal_fn = fn; + call_stmt->u.internal_fn = fn; } @@ -2175,9 +2491,9 @@ gimple_call_set_tail (gimple s, bool tail_p) { GIMPLE_CHECK (s, GIMPLE_CALL); if (tail_p) - s->gsbase.subcode |= GF_CALL_TAILCALL; + s->subcode |= GF_CALL_TAILCALL; else - s->gsbase.subcode &= ~GF_CALL_TAILCALL; + s->subcode &= ~GF_CALL_TAILCALL; } @@ -2187,7 +2503,7 @@ static inline bool gimple_call_tail_p (gimple s) { GIMPLE_CHECK (s, GIMPLE_CALL); - return (s->gsbase.subcode & GF_CALL_TAILCALL) != 0; + return (s->subcode & GF_CALL_TAILCALL) != 0; } @@ -2200,9 +2516,9 @@ gimple_call_set_return_slot_opt (gimple s, bool return_slot_opt_p) { GIMPLE_CHECK (s, GIMPLE_CALL); if (return_slot_opt_p) - s->gsbase.subcode |= GF_CALL_RETURN_SLOT_OPT; + s->subcode |= GF_CALL_RETURN_SLOT_OPT; else - s->gsbase.subcode &= ~GF_CALL_RETURN_SLOT_OPT; + s->subcode &= ~GF_CALL_RETURN_SLOT_OPT; } @@ -2212,7 +2528,7 @@ static inline bool gimple_call_return_slot_opt_p (gimple s) { GIMPLE_CHECK (s, GIMPLE_CALL); - return (s->gsbase.subcode & GF_CALL_RETURN_SLOT_OPT) != 0; + return (s->subcode & GF_CALL_RETURN_SLOT_OPT) != 0; } @@ -2224,9 +2540,9 @@ gimple_call_set_from_thunk (gimple s, bool from_thunk_p) { GIMPLE_CHECK (s, GIMPLE_CALL); if (from_thunk_p) - s->gsbase.subcode |= GF_CALL_FROM_THUNK; + s->subcode |= GF_CALL_FROM_THUNK; else - s->gsbase.subcode &= ~GF_CALL_FROM_THUNK; + s->subcode &= ~GF_CALL_FROM_THUNK; } @@ -2236,7 +2552,7 @@ static inline bool gimple_call_from_thunk_p (gimple s) { GIMPLE_CHECK (s, GIMPLE_CALL); - return (s->gsbase.subcode & GF_CALL_FROM_THUNK) != 0; + return (s->subcode & GF_CALL_FROM_THUNK) != 0; } @@ -2248,9 +2564,9 @@ gimple_call_set_va_arg_pack (gimple s, bool pass_arg_pack_p) { GIMPLE_CHECK (s, GIMPLE_CALL); if (pass_arg_pack_p) - s->gsbase.subcode |= GF_CALL_VA_ARG_PACK; + s->subcode |= GF_CALL_VA_ARG_PACK; else - s->gsbase.subcode &= ~GF_CALL_VA_ARG_PACK; + s->subcode &= ~GF_CALL_VA_ARG_PACK; } @@ -2261,7 +2577,7 @@ static inline bool gimple_call_va_arg_pack_p (gimple s) { GIMPLE_CHECK (s, GIMPLE_CALL); - return (s->gsbase.subcode & GF_CALL_VA_ARG_PACK) != 0; + return (s->subcode & GF_CALL_VA_ARG_PACK) != 0; } @@ -2283,9 +2599,9 @@ gimple_call_set_nothrow (gimple s, bool nothrow_p) { GIMPLE_CHECK (s, GIMPLE_CALL); if (nothrow_p) - s->gsbase.subcode |= GF_CALL_NOTHROW; + s->subcode |= GF_CALL_NOTHROW; else - s->gsbase.subcode &= ~GF_CALL_NOTHROW; + s->subcode &= ~GF_CALL_NOTHROW; } /* Return true if S is a nothrow call. */ @@ -2307,9 +2623,9 @@ gimple_call_set_alloca_for_var (gimple s, bool for_var) { GIMPLE_CHECK (s, GIMPLE_CALL); if (for_var) - s->gsbase.subcode |= GF_CALL_ALLOCA_FOR_VAR; + s->subcode |= GF_CALL_ALLOCA_FOR_VAR; else - s->gsbase.subcode &= ~GF_CALL_ALLOCA_FOR_VAR; + s->subcode &= ~GF_CALL_ALLOCA_FOR_VAR; } /* Return true of S is a call to builtin_alloca emitted for VLA objects. */ @@ -2318,7 +2634,7 @@ static inline bool gimple_call_alloca_for_var_p (gimple s) { GIMPLE_CHECK (s, GIMPLE_CALL); - return (s->gsbase.subcode & GF_CALL_ALLOCA_FOR_VAR) != 0; + return (s->subcode & GF_CALL_ALLOCA_FOR_VAR) != 0; } /* Copy all the GF_CALL_* flags from ORIG_CALL to DEST_CALL. */ @@ -2328,7 +2644,7 @@ gimple_call_copy_flags (gimple dest_call, gimple orig_call) { GIMPLE_CHECK (dest_call, GIMPLE_CALL); GIMPLE_CHECK (orig_call, GIMPLE_CALL); - dest_call->gsbase.subcode = orig_call->gsbase.subcode; + dest_call->subcode = orig_call->subcode; } @@ -2338,8 +2654,8 @@ gimple_call_copy_flags (gimple dest_call, gimple orig_call) static inline struct pt_solution * gimple_call_use_set (gimple call) { - GIMPLE_CHECK (call, GIMPLE_CALL); - return &call->gimple_call.call_used; + gimple_statement_call *call_stmt = as_a <gimple_statement_call> (call); + return &call_stmt->call_used; } @@ -2349,8 +2665,8 @@ gimple_call_use_set (gimple call) static inline struct pt_solution * gimple_call_clobber_set (gimple call) { - GIMPLE_CHECK (call, GIMPLE_CALL); - return &call->gimple_call.call_clobbered; + gimple_statement_call *call_stmt = as_a <gimple_statement_call> (call); + return &call_stmt->call_clobbered; } @@ -2372,7 +2688,7 @@ static inline enum tree_code gimple_cond_code (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_COND); - return (enum tree_code) gs->gsbase.subcode; + return (enum tree_code) gs->subcode; } @@ -2382,7 +2698,7 @@ static inline void gimple_cond_set_code (gimple gs, enum tree_code code) { GIMPLE_CHECK (gs, GIMPLE_COND); - gs->gsbase.subcode = code; + gs->subcode = code; } @@ -2498,7 +2814,7 @@ gimple_cond_make_false (gimple gs) { gimple_cond_set_lhs (gs, boolean_true_node); gimple_cond_set_rhs (gs, boolean_false_node); - gs->gsbase.subcode = EQ_EXPR; + gs->subcode = EQ_EXPR; } @@ -2509,7 +2825,7 @@ gimple_cond_make_true (gimple gs) { gimple_cond_set_lhs (gs, boolean_true_node); gimple_cond_set_rhs (gs, boolean_true_node); - gs->gsbase.subcode = EQ_EXPR; + gs->subcode = EQ_EXPR; } /* Check if conditional statemente GS is of the form 'if (1 == 1)', @@ -2618,8 +2934,9 @@ gimple_goto_set_dest (gimple gs, tree dest) static inline tree gimple_bind_vars (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - return gs->gimple_bind.vars; + const gimple_statement_bind *bind_stmt = + as_a <const gimple_statement_bind> (gs); + return bind_stmt->vars; } @@ -2629,8 +2946,8 @@ gimple_bind_vars (const_gimple gs) static inline void gimple_bind_set_vars (gimple gs, tree vars) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - gs->gimple_bind.vars = vars; + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); + bind_stmt->vars = vars; } @@ -2640,16 +2957,16 @@ gimple_bind_set_vars (gimple gs, tree vars) static inline void gimple_bind_append_vars (gimple gs, tree vars) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - gs->gimple_bind.vars = chainon (gs->gimple_bind.vars, vars); + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); + bind_stmt->vars = chainon (bind_stmt->vars, vars); } static inline gimple_seq * gimple_bind_body_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - return &gs->gimple_bind.body; + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); + return &bind_stmt->body; } /* Return the GIMPLE sequence contained in the GIMPLE_BIND statement GS. */ @@ -2667,8 +2984,8 @@ gimple_bind_body (gimple gs) static inline void gimple_bind_set_body (gimple gs, gimple_seq seq) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - gs->gimple_bind.body = seq; + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); + bind_stmt->body = seq; } @@ -2677,8 +2994,8 @@ gimple_bind_set_body (gimple gs, gimple_seq seq) static inline void gimple_bind_add_stmt (gimple gs, gimple stmt) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - gimple_seq_add_stmt (&gs->gimple_bind.body, stmt); + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); + gimple_seq_add_stmt (&bind_stmt->body, stmt); } @@ -2687,8 +3004,8 @@ gimple_bind_add_stmt (gimple gs, gimple stmt) static inline void gimple_bind_add_seq (gimple gs, gimple_seq seq) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - gimple_seq_add_seq (&gs->gimple_bind.body, seq); + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); + gimple_seq_add_seq (&bind_stmt->body, seq); } @@ -2698,8 +3015,9 @@ gimple_bind_add_seq (gimple gs, gimple_seq seq) static inline tree gimple_bind_block (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_BIND); - return gs->gimple_bind.block; + const gimple_statement_bind *bind_stmt = + as_a <const gimple_statement_bind> (gs); + return bind_stmt->block; } @@ -2709,10 +3027,10 @@ gimple_bind_block (const_gimple gs) static inline void gimple_bind_set_block (gimple gs, tree block) { - GIMPLE_CHECK (gs, GIMPLE_BIND); + gimple_statement_bind *bind_stmt = as_a <gimple_statement_bind> (gs); gcc_gimple_checking_assert (block == NULL_TREE || TREE_CODE (block) == BLOCK); - gs->gimple_bind.block = block; + bind_stmt->block = block; } @@ -2721,8 +3039,9 @@ gimple_bind_set_block (gimple gs, tree block) static inline unsigned gimple_asm_ninputs (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - return gs->gimple_asm.ni; + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + return asm_stmt->ni; } @@ -2731,8 +3050,9 @@ gimple_asm_ninputs (const_gimple gs) static inline unsigned gimple_asm_noutputs (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - return gs->gimple_asm.no; + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + return asm_stmt->no; } @@ -2741,8 +3061,9 @@ gimple_asm_noutputs (const_gimple gs) static inline unsigned gimple_asm_nclobbers (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - return gs->gimple_asm.nc; + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + return asm_stmt->nc; } /* Return the number of label operands for GIMPLE_ASM GS. */ @@ -2750,8 +3071,9 @@ gimple_asm_nclobbers (const_gimple gs) static inline unsigned gimple_asm_nlabels (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - return gs->gimple_asm.nl; + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + return asm_stmt->nl; } /* Return input operand INDEX of GIMPLE_ASM GS. */ @@ -2759,9 +3081,10 @@ gimple_asm_nlabels (const_gimple gs) static inline tree gimple_asm_input_op (const_gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.ni); - return gimple_op (gs, index + gs->gimple_asm.no); + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->ni); + return gimple_op (gs, index + asm_stmt->no); } /* Return a pointer to input operand INDEX of GIMPLE_ASM GS. */ @@ -2769,9 +3092,10 @@ gimple_asm_input_op (const_gimple gs, unsigned index) static inline tree * gimple_asm_input_op_ptr (const_gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.ni); - return gimple_op_ptr (gs, index + gs->gimple_asm.no); + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->ni); + return gimple_op_ptr (gs, index + asm_stmt->no); } @@ -2780,10 +3104,10 @@ gimple_asm_input_op_ptr (const_gimple gs, unsigned index) static inline void gimple_asm_set_input_op (gimple gs, unsigned index, tree in_op) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.ni + gimple_statement_asm *asm_stmt = as_a <gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->ni && TREE_CODE (in_op) == TREE_LIST); - gimple_set_op (gs, index + gs->gimple_asm.no, in_op); + gimple_set_op (gs, index + asm_stmt->no, in_op); } @@ -2792,8 +3116,9 @@ gimple_asm_set_input_op (gimple gs, unsigned index, tree in_op) static inline tree gimple_asm_output_op (const_gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.no); + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->no); return gimple_op (gs, index); } @@ -2802,8 +3127,9 @@ gimple_asm_output_op (const_gimple gs, unsigned index) static inline tree * gimple_asm_output_op_ptr (const_gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.no); + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->no); return gimple_op_ptr (gs, index); } @@ -2813,8 +3139,8 @@ gimple_asm_output_op_ptr (const_gimple gs, unsigned index) static inline void gimple_asm_set_output_op (gimple gs, unsigned index, tree out_op) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.no + gimple_statement_asm *asm_stmt = as_a <gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->no && TREE_CODE (out_op) == TREE_LIST); gimple_set_op (gs, index, out_op); } @@ -2825,9 +3151,10 @@ gimple_asm_set_output_op (gimple gs, unsigned index, tree out_op) static inline tree gimple_asm_clobber_op (const_gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.nc); - return gimple_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.no); + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->nc); + return gimple_op (gs, index + asm_stmt->ni + asm_stmt->no); } @@ -2836,10 +3163,10 @@ gimple_asm_clobber_op (const_gimple gs, unsigned index) static inline void gimple_asm_set_clobber_op (gimple gs, unsigned index, tree clobber_op) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.nc + gimple_statement_asm *asm_stmt = as_a <gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->nc && TREE_CODE (clobber_op) == TREE_LIST); - gimple_set_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.no, clobber_op); + gimple_set_op (gs, index + asm_stmt->ni + asm_stmt->no, clobber_op); } /* Return label operand INDEX of GIMPLE_ASM GS. */ @@ -2847,9 +3174,10 @@ gimple_asm_set_clobber_op (gimple gs, unsigned index, tree clobber_op) static inline tree gimple_asm_label_op (const_gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.nl); - return gimple_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.nc); + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->nl); + return gimple_op (gs, index + asm_stmt->ni + asm_stmt->nc); } /* Set LABEL_OP to be label operand INDEX in GIMPLE_ASM GS. */ @@ -2857,10 +3185,10 @@ gimple_asm_label_op (const_gimple gs, unsigned index) static inline void gimple_asm_set_label_op (gimple gs, unsigned index, tree label_op) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - gcc_gimple_checking_assert (index < gs->gimple_asm.nl + gimple_statement_asm *asm_stmt = as_a <gimple_statement_asm> (gs); + gcc_gimple_checking_assert (index < asm_stmt->nl && TREE_CODE (label_op) == TREE_LIST); - gimple_set_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.nc, label_op); + gimple_set_op (gs, index + asm_stmt->ni + asm_stmt->nc, label_op); } /* Return the string representing the assembly instruction in @@ -2869,8 +3197,9 @@ gimple_asm_set_label_op (gimple gs, unsigned index, tree label_op) static inline const char * gimple_asm_string (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_ASM); - return gs->gimple_asm.string; + const gimple_statement_asm *asm_stmt = + as_a <const gimple_statement_asm> (gs); + return asm_stmt->string; } @@ -2880,7 +3209,7 @@ static inline bool gimple_asm_volatile_p (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_ASM); - return (gs->gsbase.subcode & GF_ASM_VOLATILE) != 0; + return (gs->subcode & GF_ASM_VOLATILE) != 0; } @@ -2891,9 +3220,9 @@ gimple_asm_set_volatile (gimple gs, bool volatile_p) { GIMPLE_CHECK (gs, GIMPLE_ASM); if (volatile_p) - gs->gsbase.subcode |= GF_ASM_VOLATILE; + gs->subcode |= GF_ASM_VOLATILE; else - gs->gsbase.subcode &= ~GF_ASM_VOLATILE; + gs->subcode &= ~GF_ASM_VOLATILE; } @@ -2904,9 +3233,9 @@ gimple_asm_set_input (gimple gs, bool input_p) { GIMPLE_CHECK (gs, GIMPLE_ASM); if (input_p) - gs->gsbase.subcode |= GF_ASM_INPUT; + gs->subcode |= GF_ASM_INPUT; else - gs->gsbase.subcode &= ~GF_ASM_INPUT; + gs->subcode &= ~GF_ASM_INPUT; } @@ -2916,7 +3245,7 @@ static inline bool gimple_asm_input_p (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_ASM); - return (gs->gsbase.subcode & GF_ASM_INPUT) != 0; + return (gs->subcode & GF_ASM_INPUT) != 0; } @@ -2925,8 +3254,9 @@ gimple_asm_input_p (const_gimple gs) static inline tree gimple_catch_types (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_CATCH); - return gs->gimple_catch.types; + const gimple_statement_catch *catch_stmt = + as_a <const gimple_statement_catch> (gs); + return catch_stmt->types; } @@ -2935,8 +3265,8 @@ gimple_catch_types (const_gimple gs) static inline tree * gimple_catch_types_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_CATCH); - return &gs->gimple_catch.types; + gimple_statement_catch *catch_stmt = as_a <gimple_statement_catch> (gs); + return &catch_stmt->types; } @@ -2946,8 +3276,8 @@ gimple_catch_types_ptr (gimple gs) static inline gimple_seq * gimple_catch_handler_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_CATCH); - return &gs->gimple_catch.handler; + gimple_statement_catch *catch_stmt = as_a <gimple_statement_catch> (gs); + return &catch_stmt->handler; } @@ -2966,8 +3296,8 @@ gimple_catch_handler (gimple gs) static inline void gimple_catch_set_types (gimple gs, tree t) { - GIMPLE_CHECK (gs, GIMPLE_CATCH); - gs->gimple_catch.types = t; + gimple_statement_catch *catch_stmt = as_a <gimple_statement_catch> (gs); + catch_stmt->types = t; } @@ -2976,8 +3306,8 @@ gimple_catch_set_types (gimple gs, tree t) static inline void gimple_catch_set_handler (gimple gs, gimple_seq handler) { - GIMPLE_CHECK (gs, GIMPLE_CATCH); - gs->gimple_catch.handler = handler; + gimple_statement_catch *catch_stmt = as_a <gimple_statement_catch> (gs); + catch_stmt->handler = handler; } @@ -2986,8 +3316,9 @@ gimple_catch_set_handler (gimple gs, gimple_seq handler) static inline tree gimple_eh_filter_types (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); - return gs->gimple_eh_filter.types; + const gimple_statement_eh_filter *eh_filter_stmt = + as_a <const gimple_statement_eh_filter> (gs); + return eh_filter_stmt->types; } @@ -2997,8 +3328,9 @@ gimple_eh_filter_types (const_gimple gs) static inline tree * gimple_eh_filter_types_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); - return &gs->gimple_eh_filter.types; + gimple_statement_eh_filter *eh_filter_stmt = + as_a <gimple_statement_eh_filter> (gs); + return &eh_filter_stmt->types; } @@ -3008,8 +3340,9 @@ gimple_eh_filter_types_ptr (gimple gs) static inline gimple_seq * gimple_eh_filter_failure_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); - return &gs->gimple_eh_filter.failure; + gimple_statement_eh_filter *eh_filter_stmt = + as_a <gimple_statement_eh_filter> (gs); + return &eh_filter_stmt->failure; } @@ -3028,8 +3361,9 @@ gimple_eh_filter_failure (gimple gs) static inline void gimple_eh_filter_set_types (gimple gs, tree types) { - GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); - gs->gimple_eh_filter.types = types; + gimple_statement_eh_filter *eh_filter_stmt = + as_a <gimple_statement_eh_filter> (gs); + eh_filter_stmt->types = types; } @@ -3039,8 +3373,9 @@ gimple_eh_filter_set_types (gimple gs, tree types) static inline void gimple_eh_filter_set_failure (gimple gs, gimple_seq failure) { - GIMPLE_CHECK (gs, GIMPLE_EH_FILTER); - gs->gimple_eh_filter.failure = failure; + gimple_statement_eh_filter *eh_filter_stmt = + as_a <gimple_statement_eh_filter> (gs); + eh_filter_stmt->failure = failure; } /* Get the function decl to be called by the MUST_NOT_THROW region. */ @@ -3048,8 +3383,8 @@ gimple_eh_filter_set_failure (gimple gs, gimple_seq failure) static inline tree gimple_eh_must_not_throw_fndecl (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_MUST_NOT_THROW); - return gs->gimple_eh_mnt.fndecl; + gimple_statement_eh_mnt *eh_mnt_stmt = as_a <gimple_statement_eh_mnt> (gs); + return eh_mnt_stmt->fndecl; } /* Set the function decl to be called by GS to DECL. */ @@ -3057,8 +3392,8 @@ gimple_eh_must_not_throw_fndecl (gimple gs) static inline void gimple_eh_must_not_throw_set_fndecl (gimple gs, tree decl) { - GIMPLE_CHECK (gs, GIMPLE_EH_MUST_NOT_THROW); - gs->gimple_eh_mnt.fndecl = decl; + gimple_statement_eh_mnt *eh_mnt_stmt = as_a <gimple_statement_eh_mnt> (gs); + eh_mnt_stmt->fndecl = decl; } /* GIMPLE_EH_ELSE accessors. */ @@ -3066,8 +3401,9 @@ gimple_eh_must_not_throw_set_fndecl (gimple gs, tree decl) static inline gimple_seq * gimple_eh_else_n_body_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_ELSE); - return &gs->gimple_eh_else.n_body; + gimple_statement_eh_else *eh_else_stmt = + as_a <gimple_statement_eh_else> (gs); + return &eh_else_stmt->n_body; } static inline gimple_seq @@ -3079,8 +3415,9 @@ gimple_eh_else_n_body (gimple gs) static inline gimple_seq * gimple_eh_else_e_body_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_ELSE); - return &gs->gimple_eh_else.e_body; + gimple_statement_eh_else *eh_else_stmt = + as_a <gimple_statement_eh_else> (gs); + return &eh_else_stmt->e_body; } static inline gimple_seq @@ -3092,15 +3429,17 @@ gimple_eh_else_e_body (gimple gs) static inline void gimple_eh_else_set_n_body (gimple gs, gimple_seq seq) { - GIMPLE_CHECK (gs, GIMPLE_EH_ELSE); - gs->gimple_eh_else.n_body = seq; + gimple_statement_eh_else *eh_else_stmt = + as_a <gimple_statement_eh_else> (gs); + eh_else_stmt->n_body = seq; } static inline void gimple_eh_else_set_e_body (gimple gs, gimple_seq seq) { - GIMPLE_CHECK (gs, GIMPLE_EH_ELSE); - gs->gimple_eh_else.e_body = seq; + gimple_statement_eh_else *eh_else_stmt = + as_a <gimple_statement_eh_else> (gs); + eh_else_stmt->e_body = seq; } /* GIMPLE_TRY accessors. */ @@ -3112,7 +3451,7 @@ static inline enum gimple_try_flags gimple_try_kind (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_TRY); - return (enum gimple_try_flags) (gs->gsbase.subcode & GIMPLE_TRY_KIND); + return (enum gimple_try_flags) (gs->subcode & GIMPLE_TRY_KIND); } @@ -3125,7 +3464,7 @@ gimple_try_set_kind (gimple gs, enum gimple_try_flags kind) gcc_gimple_checking_assert (kind == GIMPLE_TRY_CATCH || kind == GIMPLE_TRY_FINALLY); if (gimple_try_kind (gs) != kind) - gs->gsbase.subcode = (unsigned int) kind; + gs->subcode = (unsigned int) kind; } @@ -3135,7 +3474,7 @@ static inline bool gimple_try_catch_is_cleanup (const_gimple gs) { gcc_gimple_checking_assert (gimple_try_kind (gs) == GIMPLE_TRY_CATCH); - return (gs->gsbase.subcode & GIMPLE_TRY_CATCH_IS_CLEANUP) != 0; + return (gs->subcode & GIMPLE_TRY_CATCH_IS_CLEANUP) != 0; } @@ -3145,8 +3484,8 @@ gimple_try_catch_is_cleanup (const_gimple gs) static inline gimple_seq * gimple_try_eval_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_TRY); - return &gs->gimple_try.eval; + gimple_statement_try *try_stmt = as_a <gimple_statement_try> (gs); + return &try_stmt->eval; } @@ -3165,8 +3504,8 @@ gimple_try_eval (gimple gs) static inline gimple_seq * gimple_try_cleanup_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_TRY); - return &gs->gimple_try.cleanup; + gimple_statement_try *try_stmt = as_a <gimple_statement_try> (gs); + return &try_stmt->cleanup; } @@ -3187,9 +3526,9 @@ gimple_try_set_catch_is_cleanup (gimple g, bool catch_is_cleanup) { gcc_gimple_checking_assert (gimple_try_kind (g) == GIMPLE_TRY_CATCH); if (catch_is_cleanup) - g->gsbase.subcode |= GIMPLE_TRY_CATCH_IS_CLEANUP; + g->subcode |= GIMPLE_TRY_CATCH_IS_CLEANUP; else - g->gsbase.subcode &= ~GIMPLE_TRY_CATCH_IS_CLEANUP; + g->subcode &= ~GIMPLE_TRY_CATCH_IS_CLEANUP; } @@ -3199,8 +3538,8 @@ gimple_try_set_catch_is_cleanup (gimple g, bool catch_is_cleanup) static inline void gimple_try_set_eval (gimple gs, gimple_seq eval) { - GIMPLE_CHECK (gs, GIMPLE_TRY); - gs->gimple_try.eval = eval; + gimple_statement_try *try_stmt = as_a <gimple_statement_try> (gs); + try_stmt->eval = eval; } @@ -3210,8 +3549,8 @@ gimple_try_set_eval (gimple gs, gimple_seq eval) static inline void gimple_try_set_cleanup (gimple gs, gimple_seq cleanup) { - GIMPLE_CHECK (gs, GIMPLE_TRY); - gs->gimple_try.cleanup = cleanup; + gimple_statement_try *try_stmt = as_a <gimple_statement_try> (gs); + try_stmt->cleanup = cleanup; } @@ -3220,8 +3559,8 @@ gimple_try_set_cleanup (gimple gs, gimple_seq cleanup) static inline gimple_seq * gimple_wce_cleanup_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR); - return &gs->gimple_wce.cleanup; + gimple_statement_wce *wce_stmt = as_a <gimple_statement_wce> (gs); + return &wce_stmt->cleanup; } @@ -3239,8 +3578,8 @@ gimple_wce_cleanup (gimple gs) static inline void gimple_wce_set_cleanup (gimple gs, gimple_seq cleanup) { - GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR); - gs->gimple_wce.cleanup = cleanup; + gimple_statement_wce *wce_stmt = as_a <gimple_statement_wce> (gs); + wce_stmt->cleanup = cleanup; } @@ -3250,7 +3589,7 @@ static inline bool gimple_wce_cleanup_eh_only (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR); - return gs->gsbase.subcode != 0; + return gs->subcode != 0; } @@ -3260,7 +3599,7 @@ static inline void gimple_wce_set_cleanup_eh_only (gimple gs, bool eh_only_p) { GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR); - gs->gsbase.subcode = (unsigned int) eh_only_p; + gs->subcode = (unsigned int) eh_only_p; } @@ -3269,8 +3608,9 @@ gimple_wce_set_cleanup_eh_only (gimple gs, bool eh_only_p) static inline unsigned gimple_phi_capacity (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - return gs->gimple_phi.capacity; + const gimple_statement_phi *phi_stmt = + as_a <const gimple_statement_phi> (gs); + return phi_stmt->capacity; } @@ -3281,8 +3621,9 @@ gimple_phi_capacity (const_gimple gs) static inline unsigned gimple_phi_num_args (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - return gs->gimple_phi.nargs; + const gimple_statement_phi *phi_stmt = + as_a <const gimple_statement_phi> (gs); + return phi_stmt->nargs; } @@ -3291,8 +3632,9 @@ gimple_phi_num_args (const_gimple gs) static inline tree gimple_phi_result (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - return gs->gimple_phi.result; + const gimple_statement_phi *phi_stmt = + as_a <const gimple_statement_phi> (gs); + return phi_stmt->result; } /* Return a pointer to the SSA name created by GIMPLE_PHI GS. */ @@ -3300,8 +3642,8 @@ gimple_phi_result (const_gimple gs) static inline tree * gimple_phi_result_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - return &gs->gimple_phi.result; + gimple_statement_phi *phi_stmt = as_a <gimple_statement_phi> (gs); + return &phi_stmt->result; } /* Set RESULT to be the SSA name created by GIMPLE_PHI GS. */ @@ -3309,8 +3651,8 @@ gimple_phi_result_ptr (gimple gs) static inline void gimple_phi_set_result (gimple gs, tree result) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - gs->gimple_phi.result = result; + gimple_statement_phi *phi_stmt = as_a <gimple_statement_phi> (gs); + phi_stmt->result = result; if (result && TREE_CODE (result) == SSA_NAME) SSA_NAME_DEF_STMT (result) = gs; } @@ -3322,9 +3664,9 @@ gimple_phi_set_result (gimple gs, tree result) static inline struct phi_arg_d * gimple_phi_arg (gimple gs, unsigned index) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - gcc_gimple_checking_assert (index <= gs->gimple_phi.capacity); - return &(gs->gimple_phi.args[index]); + gimple_statement_phi *phi_stmt = as_a <gimple_statement_phi> (gs); + gcc_gimple_checking_assert (index <= phi_stmt->capacity); + return &(phi_stmt->args[index]); } /* Set PHIARG to be the argument corresponding to incoming edge INDEX @@ -3333,9 +3675,9 @@ gimple_phi_arg (gimple gs, unsigned index) static inline void gimple_phi_set_arg (gimple gs, unsigned index, struct phi_arg_d * phiarg) { - GIMPLE_CHECK (gs, GIMPLE_PHI); - gcc_gimple_checking_assert (index <= gs->gimple_phi.nargs); - gs->gimple_phi.args[index] = *phiarg; + gimple_statement_phi *phi_stmt = as_a <gimple_statement_phi> (gs); + gcc_gimple_checking_assert (index <= phi_stmt->nargs); + phi_stmt->args[index] = *phiarg; } /* Return the PHI nodes for basic block BB, or NULL if there are no @@ -3420,8 +3762,9 @@ gimple_phi_arg_has_location (gimple gs, size_t i) static inline int gimple_resx_region (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_RESX); - return gs->gimple_eh_ctrl.region; + const gimple_statement_eh_ctrl *eh_ctrl_stmt = + as_a <const gimple_statement_eh_ctrl> (gs); + return eh_ctrl_stmt->region; } /* Set REGION to be the region number for GIMPLE_RESX GS. */ @@ -3429,8 +3772,9 @@ gimple_resx_region (const_gimple gs) static inline void gimple_resx_set_region (gimple gs, int region) { - GIMPLE_CHECK (gs, GIMPLE_RESX); - gs->gimple_eh_ctrl.region = region; + gimple_statement_eh_ctrl *eh_ctrl_stmt = + as_a <gimple_statement_eh_ctrl> (gs); + eh_ctrl_stmt->region = region; } /* Return the region number for GIMPLE_EH_DISPATCH GS. */ @@ -3438,8 +3782,9 @@ gimple_resx_set_region (gimple gs, int region) static inline int gimple_eh_dispatch_region (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_EH_DISPATCH); - return gs->gimple_eh_ctrl.region; + const gimple_statement_eh_ctrl *eh_ctrl_stmt = + as_a <const gimple_statement_eh_ctrl> (gs); + return eh_ctrl_stmt->region; } /* Set REGION to be the region number for GIMPLE_EH_DISPATCH GS. */ @@ -3447,8 +3792,9 @@ gimple_eh_dispatch_region (const_gimple gs) static inline void gimple_eh_dispatch_set_region (gimple gs, int region) { - GIMPLE_CHECK (gs, GIMPLE_EH_DISPATCH); - gs->gimple_eh_ctrl.region = region; + gimple_statement_eh_ctrl *eh_ctrl_stmt = + as_a <gimple_statement_eh_ctrl> (gs); + eh_ctrl_stmt->region = region; } /* Return the number of labels associated with the switch statement GS. */ @@ -3561,7 +3907,7 @@ static inline bool gimple_debug_bind_p (const_gimple s) { if (is_gimple_debug (s)) - return s->gsbase.subcode == GIMPLE_DEBUG_BIND; + return s->subcode == GIMPLE_DEBUG_BIND; return false; } @@ -3653,7 +3999,7 @@ static inline bool gimple_debug_source_bind_p (const_gimple s) { if (is_gimple_debug (s)) - return s->gsbase.subcode == GIMPLE_DEBUG_SOURCE_BIND; + return s->subcode == GIMPLE_DEBUG_SOURCE_BIND; return false; } @@ -3758,8 +4104,9 @@ gimple_omp_set_body (gimple gs, gimple_seq body) static inline tree gimple_omp_critical_name (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_CRITICAL); - return gs->gimple_omp_critical.name; + const gimple_statement_omp_critical *omp_critical_stmt = + as_a <const gimple_statement_omp_critical> (gs); + return omp_critical_stmt->name; } @@ -3768,8 +4115,9 @@ gimple_omp_critical_name (const_gimple gs) static inline tree * gimple_omp_critical_name_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_CRITICAL); - return &gs->gimple_omp_critical.name; + gimple_statement_omp_critical *omp_critical_stmt = + as_a <gimple_statement_omp_critical> (gs); + return &omp_critical_stmt->name; } @@ -3778,8 +4126,9 @@ gimple_omp_critical_name_ptr (gimple gs) static inline void gimple_omp_critical_set_name (gimple gs, tree name) { - GIMPLE_CHECK (gs, GIMPLE_OMP_CRITICAL); - gs->gimple_omp_critical.name = name; + gimple_statement_omp_critical *omp_critical_stmt = + as_a <gimple_statement_omp_critical> (gs); + omp_critical_stmt->name = name; } @@ -3799,7 +4148,7 @@ static inline void gimple_omp_for_set_kind (gimple g, int kind) { GIMPLE_CHECK (g, GIMPLE_OMP_FOR); - g->gsbase.subcode = (g->gsbase.subcode & ~GF_OMP_FOR_KIND_MASK) + g->subcode = (g->subcode & ~GF_OMP_FOR_KIND_MASK) | (kind & GF_OMP_FOR_KIND_MASK); } @@ -3823,9 +4172,9 @@ gimple_omp_for_set_combined_p (gimple g, bool combined_p) { GIMPLE_CHECK (g, GIMPLE_OMP_FOR); if (combined_p) - g->gsbase.subcode |= GF_OMP_FOR_COMBINED; + g->subcode |= GF_OMP_FOR_COMBINED; else - g->gsbase.subcode &= ~GF_OMP_FOR_COMBINED; + g->subcode &= ~GF_OMP_FOR_COMBINED; } @@ -3848,9 +4197,9 @@ gimple_omp_for_set_combined_into_p (gimple g, bool combined_p) { GIMPLE_CHECK (g, GIMPLE_OMP_FOR); if (combined_p) - g->gsbase.subcode |= GF_OMP_FOR_COMBINED_INTO; + g->subcode |= GF_OMP_FOR_COMBINED_INTO; else - g->gsbase.subcode &= ~GF_OMP_FOR_COMBINED_INTO; + g->subcode &= ~GF_OMP_FOR_COMBINED_INTO; } @@ -3859,8 +4208,9 @@ gimple_omp_for_set_combined_into_p (gimple g, bool combined_p) static inline tree gimple_omp_for_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - return gs->gimple_omp_for.clauses; + const gimple_statement_omp_for *omp_for_stmt = + as_a <const gimple_statement_omp_for> (gs); + return omp_for_stmt->clauses; } @@ -3869,8 +4219,9 @@ gimple_omp_for_clauses (const_gimple gs) static inline tree * gimple_omp_for_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - return &gs->gimple_omp_for.clauses; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + return &omp_for_stmt->clauses; } @@ -3879,8 +4230,9 @@ gimple_omp_for_clauses_ptr (gimple gs) static inline void gimple_omp_for_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gs->gimple_omp_for.clauses = clauses; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + omp_for_stmt->clauses = clauses; } @@ -3889,8 +4241,9 @@ gimple_omp_for_set_clauses (gimple gs, tree clauses) static inline size_t gimple_omp_for_collapse (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - return gs->gimple_omp_for.collapse; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + return omp_for_stmt->collapse; } @@ -3899,9 +4252,10 @@ gimple_omp_for_collapse (gimple gs) static inline tree gimple_omp_for_index (const_gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return gs->gimple_omp_for.iter[i].index; + const gimple_statement_omp_for *omp_for_stmt = + as_a <const gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return omp_for_stmt->iter[i].index; } @@ -3910,9 +4264,10 @@ gimple_omp_for_index (const_gimple gs, size_t i) static inline tree * gimple_omp_for_index_ptr (gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return &gs->gimple_omp_for.iter[i].index; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return &omp_for_stmt->iter[i].index; } @@ -3921,9 +4276,10 @@ gimple_omp_for_index_ptr (gimple gs, size_t i) static inline void gimple_omp_for_set_index (gimple gs, size_t i, tree index) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - gs->gimple_omp_for.iter[i].index = index; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + omp_for_stmt->iter[i].index = index; } @@ -3932,9 +4288,10 @@ gimple_omp_for_set_index (gimple gs, size_t i, tree index) static inline tree gimple_omp_for_initial (const_gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return gs->gimple_omp_for.iter[i].initial; + const gimple_statement_omp_for *omp_for_stmt = + as_a <const gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return omp_for_stmt->iter[i].initial; } @@ -3943,9 +4300,10 @@ gimple_omp_for_initial (const_gimple gs, size_t i) static inline tree * gimple_omp_for_initial_ptr (gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return &gs->gimple_omp_for.iter[i].initial; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return &omp_for_stmt->iter[i].initial; } @@ -3954,9 +4312,10 @@ gimple_omp_for_initial_ptr (gimple gs, size_t i) static inline void gimple_omp_for_set_initial (gimple gs, size_t i, tree initial) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - gs->gimple_omp_for.iter[i].initial = initial; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + omp_for_stmt->iter[i].initial = initial; } @@ -3965,9 +4324,10 @@ gimple_omp_for_set_initial (gimple gs, size_t i, tree initial) static inline tree gimple_omp_for_final (const_gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return gs->gimple_omp_for.iter[i].final; + const gimple_statement_omp_for *omp_for_stmt = + as_a <const gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return omp_for_stmt->iter[i].final; } @@ -3976,9 +4336,10 @@ gimple_omp_for_final (const_gimple gs, size_t i) static inline tree * gimple_omp_for_final_ptr (gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return &gs->gimple_omp_for.iter[i].final; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return &omp_for_stmt->iter[i].final; } @@ -3987,9 +4348,10 @@ gimple_omp_for_final_ptr (gimple gs, size_t i) static inline void gimple_omp_for_set_final (gimple gs, size_t i, tree final) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - gs->gimple_omp_for.iter[i].final = final; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + omp_for_stmt->iter[i].final = final; } @@ -3998,9 +4360,10 @@ gimple_omp_for_set_final (gimple gs, size_t i, tree final) static inline tree gimple_omp_for_incr (const_gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return gs->gimple_omp_for.iter[i].incr; + const gimple_statement_omp_for *omp_for_stmt = + as_a <const gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return omp_for_stmt->iter[i].incr; } @@ -4009,9 +4372,10 @@ gimple_omp_for_incr (const_gimple gs, size_t i) static inline tree * gimple_omp_for_incr_ptr (gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return &gs->gimple_omp_for.iter[i].incr; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return &omp_for_stmt->iter[i].incr; } @@ -4020,9 +4384,10 @@ gimple_omp_for_incr_ptr (gimple gs, size_t i) static inline void gimple_omp_for_set_incr (gimple gs, size_t i, tree incr) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - gs->gimple_omp_for.iter[i].incr = incr; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + omp_for_stmt->iter[i].incr = incr; } @@ -4032,8 +4397,9 @@ gimple_omp_for_set_incr (gimple gs, size_t i, tree incr) static inline gimple_seq * gimple_omp_for_pre_body_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - return &gs->gimple_omp_for.pre_body; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + return &omp_for_stmt->pre_body; } @@ -4053,8 +4419,9 @@ gimple_omp_for_pre_body (gimple gs) static inline void gimple_omp_for_set_pre_body (gimple gs, gimple_seq pre_body) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gs->gimple_omp_for.pre_body = pre_body; + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); + omp_for_stmt->pre_body = pre_body; } @@ -4063,8 +4430,9 @@ gimple_omp_for_set_pre_body (gimple gs, gimple_seq pre_body) static inline tree gimple_omp_parallel_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - return gs->gimple_omp_parallel.clauses; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->clauses; } @@ -4073,8 +4441,9 @@ gimple_omp_parallel_clauses (const_gimple gs) static inline tree * gimple_omp_parallel_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - return &gs->gimple_omp_parallel.clauses; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->clauses; } @@ -4084,8 +4453,9 @@ gimple_omp_parallel_clauses_ptr (gimple gs) static inline void gimple_omp_parallel_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - gs->gimple_omp_parallel.clauses = clauses; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->clauses = clauses; } @@ -4094,8 +4464,9 @@ gimple_omp_parallel_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_parallel_child_fn (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - return gs->gimple_omp_parallel.child_fn; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->child_fn; } /* Return a pointer to the child function used to hold the body of @@ -4104,8 +4475,9 @@ gimple_omp_parallel_child_fn (const_gimple gs) static inline tree * gimple_omp_parallel_child_fn_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - return &gs->gimple_omp_parallel.child_fn; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->child_fn; } @@ -4114,8 +4486,9 @@ gimple_omp_parallel_child_fn_ptr (gimple gs) static inline void gimple_omp_parallel_set_child_fn (gimple gs, tree child_fn) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - gs->gimple_omp_parallel.child_fn = child_fn; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->child_fn = child_fn; } @@ -4125,8 +4498,9 @@ gimple_omp_parallel_set_child_fn (gimple gs, tree child_fn) static inline tree gimple_omp_parallel_data_arg (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - return gs->gimple_omp_parallel.data_arg; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->data_arg; } @@ -4135,8 +4509,9 @@ gimple_omp_parallel_data_arg (const_gimple gs) static inline tree * gimple_omp_parallel_data_arg_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - return &gs->gimple_omp_parallel.data_arg; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->data_arg; } @@ -4145,8 +4520,9 @@ gimple_omp_parallel_data_arg_ptr (gimple gs) static inline void gimple_omp_parallel_set_data_arg (gimple gs, tree data_arg) { - GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL); - gs->gimple_omp_parallel.data_arg = data_arg; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->data_arg = data_arg; } @@ -4155,8 +4531,9 @@ gimple_omp_parallel_set_data_arg (gimple gs, tree data_arg) static inline tree gimple_omp_task_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_parallel.clauses; + const gimple_statement_omp_task *omp_task_stmt = + as_a <const gimple_statement_omp_task> (gs); + return omp_task_stmt->clauses; } @@ -4165,8 +4542,9 @@ gimple_omp_task_clauses (const_gimple gs) static inline tree * gimple_omp_task_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_parallel.clauses; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + return &omp_task_stmt->clauses; } @@ -4176,8 +4554,9 @@ gimple_omp_task_clauses_ptr (gimple gs) static inline void gimple_omp_task_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_parallel.clauses = clauses; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + omp_task_stmt->clauses = clauses; } @@ -4186,8 +4565,9 @@ gimple_omp_task_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_task_child_fn (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_parallel.child_fn; + const gimple_statement_omp_task *omp_task_stmt = + as_a <const gimple_statement_omp_task> (gs); + return omp_task_stmt->child_fn; } /* Return a pointer to the child function used to hold the body of @@ -4196,8 +4576,9 @@ gimple_omp_task_child_fn (const_gimple gs) static inline tree * gimple_omp_task_child_fn_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_parallel.child_fn; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + return &omp_task_stmt->child_fn; } @@ -4206,8 +4587,9 @@ gimple_omp_task_child_fn_ptr (gimple gs) static inline void gimple_omp_task_set_child_fn (gimple gs, tree child_fn) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_parallel.child_fn = child_fn; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + omp_task_stmt->child_fn = child_fn; } @@ -4217,8 +4599,9 @@ gimple_omp_task_set_child_fn (gimple gs, tree child_fn) static inline tree gimple_omp_task_data_arg (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_parallel.data_arg; + const gimple_statement_omp_task *omp_task_stmt = + as_a <const gimple_statement_omp_task> (gs); + return omp_task_stmt->data_arg; } @@ -4227,8 +4610,9 @@ gimple_omp_task_data_arg (const_gimple gs) static inline tree * gimple_omp_task_data_arg_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_parallel.data_arg; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + return &omp_task_stmt->data_arg; } @@ -4237,8 +4621,9 @@ gimple_omp_task_data_arg_ptr (gimple gs) static inline void gimple_omp_task_set_data_arg (gimple gs, tree data_arg) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_parallel.data_arg = data_arg; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + omp_task_stmt->data_arg = data_arg; } @@ -4247,9 +4632,9 @@ gimple_omp_task_set_data_arg (gimple gs, tree data_arg) static inline tree gimple_omp_taskreg_clauses (const_gimple gs) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_parallel.clauses; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->clauses; } @@ -4258,9 +4643,9 @@ gimple_omp_taskreg_clauses (const_gimple gs) static inline tree * gimple_omp_taskreg_clauses_ptr (gimple gs) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_parallel.clauses; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->clauses; } @@ -4270,9 +4655,9 @@ gimple_omp_taskreg_clauses_ptr (gimple gs) static inline void gimple_omp_taskreg_set_clauses (gimple gs, tree clauses) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_parallel.clauses = clauses; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->clauses = clauses; } @@ -4281,9 +4666,9 @@ gimple_omp_taskreg_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_taskreg_child_fn (const_gimple gs) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_parallel.child_fn; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->child_fn; } /* Return a pointer to the child function used to hold the body of @@ -4292,9 +4677,9 @@ gimple_omp_taskreg_child_fn (const_gimple gs) static inline tree * gimple_omp_taskreg_child_fn_ptr (gimple gs) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_parallel.child_fn; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->child_fn; } @@ -4303,9 +4688,9 @@ gimple_omp_taskreg_child_fn_ptr (gimple gs) static inline void gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_parallel.child_fn = child_fn; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->child_fn = child_fn; } @@ -4315,9 +4700,9 @@ gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn) static inline tree gimple_omp_taskreg_data_arg (const_gimple gs) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_parallel.data_arg; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->data_arg; } @@ -4326,9 +4711,9 @@ gimple_omp_taskreg_data_arg (const_gimple gs) static inline tree * gimple_omp_taskreg_data_arg_ptr (gimple gs) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_parallel.data_arg; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->data_arg; } @@ -4337,9 +4722,9 @@ gimple_omp_taskreg_data_arg_ptr (gimple gs) static inline void gimple_omp_taskreg_set_data_arg (gimple gs, tree data_arg) { - if (gimple_code (gs) != GIMPLE_OMP_PARALLEL) - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_parallel.data_arg = data_arg; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->data_arg = data_arg; } @@ -4348,8 +4733,9 @@ gimple_omp_taskreg_set_data_arg (gimple gs, tree data_arg) static inline tree gimple_omp_task_copy_fn (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_task.copy_fn; + const gimple_statement_omp_task *omp_task_stmt = + as_a <const gimple_statement_omp_task> (gs); + return omp_task_stmt->copy_fn; } /* Return a pointer to the copy function used to hold the body of @@ -4358,8 +4744,9 @@ gimple_omp_task_copy_fn (const_gimple gs) static inline tree * gimple_omp_task_copy_fn_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_task.copy_fn; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + return &omp_task_stmt->copy_fn; } @@ -4368,8 +4755,9 @@ gimple_omp_task_copy_fn_ptr (gimple gs) static inline void gimple_omp_task_set_copy_fn (gimple gs, tree copy_fn) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_task.copy_fn = copy_fn; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + omp_task_stmt->copy_fn = copy_fn; } @@ -4378,8 +4766,9 @@ gimple_omp_task_set_copy_fn (gimple gs, tree copy_fn) static inline tree gimple_omp_task_arg_size (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_task.arg_size; + const gimple_statement_omp_task *omp_task_stmt = + as_a <const gimple_statement_omp_task> (gs); + return omp_task_stmt->arg_size; } @@ -4388,8 +4777,9 @@ gimple_omp_task_arg_size (const_gimple gs) static inline tree * gimple_omp_task_arg_size_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_task.arg_size; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + return &omp_task_stmt->arg_size; } @@ -4398,8 +4788,9 @@ gimple_omp_task_arg_size_ptr (gimple gs) static inline void gimple_omp_task_set_arg_size (gimple gs, tree arg_size) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_task.arg_size = arg_size; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + omp_task_stmt->arg_size = arg_size; } @@ -4408,8 +4799,9 @@ gimple_omp_task_set_arg_size (gimple gs, tree arg_size) static inline tree gimple_omp_task_arg_align (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return gs->gimple_omp_task.arg_align; + const gimple_statement_omp_task *omp_task_stmt = + as_a <const gimple_statement_omp_task> (gs); + return omp_task_stmt->arg_align; } @@ -4418,8 +4810,9 @@ gimple_omp_task_arg_align (const_gimple gs) static inline tree * gimple_omp_task_arg_align_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - return &gs->gimple_omp_task.arg_align; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + return &omp_task_stmt->arg_align; } @@ -4428,8 +4821,9 @@ gimple_omp_task_arg_align_ptr (gimple gs) static inline void gimple_omp_task_set_arg_align (gimple gs, tree arg_align) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TASK); - gs->gimple_omp_task.arg_align = arg_align; + gimple_statement_omp_task *omp_task_stmt = + as_a <gimple_statement_omp_task> (gs); + omp_task_stmt->arg_align = arg_align; } @@ -4438,8 +4832,9 @@ gimple_omp_task_set_arg_align (gimple gs, tree arg_align) static inline tree gimple_omp_single_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SINGLE); - return gs->gimple_omp_single.clauses; + const gimple_statement_omp_single *omp_single_stmt = + as_a <const gimple_statement_omp_single> (gs); + return omp_single_stmt->clauses; } @@ -4448,8 +4843,9 @@ gimple_omp_single_clauses (const_gimple gs) static inline tree * gimple_omp_single_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SINGLE); - return &gs->gimple_omp_single.clauses; + gimple_statement_omp_single *omp_single_stmt = + as_a <gimple_statement_omp_single> (gs); + return &omp_single_stmt->clauses; } @@ -4458,8 +4854,9 @@ gimple_omp_single_clauses_ptr (gimple gs) static inline void gimple_omp_single_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SINGLE); - gs->gimple_omp_single.clauses = clauses; + gimple_statement_omp_single *omp_single_stmt = + as_a <gimple_statement_omp_single> (gs); + omp_single_stmt->clauses = clauses; } @@ -4468,8 +4865,9 @@ gimple_omp_single_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_target_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - return gs->gimple_omp_parallel.clauses; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->clauses; } @@ -4478,8 +4876,9 @@ gimple_omp_target_clauses (const_gimple gs) static inline tree * gimple_omp_target_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - return &gs->gimple_omp_parallel.clauses; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->clauses; } @@ -4488,8 +4887,9 @@ gimple_omp_target_clauses_ptr (gimple gs) static inline void gimple_omp_target_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - gs->gimple_omp_parallel.clauses = clauses; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->clauses = clauses; } @@ -4509,7 +4909,7 @@ static inline void gimple_omp_target_set_kind (gimple g, int kind) { GIMPLE_CHECK (g, GIMPLE_OMP_TARGET); - g->gsbase.subcode = (g->gsbase.subcode & ~GF_OMP_TARGET_KIND_MASK) + g->subcode = (g->subcode & ~GF_OMP_TARGET_KIND_MASK) | (kind & GF_OMP_TARGET_KIND_MASK); } @@ -4519,8 +4919,9 @@ gimple_omp_target_set_kind (gimple g, int kind) static inline tree gimple_omp_target_child_fn (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - return gs->gimple_omp_parallel.child_fn; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->child_fn; } /* Return a pointer to the child function used to hold the body of @@ -4529,8 +4930,9 @@ gimple_omp_target_child_fn (const_gimple gs) static inline tree * gimple_omp_target_child_fn_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - return &gs->gimple_omp_parallel.child_fn; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->child_fn; } @@ -4539,8 +4941,9 @@ gimple_omp_target_child_fn_ptr (gimple gs) static inline void gimple_omp_target_set_child_fn (gimple gs, tree child_fn) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - gs->gimple_omp_parallel.child_fn = child_fn; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->child_fn = child_fn; } @@ -4550,8 +4953,9 @@ gimple_omp_target_set_child_fn (gimple gs, tree child_fn) static inline tree gimple_omp_target_data_arg (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - return gs->gimple_omp_parallel.data_arg; + const gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <const gimple_statement_omp_parallel> (gs); + return omp_parallel_stmt->data_arg; } @@ -4560,8 +4964,9 @@ gimple_omp_target_data_arg (const_gimple gs) static inline tree * gimple_omp_target_data_arg_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - return &gs->gimple_omp_parallel.data_arg; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + return &omp_parallel_stmt->data_arg; } @@ -4570,8 +4975,9 @@ gimple_omp_target_data_arg_ptr (gimple gs) static inline void gimple_omp_target_set_data_arg (gimple gs, tree data_arg) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TARGET); - gs->gimple_omp_parallel.data_arg = data_arg; + gimple_statement_omp_parallel *omp_parallel_stmt = + as_a <gimple_statement_omp_parallel> (gs); + omp_parallel_stmt->data_arg = data_arg; } @@ -4580,8 +4986,9 @@ gimple_omp_target_set_data_arg (gimple gs, tree data_arg) static inline tree gimple_omp_teams_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TEAMS); - return gs->gimple_omp_single.clauses; + const gimple_statement_omp_single *omp_single_stmt = + as_a <const gimple_statement_omp_single> (gs); + return omp_single_stmt->clauses; } @@ -4590,8 +4997,9 @@ gimple_omp_teams_clauses (const_gimple gs) static inline tree * gimple_omp_teams_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TEAMS); - return &gs->gimple_omp_single.clauses; + gimple_statement_omp_single *omp_single_stmt = + as_a <gimple_statement_omp_single> (gs); + return &omp_single_stmt->clauses; } @@ -4600,8 +5008,9 @@ gimple_omp_teams_clauses_ptr (gimple gs) static inline void gimple_omp_teams_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_TEAMS); - gs->gimple_omp_single.clauses = clauses; + gimple_statement_omp_single *omp_single_stmt = + as_a <gimple_statement_omp_single> (gs); + omp_single_stmt->clauses = clauses; } @@ -4610,8 +5019,9 @@ gimple_omp_teams_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_sections_clauses (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); - return gs->gimple_omp_sections.clauses; + const gimple_statement_omp_sections *omp_sections_stmt = + as_a <const gimple_statement_omp_sections> (gs); + return omp_sections_stmt->clauses; } @@ -4620,8 +5030,9 @@ gimple_omp_sections_clauses (const_gimple gs) static inline tree * gimple_omp_sections_clauses_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); - return &gs->gimple_omp_sections.clauses; + gimple_statement_omp_sections *omp_sections_stmt = + as_a <gimple_statement_omp_sections> (gs); + return &omp_sections_stmt->clauses; } @@ -4631,8 +5042,9 @@ gimple_omp_sections_clauses_ptr (gimple gs) static inline void gimple_omp_sections_set_clauses (gimple gs, tree clauses) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); - gs->gimple_omp_sections.clauses = clauses; + gimple_statement_omp_sections *omp_sections_stmt = + as_a <gimple_statement_omp_sections> (gs); + omp_sections_stmt->clauses = clauses; } @@ -4642,8 +5054,9 @@ gimple_omp_sections_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_sections_control (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); - return gs->gimple_omp_sections.control; + const gimple_statement_omp_sections *omp_sections_stmt = + as_a <const gimple_statement_omp_sections> (gs); + return omp_sections_stmt->control; } @@ -4653,8 +5066,9 @@ gimple_omp_sections_control (const_gimple gs) static inline tree * gimple_omp_sections_control_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); - return &gs->gimple_omp_sections.control; + gimple_statement_omp_sections *omp_sections_stmt = + as_a <gimple_statement_omp_sections> (gs); + return &omp_sections_stmt->control; } @@ -4664,8 +5078,9 @@ gimple_omp_sections_control_ptr (gimple gs) static inline void gimple_omp_sections_set_control (gimple gs, tree control) { - GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS); - gs->gimple_omp_sections.control = control; + gimple_statement_omp_sections *omp_sections_stmt = + as_a <gimple_statement_omp_sections> (gs); + omp_sections_stmt->control = control; } @@ -4674,10 +5089,11 @@ gimple_omp_sections_set_control (gimple gs, tree control) static inline void gimple_omp_for_set_cond (gimple gs, size_t i, enum tree_code cond) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); + gimple_statement_omp_for *omp_for_stmt = + as_a <gimple_statement_omp_for> (gs); gcc_gimple_checking_assert (TREE_CODE_CLASS (cond) == tcc_comparison - && i < gs->gimple_omp_for.collapse); - gs->gimple_omp_for.iter[i].cond = cond; + && i < omp_for_stmt->collapse); + omp_for_stmt->iter[i].cond = cond; } @@ -4686,9 +5102,10 @@ gimple_omp_for_set_cond (gimple gs, size_t i, enum tree_code cond) static inline enum tree_code gimple_omp_for_cond (const_gimple gs, size_t i) { - GIMPLE_CHECK (gs, GIMPLE_OMP_FOR); - gcc_gimple_checking_assert (i < gs->gimple_omp_for.collapse); - return gs->gimple_omp_for.iter[i].cond; + const gimple_statement_omp_for *omp_for_stmt = + as_a <const gimple_statement_omp_for> (gs); + gcc_gimple_checking_assert (i < omp_for_stmt->collapse); + return omp_for_stmt->iter[i].cond; } @@ -4697,8 +5114,9 @@ gimple_omp_for_cond (const_gimple gs, size_t i) static inline void gimple_omp_atomic_store_set_val (gimple g, tree val) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); - g->gimple_omp_atomic_store.val = val; + gimple_statement_omp_atomic_store *omp_atomic_store_stmt = + as_a <gimple_statement_omp_atomic_store> (g); + omp_atomic_store_stmt->val = val; } @@ -4707,8 +5125,9 @@ gimple_omp_atomic_store_set_val (gimple g, tree val) static inline tree gimple_omp_atomic_store_val (const_gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); - return g->gimple_omp_atomic_store.val; + const gimple_statement_omp_atomic_store *omp_atomic_store_stmt = + as_a <const gimple_statement_omp_atomic_store> (g); + return omp_atomic_store_stmt->val; } @@ -4717,8 +5136,9 @@ gimple_omp_atomic_store_val (const_gimple g) static inline tree * gimple_omp_atomic_store_val_ptr (gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); - return &g->gimple_omp_atomic_store.val; + gimple_statement_omp_atomic_store *omp_atomic_store_stmt = + as_a <gimple_statement_omp_atomic_store> (g); + return &omp_atomic_store_stmt->val; } @@ -4727,8 +5147,9 @@ gimple_omp_atomic_store_val_ptr (gimple g) static inline void gimple_omp_atomic_load_set_lhs (gimple g, tree lhs) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); - g->gimple_omp_atomic_load.lhs = lhs; + gimple_statement_omp_atomic_load *omp_atomic_load_stmt = + as_a <gimple_statement_omp_atomic_load> (g); + omp_atomic_load_stmt->lhs = lhs; } @@ -4737,8 +5158,9 @@ gimple_omp_atomic_load_set_lhs (gimple g, tree lhs) static inline tree gimple_omp_atomic_load_lhs (const_gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); - return g->gimple_omp_atomic_load.lhs; + const gimple_statement_omp_atomic_load *omp_atomic_load_stmt = + as_a <const gimple_statement_omp_atomic_load> (g); + return omp_atomic_load_stmt->lhs; } @@ -4747,8 +5169,9 @@ gimple_omp_atomic_load_lhs (const_gimple g) static inline tree * gimple_omp_atomic_load_lhs_ptr (gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); - return &g->gimple_omp_atomic_load.lhs; + gimple_statement_omp_atomic_load *omp_atomic_load_stmt = + as_a <gimple_statement_omp_atomic_load> (g); + return &omp_atomic_load_stmt->lhs; } @@ -4757,8 +5180,9 @@ gimple_omp_atomic_load_lhs_ptr (gimple g) static inline void gimple_omp_atomic_load_set_rhs (gimple g, tree rhs) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); - g->gimple_omp_atomic_load.rhs = rhs; + gimple_statement_omp_atomic_load *omp_atomic_load_stmt = + as_a <gimple_statement_omp_atomic_load> (g); + omp_atomic_load_stmt->rhs = rhs; } @@ -4767,8 +5191,9 @@ gimple_omp_atomic_load_set_rhs (gimple g, tree rhs) static inline tree gimple_omp_atomic_load_rhs (const_gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); - return g->gimple_omp_atomic_load.rhs; + const gimple_statement_omp_atomic_load *omp_atomic_load_stmt = + as_a <const gimple_statement_omp_atomic_load> (g); + return omp_atomic_load_stmt->rhs; } @@ -4777,8 +5202,9 @@ gimple_omp_atomic_load_rhs (const_gimple g) static inline tree * gimple_omp_atomic_load_rhs_ptr (gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD); - return &g->gimple_omp_atomic_load.rhs; + gimple_statement_omp_atomic_load *omp_atomic_load_stmt = + as_a <gimple_statement_omp_atomic_load> (g); + return &omp_atomic_load_stmt->rhs; } @@ -4787,8 +5213,9 @@ gimple_omp_atomic_load_rhs_ptr (gimple g) static inline tree gimple_omp_continue_control_def (const_gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); - return g->gimple_omp_continue.control_def; + const gimple_statement_omp_continue *omp_continue_stmt = + as_a <const gimple_statement_omp_continue> (g); + return omp_continue_stmt->control_def; } /* The same as above, but return the address. */ @@ -4796,8 +5223,9 @@ gimple_omp_continue_control_def (const_gimple g) static inline tree * gimple_omp_continue_control_def_ptr (gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); - return &g->gimple_omp_continue.control_def; + gimple_statement_omp_continue *omp_continue_stmt = + as_a <gimple_statement_omp_continue> (g); + return &omp_continue_stmt->control_def; } /* Set the definition of the control variable in a GIMPLE_OMP_CONTINUE. */ @@ -4805,8 +5233,9 @@ gimple_omp_continue_control_def_ptr (gimple g) static inline void gimple_omp_continue_set_control_def (gimple g, tree def) { - GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); - g->gimple_omp_continue.control_def = def; + gimple_statement_omp_continue *omp_continue_stmt = + as_a <gimple_statement_omp_continue> (g); + omp_continue_stmt->control_def = def; } @@ -4815,8 +5244,9 @@ gimple_omp_continue_set_control_def (gimple g, tree def) static inline tree gimple_omp_continue_control_use (const_gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); - return g->gimple_omp_continue.control_use; + const gimple_statement_omp_continue *omp_continue_stmt = + as_a <const gimple_statement_omp_continue> (g); + return omp_continue_stmt->control_use; } @@ -4825,8 +5255,9 @@ gimple_omp_continue_control_use (const_gimple g) static inline tree * gimple_omp_continue_control_use_ptr (gimple g) { - GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); - return &g->gimple_omp_continue.control_use; + gimple_statement_omp_continue *omp_continue_stmt = + as_a <gimple_statement_omp_continue> (g); + return &omp_continue_stmt->control_use; } @@ -4835,8 +5266,9 @@ gimple_omp_continue_control_use_ptr (gimple g) static inline void gimple_omp_continue_set_control_use (gimple g, tree use) { - GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE); - g->gimple_omp_continue.control_use = use; + gimple_statement_omp_continue *omp_continue_stmt = + as_a <gimple_statement_omp_continue> (g); + omp_continue_stmt->control_use = use; } /* Return a pointer to the body for the GIMPLE_TRANSACTION statement GS. */ @@ -4844,8 +5276,9 @@ gimple_omp_continue_set_control_use (gimple g, tree use) static inline gimple_seq * gimple_transaction_body_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - return &gs->gimple_transaction.body; + gimple_statement_transaction *transaction_stmt = + as_a <gimple_statement_transaction> (gs); + return &transaction_stmt->body; } /* Return the body for the GIMPLE_TRANSACTION statement GS. */ @@ -4861,15 +5294,17 @@ gimple_transaction_body (gimple gs) static inline tree gimple_transaction_label (const_gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - return gs->gimple_transaction.label; + const gimple_statement_transaction *transaction_stmt = + as_a <const gimple_statement_transaction> (gs); + return transaction_stmt->label; } static inline tree * gimple_transaction_label_ptr (gimple gs) { - GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - return &gs->gimple_transaction.label; + gimple_statement_transaction *transaction_stmt = + as_a <gimple_statement_transaction> (gs); + return &transaction_stmt->label; } /* Return the subcode associated with a GIMPLE_TRANSACTION. */ @@ -4878,7 +5313,7 @@ static inline unsigned int gimple_transaction_subcode (const_gimple gs) { GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - return gs->gsbase.subcode; + return gs->subcode; } /* Set BODY to be the body for the GIMPLE_TRANSACTION statement GS. */ @@ -4886,8 +5321,9 @@ gimple_transaction_subcode (const_gimple gs) static inline void gimple_transaction_set_body (gimple gs, gimple_seq body) { - GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - gs->gimple_transaction.body = body; + gimple_statement_transaction *transaction_stmt = + as_a <gimple_statement_transaction> (gs); + transaction_stmt->body = body; } /* Set the label associated with a GIMPLE_TRANSACTION. */ @@ -4895,8 +5331,9 @@ gimple_transaction_set_body (gimple gs, gimple_seq body) static inline void gimple_transaction_set_label (gimple gs, tree label) { - GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - gs->gimple_transaction.label = label; + gimple_statement_transaction *transaction_stmt = + as_a <gimple_statement_transaction> (gs); + transaction_stmt->label = label; } /* Set the subcode associated with a GIMPLE_TRANSACTION. */ @@ -4905,7 +5342,7 @@ static inline void gimple_transaction_set_subcode (gimple gs, unsigned int subcode) { GIMPLE_CHECK (gs, GIMPLE_TRANSACTION); - gs->gsbase.subcode = subcode; + gs->subcode = subcode; } @@ -5015,7 +5452,7 @@ static inline enum br_predictor gimple_predict_predictor (gimple gs) { GIMPLE_CHECK (gs, GIMPLE_PREDICT); - return (enum br_predictor) (gs->gsbase.subcode & ~GF_PREDICT_TAKEN); + return (enum br_predictor) (gs->subcode & ~GF_PREDICT_TAKEN); } @@ -5025,7 +5462,7 @@ static inline void gimple_predict_set_predictor (gimple gs, enum br_predictor predictor) { GIMPLE_CHECK (gs, GIMPLE_PREDICT); - gs->gsbase.subcode = (gs->gsbase.subcode & GF_PREDICT_TAKEN) + gs->subcode = (gs->subcode & GF_PREDICT_TAKEN) | (unsigned) predictor; } @@ -5036,7 +5473,7 @@ static inline enum prediction gimple_predict_outcome (gimple gs) { GIMPLE_CHECK (gs, GIMPLE_PREDICT); - return (gs->gsbase.subcode & GF_PREDICT_TAKEN) ? TAKEN : NOT_TAKEN; + return (gs->subcode & GF_PREDICT_TAKEN) ? TAKEN : NOT_TAKEN; } @@ -5047,9 +5484,9 @@ gimple_predict_set_outcome (gimple gs, enum prediction outcome) { GIMPLE_CHECK (gs, GIMPLE_PREDICT); if (outcome == TAKEN) - gs->gsbase.subcode |= GF_PREDICT_TAKEN; + gs->subcode |= GF_PREDICT_TAKEN; else - gs->gsbase.subcode &= ~GF_PREDICT_TAKEN; + gs->subcode &= ~GF_PREDICT_TAKEN; } diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index caecbf2..9e52d1a 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -2631,7 +2631,7 @@ copy_debug_stmt (gimple stmt, copy_body_data *id) && TREE_CODE ((**debug_args)[i + 1]) == DEBUG_EXPR_DECL) { t = (**debug_args)[i + 1]; - stmt->gsbase.subcode = GIMPLE_DEBUG_BIND; + stmt->subcode = GIMPLE_DEBUG_BIND; gimple_debug_bind_set_value (stmt, t); break; } diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c index da7bf5b..417d5b5 100644 --- a/gcc/tree-phinodes.c +++ b/gcc/tree-phinodes.c @@ -184,7 +184,7 @@ make_phi_node (tree var, int len) memset (phi, 0, (sizeof (struct gimple_statement_phi) - sizeof (struct phi_arg_d) + sizeof (struct phi_arg_d) * len)); - phi->gsbase.code = GIMPLE_PHI; + phi->code = GIMPLE_PHI; gimple_init_singleton (phi); phi->gimple_phi.nargs = len; phi->gimple_phi.capacity = capacity; -- 1.7.11.7 ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Updated automated patch (was Re: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance) 2013-11-18 22:17 ` [PATCH] Updated automated patch (was Re: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance) David Malcolm @ 2013-11-19 8:49 ` Jeff Law 2013-11-19 16:36 ` David Malcolm 2013-11-22 0:27 ` Jakub Jelinek 1 sibling, 1 reply; 116+ messages in thread From: Jeff Law @ 2013-11-19 8:49 UTC (permalink / raw) To: David Malcolm; +Cc: gcc-patches, Andrew MacLeod On 11/18/13 13:25, David Malcolm wrote: > > I regenerated it and am bootstrapping now. I glanced over it and > nothing major seems to have changed; just changes due to the movement of > code between files. Am attaching the changed patch. Yea, there's a lot of churn right now, so this is kind-of expected. Thanks for re-posting and verifying it's good to go. Never hurts to be careful. > > I think so, yes, though you'll have to cast it to the appropriate > subclass by hand; rather than the status quo of getting multiple > screenfuls of text, you'll just get the gimple_statement_base fields: Right. It's parsing the pages of text that I find to be a totally pointless waste of time. It's gotten worse, mostly because I was away for too long and I don't have the accessors in muscle-memory. WRT elimination of the GIMPLE_CHECKs, understood on the state of things and why the script didn't eliminate them in the various places I pointed out. This is fine. Please install. Thanks, jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Updated automated patch (was Re: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance) 2013-11-19 8:49 ` Jeff Law @ 2013-11-19 16:36 ` David Malcolm 0 siblings, 0 replies; 116+ messages in thread From: David Malcolm @ 2013-11-19 16:36 UTC (permalink / raw) To: Jeff Law; +Cc: gcc-patches, Andrew MacLeod On Mon, 2013-11-18 at 22:13 -0700, Jeff Law wrote: > On 11/18/13 13:25, David Malcolm wrote: > > > > I regenerated it and am bootstrapping now. I glanced over it and > > nothing major seems to have changed; just changes due to the movement of > > code between files. Am attaching the changed patch. > Yea, there's a lot of churn right now, so this is kind-of expected. > > Thanks for re-posting and verifying it's good to go. Never hurts to be > careful. > > > > > I think so, yes, though you'll have to cast it to the appropriate > > subclass by hand; rather than the status quo of getting multiple > > screenfuls of text, you'll just get the gimple_statement_base fields: > Right. It's parsing the pages of text that I find to be a totally > pointless waste of time. It's gotten worse, mostly because I was away > for too long and I don't have the accessors in muscle-memory. > > WRT elimination of the GIMPLE_CHECKs, understood on the state of things > and why the script didn't eliminate them in the various places I pointed > out. > > This is fine. Please install. Thanks; I've committed the combined patch series to trunk as r205034. ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Updated automated patch (was Re: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance) 2013-11-18 22:17 ` [PATCH] Updated automated patch (was Re: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance) David Malcolm 2013-11-19 8:49 ` Jeff Law @ 2013-11-22 0:27 ` Jakub Jelinek 2013-11-22 0:35 ` Jeff Law 1 sibling, 1 reply; 116+ messages in thread From: Jakub Jelinek @ 2013-11-22 0:27 UTC (permalink / raw) To: David Malcolm; +Cc: Jeff Law, gcc-patches, Andrew MacLeod On Mon, Nov 18, 2013 at 03:25:52PM -0500, David Malcolm wrote: > > So is there some reason the GIMPLE_CHECK was left in here rather than > > doing the downcasting? This happens in other places. Note that the changes removed tons of checks that IMHO were desirable. The as_a that replaced those checks e.g. allows 3 different gimple codes, while previously only one was allowed, this is both more expensive for --enable-checking=yes, and allows one to use inline wrappers e.g. gimple_omp_parallel_something on GIMPLE_OMP_TASK etc. Jakub ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Updated automated patch (was Re: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance) 2013-11-22 0:27 ` Jakub Jelinek @ 2013-11-22 0:35 ` Jeff Law 2013-11-22 1:51 ` Jakub Jelinek 0 siblings, 1 reply; 116+ messages in thread From: Jeff Law @ 2013-11-22 0:35 UTC (permalink / raw) To: Jakub Jelinek, David Malcolm; +Cc: gcc-patches, Andrew MacLeod On 11/21/13 15:19, Jakub Jelinek wrote: > On Mon, Nov 18, 2013 at 03:25:52PM -0500, David Malcolm wrote: >>> So is there some reason the GIMPLE_CHECK was left in here rather than >>> doing the downcasting? This happens in other places. > > Note that the changes removed tons of checks that IMHO were desirable. > The as_a that replaced those checks e.g. allows 3 different gimple codes, > while previously only one was allowed, this is both more expensive for > --enable-checking=yes, and allows one to use inline wrappers e.g. > gimple_omp_parallel_something on GIMPLE_OMP_TASK etc. Can you give a couple examples, please? jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Updated automated patch (was Re: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance) 2013-11-22 0:35 ` Jeff Law @ 2013-11-22 1:51 ` Jakub Jelinek 2013-11-22 2:52 ` Andrew MacLeod 0 siblings, 1 reply; 116+ messages in thread From: Jakub Jelinek @ 2013-11-22 1:51 UTC (permalink / raw) To: Jeff Law; +Cc: David Malcolm, gcc-patches, Andrew MacLeod On Thu, Nov 21, 2013 at 03:24:55PM -0700, Jeff Law wrote: > On 11/21/13 15:19, Jakub Jelinek wrote: > >On Mon, Nov 18, 2013 at 03:25:52PM -0500, David Malcolm wrote: > >>>So is there some reason the GIMPLE_CHECK was left in here rather than > >>>doing the downcasting? This happens in other places. > > > >Note that the changes removed tons of checks that IMHO were desirable. > >The as_a that replaced those checks e.g. allows 3 different gimple codes, > >while previously only one was allowed, this is both more expensive for > >--enable-checking=yes, and allows one to use inline wrappers e.g. > >gimple_omp_parallel_something on GIMPLE_OMP_TASK etc. > Can you give a couple examples, please? I mean e.g. gimple_omp_parallel_{,set_}{clauses,child_fn,data_arg}{,_ptr} gimple_omp_taskreg_{,set_}{clauses,child_fn,data_arg}{,_ptr} gimple_omp_target_{,set_}{clauses,child_fn,data_arg}{,_ptr} gimple_omp_teams_{,set_}clauses{,_ptr} gimple_omp_return_{,set_}lhs{,_ptr} gimple_omp_atomic_store_{,set_}val{,_ptr} gimple_resx_{,set_}region gimple_eh_dispatch_{,set_}region Jakub ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Updated automated patch (was Re: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance) 2013-11-22 1:51 ` Jakub Jelinek @ 2013-11-22 2:52 ` Andrew MacLeod 2013-11-22 3:48 ` David Malcolm 2013-11-25 18:09 ` [PATCH] Fix checking of gimple types David Malcolm 0 siblings, 2 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-11-22 2:52 UTC (permalink / raw) To: Jakub Jelinek, Jeff Law; +Cc: David Malcolm, gcc-patches On 11/21/2013 05:42 PM, Jakub Jelinek wrote: > On Thu, Nov 21, 2013 at 03:24:55PM -0700, Jeff Law wrote: >> On 11/21/13 15:19, Jakub Jelinek wrote: >>> On Mon, Nov 18, 2013 at 03:25:52PM -0500, David Malcolm wrote: >>>>> So is there some reason the GIMPLE_CHECK was left in here rather than >>>>> doing the downcasting? This happens in other places. >>> Note that the changes removed tons of checks that IMHO were desirable. >>> The as_a that replaced those checks e.g. allows 3 different gimple codes, >>> while previously only one was allowed, this is both more expensive for >>> --enable-checking=yes, and allows one to use inline wrappers e.g. >>> gimple_omp_parallel_something on GIMPLE_OMP_TASK etc. >> Can you give a couple examples, please? > I mean e.g. > gimple_omp_parallel_{,set_}{clauses,child_fn,data_arg}{,_ptr} > gimple_omp_taskreg_{,set_}{clauses,child_fn,data_arg}{,_ptr} > gimple_omp_target_{,set_}{clauses,child_fn,data_arg}{,_ptr} > gimple_omp_teams_{,set_}clauses{,_ptr} > gimple_omp_return_{,set_}lhs{,_ptr} > gimple_omp_atomic_store_{,set_}val{,_ptr} > gimple_resx_{,set_}region > gimple_eh_dispatch_{,set_}region > > Jakub Why does is_a_helper <gimple_statement_omp_parallel>::test allow anything other than a GIMPLE_OMP_PARALLEL..? That seems wrong to me. should just be the one check. gimple_omp_taskreg and other routines "sharing" that helper should have their own helper and only check the one code.. thats is whole point to remain at least codegen neutral in these cases and provide correct checking. The fact that they may happen to share the same underlying structure is irrelevant. I also think this is wrong. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Updated automated patch (was Re: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance) 2013-11-22 2:52 ` Andrew MacLeod @ 2013-11-22 3:48 ` David Malcolm 2013-11-25 18:09 ` [PATCH] Fix checking of gimple types David Malcolm 1 sibling, 0 replies; 116+ messages in thread From: David Malcolm @ 2013-11-22 3:48 UTC (permalink / raw) To: Andrew MacLeod; +Cc: Jakub Jelinek, Jeff Law, gcc-patches On Thu, 2013-11-21 at 18:03 -0500, Andrew MacLeod wrote: > On 11/21/2013 05:42 PM, Jakub Jelinek wrote: > > On Thu, Nov 21, 2013 at 03:24:55PM -0700, Jeff Law wrote: > >> On 11/21/13 15:19, Jakub Jelinek wrote: > >>> On Mon, Nov 18, 2013 at 03:25:52PM -0500, David Malcolm wrote: > >>>>> So is there some reason the GIMPLE_CHECK was left in here rather than > >>>>> doing the downcasting? This happens in other places. > >>> Note that the changes removed tons of checks that IMHO were desirable. > >>> The as_a that replaced those checks e.g. allows 3 different gimple codes, > >>> while previously only one was allowed, this is both more expensive for > >>> --enable-checking=yes, and allows one to use inline wrappers e.g. > >>> gimple_omp_parallel_something on GIMPLE_OMP_TASK etc. > >> Can you give a couple examples, please? > > I mean e.g. > > gimple_omp_parallel_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > gimple_omp_taskreg_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > gimple_omp_target_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > gimple_omp_teams_{,set_}clauses{,_ptr} > > gimple_omp_return_{,set_}lhs{,_ptr} > > gimple_omp_atomic_store_{,set_}val{,_ptr} > > gimple_resx_{,set_}region > > gimple_eh_dispatch_{,set_}region > > > > Jakub > Why does is_a_helper <gimple_statement_omp_parallel>::test allow > anything other than a GIMPLE_OMP_PARALLEL..? That seems wrong to me. > should just be the one check. > > gimple_omp_taskreg and other routines "sharing" that helper should have > their own helper and only check the one code.. thats is whole point to > remain at least codegen neutral in these cases and provide correct > checking. The fact that they may happen to share the same underlying > structure is irrelevant. > > I also think this is wrong. This was a bug in my script. Sorry. Working on a fix. ^ permalink raw reply [flat|nested] 116+ messages in thread
* [PATCH] Fix checking of gimple types 2013-11-22 2:52 ` Andrew MacLeod 2013-11-22 3:48 ` David Malcolm @ 2013-11-25 18:09 ` David Malcolm 2013-11-25 18:42 ` Michael Matz ` (2 more replies) 1 sibling, 3 replies; 116+ messages in thread From: David Malcolm @ 2013-11-25 18:09 UTC (permalink / raw) To: Andrew MacLeod; +Cc: Jakub Jelinek, Jeff Law, gcc-patches [-- Attachment #1: Type: text/plain, Size: 9252 bytes --] On Thu, 2013-11-21 at 18:03 -0500, Andrew MacLeod wrote: > On 11/21/2013 05:42 PM, Jakub Jelinek wrote: > > On Thu, Nov 21, 2013 at 03:24:55PM -0700, Jeff Law wrote: > >> On 11/21/13 15:19, Jakub Jelinek wrote: > >>> On Mon, Nov 18, 2013 at 03:25:52PM -0500, David Malcolm wrote: > >>>>> So is there some reason the GIMPLE_CHECK was left in here rather than > >>>>> doing the downcasting? This happens in other places. > >>> Note that the changes removed tons of checks that IMHO were desirable. > >>> The as_a that replaced those checks e.g. allows 3 different gimple codes, > >>> while previously only one was allowed, this is both more expensive for > >>> --enable-checking=yes, and allows one to use inline wrappers e.g. > >>> gimple_omp_parallel_something on GIMPLE_OMP_TASK etc. > >> Can you give a couple examples, please? > > I mean e.g. > > gimple_omp_parallel_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > gimple_omp_taskreg_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > gimple_omp_target_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > gimple_omp_teams_{,set_}clauses{,_ptr} > > gimple_omp_return_{,set_}lhs{,_ptr} > > gimple_omp_atomic_store_{,set_}val{,_ptr} > > gimple_resx_{,set_}region > > gimple_eh_dispatch_{,set_}region > > > > Jakub > Why does is_a_helper <gimple_statement_omp_parallel>::test allow > anything other than a GIMPLE_OMP_PARALLEL..? That seems wrong to me. > should just be the one check. > > gimple_omp_taskreg and other routines "sharing" that helper should have > their own helper and only check the one code.. thats is whole point to > remain at least codegen neutral in these cases and provide correct > checking. The fact that they may happen to share the same underlying > structure is irrelevant. > > I also think this is wrong. Mea culpa. Unfortunately I made a conceptual error during the conversion (the worst kind of error). I misunderstood the relationships between the various OMP statements: there (mostly) aren't any, but the sharing of structures for layout made me think there were. Attached is a patch, successfully bootstrapped®tested on x86_64-unknown-linux-gnu, which I believe reinstates the checked-build behaviors from before r205034 (and that the unchecked-build behaviors were not affected by that commit and likewise are not by this patch). As I understand it, there are almost no "is-a" relationships between the various omp statement types, some of them just happen to share layouts. The exception is that the various gimple_omp_taskreg_* accessors accept either codes GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK and so an "omp_taskreg" is a concept, of which OMP_PARALLEL and OMP_TASK have an is-a relationship. Based on this, I've reworked the is_a_helper functions, eliminating almost all of the ones that accepted multiple codes. The only ones that remain accepting multiple codes are those for: * gimple_statement_with_ops, which uses gimple_has_ops (gs), and for * gimple_statement_with_memory_ops, which uses gimple_has_mem_ops (gs), plus * a new class gimple_statement_omp_taskreg, which expresses the "either GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK" condition, and becomes a parent struct for those. I introduced some new structs to express the pre-existing layouts for GSS codes, and to distinguish them from structs that imply a specific GIMPLE_ code. For example, gimple_statement_omp_atomic_store now requires that the code be GIMPLE_OMP_ATOMIC_STORE, but it was also the name of a layout, GSS_OMP_ATOMIC_STORE. So I renamed these purely layout classes, so that there is now a gimple_statement_omp_atomic_store_layout class for the corresponding GSS value, which I renamed to GSS_OMP_ATOMIC_STORE_LAYOUT to make clear that this is just a layout: that although GIMPLE_OMP_RETURN happens to share the data layout of GIMPLE_OMP_ATOMIC_STORE, they are not otherwise related - they now both inherit from the "_layout" class. I'm not a fan of these "_layout" names, but I'm not sure what better to call them. Perhaps: GSS_OMP_PARALLEL_LAYOUT -> GSS_OMP_WITH_CLAUSES_CHILD_FN_DATA_ARG GSS_OMP_SINGLE_LAYOUT -> GSS_OMP_WITH_CLAUSES GSS_OMP_ATOMIC_STORE_LAYOUT -> GSS_OMP_WITHOUT_SEQ_WITH_VAL with analogous names for the corresponding structs. I added GTY tags for every class in the hierarchy, not just those that introduce a new layout, since gengtype only recognizes inheritance when supplied a "tag" option. This leads to the GSS values appearing multiple times within the class hierarchy, which required a patch to gengtype, to prevent duplicate case labels in the generated switch statement. I believe that this structure correctly reinstates the exact behavior from before the inheritance patch for the checked build, and that either way, the behavior in the unchecked build is the same. Another approach to this would be to entirely eliminate these shared layout types, going purely with the conceptual is-a relationships between the types, say, by replacing the gengtype switch on GSS_ value with a switch on GIMPLE_ code. Given that this might affect the speed of GC (bigger switch statements), I went with the relatively more conservative change. Successfully bootstrapped®tested on x86_64-unknown-linux-gnu. OK for trunk? Sorry again for breaking this. Here's an ASCII art inheritance diagram, showing the relationships between structs, GSS_ values (layouts) and GIMPLE_ values (codes) - as I see them. If I'm still misunderstanding something, sorry, please let me know. Should this diagram live in gimple.h? +- gimple_statement_base | layout: GSS_BASE. 4 codes use this layout. | + gimple_statement_with_ops_base | | (no GSS layout) | | | + gimple_statement_with_ops | | layout: GSS_WITH_OPS. 5 codes use this layout. | | | + gimple_statement_with_memory_ops_base | | layout: GSS_WITH_MEM_OPS_BASE | | | + gimple_statement_with_memory_ops | | layout: GSS_WITH_MEM_OPS. | | Used by codes GIMPLE_ASSIGN and GIMPLE_RETURN. | | | + gimple_statement_call | | layout: GSS_CALL, code: GIMPLE_CALL | | | + gimple_statement_asm | | layout: GSS_ASM, code: GIMPLE_ASM | | | + gimple_statement_transaction | layout: GSS_TRANSACTION, code: GIMPLE_TRANSACTION | + gimple_statement_omp | | layout: GSS_OMP | | | + gimple_statement_omp_critical | | layout: GSS_OMP_CRITICAL, code: GIMPLE_OMP_CRITICAL | | | + gimple_statement_omp_for | | layout: GSS_OMP_FOR, code: GIMPLE_OMP_FOR | | | + gimple_statement_omp_parallel_layout | | | layout: GSS_OMP_PARALLEL_LAYOUT | | | | | + gimple_statement_omp_taskreg | | | | | | | + gimple_statement_omp_parallel | | | | code: GIMPLE_OMP_PARALLEL | | | | | | | + gimple_statement_omp_task | | | code: GIMPLE_OMP_TASK | | | | | + gimple_statement_omp_target | | code: GIMPLE_OMP_TARGET | | | + gimple_statement_omp_sections | | layout: GSS_OMP_SECTIONS, code: GIMPLE_OMP_SECTIONS | | | + gimple_statement_omp_single_layout | | layout: GSS_OMP_SINGLE_LAYOUT | | | + gimple_statement_omp_single | | code: GIMPLE_OMP_SINGLE | | | + gimple_statement_omp_teams | code: GIMPLE_OMP_TEAMS | + gimple_statement_bind | layout: GSS_BIND, code: GIMPLE_BIND | + gimple_statement_catch | layout: GSS_CATCH, code: GIMPLE_CATCH | + gimple_statement_eh_filter | layout: GSS_EH_FILTER, code: GIMPLE_EH_FILTER | + gimple_statement_eh_else | layout: GSS_EH_ELSE, code: GIMPLE_EH_ELSE | + gimple_statement_eh_mnt | layout: GSS_EH_MNT, code: GIMPLE_EH_MUST_NOT_THROW | + gimple_statement_phi | layout: GSS_PHI, code: GIMPLE_PHI | + gimple_statement_eh_ctrl | | layout: GSS_EH_CTRL | | | + gimple_statement_resx | | code: GIMPLE_RESX | | | + gimple_statement_eh_dispatch | code: GIMPLE_EH_DISPATCH | + gimple_statement_try | layout: GSS_TRY, code: GIMPLE_TRY | + gimple_statement_wce | layout: GSS_WCE, code: GIMPLE_WITH_CLEANUP_EXPR | + gimple_statement_omp_continue | layout: GSS_OMP_CONTINUE, code: GIMPLE_OMP_CONTINUE | + gimple_statement_omp_atomic_load | layout: GSS_OMP_ATOMIC_LOAD, code: GIMPLE_OMP_ATOMIC_LOAD | + gimple_statement_omp_atomic_store_layout | layout: GSS_OMP_ATOMIC_STORE_LAYOUT, | code: GIMPLE_OMP_ATOMIC_STORE | + gimple_statement_omp_atomic_store | code: GIMPLE_OMP_ATOMIC_STORE | + gimple_statement_omp_return code: GIMPLE_OMP_RETURN [-- Attachment #2: fix-gimple-checking.patch --] [-- Type: text/x-patch, Size: 36141 bytes --] commit 9a0c36081b3baecfc16a8500464df3a94c8dd145 Author: David Malcolm <dmalcolm@redhat.com> Date: Thu Nov 21 21:46:58 2013 -0500 Fix as_a<> helpers for gimple * gengtype.c (struct seen_tag): New. (already_seen_tag): New. (mark_tag_as_seen): New. (walk_subclasses): Support having multiple subclasses using the same tag by tracking which tags have already been seen, and using this to avoid adding duplicate cases to the "switch" statement. The call to already_seen_tag introduces an O(N^2) when running gengtype on N, the number of tags, due to the repeated linear search, but currently max(N) is relatively small (the number of GSS codes, which is 26). (walk_type): Pass in a seen_tag for use by the walk_subclasses recursion. * gimple.def (GIMPLE_OMP_ATOMIC_STORE, GIMPLE_OMP_RETURN): Rename underlying GSS values for these codes (from GSS_OMP_ATOMIC_STORE to GSS_OMP_ATOMIC_STORE_LAYOUT) to make clear that although GIMPLE_OMP_RETURN happens to share the data layout of GIMPLE_OMP_ATOMIC_STORE, they are not otherwise related. (GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET): Likewise, rename underlying GSS value from GSS_OMP_PARALLEL to GSS_OMP_PARALLEL_LAYOUT to make clear that these gimple codes are not directly related; they merely share in-memory layout. (GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS): Likewise, rename GSS values for these two codes from GSS_OMP_SINGLE to GSS_OMP_SINGLE_LAYOUT. * gsstruct.def (GSS_OMP_PARALLEL, gimple_statement_omp_parallel): Rename to... (GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout): ...these. (GSS_OMP_SINGLE, gimple_statement_omp_single): Rename to... (GSS_OMP_SINGLE_LAYOUT, gimple_statement_omp_single_layout): ...these. (GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store): Rename to... (GSS_OMP_ATOMIC_STORE_LAYOUT, gimple_statement_omp_atomic_store): ...these. * gimple.h (gimple_statement_resx): New subclass of gimple_statement_eh_ctrl, with the invariant that stmt->code == GIMPLE_RESX. (gimple_statement_eh_dispatch): New subclass of gimple_statement_eh_ctrl, with the invariant that stmt->code == GIMPLE_EH_DISPATH. (gimple_statement_omp_parallel): The existing class expressed a layout (GSS_OMP_PARALLEL), but the codes with that layout are not all related, so it makes more sense for this class to express a *code* (GIMPLE_OMP_PARALLEL). GSS_OMP_PARALLEL has been renamed to GSS_OMP_PARALLEL_LAYOUT to express this, so rename the existing gimple_statement_omp_parallel class to... (gimple_statement_omp_parallel_layout): ...this, expressing a statement of structure layout GSS_OMP_PARALLEL_LAYOUT. (gimple_statement_omp_taskreg): New subclass of gimple_statement_omp_parallel_layout, expressing the invariant that the code is one of GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK, as used by the various gimple_omp_taskreg_ accessors. (gimple_statement_omp_parallel): Reintroduce this class, this time as a subclass of gimple_statement_omp_taskreg to express the invariant stmt->code == GIMPLE_OMP_PARALLEL. (gimple_statement_omp_target) New class, subclassing gimple_statement_omp_parallel_layout, to express the invariant stmt->code == GIMPLE_OMP_TARGET. (gimple_statement_omp_task): Update to inherit from gimple_statement_omp_taskreg rather than gimple_statement_omp_parallel. (gimple_statement_omp_single): Rename to... (gimple_statement_omp_single_layout): ...this, expressing the invariant that the layout is GSS_OMP_SINGLE_LAYOUT. (gimple_statement_omp_single): ...and reintroduce this name as a subclass of gimple_statement_omp_single_layout, expressing the invariant that code == GIMPLE_OMP_SINGLE. (gimple_statement_omp_teams): New class, subclassing gimple_statement_omp_single_layout, for the code GIMPLE_OMP_TEAMS. (gimple_statement_omp_atomic_store): Rename to... (gimple_statement_omp_atomic_store_layout): ...this, expressing the invariant that the layout is GSS_OMP_ATOMIC_STORE_LAYOUT. (gimple_statement_omp_atomic_store): ...and reintroduce this name as a subclass of gimple_statement_omp_atomic_store_layout with code == GIMPLE_OMP_ATOMIC_STORE. (gimple_statement_omp_return): New class, subclassing gimple_statement_omp_atomic_store_layout for the code GIMPLE_OMP_RETURN. (is_a_helper <gimple_statement_eh_ctrl>::test): Delete. (is_a_helper <gimple_statement_resx>::test): New. (is_a_helper <gimple_statement_eh_dispatch>::test): New. (is_a_helper <gimple_statement_omp_atomic_store>::test): Only check for GIMPLE_OMP_ATOMIC_STORE, not for GIMPLE_OMP_RETURN. (is_a_helper <gimple_statement_omp_return>::test): New. (is_a_helper <gimple_statement_omp_taskreg>::test): New. (is_a_helper <gimple_statement_omp_parallel>::test): Only check for GIMPLE_OMP_PARALLEL, not for GIMPLE_OMP_TASK or GIMPLE_OMP_TARGET. (is_a_helper <gimple_statement_omp_target>::test): New. (is_a_helper <gimple_statement_omp_single>::test): Only check for GIMPLE_OMP_SINGLE, not for GIMPLE_OMP_TEAMS. (is_a_helper <gimple_statement_omp_teams>::test): New. (is_a_helper <const gimple_statement_eh_ctrl>::test): Delete. (is_a_helper <const gimple_statement_resx>::test): New. (is_a_helper <const gimple_statement_eh_dispatch>::test): New. (is_a_helper <const gimple_statement_omp_atomic_store>::test): Only check for GIMPLE_OMP_ATOMIC_STORE, not for GIMPLE_OMP_RETURN. (is_a_helper <const gimple_statement_omp_return>::test): New. (is_a_helper <const gimple_statement_omp_taskreg>::test): New. (is_a_helper <const gimple_statement_omp_parallel>::test): Only check for GIMPLE_OMP_PARALLEL, not for GIMPLE_OMP_TASK or GIMPLE_OMP_TARGET. (is_a_helper <const gimple_statement_omp_target>::test): New. (is_a_helper <const gimple_statement_omp_single>::test): Only check for GIMPLE_OMP_SINGLE, not for GIMPLE_OMP_TEAMS. (is_a_helper <const gimple_statement_omp_teams>::test): New. (gimple_omp_return_set_lhs, gimple_omp_return_lhs, gimple_omp_return_lhs_ptr): Replace bogus downcasts to gimple_statement_omp_atomic_store with downcasts to gimple_statement_omp_return, thus requiring that the code be GIMPLE_OMP_RETURN. (gimple_resx_region, gimple_resx_set_region): Replace bogus downcasts to gimple_statement_eh_ctrl with downcasts to gimple_statement_resx, thus requiring that the code be GIMPLE_RESX. (gimple_eh_dispatch_region, gimple_eh_dispatch_set_region): Replace bogus downcasts to const gimple_statement_eh_ctrl with downcasts to gimple_statement_eh_dispatch, thus requiring that the code be GIMPLE_EH_DISPATCH. (gimple_omp_taskreg_clauses, gimple_omp_taskreg_clauses_ptr) gimple_omp_taskreg_set_clauses, gimple_omp_taskreg_child_fn, gimple_omp_taskreg_child_fn_ptr, gimple_omp_taskreg_set_child_fn, gimple_omp_taskreg_data_arg, gimple_omp_taskreg_data_arg_ptr, gimple_omp_taskreg_set_data_arg): Replace bogus downcasts to gimple_statement_omp_parallel with downcasts to gimple_statement_omp_taskreg, thus requiring that the code be either GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK. (gimple_omp_target_clauses, gimple_omp_target_clauses_ptr gimple_omp_target_set_clauses, gimple_omp_target_child_fn gimple_omp_target_child_fn_ptr, gimple_omp_target_set_child_fn gimple_omp_target_data_arg, gimple_omp_target_data_arg_ptr gimple_omp_target_set_data_arg): Replace bogus downcasts to gimple_statement_omp_parallel with downcasts to gimple_statement_omp_target, thus requiring that the code be GIMPLE_OMP_TARGET. (gimple_omp_teams_clauses, gimple_omp_teams_clauses_ptr gimple_omp_teams_set_clauses): Replace bogus downcasts to gimple_statement_omp_single with downcasts to gimple_statement_omp_teams, thus requiring that the code be GIMPLE_OMP_TEAMS. * gimple.c (gimple_build_resx): Fix bogus as_a<> to use gimple_statement_resx. (gimple_build_eh_dispatch): Fix bogus as_a<> to use gimple_statement_eh_dispatch. diff --git a/gcc/gengtype.c b/gcc/gengtype.c index 86e9ca2..6e675cc 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -2654,15 +2654,48 @@ get_string_option (options_p opt, const char *key) return NULL; } +/* Machinery for avoiding duplicate tags within switch statements. */ +struct seen_tag +{ + const char *tag; + struct seen_tag *next; +}; + +int +already_seen_tag (struct seen_tag *seen_tags, const char *tag) +{ + /* Linear search, so O(n^2), but n is currently small. */ + while (seen_tags) + { + if (!strcmp (seen_tags->tag, tag)) + return 1; + seen_tags = seen_tags->next; + } + /* Not yet seen this tag. */ + return 0; +} + +void +mark_tag_as_seen (struct seen_tag **seen_tags, const char *tag) +{ + /* Add to front of linked list. */ + struct seen_tag *new_node = XCNEW (struct seen_tag); + new_node->tag = tag; + new_node->next = *seen_tags; + *seen_tags = new_node; +} + static void -walk_subclasses (type_p base, struct walk_type_data *d) +walk_subclasses (type_p base, struct walk_type_data *d, + struct seen_tag **seen_tags) { for (type_p sub = base->u.s.first_subclass; sub != NULL; sub = sub->u.s.next_sibling_class) { const char *type_tag = get_string_option (sub->u.s.opt, "tag"); - if (type_tag) + if (type_tag && !already_seen_tag (*seen_tags, type_tag)) { + mark_tag_as_seen (seen_tags, type_tag); oprintf (d->of, "%*scase %s:\n", d->indent, "", type_tag); d->indent += 2; oprintf (d->of, "%*s{\n", d->indent, ""); @@ -2678,7 +2711,7 @@ walk_subclasses (type_p base, struct walk_type_data *d) oprintf (d->of, "%*sbreak;\n", d->indent, ""); d->indent -= 2; } - walk_subclasses (sub, d); + walk_subclasses (sub, d, seen_tags); } } @@ -3225,7 +3258,8 @@ walk_type (type_p t, struct walk_type_data *d) else if (desc) { /* Add cases to handle subclasses. */ - walk_subclasses (t, d); + struct seen_tag *tags = NULL; + walk_subclasses (t, d, &tags); /* Ensure that if someone forgets a "tag" option that we don't silent fail to traverse that subclass's fields. */ diff --git a/gcc/gimple.c b/gcc/gimple.c index d48ca6b..2e45f37 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -697,8 +697,8 @@ gimple_build_wce (gimple_seq cleanup) gimple gimple_build_resx (int region) { - gimple_statement_eh_ctrl *p = - as_a <gimple_statement_eh_ctrl> ( + gimple_statement_resx *p = + as_a <gimple_statement_resx> ( gimple_build_with_ops (GIMPLE_RESX, ERROR_MARK, 0)); p->region = region; return p; @@ -747,8 +747,8 @@ gimple_build_switch (tree index, tree default_label, vec<tree> args) gimple gimple_build_eh_dispatch (int region) { - gimple_statement_eh_ctrl *p = - as_a <gimple_statement_eh_ctrl> ( + gimple_statement_eh_dispatch *p = + as_a <gimple_statement_eh_dispatch> ( gimple_build_with_ops (GIMPLE_EH_DISPATCH, ERROR_MARK, 0)); p->region = region; return p; diff --git a/gcc/gimple.def b/gcc/gimple.def index 07370ae..ff1ef43 100644 --- a/gcc/gimple.def +++ b/gcc/gimple.def @@ -221,7 +221,7 @@ DEFGSCODE(GIMPLE_NOP, "gimple_nop", GSS_BASE) DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load", GSS_OMP_ATOMIC_LOAD) DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store", - GSS_OMP_ATOMIC_STORE) + GSS_OMP_ATOMIC_STORE_LAYOUT) /* GIMPLE_OMP_CONTINUE marks the location of the loop or sections iteration in partially lowered OpenMP code. */ @@ -300,7 +300,7 @@ DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP) DATA_ARG is a local variable in the parent function containing data to be shared with CHILD_FN. This is used to implement all the data sharing clauses. */ -DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL) +DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL_LAYOUT) /* GIMPLE_OMP_TASK <BODY, CLAUSES, CHILD_FN, DATA_ARG, COPY_FN, ARG_SIZE, ARG_ALIGN> represents @@ -329,7 +329,7 @@ DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL) DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", GSS_OMP_TASK) /* OMP_RETURN marks the end of an OpenMP directive. */ -DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_OMP_ATOMIC_STORE) +DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_OMP_ATOMIC_STORE_LAYOUT) /* OMP_SECTION <BODY> represents #pragma omp section. BODY is the sequence of statements in the section body. */ @@ -351,7 +351,7 @@ DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE) /* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single BODY is the sequence of statements inside the single section. CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ -DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE) +DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE_LAYOUT) /* GIMPLE_OMP_TARGET <BODY, CLAUSES, CHILD_FN> represents #pragma omp target {,data,update} @@ -364,12 +364,12 @@ DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE) DATA_ARG is a vec of 3 local variables in the parent function containing data to be mapped to CHILD_FN. This is used to implement the MAP clauses. */ -DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL) +DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL_LAYOUT) /* GIMPLE_OMP_TEAMS <BODY, CLAUSES> represents #pragma omp teams BODY is the sequence of statements inside the single section. CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ -DEFGSCODE(GIMPLE_OMP_TEAMS, "gimple_omp_teams", GSS_OMP_SINGLE) +DEFGSCODE(GIMPLE_OMP_TEAMS, "gimple_omp_teams", GSS_OMP_SINGLE_LAYOUT) /* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction. diff --git a/gcc/gimple.h b/gcc/gimple.h index 0eb23fc..0257576 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -420,6 +420,20 @@ struct GTY((tag("GSS_EH_CTRL"))) int region; }; +struct GTY((tag("GSS_EH_CTRL"))) + gimple_statement_resx : public gimple_statement_eh_ctrl +{ + /* No extra fields; adds invariant: + stmt->code == GIMPLE_RESX. */ +}; + +struct GTY((tag("GSS_EH_CTRL"))) + gimple_statement_eh_dispatch : public gimple_statement_eh_ctrl +{ + /* No extra fields; adds invariant: + stmt->code == GIMPLE_EH_DISPATH. */ +}; + /* GIMPLE_TRY */ @@ -547,10 +561,9 @@ struct GTY((tag("GSS_OMP_FOR"))) }; -/* GIMPLE_OMP_PARALLEL */ - -struct GTY((tag("GSS_OMP_PARALLEL"))) - gimple_statement_omp_parallel : public gimple_statement_omp +/* GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET */ +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) + gimple_statement_omp_parallel_layout : public gimple_statement_omp { /* [ WORD 1-7 ] : base class */ @@ -567,11 +580,35 @@ struct GTY((tag("GSS_OMP_PARALLEL"))) tree data_arg; }; +/* GIMPLE_OMP_PARALLEL or GIMPLE_TASK */ +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) + gimple_statement_omp_taskreg : public gimple_statement_omp_parallel_layout +{ + /* No extra fields; adds invariant: + stmt->code == GIMPLE_OMP_PARALLEL + || stmt->code == GIMPLE_OMP_TASK. */ +}; + + +/* GIMPLE_OMP_PARALLEL */ +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) + gimple_statement_omp_parallel : public gimple_statement_omp_taskreg +{ + /* No extra fields; adds invariant: + stmt->code == GIMPLE_OMP_PARALLEL. */ +}; + +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) + gimple_statement_omp_target : public gimple_statement_omp_parallel_layout +{ + /* No extra fields; adds invariant: + stmt->code == GIMPLE_OMP_TARGET. */ +}; /* GIMPLE_OMP_TASK */ struct GTY((tag("GSS_OMP_TASK"))) - gimple_statement_omp_task : public gimple_statement_omp_parallel + gimple_statement_omp_task : public gimple_statement_omp_taskreg { /* [ WORD 1-10 ] : base class */ @@ -623,10 +660,10 @@ struct GTY((tag("GSS_OMP_CONTINUE"))) tree control_use; }; -/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS */ +/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS */ -struct GTY((tag("GSS_OMP_SINGLE"))) - gimple_statement_omp_single : public gimple_statement_omp +struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) + gimple_statement_omp_single_layout : public gimple_statement_omp { /* [ WORD 1-7 ] : base class */ @@ -634,6 +671,20 @@ struct GTY((tag("GSS_OMP_SINGLE"))) tree clauses; }; +struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) + gimple_statement_omp_single : public gimple_statement_omp_single_layout +{ + /* No extra fields; adds invariant: + stmt->code == GIMPLE_OMP_SINGLE. */ +}; + +struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) + gimple_statement_omp_teams : public gimple_statement_omp_single_layout +{ + /* No extra fields; adds invariant: + stmt->code == GIMPLE_OMP_TEAMS. */ +}; + /* GIMPLE_OMP_ATOMIC_LOAD. Note: This is based on gimple_statement_base, not g_s_omp, because g_s_omp @@ -651,8 +702,8 @@ struct GTY((tag("GSS_OMP_ATOMIC_LOAD"))) /* GIMPLE_OMP_ATOMIC_STORE. See note on GIMPLE_OMP_ATOMIC_LOAD. */ -struct GTY((tag("GSS_OMP_ATOMIC_STORE"))) - gimple_statement_omp_atomic_store : public gimple_statement_base +struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) + gimple_statement_omp_atomic_store_layout : public gimple_statement_base { /* [ WORD 1-6 ] : base class */ @@ -660,6 +711,22 @@ struct GTY((tag("GSS_OMP_ATOMIC_STORE"))) tree val; }; +struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) + gimple_statement_omp_atomic_store : + public gimple_statement_omp_atomic_store_layout +{ + /* No extra fields; adds invariant: + stmt->code == GIMPLE_OMP_ATOMIC_STORE. */ +}; + +struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) + gimple_statement_omp_return : + public gimple_statement_omp_atomic_store_layout +{ + /* No extra fields; adds invariant: + stmt->code == GIMPLE_OMP_RETURN. */ +}; + /* GIMPLE_TRANSACTION. */ /* Bits to be stored in the GIMPLE_TRANSACTION subcode. */ @@ -742,9 +809,17 @@ is_a_helper <gimple_statement_catch>::test (gimple gs) template <> template <> inline bool -is_a_helper <gimple_statement_eh_ctrl>::test (gimple gs) +is_a_helper <gimple_statement_resx>::test (gimple gs) +{ + return gs->code == GIMPLE_RESX; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_eh_dispatch>::test (gimple gs) { - return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH; + return gs->code == GIMPLE_EH_DISPATCH; } template <> @@ -784,7 +859,15 @@ template <> inline bool is_a_helper <gimple_statement_omp_atomic_store>::test (gimple gs) { - return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN; + return gs->code == GIMPLE_OMP_ATOMIC_STORE; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_return>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_RETURN; } template <> @@ -814,9 +897,25 @@ is_a_helper <gimple_statement_omp_for>::test (gimple gs) template <> template <> inline bool +is_a_helper <gimple_statement_omp_taskreg>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK; +} + +template <> +template <> +inline bool is_a_helper <gimple_statement_omp_parallel>::test (gimple gs) { - return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET; + return gs->code == GIMPLE_OMP_PARALLEL; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_target>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_TARGET; } template <> @@ -832,7 +931,15 @@ template <> inline bool is_a_helper <gimple_statement_omp_single>::test (gimple gs) { - return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS; + return gs->code == GIMPLE_OMP_SINGLE; +} + +template <> +template <> +inline bool +is_a_helper <gimple_statement_omp_teams>::test (gimple gs) +{ + return gs->code == GIMPLE_OMP_TEAMS; } template <> @@ -910,9 +1017,17 @@ is_a_helper <const gimple_statement_catch>::test (const_gimple gs) template <> template <> inline bool -is_a_helper <const gimple_statement_eh_ctrl>::test (const_gimple gs) +is_a_helper <const gimple_statement_resx>::test (const_gimple gs) { - return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH; + return gs->code == GIMPLE_RESX; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_eh_dispatch>::test (const_gimple gs) +{ + return gs->code == GIMPLE_EH_DISPATCH; } template <> @@ -936,7 +1051,15 @@ template <> inline bool is_a_helper <const gimple_statement_omp_atomic_store>::test (const_gimple gs) { - return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN; + return gs->code == GIMPLE_OMP_ATOMIC_STORE; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_return>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_RETURN; } template <> @@ -966,9 +1089,25 @@ is_a_helper <const gimple_statement_omp_for>::test (const_gimple gs) template <> template <> inline bool +is_a_helper <const gimple_statement_omp_taskreg>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK; +} + +template <> +template <> +inline bool is_a_helper <const gimple_statement_omp_parallel>::test (const_gimple gs) { - return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET; + return gs->code == GIMPLE_OMP_PARALLEL; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_target>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_TARGET; } template <> @@ -984,7 +1123,15 @@ template <> inline bool is_a_helper <const gimple_statement_omp_single>::test (const_gimple gs) { - return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS; + return gs->code == GIMPLE_OMP_SINGLE; +} + +template <> +template <> +inline bool +is_a_helper <const gimple_statement_omp_teams>::test (const_gimple gs) +{ + return gs->code == GIMPLE_OMP_TEAMS; } template <> @@ -1766,9 +1913,9 @@ gimple_omp_return_nowait_p (const_gimple g) static inline void gimple_omp_return_set_lhs (gimple g, tree lhs) { - gimple_statement_omp_atomic_store *omp_atomic_store_stmt = - as_a <gimple_statement_omp_atomic_store> (g); - omp_atomic_store_stmt->val = lhs; + gimple_statement_omp_return *omp_return_stmt = + as_a <gimple_statement_omp_return> (g); + omp_return_stmt->val = lhs; } @@ -1777,9 +1924,9 @@ gimple_omp_return_set_lhs (gimple g, tree lhs) static inline tree gimple_omp_return_lhs (const_gimple g) { - const gimple_statement_omp_atomic_store *omp_atomic_store_stmt = - as_a <const gimple_statement_omp_atomic_store> (g); - return omp_atomic_store_stmt->val; + const gimple_statement_omp_return *omp_return_stmt = + as_a <const gimple_statement_omp_return> (g); + return omp_return_stmt->val; } @@ -1788,9 +1935,9 @@ gimple_omp_return_lhs (const_gimple g) static inline tree * gimple_omp_return_lhs_ptr (gimple g) { - gimple_statement_omp_atomic_store *omp_atomic_store_stmt = - as_a <gimple_statement_omp_atomic_store> (g); - return &omp_atomic_store_stmt->val; + gimple_statement_omp_return *omp_return_stmt = + as_a <gimple_statement_omp_return> (g); + return &omp_return_stmt->val; } @@ -3793,9 +3940,9 @@ gimple_phi_arg_has_location (gimple gs, size_t i) static inline int gimple_resx_region (const_gimple gs) { - const gimple_statement_eh_ctrl *eh_ctrl_stmt = - as_a <const gimple_statement_eh_ctrl> (gs); - return eh_ctrl_stmt->region; + const gimple_statement_resx *resx_stmt = + as_a <const gimple_statement_resx> (gs); + return resx_stmt->region; } /* Set REGION to be the region number for GIMPLE_RESX GS. */ @@ -3803,9 +3950,8 @@ gimple_resx_region (const_gimple gs) static inline void gimple_resx_set_region (gimple gs, int region) { - gimple_statement_eh_ctrl *eh_ctrl_stmt = - as_a <gimple_statement_eh_ctrl> (gs); - eh_ctrl_stmt->region = region; + gimple_statement_resx *resx_stmt = as_a <gimple_statement_resx> (gs); + resx_stmt->region = region; } /* Return the region number for GIMPLE_EH_DISPATCH GS. */ @@ -3813,9 +3959,9 @@ gimple_resx_set_region (gimple gs, int region) static inline int gimple_eh_dispatch_region (const_gimple gs) { - const gimple_statement_eh_ctrl *eh_ctrl_stmt = - as_a <const gimple_statement_eh_ctrl> (gs); - return eh_ctrl_stmt->region; + const gimple_statement_eh_dispatch *eh_dispatch_stmt = + as_a <const gimple_statement_eh_dispatch> (gs); + return eh_dispatch_stmt->region; } /* Set REGION to be the region number for GIMPLE_EH_DISPATCH GS. */ @@ -3823,9 +3969,9 @@ gimple_eh_dispatch_region (const_gimple gs) static inline void gimple_eh_dispatch_set_region (gimple gs, int region) { - gimple_statement_eh_ctrl *eh_ctrl_stmt = - as_a <gimple_statement_eh_ctrl> (gs); - eh_ctrl_stmt->region = region; + gimple_statement_eh_dispatch *eh_dispatch_stmt = + as_a <gimple_statement_eh_dispatch> (gs); + eh_dispatch_stmt->region = region; } /* Return the number of labels associated with the switch statement GS. */ @@ -4663,9 +4809,9 @@ gimple_omp_task_set_data_arg (gimple gs, tree data_arg) static inline tree gimple_omp_taskreg_clauses (const_gimple gs) { - const gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <const gimple_statement_omp_parallel> (gs); - return omp_parallel_stmt->clauses; + const gimple_statement_omp_taskreg *omp_taskreg_stmt = + as_a <const gimple_statement_omp_taskreg> (gs); + return omp_taskreg_stmt->clauses; } @@ -4674,9 +4820,9 @@ gimple_omp_taskreg_clauses (const_gimple gs) static inline tree * gimple_omp_taskreg_clauses_ptr (gimple gs) { - gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <gimple_statement_omp_parallel> (gs); - return &omp_parallel_stmt->clauses; + gimple_statement_omp_taskreg *omp_taskreg_stmt = + as_a <gimple_statement_omp_taskreg> (gs); + return &omp_taskreg_stmt->clauses; } @@ -4686,9 +4832,9 @@ gimple_omp_taskreg_clauses_ptr (gimple gs) static inline void gimple_omp_taskreg_set_clauses (gimple gs, tree clauses) { - gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <gimple_statement_omp_parallel> (gs); - omp_parallel_stmt->clauses = clauses; + gimple_statement_omp_taskreg *omp_taskreg_stmt = + as_a <gimple_statement_omp_taskreg> (gs); + omp_taskreg_stmt->clauses = clauses; } @@ -4697,9 +4843,9 @@ gimple_omp_taskreg_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_taskreg_child_fn (const_gimple gs) { - const gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <const gimple_statement_omp_parallel> (gs); - return omp_parallel_stmt->child_fn; + const gimple_statement_omp_taskreg *omp_taskreg_stmt = + as_a <const gimple_statement_omp_taskreg> (gs); + return omp_taskreg_stmt->child_fn; } /* Return a pointer to the child function used to hold the body of @@ -4708,9 +4854,9 @@ gimple_omp_taskreg_child_fn (const_gimple gs) static inline tree * gimple_omp_taskreg_child_fn_ptr (gimple gs) { - gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <gimple_statement_omp_parallel> (gs); - return &omp_parallel_stmt->child_fn; + gimple_statement_omp_taskreg *omp_taskreg_stmt = + as_a <gimple_statement_omp_taskreg> (gs); + return &omp_taskreg_stmt->child_fn; } @@ -4719,9 +4865,9 @@ gimple_omp_taskreg_child_fn_ptr (gimple gs) static inline void gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn) { - gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <gimple_statement_omp_parallel> (gs); - omp_parallel_stmt->child_fn = child_fn; + gimple_statement_omp_taskreg *omp_taskreg_stmt = + as_a <gimple_statement_omp_taskreg> (gs); + omp_taskreg_stmt->child_fn = child_fn; } @@ -4731,9 +4877,9 @@ gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn) static inline tree gimple_omp_taskreg_data_arg (const_gimple gs) { - const gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <const gimple_statement_omp_parallel> (gs); - return omp_parallel_stmt->data_arg; + const gimple_statement_omp_taskreg *omp_taskreg_stmt = + as_a <const gimple_statement_omp_taskreg> (gs); + return omp_taskreg_stmt->data_arg; } @@ -4742,9 +4888,9 @@ gimple_omp_taskreg_data_arg (const_gimple gs) static inline tree * gimple_omp_taskreg_data_arg_ptr (gimple gs) { - gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <gimple_statement_omp_parallel> (gs); - return &omp_parallel_stmt->data_arg; + gimple_statement_omp_taskreg *omp_taskreg_stmt = + as_a <gimple_statement_omp_taskreg> (gs); + return &omp_taskreg_stmt->data_arg; } @@ -4753,9 +4899,9 @@ gimple_omp_taskreg_data_arg_ptr (gimple gs) static inline void gimple_omp_taskreg_set_data_arg (gimple gs, tree data_arg) { - gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <gimple_statement_omp_parallel> (gs); - omp_parallel_stmt->data_arg = data_arg; + gimple_statement_omp_taskreg *omp_taskreg_stmt = + as_a <gimple_statement_omp_taskreg> (gs); + omp_taskreg_stmt->data_arg = data_arg; } @@ -4896,9 +5042,9 @@ gimple_omp_single_set_clauses (gimple gs, tree clauses) static inline tree gimple_omp_target_clauses (const_gimple gs) { - const gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <const gimple_statement_omp_parallel> (gs); - return omp_parallel_stmt->clauses; + const gimple_statement_omp_target *omp_target_stmt = + as_a <const gimple_statement_omp_target> (gs); + return omp_target_stmt->clauses; } @@ -4907,9 +5053,9 @@ gimple_omp_target_clauses (const_gimple gs) static inline tree * gimple_omp_target_clauses_ptr (gimple gs) { - gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <gimple_statement_omp_parallel> (gs); - return &omp_parallel_stmt->clauses; + gimple_statement_omp_target *omp_target_stmt = + as_a <gimple_statement_omp_target> (gs); + return &omp_target_stmt->clauses; } @@ -4918,9 +5064,9 @@ gimple_omp_target_clauses_ptr (gimple gs) static inline void gimple_omp_target_set_clauses (gimple gs, tree clauses) { - gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <gimple_statement_omp_parallel> (gs); - omp_parallel_stmt->clauses = clauses; + gimple_statement_omp_target *omp_target_stmt = + as_a <gimple_statement_omp_target> (gs); + omp_target_stmt->clauses = clauses; } @@ -4950,9 +5096,9 @@ gimple_omp_target_set_kind (gimple g, int kind) static inline tree gimple_omp_target_child_fn (const_gimple gs) { - const gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <const gimple_statement_omp_parallel> (gs); - return omp_parallel_stmt->child_fn; + const gimple_statement_omp_target *omp_target_stmt = + as_a <const gimple_statement_omp_target> (gs); + return omp_target_stmt->child_fn; } /* Return a pointer to the child function used to hold the body of @@ -4961,9 +5107,9 @@ gimple_omp_target_child_fn (const_gimple gs) static inline tree * gimple_omp_target_child_fn_ptr (gimple gs) { - gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <gimple_statement_omp_parallel> (gs); - return &omp_parallel_stmt->child_fn; + gimple_statement_omp_target *omp_target_stmt = + as_a <gimple_statement_omp_target> (gs); + return &omp_target_stmt->child_fn; } @@ -4972,9 +5118,9 @@ gimple_omp_target_child_fn_ptr (gimple gs) static inline void gimple_omp_target_set_child_fn (gimple gs, tree child_fn) { - gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <gimple_statement_omp_parallel> (gs); - omp_parallel_stmt->child_fn = child_fn; + gimple_statement_omp_target *omp_target_stmt = + as_a <gimple_statement_omp_target> (gs); + omp_target_stmt->child_fn = child_fn; } @@ -4984,9 +5130,9 @@ gimple_omp_target_set_child_fn (gimple gs, tree child_fn) static inline tree gimple_omp_target_data_arg (const_gimple gs) { - const gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <const gimple_statement_omp_parallel> (gs); - return omp_parallel_stmt->data_arg; + const gimple_statement_omp_target *omp_target_stmt = + as_a <const gimple_statement_omp_target> (gs); + return omp_target_stmt->data_arg; } @@ -4995,9 +5141,9 @@ gimple_omp_target_data_arg (const_gimple gs) static inline tree * gimple_omp_target_data_arg_ptr (gimple gs) { - gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <gimple_statement_omp_parallel> (gs); - return &omp_parallel_stmt->data_arg; + gimple_statement_omp_target *omp_target_stmt = + as_a <gimple_statement_omp_target> (gs); + return &omp_target_stmt->data_arg; } @@ -5006,9 +5152,9 @@ gimple_omp_target_data_arg_ptr (gimple gs) static inline void gimple_omp_target_set_data_arg (gimple gs, tree data_arg) { - gimple_statement_omp_parallel *omp_parallel_stmt = - as_a <gimple_statement_omp_parallel> (gs); - omp_parallel_stmt->data_arg = data_arg; + gimple_statement_omp_target *omp_target_stmt = + as_a <gimple_statement_omp_target> (gs); + omp_target_stmt->data_arg = data_arg; } @@ -5017,9 +5163,9 @@ gimple_omp_target_set_data_arg (gimple gs, tree data_arg) static inline tree gimple_omp_teams_clauses (const_gimple gs) { - const gimple_statement_omp_single *omp_single_stmt = - as_a <const gimple_statement_omp_single> (gs); - return omp_single_stmt->clauses; + const gimple_statement_omp_teams *omp_teams_stmt = + as_a <const gimple_statement_omp_teams> (gs); + return omp_teams_stmt->clauses; } @@ -5028,9 +5174,9 @@ gimple_omp_teams_clauses (const_gimple gs) static inline tree * gimple_omp_teams_clauses_ptr (gimple gs) { - gimple_statement_omp_single *omp_single_stmt = - as_a <gimple_statement_omp_single> (gs); - return &omp_single_stmt->clauses; + gimple_statement_omp_teams *omp_teams_stmt = + as_a <gimple_statement_omp_teams> (gs); + return &omp_teams_stmt->clauses; } @@ -5039,9 +5185,9 @@ gimple_omp_teams_clauses_ptr (gimple gs) static inline void gimple_omp_teams_set_clauses (gimple gs, tree clauses) { - gimple_statement_omp_single *omp_single_stmt = - as_a <gimple_statement_omp_single> (gs); - omp_single_stmt->clauses = clauses; + gimple_statement_omp_teams *omp_teams_stmt = + as_a <gimple_statement_omp_teams> (gs); + omp_teams_stmt->clauses = clauses; } diff --git a/gcc/gsstruct.def b/gcc/gsstruct.def index 91738f4..82f1f52 100644 --- a/gcc/gsstruct.def +++ b/gcc/gsstruct.def @@ -43,11 +43,11 @@ DEFGSSTRUCT(GSS_WCE, gimple_statement_wce, false) DEFGSSTRUCT(GSS_OMP, gimple_statement_omp, false) DEFGSSTRUCT(GSS_OMP_CRITICAL, gimple_statement_omp_critical, false) DEFGSSTRUCT(GSS_OMP_FOR, gimple_statement_omp_for, false) -DEFGSSTRUCT(GSS_OMP_PARALLEL, gimple_statement_omp_parallel, false) +DEFGSSTRUCT(GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout, false) DEFGSSTRUCT(GSS_OMP_TASK, gimple_statement_omp_task, false) DEFGSSTRUCT(GSS_OMP_SECTIONS, gimple_statement_omp_sections, false) -DEFGSSTRUCT(GSS_OMP_SINGLE, gimple_statement_omp_single, false) +DEFGSSTRUCT(GSS_OMP_SINGLE_LAYOUT, gimple_statement_omp_single_layout, false) DEFGSSTRUCT(GSS_OMP_CONTINUE, gimple_statement_omp_continue, false) DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, gimple_statement_omp_atomic_load, false) -DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store, false) +DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE_LAYOUT, gimple_statement_omp_atomic_store, false) DEFGSSTRUCT(GSS_TRANSACTION, gimple_statement_transaction, false) ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Fix checking of gimple types 2013-11-25 18:09 ` [PATCH] Fix checking of gimple types David Malcolm @ 2013-11-25 18:42 ` Michael Matz 2013-11-25 22:18 ` Jeff Law 2014-07-23 13:16 ` Thomas Schwinge 2 siblings, 0 replies; 116+ messages in thread From: Michael Matz @ 2013-11-25 18:42 UTC (permalink / raw) To: David Malcolm; +Cc: Andrew MacLeod, Jakub Jelinek, Jeff Law, gcc-patches Hi, On Mon, 25 Nov 2013, David Malcolm wrote: > I'm not a fan of these "_layout" names, but I'm not sure what better to > call them. Perhaps: > GSS_OMP_PARALLEL_LAYOUT -> GSS_OMP_WITH_CLAUSES_CHILD_FN_DATA_ARG > GSS_OMP_SINGLE_LAYOUT -> GSS_OMP_WITH_CLAUSES > GSS_OMP_ATOMIC_STORE_LAYOUT -> GSS_OMP_WITHOUT_SEQ_WITH_VAL > with analogous names for the corresponding structs. The preexisting name for these structs has a _base suffix (gimple_statement_with_ops_base and gimple_statement_with_memory_ops_base are indeed in the same situation in that no gimple codes exist that directly make use of that gss, unlike e.g. GSS_BASE which does have some direct users). (I do like more selfdescribing names, though, so perhaps the existing _base variants could also use some renaming, but it should either be no _base names at all, or only _base names (i.e. no additional _layout for some other names)). > Another approach to this would be to entirely eliminate these shared > layout types, going purely with the conceptual is-a relationships > between the types, say, by replacing the gengtype switch on GSS_ value > with a switch on GIMPLE_ code. Given that this might affect the speed > of GC (bigger switch statements), I went with the relatively more > conservative change. I think it makes sense to keep storage layout and gimple codes separate, but still have them both structured. The former allows easier changes when looking at data layout problems (like memory optimizations, or GC), the latter easier transformations related to higher level logic of the data structures. Ciao, Michael. ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Fix checking of gimple types 2013-11-25 18:09 ` [PATCH] Fix checking of gimple types David Malcolm 2013-11-25 18:42 ` Michael Matz @ 2013-11-25 22:18 ` Jeff Law 2013-11-27 8:54 ` David Malcolm 2014-07-23 13:16 ` Thomas Schwinge 2 siblings, 1 reply; 116+ messages in thread From: Jeff Law @ 2013-11-25 22:18 UTC (permalink / raw) To: David Malcolm, Andrew MacLeod; +Cc: Jakub Jelinek, gcc-patches On 11/25/13 08:35, David Malcolm wrote: > > I'm not a fan of these "_layout" names, but I'm not sure what better to > call them. Perhaps: > GSS_OMP_PARALLEL_LAYOUT -> GSS_OMP_WITH_CLAUSES_CHILD_FN_DATA_ARG > GSS_OMP_SINGLE_LAYOUT -> GSS_OMP_WITH_CLAUSES > GSS_OMP_ATOMIC_STORE_LAYOUT -> GSS_OMP_WITHOUT_SEQ_WITH_VAL > with analogous names for the corresponding structs. I think the _layout names are fine for now. We might want change them to be more descriptive at a later date. > > OK for trunk? Yes. > > Sorry again for breaking this. It happens. I suspect you'll look beyond the sharing of data structures to build a class hierarchy next time :-) Thanks for quickly addressing this. Jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Fix checking of gimple types 2013-11-25 22:18 ` Jeff Law @ 2013-11-27 8:54 ` David Malcolm 0 siblings, 0 replies; 116+ messages in thread From: David Malcolm @ 2013-11-27 8:54 UTC (permalink / raw) To: Jeff Law; +Cc: Andrew MacLeod, Jakub Jelinek, gcc-patches On Mon, 2013-11-25 at 12:34 -0700, Jeff Law wrote: > On 11/25/13 08:35, David Malcolm wrote: > > > > I'm not a fan of these "_layout" names, but I'm not sure what better to > > call them. Perhaps: > > GSS_OMP_PARALLEL_LAYOUT -> GSS_OMP_WITH_CLAUSES_CHILD_FN_DATA_ARG > > GSS_OMP_SINGLE_LAYOUT -> GSS_OMP_WITH_CLAUSES > > GSS_OMP_ATOMIC_STORE_LAYOUT -> GSS_OMP_WITHOUT_SEQ_WITH_VAL > > with analogous names for the corresponding structs. > I think the _layout names are fine for now. We might want change them > to be more descriptive at a later date. > > > > > OK for trunk? > Yes. Thanks; committed to trunk as r205428. ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Fix checking of gimple types 2013-11-25 18:09 ` [PATCH] Fix checking of gimple types David Malcolm 2013-11-25 18:42 ` Michael Matz 2013-11-25 22:18 ` Jeff Law @ 2014-07-23 13:16 ` Thomas Schwinge 2014-07-24 1:50 ` David Malcolm 2 siblings, 1 reply; 116+ messages in thread From: Thomas Schwinge @ 2014-07-23 13:16 UTC (permalink / raw) To: David Malcolm, Andrew MacLeod; +Cc: Jakub Jelinek, Jeff Law, gcc-patches [-- Attachment #1: Type: text/plain, Size: 53150 bytes --] Hi! In context of adding support for OpenACC, next to the existing GIMPLE_OMP_TARGET (quoting from gcc/gimple.def and gcc/gimple.h): DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL_LAYOUT) /* GIMPLE_OMP_TARGET */ struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) gimple_statement_omp_target : public gimple_statement_omp_parallel_layout { /* No extra fields; adds invariant: stmt->code == GIMPLE_OMP_TARGET. */ }; ..., we're adding additional GIMPLE codes: DEFGSCODE(GIMPLE_OACC_KERNELS, "gimple_oacc_kernels", GSS_OMP_PARALLEL_LAYOUT) /* GIMPLE_OACC_KERNELS */ struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) gimple_statement_oacc_kernels : public gimple_statement_omp_parallel_layout { /* No extra fields; adds invariant: stmt->code == GIMPLE_OACC_KERNELS. */ }; DEFGSCODE(GIMPLE_OACC_PARALLEL, "gimple_oacc_parallel", GSS_OMP_PARALLEL_LAYOUT) /* GIMPLE_OACC_PARALLEL */ struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) gimple_statement_oacc_parallel : public gimple_statement_omp_parallel_layout { /* No extra fields; adds invariant: stmt->code == GIMPLE_OACC_PARALLEL. */ }; As you can see, all these codes share the same layout, GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout. Given this, I'd like to better understand the following: On Mon, 25 Nov 2013 10:35:18 -0500, David Malcolm <dmalcolm@redhat.com> wrote: > On Thu, 2013-11-21 at 18:03 -0500, Andrew MacLeod wrote: > > On 11/21/2013 05:42 PM, Jakub Jelinek wrote: > > > On Thu, Nov 21, 2013 at 03:24:55PM -0700, Jeff Law wrote: > > >> On 11/21/13 15:19, Jakub Jelinek wrote: > > >>> On Mon, Nov 18, 2013 at 03:25:52PM -0500, David Malcolm wrote: > > >>>>> So is there some reason the GIMPLE_CHECK was left in here rather than > > >>>>> doing the downcasting? This happens in other places. > > >>> Note that the changes removed tons of checks that IMHO were desirable. > > >>> The as_a that replaced those checks e.g. allows 3 different gimple codes, > > >>> while previously only one was allowed, this is both more expensive for > > >>> --enable-checking=yes, and allows one to use inline wrappers e.g. > > >>> gimple_omp_parallel_something on GIMPLE_OMP_TASK etc. > > >> Can you give a couple examples, please? > > > I mean e.g. > > > gimple_omp_parallel_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > > gimple_omp_taskreg_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > > gimple_omp_target_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > > gimple_omp_teams_{,set_}clauses{,_ptr} > > > gimple_omp_return_{,set_}lhs{,_ptr} > > > gimple_omp_atomic_store_{,set_}val{,_ptr} > > > gimple_resx_{,set_}region > > > gimple_eh_dispatch_{,set_}region We (have to) add the whole fleet of gimple_oacc_{kernels,parallel}_{clauses,...} accessors as well as new is_a_helper for {,const} gimple_statement_oacc_{kernels,parallel}. > > Why does is_a_helper <gimple_statement_omp_parallel>::test allow > > anything other than a GIMPLE_OMP_PARALLEL..? That seems wrong to me. > > should just be the one check. > > > > gimple_omp_taskreg and other routines "sharing" that helper should have > > their own helper and only check the one code.. thats is whole point to > > remain at least codegen neutral in these cases and provide correct > > checking. The fact that they may happen to share the same underlying > > structure is irrelevant. > > > > I also think this is wrong. > > Mea culpa. Unfortunately I made a conceptual error during the > conversion (the worst kind of error). I misunderstood the relationships > between the various OMP statements: there (mostly) aren't any, but the > sharing of structures for layout made me think there were. > > Attached is a patch, successfully bootstrapped®tested on > x86_64-unknown-linux-gnu, which I believe reinstates the checked-build > behaviors from before r205034 (and that the unchecked-build behaviors > were not affected by that commit and likewise are not by this patch). > > As I understand it, there are almost no "is-a" relationships between the > various omp statement types, some of them just happen to share layouts. > The exception is that the various gimple_omp_taskreg_* accessors accept > either codes GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK and so an > "omp_taskreg" is a concept, of which OMP_PARALLEL and OMP_TASK have an > is-a relationship. Admittedly, there is no is-a relationship between these, but yet, GIMPLE_OMP_TARGET as well as the new GIMPLE_OACC_KERNELS and GIMPLE_OACC_PARALLEL can share a lot of code, but, for example, where previously gimple_omp_target_set_child_fn or gimple_omp_target_clauses have been used, I now find myself writing code such as: void (*gimple_omp_set_child_fn) (gimple, tree); tree (*gimple_omp_clauses) (const_gimple); switch (gimple_code (stmt)) { case GIMPLE_OACC_KERNELS: gimple_omp_set_child_fn = gimple_oacc_kernels_set_child_fn; gimple_omp_clauses = gimple_oacc_kernels_clauses; break; case GIMPLE_OACC_PARALLEL: gimple_omp_set_child_fn = gimple_oacc_parallel_set_child_fn; gimple_omp_clauses = gimple_oacc_parallel_clauses; break; case GIMPLE_OMP_TARGET: gimple_omp_set_child_fn = gimple_omp_target_set_child_fn; gimple_omp_clauses = gimple_omp_target_clauses; break; default: gcc_unreachable (); } ..., only that I can then in the following use a unified interface for setting the child function or getting access to the clauses. What you can see here is that I first look at the GIMPLE code, and use that to determine the appropritate accessor functions. I have to do that because these specific accessor functions then again would like to check the respective GIMPLE code -- which I have just checked in the code quoted above. Instead, I'd rather like layout-specific accessor functions, such as gimple_omp_parallel_layout_set_child_fn or gimple_omp_parallel_layout_clauses. Is this a reasonable wish, or am I misunderstanding what all this "boilerplate" code for GIMPLE code checking is meant to achieve? (It's entirely possible that I'm misunderstanding something...) ;-) For example, might this suggest that our new GIMPLE code should in fact be proper sub-codes of GIMPLE_OMP_TARGET? Hmm... And regardless of this, from someone who is still learning his share of GCC internals, many, many thanks to you, Andrew and David (as well as everyone else who's contributing, of course), for all the refactoring work you're doing! This does make the GCC code more accessible. :-) (Follows full quote for reference.) > Based on this, I've reworked the is_a_helper functions, eliminating > almost all of the ones that accepted multiple codes. The only ones that > remain accepting multiple codes are those for: > > * gimple_statement_with_ops, which uses gimple_has_ops (gs), and for > * gimple_statement_with_memory_ops, which uses gimple_has_mem_ops > (gs), plus > * a new class gimple_statement_omp_taskreg, which expresses the > "either GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK" condition, and becomes a > parent struct for those. > > I introduced some new structs to express the pre-existing layouts for > GSS codes, and to distinguish them from structs that imply a specific > GIMPLE_ code. > For example, > gimple_statement_omp_atomic_store > now requires that the code be GIMPLE_OMP_ATOMIC_STORE, but it was also > the name of a layout, GSS_OMP_ATOMIC_STORE. So I renamed these purely > layout classes, so that there is now a > gimple_statement_omp_atomic_store_layout > class for the corresponding GSS value, which I renamed to > GSS_OMP_ATOMIC_STORE_LAYOUT > to make clear that this is just a layout: that although > GIMPLE_OMP_RETURN happens to share the data layout of > GIMPLE_OMP_ATOMIC_STORE, they are not otherwise related - they now both > inherit from the "_layout" class. > > I'm not a fan of these "_layout" names, but I'm not sure what better to > call them. Perhaps: > GSS_OMP_PARALLEL_LAYOUT -> GSS_OMP_WITH_CLAUSES_CHILD_FN_DATA_ARG > GSS_OMP_SINGLE_LAYOUT -> GSS_OMP_WITH_CLAUSES > GSS_OMP_ATOMIC_STORE_LAYOUT -> GSS_OMP_WITHOUT_SEQ_WITH_VAL > with analogous names for the corresponding structs. > > I added GTY tags for every class in the hierarchy, not just those that > introduce a new layout, since gengtype only recognizes inheritance when > supplied a "tag" option. This leads to the GSS values appearing > multiple times within the class hierarchy, which required a patch to > gengtype, to prevent duplicate case labels in the generated switch > statement. > > I believe that this structure correctly reinstates the exact behavior > from before the inheritance patch for the checked build, and that either > way, the behavior in the unchecked build is the same. > > Another approach to this would be to entirely eliminate these shared > layout types, going purely with the conceptual is-a relationships > between the types, say, by replacing the gengtype switch on GSS_ value > with a switch on GIMPLE_ code. Given that this might affect the speed > of GC (bigger switch statements), I went with the relatively more > conservative change. > > Successfully bootstrapped®tested on x86_64-unknown-linux-gnu. > > OK for trunk? > > Sorry again for breaking this. > > Here's an ASCII art inheritance diagram, showing the relationships > between structs, GSS_ values (layouts) and GIMPLE_ values (codes) - as I > see them. If I'm still misunderstanding something, sorry, please let me > know. Should this diagram live in gimple.h? > +- gimple_statement_base > | layout: GSS_BASE. 4 codes use this layout. > | > + gimple_statement_with_ops_base > | | (no GSS layout) > | | > | + gimple_statement_with_ops > | | layout: GSS_WITH_OPS. 5 codes use this layout. > | | > | + gimple_statement_with_memory_ops_base > | | layout: GSS_WITH_MEM_OPS_BASE > | | > | + gimple_statement_with_memory_ops > | | layout: GSS_WITH_MEM_OPS. > | | Used by codes GIMPLE_ASSIGN and GIMPLE_RETURN. > | | > | + gimple_statement_call > | | layout: GSS_CALL, code: GIMPLE_CALL > | | > | + gimple_statement_asm > | | layout: GSS_ASM, code: GIMPLE_ASM > | | > | + gimple_statement_transaction > | layout: GSS_TRANSACTION, code: GIMPLE_TRANSACTION > | > + gimple_statement_omp > | | layout: GSS_OMP > | | > | + gimple_statement_omp_critical > | | layout: GSS_OMP_CRITICAL, code: GIMPLE_OMP_CRITICAL > | | > | + gimple_statement_omp_for > | | layout: GSS_OMP_FOR, code: GIMPLE_OMP_FOR > | | > | + gimple_statement_omp_parallel_layout > | | | layout: GSS_OMP_PARALLEL_LAYOUT > | | | > | | + gimple_statement_omp_taskreg > | | | | > | | | + gimple_statement_omp_parallel > | | | | code: GIMPLE_OMP_PARALLEL > | | | | > | | | + gimple_statement_omp_task > | | | code: GIMPLE_OMP_TASK > | | | > | | + gimple_statement_omp_target > | | code: GIMPLE_OMP_TARGET > | | > | + gimple_statement_omp_sections > | | layout: GSS_OMP_SECTIONS, code: GIMPLE_OMP_SECTIONS > | | > | + gimple_statement_omp_single_layout > | | layout: GSS_OMP_SINGLE_LAYOUT > | | > | + gimple_statement_omp_single > | | code: GIMPLE_OMP_SINGLE > | | > | + gimple_statement_omp_teams > | code: GIMPLE_OMP_TEAMS > | > + gimple_statement_bind > | layout: GSS_BIND, code: GIMPLE_BIND > | > + gimple_statement_catch > | layout: GSS_CATCH, code: GIMPLE_CATCH > | > + gimple_statement_eh_filter > | layout: GSS_EH_FILTER, code: GIMPLE_EH_FILTER > | > + gimple_statement_eh_else > | layout: GSS_EH_ELSE, code: GIMPLE_EH_ELSE > | > + gimple_statement_eh_mnt > | layout: GSS_EH_MNT, code: GIMPLE_EH_MUST_NOT_THROW > | > + gimple_statement_phi > | layout: GSS_PHI, code: GIMPLE_PHI > | > + gimple_statement_eh_ctrl > | | layout: GSS_EH_CTRL > | | > | + gimple_statement_resx > | | code: GIMPLE_RESX > | | > | + gimple_statement_eh_dispatch > | code: GIMPLE_EH_DISPATCH > | > + gimple_statement_try > | layout: GSS_TRY, code: GIMPLE_TRY > | > + gimple_statement_wce > | layout: GSS_WCE, code: GIMPLE_WITH_CLEANUP_EXPR > | > + gimple_statement_omp_continue > | layout: GSS_OMP_CONTINUE, code: GIMPLE_OMP_CONTINUE > | > + gimple_statement_omp_atomic_load > | layout: GSS_OMP_ATOMIC_LOAD, code: GIMPLE_OMP_ATOMIC_LOAD > | > + gimple_statement_omp_atomic_store_layout > | layout: GSS_OMP_ATOMIC_STORE_LAYOUT, > | code: GIMPLE_OMP_ATOMIC_STORE > | > + gimple_statement_omp_atomic_store > | code: GIMPLE_OMP_ATOMIC_STORE > | > + gimple_statement_omp_return > code: GIMPLE_OMP_RETURN > > > commit 9a0c36081b3baecfc16a8500464df3a94c8dd145 > Author: David Malcolm <dmalcolm@redhat.com> > Date: Thu Nov 21 21:46:58 2013 -0500 > > Fix as_a<> helpers for gimple > > * gengtype.c (struct seen_tag): New. > (already_seen_tag): New. > (mark_tag_as_seen): New. > (walk_subclasses): Support having multiple subclasses using the > same tag by tracking which tags have already been seen, and using > this to avoid adding duplicate cases to the "switch" statement. > The call to already_seen_tag introduces an O(N^2) when running > gengtype on N, the number of tags, due to the repeated linear > search, but currently max(N) is relatively small (the number of > GSS codes, which is 26). > (walk_type): Pass in a seen_tag for use by the walk_subclasses > recursion. > > * gimple.def (GIMPLE_OMP_ATOMIC_STORE, GIMPLE_OMP_RETURN): Rename > underlying GSS values for these codes (from GSS_OMP_ATOMIC_STORE to > GSS_OMP_ATOMIC_STORE_LAYOUT) to make clear that although > GIMPLE_OMP_RETURN happens to share the data layout of > GIMPLE_OMP_ATOMIC_STORE, they are not otherwise related. > (GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET): Likewise, rename > underlying GSS value from GSS_OMP_PARALLEL to > GSS_OMP_PARALLEL_LAYOUT to make clear that these gimple codes are > not directly related; they merely share in-memory layout. > (GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS): Likewise, rename GSS values > for these two codes from GSS_OMP_SINGLE to GSS_OMP_SINGLE_LAYOUT. > > * gsstruct.def (GSS_OMP_PARALLEL, gimple_statement_omp_parallel): > Rename to... > (GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout): > ...these. > (GSS_OMP_SINGLE, gimple_statement_omp_single): Rename to... > (GSS_OMP_SINGLE_LAYOUT, gimple_statement_omp_single_layout): > ...these. > (GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store): Rename > to... > (GSS_OMP_ATOMIC_STORE_LAYOUT, gimple_statement_omp_atomic_store): > ...these. > > * gimple.h (gimple_statement_resx): New subclass of > gimple_statement_eh_ctrl, with the invariant that > stmt->code == GIMPLE_RESX. > (gimple_statement_eh_dispatch): New subclass of > gimple_statement_eh_ctrl, with the invariant that > stmt->code == GIMPLE_EH_DISPATH. > > (gimple_statement_omp_parallel): The existing class expressed > a layout (GSS_OMP_PARALLEL), but the codes with that layout > are not all related, so it makes more sense for this class to > express a *code* (GIMPLE_OMP_PARALLEL). GSS_OMP_PARALLEL has > been renamed to GSS_OMP_PARALLEL_LAYOUT to express this, so > rename the existing gimple_statement_omp_parallel class to... > (gimple_statement_omp_parallel_layout): ...this, expressing > a statement of structure layout GSS_OMP_PARALLEL_LAYOUT. > (gimple_statement_omp_taskreg): New subclass of > gimple_statement_omp_parallel_layout, expressing the invariant > that the code is one of GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK, > as used by the various gimple_omp_taskreg_ accessors. > (gimple_statement_omp_parallel): Reintroduce this class, this time > as a subclass of gimple_statement_omp_taskreg to express the > invariant stmt->code == GIMPLE_OMP_PARALLEL. > (gimple_statement_omp_target) New class, subclassing > gimple_statement_omp_parallel_layout, to express the invariant > stmt->code == GIMPLE_OMP_TARGET. > (gimple_statement_omp_task): Update to inherit from > gimple_statement_omp_taskreg rather than > gimple_statement_omp_parallel. > > (gimple_statement_omp_single): Rename to... > (gimple_statement_omp_single_layout): ...this, expressing the > invariant that the layout is GSS_OMP_SINGLE_LAYOUT. > (gimple_statement_omp_single): ...and reintroduce this name as > a subclass of gimple_statement_omp_single_layout, expressing > the invariant that code == GIMPLE_OMP_SINGLE. > (gimple_statement_omp_teams): New class, subclassing > gimple_statement_omp_single_layout, for the code GIMPLE_OMP_TEAMS. > > (gimple_statement_omp_atomic_store): Rename to... > (gimple_statement_omp_atomic_store_layout): ...this, expressing > the invariant that the layout is GSS_OMP_ATOMIC_STORE_LAYOUT. > (gimple_statement_omp_atomic_store): ...and reintroduce this > name as a subclass of gimple_statement_omp_atomic_store_layout > with code == GIMPLE_OMP_ATOMIC_STORE. > (gimple_statement_omp_return): New class, subclassing > gimple_statement_omp_atomic_store_layout for the code > GIMPLE_OMP_RETURN. > > (is_a_helper <gimple_statement_eh_ctrl>::test): Delete. > (is_a_helper <gimple_statement_resx>::test): New. > (is_a_helper <gimple_statement_eh_dispatch>::test): New. > (is_a_helper <gimple_statement_omp_atomic_store>::test): Only > check for GIMPLE_OMP_ATOMIC_STORE, not for GIMPLE_OMP_RETURN. > (is_a_helper <gimple_statement_omp_return>::test): New. > (is_a_helper <gimple_statement_omp_taskreg>::test): New. > (is_a_helper <gimple_statement_omp_parallel>::test): Only check > for GIMPLE_OMP_PARALLEL, not for GIMPLE_OMP_TASK or > GIMPLE_OMP_TARGET. > (is_a_helper <gimple_statement_omp_target>::test): New. > (is_a_helper <gimple_statement_omp_single>::test): Only check > for GIMPLE_OMP_SINGLE, not for GIMPLE_OMP_TEAMS. > (is_a_helper <gimple_statement_omp_teams>::test): New. > > (is_a_helper <const gimple_statement_eh_ctrl>::test): Delete. > (is_a_helper <const gimple_statement_resx>::test): New. > (is_a_helper <const gimple_statement_eh_dispatch>::test): New. > (is_a_helper <const gimple_statement_omp_atomic_store>::test): Only > check for GIMPLE_OMP_ATOMIC_STORE, not for GIMPLE_OMP_RETURN. > (is_a_helper <const gimple_statement_omp_return>::test): New. > (is_a_helper <const gimple_statement_omp_taskreg>::test): New. > (is_a_helper <const gimple_statement_omp_parallel>::test): Only > check for GIMPLE_OMP_PARALLEL, not for GIMPLE_OMP_TASK or > GIMPLE_OMP_TARGET. > (is_a_helper <const gimple_statement_omp_target>::test): New. > (is_a_helper <const gimple_statement_omp_single>::test): Only > check for GIMPLE_OMP_SINGLE, not for GIMPLE_OMP_TEAMS. > (is_a_helper <const gimple_statement_omp_teams>::test): New. > > (gimple_omp_return_set_lhs, gimple_omp_return_lhs, > gimple_omp_return_lhs_ptr): Replace bogus downcasts to > gimple_statement_omp_atomic_store with downcasts to > gimple_statement_omp_return, thus requiring that the code be > GIMPLE_OMP_RETURN. > (gimple_resx_region, gimple_resx_set_region): Replace bogus > downcasts to gimple_statement_eh_ctrl with downcasts to > gimple_statement_resx, thus requiring that the code be > GIMPLE_RESX. > (gimple_eh_dispatch_region, gimple_eh_dispatch_set_region): > Replace bogus downcasts to const gimple_statement_eh_ctrl with > downcasts to gimple_statement_eh_dispatch, thus requiring that > the code be GIMPLE_EH_DISPATCH. > (gimple_omp_taskreg_clauses, gimple_omp_taskreg_clauses_ptr) > gimple_omp_taskreg_set_clauses, gimple_omp_taskreg_child_fn, > gimple_omp_taskreg_child_fn_ptr, gimple_omp_taskreg_set_child_fn, > gimple_omp_taskreg_data_arg, gimple_omp_taskreg_data_arg_ptr, > gimple_omp_taskreg_set_data_arg): Replace bogus downcasts to > gimple_statement_omp_parallel with downcasts to > gimple_statement_omp_taskreg, thus requiring that the code be > either GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK. > (gimple_omp_target_clauses, gimple_omp_target_clauses_ptr > gimple_omp_target_set_clauses, gimple_omp_target_child_fn > gimple_omp_target_child_fn_ptr, gimple_omp_target_set_child_fn > gimple_omp_target_data_arg, gimple_omp_target_data_arg_ptr > gimple_omp_target_set_data_arg): Replace bogus downcasts to > gimple_statement_omp_parallel with downcasts to > gimple_statement_omp_target, thus requiring that the code be > GIMPLE_OMP_TARGET. > (gimple_omp_teams_clauses, gimple_omp_teams_clauses_ptr > gimple_omp_teams_set_clauses): Replace bogus downcasts to > gimple_statement_omp_single with downcasts to > gimple_statement_omp_teams, thus requiring that the code be > GIMPLE_OMP_TEAMS. > > * gimple.c (gimple_build_resx): Fix bogus as_a<> to use > gimple_statement_resx. > (gimple_build_eh_dispatch): Fix bogus as_a<> to use > gimple_statement_eh_dispatch. > > diff --git a/gcc/gengtype.c b/gcc/gengtype.c > index 86e9ca2..6e675cc 100644 > --- a/gcc/gengtype.c > +++ b/gcc/gengtype.c > @@ -2654,15 +2654,48 @@ get_string_option (options_p opt, const char *key) > return NULL; > } > > +/* Machinery for avoiding duplicate tags within switch statements. */ > +struct seen_tag > +{ > + const char *tag; > + struct seen_tag *next; > +}; > + > +int > +already_seen_tag (struct seen_tag *seen_tags, const char *tag) > +{ > + /* Linear search, so O(n^2), but n is currently small. */ > + while (seen_tags) > + { > + if (!strcmp (seen_tags->tag, tag)) > + return 1; > + seen_tags = seen_tags->next; > + } > + /* Not yet seen this tag. */ > + return 0; > +} > + > +void > +mark_tag_as_seen (struct seen_tag **seen_tags, const char *tag) > +{ > + /* Add to front of linked list. */ > + struct seen_tag *new_node = XCNEW (struct seen_tag); > + new_node->tag = tag; > + new_node->next = *seen_tags; > + *seen_tags = new_node; > +} > + > static void > -walk_subclasses (type_p base, struct walk_type_data *d) > +walk_subclasses (type_p base, struct walk_type_data *d, > + struct seen_tag **seen_tags) > { > for (type_p sub = base->u.s.first_subclass; sub != NULL; > sub = sub->u.s.next_sibling_class) > { > const char *type_tag = get_string_option (sub->u.s.opt, "tag"); > - if (type_tag) > + if (type_tag && !already_seen_tag (*seen_tags, type_tag)) > { > + mark_tag_as_seen (seen_tags, type_tag); > oprintf (d->of, "%*scase %s:\n", d->indent, "", type_tag); > d->indent += 2; > oprintf (d->of, "%*s{\n", d->indent, ""); > @@ -2678,7 +2711,7 @@ walk_subclasses (type_p base, struct walk_type_data *d) > oprintf (d->of, "%*sbreak;\n", d->indent, ""); > d->indent -= 2; > } > - walk_subclasses (sub, d); > + walk_subclasses (sub, d, seen_tags); > } > } > > @@ -3225,7 +3258,8 @@ walk_type (type_p t, struct walk_type_data *d) > else if (desc) > { > /* Add cases to handle subclasses. */ > - walk_subclasses (t, d); > + struct seen_tag *tags = NULL; > + walk_subclasses (t, d, &tags); > > /* Ensure that if someone forgets a "tag" option that we don't > silent fail to traverse that subclass's fields. */ > diff --git a/gcc/gimple.c b/gcc/gimple.c > index d48ca6b..2e45f37 100644 > --- a/gcc/gimple.c > +++ b/gcc/gimple.c > @@ -697,8 +697,8 @@ gimple_build_wce (gimple_seq cleanup) > gimple > gimple_build_resx (int region) > { > - gimple_statement_eh_ctrl *p = > - as_a <gimple_statement_eh_ctrl> ( > + gimple_statement_resx *p = > + as_a <gimple_statement_resx> ( > gimple_build_with_ops (GIMPLE_RESX, ERROR_MARK, 0)); > p->region = region; > return p; > @@ -747,8 +747,8 @@ gimple_build_switch (tree index, tree default_label, vec<tree> args) > gimple > gimple_build_eh_dispatch (int region) > { > - gimple_statement_eh_ctrl *p = > - as_a <gimple_statement_eh_ctrl> ( > + gimple_statement_eh_dispatch *p = > + as_a <gimple_statement_eh_dispatch> ( > gimple_build_with_ops (GIMPLE_EH_DISPATCH, ERROR_MARK, 0)); > p->region = region; > return p; > diff --git a/gcc/gimple.def b/gcc/gimple.def > index 07370ae..ff1ef43 100644 > --- a/gcc/gimple.def > +++ b/gcc/gimple.def > @@ -221,7 +221,7 @@ DEFGSCODE(GIMPLE_NOP, "gimple_nop", GSS_BASE) > DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load", > GSS_OMP_ATOMIC_LOAD) > DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store", > - GSS_OMP_ATOMIC_STORE) > + GSS_OMP_ATOMIC_STORE_LAYOUT) > > /* GIMPLE_OMP_CONTINUE marks the location of the loop or sections > iteration in partially lowered OpenMP code. */ > @@ -300,7 +300,7 @@ DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP) > DATA_ARG is a local variable in the parent function containing data > to be shared with CHILD_FN. This is used to implement all the data > sharing clauses. */ > -DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL) > +DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL_LAYOUT) > > /* GIMPLE_OMP_TASK <BODY, CLAUSES, CHILD_FN, DATA_ARG, COPY_FN, > ARG_SIZE, ARG_ALIGN> represents > @@ -329,7 +329,7 @@ DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL) > DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", GSS_OMP_TASK) > > /* OMP_RETURN marks the end of an OpenMP directive. */ > -DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_OMP_ATOMIC_STORE) > +DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_OMP_ATOMIC_STORE_LAYOUT) > > /* OMP_SECTION <BODY> represents #pragma omp section. > BODY is the sequence of statements in the section body. */ > @@ -351,7 +351,7 @@ DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE) > /* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single > BODY is the sequence of statements inside the single section. > CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ > -DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE) > +DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE_LAYOUT) > > /* GIMPLE_OMP_TARGET <BODY, CLAUSES, CHILD_FN> represents > #pragma omp target {,data,update} > @@ -364,12 +364,12 @@ DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE) > DATA_ARG is a vec of 3 local variables in the parent function > containing data to be mapped to CHILD_FN. This is used to > implement the MAP clauses. */ > -DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL) > +DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL_LAYOUT) > > /* GIMPLE_OMP_TEAMS <BODY, CLAUSES> represents #pragma omp teams > BODY is the sequence of statements inside the single section. > CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ > -DEFGSCODE(GIMPLE_OMP_TEAMS, "gimple_omp_teams", GSS_OMP_SINGLE) > +DEFGSCODE(GIMPLE_OMP_TEAMS, "gimple_omp_teams", GSS_OMP_SINGLE_LAYOUT) > > /* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction. > > diff --git a/gcc/gimple.h b/gcc/gimple.h > index 0eb23fc..0257576 100644 > --- a/gcc/gimple.h > +++ b/gcc/gimple.h > @@ -420,6 +420,20 @@ struct GTY((tag("GSS_EH_CTRL"))) > int region; > }; > > +struct GTY((tag("GSS_EH_CTRL"))) > + gimple_statement_resx : public gimple_statement_eh_ctrl > +{ > + /* No extra fields; adds invariant: > + stmt->code == GIMPLE_RESX. */ > +}; > + > +struct GTY((tag("GSS_EH_CTRL"))) > + gimple_statement_eh_dispatch : public gimple_statement_eh_ctrl > +{ > + /* No extra fields; adds invariant: > + stmt->code == GIMPLE_EH_DISPATH. */ > +}; > + > > /* GIMPLE_TRY */ > > @@ -547,10 +561,9 @@ struct GTY((tag("GSS_OMP_FOR"))) > }; > > > -/* GIMPLE_OMP_PARALLEL */ > - > -struct GTY((tag("GSS_OMP_PARALLEL"))) > - gimple_statement_omp_parallel : public gimple_statement_omp > +/* GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET */ > +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > + gimple_statement_omp_parallel_layout : public gimple_statement_omp > { > /* [ WORD 1-7 ] : base class */ > > @@ -567,11 +580,35 @@ struct GTY((tag("GSS_OMP_PARALLEL"))) > tree data_arg; > }; > > +/* GIMPLE_OMP_PARALLEL or GIMPLE_TASK */ > +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > + gimple_statement_omp_taskreg : public gimple_statement_omp_parallel_layout > +{ > + /* No extra fields; adds invariant: > + stmt->code == GIMPLE_OMP_PARALLEL > + || stmt->code == GIMPLE_OMP_TASK. */ > +}; > + > + > +/* GIMPLE_OMP_PARALLEL */ > +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > + gimple_statement_omp_parallel : public gimple_statement_omp_taskreg > +{ > + /* No extra fields; adds invariant: > + stmt->code == GIMPLE_OMP_PARALLEL. */ > +}; > + > +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > + gimple_statement_omp_target : public gimple_statement_omp_parallel_layout > +{ > + /* No extra fields; adds invariant: > + stmt->code == GIMPLE_OMP_TARGET. */ > +}; > > /* GIMPLE_OMP_TASK */ > > struct GTY((tag("GSS_OMP_TASK"))) > - gimple_statement_omp_task : public gimple_statement_omp_parallel > + gimple_statement_omp_task : public gimple_statement_omp_taskreg > { > /* [ WORD 1-10 ] : base class */ > > @@ -623,10 +660,10 @@ struct GTY((tag("GSS_OMP_CONTINUE"))) > tree control_use; > }; > > -/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS */ > +/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS */ > > -struct GTY((tag("GSS_OMP_SINGLE"))) > - gimple_statement_omp_single : public gimple_statement_omp > +struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) > + gimple_statement_omp_single_layout : public gimple_statement_omp > { > /* [ WORD 1-7 ] : base class */ > > @@ -634,6 +671,20 @@ struct GTY((tag("GSS_OMP_SINGLE"))) > tree clauses; > }; > > +struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) > + gimple_statement_omp_single : public gimple_statement_omp_single_layout > +{ > + /* No extra fields; adds invariant: > + stmt->code == GIMPLE_OMP_SINGLE. */ > +}; > + > +struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) > + gimple_statement_omp_teams : public gimple_statement_omp_single_layout > +{ > + /* No extra fields; adds invariant: > + stmt->code == GIMPLE_OMP_TEAMS. */ > +}; > + > > /* GIMPLE_OMP_ATOMIC_LOAD. > Note: This is based on gimple_statement_base, not g_s_omp, because g_s_omp > @@ -651,8 +702,8 @@ struct GTY((tag("GSS_OMP_ATOMIC_LOAD"))) > /* GIMPLE_OMP_ATOMIC_STORE. > See note on GIMPLE_OMP_ATOMIC_LOAD. */ > > -struct GTY((tag("GSS_OMP_ATOMIC_STORE"))) > - gimple_statement_omp_atomic_store : public gimple_statement_base > +struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) > + gimple_statement_omp_atomic_store_layout : public gimple_statement_base > { > /* [ WORD 1-6 ] : base class */ > > @@ -660,6 +711,22 @@ struct GTY((tag("GSS_OMP_ATOMIC_STORE"))) > tree val; > }; > > +struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) > + gimple_statement_omp_atomic_store : > + public gimple_statement_omp_atomic_store_layout > +{ > + /* No extra fields; adds invariant: > + stmt->code == GIMPLE_OMP_ATOMIC_STORE. */ > +}; > + > +struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) > + gimple_statement_omp_return : > + public gimple_statement_omp_atomic_store_layout > +{ > + /* No extra fields; adds invariant: > + stmt->code == GIMPLE_OMP_RETURN. */ > +}; > + > /* GIMPLE_TRANSACTION. */ > > /* Bits to be stored in the GIMPLE_TRANSACTION subcode. */ > @@ -742,9 +809,17 @@ is_a_helper <gimple_statement_catch>::test (gimple gs) > template <> > template <> > inline bool > -is_a_helper <gimple_statement_eh_ctrl>::test (gimple gs) > +is_a_helper <gimple_statement_resx>::test (gimple gs) > +{ > + return gs->code == GIMPLE_RESX; > +} > + > +template <> > +template <> > +inline bool > +is_a_helper <gimple_statement_eh_dispatch>::test (gimple gs) > { > - return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH; > + return gs->code == GIMPLE_EH_DISPATCH; > } > > template <> > @@ -784,7 +859,15 @@ template <> > inline bool > is_a_helper <gimple_statement_omp_atomic_store>::test (gimple gs) > { > - return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN; > + return gs->code == GIMPLE_OMP_ATOMIC_STORE; > +} > + > +template <> > +template <> > +inline bool > +is_a_helper <gimple_statement_omp_return>::test (gimple gs) > +{ > + return gs->code == GIMPLE_OMP_RETURN; > } > > template <> > @@ -814,9 +897,25 @@ is_a_helper <gimple_statement_omp_for>::test (gimple gs) > template <> > template <> > inline bool > +is_a_helper <gimple_statement_omp_taskreg>::test (gimple gs) > +{ > + return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK; > +} > + > +template <> > +template <> > +inline bool > is_a_helper <gimple_statement_omp_parallel>::test (gimple gs) > { > - return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET; > + return gs->code == GIMPLE_OMP_PARALLEL; > +} > + > +template <> > +template <> > +inline bool > +is_a_helper <gimple_statement_omp_target>::test (gimple gs) > +{ > + return gs->code == GIMPLE_OMP_TARGET; > } > > template <> > @@ -832,7 +931,15 @@ template <> > inline bool > is_a_helper <gimple_statement_omp_single>::test (gimple gs) > { > - return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS; > + return gs->code == GIMPLE_OMP_SINGLE; > +} > + > +template <> > +template <> > +inline bool > +is_a_helper <gimple_statement_omp_teams>::test (gimple gs) > +{ > + return gs->code == GIMPLE_OMP_TEAMS; > } > > template <> > @@ -910,9 +1017,17 @@ is_a_helper <const gimple_statement_catch>::test (const_gimple gs) > template <> > template <> > inline bool > -is_a_helper <const gimple_statement_eh_ctrl>::test (const_gimple gs) > +is_a_helper <const gimple_statement_resx>::test (const_gimple gs) > { > - return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH; > + return gs->code == GIMPLE_RESX; > +} > + > +template <> > +template <> > +inline bool > +is_a_helper <const gimple_statement_eh_dispatch>::test (const_gimple gs) > +{ > + return gs->code == GIMPLE_EH_DISPATCH; > } > > template <> > @@ -936,7 +1051,15 @@ template <> > inline bool > is_a_helper <const gimple_statement_omp_atomic_store>::test (const_gimple gs) > { > - return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN; > + return gs->code == GIMPLE_OMP_ATOMIC_STORE; > +} > + > +template <> > +template <> > +inline bool > +is_a_helper <const gimple_statement_omp_return>::test (const_gimple gs) > +{ > + return gs->code == GIMPLE_OMP_RETURN; > } > > template <> > @@ -966,9 +1089,25 @@ is_a_helper <const gimple_statement_omp_for>::test (const_gimple gs) > template <> > template <> > inline bool > +is_a_helper <const gimple_statement_omp_taskreg>::test (const_gimple gs) > +{ > + return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK; > +} > + > +template <> > +template <> > +inline bool > is_a_helper <const gimple_statement_omp_parallel>::test (const_gimple gs) > { > - return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET; > + return gs->code == GIMPLE_OMP_PARALLEL; > +} > + > +template <> > +template <> > +inline bool > +is_a_helper <const gimple_statement_omp_target>::test (const_gimple gs) > +{ > + return gs->code == GIMPLE_OMP_TARGET; > } > > template <> > @@ -984,7 +1123,15 @@ template <> > inline bool > is_a_helper <const gimple_statement_omp_single>::test (const_gimple gs) > { > - return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS; > + return gs->code == GIMPLE_OMP_SINGLE; > +} > + > +template <> > +template <> > +inline bool > +is_a_helper <const gimple_statement_omp_teams>::test (const_gimple gs) > +{ > + return gs->code == GIMPLE_OMP_TEAMS; > } > > template <> > @@ -1766,9 +1913,9 @@ gimple_omp_return_nowait_p (const_gimple g) > static inline void > gimple_omp_return_set_lhs (gimple g, tree lhs) > { > - gimple_statement_omp_atomic_store *omp_atomic_store_stmt = > - as_a <gimple_statement_omp_atomic_store> (g); > - omp_atomic_store_stmt->val = lhs; > + gimple_statement_omp_return *omp_return_stmt = > + as_a <gimple_statement_omp_return> (g); > + omp_return_stmt->val = lhs; > } > > > @@ -1777,9 +1924,9 @@ gimple_omp_return_set_lhs (gimple g, tree lhs) > static inline tree > gimple_omp_return_lhs (const_gimple g) > { > - const gimple_statement_omp_atomic_store *omp_atomic_store_stmt = > - as_a <const gimple_statement_omp_atomic_store> (g); > - return omp_atomic_store_stmt->val; > + const gimple_statement_omp_return *omp_return_stmt = > + as_a <const gimple_statement_omp_return> (g); > + return omp_return_stmt->val; > } > > > @@ -1788,9 +1935,9 @@ gimple_omp_return_lhs (const_gimple g) > static inline tree * > gimple_omp_return_lhs_ptr (gimple g) > { > - gimple_statement_omp_atomic_store *omp_atomic_store_stmt = > - as_a <gimple_statement_omp_atomic_store> (g); > - return &omp_atomic_store_stmt->val; > + gimple_statement_omp_return *omp_return_stmt = > + as_a <gimple_statement_omp_return> (g); > + return &omp_return_stmt->val; > } > > > @@ -3793,9 +3940,9 @@ gimple_phi_arg_has_location (gimple gs, size_t i) > static inline int > gimple_resx_region (const_gimple gs) > { > - const gimple_statement_eh_ctrl *eh_ctrl_stmt = > - as_a <const gimple_statement_eh_ctrl> (gs); > - return eh_ctrl_stmt->region; > + const gimple_statement_resx *resx_stmt = > + as_a <const gimple_statement_resx> (gs); > + return resx_stmt->region; > } > > /* Set REGION to be the region number for GIMPLE_RESX GS. */ > @@ -3803,9 +3950,8 @@ gimple_resx_region (const_gimple gs) > static inline void > gimple_resx_set_region (gimple gs, int region) > { > - gimple_statement_eh_ctrl *eh_ctrl_stmt = > - as_a <gimple_statement_eh_ctrl> (gs); > - eh_ctrl_stmt->region = region; > + gimple_statement_resx *resx_stmt = as_a <gimple_statement_resx> (gs); > + resx_stmt->region = region; > } > > /* Return the region number for GIMPLE_EH_DISPATCH GS. */ > @@ -3813,9 +3959,9 @@ gimple_resx_set_region (gimple gs, int region) > static inline int > gimple_eh_dispatch_region (const_gimple gs) > { > - const gimple_statement_eh_ctrl *eh_ctrl_stmt = > - as_a <const gimple_statement_eh_ctrl> (gs); > - return eh_ctrl_stmt->region; > + const gimple_statement_eh_dispatch *eh_dispatch_stmt = > + as_a <const gimple_statement_eh_dispatch> (gs); > + return eh_dispatch_stmt->region; > } > > /* Set REGION to be the region number for GIMPLE_EH_DISPATCH GS. */ > @@ -3823,9 +3969,9 @@ gimple_eh_dispatch_region (const_gimple gs) > static inline void > gimple_eh_dispatch_set_region (gimple gs, int region) > { > - gimple_statement_eh_ctrl *eh_ctrl_stmt = > - as_a <gimple_statement_eh_ctrl> (gs); > - eh_ctrl_stmt->region = region; > + gimple_statement_eh_dispatch *eh_dispatch_stmt = > + as_a <gimple_statement_eh_dispatch> (gs); > + eh_dispatch_stmt->region = region; > } > > /* Return the number of labels associated with the switch statement GS. */ > @@ -4663,9 +4809,9 @@ gimple_omp_task_set_data_arg (gimple gs, tree data_arg) > static inline tree > gimple_omp_taskreg_clauses (const_gimple gs) > { > - const gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <const gimple_statement_omp_parallel> (gs); > - return omp_parallel_stmt->clauses; > + const gimple_statement_omp_taskreg *omp_taskreg_stmt = > + as_a <const gimple_statement_omp_taskreg> (gs); > + return omp_taskreg_stmt->clauses; > } > > > @@ -4674,9 +4820,9 @@ gimple_omp_taskreg_clauses (const_gimple gs) > static inline tree * > gimple_omp_taskreg_clauses_ptr (gimple gs) > { > - gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <gimple_statement_omp_parallel> (gs); > - return &omp_parallel_stmt->clauses; > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > + as_a <gimple_statement_omp_taskreg> (gs); > + return &omp_taskreg_stmt->clauses; > } > > > @@ -4686,9 +4832,9 @@ gimple_omp_taskreg_clauses_ptr (gimple gs) > static inline void > gimple_omp_taskreg_set_clauses (gimple gs, tree clauses) > { > - gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <gimple_statement_omp_parallel> (gs); > - omp_parallel_stmt->clauses = clauses; > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > + as_a <gimple_statement_omp_taskreg> (gs); > + omp_taskreg_stmt->clauses = clauses; > } > > > @@ -4697,9 +4843,9 @@ gimple_omp_taskreg_set_clauses (gimple gs, tree clauses) > static inline tree > gimple_omp_taskreg_child_fn (const_gimple gs) > { > - const gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <const gimple_statement_omp_parallel> (gs); > - return omp_parallel_stmt->child_fn; > + const gimple_statement_omp_taskreg *omp_taskreg_stmt = > + as_a <const gimple_statement_omp_taskreg> (gs); > + return omp_taskreg_stmt->child_fn; > } > > /* Return a pointer to the child function used to hold the body of > @@ -4708,9 +4854,9 @@ gimple_omp_taskreg_child_fn (const_gimple gs) > static inline tree * > gimple_omp_taskreg_child_fn_ptr (gimple gs) > { > - gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <gimple_statement_omp_parallel> (gs); > - return &omp_parallel_stmt->child_fn; > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > + as_a <gimple_statement_omp_taskreg> (gs); > + return &omp_taskreg_stmt->child_fn; > } > > > @@ -4719,9 +4865,9 @@ gimple_omp_taskreg_child_fn_ptr (gimple gs) > static inline void > gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn) > { > - gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <gimple_statement_omp_parallel> (gs); > - omp_parallel_stmt->child_fn = child_fn; > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > + as_a <gimple_statement_omp_taskreg> (gs); > + omp_taskreg_stmt->child_fn = child_fn; > } > > > @@ -4731,9 +4877,9 @@ gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn) > static inline tree > gimple_omp_taskreg_data_arg (const_gimple gs) > { > - const gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <const gimple_statement_omp_parallel> (gs); > - return omp_parallel_stmt->data_arg; > + const gimple_statement_omp_taskreg *omp_taskreg_stmt = > + as_a <const gimple_statement_omp_taskreg> (gs); > + return omp_taskreg_stmt->data_arg; > } > > > @@ -4742,9 +4888,9 @@ gimple_omp_taskreg_data_arg (const_gimple gs) > static inline tree * > gimple_omp_taskreg_data_arg_ptr (gimple gs) > { > - gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <gimple_statement_omp_parallel> (gs); > - return &omp_parallel_stmt->data_arg; > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > + as_a <gimple_statement_omp_taskreg> (gs); > + return &omp_taskreg_stmt->data_arg; > } > > > @@ -4753,9 +4899,9 @@ gimple_omp_taskreg_data_arg_ptr (gimple gs) > static inline void > gimple_omp_taskreg_set_data_arg (gimple gs, tree data_arg) > { > - gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <gimple_statement_omp_parallel> (gs); > - omp_parallel_stmt->data_arg = data_arg; > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > + as_a <gimple_statement_omp_taskreg> (gs); > + omp_taskreg_stmt->data_arg = data_arg; > } > > > @@ -4896,9 +5042,9 @@ gimple_omp_single_set_clauses (gimple gs, tree clauses) > static inline tree > gimple_omp_target_clauses (const_gimple gs) > { > - const gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <const gimple_statement_omp_parallel> (gs); > - return omp_parallel_stmt->clauses; > + const gimple_statement_omp_target *omp_target_stmt = > + as_a <const gimple_statement_omp_target> (gs); > + return omp_target_stmt->clauses; > } > > > @@ -4907,9 +5053,9 @@ gimple_omp_target_clauses (const_gimple gs) > static inline tree * > gimple_omp_target_clauses_ptr (gimple gs) > { > - gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <gimple_statement_omp_parallel> (gs); > - return &omp_parallel_stmt->clauses; > + gimple_statement_omp_target *omp_target_stmt = > + as_a <gimple_statement_omp_target> (gs); > + return &omp_target_stmt->clauses; > } > > > @@ -4918,9 +5064,9 @@ gimple_omp_target_clauses_ptr (gimple gs) > static inline void > gimple_omp_target_set_clauses (gimple gs, tree clauses) > { > - gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <gimple_statement_omp_parallel> (gs); > - omp_parallel_stmt->clauses = clauses; > + gimple_statement_omp_target *omp_target_stmt = > + as_a <gimple_statement_omp_target> (gs); > + omp_target_stmt->clauses = clauses; > } > > > @@ -4950,9 +5096,9 @@ gimple_omp_target_set_kind (gimple g, int kind) > static inline tree > gimple_omp_target_child_fn (const_gimple gs) > { > - const gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <const gimple_statement_omp_parallel> (gs); > - return omp_parallel_stmt->child_fn; > + const gimple_statement_omp_target *omp_target_stmt = > + as_a <const gimple_statement_omp_target> (gs); > + return omp_target_stmt->child_fn; > } > > /* Return a pointer to the child function used to hold the body of > @@ -4961,9 +5107,9 @@ gimple_omp_target_child_fn (const_gimple gs) > static inline tree * > gimple_omp_target_child_fn_ptr (gimple gs) > { > - gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <gimple_statement_omp_parallel> (gs); > - return &omp_parallel_stmt->child_fn; > + gimple_statement_omp_target *omp_target_stmt = > + as_a <gimple_statement_omp_target> (gs); > + return &omp_target_stmt->child_fn; > } > > > @@ -4972,9 +5118,9 @@ gimple_omp_target_child_fn_ptr (gimple gs) > static inline void > gimple_omp_target_set_child_fn (gimple gs, tree child_fn) > { > - gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <gimple_statement_omp_parallel> (gs); > - omp_parallel_stmt->child_fn = child_fn; > + gimple_statement_omp_target *omp_target_stmt = > + as_a <gimple_statement_omp_target> (gs); > + omp_target_stmt->child_fn = child_fn; > } > > > @@ -4984,9 +5130,9 @@ gimple_omp_target_set_child_fn (gimple gs, tree child_fn) > static inline tree > gimple_omp_target_data_arg (const_gimple gs) > { > - const gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <const gimple_statement_omp_parallel> (gs); > - return omp_parallel_stmt->data_arg; > + const gimple_statement_omp_target *omp_target_stmt = > + as_a <const gimple_statement_omp_target> (gs); > + return omp_target_stmt->data_arg; > } > > > @@ -4995,9 +5141,9 @@ gimple_omp_target_data_arg (const_gimple gs) > static inline tree * > gimple_omp_target_data_arg_ptr (gimple gs) > { > - gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <gimple_statement_omp_parallel> (gs); > - return &omp_parallel_stmt->data_arg; > + gimple_statement_omp_target *omp_target_stmt = > + as_a <gimple_statement_omp_target> (gs); > + return &omp_target_stmt->data_arg; > } > > > @@ -5006,9 +5152,9 @@ gimple_omp_target_data_arg_ptr (gimple gs) > static inline void > gimple_omp_target_set_data_arg (gimple gs, tree data_arg) > { > - gimple_statement_omp_parallel *omp_parallel_stmt = > - as_a <gimple_statement_omp_parallel> (gs); > - omp_parallel_stmt->data_arg = data_arg; > + gimple_statement_omp_target *omp_target_stmt = > + as_a <gimple_statement_omp_target> (gs); > + omp_target_stmt->data_arg = data_arg; > } > > > @@ -5017,9 +5163,9 @@ gimple_omp_target_set_data_arg (gimple gs, tree data_arg) > static inline tree > gimple_omp_teams_clauses (const_gimple gs) > { > - const gimple_statement_omp_single *omp_single_stmt = > - as_a <const gimple_statement_omp_single> (gs); > - return omp_single_stmt->clauses; > + const gimple_statement_omp_teams *omp_teams_stmt = > + as_a <const gimple_statement_omp_teams> (gs); > + return omp_teams_stmt->clauses; > } > > > @@ -5028,9 +5174,9 @@ gimple_omp_teams_clauses (const_gimple gs) > static inline tree * > gimple_omp_teams_clauses_ptr (gimple gs) > { > - gimple_statement_omp_single *omp_single_stmt = > - as_a <gimple_statement_omp_single> (gs); > - return &omp_single_stmt->clauses; > + gimple_statement_omp_teams *omp_teams_stmt = > + as_a <gimple_statement_omp_teams> (gs); > + return &omp_teams_stmt->clauses; > } > > > @@ -5039,9 +5185,9 @@ gimple_omp_teams_clauses_ptr (gimple gs) > static inline void > gimple_omp_teams_set_clauses (gimple gs, tree clauses) > { > - gimple_statement_omp_single *omp_single_stmt = > - as_a <gimple_statement_omp_single> (gs); > - omp_single_stmt->clauses = clauses; > + gimple_statement_omp_teams *omp_teams_stmt = > + as_a <gimple_statement_omp_teams> (gs); > + omp_teams_stmt->clauses = clauses; > } > > > diff --git a/gcc/gsstruct.def b/gcc/gsstruct.def > index 91738f4..82f1f52 100644 > --- a/gcc/gsstruct.def > +++ b/gcc/gsstruct.def > @@ -43,11 +43,11 @@ DEFGSSTRUCT(GSS_WCE, gimple_statement_wce, false) > DEFGSSTRUCT(GSS_OMP, gimple_statement_omp, false) > DEFGSSTRUCT(GSS_OMP_CRITICAL, gimple_statement_omp_critical, false) > DEFGSSTRUCT(GSS_OMP_FOR, gimple_statement_omp_for, false) > -DEFGSSTRUCT(GSS_OMP_PARALLEL, gimple_statement_omp_parallel, false) > +DEFGSSTRUCT(GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout, false) > DEFGSSTRUCT(GSS_OMP_TASK, gimple_statement_omp_task, false) > DEFGSSTRUCT(GSS_OMP_SECTIONS, gimple_statement_omp_sections, false) > -DEFGSSTRUCT(GSS_OMP_SINGLE, gimple_statement_omp_single, false) > +DEFGSSTRUCT(GSS_OMP_SINGLE_LAYOUT, gimple_statement_omp_single_layout, false) > DEFGSSTRUCT(GSS_OMP_CONTINUE, gimple_statement_omp_continue, false) > DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, gimple_statement_omp_atomic_load, false) > -DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store, false) > +DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE_LAYOUT, gimple_statement_omp_atomic_store, false) > DEFGSSTRUCT(GSS_TRANSACTION, gimple_statement_transaction, false) Grüße, Thomas [-- Attachment #2: Type: application/pgp-signature, Size: 472 bytes --] ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Fix checking of gimple types 2014-07-23 13:16 ` Thomas Schwinge @ 2014-07-24 1:50 ` David Malcolm 2014-07-29 8:11 ` Thomas Schwinge 0 siblings, 1 reply; 116+ messages in thread From: David Malcolm @ 2014-07-24 1:50 UTC (permalink / raw) To: Thomas Schwinge; +Cc: Andrew MacLeod, Jakub Jelinek, Jeff Law, gcc-patches On Wed, 2014-07-23 at 15:00 +0200, Thomas Schwinge wrote: > Hi! > > In context of adding support for OpenACC, next to the existing > GIMPLE_OMP_TARGET (quoting from gcc/gimple.def and gcc/gimple.h): > > DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL_LAYOUT) > > /* GIMPLE_OMP_TARGET */ > struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > gimple_statement_omp_target : public gimple_statement_omp_parallel_layout > { > /* No extra fields; adds invariant: > stmt->code == GIMPLE_OMP_TARGET. */ > }; > > ..., we're adding additional GIMPLE codes: > > DEFGSCODE(GIMPLE_OACC_KERNELS, "gimple_oacc_kernels", GSS_OMP_PARALLEL_LAYOUT) > > /* GIMPLE_OACC_KERNELS */ > struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > gimple_statement_oacc_kernels : public gimple_statement_omp_parallel_layout > { > /* No extra fields; adds invariant: > stmt->code == GIMPLE_OACC_KERNELS. */ > }; > > DEFGSCODE(GIMPLE_OACC_PARALLEL, "gimple_oacc_parallel", GSS_OMP_PARALLEL_LAYOUT) > > /* GIMPLE_OACC_PARALLEL */ > struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > gimple_statement_oacc_parallel : public gimple_statement_omp_parallel_layout > { > /* No extra fields; adds invariant: > stmt->code == GIMPLE_OACC_PARALLEL. */ > }; > > As you can see, all these codes share the same layout, > GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout. > > Given this, I'd like to better understand the following: > > On Mon, 25 Nov 2013 10:35:18 -0500, David Malcolm <dmalcolm@redhat.com> wrote: > > On Thu, 2013-11-21 at 18:03 -0500, Andrew MacLeod wrote: > > > On 11/21/2013 05:42 PM, Jakub Jelinek wrote: > > > > On Thu, Nov 21, 2013 at 03:24:55PM -0700, Jeff Law wrote: > > > >> On 11/21/13 15:19, Jakub Jelinek wrote: > > > >>> On Mon, Nov 18, 2013 at 03:25:52PM -0500, David Malcolm wrote: > > > >>>>> So is there some reason the GIMPLE_CHECK was left in here rather than > > > >>>>> doing the downcasting? This happens in other places. > > > >>> Note that the changes removed tons of checks that IMHO were desirable. > > > >>> The as_a that replaced those checks e.g. allows 3 different gimple codes, > > > >>> while previously only one was allowed, this is both more expensive for > > > >>> --enable-checking=yes, and allows one to use inline wrappers e.g. > > > >>> gimple_omp_parallel_something on GIMPLE_OMP_TASK etc. > > > >> Can you give a couple examples, please? > > > > I mean e.g. > > > > gimple_omp_parallel_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > > > gimple_omp_taskreg_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > > > gimple_omp_target_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > > > gimple_omp_teams_{,set_}clauses{,_ptr} > > > > gimple_omp_return_{,set_}lhs{,_ptr} > > > > gimple_omp_atomic_store_{,set_}val{,_ptr} > > > > gimple_resx_{,set_}region > > > > gimple_eh_dispatch_{,set_}region > > We (have to) add the whole fleet of > gimple_oacc_{kernels,parallel}_{clauses,...} accessors as well as new > is_a_helper for {,const} gimple_statement_oacc_{kernels,parallel}. > > > > Why does is_a_helper <gimple_statement_omp_parallel>::test allow > > > anything other than a GIMPLE_OMP_PARALLEL..? That seems wrong to me. > > > should just be the one check. > > > > > > gimple_omp_taskreg and other routines "sharing" that helper should have > > > their own helper and only check the one code.. thats is whole point to > > > remain at least codegen neutral in these cases and provide correct > > > checking. The fact that they may happen to share the same underlying > > > structure is irrelevant. > > > > > > I also think this is wrong. > > > > Mea culpa. Unfortunately I made a conceptual error during the > > conversion (the worst kind of error). I misunderstood the relationships > > between the various OMP statements: there (mostly) aren't any, but the > > sharing of structures for layout made me think there were. > > > > Attached is a patch, successfully bootstrapped®tested on > > x86_64-unknown-linux-gnu, which I believe reinstates the checked-build > > behaviors from before r205034 (and that the unchecked-build behaviors > > were not affected by that commit and likewise are not by this patch). > > > > As I understand it, there are almost no "is-a" relationships between the > > various omp statement types, some of them just happen to share layouts. > > The exception is that the various gimple_omp_taskreg_* accessors accept > > either codes GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK and so an > > "omp_taskreg" is a concept, of which OMP_PARALLEL and OMP_TASK have an > > is-a relationship. > > Admittedly, there is no is-a relationship between these, but yet, > GIMPLE_OMP_TARGET as well as the new GIMPLE_OACC_KERNELS and > GIMPLE_OACC_PARALLEL can share a lot of code, but, for example, where > previously gimple_omp_target_set_child_fn or gimple_omp_target_clauses > have been used, I now find myself writing code such as: > > void (*gimple_omp_set_child_fn) (gimple, tree); > tree (*gimple_omp_clauses) (const_gimple); > switch (gimple_code (stmt)) > { > case GIMPLE_OACC_KERNELS: > gimple_omp_set_child_fn = gimple_oacc_kernels_set_child_fn; > gimple_omp_clauses = gimple_oacc_kernels_clauses; > break; > case GIMPLE_OACC_PARALLEL: > gimple_omp_set_child_fn = gimple_oacc_parallel_set_child_fn; > gimple_omp_clauses = gimple_oacc_parallel_clauses; > break; > case GIMPLE_OMP_TARGET: > gimple_omp_set_child_fn = gimple_omp_target_set_child_fn; > gimple_omp_clauses = gimple_omp_target_clauses; > break; > default: > gcc_unreachable (); > } > > ..., only that I can then in the following use a unified interface for > setting the child function or getting access to the clauses. Hmmmm. What does the above code do, and is that pattern happening repeatedly? Given the above it sounds like we may need these types to inherit from a common parent class ("gimple_something"), and for the parent to provide: gimple_something_set_child_fn gimple_something_clauses > What you can see here is that I first look at the GIMPLE code, and use > that to determine the appropritate accessor functions. I have to do that > because these specific accessor functions then again would like to check > the respective GIMPLE code -- which I have just checked in the code > quoted above. Instead, I'd rather like layout-specific accessor > functions, such as gimple_omp_parallel_layout_set_child_fn or > gimple_omp_parallel_layout_clauses. BTW I have an 89-patch patch kit that strengthens the params to gimple accessors, requiring appropriate subclasses, and eliminating the code checks; see e.g.: https://gcc.gnu.org/ml/gcc-patches/2014-04/msg01159.html This patch kit was approved, but I was asked to hold off committing it to trunk until 4.9.1 was out, and also to investigate some renamings, so it's been in a "holding pattern" for a while. So we'll need to incorporate whatever we do for OpenACC into those patches (or vice versa). FWIW, I was never particularly fond of the name "gimple_omp_parallel_layout"; IIRC it was necessary as a way of expressing that we're using a particular data layout (GSS_OMP_PARALLEL_LAYOUT), and to be different from the specific concrete subclass used for code GIMPLE_OMP_PARALLEL. > Is this a reasonable wish, or am I misunderstanding what all this > "boilerplate" code for GIMPLE code checking is meant to achieve? (It's > entirely possible that I'm misunderstanding something...) ;-) > > For example, might this suggest that our new GIMPLE code should in fact > be proper sub-codes of GIMPLE_OMP_TARGET? Hmm... Right now, the relevant part of the class hierarchy looks like this (from doc/gimple.texi): + gimple_statement_omp | | layout: GSS_OMP. Used for code GIMPLE_OMP_SECTION | | | + gimple_statement_omp_parallel_layout | | | layout: GSS_OMP_PARALLEL_LAYOUT | | | | | + gimple_statement_omp_taskreg | | | | | | | + gimple_statement_omp_parallel | | | | code: GIMPLE_OMP_PARALLEL | | | | | | | + gimple_statement_omp_task | | | code: GIMPLE_OMP_TASK | | | | | + gimple_statement_omp_target | | code: GIMPLE_OMP_TARGET Given the code fragment you posted above, where you want to work on each of GIMPLE_OACC_KERNELS, GIMPLE_OACC_PARALLEL, GIMPLE_OMP_TARGET to get at "set_child_fn" and the "clauses", it seems to me that you want the new classes to inherit from either gimple_statement_omp_parallel_layout (and have omp_target inherit from it) or from gimple_statement_omp_target; the accessors could then work on that specific new class. I suspect I don't yet have enough knowledge of OpenACC and OpenMP to propose a good name for the class, but for the former approach, the new class hierarchy might look like this: + gimple_statement_omp | | layout: GSS_OMP. Used for code GIMPLE_OMP_SECTION | | | + gimple_statement_omp_parallel_layout | | | layout: GSS_OMP_PARALLEL_LAYOUT | | | | | + gimple_statement_omp_taskreg | | | | | | | + gimple_statement_omp_parallel | | | | code: GIMPLE_OMP_PARALLEL | | | | | | | + gimple_statement_omp_task | | | code: GIMPLE_OMP_TASK | | | | | + "gimple_something" <<< NEW CLASS GOES HERE? | | | | | + gimple_statement_omp_target | | | code: GIMPLE_OMP_TARGET | | | | | + gimple_statement_oacc_kernels | | | code: GIMPLE_OACC_KERNELS | | | | | + gimple_statement_oacc_parallel | | code: GIMPLE_OACC_PARALLEL again, assuming that "gimple_something" is a meaningful concept, for the above to be sane. > And regardless of this, from someone who is still learning his share of > GCC internals, many, many thanks to you, Andrew and David (as well as > everyone else who's contributing, of course), for all the refactoring > work you're doing! This does make the GCC code more accessible. :-) Thanks; hope the above was helpful Dave > (Follows full quote for reference.) > > > Based on this, I've reworked the is_a_helper functions, eliminating > > almost all of the ones that accepted multiple codes. The only ones that > > remain accepting multiple codes are those for: > > > > * gimple_statement_with_ops, which uses gimple_has_ops (gs), and for > > * gimple_statement_with_memory_ops, which uses gimple_has_mem_ops > > (gs), plus > > * a new class gimple_statement_omp_taskreg, which expresses the > > "either GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK" condition, and becomes a > > parent struct for those. > > > > I introduced some new structs to express the pre-existing layouts for > > GSS codes, and to distinguish them from structs that imply a specific > > GIMPLE_ code. > > For example, > > gimple_statement_omp_atomic_store > > now requires that the code be GIMPLE_OMP_ATOMIC_STORE, but it was also > > the name of a layout, GSS_OMP_ATOMIC_STORE. So I renamed these purely > > layout classes, so that there is now a > > gimple_statement_omp_atomic_store_layout > > class for the corresponding GSS value, which I renamed to > > GSS_OMP_ATOMIC_STORE_LAYOUT > > to make clear that this is just a layout: that although > > GIMPLE_OMP_RETURN happens to share the data layout of > > GIMPLE_OMP_ATOMIC_STORE, they are not otherwise related - they now both > > inherit from the "_layout" class. > > > > I'm not a fan of these "_layout" names, but I'm not sure what better to > > call them. Perhaps: > > GSS_OMP_PARALLEL_LAYOUT -> GSS_OMP_WITH_CLAUSES_CHILD_FN_DATA_ARG > > GSS_OMP_SINGLE_LAYOUT -> GSS_OMP_WITH_CLAUSES > > GSS_OMP_ATOMIC_STORE_LAYOUT -> GSS_OMP_WITHOUT_SEQ_WITH_VAL > > with analogous names for the corresponding structs. > > > > I added GTY tags for every class in the hierarchy, not just those that > > introduce a new layout, since gengtype only recognizes inheritance when > > supplied a "tag" option. This leads to the GSS values appearing > > multiple times within the class hierarchy, which required a patch to > > gengtype, to prevent duplicate case labels in the generated switch > > statement. > > > > I believe that this structure correctly reinstates the exact behavior > > from before the inheritance patch for the checked build, and that either > > way, the behavior in the unchecked build is the same. > > > > Another approach to this would be to entirely eliminate these shared > > layout types, going purely with the conceptual is-a relationships > > between the types, say, by replacing the gengtype switch on GSS_ value > > with a switch on GIMPLE_ code. Given that this might affect the speed > > of GC (bigger switch statements), I went with the relatively more > > conservative change. > > > > Successfully bootstrapped®tested on x86_64-unknown-linux-gnu. > > > > OK for trunk? > > > > Sorry again for breaking this. > > > > Here's an ASCII art inheritance diagram, showing the relationships > > between structs, GSS_ values (layouts) and GIMPLE_ values (codes) - as I > > see them. If I'm still misunderstanding something, sorry, please let me > > know. Should this diagram live in gimple.h? > > +- gimple_statement_base > > | layout: GSS_BASE. 4 codes use this layout. > > | > > + gimple_statement_with_ops_base > > | | (no GSS layout) > > | | > > | + gimple_statement_with_ops > > | | layout: GSS_WITH_OPS. 5 codes use this layout. > > | | > > | + gimple_statement_with_memory_ops_base > > | | layout: GSS_WITH_MEM_OPS_BASE > > | | > > | + gimple_statement_with_memory_ops > > | | layout: GSS_WITH_MEM_OPS. > > | | Used by codes GIMPLE_ASSIGN and GIMPLE_RETURN. > > | | > > | + gimple_statement_call > > | | layout: GSS_CALL, code: GIMPLE_CALL > > | | > > | + gimple_statement_asm > > | | layout: GSS_ASM, code: GIMPLE_ASM > > | | > > | + gimple_statement_transaction > > | layout: GSS_TRANSACTION, code: GIMPLE_TRANSACTION > > | > > + gimple_statement_omp > > | | layout: GSS_OMP > > | | > > | + gimple_statement_omp_critical > > | | layout: GSS_OMP_CRITICAL, code: GIMPLE_OMP_CRITICAL > > | | > > | + gimple_statement_omp_for > > | | layout: GSS_OMP_FOR, code: GIMPLE_OMP_FOR > > | | > > | + gimple_statement_omp_parallel_layout > > | | | layout: GSS_OMP_PARALLEL_LAYOUT > > | | | > > | | + gimple_statement_omp_taskreg > > | | | | > > | | | + gimple_statement_omp_parallel > > | | | | code: GIMPLE_OMP_PARALLEL > > | | | | > > | | | + gimple_statement_omp_task > > | | | code: GIMPLE_OMP_TASK > > | | | > > | | + gimple_statement_omp_target > > | | code: GIMPLE_OMP_TARGET > > | | > > | + gimple_statement_omp_sections > > | | layout: GSS_OMP_SECTIONS, code: GIMPLE_OMP_SECTIONS > > | | > > | + gimple_statement_omp_single_layout > > | | layout: GSS_OMP_SINGLE_LAYOUT > > | | > > | + gimple_statement_omp_single > > | | code: GIMPLE_OMP_SINGLE > > | | > > | + gimple_statement_omp_teams > > | code: GIMPLE_OMP_TEAMS > > | > > + gimple_statement_bind > > | layout: GSS_BIND, code: GIMPLE_BIND > > | > > + gimple_statement_catch > > | layout: GSS_CATCH, code: GIMPLE_CATCH > > | > > + gimple_statement_eh_filter > > | layout: GSS_EH_FILTER, code: GIMPLE_EH_FILTER > > | > > + gimple_statement_eh_else > > | layout: GSS_EH_ELSE, code: GIMPLE_EH_ELSE > > | > > + gimple_statement_eh_mnt > > | layout: GSS_EH_MNT, code: GIMPLE_EH_MUST_NOT_THROW > > | > > + gimple_statement_phi > > | layout: GSS_PHI, code: GIMPLE_PHI > > | > > + gimple_statement_eh_ctrl > > | | layout: GSS_EH_CTRL > > | | > > | + gimple_statement_resx > > | | code: GIMPLE_RESX > > | | > > | + gimple_statement_eh_dispatch > > | code: GIMPLE_EH_DISPATCH > > | > > + gimple_statement_try > > | layout: GSS_TRY, code: GIMPLE_TRY > > | > > + gimple_statement_wce > > | layout: GSS_WCE, code: GIMPLE_WITH_CLEANUP_EXPR > > | > > + gimple_statement_omp_continue > > | layout: GSS_OMP_CONTINUE, code: GIMPLE_OMP_CONTINUE > > | > > + gimple_statement_omp_atomic_load > > | layout: GSS_OMP_ATOMIC_LOAD, code: GIMPLE_OMP_ATOMIC_LOAD > > | > > + gimple_statement_omp_atomic_store_layout > > | layout: GSS_OMP_ATOMIC_STORE_LAYOUT, > > | code: GIMPLE_OMP_ATOMIC_STORE > > | > > + gimple_statement_omp_atomic_store > > | code: GIMPLE_OMP_ATOMIC_STORE > > | > > + gimple_statement_omp_return > > code: GIMPLE_OMP_RETURN > > > > > > commit 9a0c36081b3baecfc16a8500464df3a94c8dd145 > > Author: David Malcolm <dmalcolm@redhat.com> > > Date: Thu Nov 21 21:46:58 2013 -0500 > > > > Fix as_a<> helpers for gimple > > > > * gengtype.c (struct seen_tag): New. > > (already_seen_tag): New. > > (mark_tag_as_seen): New. > > (walk_subclasses): Support having multiple subclasses using the > > same tag by tracking which tags have already been seen, and using > > this to avoid adding duplicate cases to the "switch" statement. > > The call to already_seen_tag introduces an O(N^2) when running > > gengtype on N, the number of tags, due to the repeated linear > > search, but currently max(N) is relatively small (the number of > > GSS codes, which is 26). > > (walk_type): Pass in a seen_tag for use by the walk_subclasses > > recursion. > > > > * gimple.def (GIMPLE_OMP_ATOMIC_STORE, GIMPLE_OMP_RETURN): Rename > > underlying GSS values for these codes (from GSS_OMP_ATOMIC_STORE to > > GSS_OMP_ATOMIC_STORE_LAYOUT) to make clear that although > > GIMPLE_OMP_RETURN happens to share the data layout of > > GIMPLE_OMP_ATOMIC_STORE, they are not otherwise related. > > (GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET): Likewise, rename > > underlying GSS value from GSS_OMP_PARALLEL to > > GSS_OMP_PARALLEL_LAYOUT to make clear that these gimple codes are > > not directly related; they merely share in-memory layout. > > (GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS): Likewise, rename GSS values > > for these two codes from GSS_OMP_SINGLE to GSS_OMP_SINGLE_LAYOUT. > > > > * gsstruct.def (GSS_OMP_PARALLEL, gimple_statement_omp_parallel): > > Rename to... > > (GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout): > > ...these. > > (GSS_OMP_SINGLE, gimple_statement_omp_single): Rename to... > > (GSS_OMP_SINGLE_LAYOUT, gimple_statement_omp_single_layout): > > ...these. > > (GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store): Rename > > to... > > (GSS_OMP_ATOMIC_STORE_LAYOUT, gimple_statement_omp_atomic_store): > > ...these. > > > > * gimple.h (gimple_statement_resx): New subclass of > > gimple_statement_eh_ctrl, with the invariant that > > stmt->code == GIMPLE_RESX. > > (gimple_statement_eh_dispatch): New subclass of > > gimple_statement_eh_ctrl, with the invariant that > > stmt->code == GIMPLE_EH_DISPATH. > > > > (gimple_statement_omp_parallel): The existing class expressed > > a layout (GSS_OMP_PARALLEL), but the codes with that layout > > are not all related, so it makes more sense for this class to > > express a *code* (GIMPLE_OMP_PARALLEL). GSS_OMP_PARALLEL has > > been renamed to GSS_OMP_PARALLEL_LAYOUT to express this, so > > rename the existing gimple_statement_omp_parallel class to... > > (gimple_statement_omp_parallel_layout): ...this, expressing > > a statement of structure layout GSS_OMP_PARALLEL_LAYOUT. > > (gimple_statement_omp_taskreg): New subclass of > > gimple_statement_omp_parallel_layout, expressing the invariant > > that the code is one of GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK, > > as used by the various gimple_omp_taskreg_ accessors. > > (gimple_statement_omp_parallel): Reintroduce this class, this time > > as a subclass of gimple_statement_omp_taskreg to express the > > invariant stmt->code == GIMPLE_OMP_PARALLEL. > > (gimple_statement_omp_target) New class, subclassing > > gimple_statement_omp_parallel_layout, to express the invariant > > stmt->code == GIMPLE_OMP_TARGET. > > (gimple_statement_omp_task): Update to inherit from > > gimple_statement_omp_taskreg rather than > > gimple_statement_omp_parallel. > > > > (gimple_statement_omp_single): Rename to... > > (gimple_statement_omp_single_layout): ...this, expressing the > > invariant that the layout is GSS_OMP_SINGLE_LAYOUT. > > (gimple_statement_omp_single): ...and reintroduce this name as > > a subclass of gimple_statement_omp_single_layout, expressing > > the invariant that code == GIMPLE_OMP_SINGLE. > > (gimple_statement_omp_teams): New class, subclassing > > gimple_statement_omp_single_layout, for the code GIMPLE_OMP_TEAMS. > > > > (gimple_statement_omp_atomic_store): Rename to... > > (gimple_statement_omp_atomic_store_layout): ...this, expressing > > the invariant that the layout is GSS_OMP_ATOMIC_STORE_LAYOUT. > > (gimple_statement_omp_atomic_store): ...and reintroduce this > > name as a subclass of gimple_statement_omp_atomic_store_layout > > with code == GIMPLE_OMP_ATOMIC_STORE. > > (gimple_statement_omp_return): New class, subclassing > > gimple_statement_omp_atomic_store_layout for the code > > GIMPLE_OMP_RETURN. > > > > (is_a_helper <gimple_statement_eh_ctrl>::test): Delete. > > (is_a_helper <gimple_statement_resx>::test): New. > > (is_a_helper <gimple_statement_eh_dispatch>::test): New. > > (is_a_helper <gimple_statement_omp_atomic_store>::test): Only > > check for GIMPLE_OMP_ATOMIC_STORE, not for GIMPLE_OMP_RETURN. > > (is_a_helper <gimple_statement_omp_return>::test): New. > > (is_a_helper <gimple_statement_omp_taskreg>::test): New. > > (is_a_helper <gimple_statement_omp_parallel>::test): Only check > > for GIMPLE_OMP_PARALLEL, not for GIMPLE_OMP_TASK or > > GIMPLE_OMP_TARGET. > > (is_a_helper <gimple_statement_omp_target>::test): New. > > (is_a_helper <gimple_statement_omp_single>::test): Only check > > for GIMPLE_OMP_SINGLE, not for GIMPLE_OMP_TEAMS. > > (is_a_helper <gimple_statement_omp_teams>::test): New. > > > > (is_a_helper <const gimple_statement_eh_ctrl>::test): Delete. > > (is_a_helper <const gimple_statement_resx>::test): New. > > (is_a_helper <const gimple_statement_eh_dispatch>::test): New. > > (is_a_helper <const gimple_statement_omp_atomic_store>::test): Only > > check for GIMPLE_OMP_ATOMIC_STORE, not for GIMPLE_OMP_RETURN. > > (is_a_helper <const gimple_statement_omp_return>::test): New. > > (is_a_helper <const gimple_statement_omp_taskreg>::test): New. > > (is_a_helper <const gimple_statement_omp_parallel>::test): Only > > check for GIMPLE_OMP_PARALLEL, not for GIMPLE_OMP_TASK or > > GIMPLE_OMP_TARGET. > > (is_a_helper <const gimple_statement_omp_target>::test): New. > > (is_a_helper <const gimple_statement_omp_single>::test): Only > > check for GIMPLE_OMP_SINGLE, not for GIMPLE_OMP_TEAMS. > > (is_a_helper <const gimple_statement_omp_teams>::test): New. > > > > (gimple_omp_return_set_lhs, gimple_omp_return_lhs, > > gimple_omp_return_lhs_ptr): Replace bogus downcasts to > > gimple_statement_omp_atomic_store with downcasts to > > gimple_statement_omp_return, thus requiring that the code be > > GIMPLE_OMP_RETURN. > > (gimple_resx_region, gimple_resx_set_region): Replace bogus > > downcasts to gimple_statement_eh_ctrl with downcasts to > > gimple_statement_resx, thus requiring that the code be > > GIMPLE_RESX. > > (gimple_eh_dispatch_region, gimple_eh_dispatch_set_region): > > Replace bogus downcasts to const gimple_statement_eh_ctrl with > > downcasts to gimple_statement_eh_dispatch, thus requiring that > > the code be GIMPLE_EH_DISPATCH. > > (gimple_omp_taskreg_clauses, gimple_omp_taskreg_clauses_ptr) > > gimple_omp_taskreg_set_clauses, gimple_omp_taskreg_child_fn, > > gimple_omp_taskreg_child_fn_ptr, gimple_omp_taskreg_set_child_fn, > > gimple_omp_taskreg_data_arg, gimple_omp_taskreg_data_arg_ptr, > > gimple_omp_taskreg_set_data_arg): Replace bogus downcasts to > > gimple_statement_omp_parallel with downcasts to > > gimple_statement_omp_taskreg, thus requiring that the code be > > either GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK. > > (gimple_omp_target_clauses, gimple_omp_target_clauses_ptr > > gimple_omp_target_set_clauses, gimple_omp_target_child_fn > > gimple_omp_target_child_fn_ptr, gimple_omp_target_set_child_fn > > gimple_omp_target_data_arg, gimple_omp_target_data_arg_ptr > > gimple_omp_target_set_data_arg): Replace bogus downcasts to > > gimple_statement_omp_parallel with downcasts to > > gimple_statement_omp_target, thus requiring that the code be > > GIMPLE_OMP_TARGET. > > (gimple_omp_teams_clauses, gimple_omp_teams_clauses_ptr > > gimple_omp_teams_set_clauses): Replace bogus downcasts to > > gimple_statement_omp_single with downcasts to > > gimple_statement_omp_teams, thus requiring that the code be > > GIMPLE_OMP_TEAMS. > > > > * gimple.c (gimple_build_resx): Fix bogus as_a<> to use > > gimple_statement_resx. > > (gimple_build_eh_dispatch): Fix bogus as_a<> to use > > gimple_statement_eh_dispatch. > > > > diff --git a/gcc/gengtype.c b/gcc/gengtype.c > > index 86e9ca2..6e675cc 100644 > > --- a/gcc/gengtype.c > > +++ b/gcc/gengtype.c > > @@ -2654,15 +2654,48 @@ get_string_option (options_p opt, const char *key) > > return NULL; > > } > > > > +/* Machinery for avoiding duplicate tags within switch statements. */ > > +struct seen_tag > > +{ > > + const char *tag; > > + struct seen_tag *next; > > +}; > > + > > +int > > +already_seen_tag (struct seen_tag *seen_tags, const char *tag) > > +{ > > + /* Linear search, so O(n^2), but n is currently small. */ > > + while (seen_tags) > > + { > > + if (!strcmp (seen_tags->tag, tag)) > > + return 1; > > + seen_tags = seen_tags->next; > > + } > > + /* Not yet seen this tag. */ > > + return 0; > > +} > > + > > +void > > +mark_tag_as_seen (struct seen_tag **seen_tags, const char *tag) > > +{ > > + /* Add to front of linked list. */ > > + struct seen_tag *new_node = XCNEW (struct seen_tag); > > + new_node->tag = tag; > > + new_node->next = *seen_tags; > > + *seen_tags = new_node; > > +} > > + > > static void > > -walk_subclasses (type_p base, struct walk_type_data *d) > > +walk_subclasses (type_p base, struct walk_type_data *d, > > + struct seen_tag **seen_tags) > > { > > for (type_p sub = base->u.s.first_subclass; sub != NULL; > > sub = sub->u.s.next_sibling_class) > > { > > const char *type_tag = get_string_option (sub->u.s.opt, "tag"); > > - if (type_tag) > > + if (type_tag && !already_seen_tag (*seen_tags, type_tag)) > > { > > + mark_tag_as_seen (seen_tags, type_tag); > > oprintf (d->of, "%*scase %s:\n", d->indent, "", type_tag); > > d->indent += 2; > > oprintf (d->of, "%*s{\n", d->indent, ""); > > @@ -2678,7 +2711,7 @@ walk_subclasses (type_p base, struct walk_type_data *d) > > oprintf (d->of, "%*sbreak;\n", d->indent, ""); > > d->indent -= 2; > > } > > - walk_subclasses (sub, d); > > + walk_subclasses (sub, d, seen_tags); > > } > > } > > > > @@ -3225,7 +3258,8 @@ walk_type (type_p t, struct walk_type_data *d) > > else if (desc) > > { > > /* Add cases to handle subclasses. */ > > - walk_subclasses (t, d); > > + struct seen_tag *tags = NULL; > > + walk_subclasses (t, d, &tags); > > > > /* Ensure that if someone forgets a "tag" option that we don't > > silent fail to traverse that subclass's fields. */ > > diff --git a/gcc/gimple.c b/gcc/gimple.c > > index d48ca6b..2e45f37 100644 > > --- a/gcc/gimple.c > > +++ b/gcc/gimple.c > > @@ -697,8 +697,8 @@ gimple_build_wce (gimple_seq cleanup) > > gimple > > gimple_build_resx (int region) > > { > > - gimple_statement_eh_ctrl *p = > > - as_a <gimple_statement_eh_ctrl> ( > > + gimple_statement_resx *p = > > + as_a <gimple_statement_resx> ( > > gimple_build_with_ops (GIMPLE_RESX, ERROR_MARK, 0)); > > p->region = region; > > return p; > > @@ -747,8 +747,8 @@ gimple_build_switch (tree index, tree default_label, vec<tree> args) > > gimple > > gimple_build_eh_dispatch (int region) > > { > > - gimple_statement_eh_ctrl *p = > > - as_a <gimple_statement_eh_ctrl> ( > > + gimple_statement_eh_dispatch *p = > > + as_a <gimple_statement_eh_dispatch> ( > > gimple_build_with_ops (GIMPLE_EH_DISPATCH, ERROR_MARK, 0)); > > p->region = region; > > return p; > > diff --git a/gcc/gimple.def b/gcc/gimple.def > > index 07370ae..ff1ef43 100644 > > --- a/gcc/gimple.def > > +++ b/gcc/gimple.def > > @@ -221,7 +221,7 @@ DEFGSCODE(GIMPLE_NOP, "gimple_nop", GSS_BASE) > > DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load", > > GSS_OMP_ATOMIC_LOAD) > > DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store", > > - GSS_OMP_ATOMIC_STORE) > > + GSS_OMP_ATOMIC_STORE_LAYOUT) > > > > /* GIMPLE_OMP_CONTINUE marks the location of the loop or sections > > iteration in partially lowered OpenMP code. */ > > @@ -300,7 +300,7 @@ DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP) > > DATA_ARG is a local variable in the parent function containing data > > to be shared with CHILD_FN. This is used to implement all the data > > sharing clauses. */ > > -DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL) > > +DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL_LAYOUT) > > > > /* GIMPLE_OMP_TASK <BODY, CLAUSES, CHILD_FN, DATA_ARG, COPY_FN, > > ARG_SIZE, ARG_ALIGN> represents > > @@ -329,7 +329,7 @@ DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL) > > DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", GSS_OMP_TASK) > > > > /* OMP_RETURN marks the end of an OpenMP directive. */ > > -DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_OMP_ATOMIC_STORE) > > +DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_OMP_ATOMIC_STORE_LAYOUT) > > > > /* OMP_SECTION <BODY> represents #pragma omp section. > > BODY is the sequence of statements in the section body. */ > > @@ -351,7 +351,7 @@ DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE) > > /* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single > > BODY is the sequence of statements inside the single section. > > CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ > > -DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE) > > +DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE_LAYOUT) > > > > /* GIMPLE_OMP_TARGET <BODY, CLAUSES, CHILD_FN> represents > > #pragma omp target {,data,update} > > @@ -364,12 +364,12 @@ DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE) > > DATA_ARG is a vec of 3 local variables in the parent function > > containing data to be mapped to CHILD_FN. This is used to > > implement the MAP clauses. */ > > -DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL) > > +DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL_LAYOUT) > > > > /* GIMPLE_OMP_TEAMS <BODY, CLAUSES> represents #pragma omp teams > > BODY is the sequence of statements inside the single section. > > CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ > > -DEFGSCODE(GIMPLE_OMP_TEAMS, "gimple_omp_teams", GSS_OMP_SINGLE) > > +DEFGSCODE(GIMPLE_OMP_TEAMS, "gimple_omp_teams", GSS_OMP_SINGLE_LAYOUT) > > > > /* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction. > > > > diff --git a/gcc/gimple.h b/gcc/gimple.h > > index 0eb23fc..0257576 100644 > > --- a/gcc/gimple.h > > +++ b/gcc/gimple.h > > @@ -420,6 +420,20 @@ struct GTY((tag("GSS_EH_CTRL"))) > > int region; > > }; > > > > +struct GTY((tag("GSS_EH_CTRL"))) > > + gimple_statement_resx : public gimple_statement_eh_ctrl > > +{ > > + /* No extra fields; adds invariant: > > + stmt->code == GIMPLE_RESX. */ > > +}; > > + > > +struct GTY((tag("GSS_EH_CTRL"))) > > + gimple_statement_eh_dispatch : public gimple_statement_eh_ctrl > > +{ > > + /* No extra fields; adds invariant: > > + stmt->code == GIMPLE_EH_DISPATH. */ > > +}; > > + > > > > /* GIMPLE_TRY */ > > > > @@ -547,10 +561,9 @@ struct GTY((tag("GSS_OMP_FOR"))) > > }; > > > > > > -/* GIMPLE_OMP_PARALLEL */ > > - > > -struct GTY((tag("GSS_OMP_PARALLEL"))) > > - gimple_statement_omp_parallel : public gimple_statement_omp > > +/* GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET */ > > +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > > + gimple_statement_omp_parallel_layout : public gimple_statement_omp > > { > > /* [ WORD 1-7 ] : base class */ > > > > @@ -567,11 +580,35 @@ struct GTY((tag("GSS_OMP_PARALLEL"))) > > tree data_arg; > > }; > > > > +/* GIMPLE_OMP_PARALLEL or GIMPLE_TASK */ > > +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > > + gimple_statement_omp_taskreg : public gimple_statement_omp_parallel_layout > > +{ > > + /* No extra fields; adds invariant: > > + stmt->code == GIMPLE_OMP_PARALLEL > > + || stmt->code == GIMPLE_OMP_TASK. */ > > +}; > > + > > + > > +/* GIMPLE_OMP_PARALLEL */ > > +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > > + gimple_statement_omp_parallel : public gimple_statement_omp_taskreg > > +{ > > + /* No extra fields; adds invariant: > > + stmt->code == GIMPLE_OMP_PARALLEL. */ > > +}; > > + > > +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > > + gimple_statement_omp_target : public gimple_statement_omp_parallel_layout > > +{ > > + /* No extra fields; adds invariant: > > + stmt->code == GIMPLE_OMP_TARGET. */ > > +}; > > > > /* GIMPLE_OMP_TASK */ > > > > struct GTY((tag("GSS_OMP_TASK"))) > > - gimple_statement_omp_task : public gimple_statement_omp_parallel > > + gimple_statement_omp_task : public gimple_statement_omp_taskreg > > { > > /* [ WORD 1-10 ] : base class */ > > > > @@ -623,10 +660,10 @@ struct GTY((tag("GSS_OMP_CONTINUE"))) > > tree control_use; > > }; > > > > -/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS */ > > +/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS */ > > > > -struct GTY((tag("GSS_OMP_SINGLE"))) > > - gimple_statement_omp_single : public gimple_statement_omp > > +struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) > > + gimple_statement_omp_single_layout : public gimple_statement_omp > > { > > /* [ WORD 1-7 ] : base class */ > > > > @@ -634,6 +671,20 @@ struct GTY((tag("GSS_OMP_SINGLE"))) > > tree clauses; > > }; > > > > +struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) > > + gimple_statement_omp_single : public gimple_statement_omp_single_layout > > +{ > > + /* No extra fields; adds invariant: > > + stmt->code == GIMPLE_OMP_SINGLE. */ > > +}; > > + > > +struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) > > + gimple_statement_omp_teams : public gimple_statement_omp_single_layout > > +{ > > + /* No extra fields; adds invariant: > > + stmt->code == GIMPLE_OMP_TEAMS. */ > > +}; > > + > > > > /* GIMPLE_OMP_ATOMIC_LOAD. > > Note: This is based on gimple_statement_base, not g_s_omp, because g_s_omp > > @@ -651,8 +702,8 @@ struct GTY((tag("GSS_OMP_ATOMIC_LOAD"))) > > /* GIMPLE_OMP_ATOMIC_STORE. > > See note on GIMPLE_OMP_ATOMIC_LOAD. */ > > > > -struct GTY((tag("GSS_OMP_ATOMIC_STORE"))) > > - gimple_statement_omp_atomic_store : public gimple_statement_base > > +struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) > > + gimple_statement_omp_atomic_store_layout : public gimple_statement_base > > { > > /* [ WORD 1-6 ] : base class */ > > > > @@ -660,6 +711,22 @@ struct GTY((tag("GSS_OMP_ATOMIC_STORE"))) > > tree val; > > }; > > > > +struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) > > + gimple_statement_omp_atomic_store : > > + public gimple_statement_omp_atomic_store_layout > > +{ > > + /* No extra fields; adds invariant: > > + stmt->code == GIMPLE_OMP_ATOMIC_STORE. */ > > +}; > > + > > +struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) > > + gimple_statement_omp_return : > > + public gimple_statement_omp_atomic_store_layout > > +{ > > + /* No extra fields; adds invariant: > > + stmt->code == GIMPLE_OMP_RETURN. */ > > +}; > > + > > /* GIMPLE_TRANSACTION. */ > > > > /* Bits to be stored in the GIMPLE_TRANSACTION subcode. */ > > @@ -742,9 +809,17 @@ is_a_helper <gimple_statement_catch>::test (gimple gs) > > template <> > > template <> > > inline bool > > -is_a_helper <gimple_statement_eh_ctrl>::test (gimple gs) > > +is_a_helper <gimple_statement_resx>::test (gimple gs) > > +{ > > + return gs->code == GIMPLE_RESX; > > +} > > + > > +template <> > > +template <> > > +inline bool > > +is_a_helper <gimple_statement_eh_dispatch>::test (gimple gs) > > { > > - return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH; > > + return gs->code == GIMPLE_EH_DISPATCH; > > } > > > > template <> > > @@ -784,7 +859,15 @@ template <> > > inline bool > > is_a_helper <gimple_statement_omp_atomic_store>::test (gimple gs) > > { > > - return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN; > > + return gs->code == GIMPLE_OMP_ATOMIC_STORE; > > +} > > + > > +template <> > > +template <> > > +inline bool > > +is_a_helper <gimple_statement_omp_return>::test (gimple gs) > > +{ > > + return gs->code == GIMPLE_OMP_RETURN; > > } > > > > template <> > > @@ -814,9 +897,25 @@ is_a_helper <gimple_statement_omp_for>::test (gimple gs) > > template <> > > template <> > > inline bool > > +is_a_helper <gimple_statement_omp_taskreg>::test (gimple gs) > > +{ > > + return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK; > > +} > > + > > +template <> > > +template <> > > +inline bool > > is_a_helper <gimple_statement_omp_parallel>::test (gimple gs) > > { > > - return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET; > > + return gs->code == GIMPLE_OMP_PARALLEL; > > +} > > + > > +template <> > > +template <> > > +inline bool > > +is_a_helper <gimple_statement_omp_target>::test (gimple gs) > > +{ > > + return gs->code == GIMPLE_OMP_TARGET; > > } > > > > template <> > > @@ -832,7 +931,15 @@ template <> > > inline bool > > is_a_helper <gimple_statement_omp_single>::test (gimple gs) > > { > > - return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS; > > + return gs->code == GIMPLE_OMP_SINGLE; > > +} > > + > > +template <> > > +template <> > > +inline bool > > +is_a_helper <gimple_statement_omp_teams>::test (gimple gs) > > +{ > > + return gs->code == GIMPLE_OMP_TEAMS; > > } > > > > template <> > > @@ -910,9 +1017,17 @@ is_a_helper <const gimple_statement_catch>::test (const_gimple gs) > > template <> > > template <> > > inline bool > > -is_a_helper <const gimple_statement_eh_ctrl>::test (const_gimple gs) > > +is_a_helper <const gimple_statement_resx>::test (const_gimple gs) > > { > > - return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH; > > + return gs->code == GIMPLE_RESX; > > +} > > + > > +template <> > > +template <> > > +inline bool > > +is_a_helper <const gimple_statement_eh_dispatch>::test (const_gimple gs) > > +{ > > + return gs->code == GIMPLE_EH_DISPATCH; > > } > > > > template <> > > @@ -936,7 +1051,15 @@ template <> > > inline bool > > is_a_helper <const gimple_statement_omp_atomic_store>::test (const_gimple gs) > > { > > - return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN; > > + return gs->code == GIMPLE_OMP_ATOMIC_STORE; > > +} > > + > > +template <> > > +template <> > > +inline bool > > +is_a_helper <const gimple_statement_omp_return>::test (const_gimple gs) > > +{ > > + return gs->code == GIMPLE_OMP_RETURN; > > } > > > > template <> > > @@ -966,9 +1089,25 @@ is_a_helper <const gimple_statement_omp_for>::test (const_gimple gs) > > template <> > > template <> > > inline bool > > +is_a_helper <const gimple_statement_omp_taskreg>::test (const_gimple gs) > > +{ > > + return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK; > > +} > > + > > +template <> > > +template <> > > +inline bool > > is_a_helper <const gimple_statement_omp_parallel>::test (const_gimple gs) > > { > > - return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET; > > + return gs->code == GIMPLE_OMP_PARALLEL; > > +} > > + > > +template <> > > +template <> > > +inline bool > > +is_a_helper <const gimple_statement_omp_target>::test (const_gimple gs) > > +{ > > + return gs->code == GIMPLE_OMP_TARGET; > > } > > > > template <> > > @@ -984,7 +1123,15 @@ template <> > > inline bool > > is_a_helper <const gimple_statement_omp_single>::test (const_gimple gs) > > { > > - return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS; > > + return gs->code == GIMPLE_OMP_SINGLE; > > +} > > + > > +template <> > > +template <> > > +inline bool > > +is_a_helper <const gimple_statement_omp_teams>::test (const_gimple gs) > > +{ > > + return gs->code == GIMPLE_OMP_TEAMS; > > } > > > > template <> > > @@ -1766,9 +1913,9 @@ gimple_omp_return_nowait_p (const_gimple g) > > static inline void > > gimple_omp_return_set_lhs (gimple g, tree lhs) > > { > > - gimple_statement_omp_atomic_store *omp_atomic_store_stmt = > > - as_a <gimple_statement_omp_atomic_store> (g); > > - omp_atomic_store_stmt->val = lhs; > > + gimple_statement_omp_return *omp_return_stmt = > > + as_a <gimple_statement_omp_return> (g); > > + omp_return_stmt->val = lhs; > > } > > > > > > @@ -1777,9 +1924,9 @@ gimple_omp_return_set_lhs (gimple g, tree lhs) > > static inline tree > > gimple_omp_return_lhs (const_gimple g) > > { > > - const gimple_statement_omp_atomic_store *omp_atomic_store_stmt = > > - as_a <const gimple_statement_omp_atomic_store> (g); > > - return omp_atomic_store_stmt->val; > > + const gimple_statement_omp_return *omp_return_stmt = > > + as_a <const gimple_statement_omp_return> (g); > > + return omp_return_stmt->val; > > } > > > > > > @@ -1788,9 +1935,9 @@ gimple_omp_return_lhs (const_gimple g) > > static inline tree * > > gimple_omp_return_lhs_ptr (gimple g) > > { > > - gimple_statement_omp_atomic_store *omp_atomic_store_stmt = > > - as_a <gimple_statement_omp_atomic_store> (g); > > - return &omp_atomic_store_stmt->val; > > + gimple_statement_omp_return *omp_return_stmt = > > + as_a <gimple_statement_omp_return> (g); > > + return &omp_return_stmt->val; > > } > > > > > > @@ -3793,9 +3940,9 @@ gimple_phi_arg_has_location (gimple gs, size_t i) > > static inline int > > gimple_resx_region (const_gimple gs) > > { > > - const gimple_statement_eh_ctrl *eh_ctrl_stmt = > > - as_a <const gimple_statement_eh_ctrl> (gs); > > - return eh_ctrl_stmt->region; > > + const gimple_statement_resx *resx_stmt = > > + as_a <const gimple_statement_resx> (gs); > > + return resx_stmt->region; > > } > > > > /* Set REGION to be the region number for GIMPLE_RESX GS. */ > > @@ -3803,9 +3950,8 @@ gimple_resx_region (const_gimple gs) > > static inline void > > gimple_resx_set_region (gimple gs, int region) > > { > > - gimple_statement_eh_ctrl *eh_ctrl_stmt = > > - as_a <gimple_statement_eh_ctrl> (gs); > > - eh_ctrl_stmt->region = region; > > + gimple_statement_resx *resx_stmt = as_a <gimple_statement_resx> (gs); > > + resx_stmt->region = region; > > } > > > > /* Return the region number for GIMPLE_EH_DISPATCH GS. */ > > @@ -3813,9 +3959,9 @@ gimple_resx_set_region (gimple gs, int region) > > static inline int > > gimple_eh_dispatch_region (const_gimple gs) > > { > > - const gimple_statement_eh_ctrl *eh_ctrl_stmt = > > - as_a <const gimple_statement_eh_ctrl> (gs); > > - return eh_ctrl_stmt->region; > > + const gimple_statement_eh_dispatch *eh_dispatch_stmt = > > + as_a <const gimple_statement_eh_dispatch> (gs); > > + return eh_dispatch_stmt->region; > > } > > > > /* Set REGION to be the region number for GIMPLE_EH_DISPATCH GS. */ > > @@ -3823,9 +3969,9 @@ gimple_eh_dispatch_region (const_gimple gs) > > static inline void > > gimple_eh_dispatch_set_region (gimple gs, int region) > > { > > - gimple_statement_eh_ctrl *eh_ctrl_stmt = > > - as_a <gimple_statement_eh_ctrl> (gs); > > - eh_ctrl_stmt->region = region; > > + gimple_statement_eh_dispatch *eh_dispatch_stmt = > > + as_a <gimple_statement_eh_dispatch> (gs); > > + eh_dispatch_stmt->region = region; > > } > > > > /* Return the number of labels associated with the switch statement GS. */ > > @@ -4663,9 +4809,9 @@ gimple_omp_task_set_data_arg (gimple gs, tree data_arg) > > static inline tree > > gimple_omp_taskreg_clauses (const_gimple gs) > > { > > - const gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <const gimple_statement_omp_parallel> (gs); > > - return omp_parallel_stmt->clauses; > > + const gimple_statement_omp_taskreg *omp_taskreg_stmt = > > + as_a <const gimple_statement_omp_taskreg> (gs); > > + return omp_taskreg_stmt->clauses; > > } > > > > > > @@ -4674,9 +4820,9 @@ gimple_omp_taskreg_clauses (const_gimple gs) > > static inline tree * > > gimple_omp_taskreg_clauses_ptr (gimple gs) > > { > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <gimple_statement_omp_parallel> (gs); > > - return &omp_parallel_stmt->clauses; > > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > > + as_a <gimple_statement_omp_taskreg> (gs); > > + return &omp_taskreg_stmt->clauses; > > } > > > > > > @@ -4686,9 +4832,9 @@ gimple_omp_taskreg_clauses_ptr (gimple gs) > > static inline void > > gimple_omp_taskreg_set_clauses (gimple gs, tree clauses) > > { > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <gimple_statement_omp_parallel> (gs); > > - omp_parallel_stmt->clauses = clauses; > > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > > + as_a <gimple_statement_omp_taskreg> (gs); > > + omp_taskreg_stmt->clauses = clauses; > > } > > > > > > @@ -4697,9 +4843,9 @@ gimple_omp_taskreg_set_clauses (gimple gs, tree clauses) > > static inline tree > > gimple_omp_taskreg_child_fn (const_gimple gs) > > { > > - const gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <const gimple_statement_omp_parallel> (gs); > > - return omp_parallel_stmt->child_fn; > > + const gimple_statement_omp_taskreg *omp_taskreg_stmt = > > + as_a <const gimple_statement_omp_taskreg> (gs); > > + return omp_taskreg_stmt->child_fn; > > } > > > > /* Return a pointer to the child function used to hold the body of > > @@ -4708,9 +4854,9 @@ gimple_omp_taskreg_child_fn (const_gimple gs) > > static inline tree * > > gimple_omp_taskreg_child_fn_ptr (gimple gs) > > { > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <gimple_statement_omp_parallel> (gs); > > - return &omp_parallel_stmt->child_fn; > > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > > + as_a <gimple_statement_omp_taskreg> (gs); > > + return &omp_taskreg_stmt->child_fn; > > } > > > > > > @@ -4719,9 +4865,9 @@ gimple_omp_taskreg_child_fn_ptr (gimple gs) > > static inline void > > gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn) > > { > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <gimple_statement_omp_parallel> (gs); > > - omp_parallel_stmt->child_fn = child_fn; > > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > > + as_a <gimple_statement_omp_taskreg> (gs); > > + omp_taskreg_stmt->child_fn = child_fn; > > } > > > > > > @@ -4731,9 +4877,9 @@ gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn) > > static inline tree > > gimple_omp_taskreg_data_arg (const_gimple gs) > > { > > - const gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <const gimple_statement_omp_parallel> (gs); > > - return omp_parallel_stmt->data_arg; > > + const gimple_statement_omp_taskreg *omp_taskreg_stmt = > > + as_a <const gimple_statement_omp_taskreg> (gs); > > + return omp_taskreg_stmt->data_arg; > > } > > > > > > @@ -4742,9 +4888,9 @@ gimple_omp_taskreg_data_arg (const_gimple gs) > > static inline tree * > > gimple_omp_taskreg_data_arg_ptr (gimple gs) > > { > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <gimple_statement_omp_parallel> (gs); > > - return &omp_parallel_stmt->data_arg; > > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > > + as_a <gimple_statement_omp_taskreg> (gs); > > + return &omp_taskreg_stmt->data_arg; > > } > > > > > > @@ -4753,9 +4899,9 @@ gimple_omp_taskreg_data_arg_ptr (gimple gs) > > static inline void > > gimple_omp_taskreg_set_data_arg (gimple gs, tree data_arg) > > { > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <gimple_statement_omp_parallel> (gs); > > - omp_parallel_stmt->data_arg = data_arg; > > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > > + as_a <gimple_statement_omp_taskreg> (gs); > > + omp_taskreg_stmt->data_arg = data_arg; > > } > > > > > > @@ -4896,9 +5042,9 @@ gimple_omp_single_set_clauses (gimple gs, tree clauses) > > static inline tree > > gimple_omp_target_clauses (const_gimple gs) > > { > > - const gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <const gimple_statement_omp_parallel> (gs); > > - return omp_parallel_stmt->clauses; > > + const gimple_statement_omp_target *omp_target_stmt = > > + as_a <const gimple_statement_omp_target> (gs); > > + return omp_target_stmt->clauses; > > } > > > > > > @@ -4907,9 +5053,9 @@ gimple_omp_target_clauses (const_gimple gs) > > static inline tree * > > gimple_omp_target_clauses_ptr (gimple gs) > > { > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <gimple_statement_omp_parallel> (gs); > > - return &omp_parallel_stmt->clauses; > > + gimple_statement_omp_target *omp_target_stmt = > > + as_a <gimple_statement_omp_target> (gs); > > + return &omp_target_stmt->clauses; > > } > > > > > > @@ -4918,9 +5064,9 @@ gimple_omp_target_clauses_ptr (gimple gs) > > static inline void > > gimple_omp_target_set_clauses (gimple gs, tree clauses) > > { > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <gimple_statement_omp_parallel> (gs); > > - omp_parallel_stmt->clauses = clauses; > > + gimple_statement_omp_target *omp_target_stmt = > > + as_a <gimple_statement_omp_target> (gs); > > + omp_target_stmt->clauses = clauses; > > } > > > > > > @@ -4950,9 +5096,9 @@ gimple_omp_target_set_kind (gimple g, int kind) > > static inline tree > > gimple_omp_target_child_fn (const_gimple gs) > > { > > - const gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <const gimple_statement_omp_parallel> (gs); > > - return omp_parallel_stmt->child_fn; > > + const gimple_statement_omp_target *omp_target_stmt = > > + as_a <const gimple_statement_omp_target> (gs); > > + return omp_target_stmt->child_fn; > > } > > > > /* Return a pointer to the child function used to hold the body of > > @@ -4961,9 +5107,9 @@ gimple_omp_target_child_fn (const_gimple gs) > > static inline tree * > > gimple_omp_target_child_fn_ptr (gimple gs) > > { > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <gimple_statement_omp_parallel> (gs); > > - return &omp_parallel_stmt->child_fn; > > + gimple_statement_omp_target *omp_target_stmt = > > + as_a <gimple_statement_omp_target> (gs); > > + return &omp_target_stmt->child_fn; > > } > > > > > > @@ -4972,9 +5118,9 @@ gimple_omp_target_child_fn_ptr (gimple gs) > > static inline void > > gimple_omp_target_set_child_fn (gimple gs, tree child_fn) > > { > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <gimple_statement_omp_parallel> (gs); > > - omp_parallel_stmt->child_fn = child_fn; > > + gimple_statement_omp_target *omp_target_stmt = > > + as_a <gimple_statement_omp_target> (gs); > > + omp_target_stmt->child_fn = child_fn; > > } > > > > > > @@ -4984,9 +5130,9 @@ gimple_omp_target_set_child_fn (gimple gs, tree child_fn) > > static inline tree > > gimple_omp_target_data_arg (const_gimple gs) > > { > > - const gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <const gimple_statement_omp_parallel> (gs); > > - return omp_parallel_stmt->data_arg; > > + const gimple_statement_omp_target *omp_target_stmt = > > + as_a <const gimple_statement_omp_target> (gs); > > + return omp_target_stmt->data_arg; > > } > > > > > > @@ -4995,9 +5141,9 @@ gimple_omp_target_data_arg (const_gimple gs) > > static inline tree * > > gimple_omp_target_data_arg_ptr (gimple gs) > > { > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <gimple_statement_omp_parallel> (gs); > > - return &omp_parallel_stmt->data_arg; > > + gimple_statement_omp_target *omp_target_stmt = > > + as_a <gimple_statement_omp_target> (gs); > > + return &omp_target_stmt->data_arg; > > } > > > > > > @@ -5006,9 +5152,9 @@ gimple_omp_target_data_arg_ptr (gimple gs) > > static inline void > > gimple_omp_target_set_data_arg (gimple gs, tree data_arg) > > { > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > - as_a <gimple_statement_omp_parallel> (gs); > > - omp_parallel_stmt->data_arg = data_arg; > > + gimple_statement_omp_target *omp_target_stmt = > > + as_a <gimple_statement_omp_target> (gs); > > + omp_target_stmt->data_arg = data_arg; > > } > > > > > > @@ -5017,9 +5163,9 @@ gimple_omp_target_set_data_arg (gimple gs, tree data_arg) > > static inline tree > > gimple_omp_teams_clauses (const_gimple gs) > > { > > - const gimple_statement_omp_single *omp_single_stmt = > > - as_a <const gimple_statement_omp_single> (gs); > > - return omp_single_stmt->clauses; > > + const gimple_statement_omp_teams *omp_teams_stmt = > > + as_a <const gimple_statement_omp_teams> (gs); > > + return omp_teams_stmt->clauses; > > } > > > > > > @@ -5028,9 +5174,9 @@ gimple_omp_teams_clauses (const_gimple gs) > > static inline tree * > > gimple_omp_teams_clauses_ptr (gimple gs) > > { > > - gimple_statement_omp_single *omp_single_stmt = > > - as_a <gimple_statement_omp_single> (gs); > > - return &omp_single_stmt->clauses; > > + gimple_statement_omp_teams *omp_teams_stmt = > > + as_a <gimple_statement_omp_teams> (gs); > > + return &omp_teams_stmt->clauses; > > } > > > > > > @@ -5039,9 +5185,9 @@ gimple_omp_teams_clauses_ptr (gimple gs) > > static inline void > > gimple_omp_teams_set_clauses (gimple gs, tree clauses) > > { > > - gimple_statement_omp_single *omp_single_stmt = > > - as_a <gimple_statement_omp_single> (gs); > > - omp_single_stmt->clauses = clauses; > > + gimple_statement_omp_teams *omp_teams_stmt = > > + as_a <gimple_statement_omp_teams> (gs); > > + omp_teams_stmt->clauses = clauses; > > } > > > > > > diff --git a/gcc/gsstruct.def b/gcc/gsstruct.def > > index 91738f4..82f1f52 100644 > > --- a/gcc/gsstruct.def > > +++ b/gcc/gsstruct.def > > @@ -43,11 +43,11 @@ DEFGSSTRUCT(GSS_WCE, gimple_statement_wce, false) > > DEFGSSTRUCT(GSS_OMP, gimple_statement_omp, false) > > DEFGSSTRUCT(GSS_OMP_CRITICAL, gimple_statement_omp_critical, false) > > DEFGSSTRUCT(GSS_OMP_FOR, gimple_statement_omp_for, false) > > -DEFGSSTRUCT(GSS_OMP_PARALLEL, gimple_statement_omp_parallel, false) > > +DEFGSSTRUCT(GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout, false) > > DEFGSSTRUCT(GSS_OMP_TASK, gimple_statement_omp_task, false) > > DEFGSSTRUCT(GSS_OMP_SECTIONS, gimple_statement_omp_sections, false) > > -DEFGSSTRUCT(GSS_OMP_SINGLE, gimple_statement_omp_single, false) > > +DEFGSSTRUCT(GSS_OMP_SINGLE_LAYOUT, gimple_statement_omp_single_layout, false) > > DEFGSSTRUCT(GSS_OMP_CONTINUE, gimple_statement_omp_continue, false) > > DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, gimple_statement_omp_atomic_load, false) > > -DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store, false) > > +DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE_LAYOUT, gimple_statement_omp_atomic_store, false) > > DEFGSSTRUCT(GSS_TRANSACTION, gimple_statement_transaction, false) > > > GrüÃe, > Thomas ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Fix checking of gimple types 2014-07-24 1:50 ` David Malcolm @ 2014-07-29 8:11 ` Thomas Schwinge 0 siblings, 0 replies; 116+ messages in thread From: Thomas Schwinge @ 2014-07-29 8:11 UTC (permalink / raw) To: David Malcolm Cc: Andrew MacLeod, Jakub Jelinek, Jeff Law, gcc-patches, Cesar Philippidis [-- Attachment #1: Type: text/plain, Size: 63305 bytes --] Hi! On Wed, 23 Jul 2014 20:54:24 -0400, David Malcolm <dmalcolm@redhat.com> wrote: > On Wed, 2014-07-23 at 15:00 +0200, Thomas Schwinge wrote: > > In context of adding support for OpenACC, next to the existing > > GIMPLE_OMP_TARGET (quoting from gcc/gimple.def and gcc/gimple.h): > > > > DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL_LAYOUT) > > > > /* GIMPLE_OMP_TARGET */ > > struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > > gimple_statement_omp_target : public gimple_statement_omp_parallel_layout > > { > > /* No extra fields; adds invariant: > > stmt->code == GIMPLE_OMP_TARGET. */ > > }; > > > > ..., we're adding additional GIMPLE codes: > > > > DEFGSCODE(GIMPLE_OACC_KERNELS, "gimple_oacc_kernels", GSS_OMP_PARALLEL_LAYOUT) > > > > /* GIMPLE_OACC_KERNELS */ > > struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > > gimple_statement_oacc_kernels : public gimple_statement_omp_parallel_layout > > { > > /* No extra fields; adds invariant: > > stmt->code == GIMPLE_OACC_KERNELS. */ > > }; > > > > DEFGSCODE(GIMPLE_OACC_PARALLEL, "gimple_oacc_parallel", GSS_OMP_PARALLEL_LAYOUT) > > > > /* GIMPLE_OACC_PARALLEL */ > > struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > > gimple_statement_oacc_parallel : public gimple_statement_omp_parallel_layout > > { > > /* No extra fields; adds invariant: > > stmt->code == GIMPLE_OACC_PARALLEL. */ > > }; > > > > As you can see, all these codes share the same layout, > > GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout. > > > > Given this, I'd like to better understand the following: > > > > On Mon, 25 Nov 2013 10:35:18 -0500, David Malcolm <dmalcolm@redhat.com> wrote: > > > On Thu, 2013-11-21 at 18:03 -0500, Andrew MacLeod wrote: > > > > On 11/21/2013 05:42 PM, Jakub Jelinek wrote: > > > > > On Thu, Nov 21, 2013 at 03:24:55PM -0700, Jeff Law wrote: > > > > >> On 11/21/13 15:19, Jakub Jelinek wrote: > > > > >>> On Mon, Nov 18, 2013 at 03:25:52PM -0500, David Malcolm wrote: > > > > >>>>> So is there some reason the GIMPLE_CHECK was left in here rather than > > > > >>>>> doing the downcasting? This happens in other places. > > > > >>> Note that the changes removed tons of checks that IMHO were desirable. > > > > >>> The as_a that replaced those checks e.g. allows 3 different gimple codes, > > > > >>> while previously only one was allowed, this is both more expensive for > > > > >>> --enable-checking=yes, and allows one to use inline wrappers e.g. > > > > >>> gimple_omp_parallel_something on GIMPLE_OMP_TASK etc. > > > > >> Can you give a couple examples, please? > > > > > I mean e.g. > > > > > gimple_omp_parallel_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > > > > gimple_omp_taskreg_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > > > > gimple_omp_target_{,set_}{clauses,child_fn,data_arg}{,_ptr} > > > > > gimple_omp_teams_{,set_}clauses{,_ptr} > > > > > gimple_omp_return_{,set_}lhs{,_ptr} > > > > > gimple_omp_atomic_store_{,set_}val{,_ptr} > > > > > gimple_resx_{,set_}region > > > > > gimple_eh_dispatch_{,set_}region > > > > We (have to) add the whole fleet of > > gimple_oacc_{kernels,parallel}_{clauses,...} accessors as well as new > > is_a_helper for {,const} gimple_statement_oacc_{kernels,parallel}. > > > > > > Why does is_a_helper <gimple_statement_omp_parallel>::test allow > > > > anything other than a GIMPLE_OMP_PARALLEL..? That seems wrong to me. > > > > should just be the one check. > > > > > > > > gimple_omp_taskreg and other routines "sharing" that helper should have > > > > their own helper and only check the one code.. thats is whole point to > > > > remain at least codegen neutral in these cases and provide correct > > > > checking. The fact that they may happen to share the same underlying > > > > structure is irrelevant. > > > > > > > > I also think this is wrong. > > > > > > Mea culpa. Unfortunately I made a conceptual error during the > > > conversion (the worst kind of error). I misunderstood the relationships > > > between the various OMP statements: there (mostly) aren't any, but the > > > sharing of structures for layout made me think there were. > > > > > > Attached is a patch, successfully bootstrapped®tested on > > > x86_64-unknown-linux-gnu, which I believe reinstates the checked-build > > > behaviors from before r205034 (and that the unchecked-build behaviors > > > were not affected by that commit and likewise are not by this patch). > > > > > > As I understand it, there are almost no "is-a" relationships between the > > > various omp statement types, some of them just happen to share layouts. > > > The exception is that the various gimple_omp_taskreg_* accessors accept > > > either codes GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK and so an > > > "omp_taskreg" is a concept, of which OMP_PARALLEL and OMP_TASK have an > > > is-a relationship. > > > > Admittedly, there is no is-a relationship between these, but yet, > > GIMPLE_OMP_TARGET as well as the new GIMPLE_OACC_KERNELS and > > GIMPLE_OACC_PARALLEL can share a lot of code, but, for example, where > > previously gimple_omp_target_set_child_fn or gimple_omp_target_clauses > > have been used, I now find myself writing code such as: > > > > void (*gimple_omp_set_child_fn) (gimple, tree); > > tree (*gimple_omp_clauses) (const_gimple); > > switch (gimple_code (stmt)) > > { > > case GIMPLE_OACC_KERNELS: > > gimple_omp_set_child_fn = gimple_oacc_kernels_set_child_fn; > > gimple_omp_clauses = gimple_oacc_kernels_clauses; > > break; > > case GIMPLE_OACC_PARALLEL: > > gimple_omp_set_child_fn = gimple_oacc_parallel_set_child_fn; > > gimple_omp_clauses = gimple_oacc_parallel_clauses; > > break; > > case GIMPLE_OMP_TARGET: > > gimple_omp_set_child_fn = gimple_omp_target_set_child_fn; > > gimple_omp_clauses = gimple_omp_target_clauses; > > break; > > default: > > gcc_unreachable (); > > } > > > > ..., only that I can then in the following use a unified interface for > > setting the child function or getting access to the clauses. > > Hmmmm. What does the above code do, and is that pattern happening > repeatedly? Given the above it sounds like we may need these types to > inherit from a common parent class ("gimple_something"), and for the > parent to provide: > gimple_something_set_child_fn > gimple_something_clauses Yes, that seems reasonable to me. And, isn't that base class basically the ... > > What you can see here is that I first look at the GIMPLE code, and use > > that to determine the appropritate accessor functions. I have to do that > > because these specific accessor functions then again would like to check > > the respective GIMPLE code -- which I have just checked in the code > > quoted above. Instead, I'd rather like layout-specific accessor > > functions, such as gimple_omp_parallel_layout_set_child_fn or > > gimple_omp_parallel_layout_clauses. ... gimple_omp_parallel_layout class that I (sort of) proposed here? (And no doubt it could do with a more descriptive name, which is, hmm...) > BTW I have an 89-patch patch kit that strengthens the params to gimple > accessors, requiring appropriate subclasses, and eliminating the code > checks; see e.g.: > https://gcc.gnu.org/ml/gcc-patches/2014-04/msg01159.html > This patch kit was approved, but I was asked to hold off committing it > to trunk until 4.9.1 was out, and also to investigate some renamings, so > it's been in a "holding pattern" for a while. > > So we'll need to incorporate whatever we do for OpenACC into those > patches (or vice versa). Every few weeks I merge from trunk into gomp-4_0-branch, so I can then take care of this; I understand the changes will be rather "mechanic". > FWIW, I was never particularly fond of the name > "gimple_omp_parallel_layout"; IIRC it was necessary as a way of > expressing that we're using a particular data layout > (GSS_OMP_PARALLEL_LAYOUT), and to be different from the specific > concrete subclass used for code GIMPLE_OMP_PARALLEL. Right. I however also have difficulties coming up with a better name. > > Is this a reasonable wish, or am I misunderstanding what all this > > "boilerplate" code for GIMPLE code checking is meant to achieve? (It's > > entirely possible that I'm misunderstanding something...) ;-) > > > > For example, might this suggest that our new GIMPLE code should in fact > > be proper sub-codes of GIMPLE_OMP_TARGET? Hmm... > > Right now, the relevant part of the class hierarchy looks like this > (from doc/gimple.texi): > + gimple_statement_omp > | | layout: GSS_OMP. Used for code GIMPLE_OMP_SECTION > | | > | + gimple_statement_omp_parallel_layout > | | | layout: GSS_OMP_PARALLEL_LAYOUT > | | | > | | + gimple_statement_omp_taskreg > | | | | > | | | + gimple_statement_omp_parallel > | | | | code: GIMPLE_OMP_PARALLEL > | | | | > | | | + gimple_statement_omp_task > | | | code: GIMPLE_OMP_TASK > | | | > | | + gimple_statement_omp_target > | | code: GIMPLE_OMP_TARGET > > > Given the code fragment you posted above, where you want to work on each > of GIMPLE_OACC_KERNELS, GIMPLE_OACC_PARALLEL, GIMPLE_OMP_TARGET to get > at "set_child_fn" and the "clauses", it seems to me that you want the > new classes to inherit from either gimple_statement_omp_parallel_layout > (and have omp_target inherit from it) or from > gimple_statement_omp_target; the accessors could then work on that > specific new class. I think conceptually, gimple_statement_omp_parallel_layout/GSS_OMP_PARALLEL_LAYOUT would be the base class. > I suspect I don't yet have enough knowledge of OpenACC and OpenMP to > propose a good name for the class, but for the former approach, the new > class hierarchy might look like this: > + gimple_statement_omp > | | layout: GSS_OMP. Used for code GIMPLE_OMP_SECTION > | | > | + gimple_statement_omp_parallel_layout > | | | layout: GSS_OMP_PARALLEL_LAYOUT > | | | > | | + gimple_statement_omp_taskreg > | | | | > | | | + gimple_statement_omp_parallel > | | | | code: GIMPLE_OMP_PARALLEL > | | | | > | | | + gimple_statement_omp_task > | | | code: GIMPLE_OMP_TASK > | | | > | | + "gimple_something" <<< NEW CLASS GOES HERE? > | | | > | | + gimple_statement_omp_target > | | | code: GIMPLE_OMP_TARGET > | | | > | | + gimple_statement_oacc_kernels > | | | code: GIMPLE_OACC_KERNELS > | | | > | | + gimple_statement_oacc_parallel > | | code: GIMPLE_OACC_PARALLEL > > again, assuming that "gimple_something" is a meaningful concept, for the > above to be sane. Given that all of GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TASK, GIMPLE_OMP_TARGET, GIMPLE_OACC_KERNELS, GIMPLE_OACC_PARALLEL have a (the same) concept of clauses and a child_fn (see gcc/gimple.def), I assume gimple_statement_omp_parallel_layout/GSS_OMP_PARALLEL_LAYOUT is where the base class should be located. And, the accessors for the clauses could be moved up in the class hierarchy, as that is a concept that universally applies to all GIMPLE_OMP_* (as well as GIMPLE_OACC_*). > > And regardless of this, from someone who is still learning his share of > > GCC internals, many, many thanks to you, Andrew and David (as well as > > everyone else who's contributing, of course), for all the refactoring > > work you're doing! This does make the GCC code more accessible. :-) > > Thanks; hope the above was helpful Yes, thanks! > > (Follows full quote for reference.) > > > > > Based on this, I've reworked the is_a_helper functions, eliminating > > > almost all of the ones that accepted multiple codes. The only ones that > > > remain accepting multiple codes are those for: > > > > > > * gimple_statement_with_ops, which uses gimple_has_ops (gs), and for > > > * gimple_statement_with_memory_ops, which uses gimple_has_mem_ops > > > (gs), plus > > > * a new class gimple_statement_omp_taskreg, which expresses the > > > "either GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK" condition, and becomes a > > > parent struct for those. > > > > > > I introduced some new structs to express the pre-existing layouts for > > > GSS codes, and to distinguish them from structs that imply a specific > > > GIMPLE_ code. > > > For example, > > > gimple_statement_omp_atomic_store > > > now requires that the code be GIMPLE_OMP_ATOMIC_STORE, but it was also > > > the name of a layout, GSS_OMP_ATOMIC_STORE. So I renamed these purely > > > layout classes, so that there is now a > > > gimple_statement_omp_atomic_store_layout > > > class for the corresponding GSS value, which I renamed to > > > GSS_OMP_ATOMIC_STORE_LAYOUT > > > to make clear that this is just a layout: that although > > > GIMPLE_OMP_RETURN happens to share the data layout of > > > GIMPLE_OMP_ATOMIC_STORE, they are not otherwise related - they now both > > > inherit from the "_layout" class. > > > > > > I'm not a fan of these "_layout" names, but I'm not sure what better to > > > call them. Perhaps: > > > GSS_OMP_PARALLEL_LAYOUT -> GSS_OMP_WITH_CLAUSES_CHILD_FN_DATA_ARG > > > GSS_OMP_SINGLE_LAYOUT -> GSS_OMP_WITH_CLAUSES > > > GSS_OMP_ATOMIC_STORE_LAYOUT -> GSS_OMP_WITHOUT_SEQ_WITH_VAL > > > with analogous names for the corresponding structs. > > > > > > I added GTY tags for every class in the hierarchy, not just those that > > > introduce a new layout, since gengtype only recognizes inheritance when > > > supplied a "tag" option. This leads to the GSS values appearing > > > multiple times within the class hierarchy, which required a patch to > > > gengtype, to prevent duplicate case labels in the generated switch > > > statement. > > > > > > I believe that this structure correctly reinstates the exact behavior > > > from before the inheritance patch for the checked build, and that either > > > way, the behavior in the unchecked build is the same. > > > > > > Another approach to this would be to entirely eliminate these shared > > > layout types, going purely with the conceptual is-a relationships > > > between the types, say, by replacing the gengtype switch on GSS_ value > > > with a switch on GIMPLE_ code. Given that this might affect the speed > > > of GC (bigger switch statements), I went with the relatively more > > > conservative change. > > > > > > Successfully bootstrapped®tested on x86_64-unknown-linux-gnu. > > > > > > OK for trunk? > > > > > > Sorry again for breaking this. > > > > > > Here's an ASCII art inheritance diagram, showing the relationships > > > between structs, GSS_ values (layouts) and GIMPLE_ values (codes) - as I > > > see them. If I'm still misunderstanding something, sorry, please let me > > > know. Should this diagram live in gimple.h? > > > +- gimple_statement_base > > > | layout: GSS_BASE. 4 codes use this layout. > > > | > > > + gimple_statement_with_ops_base > > > | | (no GSS layout) > > > | | > > > | + gimple_statement_with_ops > > > | | layout: GSS_WITH_OPS. 5 codes use this layout. > > > | | > > > | + gimple_statement_with_memory_ops_base > > > | | layout: GSS_WITH_MEM_OPS_BASE > > > | | > > > | + gimple_statement_with_memory_ops > > > | | layout: GSS_WITH_MEM_OPS. > > > | | Used by codes GIMPLE_ASSIGN and GIMPLE_RETURN. > > > | | > > > | + gimple_statement_call > > > | | layout: GSS_CALL, code: GIMPLE_CALL > > > | | > > > | + gimple_statement_asm > > > | | layout: GSS_ASM, code: GIMPLE_ASM > > > | | > > > | + gimple_statement_transaction > > > | layout: GSS_TRANSACTION, code: GIMPLE_TRANSACTION > > > | > > > + gimple_statement_omp > > > | | layout: GSS_OMP > > > | | > > > | + gimple_statement_omp_critical > > > | | layout: GSS_OMP_CRITICAL, code: GIMPLE_OMP_CRITICAL > > > | | > > > | + gimple_statement_omp_for > > > | | layout: GSS_OMP_FOR, code: GIMPLE_OMP_FOR > > > | | > > > | + gimple_statement_omp_parallel_layout > > > | | | layout: GSS_OMP_PARALLEL_LAYOUT > > > | | | > > > | | + gimple_statement_omp_taskreg > > > | | | | > > > | | | + gimple_statement_omp_parallel > > > | | | | code: GIMPLE_OMP_PARALLEL > > > | | | | > > > | | | + gimple_statement_omp_task > > > | | | code: GIMPLE_OMP_TASK > > > | | | > > > | | + gimple_statement_omp_target > > > | | code: GIMPLE_OMP_TARGET > > > | | > > > | + gimple_statement_omp_sections > > > | | layout: GSS_OMP_SECTIONS, code: GIMPLE_OMP_SECTIONS > > > | | > > > | + gimple_statement_omp_single_layout > > > | | layout: GSS_OMP_SINGLE_LAYOUT > > > | | > > > | + gimple_statement_omp_single > > > | | code: GIMPLE_OMP_SINGLE > > > | | > > > | + gimple_statement_omp_teams > > > | code: GIMPLE_OMP_TEAMS > > > | > > > + gimple_statement_bind > > > | layout: GSS_BIND, code: GIMPLE_BIND > > > | > > > + gimple_statement_catch > > > | layout: GSS_CATCH, code: GIMPLE_CATCH > > > | > > > + gimple_statement_eh_filter > > > | layout: GSS_EH_FILTER, code: GIMPLE_EH_FILTER > > > | > > > + gimple_statement_eh_else > > > | layout: GSS_EH_ELSE, code: GIMPLE_EH_ELSE > > > | > > > + gimple_statement_eh_mnt > > > | layout: GSS_EH_MNT, code: GIMPLE_EH_MUST_NOT_THROW > > > | > > > + gimple_statement_phi > > > | layout: GSS_PHI, code: GIMPLE_PHI > > > | > > > + gimple_statement_eh_ctrl > > > | | layout: GSS_EH_CTRL > > > | | > > > | + gimple_statement_resx > > > | | code: GIMPLE_RESX > > > | | > > > | + gimple_statement_eh_dispatch > > > | code: GIMPLE_EH_DISPATCH > > > | > > > + gimple_statement_try > > > | layout: GSS_TRY, code: GIMPLE_TRY > > > | > > > + gimple_statement_wce > > > | layout: GSS_WCE, code: GIMPLE_WITH_CLEANUP_EXPR > > > | > > > + gimple_statement_omp_continue > > > | layout: GSS_OMP_CONTINUE, code: GIMPLE_OMP_CONTINUE > > > | > > > + gimple_statement_omp_atomic_load > > > | layout: GSS_OMP_ATOMIC_LOAD, code: GIMPLE_OMP_ATOMIC_LOAD > > > | > > > + gimple_statement_omp_atomic_store_layout > > > | layout: GSS_OMP_ATOMIC_STORE_LAYOUT, > > > | code: GIMPLE_OMP_ATOMIC_STORE > > > | > > > + gimple_statement_omp_atomic_store > > > | code: GIMPLE_OMP_ATOMIC_STORE > > > | > > > + gimple_statement_omp_return > > > code: GIMPLE_OMP_RETURN > > > > > > > > > commit 9a0c36081b3baecfc16a8500464df3a94c8dd145 > > > Author: David Malcolm <dmalcolm@redhat.com> > > > Date: Thu Nov 21 21:46:58 2013 -0500 > > > > > > Fix as_a<> helpers for gimple > > > > > > * gengtype.c (struct seen_tag): New. > > > (already_seen_tag): New. > > > (mark_tag_as_seen): New. > > > (walk_subclasses): Support having multiple subclasses using the > > > same tag by tracking which tags have already been seen, and using > > > this to avoid adding duplicate cases to the "switch" statement. > > > The call to already_seen_tag introduces an O(N^2) when running > > > gengtype on N, the number of tags, due to the repeated linear > > > search, but currently max(N) is relatively small (the number of > > > GSS codes, which is 26). > > > (walk_type): Pass in a seen_tag for use by the walk_subclasses > > > recursion. > > > > > > * gimple.def (GIMPLE_OMP_ATOMIC_STORE, GIMPLE_OMP_RETURN): Rename > > > underlying GSS values for these codes (from GSS_OMP_ATOMIC_STORE to > > > GSS_OMP_ATOMIC_STORE_LAYOUT) to make clear that although > > > GIMPLE_OMP_RETURN happens to share the data layout of > > > GIMPLE_OMP_ATOMIC_STORE, they are not otherwise related. > > > (GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET): Likewise, rename > > > underlying GSS value from GSS_OMP_PARALLEL to > > > GSS_OMP_PARALLEL_LAYOUT to make clear that these gimple codes are > > > not directly related; they merely share in-memory layout. > > > (GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS): Likewise, rename GSS values > > > for these two codes from GSS_OMP_SINGLE to GSS_OMP_SINGLE_LAYOUT. > > > > > > * gsstruct.def (GSS_OMP_PARALLEL, gimple_statement_omp_parallel): > > > Rename to... > > > (GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout): > > > ...these. > > > (GSS_OMP_SINGLE, gimple_statement_omp_single): Rename to... > > > (GSS_OMP_SINGLE_LAYOUT, gimple_statement_omp_single_layout): > > > ...these. > > > (GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store): Rename > > > to... > > > (GSS_OMP_ATOMIC_STORE_LAYOUT, gimple_statement_omp_atomic_store): > > > ...these. > > > > > > * gimple.h (gimple_statement_resx): New subclass of > > > gimple_statement_eh_ctrl, with the invariant that > > > stmt->code == GIMPLE_RESX. > > > (gimple_statement_eh_dispatch): New subclass of > > > gimple_statement_eh_ctrl, with the invariant that > > > stmt->code == GIMPLE_EH_DISPATH. > > > > > > (gimple_statement_omp_parallel): The existing class expressed > > > a layout (GSS_OMP_PARALLEL), but the codes with that layout > > > are not all related, so it makes more sense for this class to > > > express a *code* (GIMPLE_OMP_PARALLEL). GSS_OMP_PARALLEL has > > > been renamed to GSS_OMP_PARALLEL_LAYOUT to express this, so > > > rename the existing gimple_statement_omp_parallel class to... > > > (gimple_statement_omp_parallel_layout): ...this, expressing > > > a statement of structure layout GSS_OMP_PARALLEL_LAYOUT. > > > (gimple_statement_omp_taskreg): New subclass of > > > gimple_statement_omp_parallel_layout, expressing the invariant > > > that the code is one of GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK, > > > as used by the various gimple_omp_taskreg_ accessors. > > > (gimple_statement_omp_parallel): Reintroduce this class, this time > > > as a subclass of gimple_statement_omp_taskreg to express the > > > invariant stmt->code == GIMPLE_OMP_PARALLEL. > > > (gimple_statement_omp_target) New class, subclassing > > > gimple_statement_omp_parallel_layout, to express the invariant > > > stmt->code == GIMPLE_OMP_TARGET. > > > (gimple_statement_omp_task): Update to inherit from > > > gimple_statement_omp_taskreg rather than > > > gimple_statement_omp_parallel. > > > > > > (gimple_statement_omp_single): Rename to... > > > (gimple_statement_omp_single_layout): ...this, expressing the > > > invariant that the layout is GSS_OMP_SINGLE_LAYOUT. > > > (gimple_statement_omp_single): ...and reintroduce this name as > > > a subclass of gimple_statement_omp_single_layout, expressing > > > the invariant that code == GIMPLE_OMP_SINGLE. > > > (gimple_statement_omp_teams): New class, subclassing > > > gimple_statement_omp_single_layout, for the code GIMPLE_OMP_TEAMS. > > > > > > (gimple_statement_omp_atomic_store): Rename to... > > > (gimple_statement_omp_atomic_store_layout): ...this, expressing > > > the invariant that the layout is GSS_OMP_ATOMIC_STORE_LAYOUT. > > > (gimple_statement_omp_atomic_store): ...and reintroduce this > > > name as a subclass of gimple_statement_omp_atomic_store_layout > > > with code == GIMPLE_OMP_ATOMIC_STORE. > > > (gimple_statement_omp_return): New class, subclassing > > > gimple_statement_omp_atomic_store_layout for the code > > > GIMPLE_OMP_RETURN. > > > > > > (is_a_helper <gimple_statement_eh_ctrl>::test): Delete. > > > (is_a_helper <gimple_statement_resx>::test): New. > > > (is_a_helper <gimple_statement_eh_dispatch>::test): New. > > > (is_a_helper <gimple_statement_omp_atomic_store>::test): Only > > > check for GIMPLE_OMP_ATOMIC_STORE, not for GIMPLE_OMP_RETURN. > > > (is_a_helper <gimple_statement_omp_return>::test): New. > > > (is_a_helper <gimple_statement_omp_taskreg>::test): New. > > > (is_a_helper <gimple_statement_omp_parallel>::test): Only check > > > for GIMPLE_OMP_PARALLEL, not for GIMPLE_OMP_TASK or > > > GIMPLE_OMP_TARGET. > > > (is_a_helper <gimple_statement_omp_target>::test): New. > > > (is_a_helper <gimple_statement_omp_single>::test): Only check > > > for GIMPLE_OMP_SINGLE, not for GIMPLE_OMP_TEAMS. > > > (is_a_helper <gimple_statement_omp_teams>::test): New. > > > > > > (is_a_helper <const gimple_statement_eh_ctrl>::test): Delete. > > > (is_a_helper <const gimple_statement_resx>::test): New. > > > (is_a_helper <const gimple_statement_eh_dispatch>::test): New. > > > (is_a_helper <const gimple_statement_omp_atomic_store>::test): Only > > > check for GIMPLE_OMP_ATOMIC_STORE, not for GIMPLE_OMP_RETURN. > > > (is_a_helper <const gimple_statement_omp_return>::test): New. > > > (is_a_helper <const gimple_statement_omp_taskreg>::test): New. > > > (is_a_helper <const gimple_statement_omp_parallel>::test): Only > > > check for GIMPLE_OMP_PARALLEL, not for GIMPLE_OMP_TASK or > > > GIMPLE_OMP_TARGET. > > > (is_a_helper <const gimple_statement_omp_target>::test): New. > > > (is_a_helper <const gimple_statement_omp_single>::test): Only > > > check for GIMPLE_OMP_SINGLE, not for GIMPLE_OMP_TEAMS. > > > (is_a_helper <const gimple_statement_omp_teams>::test): New. > > > > > > (gimple_omp_return_set_lhs, gimple_omp_return_lhs, > > > gimple_omp_return_lhs_ptr): Replace bogus downcasts to > > > gimple_statement_omp_atomic_store with downcasts to > > > gimple_statement_omp_return, thus requiring that the code be > > > GIMPLE_OMP_RETURN. > > > (gimple_resx_region, gimple_resx_set_region): Replace bogus > > > downcasts to gimple_statement_eh_ctrl with downcasts to > > > gimple_statement_resx, thus requiring that the code be > > > GIMPLE_RESX. > > > (gimple_eh_dispatch_region, gimple_eh_dispatch_set_region): > > > Replace bogus downcasts to const gimple_statement_eh_ctrl with > > > downcasts to gimple_statement_eh_dispatch, thus requiring that > > > the code be GIMPLE_EH_DISPATCH. > > > (gimple_omp_taskreg_clauses, gimple_omp_taskreg_clauses_ptr) > > > gimple_omp_taskreg_set_clauses, gimple_omp_taskreg_child_fn, > > > gimple_omp_taskreg_child_fn_ptr, gimple_omp_taskreg_set_child_fn, > > > gimple_omp_taskreg_data_arg, gimple_omp_taskreg_data_arg_ptr, > > > gimple_omp_taskreg_set_data_arg): Replace bogus downcasts to > > > gimple_statement_omp_parallel with downcasts to > > > gimple_statement_omp_taskreg, thus requiring that the code be > > > either GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK. > > > (gimple_omp_target_clauses, gimple_omp_target_clauses_ptr > > > gimple_omp_target_set_clauses, gimple_omp_target_child_fn > > > gimple_omp_target_child_fn_ptr, gimple_omp_target_set_child_fn > > > gimple_omp_target_data_arg, gimple_omp_target_data_arg_ptr > > > gimple_omp_target_set_data_arg): Replace bogus downcasts to > > > gimple_statement_omp_parallel with downcasts to > > > gimple_statement_omp_target, thus requiring that the code be > > > GIMPLE_OMP_TARGET. > > > (gimple_omp_teams_clauses, gimple_omp_teams_clauses_ptr > > > gimple_omp_teams_set_clauses): Replace bogus downcasts to > > > gimple_statement_omp_single with downcasts to > > > gimple_statement_omp_teams, thus requiring that the code be > > > GIMPLE_OMP_TEAMS. > > > > > > * gimple.c (gimple_build_resx): Fix bogus as_a<> to use > > > gimple_statement_resx. > > > (gimple_build_eh_dispatch): Fix bogus as_a<> to use > > > gimple_statement_eh_dispatch. > > > > > > diff --git a/gcc/gengtype.c b/gcc/gengtype.c > > > index 86e9ca2..6e675cc 100644 > > > --- a/gcc/gengtype.c > > > +++ b/gcc/gengtype.c > > > @@ -2654,15 +2654,48 @@ get_string_option (options_p opt, const char *key) > > > return NULL; > > > } > > > > > > +/* Machinery for avoiding duplicate tags within switch statements. */ > > > +struct seen_tag > > > +{ > > > + const char *tag; > > > + struct seen_tag *next; > > > +}; > > > + > > > +int > > > +already_seen_tag (struct seen_tag *seen_tags, const char *tag) > > > +{ > > > + /* Linear search, so O(n^2), but n is currently small. */ > > > + while (seen_tags) > > > + { > > > + if (!strcmp (seen_tags->tag, tag)) > > > + return 1; > > > + seen_tags = seen_tags->next; > > > + } > > > + /* Not yet seen this tag. */ > > > + return 0; > > > +} > > > + > > > +void > > > +mark_tag_as_seen (struct seen_tag **seen_tags, const char *tag) > > > +{ > > > + /* Add to front of linked list. */ > > > + struct seen_tag *new_node = XCNEW (struct seen_tag); > > > + new_node->tag = tag; > > > + new_node->next = *seen_tags; > > > + *seen_tags = new_node; > > > +} > > > + > > > static void > > > -walk_subclasses (type_p base, struct walk_type_data *d) > > > +walk_subclasses (type_p base, struct walk_type_data *d, > > > + struct seen_tag **seen_tags) > > > { > > > for (type_p sub = base->u.s.first_subclass; sub != NULL; > > > sub = sub->u.s.next_sibling_class) > > > { > > > const char *type_tag = get_string_option (sub->u.s.opt, "tag"); > > > - if (type_tag) > > > + if (type_tag && !already_seen_tag (*seen_tags, type_tag)) > > > { > > > + mark_tag_as_seen (seen_tags, type_tag); > > > oprintf (d->of, "%*scase %s:\n", d->indent, "", type_tag); > > > d->indent += 2; > > > oprintf (d->of, "%*s{\n", d->indent, ""); > > > @@ -2678,7 +2711,7 @@ walk_subclasses (type_p base, struct walk_type_data *d) > > > oprintf (d->of, "%*sbreak;\n", d->indent, ""); > > > d->indent -= 2; > > > } > > > - walk_subclasses (sub, d); > > > + walk_subclasses (sub, d, seen_tags); > > > } > > > } > > > > > > @@ -3225,7 +3258,8 @@ walk_type (type_p t, struct walk_type_data *d) > > > else if (desc) > > > { > > > /* Add cases to handle subclasses. */ > > > - walk_subclasses (t, d); > > > + struct seen_tag *tags = NULL; > > > + walk_subclasses (t, d, &tags); > > > > > > /* Ensure that if someone forgets a "tag" option that we don't > > > silent fail to traverse that subclass's fields. */ > > > diff --git a/gcc/gimple.c b/gcc/gimple.c > > > index d48ca6b..2e45f37 100644 > > > --- a/gcc/gimple.c > > > +++ b/gcc/gimple.c > > > @@ -697,8 +697,8 @@ gimple_build_wce (gimple_seq cleanup) > > > gimple > > > gimple_build_resx (int region) > > > { > > > - gimple_statement_eh_ctrl *p = > > > - as_a <gimple_statement_eh_ctrl> ( > > > + gimple_statement_resx *p = > > > + as_a <gimple_statement_resx> ( > > > gimple_build_with_ops (GIMPLE_RESX, ERROR_MARK, 0)); > > > p->region = region; > > > return p; > > > @@ -747,8 +747,8 @@ gimple_build_switch (tree index, tree default_label, vec<tree> args) > > > gimple > > > gimple_build_eh_dispatch (int region) > > > { > > > - gimple_statement_eh_ctrl *p = > > > - as_a <gimple_statement_eh_ctrl> ( > > > + gimple_statement_eh_dispatch *p = > > > + as_a <gimple_statement_eh_dispatch> ( > > > gimple_build_with_ops (GIMPLE_EH_DISPATCH, ERROR_MARK, 0)); > > > p->region = region; > > > return p; > > > diff --git a/gcc/gimple.def b/gcc/gimple.def > > > index 07370ae..ff1ef43 100644 > > > --- a/gcc/gimple.def > > > +++ b/gcc/gimple.def > > > @@ -221,7 +221,7 @@ DEFGSCODE(GIMPLE_NOP, "gimple_nop", GSS_BASE) > > > DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load", > > > GSS_OMP_ATOMIC_LOAD) > > > DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store", > > > - GSS_OMP_ATOMIC_STORE) > > > + GSS_OMP_ATOMIC_STORE_LAYOUT) > > > > > > /* GIMPLE_OMP_CONTINUE marks the location of the loop or sections > > > iteration in partially lowered OpenMP code. */ > > > @@ -300,7 +300,7 @@ DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP) > > > DATA_ARG is a local variable in the parent function containing data > > > to be shared with CHILD_FN. This is used to implement all the data > > > sharing clauses. */ > > > -DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL) > > > +DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL_LAYOUT) > > > > > > /* GIMPLE_OMP_TASK <BODY, CLAUSES, CHILD_FN, DATA_ARG, COPY_FN, > > > ARG_SIZE, ARG_ALIGN> represents > > > @@ -329,7 +329,7 @@ DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL) > > > DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", GSS_OMP_TASK) > > > > > > /* OMP_RETURN marks the end of an OpenMP directive. */ > > > -DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_OMP_ATOMIC_STORE) > > > +DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_OMP_ATOMIC_STORE_LAYOUT) > > > > > > /* OMP_SECTION <BODY> represents #pragma omp section. > > > BODY is the sequence of statements in the section body. */ > > > @@ -351,7 +351,7 @@ DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE) > > > /* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single > > > BODY is the sequence of statements inside the single section. > > > CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ > > > -DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE) > > > +DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE_LAYOUT) > > > > > > /* GIMPLE_OMP_TARGET <BODY, CLAUSES, CHILD_FN> represents > > > #pragma omp target {,data,update} > > > @@ -364,12 +364,12 @@ DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE) > > > DATA_ARG is a vec of 3 local variables in the parent function > > > containing data to be mapped to CHILD_FN. This is used to > > > implement the MAP clauses. */ > > > -DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL) > > > +DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL_LAYOUT) > > > > > > /* GIMPLE_OMP_TEAMS <BODY, CLAUSES> represents #pragma omp teams > > > BODY is the sequence of statements inside the single section. > > > CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ > > > -DEFGSCODE(GIMPLE_OMP_TEAMS, "gimple_omp_teams", GSS_OMP_SINGLE) > > > +DEFGSCODE(GIMPLE_OMP_TEAMS, "gimple_omp_teams", GSS_OMP_SINGLE_LAYOUT) > > > > > > /* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction. > > > > > > diff --git a/gcc/gimple.h b/gcc/gimple.h > > > index 0eb23fc..0257576 100644 > > > --- a/gcc/gimple.h > > > +++ b/gcc/gimple.h > > > @@ -420,6 +420,20 @@ struct GTY((tag("GSS_EH_CTRL"))) > > > int region; > > > }; > > > > > > +struct GTY((tag("GSS_EH_CTRL"))) > > > + gimple_statement_resx : public gimple_statement_eh_ctrl > > > +{ > > > + /* No extra fields; adds invariant: > > > + stmt->code == GIMPLE_RESX. */ > > > +}; > > > + > > > +struct GTY((tag("GSS_EH_CTRL"))) > > > + gimple_statement_eh_dispatch : public gimple_statement_eh_ctrl > > > +{ > > > + /* No extra fields; adds invariant: > > > + stmt->code == GIMPLE_EH_DISPATH. */ > > > +}; > > > + > > > > > > /* GIMPLE_TRY */ > > > > > > @@ -547,10 +561,9 @@ struct GTY((tag("GSS_OMP_FOR"))) > > > }; > > > > > > > > > -/* GIMPLE_OMP_PARALLEL */ > > > - > > > -struct GTY((tag("GSS_OMP_PARALLEL"))) > > > - gimple_statement_omp_parallel : public gimple_statement_omp > > > +/* GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET */ > > > +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > > > + gimple_statement_omp_parallel_layout : public gimple_statement_omp > > > { > > > /* [ WORD 1-7 ] : base class */ > > > > > > @@ -567,11 +580,35 @@ struct GTY((tag("GSS_OMP_PARALLEL"))) > > > tree data_arg; > > > }; > > > > > > +/* GIMPLE_OMP_PARALLEL or GIMPLE_TASK */ > > > +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > > > + gimple_statement_omp_taskreg : public gimple_statement_omp_parallel_layout > > > +{ > > > + /* No extra fields; adds invariant: > > > + stmt->code == GIMPLE_OMP_PARALLEL > > > + || stmt->code == GIMPLE_OMP_TASK. */ > > > +}; > > > + > > > + > > > +/* GIMPLE_OMP_PARALLEL */ > > > +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > > > + gimple_statement_omp_parallel : public gimple_statement_omp_taskreg > > > +{ > > > + /* No extra fields; adds invariant: > > > + stmt->code == GIMPLE_OMP_PARALLEL. */ > > > +}; > > > + > > > +struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) > > > + gimple_statement_omp_target : public gimple_statement_omp_parallel_layout > > > +{ > > > + /* No extra fields; adds invariant: > > > + stmt->code == GIMPLE_OMP_TARGET. */ > > > +}; > > > > > > /* GIMPLE_OMP_TASK */ > > > > > > struct GTY((tag("GSS_OMP_TASK"))) > > > - gimple_statement_omp_task : public gimple_statement_omp_parallel > > > + gimple_statement_omp_task : public gimple_statement_omp_taskreg > > > { > > > /* [ WORD 1-10 ] : base class */ > > > > > > @@ -623,10 +660,10 @@ struct GTY((tag("GSS_OMP_CONTINUE"))) > > > tree control_use; > > > }; > > > > > > -/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS */ > > > +/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS */ > > > > > > -struct GTY((tag("GSS_OMP_SINGLE"))) > > > - gimple_statement_omp_single : public gimple_statement_omp > > > +struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) > > > + gimple_statement_omp_single_layout : public gimple_statement_omp > > > { > > > /* [ WORD 1-7 ] : base class */ > > > > > > @@ -634,6 +671,20 @@ struct GTY((tag("GSS_OMP_SINGLE"))) > > > tree clauses; > > > }; > > > > > > +struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) > > > + gimple_statement_omp_single : public gimple_statement_omp_single_layout > > > +{ > > > + /* No extra fields; adds invariant: > > > + stmt->code == GIMPLE_OMP_SINGLE. */ > > > +}; > > > + > > > +struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) > > > + gimple_statement_omp_teams : public gimple_statement_omp_single_layout > > > +{ > > > + /* No extra fields; adds invariant: > > > + stmt->code == GIMPLE_OMP_TEAMS. */ > > > +}; > > > + > > > > > > /* GIMPLE_OMP_ATOMIC_LOAD. > > > Note: This is based on gimple_statement_base, not g_s_omp, because g_s_omp > > > @@ -651,8 +702,8 @@ struct GTY((tag("GSS_OMP_ATOMIC_LOAD"))) > > > /* GIMPLE_OMP_ATOMIC_STORE. > > > See note on GIMPLE_OMP_ATOMIC_LOAD. */ > > > > > > -struct GTY((tag("GSS_OMP_ATOMIC_STORE"))) > > > - gimple_statement_omp_atomic_store : public gimple_statement_base > > > +struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) > > > + gimple_statement_omp_atomic_store_layout : public gimple_statement_base > > > { > > > /* [ WORD 1-6 ] : base class */ > > > > > > @@ -660,6 +711,22 @@ struct GTY((tag("GSS_OMP_ATOMIC_STORE"))) > > > tree val; > > > }; > > > > > > +struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) > > > + gimple_statement_omp_atomic_store : > > > + public gimple_statement_omp_atomic_store_layout > > > +{ > > > + /* No extra fields; adds invariant: > > > + stmt->code == GIMPLE_OMP_ATOMIC_STORE. */ > > > +}; > > > + > > > +struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT"))) > > > + gimple_statement_omp_return : > > > + public gimple_statement_omp_atomic_store_layout > > > +{ > > > + /* No extra fields; adds invariant: > > > + stmt->code == GIMPLE_OMP_RETURN. */ > > > +}; > > > + > > > /* GIMPLE_TRANSACTION. */ > > > > > > /* Bits to be stored in the GIMPLE_TRANSACTION subcode. */ > > > @@ -742,9 +809,17 @@ is_a_helper <gimple_statement_catch>::test (gimple gs) > > > template <> > > > template <> > > > inline bool > > > -is_a_helper <gimple_statement_eh_ctrl>::test (gimple gs) > > > +is_a_helper <gimple_statement_resx>::test (gimple gs) > > > +{ > > > + return gs->code == GIMPLE_RESX; > > > +} > > > + > > > +template <> > > > +template <> > > > +inline bool > > > +is_a_helper <gimple_statement_eh_dispatch>::test (gimple gs) > > > { > > > - return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH; > > > + return gs->code == GIMPLE_EH_DISPATCH; > > > } > > > > > > template <> > > > @@ -784,7 +859,15 @@ template <> > > > inline bool > > > is_a_helper <gimple_statement_omp_atomic_store>::test (gimple gs) > > > { > > > - return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN; > > > + return gs->code == GIMPLE_OMP_ATOMIC_STORE; > > > +} > > > + > > > +template <> > > > +template <> > > > +inline bool > > > +is_a_helper <gimple_statement_omp_return>::test (gimple gs) > > > +{ > > > + return gs->code == GIMPLE_OMP_RETURN; > > > } > > > > > > template <> > > > @@ -814,9 +897,25 @@ is_a_helper <gimple_statement_omp_for>::test (gimple gs) > > > template <> > > > template <> > > > inline bool > > > +is_a_helper <gimple_statement_omp_taskreg>::test (gimple gs) > > > +{ > > > + return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK; > > > +} > > > + > > > +template <> > > > +template <> > > > +inline bool > > > is_a_helper <gimple_statement_omp_parallel>::test (gimple gs) > > > { > > > - return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET; > > > + return gs->code == GIMPLE_OMP_PARALLEL; > > > +} > > > + > > > +template <> > > > +template <> > > > +inline bool > > > +is_a_helper <gimple_statement_omp_target>::test (gimple gs) > > > +{ > > > + return gs->code == GIMPLE_OMP_TARGET; > > > } > > > > > > template <> > > > @@ -832,7 +931,15 @@ template <> > > > inline bool > > > is_a_helper <gimple_statement_omp_single>::test (gimple gs) > > > { > > > - return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS; > > > + return gs->code == GIMPLE_OMP_SINGLE; > > > +} > > > + > > > +template <> > > > +template <> > > > +inline bool > > > +is_a_helper <gimple_statement_omp_teams>::test (gimple gs) > > > +{ > > > + return gs->code == GIMPLE_OMP_TEAMS; > > > } > > > > > > template <> > > > @@ -910,9 +1017,17 @@ is_a_helper <const gimple_statement_catch>::test (const_gimple gs) > > > template <> > > > template <> > > > inline bool > > > -is_a_helper <const gimple_statement_eh_ctrl>::test (const_gimple gs) > > > +is_a_helper <const gimple_statement_resx>::test (const_gimple gs) > > > { > > > - return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH; > > > + return gs->code == GIMPLE_RESX; > > > +} > > > + > > > +template <> > > > +template <> > > > +inline bool > > > +is_a_helper <const gimple_statement_eh_dispatch>::test (const_gimple gs) > > > +{ > > > + return gs->code == GIMPLE_EH_DISPATCH; > > > } > > > > > > template <> > > > @@ -936,7 +1051,15 @@ template <> > > > inline bool > > > is_a_helper <const gimple_statement_omp_atomic_store>::test (const_gimple gs) > > > { > > > - return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN; > > > + return gs->code == GIMPLE_OMP_ATOMIC_STORE; > > > +} > > > + > > > +template <> > > > +template <> > > > +inline bool > > > +is_a_helper <const gimple_statement_omp_return>::test (const_gimple gs) > > > +{ > > > + return gs->code == GIMPLE_OMP_RETURN; > > > } > > > > > > template <> > > > @@ -966,9 +1089,25 @@ is_a_helper <const gimple_statement_omp_for>::test (const_gimple gs) > > > template <> > > > template <> > > > inline bool > > > +is_a_helper <const gimple_statement_omp_taskreg>::test (const_gimple gs) > > > +{ > > > + return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK; > > > +} > > > + > > > +template <> > > > +template <> > > > +inline bool > > > is_a_helper <const gimple_statement_omp_parallel>::test (const_gimple gs) > > > { > > > - return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET; > > > + return gs->code == GIMPLE_OMP_PARALLEL; > > > +} > > > + > > > +template <> > > > +template <> > > > +inline bool > > > +is_a_helper <const gimple_statement_omp_target>::test (const_gimple gs) > > > +{ > > > + return gs->code == GIMPLE_OMP_TARGET; > > > } > > > > > > template <> > > > @@ -984,7 +1123,15 @@ template <> > > > inline bool > > > is_a_helper <const gimple_statement_omp_single>::test (const_gimple gs) > > > { > > > - return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS; > > > + return gs->code == GIMPLE_OMP_SINGLE; > > > +} > > > + > > > +template <> > > > +template <> > > > +inline bool > > > +is_a_helper <const gimple_statement_omp_teams>::test (const_gimple gs) > > > +{ > > > + return gs->code == GIMPLE_OMP_TEAMS; > > > } > > > > > > template <> > > > @@ -1766,9 +1913,9 @@ gimple_omp_return_nowait_p (const_gimple g) > > > static inline void > > > gimple_omp_return_set_lhs (gimple g, tree lhs) > > > { > > > - gimple_statement_omp_atomic_store *omp_atomic_store_stmt = > > > - as_a <gimple_statement_omp_atomic_store> (g); > > > - omp_atomic_store_stmt->val = lhs; > > > + gimple_statement_omp_return *omp_return_stmt = > > > + as_a <gimple_statement_omp_return> (g); > > > + omp_return_stmt->val = lhs; > > > } > > > > > > > > > @@ -1777,9 +1924,9 @@ gimple_omp_return_set_lhs (gimple g, tree lhs) > > > static inline tree > > > gimple_omp_return_lhs (const_gimple g) > > > { > > > - const gimple_statement_omp_atomic_store *omp_atomic_store_stmt = > > > - as_a <const gimple_statement_omp_atomic_store> (g); > > > - return omp_atomic_store_stmt->val; > > > + const gimple_statement_omp_return *omp_return_stmt = > > > + as_a <const gimple_statement_omp_return> (g); > > > + return omp_return_stmt->val; > > > } > > > > > > > > > @@ -1788,9 +1935,9 @@ gimple_omp_return_lhs (const_gimple g) > > > static inline tree * > > > gimple_omp_return_lhs_ptr (gimple g) > > > { > > > - gimple_statement_omp_atomic_store *omp_atomic_store_stmt = > > > - as_a <gimple_statement_omp_atomic_store> (g); > > > - return &omp_atomic_store_stmt->val; > > > + gimple_statement_omp_return *omp_return_stmt = > > > + as_a <gimple_statement_omp_return> (g); > > > + return &omp_return_stmt->val; > > > } > > > > > > > > > @@ -3793,9 +3940,9 @@ gimple_phi_arg_has_location (gimple gs, size_t i) > > > static inline int > > > gimple_resx_region (const_gimple gs) > > > { > > > - const gimple_statement_eh_ctrl *eh_ctrl_stmt = > > > - as_a <const gimple_statement_eh_ctrl> (gs); > > > - return eh_ctrl_stmt->region; > > > + const gimple_statement_resx *resx_stmt = > > > + as_a <const gimple_statement_resx> (gs); > > > + return resx_stmt->region; > > > } > > > > > > /* Set REGION to be the region number for GIMPLE_RESX GS. */ > > > @@ -3803,9 +3950,8 @@ gimple_resx_region (const_gimple gs) > > > static inline void > > > gimple_resx_set_region (gimple gs, int region) > > > { > > > - gimple_statement_eh_ctrl *eh_ctrl_stmt = > > > - as_a <gimple_statement_eh_ctrl> (gs); > > > - eh_ctrl_stmt->region = region; > > > + gimple_statement_resx *resx_stmt = as_a <gimple_statement_resx> (gs); > > > + resx_stmt->region = region; > > > } > > > > > > /* Return the region number for GIMPLE_EH_DISPATCH GS. */ > > > @@ -3813,9 +3959,9 @@ gimple_resx_set_region (gimple gs, int region) > > > static inline int > > > gimple_eh_dispatch_region (const_gimple gs) > > > { > > > - const gimple_statement_eh_ctrl *eh_ctrl_stmt = > > > - as_a <const gimple_statement_eh_ctrl> (gs); > > > - return eh_ctrl_stmt->region; > > > + const gimple_statement_eh_dispatch *eh_dispatch_stmt = > > > + as_a <const gimple_statement_eh_dispatch> (gs); > > > + return eh_dispatch_stmt->region; > > > } > > > > > > /* Set REGION to be the region number for GIMPLE_EH_DISPATCH GS. */ > > > @@ -3823,9 +3969,9 @@ gimple_eh_dispatch_region (const_gimple gs) > > > static inline void > > > gimple_eh_dispatch_set_region (gimple gs, int region) > > > { > > > - gimple_statement_eh_ctrl *eh_ctrl_stmt = > > > - as_a <gimple_statement_eh_ctrl> (gs); > > > - eh_ctrl_stmt->region = region; > > > + gimple_statement_eh_dispatch *eh_dispatch_stmt = > > > + as_a <gimple_statement_eh_dispatch> (gs); > > > + eh_dispatch_stmt->region = region; > > > } > > > > > > /* Return the number of labels associated with the switch statement GS. */ > > > @@ -4663,9 +4809,9 @@ gimple_omp_task_set_data_arg (gimple gs, tree data_arg) > > > static inline tree > > > gimple_omp_taskreg_clauses (const_gimple gs) > > > { > > > - const gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <const gimple_statement_omp_parallel> (gs); > > > - return omp_parallel_stmt->clauses; > > > + const gimple_statement_omp_taskreg *omp_taskreg_stmt = > > > + as_a <const gimple_statement_omp_taskreg> (gs); > > > + return omp_taskreg_stmt->clauses; > > > } > > > > > > > > > @@ -4674,9 +4820,9 @@ gimple_omp_taskreg_clauses (const_gimple gs) > > > static inline tree * > > > gimple_omp_taskreg_clauses_ptr (gimple gs) > > > { > > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <gimple_statement_omp_parallel> (gs); > > > - return &omp_parallel_stmt->clauses; > > > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > > > + as_a <gimple_statement_omp_taskreg> (gs); > > > + return &omp_taskreg_stmt->clauses; > > > } > > > > > > > > > @@ -4686,9 +4832,9 @@ gimple_omp_taskreg_clauses_ptr (gimple gs) > > > static inline void > > > gimple_omp_taskreg_set_clauses (gimple gs, tree clauses) > > > { > > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <gimple_statement_omp_parallel> (gs); > > > - omp_parallel_stmt->clauses = clauses; > > > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > > > + as_a <gimple_statement_omp_taskreg> (gs); > > > + omp_taskreg_stmt->clauses = clauses; > > > } > > > > > > > > > @@ -4697,9 +4843,9 @@ gimple_omp_taskreg_set_clauses (gimple gs, tree clauses) > > > static inline tree > > > gimple_omp_taskreg_child_fn (const_gimple gs) > > > { > > > - const gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <const gimple_statement_omp_parallel> (gs); > > > - return omp_parallel_stmt->child_fn; > > > + const gimple_statement_omp_taskreg *omp_taskreg_stmt = > > > + as_a <const gimple_statement_omp_taskreg> (gs); > > > + return omp_taskreg_stmt->child_fn; > > > } > > > > > > /* Return a pointer to the child function used to hold the body of > > > @@ -4708,9 +4854,9 @@ gimple_omp_taskreg_child_fn (const_gimple gs) > > > static inline tree * > > > gimple_omp_taskreg_child_fn_ptr (gimple gs) > > > { > > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <gimple_statement_omp_parallel> (gs); > > > - return &omp_parallel_stmt->child_fn; > > > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > > > + as_a <gimple_statement_omp_taskreg> (gs); > > > + return &omp_taskreg_stmt->child_fn; > > > } > > > > > > > > > @@ -4719,9 +4865,9 @@ gimple_omp_taskreg_child_fn_ptr (gimple gs) > > > static inline void > > > gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn) > > > { > > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <gimple_statement_omp_parallel> (gs); > > > - omp_parallel_stmt->child_fn = child_fn; > > > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > > > + as_a <gimple_statement_omp_taskreg> (gs); > > > + omp_taskreg_stmt->child_fn = child_fn; > > > } > > > > > > > > > @@ -4731,9 +4877,9 @@ gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn) > > > static inline tree > > > gimple_omp_taskreg_data_arg (const_gimple gs) > > > { > > > - const gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <const gimple_statement_omp_parallel> (gs); > > > - return omp_parallel_stmt->data_arg; > > > + const gimple_statement_omp_taskreg *omp_taskreg_stmt = > > > + as_a <const gimple_statement_omp_taskreg> (gs); > > > + return omp_taskreg_stmt->data_arg; > > > } > > > > > > > > > @@ -4742,9 +4888,9 @@ gimple_omp_taskreg_data_arg (const_gimple gs) > > > static inline tree * > > > gimple_omp_taskreg_data_arg_ptr (gimple gs) > > > { > > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <gimple_statement_omp_parallel> (gs); > > > - return &omp_parallel_stmt->data_arg; > > > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > > > + as_a <gimple_statement_omp_taskreg> (gs); > > > + return &omp_taskreg_stmt->data_arg; > > > } > > > > > > > > > @@ -4753,9 +4899,9 @@ gimple_omp_taskreg_data_arg_ptr (gimple gs) > > > static inline void > > > gimple_omp_taskreg_set_data_arg (gimple gs, tree data_arg) > > > { > > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <gimple_statement_omp_parallel> (gs); > > > - omp_parallel_stmt->data_arg = data_arg; > > > + gimple_statement_omp_taskreg *omp_taskreg_stmt = > > > + as_a <gimple_statement_omp_taskreg> (gs); > > > + omp_taskreg_stmt->data_arg = data_arg; > > > } > > > > > > > > > @@ -4896,9 +5042,9 @@ gimple_omp_single_set_clauses (gimple gs, tree clauses) > > > static inline tree > > > gimple_omp_target_clauses (const_gimple gs) > > > { > > > - const gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <const gimple_statement_omp_parallel> (gs); > > > - return omp_parallel_stmt->clauses; > > > + const gimple_statement_omp_target *omp_target_stmt = > > > + as_a <const gimple_statement_omp_target> (gs); > > > + return omp_target_stmt->clauses; > > > } > > > > > > > > > @@ -4907,9 +5053,9 @@ gimple_omp_target_clauses (const_gimple gs) > > > static inline tree * > > > gimple_omp_target_clauses_ptr (gimple gs) > > > { > > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <gimple_statement_omp_parallel> (gs); > > > - return &omp_parallel_stmt->clauses; > > > + gimple_statement_omp_target *omp_target_stmt = > > > + as_a <gimple_statement_omp_target> (gs); > > > + return &omp_target_stmt->clauses; > > > } > > > > > > > > > @@ -4918,9 +5064,9 @@ gimple_omp_target_clauses_ptr (gimple gs) > > > static inline void > > > gimple_omp_target_set_clauses (gimple gs, tree clauses) > > > { > > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <gimple_statement_omp_parallel> (gs); > > > - omp_parallel_stmt->clauses = clauses; > > > + gimple_statement_omp_target *omp_target_stmt = > > > + as_a <gimple_statement_omp_target> (gs); > > > + omp_target_stmt->clauses = clauses; > > > } > > > > > > > > > @@ -4950,9 +5096,9 @@ gimple_omp_target_set_kind (gimple g, int kind) > > > static inline tree > > > gimple_omp_target_child_fn (const_gimple gs) > > > { > > > - const gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <const gimple_statement_omp_parallel> (gs); > > > - return omp_parallel_stmt->child_fn; > > > + const gimple_statement_omp_target *omp_target_stmt = > > > + as_a <const gimple_statement_omp_target> (gs); > > > + return omp_target_stmt->child_fn; > > > } > > > > > > /* Return a pointer to the child function used to hold the body of > > > @@ -4961,9 +5107,9 @@ gimple_omp_target_child_fn (const_gimple gs) > > > static inline tree * > > > gimple_omp_target_child_fn_ptr (gimple gs) > > > { > > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <gimple_statement_omp_parallel> (gs); > > > - return &omp_parallel_stmt->child_fn; > > > + gimple_statement_omp_target *omp_target_stmt = > > > + as_a <gimple_statement_omp_target> (gs); > > > + return &omp_target_stmt->child_fn; > > > } > > > > > > > > > @@ -4972,9 +5118,9 @@ gimple_omp_target_child_fn_ptr (gimple gs) > > > static inline void > > > gimple_omp_target_set_child_fn (gimple gs, tree child_fn) > > > { > > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <gimple_statement_omp_parallel> (gs); > > > - omp_parallel_stmt->child_fn = child_fn; > > > + gimple_statement_omp_target *omp_target_stmt = > > > + as_a <gimple_statement_omp_target> (gs); > > > + omp_target_stmt->child_fn = child_fn; > > > } > > > > > > > > > @@ -4984,9 +5130,9 @@ gimple_omp_target_set_child_fn (gimple gs, tree child_fn) > > > static inline tree > > > gimple_omp_target_data_arg (const_gimple gs) > > > { > > > - const gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <const gimple_statement_omp_parallel> (gs); > > > - return omp_parallel_stmt->data_arg; > > > + const gimple_statement_omp_target *omp_target_stmt = > > > + as_a <const gimple_statement_omp_target> (gs); > > > + return omp_target_stmt->data_arg; > > > } > > > > > > > > > @@ -4995,9 +5141,9 @@ gimple_omp_target_data_arg (const_gimple gs) > > > static inline tree * > > > gimple_omp_target_data_arg_ptr (gimple gs) > > > { > > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <gimple_statement_omp_parallel> (gs); > > > - return &omp_parallel_stmt->data_arg; > > > + gimple_statement_omp_target *omp_target_stmt = > > > + as_a <gimple_statement_omp_target> (gs); > > > + return &omp_target_stmt->data_arg; > > > } > > > > > > > > > @@ -5006,9 +5152,9 @@ gimple_omp_target_data_arg_ptr (gimple gs) > > > static inline void > > > gimple_omp_target_set_data_arg (gimple gs, tree data_arg) > > > { > > > - gimple_statement_omp_parallel *omp_parallel_stmt = > > > - as_a <gimple_statement_omp_parallel> (gs); > > > - omp_parallel_stmt->data_arg = data_arg; > > > + gimple_statement_omp_target *omp_target_stmt = > > > + as_a <gimple_statement_omp_target> (gs); > > > + omp_target_stmt->data_arg = data_arg; > > > } > > > > > > > > > @@ -5017,9 +5163,9 @@ gimple_omp_target_set_data_arg (gimple gs, tree data_arg) > > > static inline tree > > > gimple_omp_teams_clauses (const_gimple gs) > > > { > > > - const gimple_statement_omp_single *omp_single_stmt = > > > - as_a <const gimple_statement_omp_single> (gs); > > > - return omp_single_stmt->clauses; > > > + const gimple_statement_omp_teams *omp_teams_stmt = > > > + as_a <const gimple_statement_omp_teams> (gs); > > > + return omp_teams_stmt->clauses; > > > } > > > > > > > > > @@ -5028,9 +5174,9 @@ gimple_omp_teams_clauses (const_gimple gs) > > > static inline tree * > > > gimple_omp_teams_clauses_ptr (gimple gs) > > > { > > > - gimple_statement_omp_single *omp_single_stmt = > > > - as_a <gimple_statement_omp_single> (gs); > > > - return &omp_single_stmt->clauses; > > > + gimple_statement_omp_teams *omp_teams_stmt = > > > + as_a <gimple_statement_omp_teams> (gs); > > > + return &omp_teams_stmt->clauses; > > > } > > > > > > > > > @@ -5039,9 +5185,9 @@ gimple_omp_teams_clauses_ptr (gimple gs) > > > static inline void > > > gimple_omp_teams_set_clauses (gimple gs, tree clauses) > > > { > > > - gimple_statement_omp_single *omp_single_stmt = > > > - as_a <gimple_statement_omp_single> (gs); > > > - omp_single_stmt->clauses = clauses; > > > + gimple_statement_omp_teams *omp_teams_stmt = > > > + as_a <gimple_statement_omp_teams> (gs); > > > + omp_teams_stmt->clauses = clauses; > > > } > > > > > > > > > diff --git a/gcc/gsstruct.def b/gcc/gsstruct.def > > > index 91738f4..82f1f52 100644 > > > --- a/gcc/gsstruct.def > > > +++ b/gcc/gsstruct.def > > > @@ -43,11 +43,11 @@ DEFGSSTRUCT(GSS_WCE, gimple_statement_wce, false) > > > DEFGSSTRUCT(GSS_OMP, gimple_statement_omp, false) > > > DEFGSSTRUCT(GSS_OMP_CRITICAL, gimple_statement_omp_critical, false) > > > DEFGSSTRUCT(GSS_OMP_FOR, gimple_statement_omp_for, false) > > > -DEFGSSTRUCT(GSS_OMP_PARALLEL, gimple_statement_omp_parallel, false) > > > +DEFGSSTRUCT(GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout, false) > > > DEFGSSTRUCT(GSS_OMP_TASK, gimple_statement_omp_task, false) > > > DEFGSSTRUCT(GSS_OMP_SECTIONS, gimple_statement_omp_sections, false) > > > -DEFGSSTRUCT(GSS_OMP_SINGLE, gimple_statement_omp_single, false) > > > +DEFGSSTRUCT(GSS_OMP_SINGLE_LAYOUT, gimple_statement_omp_single_layout, false) > > > DEFGSSTRUCT(GSS_OMP_CONTINUE, gimple_statement_omp_continue, false) > > > DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, gimple_statement_omp_atomic_load, false) > > > -DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store, false) > > > +DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE_LAYOUT, gimple_statement_omp_atomic_store, false) > > > DEFGSSTRUCT(GSS_TRANSACTION, gimple_statement_transaction, false) Grüße, Thomas [-- Attachment #2: Type: application/pgp-signature, Size: 472 bytes --] ^ permalink raw reply [flat|nested] 116+ messages in thread
* [PATCH 6/6] Update gdb hooks to reflect changes to gimple types 2013-10-31 16:41 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) David Malcolm ` (3 preceding siblings ...) 2013-10-31 16:31 ` [PATCH 3/6] Automated part of conversion of gimple types to use " David Malcolm @ 2013-10-31 16:46 ` David Malcolm 2013-11-14 9:10 ` Jeff Law 2013-10-31 16:49 ` [PATCH 5/6] Port various places from union access to subclass access David Malcolm ` (4 subsequent siblings) 9 siblings, 1 reply; 116+ messages in thread From: David Malcolm @ 2013-10-31 16:46 UTC (permalink / raw) To: gcc-patches, Andrew MacLeod; +Cc: David Malcolm gcc/ * gdbhooks.py (GimplePrinter.to_string): Update lookup of code field to reflect inheritance, rather than embedding of the base gimple type. --- gcc/gdbhooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py index 53abf32..c05e574 100644 --- a/gcc/gdbhooks.py +++ b/gcc/gdbhooks.py @@ -240,7 +240,7 @@ class GimplePrinter: def to_string (self): if long(self.gdbval) == 0: return '<gimple 0x0>' - val_gimple_code = self.gdbval['gsbase']['code'] + val_gimple_code = self.gdbval['code'] val_gimple_code_name = gdb.parse_and_eval('gimple_code_name') val_code_name = val_gimple_code_name[long(val_gimple_code)] result = '<%s 0x%x' % (val_code_name.string(), -- 1.7.11.7 ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 6/6] Update gdb hooks to reflect changes to gimple types 2013-10-31 16:46 ` [PATCH 6/6] Update gdb hooks to reflect changes to " David Malcolm @ 2013-11-14 9:10 ` Jeff Law 0 siblings, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-14 9:10 UTC (permalink / raw) To: David Malcolm, gcc-patches, Andrew MacLeod On 10/31/13 10:26, David Malcolm wrote: > gcc/ > * gdbhooks.py (GimplePrinter.to_string): Update lookup of > code field to reflect inheritance, rather than embedding of > the base gimple type. Conditionally approved. Obvious condition is the other 5 patches get approved. Jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* [PATCH 5/6] Port various places from union access to subclass access. 2013-10-31 16:41 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) David Malcolm ` (4 preceding siblings ...) 2013-10-31 16:46 ` [PATCH 6/6] Update gdb hooks to reflect changes to " David Malcolm @ 2013-10-31 16:49 ` David Malcolm 2013-11-14 9:23 ` Jeff Law 2013-10-31 18:43 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) Basile Starynkevitch ` (3 subsequent siblings) 9 siblings, 1 reply; 116+ messages in thread From: David Malcolm @ 2013-10-31 16:49 UTC (permalink / raw) To: gcc-patches, Andrew MacLeod; +Cc: David Malcolm * gimple-streamer-in.c (input_gimple_stmt): Port from union access to use of as_a. * gimple.c (gimple_build_asm_1): Likewise. (gimple_build_try): Likewise. Also, return a specific subclass rather than just gimple. (gimple_build_resx): Port from union access to use of as_a. (gimple_build_eh_dispatch): Likewise. (gimple_build_omp_for): Likewise. Also, convert allocation of iter now that gengtype no longer provides a typed allocator function. (gimple_copy): Likewise. * gimple.h (gimple_build_try): Return a specific subclass rather than just gimple. * gimplify.c (gimplify_cleanup_point_expr): Replace union access with subclass access by making use of new return type of gimple_build_try. * tree-phinodes.c: (allocate_phi_node): Return a "gimple_statement_phi *" rather than just a gimple. (resize_phi_node): Likewise. (make_phi_node): Replace union access with subclass access by making use of new return type of allocate_phi_node. (reserve_phi_args_for_new_edge): Replace union access with as_a. (remove_phi_arg_num): Accept a "gimple_statement_phi *" rather than just a gimple. (remove_phi_args): Update for change to remove_phi_arg_num. --- gcc/gimple-streamer-in.c | 11 ++++----- gcc/gimple.c | 58 ++++++++++++++++++++++++++++++------------------ gcc/gimple.h | 3 ++- gcc/gimplify.c | 4 ++-- gcc/tree-phinodes.c | 37 ++++++++++++++++-------------- 5 files changed, 66 insertions(+), 47 deletions(-) diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c index 4f31b83..2555dbe 100644 --- a/gcc/gimple-streamer-in.c +++ b/gcc/gimple-streamer-in.c @@ -129,13 +129,14 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, case GIMPLE_ASM: { /* FIXME lto. Move most of this into a new gimple_asm_set_string(). */ + gimple_statement_asm *asm_stmt = as_a <gimple_statement_asm> (stmt); tree str; - stmt->gimple_asm.ni = streamer_read_uhwi (ib); - stmt->gimple_asm.no = streamer_read_uhwi (ib); - stmt->gimple_asm.nc = streamer_read_uhwi (ib); - stmt->gimple_asm.nl = streamer_read_uhwi (ib); + asm_stmt->ni = streamer_read_uhwi (ib); + asm_stmt->no = streamer_read_uhwi (ib); + asm_stmt->nc = streamer_read_uhwi (ib); + asm_stmt->nl = streamer_read_uhwi (ib); str = streamer_read_string_cst (data_in, ib); - stmt->gimple_asm.string = TREE_STRING_POINTER (str); + asm_stmt->string = TREE_STRING_POINTER (str); } /* Fallthru */ diff --git a/gcc/gimple.c b/gcc/gimple.c index 9b1337a..e9ef8e0 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -641,21 +641,22 @@ static inline gimple gimple_build_asm_1 (const char *string, unsigned ninputs, unsigned noutputs, unsigned nclobbers, unsigned nlabels) { - gimple p; + gimple_statement_asm *p; int size = strlen (string); /* ASMs with labels cannot have outputs. This should have been enforced by the front end. */ gcc_assert (nlabels == 0 || noutputs == 0); - p = gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK, - ninputs + noutputs + nclobbers + nlabels); + p = as_a <gimple_statement_asm> ( + gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK, + ninputs + noutputs + nclobbers + nlabels)); - p->gimple_asm.ni = ninputs; - p->gimple_asm.no = noutputs; - p->gimple_asm.nc = nclobbers; - p->gimple_asm.nl = nlabels; - p->gimple_asm.string = ggc_alloc_string (string, size); + p->ni = ninputs; + p->no = noutputs; + p->nc = nclobbers; + p->nl = nlabels; + p->string = ggc_alloc_string (string, size); if (GATHER_STATISTICS) gimple_alloc_sizes[(int) gimple_alloc_kind (GIMPLE_ASM)] += size; @@ -767,14 +768,14 @@ gimple_build_eh_else (gimple_seq n_body, gimple_seq e_body) KIND is either GIMPLE_TRY_CATCH or GIMPLE_TRY_FINALLY depending on whether this is a try/catch or a try/finally respectively. */ -gimple +gimple_statement_try * gimple_build_try (gimple_seq eval, gimple_seq cleanup, enum gimple_try_flags kind) { - gimple p; + gimple_statement_try *p; gcc_assert (kind == GIMPLE_TRY_CATCH || kind == GIMPLE_TRY_FINALLY); - p = gimple_alloc (GIMPLE_TRY, 0); + p = as_a <gimple_statement_try> (gimple_alloc (GIMPLE_TRY, 0)); gimple_set_subcode (p, kind); if (eval) gimple_try_set_eval (p, eval); @@ -804,8 +805,10 @@ gimple_build_wce (gimple_seq cleanup) gimple gimple_build_resx (int region) { - gimple p = gimple_build_with_ops (GIMPLE_RESX, ERROR_MARK, 0); - p->gimple_eh_ctrl.region = region; + gimple_statement_eh_ctrl *p = + as_a <gimple_statement_eh_ctrl> ( + gimple_build_with_ops (GIMPLE_RESX, ERROR_MARK, 0)); + p->region = region; return p; } @@ -852,8 +855,10 @@ gimple_build_switch (tree index, tree default_label, vec<tree> args) gimple gimple_build_eh_dispatch (int region) { - gimple p = gimple_build_with_ops (GIMPLE_EH_DISPATCH, ERROR_MARK, 0); - p->gimple_eh_ctrl.region = region; + gimple_statement_eh_ctrl *p = + as_a <gimple_statement_eh_ctrl> ( + gimple_build_with_ops (GIMPLE_EH_DISPATCH, ERROR_MARK, 0)); + p->region = region; return p; } @@ -927,14 +932,17 @@ gimple gimple_build_omp_for (gimple_seq body, int kind, tree clauses, size_t collapse, gimple_seq pre_body) { - gimple p = gimple_alloc (GIMPLE_OMP_FOR, 0); + gimple_statement_omp_for *p = + as_a <gimple_statement_omp_for> (gimple_alloc (GIMPLE_OMP_FOR, 0)); if (body) gimple_omp_set_body (p, body); gimple_omp_for_set_clauses (p, clauses); gimple_omp_for_set_kind (p, kind); - p->gimple_omp_for.collapse = collapse; - p->gimple_omp_for.iter - = ggc_alloc_cleared_vec_gimple_omp_for_iter (collapse); + p->collapse = collapse; + p->iter = static_cast <struct gimple_omp_for_iter *> ( + ggc_internal_cleared_vec_alloc_stat (sizeof (*p->iter), + collapse MEM_STAT_INFO)); + if (pre_body) gimple_omp_for_set_pre_body (p, pre_body); @@ -2311,9 +2319,15 @@ gimple_copy (gimple stmt) gimple_omp_for_set_pre_body (copy, new_seq); t = unshare_expr (gimple_omp_for_clauses (stmt)); gimple_omp_for_set_clauses (copy, t); - copy->gimple_omp_for.iter - = ggc_alloc_vec_gimple_omp_for_iter - (gimple_omp_for_collapse (stmt)); + { + gimple_statement_omp_for *omp_for_copy = + as_a <gimple_statement_omp_for> (copy); + omp_for_copy->iter = + static_cast <struct gimple_omp_for_iter *> ( + ggc_internal_vec_alloc_stat (sizeof (struct gimple_omp_for_iter), + gimple_omp_for_collapse (stmt) + MEM_STAT_INFO)); + } for (i = 0; i < gimple_omp_for_collapse (stmt); i++) { gimple_omp_for_set_cond (copy, i, diff --git a/gcc/gimple.h b/gcc/gimple.h index 710ce04..35bfa06 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1074,7 +1074,8 @@ gimple gimple_build_catch (tree, gimple_seq); gimple gimple_build_eh_filter (tree, gimple_seq); gimple gimple_build_eh_must_not_throw (tree); gimple gimple_build_eh_else (gimple_seq, gimple_seq); -gimple gimple_build_try (gimple_seq, gimple_seq, enum gimple_try_flags); +gimple_statement_try *gimple_build_try (gimple_seq, gimple_seq, + enum gimple_try_flags); gimple gimple_build_wce (gimple_seq); gimple gimple_build_resx (int); gimple gimple_build_eh_dispatch (int); diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 1f18466..5869441 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -5456,7 +5456,7 @@ gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p) } else { - gimple gtry; + gimple_statement_try *gtry; gimple_seq seq; enum gimple_try_flags kind; @@ -5470,7 +5470,7 @@ gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p) /* Do not use gsi_replace here, as it may scan operands. We want to do a simple structural modification only. */ gsi_set_stmt (&iter, gtry); - iter = gsi_start (gtry->gimple_try.eval); + iter = gsi_start (gtry->eval); } } else diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c index 65c636c..6e425fe 100644 --- a/gcc/tree-phinodes.c +++ b/gcc/tree-phinodes.c @@ -92,10 +92,10 @@ phinodes_print_statistics (void) happens to contain a PHI node with LEN arguments or more, return that one. */ -static inline gimple +static inline gimple_statement_phi * allocate_phi_node (size_t len) { - gimple phi; + gimple_statement_phi *phi; size_t bucket = NUM_BUCKETS - 2; size_t size = sizeof (struct gimple_statement_phi) + (len - 1) * sizeof (struct phi_arg_d); @@ -110,7 +110,7 @@ allocate_phi_node (size_t len) && gimple_phi_capacity ((*free_phinodes[bucket])[0]) >= len) { free_phinode_count--; - phi = free_phinodes[bucket]->pop (); + phi = as_a <gimple_statement_phi> (free_phinodes[bucket]->pop ()); if (free_phinodes[bucket]->is_empty ()) vec_free (free_phinodes[bucket]); if (GATHER_STATISTICS) @@ -118,7 +118,8 @@ allocate_phi_node (size_t len) } else { - phi = ggc_alloc_gimple_statement_d (size); + phi = static_cast <gimple_statement_phi *> ( + ggc_internal_alloc_stat (size MEM_STAT_INFO)); if (GATHER_STATISTICS) { enum gimple_alloc_kind kind = gimple_alloc_kind (GIMPLE_PHI); @@ -170,7 +171,7 @@ ideal_phi_node_len (int len) static gimple make_phi_node (tree var, int len) { - gimple phi; + gimple_statement_phi *phi; int capacity, i; capacity = ideal_phi_node_len (len); @@ -185,8 +186,8 @@ make_phi_node (tree var, int len) + sizeof (struct phi_arg_d) * len)); phi->code = GIMPLE_PHI; gimple_init_singleton (phi); - phi->gimple_phi.nargs = len; - phi->gimple_phi.capacity = capacity; + phi->nargs = len; + phi->capacity = capacity; if (!var) ; else if (TREE_CODE (var) == SSA_NAME) @@ -235,11 +236,11 @@ release_phi_node (gimple phi) /* Resize an existing PHI node. The only way is up. Return the possibly relocated phi. */ -static gimple -resize_phi_node (gimple phi, size_t len) +static gimple_statement_phi * +resize_phi_node (gimple_statement_phi *phi, size_t len) { size_t old_size, i; - gimple new_phi; + gimple_statement_phi *new_phi; gcc_assert (len > gimple_phi_capacity (phi)); @@ -262,7 +263,7 @@ resize_phi_node (gimple phi, size_t len) relink_imm_use_stmt (imm, old_imm, new_phi); } - new_phi->gimple_phi.capacity = len; + new_phi->capacity = len; for (i = gimple_phi_num_args (new_phi); i < len; i++) { @@ -290,11 +291,12 @@ reserve_phi_args_for_new_edge (basic_block bb) for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { - gimple stmt = gsi_stmt (gsi); + gimple_statement_phi *stmt = + as_a <gimple_statement_phi> (gsi_stmt (gsi)); if (len > gimple_phi_capacity (stmt)) { - gimple new_phi = resize_phi_node (stmt, cap); + gimple_statement_phi *new_phi = resize_phi_node (stmt, cap); /* The result of the PHI is defined by this PHI node. */ SSA_NAME_DEF_STMT (gimple_phi_result (new_phi)) = new_phi; @@ -314,7 +316,7 @@ reserve_phi_args_for_new_edge (basic_block bb) SET_PHI_ARG_DEF (stmt, len - 1, NULL_TREE); gimple_phi_arg_set_location (stmt, len - 1, UNKNOWN_LOCATION); - stmt->gimple_phi.nargs++; + stmt->nargs++; } } @@ -390,7 +392,7 @@ add_phi_arg (gimple phi, tree def, edge e, source_location locus) is consistent with how we remove an edge from the edge vector. */ static void -remove_phi_arg_num (gimple phi, int i) +remove_phi_arg_num (gimple_statement_phi *phi, int i) { int num_elem = gimple_phi_num_args (phi); @@ -417,7 +419,7 @@ remove_phi_arg_num (gimple phi, int i) /* Shrink the vector and return. Note that we do not have to clear PHI_ARG_DEF because the garbage collector will not look at those elements beyond the first PHI_NUM_ARGS elements of the array. */ - phi->gimple_phi.nargs--; + phi->nargs--; } @@ -429,7 +431,8 @@ remove_phi_args (edge e) gimple_stmt_iterator gsi; for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) - remove_phi_arg_num (gsi_stmt (gsi), e->dest_idx); + remove_phi_arg_num (as_a <gimple_statement_phi> (gsi_stmt (gsi)), + e->dest_idx); } -- 1.7.11.7 ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 5/6] Port various places from union access to subclass access. 2013-10-31 16:49 ` [PATCH 5/6] Port various places from union access to subclass access David Malcolm @ 2013-11-14 9:23 ` Jeff Law 2013-11-19 0:52 ` David Malcolm 0 siblings, 1 reply; 116+ messages in thread From: Jeff Law @ 2013-11-14 9:23 UTC (permalink / raw) To: David Malcolm, gcc-patches, Andrew MacLeod On 10/31/13 10:26, David Malcolm wrote: > > diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c > index 4f31b83..2555dbe 100644 > --- a/gcc/gimple-streamer-in.c > +++ b/gcc/gimple-streamer-in.c > @@ -129,13 +129,14 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, > case GIMPLE_ASM: > { > /* FIXME lto. Move most of this into a new gimple_asm_set_string(). */ > + gimple_statement_asm *asm_stmt = as_a <gimple_statement_asm> (stmt); > tree str; > - stmt->gimple_asm.ni = streamer_read_uhwi (ib); > - stmt->gimple_asm.no = streamer_read_uhwi (ib); > - stmt->gimple_asm.nc = streamer_read_uhwi (ib); > - stmt->gimple_asm.nl = streamer_read_uhwi (ib); > + asm_stmt->ni = streamer_read_uhwi (ib); > + asm_stmt->no = streamer_read_uhwi (ib); > + asm_stmt->nc = streamer_read_uhwi (ib); > + asm_stmt->nl = streamer_read_uhwi (ib); > str = streamer_read_string_cst (data_in, ib); > - stmt->gimple_asm.string = TREE_STRING_POINTER (str); > + asm_stmt->string = TREE_STRING_POINTER (str); The in/out streaming seems like another natural fit for virtual functions in the long term. > } > /* Fallthru */ > > diff --git a/gcc/gimple.c b/gcc/gimple.c > index 9b1337a..e9ef8e0 100644 > --- a/gcc/gimple.c > +++ b/gcc/gimple.c > @@ -641,21 +641,22 @@ static inline gimple > gimple_build_asm_1 (const char *string, unsigned ninputs, unsigned noutputs, > unsigned nclobbers, unsigned nlabels) > { > - gimple p; > + gimple_statement_asm *p; > int size = strlen (string); > > /* ASMs with labels cannot have outputs. This should have been > enforced by the front end. */ > gcc_assert (nlabels == 0 || noutputs == 0); > > - p = gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK, > - ninputs + noutputs + nclobbers + nlabels); > + p = as_a <gimple_statement_asm> ( > + gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK, > + ninputs + noutputs + nclobbers + nlabels)); > > - p->gimple_asm.ni = ninputs; > - p->gimple_asm.no = noutputs; > - p->gimple_asm.nc = nclobbers; > - p->gimple_asm.nl = nlabels; > - p->gimple_asm.string = ggc_alloc_string (string, size); > + p->ni = ninputs; > + p->no = noutputs; > + p->nc = nclobbers; > + p->nl = nlabels; > + p->string = ggc_alloc_string (string, size); As noted in a prior message, having build methods would eliminate this downcasting. Not necessary for this patch, just wanted to point it out to anyone reading. I won't point it out everywhere ;-) So given the prior disussions around as_a, I'm not going to object to these as_a instances. I see them as warts/markers that we have further work to do in terms of fleshing out the class and possibly refactoring code. Conditionally OK. Conditional on the other related patches going in and keeping it updated with Andrew's churn. If/when the set goes in, post the final version you actually checkin -- no re-review is needed for this hunk so long as any changes are the obvious fixing of fallout from Andrew's work. Jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 5/6] Port various places from union access to subclass access. 2013-11-14 9:23 ` Jeff Law @ 2013-11-19 0:52 ` David Malcolm 0 siblings, 0 replies; 116+ messages in thread From: David Malcolm @ 2013-11-19 0:52 UTC (permalink / raw) To: Jeff Law; +Cc: gcc-patches, Andrew MacLeod On Thu, 2013-11-14 at 00:34 -0700, Jeff Law wrote: > On 10/31/13 10:26, David Malcolm wrote: [...] > > diff --git a/gcc/gimple.c b/gcc/gimple.c > > index 9b1337a..e9ef8e0 100644 > > --- a/gcc/gimple.c > > +++ b/gcc/gimple.c > > @@ -641,21 +641,22 @@ static inline gimple > > gimple_build_asm_1 (const char *string, unsigned ninputs, unsigned noutputs, > > unsigned nclobbers, unsigned nlabels) > > { > > - gimple p; > > + gimple_statement_asm *p; > > int size = strlen (string); > > > > /* ASMs with labels cannot have outputs. This should have been > > enforced by the front end. */ > > gcc_assert (nlabels == 0 || noutputs == 0); > > > > - p = gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK, > > - ninputs + noutputs + nclobbers + nlabels); > > + p = as_a <gimple_statement_asm> ( > > + gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK, > > + ninputs + noutputs + nclobbers + nlabels)); > > > > - p->gimple_asm.ni = ninputs; > > - p->gimple_asm.no = noutputs; > > - p->gimple_asm.nc = nclobbers; > > - p->gimple_asm.nl = nlabels; > > - p->gimple_asm.string = ggc_alloc_string (string, size); > > + p->ni = ninputs; > > + p->no = noutputs; > > + p->nc = nclobbers; > > + p->nl = nlabels; > > + p->string = ggc_alloc_string (string, size); > As noted in a prior message, having build methods would eliminate this > downcasting. Not necessary for this patch, just wanted to point it out > to anyone reading. I won't point it out everywhere ;-) This one (gimple_build_asm_1) is itself a build method. The checking on the downcast could be argued to be redundant, since presumably we trust gimple_build_with_ops to give us a stmt with the code we asked for, but I don't think it hurts. > So given the prior disussions around as_a, I'm not going to object to > these as_a instances. I see them as warts/markers that we have further > work to do in terms of fleshing out the class and possibly refactoring > code. > > Conditionally OK. Conditional on the other related patches going in and > keeping it updated with Andrew's churn. If/when the set goes in, post > the final version you actually checkin -- no re-review is needed for > this hunk so long as any changes are the obvious fixing of fallout from > Andrew's work. Thanks. ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-10-31 16:41 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) David Malcolm ` (5 preceding siblings ...) 2013-10-31 16:49 ` [PATCH 5/6] Port various places from union access to subclass access David Malcolm @ 2013-10-31 18:43 ` Basile Starynkevitch 2013-11-01 21:36 ` Andrew MacLeod ` (2 subsequent siblings) 9 siblings, 0 replies; 116+ messages in thread From: Basile Starynkevitch @ 2013-10-31 18:43 UTC (permalink / raw) To: David Malcolm; +Cc: gcc-patches, Andrew MacLeod On 10/31/2013 05:26 PM, David Malcolm wrote: > [Shamelessly hijacking Andrew's thread about gimple.h refactoring, > since this seems on-topic for that, and I'm keen to hear from Andrew on > how the following would interact with his work - I *think* our two > cleanups are orthogonal. > > [This is a revised version of the patches sent as: > http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01788.html > and > http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01954.html > which got bogged down in discussion of hand-written GTY hooks. This > patch series updates things to make use of the new support in gengtype > for simple inheritance schemes] > > The gimple statement types are currently implemented using a hand-coded > C inheritance scheme, with a "union gimple_statement_d" holding the > various possible structs for a statement. > > The following series of patches convert it to a C++ hierarchy, using the > existing structs, eliminating the union. The "gimple" typedef changes > from being a > (union gimple_statement_d *) > to being a: > (struct gimple_statement_base *) Very good idea. But please, document that in some texinfo file, probably gcc/doc/gimple.texi Gimple-s are so damn important, even for plugin writers, that a small but up to date documentation is absolutely essential. You don"t need to write a lot of doc, just the minimal stuff (which at least tells which file should the plugin writer look into and list all the relevant classes). I hope your patches (or similar ones) will be accepted in 4.9 Regards. -- Basile STARYNKEVITCH http://starynkevitch.net/Basile/ email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359 8, rue de la Faiencerie, 92340 Bourg La Reine, France *** opinions {are only mine, sont seulement les miennes} *** ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-10-31 16:41 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) David Malcolm ` (6 preceding siblings ...) 2013-10-31 18:43 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) Basile Starynkevitch @ 2013-11-01 21:36 ` Andrew MacLeod 2013-11-01 21:41 ` Jakub Jelinek ` (3 more replies) 2013-11-05 21:33 ` Jeff Law 2013-11-14 8:40 ` Jeff Law 9 siblings, 4 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-11-01 21:36 UTC (permalink / raw) To: David Malcolm; +Cc: gcc-patches On 10/31/2013 12:26 PM, David Malcolm wrote: > [Shamelessly hijacking Andrew's thread about gimple.h refactoring, > since this seems on-topic for that, and I'm keen to hear from Andrew on > how the following would interact with his work - I *think* our two > cleanups are orthogonal. Mostly orthogonal anyway... just stomping on the same bits :-). Since you hijacked a planning thread, do you plan to take this any further, or make this change and move on to something else? It is a start, but it doesnt do the rest of the work that needs doing to really take advantage of it... which will be extensive. for instance, we should change: static inline void ! gimple_call_set_lhs (gimple gs, tree lhs) { - GIMPLE_CHECK (gs, GIMPLE_CALL); gimple_set_op (gs, 0, lhs); to static inline void ! gimple_call_set_lhs (gimple_statement_call *gs, tree lhs) { gimple_set_op (gs, 0, lhs); but then every location that calls it needs an appropriate change: ! gimple call; ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs); gimple_call_set_lhs (call, atree); --- 1518,1524 ---- ! gimple_statement_call *call; ! call = as_a<gimple_statement_call> (gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs)); gimple_call_set_lhs (call, atree); And in fact there is a ripple effect to then change gimple_build_call_vec to simply return a gimple_statement_call *... Then this doesn't look as ugly either... ! gimple_statement_call *call; ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs); gimple_call_set_lhs (call, atree); that is looking much better :-) Leaving the names as they are should be ok, but the I'd also add a typedef for the pointer without the 'statement' in the name.. ie typedef gimple_statement_call *gimple_call; That seems in line with what we do with 'gimple' right now and the short form is the type we'd normally use. That adds a touch of difficulty with "as_a", since that requires the type name, not the shorthand pointer.... so you have something like gimple_call call = as_a <gimple_statement_call> blah(). I think as the changes to use the gimple_call type are pushed through all the callers and callee's, the requirement of as_a and the long name being ugly begins to rapidly disappear... it'll only exist in the core creation routines and no one will usually see it. So I don't *think* this is an issue... but it is an ugly transition if its only partially done. And eventually we can pull the accessor routines and others into the class itself: gimple_call call; call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs); call->set_lhs (atree); Which results in a similar feel to the new gimple_type, gimple_decl, etc. classes with my upcoming tree wrappers. Changing gimple statements to behave something like this is actually mentioned in the plan, but out in the future once trees have been taken care of. I would also plan to create instances for each of the gimple statements that don't have them now, like gimple_statement_assign. Its lumped in as a general GSS_WITH_MEM_OPS, so there is no gimple_statement_assign class/struct to use. It would really be nice to use the DEFGSCODE macro and gimple.def to make this happen automagically somehow... Its tantalizingly close now I think, especially combined with the info in gsstruct.def... Although if we are moving to proper classes eventually its probably better to explicitly write the required class for a statement kind. That all said, this change enables that work to proceed if someone wants to do it. My question is: Is anyone going to do it, and if so, who and when? :-) > > Again, as noted in the earlier patch series, the names of the structs > are rather verbose. I would prefer to also rename them all to eliminate > the "_statement" component: > "gimple_statement_base" -> "gimple_base" > "gimple_statement_phi" -> "gimple_phi" > "gimple_statement_omp" -> "gimple_omp" > etc, but I didn't do this to mimimize the patch size. But if the core > maintainers are up for that, I can redo the patch series with that > change also, or do that as a followup. As mentioned, I'd rather see the short names be typedefs for pointers to the long names since we're typically using the pointers. Other than stomping on the same bits at the moment (less so once gimple-stmt.[ch] is split out), these changes are completely orthogonal, but in line with with my direction. I think It should be done sooner or later.... My preference is to also see the follow up work carried out as well. Or at least a plan for it. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-01 21:36 ` Andrew MacLeod @ 2013-11-01 21:41 ` Jakub Jelinek 2013-11-01 21:47 ` Andrew MacLeod 2013-11-04 18:23 ` Jeff Law 2013-11-01 22:43 ` David Malcolm ` (2 subsequent siblings) 3 siblings, 2 replies; 116+ messages in thread From: Jakub Jelinek @ 2013-11-01 21:41 UTC (permalink / raw) To: Andrew MacLeod; +Cc: David Malcolm, gcc-patches On Fri, Nov 01, 2013 at 05:36:34PM -0400, Andrew MacLeod wrote: > static inline void > ! gimple_call_set_lhs (gimple gs, tree lhs) > { > - GIMPLE_CHECK (gs, GIMPLE_CALL); > gimple_set_op (gs, 0, lhs); > to > static inline void > ! gimple_call_set_lhs (gimple_statement_call *gs, tree lhs) > { > gimple_set_op (gs, 0, lhs); > > > but then every location that calls it needs an appropriate change: > > ! gimple call; > ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, > alias), vargs); > gimple_call_set_lhs (call, atree); > > --- 1518,1524 ---- > > ! gimple_statement_call *call; > ! call = as_a<gimple_statement_call> (gimple_build_call_vec > (build_fold_addr_expr_loc (0, alias), vargs)); > gimple_call_set_lhs (call, atree); > > And in fact there is a ripple effect to then change > gimple_build_call_vec to simply return a gimple_statement_call *... > Then this doesn't look as ugly either... > > ! gimple_statement_call *call; > ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, > alias), vargs); > gimple_call_set_lhs (call, atree); > > that is looking much better :-) Do you seriously think this is an improvement? The cost of changing the --enable-checking=yes cost to compile time checking in either cases sounds way too high to me. Please don't. Jakub ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-01 21:41 ` Jakub Jelinek @ 2013-11-01 21:47 ` Andrew MacLeod 2013-11-01 21:57 ` Jakub Jelinek 2013-11-04 18:23 ` Jeff Law 1 sibling, 1 reply; 116+ messages in thread From: Andrew MacLeod @ 2013-11-01 21:47 UTC (permalink / raw) To: Jakub Jelinek; +Cc: David Malcolm, gcc-patches On 11/01/2013 05:41 PM, Jakub Jelinek wrote: > On Fri, Nov 01, 2013 at 05:36:34PM -0400, Andrew MacLeod wrote: >> static inline void >> ! gimple_call_set_lhs (gimple gs, tree lhs) >> { >> - GIMPLE_CHECK (gs, GIMPLE_CALL); >> gimple_set_op (gs, 0, lhs); >> to >> static inline void >> ! gimple_call_set_lhs (gimple_statement_call *gs, tree lhs) >> { >> gimple_set_op (gs, 0, lhs); >> >> >> but then every location that calls it needs an appropriate change: >> >> ! gimple call; >> ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, >> alias), vargs); >> gimple_call_set_lhs (call, atree); >> >> --- 1518,1524 ---- >> >> ! gimple_statement_call *call; >> ! call = as_a<gimple_statement_call> (gimple_build_call_vec >> (build_fold_addr_expr_loc (0, alias), vargs)); >> gimple_call_set_lhs (call, atree); >> >> And in fact there is a ripple effect to then change >> gimple_build_call_vec to simply return a gimple_statement_call *... >> Then this doesn't look as ugly either... >> >> ! gimple_statement_call *call; >> ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, >> alias), vargs); >> gimple_call_set_lhs (call, atree); >> >> that is looking much better :-) > Do you seriously think this is an improvement? The cost of changing > the --enable-checking=yes cost to compile time checking in either > cases sounds way too high to me. Please don't. What checking? There ought to be no checking at all in this example... gimple_build_call_vec returns a gimple_call, and gimple_call_set_lhs() doesn't have to check anything because it only accepts gimple_call's.. so there is no checking other than the usual "does my parameter match" that the compiler has to do... What extra are you expecting? Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-01 21:47 ` Andrew MacLeod @ 2013-11-01 21:57 ` Jakub Jelinek 2013-11-01 22:58 ` David Malcolm 2013-11-04 14:00 ` Andrew MacLeod 0 siblings, 2 replies; 116+ messages in thread From: Jakub Jelinek @ 2013-11-01 21:57 UTC (permalink / raw) To: Andrew MacLeod; +Cc: David Malcolm, gcc-patches On Fri, Nov 01, 2013 at 05:47:14PM -0400, Andrew MacLeod wrote: > On 11/01/2013 05:41 PM, Jakub Jelinek wrote: > >On Fri, Nov 01, 2013 at 05:36:34PM -0400, Andrew MacLeod wrote: > >> static inline void > >>! gimple_call_set_lhs (gimple gs, tree lhs) > >> { > >>- GIMPLE_CHECK (gs, GIMPLE_CALL); The checking you are removing here. > What checking? There ought to be no checking at all in this > example... gimple_build_call_vec returns a gimple_call, and > gimple_call_set_lhs() doesn't have to check anything because it > only accepts gimple_call's.. so there is no checking other than the > usual "does my parameter match" that the compiler has to do... and want to replace it by checking of the types at compile time. The problem is that it uglifies the source too much, and, when you actually don't have a gimple_call but supposedly a base class of it, I expect you'd do as_a which is not only further uglification, but has runtime cost also for --enable-checking=release. Jakub ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-01 21:57 ` Jakub Jelinek @ 2013-11-01 22:58 ` David Malcolm 2013-11-04 13:23 ` Andrew MacLeod 2013-11-04 14:00 ` Andrew MacLeod 1 sibling, 1 reply; 116+ messages in thread From: David Malcolm @ 2013-11-01 22:58 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Andrew MacLeod, gcc-patches On Fri, 2013-11-01 at 22:57 +0100, Jakub Jelinek wrote: > On Fri, Nov 01, 2013 at 05:47:14PM -0400, Andrew MacLeod wrote: > > On 11/01/2013 05:41 PM, Jakub Jelinek wrote: > > >On Fri, Nov 01, 2013 at 05:36:34PM -0400, Andrew MacLeod wrote: > > >> static inline void > > >>! gimple_call_set_lhs (gimple gs, tree lhs) > > >> { > > >>- GIMPLE_CHECK (gs, GIMPLE_CALL); > > The checking you are removing here. > > > What checking? There ought to be no checking at all in this > > example... gimple_build_call_vec returns a gimple_call, and > > gimple_call_set_lhs() doesn't have to check anything because it > > only accepts gimple_call's.. so there is no checking other than the > > usual "does my parameter match" that the compiler has to do... > > and want to replace it by checking of the types at compile time. > The problem is that it uglifies the source too much, and, when you > actually don't have a gimple_call but supposedly a base class of it, > I expect you'd do as_a which is not only further uglification, but has > runtime cost also for --enable-checking=release. I can have a look next week at every call to gimple_call_set_lhs in the tree, and see to what extent we know at compile-time that the initial arg is indeed a call (of the ones I quickly grepped just now, most are from gimple_build_call and friends, but one was from a gimple_copy). FWIW I did some performance testing of the is_a/as_a code in the earlier version of the patch, and it didn't have a noticable runtime cost compared to the GIMPLE_CHECK in the existing code: Size of compiler executable: http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01920.html Compile times: http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00171.html Dave ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-01 22:58 ` David Malcolm @ 2013-11-04 13:23 ` Andrew MacLeod 2013-11-04 21:52 ` David Malcolm 0 siblings, 1 reply; 116+ messages in thread From: Andrew MacLeod @ 2013-11-04 13:23 UTC (permalink / raw) To: David Malcolm; +Cc: Jakub Jelinek, gcc-patches On 11/01/2013 06:58 PM, David Malcolm wrote: > On Fri, 2013-11-01 at 22:57 +0100, Jakub Jelinek wrote: >> On Fri, Nov 01, 2013 at 05:47:14PM -0400, Andrew MacLeod wrote: >>> On 11/01/2013 05:41 PM, Jakub Jelinek wrote: >>>> On Fri, Nov 01, 2013 at 05:36:34PM -0400, Andrew MacLeod wrote: >>>>> static inline void >>>>> ! gimple_call_set_lhs (gimple gs, tree lhs) >>>>> { >>>>> - GIMPLE_CHECK (gs, GIMPLE_CALL); >> The checking you are removing here. >> >>> What checking? There ought to be no checking at all in this >>> example... gimple_build_call_vec returns a gimple_call, and >>> gimple_call_set_lhs() doesn't have to check anything because it >>> only accepts gimple_call's.. so there is no checking other than the >>> usual "does my parameter match" that the compiler has to do... >> and want to replace it by checking of the types at compile time. >> The problem is that it uglifies the source too much, and, when you >> actually don't have a gimple_call but supposedly a base class of it, >> I expect you'd do as_a which is not only further uglification, but has >> runtime cost also for --enable-checking=release. > I can have a look next week at every call to gimple_call_set_lhs in the > tree, and see to what extent we know at compile-time that the initial > arg is indeed a call (of the ones I quickly grepped just now, most are > from gimple_build_call and friends, but one was from a gimple_copy). > > FWIW I did some performance testing of the is_a/as_a code in the earlier > version of the patch, and it didn't have a noticable runtime cost > compared to the GIMPLE_CHECK in the existing code: > Size of compiler executable: > http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01920.html > Compile times: > http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00171.html I actually really dislike as_a<> and is_a<>, and think code needs to be restructured rather than use them, other than possibly at the very bottom level when we're allocating memory or something like that, or some kind of emergency :-)... If we require frequent uses of those, I'd be against it, I find them quite ugly. Like I said in the other reply, no rush, I don't think any of this follow up is appropriate this late in stage 1. It would be more of an "interest" examination right now.. at least in my opinion... I suspect thinks like gimple_assign are more complex cases, but without looking its hard to tell for sure. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-04 13:23 ` Andrew MacLeod @ 2013-11-04 21:52 ` David Malcolm 2013-11-04 22:09 ` David Malcolm ` (2 more replies) 0 siblings, 3 replies; 116+ messages in thread From: David Malcolm @ 2013-11-04 21:52 UTC (permalink / raw) To: Andrew MacLeod; +Cc: Jakub Jelinek, gcc-patches [-- Attachment #1: Type: text/plain, Size: 3139 bytes --] On Mon, 2013-11-04 at 08:19 -0500, Andrew MacLeod wrote: > On 11/01/2013 06:58 PM, David Malcolm wrote: > > On Fri, 2013-11-01 at 22:57 +0100, Jakub Jelinek wrote: > >> On Fri, Nov 01, 2013 at 05:47:14PM -0400, Andrew MacLeod wrote: > >>> On 11/01/2013 05:41 PM, Jakub Jelinek wrote: > >>>> On Fri, Nov 01, 2013 at 05:36:34PM -0400, Andrew MacLeod wrote: > >>>>> static inline void > >>>>> ! gimple_call_set_lhs (gimple gs, tree lhs) > >>>>> { > >>>>> - GIMPLE_CHECK (gs, GIMPLE_CALL); > >> The checking you are removing here. > >> > >>> What checking? There ought to be no checking at all in this > >>> example... gimple_build_call_vec returns a gimple_call, and > >>> gimple_call_set_lhs() doesn't have to check anything because it > >>> only accepts gimple_call's.. so there is no checking other than the > >>> usual "does my parameter match" that the compiler has to do... > >> and want to replace it by checking of the types at compile time. > >> The problem is that it uglifies the source too much, and, when you > >> actually don't have a gimple_call but supposedly a base class of it, > >> I expect you'd do as_a which is not only further uglification, but has > >> runtime cost also for --enable-checking=release. > > I can have a look next week at every call to gimple_call_set_lhs in the > > tree, and see to what extent we know at compile-time that the initial > > arg is indeed a call (of the ones I quickly grepped just now, most are > > from gimple_build_call and friends, but one was from a gimple_copy). > > > > FWIW I did some performance testing of the is_a/as_a code in the earlier > > version of the patch, and it didn't have a noticable runtime cost > > compared to the GIMPLE_CHECK in the existing code: > > Size of compiler executable: > > http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01920.html > > Compile times: > > http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00171.html > I actually really dislike as_a<> and is_a<>, and think code needs to be > restructured rather than use them, other than possibly at the very > bottom level when we're allocating memory or something like that, or > some kind of emergency :-)... If we require frequent uses of those, > I'd be against it, I find them quite ugly. > > Like I said in the other reply, no rush, I don't think any of this > follow up is appropriate this late in stage 1. It would be more of an > "interest" examination right now.. at least in my opinion... I suspect > thinks like gimple_assign are more complex cases, but without looking > its hard to tell for sure. I tried converting gimple_call_set_lhs to accept a gimple_call, rather than a gimple, and excitingly, it was easiest to also convert cgraph_edge's call_stmt to also be a gimple_call, rather than just a gimple. Am attaching a patch (on top of the patch series being discussed) which adds this compile-time typesafety; bootstrap is in-progress. IMHO very little use of is-a.h was needed (5 instances of as_a, and 3 of dyn_cast; no use of is_a). I'm also attaching a followup patch which eliminates gimple_call_set_lhs in favor of a method of gimple_statement_call. [-- Attachment #2: use-gimple_call-subclass.patch --] [-- Type: text/x-patch, Size: 65895 bytes --] commit ea57d6c7d3920cf27b23b7e978194a69be5f0071 Author: David Malcolm <dmalcolm@redhat.com> Date: Mon Nov 4 15:22:45 2013 -0500 FIXME: gimple_call_set_lhs (without methods) diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 4a4e9ac..6156993 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -764,7 +764,7 @@ cgraph_edge (struct cgraph_node *node, gimple call_stmt) edge, then update all components. */ void -cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt, +cgraph_set_call_stmt (struct cgraph_edge *e, gimple_call new_stmt, bool update_speculative) { tree decl; @@ -817,7 +817,7 @@ cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt, static struct cgraph_edge * cgraph_create_edge_1 (struct cgraph_node *caller, struct cgraph_node *callee, - gimple call_stmt, gcov_type count, int freq, + gimple_call call_stmt, gcov_type count, int freq, bool indir_unknown_callee) { struct cgraph_edge *edge; @@ -889,7 +889,7 @@ cgraph_create_edge_1 (struct cgraph_node *caller, struct cgraph_node *callee, struct cgraph_edge * cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee, - gimple call_stmt, gcov_type count, int freq) + gimple_call call_stmt, gcov_type count, int freq) { struct cgraph_edge *edge = cgraph_create_edge_1 (caller, callee, call_stmt, count, freq, false); @@ -925,7 +925,7 @@ cgraph_allocate_init_indirect_info (void) PARAM_INDEX. */ struct cgraph_edge * -cgraph_create_indirect_edge (struct cgraph_node *caller, gimple call_stmt, +cgraph_create_indirect_edge (struct cgraph_node *caller, gimple_call call_stmt, int ecf_flags, gcov_type count, int freq) { @@ -1298,7 +1298,7 @@ gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e) { tree decl = gimple_call_fndecl (e->call_stmt); - gimple new_stmt; + gimple_call new_stmt; gimple_stmt_iterator gsi; #ifdef ENABLE_CHECKING struct cgraph_node *node; @@ -1307,7 +1307,6 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e) if (e->speculative) { struct cgraph_edge *e2; - gimple new_stmt; struct ipa_ref *ref; cgraph_speculative_call_info (e, e, e2, ref); @@ -1459,7 +1458,7 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e) static void cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node, gimple old_stmt, tree old_call, - gimple new_stmt) + gimple_call new_stmt) { tree new_call = (new_stmt && is_gimple_call (new_stmt)) ? gimple_call_fndecl (new_stmt) : 0; @@ -1526,7 +1525,8 @@ cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node, of OLD_STMT before it was updated (updating can happen inplace). */ void -cgraph_update_edges_for_call_stmt (gimple old_stmt, tree old_decl, gimple new_stmt) +cgraph_update_edges_for_call_stmt (gimple old_stmt, tree old_decl, + gimple_call new_stmt) { struct cgraph_node *orig = cgraph_get_node (cfun->decl); struct cgraph_node *node; diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 9171a79..9fab47b 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -458,7 +458,7 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgrap struct cgraph_edge *next_caller; struct cgraph_edge *prev_callee; struct cgraph_edge *next_callee; - gimple call_stmt; + gimple_call call_stmt; /* Additional information about an indirect call. Not cleared when an edge becomes direct. */ struct cgraph_indirect_call_info *indirect_info; @@ -626,8 +626,9 @@ void release_function_body (tree); void cgraph_node_remove_callees (struct cgraph_node *node); struct cgraph_edge *cgraph_create_edge (struct cgraph_node *, struct cgraph_node *, - gimple, gcov_type, int); -struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, gimple, + gimple_call, gcov_type, int); +struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, + gimple_call, int, gcov_type, int); struct cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void); struct cgraph_node * cgraph_create_node (tree); @@ -639,8 +640,8 @@ struct cgraph_node * cgraph_add_thunk (struct cgraph_node *, tree, tree, bool, H HOST_WIDE_INT, tree, tree); struct cgraph_node *cgraph_node_for_asm (tree); struct cgraph_edge *cgraph_edge (struct cgraph_node *, gimple); -void cgraph_set_call_stmt (struct cgraph_edge *, gimple, bool update_speculative = true); -void cgraph_update_edges_for_call_stmt (gimple, tree, gimple); +void cgraph_set_call_stmt (struct cgraph_edge *, gimple_call, bool update_speculative = true); +void cgraph_update_edges_for_call_stmt (gimple, tree, gimple_call); struct cgraph_local_info *cgraph_local_info (tree); struct cgraph_global_info *cgraph_global_info (tree); struct cgraph_rtl_info *cgraph_rtl_info (tree); @@ -748,7 +749,7 @@ bool expand_thunk (struct cgraph_node *, bool); /* In cgraphclones.c */ struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *, - struct cgraph_node *, gimple, + struct cgraph_node *, gimple_call, unsigned, gcov_type, int, bool); struct cgraph_node * cgraph_clone_node (struct cgraph_node *, tree, gcov_type, int, bool, vec<cgraph_edge_p>, @@ -761,11 +762,11 @@ struct cgraph_node * cgraph_create_virtual_clone (struct cgraph_node *old_node, const char *clone_name); struct cgraph_node *cgraph_find_replacement_node (struct cgraph_node *); bool cgraph_remove_node_and_inline_clones (struct cgraph_node *, struct cgraph_node *); -void cgraph_set_call_stmt_including_clones (struct cgraph_node *, gimple, gimple, +void cgraph_set_call_stmt_including_clones (struct cgraph_node *, gimple, gimple_call, bool update_speculative = true); void cgraph_create_edge_including_clones (struct cgraph_node *, struct cgraph_node *, - gimple, gimple, gcov_type, int, + gimple, gimple_call, gcov_type, int, cgraph_inline_failed_t); void cgraph_materialize_all_clones (void); struct cgraph_node * cgraph_copy_node_for_versioning (struct cgraph_node *, diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index 1490cb7..b5f459d 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -319,16 +319,16 @@ build_cgraph_edges (void) if (is_gimple_debug (stmt)) continue; - if (is_gimple_call (stmt)) + if (gimple_call call_stmt = dyn_cast<gimple_statement_call> (stmt)) { int freq = compute_call_stmt_bb_frequency (current_function_decl, bb); decl = gimple_call_fndecl (stmt); if (decl) cgraph_create_edge (node, cgraph_get_create_node (decl), - stmt, bb->count, freq); + call_stmt, bb->count, freq); else - cgraph_create_indirect_edge (node, stmt, + cgraph_create_indirect_edge (node, call_stmt, gimple_call_flags (stmt), bb->count, freq); } @@ -448,16 +448,16 @@ rebuild_cgraph_edges (void) gimple stmt = gsi_stmt (gsi); tree decl; - if (is_gimple_call (stmt)) + if (gimple_call call_stmt = dyn_cast<gimple_statement_call> (stmt)) { int freq = compute_call_stmt_bb_frequency (current_function_decl, bb); decl = gimple_call_fndecl (stmt); if (decl) - cgraph_create_edge (node, cgraph_get_create_node (decl), stmt, + cgraph_create_edge (node, cgraph_get_create_node (decl), call_stmt, bb->count, freq); else - cgraph_create_indirect_edge (node, stmt, + cgraph_create_indirect_edge (node, call_stmt, gimple_call_flags (stmt), bb->count, freq); } diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index 373f501..e607e27 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -98,8 +98,8 @@ along with GCC; see the file COPYING3. If not see /* Create clone of E in the node N represented by CALL_EXPR the callgraph. */ struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n, - gimple call_stmt, unsigned stmt_uid, gcov_type count_scale, - int freq_scale, bool update_original) + gimple_call call_stmt, unsigned stmt_uid, + gcov_type count_scale, int freq_scale, bool update_original) { struct cgraph_edge *new_edge; gcov_type count = apply_probability (e->count, count_scale); @@ -488,7 +488,7 @@ cgraph_find_replacement_node (struct cgraph_node *node) void cgraph_set_call_stmt_including_clones (struct cgraph_node *orig, - gimple old_stmt, gimple new_stmt, + gimple old_stmt, gimple_call new_stmt, bool update_speculative) { struct cgraph_node *node; @@ -545,7 +545,7 @@ void cgraph_create_edge_including_clones (struct cgraph_node *orig, struct cgraph_node *callee, gimple old_stmt, - gimple stmt, gcov_type count, + gimple_call stmt, gcov_type count, int freq, cgraph_inline_failed_t reason) { diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 39fb142..a9ab226 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1519,7 +1519,7 @@ expand_thunk (struct cgraph_node *node, bool output_asm_thunks) tree restmp = NULL; vec<tree> vargs; - gimple call; + gimple_call call; gimple ret; if (in_lto_p) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 3131efd..b76479c 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -29419,7 +29419,7 @@ add_condition_to_bb (tree function_decl, tree version_decl, gimple return_stmt; tree convert_expr, result_var; gimple convert_stmt; - gimple call_cond_stmt; + gimple_call call_cond_stmt; gimple if_else_stmt; basic_block bb1, bb2, bb3; diff --git a/gcc/coretypes.h b/gcc/coretypes.h index 5d60240..5a5cfbb 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -66,6 +66,9 @@ typedef const struct gimple_statement_base *const_gimple; typedef gimple gimple_seq; struct gimple_stmt_iterator_d; typedef struct gimple_stmt_iterator_d gimple_stmt_iterator; +/* FWIW I'd rather simply have the class be called "gimple_call", and + make the pointerness be explicit rather than implicit. */ +typedef struct gimple_statement_call *gimple_call; union section; typedef union section section; struct gcc_options; diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index d527d86..b24961b 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -142,6 +142,7 @@ lower_function_body (void) if (data.calls_builtin_setjmp) { tree disp_label, disp_var, arg; + gimple_call call; /* Build 'DISP_LABEL:' and insert. */ disp_label = create_artificial_label (cfun->function_end_locus); @@ -156,11 +157,11 @@ lower_function_body (void) disp_var = create_tmp_var (ptr_type_node, "setjmpvar"); arg = build_addr (disp_label, current_function_decl); t = builtin_decl_implicit (BUILT_IN_SETJMP_DISPATCHER); - x = gimple_build_call (t, 1, arg); - gimple_call_set_lhs (x, disp_var); + call = gimple_build_call (t, 1, arg); + gimple_call_set_lhs (call, disp_var); + gsi_insert_after (&i, call, GSI_CONTINUE_LINKING); /* Build 'goto DISP_VAR;' and insert. */ - gsi_insert_after (&i, x, GSI_CONTINUE_LINKING); x = gimple_build_goto (disp_var); gsi_insert_after (&i, x, GSI_CONTINUE_LINKING); } diff --git a/gcc/gimple.c b/gcc/gimple.c index e9ef8e0..f31c935 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -200,10 +200,12 @@ gimple_call_reset_alias_info (gimple s) components of a GIMPLE_CALL statement to function FN with NARGS arguments. */ -static inline gimple +static inline gimple_call gimple_build_call_1 (tree fn, unsigned nargs) { - gimple s = gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK, nargs + 3); + gimple_call s = + static_cast<gimple_call> (gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK, + nargs + 3)); if (TREE_CODE (fn) == FUNCTION_DECL) fn = build_fold_addr_expr (fn); gimple_set_op (s, 1, fn); @@ -216,12 +218,12 @@ gimple_build_call_1 (tree fn, unsigned nargs) /* Build a GIMPLE_CALL statement to function FN with the arguments specified in vector ARGS. */ -gimple +gimple_call gimple_build_call_vec (tree fn, vec<tree> args) { unsigned i; unsigned nargs = args.length (); - gimple call = gimple_build_call_1 (fn, nargs); + gimple_call call = gimple_build_call_1 (fn, nargs); for (i = 0; i < nargs; i++) gimple_call_set_arg (call, i, args[i]); @@ -233,11 +235,11 @@ gimple_build_call_vec (tree fn, vec<tree> args) /* Build a GIMPLE_CALL statement to function FN. NARGS is the number of arguments. The ... are the arguments. */ -gimple +gimple_call gimple_build_call (tree fn, unsigned nargs, ...) { va_list ap; - gimple call; + gimple_call call; unsigned i; gcc_assert (TREE_CODE (fn) == FUNCTION_DECL || is_gimple_call_addr (fn)); @@ -256,10 +258,10 @@ gimple_build_call (tree fn, unsigned nargs, ...) /* Build a GIMPLE_CALL statement to function FN. NARGS is the number of arguments. AP contains the arguments. */ -gimple +gimple_call gimple_build_call_valist (tree fn, unsigned nargs, va_list ap) { - gimple call; + gimple_call call; unsigned i; gcc_assert (TREE_CODE (fn) == FUNCTION_DECL || is_gimple_call_addr (fn)); @@ -277,10 +279,12 @@ gimple_build_call_valist (tree fn, unsigned nargs, va_list ap) Build the basic components of a GIMPLE_CALL statement to internal function FN with NARGS arguments. */ -static inline gimple +static inline gimple_call gimple_build_call_internal_1 (enum internal_fn fn, unsigned nargs) { - gimple s = gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK, nargs + 3); + gimple_call s = + static_cast<gimple_call> (gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK, + nargs + 3)); s->subcode |= GF_CALL_INTERNAL; gimple_call_set_internal_fn (s, fn); gimple_call_reset_alias_info (s); @@ -291,11 +295,11 @@ gimple_build_call_internal_1 (enum internal_fn fn, unsigned nargs) /* Build a GIMPLE_CALL statement to internal function FN. NARGS is the number of arguments. The ... are the arguments. */ -gimple +gimple_call gimple_build_call_internal (enum internal_fn fn, unsigned nargs, ...) { va_list ap; - gimple call; + gimple_call call; unsigned i; call = gimple_build_call_internal_1 (fn, nargs); @@ -311,11 +315,11 @@ gimple_build_call_internal (enum internal_fn fn, unsigned nargs, ...) /* Build a GIMPLE_CALL statement to internal function FN with the arguments specified in vector ARGS. */ -gimple +gimple_call gimple_build_call_internal_vec (enum internal_fn fn, vec<tree> args) { unsigned i, nargs; - gimple call; + gimple_call call; nargs = args.length (); call = gimple_build_call_internal_1 (fn, nargs); @@ -330,11 +334,11 @@ gimple_build_call_internal_vec (enum internal_fn fn, vec<tree> args) assumed to be in GIMPLE form already. Minimal checking is done of this fact. */ -gimple +gimple_call gimple_build_call_from_tree (tree t) { unsigned i, nargs; - gimple call; + gimple_call call; tree fndecl = get_callee_fndecl (t); gcc_assert (TREE_CODE (t) == CALL_EXPR); @@ -2248,7 +2252,7 @@ gimple_set_lhs (gimple stmt, tree lhs) if (code == GIMPLE_ASSIGN) gimple_assign_set_lhs (stmt, lhs); else if (code == GIMPLE_CALL) - gimple_call_set_lhs (stmt, lhs); + gimple_call_set_lhs (static_cast<gimple_call> (stmt), lhs); else gcc_unreachable (); } @@ -3059,14 +3063,14 @@ canonicalize_cond_expr_cond (tree t) /* Build a GIMPLE_CALL identical to STMT but skipping the arguments in the positions marked by the set ARGS_TO_SKIP. */ -gimple +gimple_call gimple_call_copy_skip_args (gimple stmt, bitmap args_to_skip) { int i; int nargs = gimple_call_num_args (stmt); vec<tree> vargs; vargs.create (nargs); - gimple new_stmt; + gimple_call new_stmt; for (i = 0; i < nargs; i++) if (!bitmap_bit_p (args_to_skip, i)) diff --git a/gcc/gimple.h b/gcc/gimple.h index 35bfa06..1180d3e 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1055,12 +1055,12 @@ gimple gimple_build_debug_source_bind_stat (tree, tree, gimple MEM_STAT_DECL); #define gimple_build_debug_source_bind(var,val,stmt) \ gimple_build_debug_source_bind_stat ((var), (val), (stmt) MEM_STAT_INFO) -gimple gimple_build_call_vec (tree, vec<tree> ); -gimple gimple_build_call (tree, unsigned, ...); -gimple gimple_build_call_valist (tree, unsigned, va_list); -gimple gimple_build_call_internal (enum internal_fn, unsigned, ...); -gimple gimple_build_call_internal_vec (enum internal_fn, vec<tree> ); -gimple gimple_build_call_from_tree (tree); +gimple_call gimple_build_call_vec (tree, vec<tree> ); +gimple_call gimple_build_call (tree, unsigned, ...); +gimple_call gimple_build_call_valist (tree, unsigned, va_list); +gimple_call gimple_build_call_internal (enum internal_fn, unsigned, ...); +gimple_call gimple_build_call_internal_vec (enum internal_fn, vec<tree> ); +gimple_call gimple_build_call_from_tree (tree); gimple gimplify_assign (tree, tree, gimple_seq *); gimple gimple_build_cond (enum tree_code, tree, tree, tree, tree); gimple gimple_build_label (tree label); @@ -2551,9 +2551,8 @@ gimple_call_lhs_ptr (const_gimple gs) /* Set LHS to be the LHS operand of call statement GS. */ static inline void -gimple_call_set_lhs (gimple gs, tree lhs) +gimple_call_set_lhs (gimple_call gs, tree lhs) { - GIMPLE_CHECK (gs, GIMPLE_CALL); gimple_set_op (gs, 0, lhs); if (lhs && TREE_CODE (lhs) == SSA_NAME) SSA_NAME_DEF_STMT (lhs) = gs; @@ -6134,7 +6133,7 @@ basic_block gsi_insert_on_edge_immediate (edge, gimple); basic_block gsi_insert_seq_on_edge_immediate (edge, gimple_seq); void gsi_commit_one_edge_insert (edge, basic_block *); void gsi_commit_edge_inserts (void); -gimple gimple_call_copy_skip_args (gimple, bitmap); +gimple_call gimple_call_copy_skip_args (gimple, bitmap); /* In gimplify.c. */ tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree); diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 5869441..e2c81b9 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1160,7 +1160,7 @@ voidify_wrapper_expr (tree wrapper, tree temp) a temporary through which they communicate. */ static void -build_stack_save_restore (gimple *save, gimple *restore) +build_stack_save_restore (gimple_call *save, gimple_call *restore) { tree tmp_var; @@ -1183,7 +1183,7 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) tree t; gimple gimple_bind; gimple_seq body, cleanup; - gimple stack_save; + gimple_call stack_save; tree temp = voidify_wrapper_expr (bind_expr, NULL); @@ -1233,7 +1233,7 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) stack_save = NULL; if (gimplify_ctxp->save_stack) { - gimple stack_restore; + gimple_call stack_restore; /* Save stack on entry and restore it on exit. Add a try_finally block to achieve this. */ @@ -3438,7 +3438,7 @@ gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value, gimple_seq *seq_p) { tree t, to, to_ptr, from, from_ptr; - gimple gs; + gimple_call gs; location_t loc = EXPR_LOCATION (*expr_p); to = TREE_OPERAND (*expr_p, 0); @@ -3485,7 +3485,7 @@ gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value, gimple_seq *seq_p) { tree t, from, to, to_ptr; - gimple gs; + gimple_call gs; location_t loc = EXPR_LOCATION (*expr_p); /* Assert our assumptions, to abort instead of producing wrong code @@ -4876,11 +4876,12 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p)); CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0); STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p)); - assign = gimple_build_call_from_tree (*from_p); + gimple_call call = gimple_build_call_from_tree (*from_p); + assign = call; gimple_call_set_fntype (assign, TREE_TYPE (fnptrtype)); notice_special_calls (assign); if (!gimple_call_noreturn_p (assign)) - gimple_call_set_lhs (assign, *to_p); + gimple_call_set_lhs (call, *to_p); } else { @@ -7789,8 +7790,8 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, tree id = TREE_OPERAND (*expr_p, 1); tree tmp = create_tmp_var_raw (TREE_TYPE(cond), NULL); gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p)); - gimple call = gimple_build_call_internal (IFN_ANNOTATE, 2, - cond, id); + gimple_call call = gimple_build_call_internal (IFN_ANNOTATE, 2, + cond, id); gimple_call_set_lhs (call, tmp); gimplify_seq_add_stmt (pre_p, call); *expr_p = tmp; @@ -8989,7 +8990,7 @@ gimplify_function_tree (tree fndecl) gimple tf; gimple_seq cleanup = NULL, body = NULL; tree tmp_var; - gimple call; + gimple_call call; x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS); call = gimple_build_call (x, 1, integer_zero_node); diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 1ceabfa..642153d 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -3523,7 +3523,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt, struct cgraph_node *current_node = cgraph_get_node (current_function_decl); vec<tree> vargs; vec<tree, va_gc> **debug_args = NULL; - gimple new_stmt; + gimple_call new_stmt; gimple_stmt_iterator gsi, prev_gsi; tree callee_decl; int i, len; diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 849868c..915533c 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -1075,7 +1075,7 @@ split_function (struct split_point *split_point) basic_block return_bb = find_return_bb (); basic_block call_bb; gimple_stmt_iterator gsi; - gimple call; + gimple_call call; edge e; edge_iterator ei; tree retval = NULL, real_retval = NULL; diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index d4a52a7..e9e245a 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -771,7 +771,10 @@ fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple *stmts, { if (gimple_stmt_max_uid (fn) < cedge->lto_stmt_uid) fatal_error ("Cgraph edge statement index out of range"); - cedge->call_stmt = stmts[cedge->lto_stmt_uid - 1]; + gimple stmt = stmts[cedge->lto_stmt_uid - 1]; + if (stmt) + gcc_assert (stmt->code == GIMPLE_CALL); + cedge->call_stmt = static_cast<gimple_call> (stmt); if (!cedge->call_stmt) fatal_error ("Cgraph edge statement index not found"); } @@ -779,7 +782,10 @@ fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple *stmts, { if (gimple_stmt_max_uid (fn) < cedge->lto_stmt_uid) fatal_error ("Cgraph edge statement index out of range"); - cedge->call_stmt = stmts[cedge->lto_stmt_uid - 1]; + gimple stmt = stmts[cedge->lto_stmt_uid - 1]; + if (stmt) + gcc_assert (stmt->code == GIMPLE_CALL); + cedge->call_stmt = static_cast<gimple_call> (stmt); if (!cedge->call_stmt) fatal_error ("Cgraph edge statement index not found"); } diff --git a/gcc/omp-low.c b/gcc/omp-low.c index a5b9210..dcececc 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -2670,7 +2670,7 @@ build_omp_barrier (tree lhs) { tree fndecl = builtin_decl_explicit (lhs ? BUILT_IN_GOMP_BARRIER_CANCEL : BUILT_IN_GOMP_BARRIER); - gimple g = gimple_build_call (fndecl, 0); + gimple_call g = gimple_build_call (fndecl, 0); if (lhs) gimple_call_set_lhs (g, lhs); return g; @@ -3099,7 +3099,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx)) { - gimple stmt; + gimple_call stmt; tree tmp, atmp; ptr = DECL_VALUE_EXPR (new_var); @@ -3519,27 +3519,28 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, /* Don't want uninit warnings on simduid, it is always uninitialized, but we use it not for the value, but for the DECL_UID only. */ TREE_NO_WARNING (uid) = 1; - gimple g + gimple_call call = gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 1, uid); - gimple_call_set_lhs (g, lane); + gimple_call_set_lhs (call, lane); gimple_stmt_iterator gsi = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt)); - gsi_insert_before_without_update (&gsi, g, GSI_SAME_STMT); + gsi_insert_before_without_update (&gsi, call, GSI_SAME_STMT); c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_); OMP_CLAUSE__SIMDUID__DECL (c) = uid; OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt); gimple_omp_for_set_clauses (ctx->stmt, c); - g = gimple_build_assign_with_ops (INTEGER_CST, lane, - build_int_cst (unsigned_type_node, 0), - NULL_TREE); + gimple g = + gimple_build_assign_with_ops (INTEGER_CST, lane, + build_int_cst (unsigned_type_node, 0), + NULL_TREE); gimple_seq_add_stmt (ilist, g); for (int i = 0; i < 2; i++) if (llist[i]) { tree vf = create_tmp_var (unsigned_type_node, NULL); - g = gimple_build_call_internal (IFN_GOMP_SIMD_VF, 1, uid); - gimple_call_set_lhs (g, vf); + call = gimple_build_call_internal (IFN_GOMP_SIMD_VF, 1, uid); + gimple_call_set_lhs (call, vf); gimple_seq *seq = i == 0 ? ilist : dlist; - gimple_seq_add_stmt (seq, g); + gimple_seq_add_stmt (seq, call); tree t = build_int_cst (unsigned_type_node, 0); g = gimple_build_assign_with_ops (INTEGER_CST, idx, t, NULL_TREE); gimple_seq_add_stmt (seq, g); @@ -3693,7 +3694,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list, if (lastlane == NULL) { lastlane = create_tmp_var (unsigned_type_node, NULL); - gimple g + gimple_call g = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE, 2, simduid, TREE_OPERAND (val, 1)); @@ -5544,10 +5545,10 @@ expand_omp_for_generic (struct omp_region *region, t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_CANCEL); else t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END); - stmt = gimple_build_call (t, 0); + gimple_call call = gimple_build_call (t, 0); if (gimple_omp_return_lhs (gsi_stmt (gsi))) - gimple_call_set_lhs (stmt, gimple_omp_return_lhs (gsi_stmt (gsi))); - gsi_insert_after (&gsi, stmt, GSI_SAME_STMT); + gimple_call_set_lhs (call, gimple_omp_return_lhs (gsi_stmt (gsi))); + gsi_insert_after (&gsi, call, GSI_SAME_STMT); gsi_remove (&gsi, true); /* Connect the new blocks. */ @@ -6867,6 +6868,7 @@ expand_omp_sections (struct omp_region *region) basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb; gimple_stmt_iterator si, switch_si; gimple sections_stmt, stmt, cont; + gimple_call call; edge_iterator ei; edge e; struct omp_region *inner; @@ -6929,16 +6931,16 @@ expand_omp_sections (struct omp_region *region) call GOMP_sections_start. */ t = build_int_cst (unsigned_type_node, len - 1); u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START); - stmt = gimple_build_call (u, 1, t); + call = gimple_build_call (u, 1, t); } else { /* Otherwise, call GOMP_sections_next. */ u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT); - stmt = gimple_build_call (u, 0); + call = gimple_build_call (u, 0); } - gimple_call_set_lhs (stmt, vin); - gsi_insert_after (&si, stmt, GSI_SAME_STMT); + gimple_call_set_lhs (call, vin); + gsi_insert_after (&si, call, GSI_SAME_STMT); gsi_remove (&si, true); /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in @@ -7026,9 +7028,9 @@ expand_omp_sections (struct omp_region *region) gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE); bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT); - stmt = gimple_build_call (bfn_decl, 0); - gimple_call_set_lhs (stmt, vnext); - gsi_insert_after (&si, stmt, GSI_SAME_STMT); + call = gimple_build_call (bfn_decl, 0); + gimple_call_set_lhs (call, vnext); + gsi_insert_after (&si, call, GSI_SAME_STMT); gsi_remove (&si, true); single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU; @@ -7042,10 +7044,10 @@ expand_omp_sections (struct omp_region *region) t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_CANCEL); else t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END); - stmt = gimple_build_call (t, 0); + call = gimple_build_call (t, 0); if (gimple_omp_return_lhs (gsi_stmt (si))) - gimple_call_set_lhs (stmt, gimple_omp_return_lhs (gsi_stmt (si))); - gsi_insert_after (&si, stmt, GSI_SAME_STMT); + gimple_call_set_lhs (call, gimple_omp_return_lhs (gsi_stmt (si))); + gsi_insert_after (&si, call, GSI_SAME_STMT); gsi_remove (&si, true); set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb); @@ -8413,7 +8415,8 @@ lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p) location_t loc = gimple_location (single_stmt); tree tlabel = create_artificial_label (loc); tree flabel = create_artificial_label (loc); - gimple call, cond; + gimple_call call; + gimple cond; tree lhs, decl; decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START); @@ -9863,6 +9866,7 @@ static void lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx) { gimple stmt = gsi_stmt (*gsi_p); + gimple_call call; struct walk_stmt_info wi; if (gimple_has_location (stmt)) @@ -9971,6 +9975,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx) break; case GIMPLE_CALL: tree fndecl; + call = static_cast<gimple_call> (stmt); fndecl = gimple_call_fndecl (stmt); if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) @@ -10005,7 +10010,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx) gimple_call_set_fndecl (stmt, fndecl); gimple_call_set_fntype (stmt, TREE_TYPE (fndecl)); } - gimple_call_set_lhs (stmt, lhs); + gimple_call_set_lhs (call, lhs); tree fallthru_label; fallthru_label = create_artificial_label (UNKNOWN_LOCATION); gimple g; diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index d74455d2..0358b26 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -1614,11 +1614,12 @@ lower_transaction (gimple_stmt_iterator *gsi, struct walk_stmt_info *wi) n_seq = gimple_seq_alloc_with_stmt (g); e_seq = NULL; - g = gimple_build_call (builtin_decl_explicit (BUILT_IN_EH_POINTER), - 1, integer_zero_node); + gimple_call call = + gimple_build_call (builtin_decl_explicit (BUILT_IN_EH_POINTER), + 1, integer_zero_node); ptr = create_tmp_var (ptr_type_node, NULL); - gimple_call_set_lhs (g, ptr); - gimple_seq_add_stmt (&e_seq, g); + gimple_call_set_lhs (call, ptr); + gimple_seq_add_stmt (&e_seq, call); g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_COMMIT_EH), 1, ptr); @@ -2065,12 +2066,12 @@ transaction_subcode_ior (struct tm_region *region, unsigned flags) LOC is the location to use for the new statement(s). */ -static gimple +static gimple_call build_tm_load (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi) { enum built_in_function code = END_BUILTINS; tree t, type = TREE_TYPE (rhs), decl; - gimple gcall; + gimple_call gcall; if (type == float_type_node) code = BUILT_IN_TM_LOAD_FLOAT; @@ -2310,6 +2311,7 @@ expand_call_tm (struct tm_region *region, gimple_stmt_iterator *gsi) { gimple stmt = gsi_stmt (*gsi); + gimple_call call_stmt = as_a<gimple_statement_call> (stmt); tree lhs = gimple_call_lhs (stmt); tree fn_decl; struct cgraph_node *node; @@ -2412,7 +2414,7 @@ expand_call_tm (struct tm_region *region, } } - gimple_call_set_lhs (stmt, tmp); + gimple_call_set_lhs (call_stmt, tmp); update_stmt (stmt); stmt = gimple_build_assign (lhs, tmp); gimple_set_location (stmt, loc); @@ -2698,7 +2700,7 @@ expand_transaction (struct tm_region *region, void *data ATTRIBUTE_UNUSED) if (subcode & GTMA_IS_OUTER) region->original_transaction_was_outer = true; tree t = build_int_cst (tm_state_type, flags); - gimple call = gimple_build_call (tm_start, 1, t); + gimple_call call = gimple_build_call (tm_start, 1, t); gimple_call_set_lhs (call, tm_state); gimple_set_location (call, gimple_location (region->transaction_stmt)); @@ -4930,7 +4932,7 @@ ipa_tm_insert_irr_call (struct cgraph_node *node, struct tm_region *region, basic_block bb) { gimple_stmt_iterator gsi; - gimple g; + gimple_call g; transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE); @@ -4954,10 +4956,11 @@ ipa_tm_insert_irr_call (struct cgraph_node *node, struct tm_region *region, static bool ipa_tm_insert_gettmclone_call (struct cgraph_node *node, struct tm_region *region, - gimple_stmt_iterator *gsi, gimple stmt) + gimple_stmt_iterator *gsi, gimple_call stmt) { tree gettm_fn, ret, old_fn, callfn; - gimple g, g2; + gimple_call g; + gimple g2; bool safe; old_fn = gimple_call_fn (stmt); @@ -5050,7 +5053,7 @@ ipa_tm_transform_calls_redirect (struct cgraph_node *node, gimple_stmt_iterator *gsi, bool *need_ssa_rename_p) { - gimple stmt = gsi_stmt (*gsi); + gimple_call stmt = as_a<gimple_statement_call> (gsi_stmt (*gsi)); struct cgraph_node *new_node; struct cgraph_edge *e = cgraph_edge (node, stmt); tree fndecl = gimple_call_fndecl (stmt); diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index d705657..8d82342 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -8262,6 +8262,7 @@ execute_fixup_cfg (void) : NULL; if (decl) { + gimple_call call = static_cast<gimple_call> (stmt); int flags = gimple_call_flags (stmt); if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE)) { @@ -8276,7 +8277,7 @@ execute_fixup_cfg (void) } if (flags & ECF_NORETURN - && fixup_noreturn_call (stmt)) + && fixup_noreturn_call (call)) todo |= TODO_cleanup_cfg; } diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index c627d2c..3cd625c 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -499,7 +499,7 @@ remove_forwarder_block (basic_block bb) and remove LHS. Return true if something changed. */ bool -fixup_noreturn_call (gimple stmt) +fixup_noreturn_call (gimple_call stmt) { basic_block bb = gimple_bb (stmt); bool changed = false; @@ -582,7 +582,7 @@ split_bbs_on_noreturn_calls (void) || !gimple_call_noreturn_p (stmt)) continue; - changed |= fixup_noreturn_call (stmt); + changed |= fixup_noreturn_call (static_cast<gimple_call> (stmt)); } return changed; diff --git a/gcc/tree-cfgcleanup.h b/gcc/tree-cfgcleanup.h index 6bd3c39..b7e0dde 100644 --- a/gcc/tree-cfgcleanup.h +++ b/gcc/tree-cfgcleanup.h @@ -23,6 +23,6 @@ along with GCC; see the file COPYING3. If not see /* In tree-cfgcleanup.c */ extern bitmap cfgcleanup_altered_bbs; extern bool cleanup_tree_cfg (void); -extern bool fixup_noreturn_call (gimple stmt); +extern bool fixup_noreturn_call (gimple_call stmt); #endif /* GCC_TREE_CFGCLEANUP_H */ diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c index 6439402..aee1e26 100644 --- a/gcc/tree-complex.c +++ b/gcc/tree-complex.c @@ -936,7 +936,8 @@ expand_complex_libcall (gimple_stmt_iterator *gsi, tree ar, tree ai, enum machine_mode mode; enum built_in_function bcode; tree fn, type, lhs; - gimple old_stmt, stmt; + gimple old_stmt; + gimple_call stmt; old_stmt = gsi_stmt (*gsi); lhs = gimple_assign_lhs (old_stmt); diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index a91542d..3347b7b 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -3204,11 +3204,11 @@ lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map) { fn = builtin_decl_implicit (BUILT_IN_EH_POINTER); src_nr = build_int_cst (integer_type_node, src_r->index); - x = gimple_build_call (fn, 1, src_nr); + gimple_call call = gimple_build_call (fn, 1, src_nr); var = create_tmp_var (ptr_type_node, NULL); - var = make_ssa_name (var, x); - gimple_call_set_lhs (x, var); - gsi_insert_before (&gsi, x, GSI_SAME_STMT); + var = make_ssa_name (var, call); + gimple_call_set_lhs (call, var); + gsi_insert_before (&gsi, call, GSI_SAME_STMT); fn = builtin_decl_implicit (BUILT_IN_UNWIND_RESUME); x = gimple_build_call (fn, 1, var); @@ -3578,12 +3578,13 @@ lower_eh_dispatch (basic_block src, gimple stmt) else { fn = builtin_decl_implicit (BUILT_IN_EH_FILTER); - x = gimple_build_call (fn, 1, build_int_cst (integer_type_node, - region_nr)); + gimple_call call = + gimple_build_call (fn, 1, build_int_cst (integer_type_node, + region_nr)); filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL); - filter = make_ssa_name (filter, x); - gimple_call_set_lhs (x, filter); - gsi_insert_before (&gsi, x, GSI_SAME_STMT); + filter = make_ssa_name (filter, call); + gimple_call_set_lhs (call, filter); + gsi_insert_before (&gsi, call, GSI_SAME_STMT); /* Turn the default label into a default case. */ default_label = build_case_label (NULL, NULL, default_label); @@ -3604,12 +3605,13 @@ lower_eh_dispatch (basic_block src, gimple stmt) edge f_e = FALLTHRU_EDGE (src); fn = builtin_decl_implicit (BUILT_IN_EH_FILTER); - x = gimple_build_call (fn, 1, build_int_cst (integer_type_node, + gimple_call call + = gimple_build_call (fn, 1, build_int_cst (integer_type_node, region_nr)); filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL); - filter = make_ssa_name (filter, x); - gimple_call_set_lhs (x, filter); - gsi_insert_before (&gsi, x, GSI_SAME_STMT); + filter = make_ssa_name (filter, call); + gimple_call_set_lhs (call, filter); + gsi_insert_before (&gsi, call, GSI_SAME_STMT); r->u.allowed.label = NULL; x = gimple_build_cond (EQ_EXPR, filter, diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c index b5ca407..7b17a68 100644 --- a/gcc/tree-emutls.c +++ b/gcc/tree-emutls.c @@ -427,7 +427,7 @@ gen_emutls_addr (tree decl, struct lower_emutls_data *d) { struct varpool_node *cvar; tree cdecl; - gimple x; + gimple_call x; cvar = control_vars[index]; cdecl = cvar->decl; diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index a600d3c..83a3e27 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1648,7 +1648,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, /* __builtin_va_arg_pack () should be replaced by all arguments corresponding to ... in the caller. */ tree p; - gimple new_call; + gimple_call new_call; vec<tree> argarray; size_t nargs = gimple_call_num_args (id->gimple_call); size_t n; @@ -1725,7 +1725,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, /* We're duplicating a CALL_EXPR. Find any corresponding callgraph edges and update or duplicate them. */ - if (is_gimple_call (stmt)) + if (gimple_call call_stmt = dyn_cast<gimple_statement_call> (stmt)) { struct cgraph_edge *edge; int flags; @@ -1739,7 +1739,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, int edge_freq = edge->frequency; int new_freq; struct cgraph_edge *old_edge = edge; - edge = cgraph_clone_edge (edge, id->dst_node, stmt, + edge = cgraph_clone_edge (edge, id->dst_node, call_stmt, gimple_uid (stmt), REG_BR_PROB_BASE, CGRAPH_FREQ_BASE, true); @@ -1758,7 +1758,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, gcc_assert (!edge->indirect_unknown_callee); cgraph_speculative_call_info (old_edge, direct, indirect, ref); - indirect = cgraph_clone_edge (indirect, id->dst_node, stmt, + indirect = cgraph_clone_edge (indirect, id->dst_node, call_stmt, gimple_uid (stmt), REG_BR_PROB_BASE, CGRAPH_FREQ_BASE, true); @@ -1797,14 +1797,14 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, case CB_CGE_MOVE_CLONES: cgraph_set_call_stmt_including_clones (id->dst_node, - orig_stmt, stmt); + orig_stmt, call_stmt); edge = cgraph_edge (id->dst_node, stmt); break; case CB_CGE_MOVE: edge = cgraph_edge (id->dst_node, orig_stmt); if (edge) - cgraph_set_call_stmt (edge, stmt); + cgraph_set_call_stmt (edge, call_stmt); break; default: @@ -1833,12 +1833,12 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, || !id->dst_node->definition); if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES) cgraph_create_edge_including_clones - (id->dst_node, dest, orig_stmt, stmt, bb->count, + (id->dst_node, dest, orig_stmt, call_stmt, bb->count, compute_call_stmt_bb_frequency (id->dst_node->decl, copy_basic_block), CIF_ORIGINALLY_INDIRECT_CALL); else - cgraph_create_edge (id->dst_node, dest, stmt, + cgraph_create_edge (id->dst_node, dest, call_stmt, bb->count, compute_call_stmt_bb_frequency (id->dst_node->decl, @@ -4401,7 +4401,7 @@ fold_marked_statements (int first, struct pointer_set_t *statements) gsi_prev (&i2); if (fold_stmt (&gsi)) { - gimple new_stmt; + gimple_call new_stmt; /* If a builtin at the end of a bb folded into nothing, the following loop won't work. */ if (gsi_end_p (gsi)) @@ -4416,7 +4416,7 @@ fold_marked_statements (int first, struct pointer_set_t *statements) gsi_next (&i2); while (1) { - new_stmt = gsi_stmt (i2); + new_stmt = as_a<gimple_statement_call> (gsi_stmt (i2)); update_stmt (new_stmt); cgraph_update_edges_for_call_stmt (old_stmt, old_decl, new_stmt); @@ -4451,8 +4451,14 @@ fold_marked_statements (int first, struct pointer_set_t *statements) if (is_gimple_call (old_stmt) || is_gimple_call (new_stmt)) - cgraph_update_edges_for_call_stmt (old_stmt, old_decl, - new_stmt); + { + if (new_stmt) + gcc_assert (new_stmt->code == GIMPLE_CALL); + gimple_call new_call_stmt = + static_cast<gimple_call> (new_stmt); + cgraph_update_edges_for_call_stmt (old_stmt, old_decl, + new_call_stmt); + } if (maybe_clean_or_replace_eh_stmt (old_stmt, new_stmt)) gimple_purge_dead_eh_edges (BASIC_BLOCK (first)); diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index dc63ef6..5f5dcef 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -401,7 +401,7 @@ get_chain_field (struct nesting_info *info) static tree init_tmp_var_with_call (struct nesting_info *info, gimple_stmt_iterator *gsi, - gimple call) + gimple_call call) { tree t; @@ -1919,7 +1919,7 @@ convert_tramp_reference_op (tree *tp, int *walk_subtrees, void *data) struct walk_stmt_info *wi = (struct walk_stmt_info *) data; struct nesting_info *const info = (struct nesting_info *) wi->info, *i; tree t = *tp, decl, target_context, x, builtin; - gimple call; + gimple_call call; *walk_subtrees = 0; switch (TREE_CODE (t)) diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 38da577..35c97b6 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -4476,7 +4476,7 @@ replace_removed_params_ssa_names (gimple stmt, if (is_gimple_assign (stmt)) gimple_assign_set_lhs (stmt, name); else if (is_gimple_call (stmt)) - gimple_call_set_lhs (stmt, name); + gimple_call_set_lhs (static_cast<gimple_call> (stmt), name); else gimple_phi_set_result (stmt, name); diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index 72e2fb8..3527848 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -1212,6 +1212,7 @@ eliminate_unnecessary_stmts (void) } else if (is_gimple_call (stmt)) { + gimple_call call_stmt = static_cast <gimple_call> (stmt); tree name = gimple_call_lhs (stmt); notice_special_calls (stmt); @@ -1240,7 +1241,7 @@ eliminate_unnecessary_stmts (void) fprintf (dump_file, "\n"); } - gimple_call_set_lhs (stmt, NULL_TREE); + gimple_call_set_lhs (call_stmt, NULL_TREE); maybe_clean_or_replace_eh_stmt (stmt, stmt); update_stmt (stmt); release_ssa_name (name); diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 93b8970..c0415d4 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -1651,8 +1651,9 @@ simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2) { /* If STMT1 is a mem{,p}cpy call, adjust it and remove memset call. */ + gimple_call call_stmt1 = static_cast <gimple_call> (stmt1); if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY) - gimple_call_set_lhs (stmt1, NULL_TREE); + gimple_call_set_lhs (call_stmt1, NULL_TREE); gimple_call_set_arg (stmt1, 1, new_str_cst); gimple_call_set_arg (stmt1, 2, build_int_cst (TREE_TYPE (len1), src_len)); diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 9a29411..6253c3d 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -724,6 +724,7 @@ execute_cse_sincos_1 (tree name) imm_use_iterator use_iter; tree fndecl, res, type; gimple def_stmt, use_stmt, stmt; + gimple_call call_stmt; int seen_cos = 0, seen_sin = 0, seen_cexpi = 0; vec<gimple> stmts = vNULL; basic_block top_bb = NULL; @@ -768,9 +769,9 @@ execute_cse_sincos_1 (tree name) fndecl = mathfn_built_in (type, BUILT_IN_CEXPI); if (!fndecl) return false; - stmt = gimple_build_call (fndecl, 1, name); - res = make_temp_ssa_name (TREE_TYPE (TREE_TYPE (fndecl)), stmt, "sincostmp"); - gimple_call_set_lhs (stmt, res); + call_stmt = gimple_build_call (fndecl, 1, name); + res = make_temp_ssa_name (TREE_TYPE (TREE_TYPE (fndecl)), call_stmt, "sincostmp"); + gimple_call_set_lhs (call_stmt, res); def_stmt = SSA_NAME_DEF_STMT (name); if (!SSA_NAME_IS_DEFAULT_DEF (name) @@ -778,12 +779,12 @@ execute_cse_sincos_1 (tree name) && gimple_bb (def_stmt) == top_bb) { gsi = gsi_for_stmt (def_stmt); - gsi_insert_after (&gsi, stmt, GSI_SAME_STMT); + gsi_insert_after (&gsi, call_stmt, GSI_SAME_STMT); } else { gsi = gsi_after_labels (top_bb); - gsi_insert_before (&gsi, stmt, GSI_SAME_STMT); + gsi_insert_before (&gsi, call_stmt, GSI_SAME_STMT); } sincos_stats.inserted++; @@ -1944,7 +1945,7 @@ execute_optimize_bswap (void) tree bswap_tmp; tree fndecl = NULL_TREE; int type_size; - gimple call; + gimple_call call; if (!is_gimple_assign (stmt) || gimple_assign_rhs_code (stmt) != BIT_IOR_EXPR) diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index d5bcc9c..4565de0 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -697,7 +697,7 @@ move_ssa_defining_stmt_for_defs (gimple new_stmt, gimple old_stmt) A GIMPLE_CALL STMT is being replaced with GIMPLE_CALL NEW_STMT. */ static void -finish_update_gimple_call (gimple_stmt_iterator *si_p, gimple new_stmt, +finish_update_gimple_call (gimple_stmt_iterator *si_p, gimple_call new_stmt, gimple stmt) { gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt)); @@ -718,7 +718,8 @@ bool update_gimple_call (gimple_stmt_iterator *si_p, tree fn, int nargs, ...) { va_list ap; - gimple new_stmt, stmt = gsi_stmt (*si_p); + gimple_call new_stmt; + gimple stmt = gsi_stmt (*si_p); gcc_assert (is_gimple_call (stmt)); va_start (ap, nargs); @@ -752,7 +753,7 @@ update_call_from_tree (gimple_stmt_iterator *si_p, tree expr) unsigned i; unsigned nargs = call_expr_nargs (expr); vec<tree> args = vNULL; - gimple new_stmt; + gimple_call new_stmt; if (nargs > 0) { diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 39982f1..982c6d2 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -3979,7 +3979,8 @@ attempt_builtin_powi (gimple stmt, vec<operand_entry_t> *ops) tree type = TREE_TYPE (gimple_get_lhs (stmt)); tree powi_fndecl = mathfn_built_in (type, BUILT_IN_POWI); gimple_stmt_iterator gsi = gsi_for_stmt (stmt); - gimple mul_stmt, pow_stmt; + gimple mul_stmt; + gimple_call pow_stmt; /* Nothing to do if BUILT_IN_POWI doesn't exist for this type and target. */ diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index ea73179..ad18fc1 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -412,12 +412,15 @@ get_string_length (strinfo si) if (si->stmt) { - gimple stmt = si->stmt, lenstmt; + gimple stmt = si->stmt; + gimple_call lenstmt_call; + gimple lenstmt_assign; tree callee, lhs, fn, tem; location_t loc; gimple_stmt_iterator gsi; gcc_assert (is_gimple_call (stmt)); + gimple_call call_stmt = static_cast<gimple_call> (stmt); callee = gimple_call_fndecl (stmt); gcc_assert (callee && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL); lhs = gimple_call_lhs (stmt); @@ -436,11 +439,11 @@ get_string_length (strinfo si) fn = builtin_decl_implicit (BUILT_IN_STRLEN); gcc_assert (lhs == NULL_TREE); tem = unshare_expr (gimple_call_arg (stmt, 0)); - lenstmt = gimple_build_call (fn, 1, tem); - lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (fn)), lenstmt); - gimple_call_set_lhs (lenstmt, lhs); - gimple_set_vuse (lenstmt, gimple_vuse (stmt)); - gsi_insert_before (&gsi, lenstmt, GSI_SAME_STMT); + lenstmt_call = gimple_build_call (fn, 1, tem); + lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (fn)), lenstmt_call); + gimple_call_set_lhs (lenstmt_call, lhs); + gimple_set_vuse (lenstmt_call, gimple_vuse (stmt)); + gsi_insert_before (&gsi, lenstmt_call, GSI_SAME_STMT); tem = gimple_call_arg (stmt, 0); if (!ptrofftype_p (TREE_TYPE (lhs))) { @@ -448,13 +451,13 @@ get_string_length (strinfo si) lhs = force_gimple_operand_gsi (&gsi, lhs, true, NULL_TREE, true, GSI_SAME_STMT); } - lenstmt + lenstmt_assign = gimple_build_assign_with_ops (POINTER_PLUS_EXPR, make_ssa_name (TREE_TYPE (gimple_call_arg (stmt, 0)), NULL), tem, lhs); - gsi_insert_before (&gsi, lenstmt, GSI_SAME_STMT); - gimple_call_set_arg (stmt, 0, gimple_assign_lhs (lenstmt)); + gsi_insert_before (&gsi, lenstmt_assign, GSI_SAME_STMT); + gimple_call_set_arg (stmt, 0, gimple_assign_lhs (lenstmt_assign)); lhs = NULL_TREE; /* FALLTHRU */ case BUILT_IN_STRCPY: @@ -471,7 +474,7 @@ get_string_length (strinfo si) } gimple_call_set_fndecl (stmt, fn); lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (fn)), stmt); - gimple_call_set_lhs (stmt, lhs); + gimple_call_set_lhs (call_stmt, lhs); update_stmt (stmt); if (dump_file && (dump_flags & TDF_DETAILS) != 0) { diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index fb3fe94..2ddaebe 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -4463,24 +4463,24 @@ vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi, } builtin_decl = targetm.vectorize.builtin_mask_for_load (); - new_stmt = gimple_build_call (builtin_decl, 1, init_addr); + gimple_call call_stmt = gimple_build_call (builtin_decl, 1, init_addr); vec_dest = vect_create_destination_var (scalar_dest, - gimple_call_return_type (new_stmt)); - new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (new_stmt, new_temp); + gimple_call_return_type (call_stmt)); + new_temp = make_ssa_name (vec_dest, call_stmt); + gimple_call_set_lhs (call_stmt, new_temp); if (compute_in_loop) - gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); + gsi_insert_before (gsi, call_stmt, GSI_SAME_STMT); else { /* Generate the misalignment computation outside LOOP. */ pe = loop_preheader_edge (loop); - new_bb = gsi_insert_on_edge_immediate (pe, new_stmt); + new_bb = gsi_insert_on_edge_immediate (pe, call_stmt); gcc_assert (!new_bb); } - *realignment_token = gimple_call_lhs (new_stmt); + *realignment_token = gimple_call_lhs (call_stmt); /* The result of the CALL_EXPR to this builtin is determined from the value of the parameter and no global variables are touched diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 8d9aaa2..2dc918f 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -801,7 +801,7 @@ vect_recog_pow_pattern (vec<gimple> *stmts, tree *type_in, *type_in = get_vectype_for_scalar_type (TREE_TYPE (base)); if (*type_in) { - gimple stmt = gimple_build_call (newfn, 1, base); + gimple_call stmt = gimple_build_call (newfn, 1, base); if (vectorizable_function (stmt, *type_in, *type_in) != NULL_TREE) { diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 9516e76..906a44d 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -1940,9 +1940,10 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, vec<tree> vec_oprndsk = vec_defs[k]; vargs[k] = vec_oprndsk[i]; } - new_stmt = gimple_build_call_vec (fndecl, vargs); + gimple_call call = gimple_build_call_vec (fndecl, vargs); + new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (new_stmt, new_temp); + gimple_call_set_lhs (call, new_temp); vect_finish_stmt_generation (stmt, new_stmt, gsi); SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); } @@ -1992,9 +1993,10 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, } else { - new_stmt = gimple_build_call_vec (fndecl, vargs); + gimple_call call = gimple_build_call_vec (fndecl, vargs); + new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (new_stmt, new_temp); + gimple_call_set_lhs (call, new_temp); } vect_finish_stmt_generation (stmt, new_stmt, gsi); @@ -2039,9 +2041,10 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, vargs.quick_push (vec_oprndsk[i]); vargs.quick_push (vec_oprndsk[i + 1]); } - new_stmt = gimple_build_call_vec (fndecl, vargs); + gimple_call call = gimple_build_call_vec (fndecl, vargs); + new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (new_stmt, new_temp); + gimple_call_set_lhs (call, new_temp); vect_finish_stmt_generation (stmt, new_stmt, gsi); SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); } @@ -2078,9 +2081,10 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, vargs.quick_push (vec_oprnd1); } - new_stmt = gimple_build_call_vec (fndecl, vargs); + gimple_call call = gimple_build_call_vec (fndecl, vargs); + new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (new_stmt, new_temp); + gimple_call_set_lhs (call, new_temp); vect_finish_stmt_generation (stmt, new_stmt, gsi); if (j == 0) @@ -2152,13 +2156,15 @@ vect_gen_widened_results_half (enum tree_code code, /* Generate half of the widened result: */ if (code == CALL_EXPR) { + gimple_call call; /* Target specific support */ if (op_type == binary_op) - new_stmt = gimple_build_call (decl, 2, vec_oprnd0, vec_oprnd1); + call = gimple_build_call (decl, 2, vec_oprnd0, vec_oprnd1); else - new_stmt = gimple_build_call (decl, 1, vec_oprnd0); + call = gimple_build_call (decl, 1, vec_oprnd0); + new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (new_stmt, new_temp); + gimple_call_set_lhs (call, new_temp); } else { @@ -2710,9 +2716,10 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, /* Arguments are ready, create the new vector stmt. */ if (code1 == CALL_EXPR) { - new_stmt = gimple_build_call (decl1, 1, vop0); + gimple_call call = gimple_build_call (decl1, 1, vop0); + new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (new_stmt, new_temp); + gimple_call_set_lhs (call, new_temp); } else { @@ -2821,9 +2828,10 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, { if (codecvt1 == CALL_EXPR) { - new_stmt = gimple_build_call (decl1, 1, vop0); + gimple_call call = gimple_build_call (decl1, 1, vop0); + new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (new_stmt, new_temp); + gimple_call_set_lhs (call, new_temp); } else { @@ -2879,9 +2887,10 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, { if (codecvt1 == CALL_EXPR) { - new_stmt = gimple_build_call (decl1, 1, vop0); + gimple_call call = gimple_build_call (decl1, 1, vop0); + new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (new_stmt, new_temp); + gimple_call_set_lhs (call, new_temp); } else { @@ -4240,8 +4249,9 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, /* Emit: MEM_REF[...all elements...] = STORE_LANES (VEC_ARRAY). */ data_ref = create_array_ref (aggr_type, dataref_ptr, first_dr); - new_stmt = gimple_build_call_internal (IFN_STORE_LANES, 1, vec_array); - gimple_call_set_lhs (new_stmt, data_ref); + gimple_call call = gimple_build_call_internal (IFN_STORE_LANES, 1, vec_array); + new_stmt = call; + gimple_call_set_lhs (call, data_ref); vect_finish_stmt_generation (stmt, new_stmt, gsi); } else @@ -4732,8 +4742,9 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, op = var; } - new_stmt + gimple_call call = gimple_build_call (gather_decl, 5, mask, ptr, op, mask, scale); + new_stmt = call; if (!useless_type_conversion_p (vectype, rettype)) { @@ -4741,7 +4752,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, == TYPE_VECTOR_SUBPARTS (rettype)); var = vect_get_new_vect_var (rettype, vect_simple_var, NULL); op = make_ssa_name (var, new_stmt); - gimple_call_set_lhs (new_stmt, op); + gimple_call_set_lhs (call, op); vect_finish_stmt_generation (stmt, new_stmt, gsi); var = make_ssa_name (vec_dest, NULL); op = build1 (VIEW_CONVERT_EXPR, vectype, op); @@ -4752,7 +4763,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, else { var = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (new_stmt, var); + gimple_call_set_lhs (call, var); } vect_finish_stmt_generation (stmt, new_stmt, gsi); @@ -5111,8 +5122,9 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, /* Emit: VEC_ARRAY = LOAD_LANES (MEM_REF[...all elements...]). */ data_ref = create_array_ref (aggr_type, dataref_ptr, first_dr); - new_stmt = gimple_build_call_internal (IFN_LOAD_LANES, 1, data_ref); - gimple_call_set_lhs (new_stmt, vec_array); + gimple_call call = gimple_build_call_internal (IFN_LOAD_LANES, 1, data_ref); + new_stmt = call; + gimple_call_set_lhs (call, vec_array); vect_finish_stmt_generation (stmt, new_stmt, gsi); /* Extract each vector into an SSA_NAME. */ diff --git a/gcc/tsan.c b/gcc/tsan.c index bceb597..de95625 100644 --- a/gcc/tsan.c +++ b/gcc/tsan.c @@ -426,7 +426,8 @@ static const struct tsan_map_atomic static void instrument_builtin_call (gimple_stmt_iterator *gsi) { - gimple stmt = gsi_stmt (*gsi), g; + gimple stmt = gsi_stmt (*gsi); + gimple g; tree callee = gimple_call_fndecl (stmt), last_arg, args[6], t, lhs; enum built_in_function fcode = DECL_FUNCTION_CODE (callee); unsigned int i, num = gimple_call_num_args (stmt), j; @@ -487,7 +488,8 @@ instrument_builtin_call (gimple_stmt_iterator *gsi) gsi_insert_after (gsi, g, GSI_NEW_STMT); args[1] = var; } - gimple_call_set_lhs (stmt, + gimple_call call_stmt = as_a<gimple_statement_call> (stmt); + gimple_call_set_lhs (call_stmt, make_ssa_name (TREE_TYPE (lhs), NULL)); /* BIT_NOT_EXPR stands for NAND. */ if (tsan_atomic_table[i].code == BIT_NOT_EXPR) @@ -569,7 +571,8 @@ instrument_builtin_call (gimple_stmt_iterator *gsi) g = gimple_build_assign_with_ops (COND_EXPR, lhs, cond, args[1], gimple_assign_lhs (g)); - gimple_call_set_lhs (stmt, t); + gimple_call call_stmt = as_a<gimple_statement_call> (stmt); + gimple_call_set_lhs (call_stmt, t); update_stmt (stmt); gsi_insert_after (gsi, g, GSI_NEW_STMT); } @@ -649,7 +652,7 @@ instrument_func_entry (void) basic_block succ_bb; gimple_stmt_iterator gsi; tree ret_addr, builtin_decl; - gimple g; + gimple_call g; succ_bb = single_succ (ENTRY_BLOCK_PTR); gsi = gsi_after_labels (succ_bb); diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 7be54ce..7ca9f4d 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -1292,11 +1292,12 @@ check_ic_target (gimple call_stmt, struct cgraph_node *target) old call */ -gimple -gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, +gimple_call +gimple_ic (gimple_call icall_stmt, struct cgraph_node *direct_call, int prob, gcov_type count, gcov_type all) { - gimple dcall_stmt, load_stmt, cond_stmt; + gimple_call dcall_stmt; + gimple load_stmt, cond_stmt; tree tmp0, tmp1, tmp; basic_block cond_bb, dcall_bb, icall_bb, join_bb = NULL; tree optype = build_pointer_type (void_type_node); @@ -1327,7 +1328,7 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, gimple_set_vdef (icall_stmt, NULL_TREE); gimple_set_vuse (icall_stmt, NULL_TREE); update_stmt (icall_stmt); - dcall_stmt = gimple_copy (icall_stmt); + dcall_stmt = static_cast<gimple_call> (gimple_copy (icall_stmt)); gimple_call_set_fndecl (dcall_stmt, direct_call->decl); dflags = flags_from_decl_or_type (direct_call->decl); if ((dflags & ECF_NORETURN) != 0) @@ -1559,10 +1560,11 @@ interesting_stringop_to_profile_p (tree fndecl, gimple call, int *size_arg) assuming we'll propagate a true constant into ICALL_SIZE later. */ static void -gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob, +gimple_stringop_fixed_value (gimple_call vcall_stmt, tree icall_size, int prob, gcov_type count, gcov_type all) { - gimple tmp_stmt, cond_stmt, icall_stmt; + gimple tmp_stmt, cond_stmt; + gimple_call icall_stmt; tree tmp0, tmp1, vcall_size, optype; basic_block cond_bb, icall_bb, vcall_bb, join_bb; edge e_ci, e_cv, e_iv, e_ij, e_vj; @@ -1594,7 +1596,7 @@ gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob, gimple_set_vdef (vcall_stmt, NULL); gimple_set_vuse (vcall_stmt, NULL); update_stmt (vcall_stmt); - icall_stmt = gimple_copy (vcall_stmt); + icall_stmt = static_cast<gimple_call> (gimple_copy (vcall_stmt)); gimple_call_set_arg (icall_stmt, size_arg, icall_size); gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT); @@ -1654,6 +1656,7 @@ static bool gimple_stringops_transform (gimple_stmt_iterator *gsi) { gimple stmt = gsi_stmt (*gsi); + gimple_call call_stmt; tree fndecl; tree blck_size; enum built_in_function fcode; @@ -1667,6 +1670,7 @@ gimple_stringops_transform (gimple_stmt_iterator *gsi) if (gimple_code (stmt) != GIMPLE_CALL) return false; + call_stmt = static_cast<gimple_call> (stmt); fndecl = gimple_call_fndecl (stmt); if (!fndecl) return false; @@ -1731,7 +1735,7 @@ gimple_stringops_transform (gimple_stmt_iterator *gsi) (int)val); print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); } - gimple_stringop_fixed_value (stmt, tree_val, prob, count, all); + gimple_stringop_fixed_value (call_stmt, tree_val, prob, count, all); return true; } diff --git a/gcc/value-prof.h b/gcc/value-prof.h index 57f249d..0dd9033 100644 --- a/gcc/value-prof.h +++ b/gcc/value-prof.h @@ -86,7 +86,8 @@ void gimple_move_stmt_histograms (struct function *, gimple, gimple); void verify_histograms (void); void free_histograms (void); void stringop_block_profile (gimple, unsigned int *, HOST_WIDE_INT *); -gimple gimple_ic (gimple, struct cgraph_node *, int, gcov_type, gcov_type); +gimple_call +gimple_ic (gimple_call, struct cgraph_node *, int, gcov_type, gcov_type); /* In tree-profile.c. */ diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c index fb26978..a276a8d 100644 --- a/gcc/vtable-verify.c +++ b/gcc/vtable-verify.c @@ -593,7 +593,7 @@ verify_bb_vtables (basic_block bb) tree vtbl_var_decl = NULL_TREE; struct vtbl_map_node *vtable_map_node; tree vtbl_decl = NULL_TREE; - gimple call_stmt; + gimple_call call_stmt; const char *vtable_name = "<unknown>"; tree tmp0; bool found; [-- Attachment #3: convert-gimple_call_set_lhs-to-method.patch --] [-- Type: text/x-patch, Size: 32871 bytes --] commit 9a89f418eceb2d11d6eff60cb8c76c11f7cdf77c Author: David Malcolm <dmalcolm@redhat.com> Date: Mon Nov 4 16:01:42 2013 -0500 FIXME: conversion of gimple_call_set_lhs to a method diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index a9ab226..a12e581 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1587,7 +1587,7 @@ expand_thunk (struct cgraph_node *node, bool output_asm_thunks) gimple_call_set_from_thunk (call, true); if (restmp) { - gimple_call_set_lhs (call, restmp); + call->set_lhs (restmp); gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp), TREE_TYPE (TREE_TYPE (alias)))); } diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index b76479c..cd44f3d 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -29459,7 +29459,7 @@ add_condition_to_bb (tree function_decl, tree version_decl, predicate_decl = TREE_PURPOSE (predicate_chain); predicate_arg = TREE_VALUE (predicate_chain); call_cond_stmt = gimple_build_call (predicate_decl, 1, predicate_arg); - gimple_call_set_lhs (call_cond_stmt, cond_var); + call_cond_stmt->set_lhs (cond_var); gimple_set_block (call_cond_stmt, DECL_INITIAL (function_decl)); gimple_set_bb (call_cond_stmt, new_bb); diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index b24961b..f7c399e 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -158,7 +158,7 @@ lower_function_body (void) arg = build_addr (disp_label, current_function_decl); t = builtin_decl_implicit (BUILT_IN_SETJMP_DISPATCHER); call = gimple_build_call (t, 1, arg); - gimple_call_set_lhs (call, disp_var); + call->set_lhs (disp_var); gsi_insert_after (&i, call, GSI_CONTINUE_LINKING); /* Build 'goto DISP_VAR;' and insert. */ diff --git a/gcc/gimple.c b/gcc/gimple.c index f31c935..a128582 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -2252,7 +2252,7 @@ gimple_set_lhs (gimple stmt, tree lhs) if (code == GIMPLE_ASSIGN) gimple_assign_set_lhs (stmt, lhs); else if (code == GIMPLE_CALL) - gimple_call_set_lhs (static_cast<gimple_call> (stmt), lhs); + ((gimple_call)stmt)->set_lhs (lhs); else gcc_unreachable (); } @@ -3083,7 +3083,7 @@ gimple_call_copy_skip_args (gimple stmt, bitmap args_to_skip) new_stmt = gimple_build_call_vec (gimple_call_fn (stmt), vargs); vargs.release (); if (gimple_call_lhs (stmt)) - gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt)); + new_stmt->set_lhs (gimple_call_lhs (stmt)); gimple_set_vuse (new_stmt, gimple_vuse (stmt)); gimple_set_vdef (new_stmt, gimple_vdef (stmt)); diff --git a/gcc/gimple.h b/gcc/gimple.h index 1180d3e..c9df1d9 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -292,6 +292,13 @@ struct GTY((tag("GSS_WITH_MEM_OPS"))) struct GTY((tag("GSS_CALL"))) gimple_statement_call : public gimple_statement_with_memory_ops_base { +public: + + /* Set LHS to be the LHS operand of this call statement. */ + inline void set_lhs (tree lhs); + +public: + /* [ WORD 1-9 ] : base class */ /* [ WORD 10-13 ] */ @@ -2550,12 +2557,12 @@ gimple_call_lhs_ptr (const_gimple gs) /* Set LHS to be the LHS operand of call statement GS. */ -static inline void -gimple_call_set_lhs (gimple_call gs, tree lhs) +inline void +gimple_statement_call::set_lhs (tree lhs) { - gimple_set_op (gs, 0, lhs); + gimple_set_op (this, 0, lhs); if (lhs && TREE_CODE (lhs) == SSA_NAME) - SSA_NAME_DEF_STMT (lhs) = gs; + SSA_NAME_DEF_STMT (lhs) = this; } diff --git a/gcc/gimplify.c b/gcc/gimplify.c index e2c81b9..4cfc2e9 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1166,7 +1166,7 @@ build_stack_save_restore (gimple_call *save, gimple_call *restore) *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0); tmp_var = create_tmp_var (ptr_type_node, "saved_stack"); - gimple_call_set_lhs (*save, tmp_var); + (*save)->set_lhs (tmp_var); *restore = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE), @@ -3464,7 +3464,7 @@ gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value, { /* tmp = memcpy() */ t = create_tmp_var (TREE_TYPE (to_ptr), NULL); - gimple_call_set_lhs (gs, t); + gs->set_lhs (t); gimplify_seq_add_stmt (seq_p, gs); *expr_p = build_simple_mem_ref (t); @@ -3511,7 +3511,7 @@ gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value, { /* tmp = memset() */ t = create_tmp_var (TREE_TYPE (to_ptr), NULL); - gimple_call_set_lhs (gs, t); + gs->set_lhs (t); gimplify_seq_add_stmt (seq_p, gs); *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t); @@ -4881,7 +4881,7 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, gimple_call_set_fntype (assign, TREE_TYPE (fnptrtype)); notice_special_calls (assign); if (!gimple_call_noreturn_p (assign)) - gimple_call_set_lhs (call, *to_p); + call->set_lhs (*to_p); } else { @@ -7792,7 +7792,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p)); gimple_call call = gimple_build_call_internal (IFN_ANNOTATE, 2, cond, id); - gimple_call_set_lhs (call, tmp); + call->set_lhs (tmp); gimplify_seq_add_stmt (pre_p, call); *expr_p = tmp; ret = GS_ALL_DONE; @@ -8995,7 +8995,7 @@ gimplify_function_tree (tree fndecl) x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS); call = gimple_build_call (x, 1, integer_zero_node); tmp_var = create_tmp_var (ptr_type_node, "return_addr"); - gimple_call_set_lhs (call, tmp_var); + call->set_lhs (tmp_var); gimplify_seq_add_stmt (&cleanup, call); x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT); call = gimple_build_call (x, 2, @@ -9007,7 +9007,7 @@ gimplify_function_tree (tree fndecl) x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS); call = gimple_build_call (x, 1, integer_zero_node); tmp_var = create_tmp_var (ptr_type_node, "return_addr"); - gimple_call_set_lhs (call, tmp_var); + call->set_lhs (tmp_var); gimplify_seq_add_stmt (&body, call); x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER); call = gimple_build_call (x, 2, diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 642153d..5e8b068 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -3713,7 +3713,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt, new_stmt = gimple_build_call_vec (callee_decl, vargs); vargs.release (); if (gimple_call_lhs (stmt)) - gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt)); + new_stmt->set_lhs (gimple_call_lhs (stmt)); gimple_set_block (new_stmt, gimple_block (stmt)); if (gimple_has_location (stmt)) diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 915533c..b7f8381 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -1414,7 +1414,7 @@ split_function (struct split_point *split_point) } if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) { - gimple_call_set_lhs (call, build_simple_mem_ref (retval)); + call->set_lhs (build_simple_mem_ref (retval)); gsi_insert_after (&gsi, call, GSI_NEW_STMT); } else @@ -1432,7 +1432,7 @@ split_function (struct split_point *split_point) gsi_insert_after (&gsi, cpy, GSI_NEW_STMT); retval = tem; } - gimple_call_set_lhs (call, retval); + call->set_lhs (retval); update_stmt (call); } } @@ -1468,9 +1468,9 @@ split_function (struct split_point *split_point) retval = make_ssa_name (retval, call); } if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) - gimple_call_set_lhs (call, build_simple_mem_ref (retval)); + call->set_lhs (build_simple_mem_ref (retval)); else - gimple_call_set_lhs (call, retval); + call->set_lhs (retval); } gsi_insert_after (&gsi, call, GSI_NEW_STMT); ret = gimple_build_return (retval); diff --git a/gcc/omp-low.c b/gcc/omp-low.c index dcececc..3b7882d 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -2672,7 +2672,7 @@ build_omp_barrier (tree lhs) : BUILT_IN_GOMP_BARRIER); gimple_call g = gimple_build_call (fndecl, 0); if (lhs) - gimple_call_set_lhs (g, lhs); + g->set_lhs (lhs); return g; } @@ -3113,7 +3113,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, stmt = gimple_build_call (atmp, 1, x); tmp = create_tmp_var_raw (ptr_type_node, NULL); gimple_add_tmp_var (tmp); - gimple_call_set_lhs (stmt, tmp); + stmt->set_lhs (tmp); gimple_seq_add_stmt (ilist, stmt); @@ -3521,7 +3521,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, TREE_NO_WARNING (uid) = 1; gimple_call call = gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 1, uid); - gimple_call_set_lhs (call, lane); + call->set_lhs (lane); gimple_stmt_iterator gsi = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt)); gsi_insert_before_without_update (&gsi, call, GSI_SAME_STMT); c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_); @@ -3538,7 +3538,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, { tree vf = create_tmp_var (unsigned_type_node, NULL); call = gimple_build_call_internal (IFN_GOMP_SIMD_VF, 1, uid); - gimple_call_set_lhs (call, vf); + call->set_lhs (vf); gimple_seq *seq = i == 0 ? ilist : dlist; gimple_seq_add_stmt (seq, call); tree t = build_int_cst (unsigned_type_node, 0); @@ -3698,7 +3698,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list, = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE, 2, simduid, TREE_OPERAND (val, 1)); - gimple_call_set_lhs (g, lastlane); + g->set_lhs (lastlane); gimple_seq_add_stmt (stmt_list, g); } new_var = build4 (ARRAY_REF, TREE_TYPE (val), @@ -5547,7 +5547,7 @@ expand_omp_for_generic (struct omp_region *region, t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END); gimple_call call = gimple_build_call (t, 0); if (gimple_omp_return_lhs (gsi_stmt (gsi))) - gimple_call_set_lhs (call, gimple_omp_return_lhs (gsi_stmt (gsi))); + call->set_lhs (gimple_omp_return_lhs (gsi_stmt (gsi))); gsi_insert_after (&gsi, call, GSI_SAME_STMT); gsi_remove (&gsi, true); @@ -6939,7 +6939,7 @@ expand_omp_sections (struct omp_region *region) u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT); call = gimple_build_call (u, 0); } - gimple_call_set_lhs (call, vin); + call->set_lhs (vin); gsi_insert_after (&si, call, GSI_SAME_STMT); gsi_remove (&si, true); @@ -7029,7 +7029,7 @@ expand_omp_sections (struct omp_region *region) bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT); call = gimple_build_call (bfn_decl, 0); - gimple_call_set_lhs (call, vnext); + call->set_lhs (vnext); gsi_insert_after (&si, call, GSI_SAME_STMT); gsi_remove (&si, true); @@ -7046,7 +7046,7 @@ expand_omp_sections (struct omp_region *region) t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END); call = gimple_build_call (t, 0); if (gimple_omp_return_lhs (gsi_stmt (si))) - gimple_call_set_lhs (call, gimple_omp_return_lhs (gsi_stmt (si))); + call->set_lhs (gimple_omp_return_lhs (gsi_stmt (si))); gsi_insert_after (&si, call, GSI_SAME_STMT); gsi_remove (&si, true); @@ -8422,7 +8422,7 @@ lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p) decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START); lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL); call = gimple_build_call (decl, 0); - gimple_call_set_lhs (call, lhs); + call->set_lhs (lhs); gimple_seq_add_stmt (pre_p, call); cond = gimple_build_cond (EQ_EXPR, lhs, @@ -10010,7 +10010,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx) gimple_call_set_fndecl (stmt, fndecl); gimple_call_set_fntype (stmt, TREE_TYPE (fndecl)); } - gimple_call_set_lhs (call, lhs); + call->set_lhs (lhs); tree fallthru_label; fallthru_label = create_artificial_label (UNKNOWN_LOCATION); gimple g; diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index 0358b26..b9e1be6 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -1618,7 +1618,7 @@ lower_transaction (gimple_stmt_iterator *gsi, struct walk_stmt_info *wi) gimple_build_call (builtin_decl_explicit (BUILT_IN_EH_POINTER), 1, integer_zero_node); ptr = create_tmp_var (ptr_type_node, NULL); - gimple_call_set_lhs (call, ptr); + call->set_lhs (ptr); gimple_seq_add_stmt (&e_seq, call); g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_COMMIT_EH), @@ -2115,7 +2115,7 @@ build_tm_load (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi) t = TREE_TYPE (TREE_TYPE (decl)); if (useless_type_conversion_p (type, t)) { - gimple_call_set_lhs (gcall, lhs); + gcall->set_lhs (lhs); gsi_insert_before (gsi, gcall, GSI_SAME_STMT); } else @@ -2124,7 +2124,7 @@ build_tm_load (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi) tree temp; temp = create_tmp_reg (t, NULL); - gimple_call_set_lhs (gcall, temp); + gcall->set_lhs (temp); gsi_insert_before (gsi, gcall, GSI_SAME_STMT); t = fold_build1 (VIEW_CONVERT_EXPR, type, temp); @@ -2414,7 +2414,7 @@ expand_call_tm (struct tm_region *region, } } - gimple_call_set_lhs (call_stmt, tmp); + call_stmt->set_lhs (tmp); update_stmt (stmt); stmt = gimple_build_assign (lhs, tmp); gimple_set_location (stmt, loc); @@ -2701,7 +2701,7 @@ expand_transaction (struct tm_region *region, void *data ATTRIBUTE_UNUSED) region->original_transaction_was_outer = true; tree t = build_int_cst (tm_state_type, flags); gimple_call call = gimple_build_call (tm_start, 1, t); - gimple_call_set_lhs (call, tm_state); + call->set_lhs (tm_state); gimple_set_location (call, gimple_location (region->transaction_stmt)); // Replace the GIMPLE_TRANSACTION with the call to BUILT_IN_TM_START. @@ -4993,7 +4993,7 @@ ipa_tm_insert_gettmclone_call (struct cgraph_node *node, g = gimple_build_call (gettm_fn, 1, old_fn); ret = make_ssa_name (ret, g); - gimple_call_set_lhs (g, ret); + g->set_lhs (ret); gsi_insert_before (gsi, g, GSI_SAME_STMT); @@ -5029,7 +5029,7 @@ ipa_tm_insert_gettmclone_call (struct cgraph_node *node, tree temp; temp = create_tmp_reg (rettype, 0); - gimple_call_set_lhs (stmt, temp); + stmt->set_lhs (temp); g2 = gimple_build_assign (lhs, fold_build1 (VIEW_CONVERT_EXPR, diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 3cd625c..db43ea8 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -517,7 +517,7 @@ fixup_noreturn_call (gimple_call stmt) if (gimple_call_lhs (stmt)) { tree op = gimple_call_lhs (stmt); - gimple_call_set_lhs (stmt, NULL_TREE); + stmt->set_lhs (NULL_TREE); /* We need to remove SSA name to avoid checking errors. All uses are dominated by the noreturn and thus will diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c index aee1e26..325554f 100644 --- a/gcc/tree-complex.c +++ b/gcc/tree-complex.c @@ -957,7 +957,7 @@ expand_complex_libcall (gimple_stmt_iterator *gsi, tree ar, tree ai, fn = builtin_decl_explicit (bcode); stmt = gimple_build_call (fn, 4, ar, ai, br, bi); - gimple_call_set_lhs (stmt, lhs); + stmt->set_lhs (lhs); update_stmt (stmt); gsi_replace (gsi, stmt, false); diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 3347b7b..c83229f 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -3207,7 +3207,7 @@ lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map) gimple_call call = gimple_build_call (fn, 1, src_nr); var = create_tmp_var (ptr_type_node, NULL); var = make_ssa_name (var, call); - gimple_call_set_lhs (call, var); + call->set_lhs (var); gsi_insert_before (&gsi, call, GSI_SAME_STMT); fn = builtin_decl_implicit (BUILT_IN_UNWIND_RESUME); @@ -3583,7 +3583,7 @@ lower_eh_dispatch (basic_block src, gimple stmt) region_nr)); filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL); filter = make_ssa_name (filter, call); - gimple_call_set_lhs (call, filter); + call->set_lhs (filter); gsi_insert_before (&gsi, call, GSI_SAME_STMT); /* Turn the default label into a default case. */ @@ -3610,7 +3610,7 @@ lower_eh_dispatch (basic_block src, gimple stmt) region_nr)); filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL); filter = make_ssa_name (filter, call); - gimple_call_set_lhs (call, filter); + call->set_lhs (filter); gsi_insert_before (&gsi, call, GSI_SAME_STMT); r->u.allowed.label = NULL; diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c index 7b17a68..177d0e9 100644 --- a/gcc/tree-emutls.c +++ b/gcc/tree-emutls.c @@ -438,7 +438,7 @@ gen_emutls_addr (tree decl, struct lower_emutls_data *d) gimple_set_location (x, d->loc); addr = make_ssa_name (addr, x); - gimple_call_set_lhs (x, addr); + x->set_lhs (addr); gimple_seq_add_stmt (&d->seq, x); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 83a3e27..e4c80a7 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1683,7 +1683,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, gimple_call_set_va_arg_pack (new_call, false); gimple_set_location (new_call, gimple_location (stmt)); gimple_set_block (new_call, gimple_block (stmt)); - gimple_call_set_lhs (new_call, gimple_call_lhs (stmt)); + new_call->set_lhs (gimple_call_lhs (stmt)); gsi_replace (©_gsi, new_call, false); stmt = new_call; diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index 5f5dcef..0258553 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -406,7 +406,7 @@ init_tmp_var_with_call (struct nesting_info *info, gimple_stmt_iterator *gsi, tree t; t = create_tmp_var_for (info, gimple_call_return_type (call), NULL); - gimple_call_set_lhs (call, t); + call->set_lhs (t); if (! gsi_end_p (*gsi)) gimple_set_location (call, gimple_location (gsi_stmt (*gsi))); gsi_insert_before (gsi, call, GSI_SAME_STMT); diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 35c97b6..3acb721 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -4476,7 +4476,7 @@ replace_removed_params_ssa_names (gimple stmt, if (is_gimple_assign (stmt)) gimple_assign_set_lhs (stmt, name); else if (is_gimple_call (stmt)) - gimple_call_set_lhs (static_cast<gimple_call> (stmt), name); + static_cast<gimple_call> (stmt)->set_lhs (name); else gimple_phi_set_result (stmt, name); diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index 3527848..4451585 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -1241,7 +1241,7 @@ eliminate_unnecessary_stmts (void) fprintf (dump_file, "\n"); } - gimple_call_set_lhs (call_stmt, NULL_TREE); + call_stmt->set_lhs (NULL_TREE); maybe_clean_or_replace_eh_stmt (stmt, stmt); update_stmt (stmt); release_ssa_name (name); diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index c0415d4..6ad45c9 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -1653,7 +1653,7 @@ simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2) memset call. */ gimple_call call_stmt1 = static_cast <gimple_call> (stmt1); if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY) - gimple_call_set_lhs (call_stmt1, NULL_TREE); + call_stmt1->set_lhs (NULL_TREE); gimple_call_set_arg (stmt1, 1, new_str_cst); gimple_call_set_arg (stmt1, 2, build_int_cst (TREE_TYPE (len1), src_len)); diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 6253c3d..2ffa38a 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -771,7 +771,7 @@ execute_cse_sincos_1 (tree name) return false; call_stmt = gimple_build_call (fndecl, 1, name); res = make_temp_ssa_name (TREE_TYPE (TREE_TYPE (fndecl)), call_stmt, "sincostmp"); - gimple_call_set_lhs (call_stmt, res); + call_stmt->set_lhs (res); def_stmt = SSA_NAME_DEF_STMT (name); if (!SSA_NAME_IS_DEFAULT_DEF (name) @@ -2022,7 +2022,7 @@ execute_optimize_bswap (void) gsi_insert_after (&gsi, convert_stmt, GSI_SAME_STMT); } - gimple_call_set_lhs (call, bswap_tmp); + call->set_lhs (bswap_tmp); if (dump_file) { diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index 4565de0..0c84581 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -700,7 +700,7 @@ static void finish_update_gimple_call (gimple_stmt_iterator *si_p, gimple_call new_stmt, gimple stmt) { - gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt)); + new_stmt->set_lhs (gimple_call_lhs (stmt)); move_ssa_defining_stmt_for_defs (new_stmt, stmt); gimple_set_vuse (new_stmt, gimple_vuse (stmt)); gimple_set_vdef (new_stmt, gimple_vdef (stmt)); diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 982c6d2..0e66f7c 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -4097,7 +4097,7 @@ attempt_builtin_powi (gimple stmt, vec<operand_entry_t> *ops) pow_stmt = gimple_build_call (powi_fndecl, 2, rf1->repr, build_int_cst (integer_type_node, power)); - gimple_call_set_lhs (pow_stmt, iter_result); + pow_stmt->set_lhs (iter_result); gimple_set_location (pow_stmt, gimple_location (stmt)); gsi_insert_before (&gsi, pow_stmt, GSI_SAME_STMT); @@ -4198,7 +4198,7 @@ attempt_builtin_powi (gimple stmt, vec<operand_entry_t> *ops) pow_stmt = gimple_build_call (powi_fndecl, 2, rf1->repr, build_int_cst (integer_type_node, power)); - gimple_call_set_lhs (pow_stmt, iter_result); + pow_stmt->set_lhs (iter_result); gimple_set_location (pow_stmt, gimple_location (stmt)); gsi_insert_before (&gsi, pow_stmt, GSI_SAME_STMT); } diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index ad18fc1..f47b20f 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -441,7 +441,7 @@ get_string_length (strinfo si) tem = unshare_expr (gimple_call_arg (stmt, 0)); lenstmt_call = gimple_build_call (fn, 1, tem); lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (fn)), lenstmt_call); - gimple_call_set_lhs (lenstmt_call, lhs); + lenstmt_call->set_lhs (lhs); gimple_set_vuse (lenstmt_call, gimple_vuse (stmt)); gsi_insert_before (&gsi, lenstmt_call, GSI_SAME_STMT); tem = gimple_call_arg (stmt, 0); @@ -474,7 +474,7 @@ get_string_length (strinfo si) } gimple_call_set_fndecl (stmt, fn); lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (fn)), stmt); - gimple_call_set_lhs (call_stmt, lhs); + call_stmt->set_lhs (lhs); update_stmt (stmt); if (dump_file && (dump_flags & TDF_DETAILS) != 0) { diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 2ddaebe..7b8d20d 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -4468,7 +4468,7 @@ vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi, vect_create_destination_var (scalar_dest, gimple_call_return_type (call_stmt)); new_temp = make_ssa_name (vec_dest, call_stmt); - gimple_call_set_lhs (call_stmt, new_temp); + call_stmt->set_lhs (new_temp); if (compute_in_loop) gsi_insert_before (gsi, call_stmt, GSI_SAME_STMT); diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 2dc918f..b1a1e5f 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -806,7 +806,7 @@ vect_recog_pow_pattern (vec<gimple> *stmts, tree *type_in, != NULL_TREE) { var = vect_recog_temp_ssa_var (TREE_TYPE (base), stmt); - gimple_call_set_lhs (stmt, var); + stmt->set_lhs (var); return stmt; } } diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 906a44d..b982046 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -1943,7 +1943,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, gimple_call call = gimple_build_call_vec (fndecl, vargs); new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (call, new_temp); + call->set_lhs (new_temp); vect_finish_stmt_generation (stmt, new_stmt, gsi); SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); } @@ -1996,7 +1996,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, gimple_call call = gimple_build_call_vec (fndecl, vargs); new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (call, new_temp); + call->set_lhs (new_temp); } vect_finish_stmt_generation (stmt, new_stmt, gsi); @@ -2044,7 +2044,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, gimple_call call = gimple_build_call_vec (fndecl, vargs); new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (call, new_temp); + call->set_lhs (new_temp); vect_finish_stmt_generation (stmt, new_stmt, gsi); SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt); } @@ -2084,7 +2084,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, gimple_call call = gimple_build_call_vec (fndecl, vargs); new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (call, new_temp); + call->set_lhs (new_temp); vect_finish_stmt_generation (stmt, new_stmt, gsi); if (j == 0) @@ -2164,7 +2164,7 @@ vect_gen_widened_results_half (enum tree_code code, call = gimple_build_call (decl, 1, vec_oprnd0); new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (call, new_temp); + call->set_lhs (new_temp); } else { @@ -2719,7 +2719,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, gimple_call call = gimple_build_call (decl1, 1, vop0); new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (call, new_temp); + call->set_lhs (new_temp); } else { @@ -2831,7 +2831,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, gimple_call call = gimple_build_call (decl1, 1, vop0); new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (call, new_temp); + call->set_lhs (new_temp); } else { @@ -2890,7 +2890,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, gimple_call call = gimple_build_call (decl1, 1, vop0); new_stmt = call; new_temp = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (call, new_temp); + call->set_lhs (new_temp); } else { @@ -4251,7 +4251,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, data_ref = create_array_ref (aggr_type, dataref_ptr, first_dr); gimple_call call = gimple_build_call_internal (IFN_STORE_LANES, 1, vec_array); new_stmt = call; - gimple_call_set_lhs (call, data_ref); + call->set_lhs (data_ref); vect_finish_stmt_generation (stmt, new_stmt, gsi); } else @@ -4752,7 +4752,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, == TYPE_VECTOR_SUBPARTS (rettype)); var = vect_get_new_vect_var (rettype, vect_simple_var, NULL); op = make_ssa_name (var, new_stmt); - gimple_call_set_lhs (call, op); + call->set_lhs (op); vect_finish_stmt_generation (stmt, new_stmt, gsi); var = make_ssa_name (vec_dest, NULL); op = build1 (VIEW_CONVERT_EXPR, vectype, op); @@ -4763,7 +4763,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, else { var = make_ssa_name (vec_dest, new_stmt); - gimple_call_set_lhs (call, var); + call->set_lhs (var); } vect_finish_stmt_generation (stmt, new_stmt, gsi); @@ -5124,7 +5124,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, data_ref = create_array_ref (aggr_type, dataref_ptr, first_dr); gimple_call call = gimple_build_call_internal (IFN_LOAD_LANES, 1, data_ref); new_stmt = call; - gimple_call_set_lhs (call, vec_array); + call->set_lhs (vec_array); vect_finish_stmt_generation (stmt, new_stmt, gsi); /* Extract each vector into an SSA_NAME. */ diff --git a/gcc/tsan.c b/gcc/tsan.c index de95625..8a8dccf 100644 --- a/gcc/tsan.c +++ b/gcc/tsan.c @@ -489,8 +489,7 @@ instrument_builtin_call (gimple_stmt_iterator *gsi) args[1] = var; } gimple_call call_stmt = as_a<gimple_statement_call> (stmt); - gimple_call_set_lhs (call_stmt, - make_ssa_name (TREE_TYPE (lhs), NULL)); + call_stmt->set_lhs (make_ssa_name (TREE_TYPE (lhs), NULL)); /* BIT_NOT_EXPR stands for NAND. */ if (tsan_atomic_table[i].code == BIT_NOT_EXPR) { @@ -572,7 +571,7 @@ instrument_builtin_call (gimple_stmt_iterator *gsi) args[1], gimple_assign_lhs (g)); gimple_call call_stmt = as_a<gimple_statement_call> (stmt); - gimple_call_set_lhs (call_stmt, t); + call_stmt->set_lhs (t); update_stmt (stmt); gsi_insert_after (gsi, g, GSI_NEW_STMT); } @@ -660,7 +659,7 @@ instrument_func_entry (void) builtin_decl = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS); g = gimple_build_call (builtin_decl, 1, integer_zero_node); ret_addr = make_ssa_name (ptr_type_node, NULL); - gimple_call_set_lhs (g, ret_addr); + g->set_lhs (ret_addr); gimple_set_location (g, cfun->function_start_locus); gsi_insert_before (&gsi, g, GSI_SAME_STMT); diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 7ca9f4d..29d40a1 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -1332,7 +1332,7 @@ gimple_ic (gimple_call icall_stmt, struct cgraph_node *direct_call, gimple_call_set_fndecl (dcall_stmt, direct_call->decl); dflags = flags_from_decl_or_type (direct_call->decl); if ((dflags & ECF_NORETURN) != 0) - gimple_call_set_lhs (dcall_stmt, NULL_TREE); + dcall_stmt->set_lhs (NULL_TREE); gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT); /* Fix CFG. */ @@ -1397,11 +1397,9 @@ gimple_ic (gimple_call icall_stmt, struct cgraph_node *direct_call, { tree result = gimple_call_lhs (icall_stmt); gimple phi = create_phi_node (result, join_bb); - gimple_call_set_lhs (icall_stmt, - duplicate_ssa_name (result, icall_stmt)); + icall_stmt->set_lhs (duplicate_ssa_name (result, icall_stmt)); add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION); - gimple_call_set_lhs (dcall_stmt, - duplicate_ssa_name (result, dcall_stmt)); + dcall_stmt->set_lhs (duplicate_ssa_name (result, dcall_stmt)); add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION); } @@ -1637,11 +1635,9 @@ gimple_stringop_fixed_value (gimple_call vcall_stmt, tree icall_size, int prob, { tree result = gimple_call_lhs (vcall_stmt); gimple phi = create_phi_node (result, join_bb); - gimple_call_set_lhs (vcall_stmt, - duplicate_ssa_name (result, vcall_stmt)); + vcall_stmt->set_lhs (duplicate_ssa_name (result, vcall_stmt)); add_phi_arg (phi, gimple_call_lhs (vcall_stmt), e_vj, UNKNOWN_LOCATION); - gimple_call_set_lhs (icall_stmt, - duplicate_ssa_name (result, icall_stmt)); + icall_stmt->set_lhs (duplicate_ssa_name (result, icall_stmt)); add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION); } diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c index a276a8d..d743c3e 100644 --- a/gcc/vtable-verify.c +++ b/gcc/vtable-verify.c @@ -686,7 +686,7 @@ verify_bb_vtables (basic_block bb) return value, and make the call_stmt use the variable for that purpose. */ tmp0 = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "VTV"); - gimple_call_set_lhs (call_stmt, tmp0); + call_stmt->set_lhs (tmp0); update_stmt (call_stmt); /* Find the next stmt, after the vptr assignment ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-04 21:52 ` David Malcolm @ 2013-11-04 22:09 ` David Malcolm 2013-11-04 22:31 ` Andrew MacLeod 2013-11-04 22:43 ` Andrew MacLeod 2013-11-04 22:28 ` Jakub Jelinek 2013-11-05 11:53 ` Richard Biener 2 siblings, 2 replies; 116+ messages in thread From: David Malcolm @ 2013-11-04 22:09 UTC (permalink / raw) To: Andrew MacLeod; +Cc: Jakub Jelinek, gcc-patches On Mon, 2013-11-04 at 16:43 -0500, David Malcolm wrote: > On Mon, 2013-11-04 at 08:19 -0500, Andrew MacLeod wrote: > > On 11/01/2013 06:58 PM, David Malcolm wrote: > > > On Fri, 2013-11-01 at 22:57 +0100, Jakub Jelinek wrote: > > >> On Fri, Nov 01, 2013 at 05:47:14PM -0400, Andrew MacLeod wrote: > > >>> On 11/01/2013 05:41 PM, Jakub Jelinek wrote: > > >>>> On Fri, Nov 01, 2013 at 05:36:34PM -0400, Andrew MacLeod wrote: > > >>>>> static inline void > > >>>>> ! gimple_call_set_lhs (gimple gs, tree lhs) > > >>>>> { > > >>>>> - GIMPLE_CHECK (gs, GIMPLE_CALL); > > >> The checking you are removing here. > > >> > > >>> What checking? There ought to be no checking at all in this > > >>> example... gimple_build_call_vec returns a gimple_call, and > > >>> gimple_call_set_lhs() doesn't have to check anything because it > > >>> only accepts gimple_call's.. so there is no checking other than the > > >>> usual "does my parameter match" that the compiler has to do... > > >> and want to replace it by checking of the types at compile time. > > >> The problem is that it uglifies the source too much, and, when you > > >> actually don't have a gimple_call but supposedly a base class of it, > > >> I expect you'd do as_a which is not only further uglification, but has > > >> runtime cost also for --enable-checking=release. > > > I can have a look next week at every call to gimple_call_set_lhs in the > > > tree, and see to what extent we know at compile-time that the initial > > > arg is indeed a call (of the ones I quickly grepped just now, most are > > > from gimple_build_call and friends, but one was from a gimple_copy). > > > > > > FWIW I did some performance testing of the is_a/as_a code in the earlier > > > version of the patch, and it didn't have a noticable runtime cost > > > compared to the GIMPLE_CHECK in the existing code: > > > Size of compiler executable: > > > http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01920.html > > > Compile times: > > > http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00171.html > > I actually really dislike as_a<> and is_a<>, and think code needs to be > > restructured rather than use them, other than possibly at the very > > bottom level when we're allocating memory or something like that, or > > some kind of emergency :-)... If we require frequent uses of those, > > I'd be against it, I find them quite ugly. > > > > Like I said in the other reply, no rush, I don't think any of this > > follow up is appropriate this late in stage 1. I wasn't aware that there was a ramp in conservatism within stage1 - I thought that we had a "large (tested) changes are OK" attitude throughout all of stage1, and that the switch to conservatism only began at the transition to stage3. (and have been frantically attempting to get my big changes in before November 21st - should I be rethinking this?) > It would be more of an > > "interest" examination right now.. at least in my opinion... I suspect > > thinks like gimple_assign are more complex cases, but without looking > > its hard to tell for sure. > > I tried converting gimple_call_set_lhs to accept a gimple_call, rather > than a gimple, and excitingly, it was easiest to also convert > cgraph_edge's call_stmt to also be a gimple_call, rather than just a > gimple. > > Am attaching a patch (on top of the patch series being discussed) which > adds this compile-time typesafety; bootstrap is in-progress. IMHO very > little use of is-a.h was needed (5 instances of as_a, and 3 of dyn_cast; > no use of is_a). > > I'm also attaching a followup patch which eliminates gimple_call_set_lhs > in favor of a method of gimple_statement_call. (I posted the two patches in my prioer email more as a talking point than for detailed review, sorry if that wasn't clear). FWIW, my preferred strategy for 4.9 is a compromise: to do the 1st patch but not the 2nd: i.e. to make the existing gimple_foo_bar accessor functions be typesafe at compile-time, but without converting them to C++ methods - I think this gives us compile-time type-safety, whilst minimizing code-churn and minimizing the more "C++ish" aspects that may alarm those less happy with C++ in the codebase. I believe it would be easiest to do them one subclass at-a-time e.g. convert all gimple_call_* functions to accepting a gimple_call, then another subclass etc - assuming that this approach is blessed by the core reviewers. Dave ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-04 22:09 ` David Malcolm @ 2013-11-04 22:31 ` Andrew MacLeod 2013-11-05 21:27 ` Jeff Law 2013-11-04 22:43 ` Andrew MacLeod 1 sibling, 1 reply; 116+ messages in thread From: Andrew MacLeod @ 2013-11-04 22:31 UTC (permalink / raw) To: David Malcolm; +Cc: Jakub Jelinek, gcc-patches On 11/04/2013 05:03 PM, David Malcolm wrote: > On Mon, 2013-11-04 at 16:43 -0500, David Malcolm wrote: >> On Mon, 2013-11-04 at 08:19 -0500, Andrew MacLeod wrote: >>> On 11/01/2013 06:58 PM, David Malcolm wrote: >>>> On Fri, 2013-11-01 at 22:57 +0100, Jakub Jelinek wrote: >>>>> On Fri, Nov 01, 2013 at 05:47:14PM -0400, Andrew MacLeod wrote: >>>>>> On 11/01/2013 05:41 PM, Jakub Jelinek wrote: >>>>>>> On Fri, Nov 01, 2013 at 05:36:34PM -0400, Andrew MacLeod wrote: >>>>>>>> static inline void >>>>>>>> ! gimple_call_set_lhs (gimple gs, tree lhs) >>>>>>>> { >>>>>>>> - GIMPLE_CHECK (gs, GIMPLE_CALL); >>>>> The checking you are removing here. >>>>> >>>>>> What checking? There ought to be no checking at all in this >>>>>> example... gimple_build_call_vec returns a gimple_call, and >>>>>> gimple_call_set_lhs() doesn't have to check anything because it >>>>>> only accepts gimple_call's.. so there is no checking other than the >>>>>> usual "does my parameter match" that the compiler has to do... >>>>> and want to replace it by checking of the types at compile time. >>>>> The problem is that it uglifies the source too much, and, when you >>>>> actually don't have a gimple_call but supposedly a base class of it, >>>>> I expect you'd do as_a which is not only further uglification, but has >>>>> runtime cost also for --enable-checking=release. >>>> I can have a look next week at every call to gimple_call_set_lhs in the >>>> tree, and see to what extent we know at compile-time that the initial >>>> arg is indeed a call (of the ones I quickly grepped just now, most are >>>> from gimple_build_call and friends, but one was from a gimple_copy). >>>> >>>> FWIW I did some performance testing of the is_a/as_a code in the earlier >>>> version of the patch, and it didn't have a noticable runtime cost >>>> compared to the GIMPLE_CHECK in the existing code: >>>> Size of compiler executable: >>>> http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01920.html >>>> Compile times: >>>> http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00171.html >>> I actually really dislike as_a<> and is_a<>, and think code needs to be >>> restructured rather than use them, other than possibly at the very >>> bottom level when we're allocating memory or something like that, or >>> some kind of emergency :-)... If we require frequent uses of those, >>> I'd be against it, I find them quite ugly. >>> >>> Like I said in the other reply, no rush, I don't think any of this >>> follow up is appropriate this late in stage 1. > I wasn't aware that there was a ramp in conservatism within stage1 - I > thought that we had a "large (tested) changes are OK" attitude > throughout all of stage1, and that the switch to conservatism only began > at the transition to stage3. (and have been frantically attempting to > get my big changes in before November 21st - should I be rethinking > this?) You read a lot into things :-) No, what I mean its too late to get a full change in, and partial changes don't seem worthwhile to me.. ie, I don't think there is much point in partially converting one or two gimple stmt kinds and leaving the others unconverted. so converting gimple_call_stmt and some of its access methods doesnt seem worthwhile to me right now when we could do the entire thing during the next stage1 for instance. There isnt enough benefit. Especially since as the work progresses you may discover improvements that make you go back and unwind some of the changes you would now commit. I believe this is a large enough body of work that needs some serious implementation before any of it would be appropriate for mainline. That said, the patch which enables this is more self contained, so wouldn't be subject to that. Its a matter of whether it has enough merit of its own to go in. Having the first patch in mainline would actually allow someone to experiment more easily during the "off season" if they wanted to, but wouldn't be mandatory since they could apply it to their own branch to work on. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-04 22:31 ` Andrew MacLeod @ 2013-11-05 21:27 ` Jeff Law 0 siblings, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-05 21:27 UTC (permalink / raw) To: Andrew MacLeod, David Malcolm; +Cc: Jakub Jelinek, gcc-patches On 11/04/13 15:28, Andrew MacLeod wrote: > > That said, the patch which enables this is more self contained, so > wouldn't be subject to that. Its a matter of whether it has enough merit > of its own to go in. Having the first patch in mainline would actually > allow someone to experiment more easily during the "off season" if they > wanted to, but wouldn't be mandatory since they could apply it to their > own branch to work on. Let's go with this as our "plan". Jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-04 22:09 ` David Malcolm 2013-11-04 22:31 ` Andrew MacLeod @ 2013-11-04 22:43 ` Andrew MacLeod 1 sibling, 0 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-11-04 22:43 UTC (permalink / raw) To: David Malcolm; +Cc: Jakub Jelinek, gcc-patches On 11/04/2013 05:03 PM, David Malcolm wrote: > I believe it would be easiest to do them one subclass at-a-time e.g. > convert all gimple_call_* functions to accepting a gimple_call, then > another subclass etc - assuming that this approach is blessed by the > core reviewers. > I think the strategy for reworking the gimple stmts needs quite a bit of experimenting to determine what would have to be done and what it would look like, and to get buy in from more people that the end result is indeed acceptable. There are complex situation, and I dont see how we can avoid virtual functions in some cases (at least not easily without resorting to ugly as_a/is_a/dyn_cast functions). So I thinkit needs research. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-04 21:52 ` David Malcolm 2013-11-04 22:09 ` David Malcolm @ 2013-11-04 22:28 ` Jakub Jelinek 2013-11-04 22:49 ` Andrew MacLeod 2013-11-05 21:09 ` Jeff Law 2013-11-05 11:53 ` Richard Biener 2 siblings, 2 replies; 116+ messages in thread From: Jakub Jelinek @ 2013-11-04 22:28 UTC (permalink / raw) To: David Malcolm; +Cc: Andrew MacLeod, gcc-patches On Mon, Nov 04, 2013 at 04:43:33PM -0500, David Malcolm wrote: > I tried converting gimple_call_set_lhs to accept a gimple_call, rather > than a gimple, and excitingly, it was easiest to also convert > cgraph_edge's call_stmt to also be a gimple_call, rather than just a > gimple. > > Am attaching a patch (on top of the patch series being discussed) which > adds this compile-time typesafety; bootstrap is in-progress. IMHO very > little use of is-a.h was needed (5 instances of as_a, and 3 of dyn_cast; > no use of is_a). But that was just for gimple_call_set_lhs, which indeed usually is done just for newly created calls, not for inspecting preexisting IL. If you do it for say gimple_call_arg, gimple_call_fndecl and/or even gimple_call_lhs, I'm afraid suddenly it would be hundreds of ugly dyn_casts/as_a and similar mess everywhere. And, calls are still far less common gimple statements than gimple assign. Jakub ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-04 22:28 ` Jakub Jelinek @ 2013-11-04 22:49 ` Andrew MacLeod 2013-11-05 21:09 ` Jeff Law 1 sibling, 0 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-11-04 22:49 UTC (permalink / raw) To: Jakub Jelinek; +Cc: David Malcolm, gcc-patches On 11/04/2013 05:25 PM, Jakub Jelinek wrote: > On Mon, Nov 04, 2013 at 04:43:33PM -0500, David Malcolm wrote: >> I tried converting gimple_call_set_lhs to accept a gimple_call, rather >> than a gimple, and excitingly, it was easiest to also convert >> cgraph_edge's call_stmt to also be a gimple_call, rather than just a >> gimple. >> >> Am attaching a patch (on top of the patch series being discussed) which >> adds this compile-time typesafety; bootstrap is in-progress. IMHO very >> little use of is-a.h was needed (5 instances of as_a, and 3 of dyn_cast; >> no use of is_a). > But that was just for gimple_call_set_lhs, which indeed usually is done just > for newly created calls, not for inspecting preexisting IL. If you do it > for say gimple_call_arg, gimple_call_fndecl and/or even gimple_call_lhs, I'm > afraid suddenly it would be hundreds of ugly dyn_casts/as_a and similar mess > everywhere. And, calls are still far less common gimple statements than > gimple assign. > > Indeed, we need to look at a much larger swath of code before even thinking of committing anything. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-04 22:28 ` Jakub Jelinek 2013-11-04 22:49 ` Andrew MacLeod @ 2013-11-05 21:09 ` Jeff Law 1 sibling, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-05 21:09 UTC (permalink / raw) To: Jakub Jelinek, David Malcolm; +Cc: Andrew MacLeod, gcc-patches On 11/04/13 15:25, Jakub Jelinek wrote: > On Mon, Nov 04, 2013 at 04:43:33PM -0500, David Malcolm wrote: >> I tried converting gimple_call_set_lhs to accept a gimple_call, rather >> than a gimple, and excitingly, it was easiest to also convert >> cgraph_edge's call_stmt to also be a gimple_call, rather than just a >> gimple. >> >> Am attaching a patch (on top of the patch series being discussed) which >> adds this compile-time typesafety; bootstrap is in-progress. IMHO very >> little use of is-a.h was needed (5 instances of as_a, and 3 of dyn_cast; >> no use of is_a). > > But that was just for gimple_call_set_lhs, which indeed usually is done just > for newly created calls, not for inspecting preexisting IL. If you do it > for say gimple_call_arg, gimple_call_fndecl and/or even gimple_call_lhs, I'm > afraid suddenly it would be hundreds of ugly dyn_casts/as_a and similar mess > everywhere. And, calls are still far less common gimple statements than > gimple assign. Understood. I think one of the questions we need to answer is when a conversion of this nature is done (towards static typechecking), how often will we know the static type vs how often we're going to have to play these is_a/as_a games. I'd claim that often if we're stuck with needing is_a/as_a, then we've got some refactoring to do. Based on discussions Andrew, David & myself had today, my gut says let's try to go foward with the basic conversion based on its merits as they stand today, but without taking the step towards static typing at this time. Jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-04 21:52 ` David Malcolm 2013-11-04 22:09 ` David Malcolm 2013-11-04 22:28 ` Jakub Jelinek @ 2013-11-05 11:53 ` Richard Biener 2013-11-05 12:33 ` David Malcolm 2 siblings, 1 reply; 116+ messages in thread From: Richard Biener @ 2013-11-05 11:53 UTC (permalink / raw) To: David Malcolm; +Cc: Andrew MacLeod, Jakub Jelinek, GCC Patches On Mon, Nov 4, 2013 at 10:43 PM, David Malcolm <dmalcolm@redhat.com> wrote: > On Mon, 2013-11-04 at 08:19 -0500, Andrew MacLeod wrote: >> On 11/01/2013 06:58 PM, David Malcolm wrote: >> > On Fri, 2013-11-01 at 22:57 +0100, Jakub Jelinek wrote: >> >> On Fri, Nov 01, 2013 at 05:47:14PM -0400, Andrew MacLeod wrote: >> >>> On 11/01/2013 05:41 PM, Jakub Jelinek wrote: >> >>>> On Fri, Nov 01, 2013 at 05:36:34PM -0400, Andrew MacLeod wrote: >> >>>>> static inline void >> >>>>> ! gimple_call_set_lhs (gimple gs, tree lhs) >> >>>>> { >> >>>>> - GIMPLE_CHECK (gs, GIMPLE_CALL); >> >> The checking you are removing here. >> >> >> >>> What checking? There ought to be no checking at all in this >> >>> example... gimple_build_call_vec returns a gimple_call, and >> >>> gimple_call_set_lhs() doesn't have to check anything because it >> >>> only accepts gimple_call's.. so there is no checking other than the >> >>> usual "does my parameter match" that the compiler has to do... >> >> and want to replace it by checking of the types at compile time. >> >> The problem is that it uglifies the source too much, and, when you >> >> actually don't have a gimple_call but supposedly a base class of it, >> >> I expect you'd do as_a which is not only further uglification, but has >> >> runtime cost also for --enable-checking=release. >> > I can have a look next week at every call to gimple_call_set_lhs in the >> > tree, and see to what extent we know at compile-time that the initial >> > arg is indeed a call (of the ones I quickly grepped just now, most are >> > from gimple_build_call and friends, but one was from a gimple_copy). >> > >> > FWIW I did some performance testing of the is_a/as_a code in the earlier >> > version of the patch, and it didn't have a noticable runtime cost >> > compared to the GIMPLE_CHECK in the existing code: >> > Size of compiler executable: >> > http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01920.html >> > Compile times: >> > http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00171.html >> I actually really dislike as_a<> and is_a<>, and think code needs to be >> restructured rather than use them, other than possibly at the very >> bottom level when we're allocating memory or something like that, or >> some kind of emergency :-)... If we require frequent uses of those, >> I'd be against it, I find them quite ugly. >> >> Like I said in the other reply, no rush, I don't think any of this >> follow up is appropriate this late in stage 1. It would be more of an >> "interest" examination right now.. at least in my opinion... I suspect >> thinks like gimple_assign are more complex cases, but without looking >> its hard to tell for sure. > > I tried converting gimple_call_set_lhs to accept a gimple_call, rather > than a gimple, and excitingly, it was easiest to also convert > cgraph_edge's call_stmt to also be a gimple_call, rather than just a > gimple. Does that work (using gimple_call * objects) for our garbage collector? That is, does it know it is looking at a 'gimple'? It doesn't matter for this case as all stmts are reachable from struct function as sequence of 'gimple', but in general? Richard. > Am attaching a patch (on top of the patch series being discussed) which > adds this compile-time typesafety; bootstrap is in-progress. IMHO very > little use of is-a.h was needed (5 instances of as_a, and 3 of dyn_cast; > no use of is_a). > > I'm also attaching a followup patch which eliminates gimple_call_set_lhs > in favor of a method of gimple_statement_call. > ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-05 11:53 ` Richard Biener @ 2013-11-05 12:33 ` David Malcolm 2013-11-05 12:52 ` Richard Biener 0 siblings, 1 reply; 116+ messages in thread From: David Malcolm @ 2013-11-05 12:33 UTC (permalink / raw) To: Richard Biener; +Cc: Andrew MacLeod, Jakub Jelinek, GCC Patches On Tue, 2013-11-05 at 12:47 +0100, Richard Biener wrote: > On Mon, Nov 4, 2013 at 10:43 PM, David Malcolm <dmalcolm@redhat.com> wrote: > > On Mon, 2013-11-04 at 08:19 -0500, Andrew MacLeod wrote: > >> On 11/01/2013 06:58 PM, David Malcolm wrote: > >> > On Fri, 2013-11-01 at 22:57 +0100, Jakub Jelinek wrote: > >> >> On Fri, Nov 01, 2013 at 05:47:14PM -0400, Andrew MacLeod wrote: > >> >>> On 11/01/2013 05:41 PM, Jakub Jelinek wrote: > >> >>>> On Fri, Nov 01, 2013 at 05:36:34PM -0400, Andrew MacLeod wrote: > >> >>>>> static inline void > >> >>>>> ! gimple_call_set_lhs (gimple gs, tree lhs) > >> >>>>> { > >> >>>>> - GIMPLE_CHECK (gs, GIMPLE_CALL); > >> >> The checking you are removing here. > >> >> > >> >>> What checking? There ought to be no checking at all in this > >> >>> example... gimple_build_call_vec returns a gimple_call, and > >> >>> gimple_call_set_lhs() doesn't have to check anything because it > >> >>> only accepts gimple_call's.. so there is no checking other than the > >> >>> usual "does my parameter match" that the compiler has to do... > >> >> and want to replace it by checking of the types at compile time. > >> >> The problem is that it uglifies the source too much, and, when you > >> >> actually don't have a gimple_call but supposedly a base class of it, > >> >> I expect you'd do as_a which is not only further uglification, but has > >> >> runtime cost also for --enable-checking=release. > >> > I can have a look next week at every call to gimple_call_set_lhs in the > >> > tree, and see to what extent we know at compile-time that the initial > >> > arg is indeed a call (of the ones I quickly grepped just now, most are > >> > from gimple_build_call and friends, but one was from a gimple_copy). > >> > > >> > FWIW I did some performance testing of the is_a/as_a code in the earlier > >> > version of the patch, and it didn't have a noticable runtime cost > >> > compared to the GIMPLE_CHECK in the existing code: > >> > Size of compiler executable: > >> > http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01920.html > >> > Compile times: > >> > http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00171.html > >> I actually really dislike as_a<> and is_a<>, and think code needs to be > >> restructured rather than use them, other than possibly at the very > >> bottom level when we're allocating memory or something like that, or > >> some kind of emergency :-)... If we require frequent uses of those, > >> I'd be against it, I find them quite ugly. > >> > >> Like I said in the other reply, no rush, I don't think any of this > >> follow up is appropriate this late in stage 1. It would be more of an > >> "interest" examination right now.. at least in my opinion... I suspect > >> thinks like gimple_assign are more complex cases, but without looking > >> its hard to tell for sure. > > > > I tried converting gimple_call_set_lhs to accept a gimple_call, rather > > than a gimple, and excitingly, it was easiest to also convert > > cgraph_edge's call_stmt to also be a gimple_call, rather than just a > > gimple. > > Does that work (using gimple_call * objects) for our garbage collector? > That is, does it know it is looking at a 'gimple'? It doesn't matter for this > case as all stmts are reachable from struct function as sequence of 'gimple', > but in general? Yes (as of r204146, I believe). For example, the patch converts cgraph_edge's call_stmt to be a "gimple_call", rather than just a "gimple", but gengtype handles this by emitting a call to the base class visitor for call_stmt i.e. gimple_statement_base: void gt_ggc_mx_cgraph_edge (void *x_p) { struct cgraph_edge * x = (struct cgraph_edge *)x_p; [...snip chain_next/prev handling...] [...snip other fields...] gt_ggc_m_21gimple_statement_base ((*x).call_stmt); [..etc..] } ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-05 12:33 ` David Malcolm @ 2013-11-05 12:52 ` Richard Biener 0 siblings, 0 replies; 116+ messages in thread From: Richard Biener @ 2013-11-05 12:52 UTC (permalink / raw) To: David Malcolm; +Cc: Andrew MacLeod, Jakub Jelinek, GCC Patches On Tue, Nov 5, 2013 at 1:30 PM, David Malcolm <dmalcolm@redhat.com> wrote: > On Tue, 2013-11-05 at 12:47 +0100, Richard Biener wrote: >> On Mon, Nov 4, 2013 at 10:43 PM, David Malcolm <dmalcolm@redhat.com> wrote: >> > On Mon, 2013-11-04 at 08:19 -0500, Andrew MacLeod wrote: >> >> On 11/01/2013 06:58 PM, David Malcolm wrote: >> >> > On Fri, 2013-11-01 at 22:57 +0100, Jakub Jelinek wrote: >> >> >> On Fri, Nov 01, 2013 at 05:47:14PM -0400, Andrew MacLeod wrote: >> >> >>> On 11/01/2013 05:41 PM, Jakub Jelinek wrote: >> >> >>>> On Fri, Nov 01, 2013 at 05:36:34PM -0400, Andrew MacLeod wrote: >> >> >>>>> static inline void >> >> >>>>> ! gimple_call_set_lhs (gimple gs, tree lhs) >> >> >>>>> { >> >> >>>>> - GIMPLE_CHECK (gs, GIMPLE_CALL); >> >> >> The checking you are removing here. >> >> >> >> >> >>> What checking? There ought to be no checking at all in this >> >> >>> example... gimple_build_call_vec returns a gimple_call, and >> >> >>> gimple_call_set_lhs() doesn't have to check anything because it >> >> >>> only accepts gimple_call's.. so there is no checking other than the >> >> >>> usual "does my parameter match" that the compiler has to do... >> >> >> and want to replace it by checking of the types at compile time. >> >> >> The problem is that it uglifies the source too much, and, when you >> >> >> actually don't have a gimple_call but supposedly a base class of it, >> >> >> I expect you'd do as_a which is not only further uglification, but has >> >> >> runtime cost also for --enable-checking=release. >> >> > I can have a look next week at every call to gimple_call_set_lhs in the >> >> > tree, and see to what extent we know at compile-time that the initial >> >> > arg is indeed a call (of the ones I quickly grepped just now, most are >> >> > from gimple_build_call and friends, but one was from a gimple_copy). >> >> > >> >> > FWIW I did some performance testing of the is_a/as_a code in the earlier >> >> > version of the patch, and it didn't have a noticable runtime cost >> >> > compared to the GIMPLE_CHECK in the existing code: >> >> > Size of compiler executable: >> >> > http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01920.html >> >> > Compile times: >> >> > http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00171.html >> >> I actually really dislike as_a<> and is_a<>, and think code needs to be >> >> restructured rather than use them, other than possibly at the very >> >> bottom level when we're allocating memory or something like that, or >> >> some kind of emergency :-)... If we require frequent uses of those, >> >> I'd be against it, I find them quite ugly. >> >> >> >> Like I said in the other reply, no rush, I don't think any of this >> >> follow up is appropriate this late in stage 1. It would be more of an >> >> "interest" examination right now.. at least in my opinion... I suspect >> >> thinks like gimple_assign are more complex cases, but without looking >> >> its hard to tell for sure. >> > >> > I tried converting gimple_call_set_lhs to accept a gimple_call, rather >> > than a gimple, and excitingly, it was easiest to also convert >> > cgraph_edge's call_stmt to also be a gimple_call, rather than just a >> > gimple. >> >> Does that work (using gimple_call * objects) for our garbage collector? >> That is, does it know it is looking at a 'gimple'? It doesn't matter for this >> case as all stmts are reachable from struct function as sequence of 'gimple', >> but in general? > Yes (as of r204146, I believe). > > For example, the patch converts cgraph_edge's call_stmt to be a > "gimple_call", rather than just a "gimple", but gengtype handles this by > emitting a call to the base class visitor for call_stmt i.e. > gimple_statement_base: > > void > gt_ggc_mx_cgraph_edge (void *x_p) > { > struct cgraph_edge * x = (struct cgraph_edge *)x_p; > [...snip chain_next/prev handling...] > [...snip other fields...] > gt_ggc_m_21gimple_statement_base ((*x).call_stmt); > [..etc..] > } Ah, nice to know. Thanks, Richard. > ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-01 21:57 ` Jakub Jelinek 2013-11-01 22:58 ` David Malcolm @ 2013-11-04 14:00 ` Andrew MacLeod 2013-11-04 14:01 ` Jakub Jelinek 1 sibling, 1 reply; 116+ messages in thread From: Andrew MacLeod @ 2013-11-04 14:00 UTC (permalink / raw) To: Jakub Jelinek; +Cc: David Malcolm, gcc-patches On 11/01/2013 05:57 PM, Jakub Jelinek wrote: > On Fri, Nov 01, 2013 at 05:47:14PM -0400, Andrew MacLeod wrote: >> On 11/01/2013 05:41 PM, Jakub Jelinek wrote: >>> On Fri, Nov 01, 2013 at 05:36:34PM -0400, Andrew MacLeod wrote: >>>> static inline void >>>> ! gimple_call_set_lhs (gimple gs, tree lhs) >>>> { >>>> - GIMPLE_CHECK (gs, GIMPLE_CALL); > The checking you are removing here. > >> What checking? There ought to be no checking at all in this >> example... gimple_build_call_vec returns a gimple_call, and >> gimple_call_set_lhs() doesn't have to check anything because it >> only accepts gimple_call's.. so there is no checking other than the >> usual "does my parameter match" that the compiler has to do... > and want to replace it by checking of the types at compile time. > The problem is that it uglifies the source too much, and, when you > actually don't have a gimple_call but supposedly a base class of it, But when you convert all the source base for gimple calls, then you have context pretty much everywhere.. you wont be doing it from a base class... at least pretty infrequently. > I expect you'd do as_a which is not only further uglification, but has > runtime cost also for --enable-checking=release. > > Im not a fan of as_a<> or is_a<> at all. I really dislike them. They should be kept to the barest minimum, or even non existent if possible..... If you need it, you probably need restructured source. ie, functions which work with switches on gimple_code() need to be restructured... And the end result should look cleaner. Of course, thats what makes it a big project too :-) Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-04 14:00 ` Andrew MacLeod @ 2013-11-04 14:01 ` Jakub Jelinek 2013-11-04 14:15 ` Andrew MacLeod 0 siblings, 1 reply; 116+ messages in thread From: Jakub Jelinek @ 2013-11-04 14:01 UTC (permalink / raw) To: Andrew MacLeod; +Cc: David Malcolm, gcc-patches On Mon, Nov 04, 2013 at 08:54:40AM -0500, Andrew MacLeod wrote: > >>What checking? There ought to be no checking at all in this > >>example... gimple_build_call_vec returns a gimple_call, and > >>gimple_call_set_lhs() doesn't have to check anything because it > >>only accepts gimple_call's.. so there is no checking other than the > >>usual "does my parameter match" that the compiler has to do... > >and want to replace it by checking of the types at compile time. > >The problem is that it uglifies the source too much, and, when you > >actually don't have a gimple_call but supposedly a base class of it, > > But when you convert all the source base for gimple calls, then you > have context pretty much everywhere.. you wont be doing it from a > base class... at least pretty infrequently. Usually you just have IL which contains various kinds of statements, it can be a call, assign, dozens of other gimple stmt forms. If you need to modify something in these, you'd need to uglify with as_a/is_a if you require everybody using these setters/getters to use gimple_call * rather than gimple, pointer to any kind of stmt. Jakub ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-04 14:01 ` Jakub Jelinek @ 2013-11-04 14:15 ` Andrew MacLeod 0 siblings, 0 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-11-04 14:15 UTC (permalink / raw) To: Jakub Jelinek; +Cc: David Malcolm, gcc-patches On 11/04/2013 09:00 AM, Jakub Jelinek wrote: > On Mon, Nov 04, 2013 at 08:54:40AM -0500, Andrew MacLeod wrote: >>>> What checking? There ought to be no checking at all in this >>>> example... gimple_build_call_vec returns a gimple_call, and >>>> gimple_call_set_lhs() doesn't have to check anything because it >>>> only accepts gimple_call's.. so there is no checking other than the >>>> usual "does my parameter match" that the compiler has to do... >>> and want to replace it by checking of the types at compile time. >>> The problem is that it uglifies the source too much, and, when you >>> actually don't have a gimple_call but supposedly a base class of it, >> But when you convert all the source base for gimple calls, then you >> have context pretty much everywhere.. you wont be doing it from a >> base class... at least pretty infrequently. > Usually you just have IL which contains various kinds of statements, > it can be a call, assign, dozens of other gimple stmt forms. > If you need to modify something in these, you'd need to uglify with > as_a/is_a if you require everybody using these setters/getters to use > gimple_call * rather than gimple, pointer to any kind of stmt. > > Jakub In many cases splitting out the case body and typing functions will surprisingly cover many of the the uses required. Proper subclassing will cover a lot too if the get/set methods are in the right classes. In cases where none of this works... well, there is an appropriate time for a virtual function... Thats really all those kinds off switches are implementing.... but I won't get into that meta discussion right now :-). We can save that for someday when there is actually a real proposal on the table. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-01 21:41 ` Jakub Jelinek 2013-11-01 21:47 ` Andrew MacLeod @ 2013-11-04 18:23 ` Jeff Law 1 sibling, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-04 18:23 UTC (permalink / raw) To: Jakub Jelinek, Andrew MacLeod; +Cc: David Malcolm, gcc-patches On 11/01/13 15:41, Jakub Jelinek wrote: > On Fri, Nov 01, 2013 at 05:36:34PM -0400, Andrew MacLeod wrote: >> static inline void >> ! gimple_call_set_lhs (gimple gs, tree lhs) >> { >> - GIMPLE_CHECK (gs, GIMPLE_CALL); >> gimple_set_op (gs, 0, lhs); >> to >> static inline void >> ! gimple_call_set_lhs (gimple_statement_call *gs, tree lhs) >> { >> gimple_set_op (gs, 0, lhs); >> >> >> but then every location that calls it needs an appropriate change: >> >> ! gimple call; >> ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, >> alias), vargs); >> gimple_call_set_lhs (call, atree); >> >> --- 1518,1524 ---- >> >> ! gimple_statement_call *call; >> ! call = as_a<gimple_statement_call> (gimple_build_call_vec >> (build_fold_addr_expr_loc (0, alias), vargs)); >> gimple_call_set_lhs (call, atree); >> >> And in fact there is a ripple effect to then change >> gimple_build_call_vec to simply return a gimple_statement_call *... >> Then this doesn't look as ugly either... >> >> ! gimple_statement_call *call; >> ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, >> alias), vargs); >> gimple_call_set_lhs (call, atree); >> >> that is looking much better :-) > > Do you seriously think this is an improvement? The cost of changing > the --enable-checking=yes cost to compile time checking in either > cases sounds way too high to me. Please don't. ?!? One of the things we're reallying trying to do here is be type safe and use the type system to check for things at compile-time rather than runtime checks. jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-01 21:36 ` Andrew MacLeod 2013-11-01 21:41 ` Jakub Jelinek @ 2013-11-01 22:43 ` David Malcolm 2013-11-01 23:43 ` Trevor Saunders 2013-11-04 13:15 ` Andrew MacLeod 2013-11-05 17:23 ` [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) David Malcolm 2013-11-05 18:22 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) Andrew MacLeod 3 siblings, 2 replies; 116+ messages in thread From: David Malcolm @ 2013-11-01 22:43 UTC (permalink / raw) To: Andrew MacLeod; +Cc: gcc-patches On Fri, 2013-11-01 at 17:36 -0400, Andrew MacLeod wrote: > On 10/31/2013 12:26 PM, David Malcolm wrote: > > [Shamelessly hijacking Andrew's thread about gimple.h refactoring, > > since this seems on-topic for that, and I'm keen to hear from Andrew on > > how the following would interact with his work - I *think* our two > > cleanups are orthogonal. > > Mostly orthogonal anyway... just stomping on the same bits :-). > > Since you hijacked a planning thread, do you plan to take this any > further, or make this change and move on to something else? I have various changes that are mostly done that I'm trying to get finished and into trunk for stage1. These can be seen at: https://github.com/davidmalcolm/gcc-refactoring-scripts/blob/master/README.rst If you want me to do more follow cleanups to gimple, I can do those. > It is a start, but it doesnt do the rest of the work that needs doing to > really take advantage of it... which will be extensive. > for instance, we should change: > > static inline void > ! gimple_call_set_lhs (gimple gs, tree lhs) > { > - GIMPLE_CHECK (gs, GIMPLE_CALL); > gimple_set_op (gs, 0, lhs); > to > static inline void > ! gimple_call_set_lhs (gimple_statement_call *gs, tree lhs) > { > gimple_set_op (gs, 0, lhs); > > > but then every location that calls it needs an appropriate change: > > ! gimple call; > ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, > alias), vargs); > gimple_call_set_lhs (call, atree); > > --- 1518,1524 ---- > > ! gimple_statement_call *call; > ! call = as_a<gimple_statement_call> (gimple_build_call_vec > (build_fold_addr_expr_loc (0, alias), vargs)); > gimple_call_set_lhs (call, atree); > > And in fact there is a ripple effect to then change > gimple_build_call_vec to simply return a gimple_statement_call *... Then > this doesn't look as ugly either... > > ! gimple_statement_call *call; > ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, > alias), vargs); > gimple_call_set_lhs (call, atree); > > that is looking much better :-) I'd love to make use of compile-time type-safety like this, but does this have to gate this initial step? The transition to strongly-typed getters/setters could be done one at-a-time, I guess. > Leaving the names as they are should be ok, but the I'd also add a > typedef for the pointer without the 'statement' in the name.. ie > typedef gimple_statement_call *gimple_call; > That seems in line with what we do with 'gimple' right now and the short > form is the type we'd normally use. > > That adds a touch of difficulty with "as_a", since that requires the > type name, not the shorthand pointer.... so you have something like > gimple_call call = as_a <gimple_statement_call> blah(). > I think as the changes to use the gimple_call type are pushed through > all the callers and callee's, the requirement of as_a and the long name > being ugly begins to rapidly disappear... it'll only exist in the core > creation routines and no one will usually see it. So I don't *think* > this is an issue... but it is an ugly transition if its only partially > done. (nods) > And eventually we can pull the accessor routines and others into the > class itself: > gimple_call call; > call = gimple_build_call_vec (build_fold_addr_expr_loc (0, > alias), vargs); > call->set_lhs (atree); Nice. It's readable (IMHO), and the type-checking (that it's a call) is enforced at compile-time, rather than at run-time (and only in ENABLE_CHECKING builds). Sadly, this may need some further gengtype work: the simple inheritance support I'm using in this patch series will barf if it sees methods within a class. So I can have a look at supporting methods in gengtype, I guess. Though the change above of gimple_call_set_lhs to accepting a subclass ptr gives a middle-ground. > Which results in a similar feel to the new gimple_type, gimple_decl, > etc. classes with my upcoming tree wrappers. Changing gimple statements > to behave something like this is actually mentioned in the plan, but out > in the future once trees have been taken care of. > > I would also plan to create instances for each of the gimple statements By "instances" presumably you meant "subclasses"? > that don't have them now, like gimple_statement_assign. Its lumped in as > a general GSS_WITH_MEM_OPS, so there is no gimple_statement_assign > class/struct to use. > It would really be nice to use the DEFGSCODE macro and gimple.def to > make this happen automagically somehow... Its tantalizingly close now I > think, especially combined with the info in gsstruct.def... Although if > we are moving to proper classes eventually its probably better to > explicitly write the required class for a statement kind. I think writing them out explicitly is better than doing them with preprocessor magic: if we go down the route described above of wanting to add methods, the various subclasses will eventually gain their own methods, so we'll want code rather than building it all from .def files. > That all said, this change enables that work to proceed if someone wants > to do it. > > My question is: Is anyone going to do it, and if so, who and when? :-) I'd be up for working on a followup patch that adds such subclasses, and I'd be up for changing the accessors to give up compile-time type-safety. I'd do it one accessor at a time. > > Again, as noted in the earlier patch series, the names of the structs > > are rather verbose. I would prefer to also rename them all to eliminate > > the "_statement" component: > > "gimple_statement_base" -> "gimple_base" > > "gimple_statement_phi" -> "gimple_phi" > > "gimple_statement_omp" -> "gimple_omp" > > etc, but I didn't do this to mimimize the patch size. But if the core > > maintainers are up for that, I can redo the patch series with that > > change also, or do that as a followup. > > As mentioned, I'd rather see the short names be typedefs for pointers to > the long names since we're typically using the pointers. [FWIW, I'm not a fan of such typedefs, but I'll defer to you in this] Presumably we'd want typedefs for the extra subclasses as well? Also, I take it we'd use the "printable_name" from gimple.def - though would we use it for the subclass name, or for the ptr typedef? > Other than stomping on the same bits at the moment (less so once > gimple-stmt.[ch] is split out), these changes are completely orthogonal, > but in line with with my direction. I think It should be done sooner or > later.... My preference is to also see the follow up work carried out > as well. Or at least a plan for it. So you like the approach, provided I commit to the followup work? [1] OK, I'll try to create some followup patches next week. I'd prefer to get the conversion to inheritance into trunk sooner rather than later, though. Thanks for looking at this (and for your cleanup work!) Dave [1] and the patches still need formal review. ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-01 22:43 ` David Malcolm @ 2013-11-01 23:43 ` Trevor Saunders 2013-11-04 13:15 ` Andrew MacLeod 1 sibling, 0 replies; 116+ messages in thread From: Trevor Saunders @ 2013-11-01 23:43 UTC (permalink / raw) To: David Malcolm; +Cc: Andrew MacLeod, gcc-patches > > It is a start, but it doesnt do the rest of the work that needs doing to > > really take advantage of it... which will be extensive. > > for instance, we should change: > > > > static inline void > > ! gimple_call_set_lhs (gimple gs, tree lhs) > > { > > - GIMPLE_CHECK (gs, GIMPLE_CALL); > > gimple_set_op (gs, 0, lhs); > > to > > static inline void > > ! gimple_call_set_lhs (gimple_statement_call *gs, tree lhs) > > { > > gimple_set_op (gs, 0, lhs); > > > > > > but then every location that calls it needs an appropriate change: > > > > ! gimple call; > > ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, > > alias), vargs); > > gimple_call_set_lhs (call, atree); > > > > --- 1518,1524 ---- > > > > ! gimple_statement_call *call; > > ! call = as_a<gimple_statement_call> (gimple_build_call_vec > > (build_fold_addr_expr_loc (0, alias), vargs)); > > gimple_call_set_lhs (call, atree); > > > > And in fact there is a ripple effect to then change > > gimple_build_call_vec to simply return a gimple_statement_call *... Then > > this doesn't look as ugly either... > > > > ! gimple_statement_call *call; > > ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, > > alias), vargs); > > gimple_call_set_lhs (call, atree); > > > > that is looking much better :-) > > I'd love to make use of compile-time type-safety like this, but does > this have to gate this initial step? I don't think Andrew was suggesting it should, but fwiw I agree with you one step at a time. > The transition to strongly-typed getters/setters could be done one > at-a-time, I guess. I actually have a slightly different suggestion, see below. > > Leaving the names as they are should be ok, but the I'd also add a > > typedef for the pointer without the 'statement' in the name.. ie > > typedef gimple_statement_call *gimple_call; > > That seems in line with what we do with 'gimple' right now and the short > > form is the type we'd normally use. > > > > That adds a touch of difficulty with "as_a", since that requires the > > type name, not the shorthand pointer.... so you have something like > > gimple_call call = as_a <gimple_statement_call> blah(). > > I think as the changes to use the gimple_call type are pushed through > > all the callers and callee's, the requirement of as_a and the long name > > being ugly begins to rapidly disappear... it'll only exist in the core > > creation routines and no one will usually see it. So I don't *think* > > this is an issue... but it is an ugly transition if its only partially > > done. > > (nods) > > > And eventually we can pull the accessor routines and others into the > > class itself: > > gimple_call call; > > call = gimple_build_call_vec (build_fold_addr_expr_loc (0, > > alias), vargs); > > call->set_lhs (atree); > > Nice. It's readable (IMHO), and the type-checking (that it's a call) is > enforced at compile-time, rather than at run-time (and only in > ENABLE_CHECKING builds). Well, if you never need to downcast its always enforced by the type system. > Sadly, this may need some further gengtype work: the simple inheritance > support I'm using in this patch series will barf if it sees methods > within a class. So I can have a look at supporting methods in gengtype, > I guess. Though the change above of gimple_call_set_lhs to accepting a > subclass ptr gives a middle-ground. hm, I have a patch around that adds member functions to symtab_node and gentype doesn't fall over on it, is it just sub classes maybe? Anyway to avoid churn multiple times / ugly intermediates what I think we should do is: 1. add methods to the sub classes as appropriate (fixing gentype first if needed). 2. change creator functions to return dirived types. 3. when we already have the sub type replace the function with the method. 4. when all uses of the function are gone remove it. > > that don't have them now, like gimple_statement_assign. Its lumped in as > > a general GSS_WITH_MEM_OPS, so there is no gimple_statement_assign > > class/struct to use. > > > It would really be nice to use the DEFGSCODE macro and gimple.def to > > make this happen automagically somehow... Its tantalizingly close now I > > think, especially combined with the info in gsstruct.def... Although if > > we are moving to proper classes eventually its probably better to > > explicitly write the required class for a statement kind. > > I think writing them out explicitly is better than doing them with > preprocessor magic: if we go down the route described above of wanting > to add methods, the various subclasses will eventually gain their own > methods, so we'll want code rather than building it all from .def files. agreed. > > That all said, this change enables that work to proceed if someone wants > > to do it. > > > > My question is: Is anyone going to do it, and if so, who and when? :-) > > I'd be up for working on a followup patch that adds such subclasses, and > I'd be up for changing the accessors to give up compile-time > type-safety. I'd do it one accessor at a time. I'd be happy to work on this too. > > > Again, as noted in the earlier patch series, the names of the structs > > > are rather verbose. I would prefer to also rename them all to eliminate > > > the "_statement" component: > > > "gimple_statement_base" -> "gimple_base" > > > "gimple_statement_phi" -> "gimple_phi" > > > "gimple_statement_omp" -> "gimple_omp" > > > etc, but I didn't do this to mimimize the patch size. But if the core > > > maintainers are up for that, I can redo the patch series with that > > > change also, or do that as a followup. > > > > As mentioned, I'd rather see the short names be typedefs for pointers to > > the long names since we're typically using the pointers. > > [FWIW, I'm not a fan of such typedefs, but I'll defer to you in this] agreed, especially since C++ lets us omit the struct / class part anyway. Trev > Also, I take it we'd use the "printable_name" from gimple.def - though > would we use it for the subclass name, or for the ptr typedef? > > > Other than stomping on the same bits at the moment (less so once > > gimple-stmt.[ch] is split out), these changes are completely orthogonal, > > but in line with with my direction. I think It should be done sooner or > > later.... My preference is to also see the follow up work carried out > > as well. Or at least a plan for it. > > So you like the approach, provided I commit to the followup work? [1] > > OK, I'll try to create some followup patches next week. I'd prefer to > get the conversion to inheritance into trunk sooner rather than later, > though. > > Thanks for looking at this (and for your cleanup work!) > > Dave > [1] and the patches still need formal review. > ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-01 22:43 ` David Malcolm 2013-11-01 23:43 ` Trevor Saunders @ 2013-11-04 13:15 ` Andrew MacLeod 1 sibling, 0 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-11-04 13:15 UTC (permalink / raw) To: David Malcolm; +Cc: gcc-patches On 11/01/2013 06:42 PM, David Malcolm wrote: > >> ! gimple_statement_call *call; >> ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, >> alias), vargs); >> gimple_call_set_lhs (call, atree); >> >> that is looking much better :-) > I'd love to make use of compile-time type-safety like this, but does > this have to gate this initial step? no, I wasn't implying it did... just mapping out what I think we can go on to do with it. > >> And eventually we can pull the accessor routines and others into the >> class itself: >> gimple_call call; >> call = gimple_build_call_vec (build_fold_addr_expr_loc (0, >> alias), vargs); >> call->set_lhs (atree); > Nice. It's readable (IMHO), and the type-checking (that it's a call) is > enforced at compile-time, rather than at run-time (and only in > ENABLE_CHECKING builds). > > Sadly, this may need some further gengtype work: the simple inheritance > support I'm using in this patch series will barf if it sees methods > within a class. So I can have a look at supporting methods in gengtype, > I guess. Though the change above of gimple_call_set_lhs to accepting a > subclass ptr gives a middle-ground. Eventually this is going to be an issue elsewhere as well. Whats the problem with methods in gengtype? it just doesn't parse them? or something deeper and more insidious? >> Which results in a similar feel to the new gimple_type, gimple_decl, >> etc. classes with my upcoming tree wrappers. Changing gimple statements >> to behave something like this is actually mentioned in the plan, but out >> in the future once trees have been taken care of. >> >> I would also plan to create instances for each of the gimple statements > By "instances" presumably you meant "subclasses"? yeah. >> That all said, this change enables that work to proceed if someone wants >> to do it. >> >> My question is: Is anyone going to do it, and if so, who and when? :-) > I'd be up for working on a followup patch that adds such subclasses, and > I'd be up for changing the accessors to give up compile-time > type-safety. I'd do it one accessor at a time. Its probably pushing it for 4.9... and doesn't really serve much purpose to try do do any of this followup work now. Probably a better task for the next stage 1 anyway when there is time to fully flush it out and prove the various improvements to have full support from everyone :-) >>> Again, as noted in the earlier patch series, the names of the structs >>> are rather verbose. I would prefer to also rename them all to eliminate >>> the "_statement" component: >>> "gimple_statement_base" -> "gimple_base" >>> "gimple_statement_phi" -> "gimple_phi" >>> "gimple_statement_omp" -> "gimple_omp" >>> etc, but I didn't do this to mimimize the patch size. But if the core >>> maintainers are up for that, I can redo the patch series with that >>> change also, or do that as a followup. >> As mentioned, I'd rather see the short names be typedefs for pointers to >> the long names since we're typically using the pointers. > [FWIW, I'm not a fan of such typedefs, but I'll defer to you in this] Just expressing my opinion :-) > > Presumably we'd want typedefs for the extra subclasses as well? > > Also, I take it we'd use the "printable_name" from gimple.def - though > would we use it for the subclass name, or for the ptr typedef? I would think a typedef for any type that we would directly refer to in the code, like a gimple_omp_clause, gimple_assign, or whatever. > >> Other than stomping on the same bits at the moment (less so once >> gimple-stmt.[ch] is split out), these changes are completely orthogonal, >> but in line with with my direction. I think It should be done sooner or >> later.... My preference is to also see the follow up work carried out >> as well. Or at least a plan for it. > So you like the approach, provided I commit to the followup work? [1] > > OK, I'll try to create some followup patches next week. I'd prefer to > get the conversion to inheritance into trunk sooner rather than later, > though. > > Thanks for looking at this (and for your cleanup work!) > > Dave > [1] and the patches still need formal review. Im not the one that has to be sold on this, I'm actually ambivalent to the change this close to the end of stage1... I'm pointing out what we can eventually do with it in case it sways opinion.. I would have considered something similar in a "while" when the other refactoring work reached that point. In some ways it might be better for next stage 1, but perhaps you have outlined enough benefits for it to be attractive to someone today. It seems to be pretty neutral in most other respects. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) 2013-11-01 21:36 ` Andrew MacLeod 2013-11-01 21:41 ` Jakub Jelinek 2013-11-01 22:43 ` David Malcolm @ 2013-11-05 17:23 ` David Malcolm 2013-11-06 16:53 ` Michael Matz 2013-11-05 18:22 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) Andrew MacLeod 3 siblings, 1 reply; 116+ messages in thread From: David Malcolm @ 2013-11-05 17:23 UTC (permalink / raw) To: Andrew MacLeod; +Cc: gcc-patches [-- Attachment #1: Type: text/plain, Size: 4812 bytes --] On Fri, 2013-11-01 at 17:36 -0400, Andrew MacLeod wrote: > On 10/31/2013 12:26 PM, David Malcolm wrote: > > [Shamelessly hijacking Andrew's thread about gimple.h refactoring, > > since this seems on-topic for that, and I'm keen to hear from Andrew on > > how the following would interact with his work - I *think* our two > > cleanups are orthogonal. > > Mostly orthogonal anyway... just stomping on the same bits :-). > > Since you hijacked a planning thread, do you plan to take this any > further, or make this change and move on to something else? > > It is a start, but it doesnt do the rest of the work that needs doing to > really take advantage of it... which will be extensive. > for instance, we should change: > > static inline void > ! gimple_call_set_lhs (gimple gs, tree lhs) > { > - GIMPLE_CHECK (gs, GIMPLE_CALL); > gimple_set_op (gs, 0, lhs); > to > static inline void > ! gimple_call_set_lhs (gimple_statement_call *gs, tree lhs) > { > gimple_set_op (gs, 0, lhs); > > > but then every location that calls it needs an appropriate change: > > ! gimple call; > ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, > alias), vargs); > gimple_call_set_lhs (call, atree); > > --- 1518,1524 ---- > > ! gimple_statement_call *call; > ! call = as_a<gimple_statement_call> (gimple_build_call_vec > (build_fold_addr_expr_loc (0, alias), vargs)); > gimple_call_set_lhs (call, atree); > > And in fact there is a ripple effect to then change > gimple_build_call_vec to simply return a gimple_statement_call *... Then > this doesn't look as ugly either... > > ! gimple_statement_call *call; > ! call = gimple_build_call_vec (build_fold_addr_expr_loc (0, > alias), vargs); > gimple_call_set_lhs (call, atree); > > that is looking much better :-) > > > Leaving the names as they are should be ok, but the I'd also add a > typedef for the pointer without the 'statement' in the name.. ie > typedef gimple_statement_call *gimple_call; > That seems in line with what we do with 'gimple' right now and the short > form is the type we'd normally use. > > That adds a touch of difficulty with "as_a", since that requires the > type name, not the shorthand pointer.... so you have something like > gimple_call call = as_a <gimple_statement_call> blah(). > I think as the changes to use the gimple_call type are pushed through > all the callers and callee's, the requirement of as_a and the long name > being ugly begins to rapidly disappear... it'll only exist in the core > creation routines and no one will usually see it. So I don't *think* > this is an issue... but it is an ugly transition if its only partially > done. > > And eventually we can pull the accessor routines and others into the > class itself: > gimple_call call; > call = gimple_build_call_vec (build_fold_addr_expr_loc (0, > alias), vargs); > call->set_lhs (atree); > > Which results in a similar feel to the new gimple_type, gimple_decl, > etc. classes with my upcoming tree wrappers. Changing gimple statements > to behave something like this is actually mentioned in the plan, but out > in the future once trees have been taken care of. > > I would also plan to create instances for each of the gimple statements > that don't have them now, like gimple_statement_assign. Its lumped in as > a general GSS_WITH_MEM_OPS, so there is no gimple_statement_assign > class/struct to use. > > It would really be nice to use the DEFGSCODE macro and gimple.def to > make this happen automagically somehow... Its tantalizingly close now I > think, especially combined with the info in gsstruct.def... Although if > we are moving to proper classes eventually its probably better to > explicitly write the required class for a statement kind. > > That all said, this change enables that work to proceed if someone wants > to do it. > > My question is: Is anyone going to do it, and if so, who and when? :-) Here's a followup patch which ensures that every gimple code has its own subclass, by adding empty subclasses derived from the GSS_-based subclasses as appropriate (I don't bother for gimple codes that already have their own subclass due to having their own GSS layout). I also copied the comments from gimple.def into gimple.h, so that Doxygen picks up on the descriptions and uses them to describe each subclass. Posting for discussion (i.e. am still bootstrapping this; it also needs the gengtype fix posted as http://gcc.gnu.org/ml/gcc-patches/2013-11/msg00425.html) You can see what the resulting gimple class hierarchy (as reported by Doxygen) looks like here: http://dmalcolm.fedorapeople.org/gcc/2013-11-05/doxygen/html/structgimple__statement__base.html [-- Attachment #2: add-leaf-gimple-subclasses.patch --] [-- Type: text/x-patch, Size: 24339 bytes --] commit ec6a05ed9ff15b4fc458c668cfd5227a1506042b Author: David Malcolm <dmalcolm@redhat.com> Date: Tue Nov 5 04:30:15 2013 -0500 Ensure every gimple code has a subclasses; document. Add empty subclasses to gimple.h as appropriate to ensure that every gimple code has its own gimple subclass. Add a copy of the documentation from gimple.def to every gimple subclass in gimple.h (both new and existing ones) so that the per-code documentation shows up per-class within Doxygen-generated docs. gcc/ * gimple.h (struct gimple_statement_error_mark): New subclass of gimple_statement_base. (struct gimple_statement_cond): New subclass of gimple_statement_with_ops. (struct gimple_statement_debug): New subclass of gimple_statement_with_ops. (gimple_statement_goto): New subclass of gimple_statement_with_ops. (gimple_statement_label): New subclass of gimple_statement_with_ops. (gimple_statement_switch): New subclass of gimple_statement_with_ops. (gimple_statement_assign): New subclass of gimple_statement_with_memory_ops. (gimple_statement_call): Add documentation from gimple.def. (gimple_statement_bind): Likewise. (gimple_statement_catch): Likewise. (gimple_statement_eh_filter): Likewise. (gimple_statement_eh_else): Likewise. (gimple_statement_eh_mnt): Likewise. (gimple_statement_phi): Likewise. (gimple_statement_resx): New subclass of gimple_statement_eh_ctrl. (gimple_statement_dispatch): Likewise. (gimple_statement_try): Add documentation from gimple.def. (gimple_statement_nop): New subclass of gimple_statement_base. (gimple_statement_wce): Add documentation from gimple.def. (gimple_statement_asm): Likewise. (gimple_statement_omp_critical): Likewise. (gimple_statement_omp_for): Likewise. (gimple_statement_omp_master): New subclass of gimple_statement_omp. (gimple_statement_omp_taskgroup): Likewise. (gimple_statement_omp_ordered): Likewise. (gimple_statement_omp_parallel): Add documentation from gimple.def. (gimple_statement_omp_task): Likewise. (gimple_statement_omp_section): New subclass of gimple_statement_omp. (gimple_statement_omp_sections): Add documentation from gimple.def. (gimple_statement_omp_sections_switch): New subclass of gimple_statement_base. (gimple_statement_omp_continue): Add documentation from gimple.def. (gimple_statement_omp_target): New subclass of gimple_statement_omp_parallel. (gimple_statement_omp_teams): New subclass of gimple_statement_omp_single. (gimple_predict): New subclass of gimple_statement_base. (gimple_statement_omp_atomic_load): Add documentation from gimple.def. (gimple_statement_omp_atomic_store): Update comment. (gimple_statement_omp_return): New subclass of gimple_statement_omp_atomic_store. (gimple_statement_transaction): Add documentation from gimple.def. (gimple_statement_return): New subclass of gimple_statement_with_memory_ops. diff --git a/gcc/gimple.h b/gcc/gimple.h index 35bfa06..318953c 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -223,6 +223,13 @@ struct GTY((desc ("gimple_statement_structure (&%h)"), tag ("GSS_BASE"), gimple GTY((skip)) prev; }; +/* code == GIMPLE_ERROR_MARK, an error marker. */ + +struct GTY(()) + gimple_statement_error_mark : public gimple_statement_base +{ + /* no additional fields; this uses the layout for GSS_BASE. */ +}; /* Base structure for tuples with operands. */ @@ -255,6 +262,81 @@ struct GTY((tag("GSS_WITH_OPS"))) tree GTY((length ("%h.num_ops"))) op[1]; }; +/* code == GIMPLE_COND: + + GIMPLE_COND <COND_CODE, OP1, OP2, TRUE_LABEL, FALSE_LABEL> + represents the conditional jump: + + if (OP1 COND_CODE OP2) goto TRUE_LABEL else goto FALSE_LABEL + + COND_CODE is the tree code used as the comparison predicate. It + must be of class tcc_comparison. + + OP1 and OP2 are the operands used in the comparison. They must be + accepted by is_gimple_operand. + + TRUE_LABEL and FALSE_LABEL are the LABEL_DECL nodes used as the + jump target for the comparison. */ + +struct GTY(()) + gimple_statement_cond : public gimple_statement_with_ops +{ + /* no additional fields; this uses the layout for GSS_WITH_OPS. */ +}; + +/* code == GIMPLE_DEBUG, a debug statement. */ + +struct GTY(()) + gimple_statement_debug : public gimple_statement_with_ops +{ + /* no additional fields; this uses the layout for GSS_WITH_OPS. */ +}; + +/* code == GIMPLE_GOTO + + GIMPLE_GOTO <TARGET> represents unconditional jumps. + TARGET is a LABEL_DECL or an expression node for computed GOTOs. */ + +struct GTY(()) + gimple_statement_goto : public gimple_statement_with_ops +{ + /* no additional fields; this uses the layout for GSS_WITH_OPS. */ +}; + +/* code == GIMPLE_LABEL + + GIMPLE_LABEL <LABEL> represents label statements. LABEL is a + LABEL_DECL representing a jump target. */ + +struct GTY(()) + gimple_statement_label : public gimple_statement_with_ops +{ + /* no additional fields; this uses the layout for GSS_WITH_OPS. */ +}; + +/* code == GIMPLE_SWITCH + + GIMPLE_SWITCH <INDEX, DEFAULT_LAB, LAB1, ..., LABN> represents the + multiway branch: + + switch (INDEX) + { + case LAB1: ...; break; + ... + case LABN: ...; break; + default: ... + } + + INDEX is the variable evaluated to decide which label to jump to. + + DEFAULT_LAB, LAB1 ... LABN are the tree nodes representing case labels. + They must be CASE_LABEL_EXPR nodes. */ + +struct GTY(()) + gimple_statement_switch : public gimple_statement_with_ops +{ + /* no additional fields; this uses the layout for GSS_WITH_OPS. */ +}; /* Base for statements that take both memory and register operands. */ @@ -286,8 +368,49 @@ struct GTY((tag("GSS_WITH_MEM_OPS"))) tree GTY((length ("%h.num_ops"))) op[1]; }; +/* code == GIMPLE_ASSIGN: + + GIMPLE_ASSIGN <SUBCODE, LHS, RHS1[, RHS2]> represents the assignment + statement + + LHS = RHS1 SUBCODE RHS2. + + SUBCODE is the tree code for the expression computed by the RHS of the + assignment. It must be one of the tree codes accepted by + get_gimple_rhs_class. If LHS is not a gimple register according to + is_gimple_reg, SUBCODE must be of class GIMPLE_SINGLE_RHS. + + LHS is the operand on the LHS of the assignment. It must be a tree node + accepted by is_gimple_lvalue. + + RHS1 is the first operand on the RHS of the assignment. It must always be + present. It must be a tree node accepted by is_gimple_val. + + RHS2 is the second operand on the RHS of the assignment. It must be a tree + node accepted by is_gimple_val. This argument exists only if SUBCODE is + of class GIMPLE_BINARY_RHS. */ + +struct GTY(()) + gimple_statement_assign : public gimple_statement_with_memory_ops +{ + /* no additional fields; this uses the layout for GSS_WITH_MEM_OPS. */ +}; + + +/* code == GIMPLE_CALL. + + GIMPLE_CALL <FN, LHS, ARG1, ..., ARGN[, CHAIN]> represents function + calls. + + FN is the callee. It must be accepted by is_gimple_call_addr. -/* Call statements that take both memory and register operands. */ + LHS is the operand where the return value from FN is stored. It may + be NULL. + + ARG1 ... ARGN are the arguments. They must all be accepted by + is_gimple_operand. + + CHAIN is the optional static chain link for nested functions. */ struct GTY((tag("GSS_CALL"))) gimple_statement_call : public gimple_statement_with_memory_ops_base @@ -324,7 +447,12 @@ struct GTY((tag("GSS_OMP"))) }; -/* GIMPLE_BIND */ +/* code == GIMPLE_BIND: + + GIMPLE_BIND <VARS, BLOCK, BODY> represents a lexical scope. + VARS is the set of variables declared in that scope. + BLOCK is the symbol binding block used for debug information. + BODY is the sequence of statements in the scope. */ struct GTY((tag("GSS_BIND"))) gimple_statement_bind : public gimple_statement_base @@ -348,7 +476,11 @@ struct GTY((tag("GSS_BIND"))) }; -/* GIMPLE_CATCH */ +/* code == GIMPLE_CATCH: + + GIMPLE_CATCH <TYPES, HANDLER> represents a typed exception handler. + TYPES is the type (or list of types) handled. HANDLER is the + sequence of statements that handle these types. */ struct GTY((tag("GSS_CATCH"))) gimple_statement_catch : public gimple_statement_base @@ -363,7 +495,11 @@ struct GTY((tag("GSS_CATCH"))) }; -/* GIMPLE_EH_FILTER */ +/* code == GIMPLE_EH_FILTER: + + GIMPLE_EH_FILTER <TYPES, FAILURE> represents an exception + specification. TYPES is a list of allowed types and FAILURE is the + sequence of statements to execute on failure. */ struct GTY((tag("GSS_EH_FILTER"))) gimple_statement_eh_filter : public gimple_statement_base @@ -379,7 +515,12 @@ struct GTY((tag("GSS_EH_FILTER"))) gimple_seq failure; }; -/* GIMPLE_EH_ELSE */ +/* code == GIMPLE_EH_ELSE: + + GIMPLE_EH_ELSE <N_BODY, E_BODY> must be the sole contents of + a GIMPLE_TRY_FINALLY node. For all normal exits from the try block, + N_BODY is run; for all exception exits from the try block, + E_BODY is run. */ struct GTY((tag("GSS_EH_ELSE"))) gimple_statement_eh_else : public gimple_statement_base @@ -390,7 +531,11 @@ struct GTY((tag("GSS_EH_ELSE"))) gimple_seq n_body, e_body; }; -/* GIMPLE_EH_MUST_NOT_THROW */ +/* code == GIMPLE_EH_MUST_NOT_THROW: + + GIMPLE_EH_MUST_NOT_THROW <DECL> represents an exception barrier. + DECL is a noreturn function decl taking no arguments that will + be invoked if an exception propagates to this point. */ struct GTY((tag("GSS_EH_MNT"))) gimple_statement_eh_mnt : public gimple_statement_base @@ -401,7 +546,18 @@ struct GTY((tag("GSS_EH_MNT"))) tree fndecl; }; -/* GIMPLE_PHI */ +/* code == GIMPLE_PHI: + + GIMPLE_PHI <RESULT, ARG1, ..., ARGN> represents the PHI node + + RESULT = PHI <ARG1, ..., ARGN> + + RESULT is the SSA name created by this PHI node. + + ARG1 ... ARGN are the arguments to the PHI node. N must be + exactly the same as the number of incoming edges to the basic block + holding the PHI node. Every argument is either an SSA name or a + tree node of class tcc_constant. */ struct GTY((tag("GSS_PHI"))) gimple_statement_phi : public gimple_statement_base @@ -432,8 +588,43 @@ struct GTY((tag("GSS_EH_CTRL"))) int region; }; +/* code == GIMPLE_RESX: + + GIMPLE_RESX resumes execution after an exception. */ + +struct GTY(()) + gimple_statement_resx : public gimple_statement_eh_ctrl +{ + /* no additional fields; this uses the layout for GSS_EH_CTRL. */ +}; + +/* code == GIMPLE_EH_DISPATCH: -/* GIMPLE_TRY */ + GIMPLE_EH_DISPATCH demultiplexes an exception edge based on + the FILTER argument. */ + +struct GTY(()) + gimple_statement_dispatch : public gimple_statement_eh_ctrl +{ + /* no additional fields; this uses the layout for GSS_EH_CTRL. */ +}; + + +/* code == GIMPLE_TRY: + + GIMPLE_TRY <TRY_KIND, EVAL, CLEANUP> + represents a try/catch or a try/finally statement. + + TRY_KIND is either GIMPLE_TRY_CATCH or GIMPLE_TRY_FINALLY. + + EVAL is the sequence of statements to execute on entry to GIMPLE_TRY. + + CLEANUP is the sequence of statements to execute according to + TRY_KIND. If TRY_KIND is GIMPLE_TRY_CATCH, CLEANUP is only exected + if an exception is thrown during execution of EVAL. If TRY_KIND is + GIMPLE_TRY_FINALLY, CLEANUP is always executed after executing EVAL + (regardless of whether EVAL finished normally, or jumped out or an + exception was thrown). */ struct GTY((tag("GSS_TRY"))) gimple_statement_try : public gimple_statement_base @@ -463,7 +654,24 @@ enum gimple_try_flags GIMPLE_TRY_CATCH_IS_CLEANUP = 1 << 2 }; -/* GIMPLE_WITH_CLEANUP_EXPR */ +/* code == GIMPLE_NOP: + + GIMPLE_NOP represents the "do nothing" statement. */ + +struct GTY(()) + gimple_statement_nop : public gimple_statement_base +{ + /* no additional fields; this uses the layout for GSS_BASE. */ +}; + + +/* code == GIMPLE_WITH_CLEANUP_EXPR: + + This node represents a cleanup expression. It is ONLY USED INTERNALLY + by the gimplifier as a placeholder for cleanups, and its uses will be + cleaned up by the time gimplification is done. + + This tuple should not exist outside of the gimplifier proper. */ struct GTY((tag("GSS_WCE"))) gimple_statement_wce : public gimple_statement_base @@ -481,7 +689,16 @@ struct GTY((tag("GSS_WCE"))) }; -/* GIMPLE_ASM */ +/* code == GIMPLE_ASM: + + GIMPLE_ASM <STRING, I1, ..., IN, O1, ... OM, C1, ..., CP> + represents inline assembly statements. + + STRING is the string containing the assembly statements. + I1 ... IN are the N input operands. + O1 ... OM are the M output operands. + C1 ... CP are the P clobber operands. + L1 ... LQ are the Q label operands. */ struct GTY((tag("GSS_ASM"))) gimple_statement_asm : public gimple_statement_with_memory_ops_base @@ -506,7 +723,13 @@ struct GTY((tag("GSS_ASM"))) tree GTY((length ("%h.num_ops"))) op[1]; }; -/* GIMPLE_OMP_CRITICAL */ +/* code == GIMPLE_OMP_CRITICAL: + GIMPLE_OMP_CRITICAL <NAME, BODY> represents + + #pragma omp critical [name] + + NAME is the name given to the critical section. + BODY is the sequence of statements that are inside the critical section. */ struct GTY((tag("GSS_OMP_CRITICAL"))) gimple_statement_omp_critical : public gimple_statement_omp @@ -536,7 +759,43 @@ struct GTY(()) gimple_omp_for_iter { tree incr; }; -/* GIMPLE_OMP_FOR */ +/* code == GIMPLE_OMP_FOR: + + GIMPLE_OMP_FOR <BODY, CLAUSES, INDEX, INITIAL, FINAL, COND, INCR, PRE_BODY> + represents + + PRE_BODY + #pragma omp for [clause1 ... clauseN] + for (INDEX = INITIAL; INDEX COND FINAL; INDEX {+=,-=} INCR) + BODY + + BODY is the loop body. + + CLAUSES is the list of clauses. + + INDEX must be an integer or pointer variable, which is implicitly thread + private. It must be accepted by is_gimple_operand. + + INITIAL is the initial value given to INDEX. It must be + accepted by is_gimple_operand. + + FINAL is the final value that INDEX should take. It must + be accepted by is_gimple_operand. + + COND is the condition code for the controlling predicate. It must + be one of { <, >, <=, >= } + + INCR is the loop index increment. It must be tree node of type + tcc_constant. + + PRE_BODY is a landing pad filled by the gimplifier with things from + INIT, COND, and INCR that are technically part of the OMP_FOR + structured block, but are evaluated before the loop body begins. + + INITIAL, FINAL and INCR are required to be loop invariant integer + expressions that are evaluated without any synchronization. + The evaluation order, frequency of evaluation and side-effects are + unspecified by the standard. */ struct GTY((tag("GSS_OMP_FOR"))) gimple_statement_omp_for : public gimple_statement_omp @@ -558,8 +817,58 @@ struct GTY((tag("GSS_OMP_FOR"))) gimple_seq pre_body; }; +/* code == GIMPLE_OMP_MASTER: + + GIMPLE_OMP_MASTER <BODY> represents #pragma omp master. + BODY is the sequence of statements to execute in the master section. */ + +struct GTY(()) + gimple_statement_omp_master : public gimple_statement_omp +{ + /* no additional fields; this uses the layout for GSS_OMP. */ +}; + +/* code == GIMPLE_OMP_TASKGROUP: + + GIMPLE_OMP_TASKGROUP <BODY> represents #pragma omp taskgroup. + BODY is the sequence of statements to execute in the taskgroup section. */ + +struct GTY(()) + gimple_statement_omp_taskgroup : public gimple_statement_omp +{ + /* no additional fields; this uses the layout for GSS_OMP. */ +}; + +/* code == GIMPLE_OMP_ORDERED: -/* GIMPLE_OMP_PARALLEL */ + GIMPLE_OMP_ORDERED <BODY> represents #pragma omp ordered. + BODY is the sequence of statements to execute in the ordered section. */ + +struct GTY(()) + gimple_statement_omp_ordered : public gimple_statement_omp +{ + /* no additional fields; this uses the layout for GSS_OMP. */ +}; + + +/* code == GIMPLE_OMP_PARALLEL: + + GIMPLE_OMP_PARALLEL <BODY, CLAUSES, CHILD_FN, DATA_ARG> represents + + #pragma omp parallel [CLAUSES] + BODY + + BODY is a the sequence of statements to be executed by all threads. + + CLAUSES is an OMP_CLAUSE chain with all the clauses. + + CHILD_FN is set when outlining the body of the parallel region. + All the statements in BODY are moved into this newly created + function when converting OMP constructs into low-GIMPLE. + + DATA_ARG is a local variable in the parent function containing data + to be shared with CHILD_FN. This is used to implement all the data + sharing clauses. */ struct GTY((tag("GSS_OMP_PARALLEL"))) gimple_statement_omp_parallel : public gimple_statement_omp @@ -580,7 +889,33 @@ struct GTY((tag("GSS_OMP_PARALLEL"))) }; -/* GIMPLE_OMP_TASK */ +/* code == GIMPLE_OMP_TASK: + + GIMPLE_OMP_TASK <BODY, CLAUSES, CHILD_FN, DATA_ARG, COPY_FN, + ARG_SIZE, ARG_ALIGN> represents + + #pragma omp task [CLAUSES] + BODY + + BODY is a the sequence of statements to be executed by all threads. + + CLAUSES is an OMP_CLAUSE chain with all the clauses. + + CHILD_FN is set when outlining the body of the explicit task region. + All the statements in BODY are moved into this newly created + function when converting OMP constructs into low-GIMPLE. + + DATA_ARG is a local variable in the parent function containing data + to be shared with CHILD_FN. This is used to implement all the data + sharing clauses. + + COPY_FN is set when outlining the firstprivate var initialization. + All the needed statements are emitted into the newly created + function, or when only memcpy is needed, it is NULL. + + ARG_SIZE and ARG_ALIGN are the size and alignment of the incoming + data area allocated by GOMP_task and passed to CHILD_FN. */ + struct GTY((tag("GSS_OMP_TASK"))) gimple_statement_omp_task : public gimple_statement_omp_parallel @@ -597,12 +932,25 @@ struct GTY((tag("GSS_OMP_TASK"))) tree arg_align; }; +/* code == GIMPLE_OMP_SECTION: + + OMP_SECTION <BODY> represents #pragma omp section. + BODY is the sequence of statements in the section body. */ -/* GIMPLE_OMP_SECTION */ -/* Uses struct gimple_statement_omp. */ +struct GTY(()) + gimple_statement_omp_section : public gimple_statement_omp +{ + /* no additional fields; this uses the layout for GSS_OMP. */ +}; +/* code == GIMPLE_OMP_SECTIONS: -/* GIMPLE_OMP_SECTIONS */ + OMP_SECTIONS <BODY, CLAUSES, CONTROL> represents #pragma omp sections. + + BODY is the sequence of statements in the sections body. + CLAUSES is an OMP_CLAUSE chain holding the list of associated clauses. + CONTROL is a VAR_DECL used for deciding which of the sections + to execute. */ struct GTY((tag("GSS_OMP_SECTIONS"))) gimple_statement_omp_sections : public gimple_statement_omp @@ -618,10 +966,25 @@ struct GTY((tag("GSS_OMP_SECTIONS"))) tree control; }; -/* GIMPLE_OMP_CONTINUE. +/* code == GIMPLE_OMP_SECTIONS_SWITCH: + + GIMPLE_OMP_SECTIONS_SWITCH is a marker placed immediately after + OMP_SECTIONS. It represents the GIMPLE_SWITCH used to decide which + branch is taken. */ + +struct GTY(()) + gimple_statement_omp_sections_switch : public gimple_statement_base +{ + /* no additional fields; this uses the layout for GSS_BASE. */ +}; + +/* code == GIMPLE_OMP_CONTINUE: Note: This does not inherit from gimple_statement_omp, because we - do not need the body field. */ + do not need the body field. + + GIMPLE_OMP_CONTINUE marks the location of the loop or sections + iteration in partially lowered OpenMP code. */ struct GTY((tag("GSS_OMP_CONTINUE"))) gimple_statement_omp_continue : public gimple_statement_base @@ -646,10 +1009,65 @@ struct GTY((tag("GSS_OMP_SINGLE"))) tree clauses; }; +/* code == GIMPLE_OMP_TARGET: + + GIMPLE_OMP_TARGET <BODY, CLAUSES, CHILD_FN> represents + #pragma omp target {,data,update} + BODY is the sequence of statements inside the target construct + (NULL for target update). + CLAUSES is an OMP_CLAUSE chain holding the associated clauses. + CHILD_FN is set when outlining the body of the target region. + All the statements in BODY are moved into this newly created + function when converting OMP constructs into low-GIMPLE. + DATA_ARG is a vec of 3 local variables in the parent function + containing data to be mapped to CHILD_FN. This is used to + implement the MAP clauses. */ + +struct GTY(()) + gimple_statement_omp_target : public gimple_statement_omp_parallel +{ + /* no additional fields; this uses the layout for GSS_OMP_PARALLEL. */ +}; + +/* code == GIMPLE_OMP_TEAMS: + + GIMPLE_OMP_TEAMS <BODY, CLAUSES> represents #pragma omp teams + BODY is the sequence of statements inside the single section. + CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ + +struct GTY(()) + gimple_statement_omp_teams : public gimple_statement_omp_single +{ + /* no additional fields; this uses the layout for GSS_OMP_SINGLE. */ +}; + +/* code = GIMPLE_PREDICT: + + GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction. + + PREDICT is one of the predictors from predict.def. + + OUTCOME is NOT_TAKEN or TAKEN. */ -/* GIMPLE_OMP_ATOMIC_LOAD. +struct GTY(()) + gimple_predict : public gimple_statement_base +{ + /* no additional fields; this uses the layout for GSS_BASE. */ +}; + +/* code == GIMPLE_OMP_ATOMIC_LOAD. Note: This is based on gimple_statement_base, not g_s_omp, because g_s_omp - contains a sequence, which we don't need here. */ + contains a sequence, which we don't need here. + + Tuples used for lowering of OMP_ATOMIC. Although the form of the OMP_ATOMIC + expression is very simple (just in form mem op= expr), various implicit + conversions may cause the expression to become more complex, so that it does + not fit the gimple grammar very well. To overcome this problem, OMP_ATOMIC + is rewritten as a sequence of two codes in gimplification: + + GIMPLE_OMP_LOAD (tmp, mem) + val = some computations involving tmp; + GIMPLE_OMP_STORE (val). */ struct GTY((tag("GSS_OMP_ATOMIC_LOAD"))) gimple_statement_omp_atomic_load : public gimple_statement_base @@ -660,7 +1078,8 @@ struct GTY((tag("GSS_OMP_ATOMIC_LOAD"))) tree rhs, lhs; }; -/* GIMPLE_OMP_ATOMIC_STORE. +/* code == GIMPLE_OMP_ATOMIC_STORE: + See note on GIMPLE_OMP_ATOMIC_LOAD. */ struct GTY((tag("GSS_OMP_ATOMIC_STORE"))) @@ -672,6 +1091,16 @@ struct GTY((tag("GSS_OMP_ATOMIC_STORE"))) tree val; }; +/* code == OMP_RETURN: + + OMP_RETURN marks the end of an OpenMP directive. */ + +struct GTY(()) + gimple_statement_omp_return : public gimple_statement_omp_atomic_store +{ + /* no additional fields; this uses the layout for GSS_OMP_ATOMIC_STORE. */ +}; + /* GIMPLE_TRANSACTION. */ /* Bits to be stored in the GIMPLE_TRANSACTION subcode. */ @@ -700,6 +1129,16 @@ struct GTY((tag("GSS_OMP_ATOMIC_STORE"))) likely because it is guaranteed to go irrevocable upon entry. */ #define GTMA_HAS_NO_INSTRUMENTATION (1u << 7) + +/* code == GIMPLE_TRANSACTION: + + GIMPLE_TRANSACTION <BODY, LABEL> represents __transaction_atomic and + __transaction_relaxed blocks. + BODY is the sequence of statements inside the transaction. + LABEL is a label for the statement immediately following the + transaction. This is before RETURN so that it has MEM_OPS, + so that it can clobber global memory. */ + struct GTY((tag("GSS_TRANSACTION"))) gimple_statement_transaction : public gimple_statement_with_memory_ops_base { @@ -712,6 +1151,19 @@ struct GTY((tag("GSS_TRANSACTION"))) tree label; }; +/* code == GIMPLE_RETURN: + + GIMPLE_RETURN <RETVAL> represents return statements. + + RETVAL is the value to return or NULL. If a value is returned it + must be accepted by is_gimple_operand. */ + +struct GTY(()) + gimple_statement_return : public gimple_statement_with_memory_ops +{ + /* no additional fields; this uses the layout for GSS_WITH_MEM_OPS. */ +}; + #define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) SYM, enum gimple_statement_structure_enum { #include "gsstruct.def" ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) 2013-11-05 17:23 ` [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) David Malcolm @ 2013-11-06 16:53 ` Michael Matz 2013-11-07 6:19 ` David Malcolm 2013-11-08 0:07 ` Alec Teal 0 siblings, 2 replies; 116+ messages in thread From: Michael Matz @ 2013-11-06 16:53 UTC (permalink / raw) To: David Malcolm; +Cc: Andrew MacLeod, gcc-patches Hi, On Tue, 5 Nov 2013, David Malcolm wrote: > Here's a followup patch which ensures that every gimple code has its own > subclass, by adding empty subclasses derived from the GSS_-based > subclasses as appropriate (I don't bother for gimple codes that already > have their own subclass due to having their own GSS layout). I also > copied the comments from gimple.def into gimple.h, so that Doxygen picks > up on the descriptions and uses them to describe each subclass. I don't like that. The empty classes are just useless, they imply a structure that isn't really there, some of the separate gimple codes are basically selectors of specific subtypes of a generic concept, without additional data or methods; creating a type for those is confusing. Generally I don't like complicating the type system without good reasons (as in actually also making use of the complicated types). The fewer types the better IMO. Ciao, Michael. ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) 2013-11-06 16:53 ` Michael Matz @ 2013-11-07 6:19 ` David Malcolm 2013-11-07 7:08 ` Jeff Law 2013-11-07 14:57 ` Michael Matz 2013-11-08 0:07 ` Alec Teal 1 sibling, 2 replies; 116+ messages in thread From: David Malcolm @ 2013-11-07 6:19 UTC (permalink / raw) To: Michael Matz; +Cc: Andrew MacLeod, gcc-patches On Wed, 2013-11-06 at 16:32 +0100, Michael Matz wrote: > Hi, > > On Tue, 5 Nov 2013, David Malcolm wrote: > > > Here's a followup patch which ensures that every gimple code has its own > > subclass, by adding empty subclasses derived from the GSS_-based > > subclasses as appropriate (I don't bother for gimple codes that already > > have their own subclass due to having their own GSS layout). I also > > copied the comments from gimple.def into gimple.h, so that Doxygen picks > > up on the descriptions and uses them to describe each subclass. > > I don't like that. The empty classes are just useless, they imply a > structure that isn't really there, some of the separate gimple codes are > basically selectors of specific subtypes of a generic concept, without > additional data or methods; creating a type for those is confusing. A type system does more than just express memory layouts: * it permits the proof of absence of certain bugs * it supports abstraction * it documents the intent of the code To give an example from the patch, the proposed gimple_statement_switch subclass of gimple_statement_with_ops adds no extra fields, but it adds the invariant that (assuming the ptr is non-NULL), that code == GIMPLE_SWITCH, or, more intuitively, "it's a switch statement". This means that if we have a gimple_statement_switch, that both a human reading the code and the compiler can "know" at compile-time that the code == GIMPLE_SWITCH. The accessors are the big use-case for this, which would be a large patch (as discussed elsewhere in the thread), but there are other places where this could be used. Consider tree-switch-conversion.c: this contains various "gimple" variables but they don't work on arbitrary gimple; they require code == GIMPLE_SWITCH: For example: /* Collect information about GIMPLE_SWITCH statement SWTCH into INFO. */ static void collect_switch_conv_info (gimple swtch, struct switch_conv_info *info) {...} Right now we're expressing the code == GIMPLE_SWITCH invariant via naming-conventions ("swtch") and runtime checking in the checked build (covering documentation of intent and implementation respectively). We could be doing this directly in the type system, and using the compiler to check it. > Generally I don't like complicating the type system without good reasons > (as in actually also making use of the complicated types). I can post a followup patch that makes use of each of these, if it will help. > The fewer > types the better IMO. There's a reductio ad absurdum of that argument: reduce the number of types to zero and use void* everywhere, replacing field lookups with pointer arithmetic and casts [1]. Obviously this is a strawman, but looking through tree(-core).h, gimple.h and rtl.h it feels to me all too reminiscent of the current implementation, alas. Hope this is constructive. Dave [1] or cons cells if you're that way inclined. ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) 2013-11-07 6:19 ` David Malcolm @ 2013-11-07 7:08 ` Jeff Law 2013-11-08 19:23 ` David Malcolm 2013-11-07 14:57 ` Michael Matz 1 sibling, 1 reply; 116+ messages in thread From: Jeff Law @ 2013-11-07 7:08 UTC (permalink / raw) To: David Malcolm, Michael Matz; +Cc: Andrew MacLeod, gcc-patches [ Just a note, of this reply is meant for Michael and other parts for David, hopefully the audience is clear from the context. ] On 11/06/13 21:56, David Malcolm wrote: > On Wed, 2013-11-06 at 16:32 +0100, Michael Matz wrote: >> Hi, >> >> On Tue, 5 Nov 2013, David Malcolm wrote: >> >>> Here's a followup patch which ensures that every gimple code has its own >>> subclass, by adding empty subclasses derived from the GSS_-based >>> subclasses as appropriate (I don't bother for gimple codes that already >>> have their own subclass due to having their own GSS layout). I also >>> copied the comments from gimple.def into gimple.h, so that Doxygen picks >>> up on the descriptions and uses them to describe each subclass. >> >> I don't like that. The empty classes are just useless, they imply a >> structure that isn't really there, some of the separate gimple codes are >> basically selectors of specific subtypes of a generic concept, without >> additional data or methods; creating a type for those is confusing. > > A type system does more than just express memory layouts: > * it permits the proof of absence of certain bugs Right. As you have probably surmised, this is the single biggest thing we get from this work in my mind. We use the type system to ensure a certain class of bugs simply won't get through the compilation phase. That's a significant and important change from where we are now. Right now we have no way of knowing that at compile time. Instead we rely upon an insane set of macros to check this kind of invariant at run time. Note carefully just because we don't hit a checking failure doesn't mean the code is safe. It just means we haven't found a set of preconditions necessary to trip the problem at runtime. Obviously in some (many), where may be no such way to trigger the failure, but there's no way to prove it. Don't get me wrong the checking macros, when they were introduced were a godsend. But they're papering over a fundamental problems in GCC's internal representations. I think it's hard to overestimate the value we get by moving this stuff into compile-time type checking. > I can post a followup patch that makes use of each of these, if it will > help. I wouldn't mind seeing a small example proof of concept posted to help those who don't see where this is going understand the goal. I would recommend against posting another large patch for inclusion at this time. Jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) 2013-11-07 7:08 ` Jeff Law @ 2013-11-08 19:23 ` David Malcolm 2013-11-14 8:38 ` Jeff Law 0 siblings, 1 reply; 116+ messages in thread From: David Malcolm @ 2013-11-08 19:23 UTC (permalink / raw) To: Jeff Law; +Cc: Michael Matz, Andrew MacLeod, gcc-patches [-- Attachment #1: Type: text/plain, Size: 4221 bytes --] On Wed, 2013-11-06 at 22:32 -0700, Jeff Law wrote: > [ Just a note, of this reply is meant for Michael and other parts for > David, hopefully the audience is clear from the context. ] > > On 11/06/13 21:56, David Malcolm wrote: > > On Wed, 2013-11-06 at 16:32 +0100, Michael Matz wrote: > >> Hi, > >> > >> On Tue, 5 Nov 2013, David Malcolm wrote: > >> > >>> Here's a followup patch which ensures that every gimple code has its own > >>> subclass, by adding empty subclasses derived from the GSS_-based > >>> subclasses as appropriate (I don't bother for gimple codes that already > >>> have their own subclass due to having their own GSS layout). I also > >>> copied the comments from gimple.def into gimple.h, so that Doxygen picks > >>> up on the descriptions and uses them to describe each subclass. > >> > >> I don't like that. The empty classes are just useless, they imply a > >> structure that isn't really there, some of the separate gimple codes are > >> basically selectors of specific subtypes of a generic concept, without > >> additional data or methods; creating a type for those is confusing. > > > > A type system does more than just express memory layouts: > > * it permits the proof of absence of certain bugs > Right. As you have probably surmised, this is the single biggest thing > we get from this work in my mind. We use the type system to ensure a > certain class of bugs simply won't get through the compilation phase. > > That's a significant and important change from where we are now. Right > now we have no way of knowing that at compile time. Instead we rely > upon an insane set of macros to check this kind of invariant at run > time. Note carefully just because we don't hit a checking failure > doesn't mean the code is safe. It just means we haven't found a set of > preconditions necessary to trip the problem at runtime. Obviously in > some (many), where may be no such way to trigger the failure, but > there's no way to prove it. > > Don't get me wrong the checking macros, when they were introduced were a > godsend. But they're papering over a fundamental problems in GCC's > internal representations. > > I think it's hard to overestimate the value we get by moving this stuff > into compile-time type checking. > > > > I can post a followup patch that makes use of each of these, if it will > > help. > I wouldn't mind seeing a small example proof of concept posted to help > those who don't see where this is going understand the goal. I would > recommend against posting another large patch for inclusion at this time. Attached is a proof-of-concept patch which uses the gimple_statement_switch subclass (as a "gimple_switch" typedef). This is one of the subclasses that the earlier patch added, which has no new fields, but which carries the invariant that, if non-NULL, gimple_code (gs) == GIMPLE_SWITCH. The patch adds compile-time type-checking for places where switch statements are handled. For example, in tree-vrp.c's switch_update: typedef struct { - gimple stmt; + gimple_switch stmt; tree vec; } switch_update; we can capture the fact that the statements have code GIMPLE_SWITCH. I was able to make 7 of the 9 gimple_switch_* accessors accept a gimple_switch rather than a gimple, hence adding compile-time typesafety for these. We could do all of them, but doing the remaining two would enlarge the patch (I did the ones where the site of the downcast already has enclosing braces handy to scope the subclass pointer). I kept the run-time checking in those accessors, though arguably they're redundant. I deliberately used a C style for the downcast from gimple to a more specialized type, eschewing the dyn_cast<> template, though IMHO the latter is a better style. Perhaps a specialized dyncast method to gimple would be more acceptable e.g.: struct GTY((etc)) gimple statement_base { [...] gimple_switch is_switch () const { if (gimple_code (this) == GIMPLE_SWITCH) return (gimple_switch)this; else return NULL; } }; allowing us to spell a dynamic cast like this: if (gimple_switch switch_stmt = stmt->is_switch ()) { /* do typesafe stuff with switch_stmt */ } [-- Attachment #2: gimple-switch.patch --] [-- Type: text/x-patch, Size: 30194 bytes --] commit b9e2375b4250428cc20e83c9be9be80afbfcb388 Author: David Malcolm <dmalcolm@redhat.com> Date: Thu Nov 7 21:32:15 2013 -0500 Use gimple_switch in various places diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index fb05ce7..cc2d4d7 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -2221,7 +2221,7 @@ expand_gimple_stmt_1 (gimple stmt) case GIMPLE_PREDICT: break; case GIMPLE_SWITCH: - expand_case (stmt); + expand_case ((gimple_switch)stmt); break; case GIMPLE_ASM: expand_asm_stmt (stmt); diff --git a/gcc/coretypes.h b/gcc/coretypes.h index 5a5cfbb..a72ebb4 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -69,6 +69,9 @@ typedef struct gimple_stmt_iterator_d gimple_stmt_iterator; /* FWIW I'd rather simply have the class be called "gimple_call", and make the pointerness be explicit rather than implicit. */ typedef struct gimple_statement_call *gimple_call; +typedef const struct gimple_statement_call *const_gimple_call; +typedef struct gimple_statement_switch *gimple_switch; +typedef const struct gimple_statement_switch *const_gimple_switch; union section; typedef union section section; struct gcc_options; diff --git a/gcc/expr.h b/gcc/expr.h index 56f504a..f5bed84 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -734,7 +734,7 @@ rtx get_personality_function (tree); /* In stmt.c */ /* Expand a GIMPLE_SWITCH statement. */ -extern void expand_case (gimple); +extern void expand_case (gimple_switch); /* Like expand_case but special-case for SJLJ exception dispatching. */ extern void expand_sjlj_dispatch_table (rtx, vec<tree> ); diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index b9bbdc7..690b43e 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -763,7 +763,7 @@ dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags) pp_gimple_stmt_1. */ static void -dump_gimple_switch (pretty_printer *buffer, gimple gs, int spc, int flags) +dump_gimple_switch (pretty_printer *buffer, gimple_switch gs, int spc, int flags) { unsigned int i; @@ -2100,7 +2100,7 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags) break; case GIMPLE_SWITCH: - dump_gimple_switch (buffer, gs, spc, flags); + dump_gimple_switch (buffer, (gimple_switch)gs, spc, flags); break; case GIMPLE_TRY: diff --git a/gcc/gimple.c b/gcc/gimple.c index a128582..f182d0e 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -822,13 +822,14 @@ gimple_build_resx (int region) NLABELS is the number of labels in the switch excluding the default. DEFAULT_LABEL is the default label for the switch statement. */ -gimple +gimple_switch gimple_build_switch_nlabels (unsigned nlabels, tree index, tree default_label) { /* nlabels + 1 default label + 1 index. */ gcc_checking_assert (default_label); - gimple p = gimple_build_with_ops (GIMPLE_SWITCH, ERROR_MARK, - 1 + 1 + nlabels); + gimple_switch p = + (gimple_switch)gimple_build_with_ops (GIMPLE_SWITCH, ERROR_MARK, + 1 + 1 + nlabels); gimple_switch_set_index (p, index); gimple_switch_set_default_label (p, default_label); return p; @@ -840,12 +841,12 @@ gimple_build_switch_nlabels (unsigned nlabels, tree index, tree default_label) DEFAULT_LABEL is the default label ARGS is a vector of labels excluding the default. */ -gimple +gimple_switch gimple_build_switch (tree index, tree default_label, vec<tree> args) { unsigned i, nlabels = args.length (); - gimple p = gimple_build_switch_nlabels (nlabels, index, default_label); + gimple_switch p = gimple_build_switch_nlabels (nlabels, index, default_label); /* Copy the labels from the vector to the switch statement. */ for (i = 0; i < nlabels; i++) diff --git a/gcc/gimple.h b/gcc/gimple.h index cd9f89f..63827a6 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1538,8 +1538,8 @@ gimple_statement_try *gimple_build_try (gimple_seq, gimple_seq, gimple gimple_build_wce (gimple_seq); gimple gimple_build_resx (int); gimple gimple_build_eh_dispatch (int); -gimple gimple_build_switch_nlabels (unsigned, tree, tree); -gimple gimple_build_switch (tree, tree, vec<tree> ); +gimple_switch gimple_build_switch_nlabels (unsigned, tree, tree); +gimple_switch gimple_build_switch (tree, tree, vec<tree> ); gimple gimple_build_omp_parallel (gimple_seq, tree, tree, tree); gimple gimple_build_omp_task (gimple_seq, tree, tree, tree, tree, tree, tree); gimple gimple_build_omp_for (gimple_seq, int, tree, size_t, gimple_seq); @@ -4592,7 +4592,7 @@ gimple_eh_dispatch_set_region (gimple gs, int region) /* Return the number of labels associated with the switch statement GS. */ static inline unsigned -gimple_switch_num_labels (const_gimple gs) +gimple_switch_num_labels (const_gimple_switch gs) { unsigned num_ops; GIMPLE_CHECK (gs, GIMPLE_SWITCH); @@ -4605,7 +4605,7 @@ gimple_switch_num_labels (const_gimple gs) /* Set NLABELS to be the number of labels for the switch statement GS. */ static inline void -gimple_switch_set_num_labels (gimple g, unsigned nlabels) +gimple_switch_set_num_labels (gimple_switch g, unsigned nlabels) { GIMPLE_CHECK (g, GIMPLE_SWITCH); gimple_set_num_ops (g, nlabels + 1); @@ -4635,7 +4635,7 @@ gimple_switch_index_ptr (const_gimple gs) /* Set INDEX to be the index variable for switch statement GS. */ static inline void -gimple_switch_set_index (gimple gs, tree index) +gimple_switch_set_index (gimple_switch gs, tree index) { GIMPLE_CHECK (gs, GIMPLE_SWITCH); gcc_gimple_checking_assert (SSA_VAR_P (index) || CONSTANT_CLASS_P (index)); @@ -4647,7 +4647,7 @@ gimple_switch_set_index (gimple gs, tree index) labels in a switch statement. */ static inline tree -gimple_switch_label (const_gimple gs, unsigned index) +gimple_switch_label (const_gimple_switch gs, unsigned index) { GIMPLE_CHECK (gs, GIMPLE_SWITCH); gcc_gimple_checking_assert (gimple_num_ops (gs) > index + 1); @@ -4657,7 +4657,7 @@ gimple_switch_label (const_gimple gs, unsigned index) /* Set the label number INDEX to LABEL. 0 is always the default label. */ static inline void -gimple_switch_set_label (gimple gs, unsigned index, tree label) +gimple_switch_set_label (gimple_switch gs, unsigned index, tree label) { GIMPLE_CHECK (gs, GIMPLE_SWITCH); gcc_gimple_checking_assert (gimple_num_ops (gs) > index + 1 @@ -4669,7 +4669,7 @@ gimple_switch_set_label (gimple gs, unsigned index, tree label) /* Return the default label for a switch statement. */ static inline tree -gimple_switch_default_label (const_gimple gs) +gimple_switch_default_label (const_gimple_switch gs) { tree label = gimple_switch_label (gs, 0); gcc_checking_assert (!CASE_LOW (label) && !CASE_HIGH (label)); @@ -4679,7 +4679,7 @@ gimple_switch_default_label (const_gimple gs) /* Set the default label for a switch statement. */ static inline void -gimple_switch_set_default_label (gimple gs, tree label) +gimple_switch_set_default_label (gimple_switch gs, tree label) { gcc_checking_assert (!CASE_LOW (label) && !CASE_HIGH (label)); gimple_switch_set_label (gs, 0, label); diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 83bd479..8958f1f 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -1765,7 +1765,7 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info, struct inline_summary *summary, basic_block bb) { - gimple last; + gimple lastg; tree op; int index; struct agg_position_info aggpos; @@ -1774,9 +1774,10 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info, size_t n; size_t case_idx; - last = last_stmt (bb); - if (!last || gimple_code (last) != GIMPLE_SWITCH) + lastg = last_stmt (bb); + if (!lastg || gimple_code (lastg) != GIMPLE_SWITCH) return; + gimple_switch last = (gimple_switch)lastg; op = gimple_switch_index (last); if (!unmodified_parm_or_parm_agg_item (info, last, op, &index, &aggpos)) return; diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 3b7882d..4ef1f4c 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -10324,10 +10324,11 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p, case GIMPLE_SWITCH: { + gimple_switch switch_stmt = (gimple_switch)stmt; unsigned int i; - for (i = 0; i < gimple_switch_num_labels (stmt); ++i) + for (i = 0; i < gimple_switch_num_labels (switch_stmt); ++i) { - tree lab = CASE_LABEL (gimple_switch_label (stmt, i)); + tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i)); n = splay_tree_lookup (all_labels, (splay_tree_key) lab); if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value)) break; diff --git a/gcc/stmt.c b/gcc/stmt.c index b3fd255..1d7298b 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -2010,7 +2010,7 @@ reset_out_edges_aux (basic_block bb) STMT. Record this information in the aux field of the edge. */ static inline void -compute_cases_per_edge (gimple stmt) +compute_cases_per_edge (gimple_switch stmt) { basic_block bb = gimple_bb (stmt); reset_out_edges_aux (bb); @@ -2032,7 +2032,7 @@ compute_cases_per_edge (gimple stmt) Generate the code to test it and jump to the right place. */ void -expand_case (gimple stmt) +expand_case (gimple_switch stmt) { tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE; rtx default_label = NULL_RTX; diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 8d82342..3cbb232 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -141,7 +141,7 @@ static void factor_computed_gotos (void); static void make_edges (void); static void assign_discriminators (void); static void make_cond_expr_edges (basic_block); -static void make_gimple_switch_edges (basic_block); +static void make_gimple_switch_edges (gimple_switch, basic_block); static void make_goto_expr_edges (basic_block); static void make_gimple_asm_edges (basic_block); static edge gimple_redirect_edge_and_branch (edge, basic_block); @@ -161,8 +161,8 @@ static bool gimple_can_merge_blocks_p (basic_block, basic_block); static void remove_bb (basic_block); static edge find_taken_edge_computed_goto (basic_block, tree); static edge find_taken_edge_cond_expr (basic_block, tree); -static edge find_taken_edge_switch_expr (basic_block, tree); -static tree find_case_label_for_value (gimple, tree); +static edge find_taken_edge_switch_expr (gimple_switch, basic_block, tree); +static tree find_case_label_for_value (gimple_switch, tree); void init_empty_tree_cfg_for_function (struct function *fn) @@ -644,7 +644,7 @@ make_edges (void) fallthru = false; break; case GIMPLE_SWITCH: - make_gimple_switch_edges (bb); + make_gimple_switch_edges ((gimple_switch)last, bb); fallthru = false; break; case GIMPLE_RESX: @@ -892,7 +892,7 @@ end_recording_case_labels (void) { gimple stmt = last_stmt (bb); if (stmt && gimple_code (stmt) == GIMPLE_SWITCH) - group_case_labels_stmt (stmt); + group_case_labels_stmt ((gimple_switch)stmt); } } BITMAP_FREE (touched_switch_bbs); @@ -904,7 +904,7 @@ end_recording_case_labels (void) Otherwise return NULL. */ static tree -get_cases_for_edge (edge e, gimple t) +get_cases_for_edge (edge e, gimple_switch t) { void **slot; size_t i, n; @@ -943,9 +943,8 @@ get_cases_for_edge (edge e, gimple t) /* Create the edges for a GIMPLE_SWITCH starting at block BB. */ static void -make_gimple_switch_edges (basic_block bb) +make_gimple_switch_edges (gimple_switch entry, basic_block bb) { - gimple entry = last_stmt (bb); size_t i, n; n = gimple_switch_num_labels (entry); @@ -1238,12 +1237,13 @@ cleanup_dead_labels (void) case GIMPLE_SWITCH: { - size_t i, n = gimple_switch_num_labels (stmt); + gimple_switch switch_stmt = (gimple_switch)stmt; + size_t i, n = gimple_switch_num_labels (switch_stmt); /* Replace all destination labels. */ for (i = 0; i < n; ++i) { - tree case_label = gimple_switch_label (stmt, i); + tree case_label = gimple_switch_label (switch_stmt, i); label = CASE_LABEL (case_label); new_label = main_block_label (label); if (new_label != label) @@ -1340,7 +1340,7 @@ cleanup_dead_labels (void) Eg. three separate entries 1: 2: 3: become one entry 1..3: */ void -group_case_labels_stmt (gimple stmt) +group_case_labels_stmt (gimple_switch stmt) { int old_size = gimple_switch_num_labels (stmt); int i, j, new_size = old_size; @@ -1428,7 +1428,7 @@ group_case_labels (void) { gimple stmt = last_stmt (bb); if (stmt && gimple_code (stmt) == GIMPLE_SWITCH) - group_case_labels_stmt (stmt); + group_case_labels_stmt ((gimple_switch)stmt); } } @@ -1895,7 +1895,7 @@ find_taken_edge (basic_block bb, tree val) return find_taken_edge_cond_expr (bb, val); if (gimple_code (stmt) == GIMPLE_SWITCH) - return find_taken_edge_switch_expr (bb, val); + return find_taken_edge_switch_expr ((gimple_switch)stmt, bb, val); if (computed_goto_p (stmt)) { @@ -1954,14 +1954,13 @@ find_taken_edge_cond_expr (basic_block bb, tree val) NULL if any edge may be taken. */ static edge -find_taken_edge_switch_expr (basic_block bb, tree val) +find_taken_edge_switch_expr (gimple_switch switch_stmt, basic_block bb, + tree val) { basic_block dest_bb; edge e; - gimple switch_stmt; tree taken_case; - switch_stmt = last_stmt (bb); taken_case = find_case_label_for_value (switch_stmt, val); dest_bb = label_to_block (CASE_LABEL (taken_case)); @@ -1976,7 +1975,7 @@ find_taken_edge_switch_expr (basic_block bb, tree val) sorted: We can do a binary search for a case matching VAL. */ static tree -find_case_label_for_value (gimple switch_stmt, tree val) +find_case_label_for_value (gimple_switch switch_stmt, tree val) { size_t low, high, n = gimple_switch_num_labels (switch_stmt); tree default_case = gimple_switch_default_label (switch_stmt); @@ -4089,7 +4088,7 @@ verify_gimple_goto (gimple stmt) is a problem, otherwise false. */ static bool -verify_gimple_switch (gimple stmt) +verify_gimple_switch (gimple_switch stmt) { unsigned int i, n; tree elt, prev_upper_bound = NULL_TREE; @@ -4270,7 +4269,7 @@ verify_gimple_stmt (gimple stmt) return verify_gimple_goto (stmt); case GIMPLE_SWITCH: - return verify_gimple_switch (stmt); + return verify_gimple_switch ((gimple_switch)stmt); case GIMPLE_RETURN: return verify_gimple_return (stmt); @@ -5000,26 +4999,27 @@ gimple_verify_flow_info (void) case GIMPLE_SWITCH: { + gimple_switch switch_stmt = (gimple_switch)stmt; tree prev; edge e; size_t i, n; - n = gimple_switch_num_labels (stmt); + n = gimple_switch_num_labels (switch_stmt); /* Mark all the destination basic blocks. */ for (i = 0; i < n; ++i) { - tree lab = CASE_LABEL (gimple_switch_label (stmt, i)); + tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i)); basic_block label_bb = label_to_block (lab); gcc_assert (!label_bb->aux || label_bb->aux == (void *)1); label_bb->aux = (void *)1; } /* Verify that the case labels are sorted. */ - prev = gimple_switch_label (stmt, 0); + prev = gimple_switch_label (switch_stmt, 0); for (i = 1; i < n; ++i) { - tree c = gimple_switch_label (stmt, i); + tree c = gimple_switch_label (switch_stmt, i); if (!CASE_LOW (c)) { error ("found default case not at the start of " @@ -5065,7 +5065,7 @@ gimple_verify_flow_info (void) /* Check that we have all of them. */ for (i = 0; i < n; ++i) { - tree lab = CASE_LABEL (gimple_switch_label (stmt, i)); + tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i)); basic_block label_bb = label_to_block (lab); if (label_bb->aux != (void *)2) @@ -5253,8 +5253,9 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest) case GIMPLE_SWITCH: { + gimple_switch switch_stmt = (gimple_switch)stmt; tree label = gimple_block_label (dest); - tree cases = get_cases_for_edge (e, stmt); + tree cases = get_cases_for_edge (e, switch_stmt); /* If we have a list of cases associated with E, then use it as it's a lot faster than walking the entire case vector. */ @@ -5275,7 +5276,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest) to move all the cases associated with E to E2. */ if (e2) { - tree cases2 = get_cases_for_edge (e2, stmt); + tree cases2 = get_cases_for_edge (e2, switch_stmt); CASE_CHAIN (last) = CASE_CHAIN (cases2); CASE_CHAIN (cases2) = first; @@ -5284,11 +5285,11 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest) } else { - size_t i, n = gimple_switch_num_labels (stmt); + size_t i, n = gimple_switch_num_labels (switch_stmt); for (i = 0; i < n; i++) { - tree elt = gimple_switch_label (stmt, i); + tree elt = gimple_switch_label (switch_stmt, i); if (label_to_block (CASE_LABEL (elt)) == e->dest) CASE_LABEL (elt) = label; } diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h index d6a5d8f..72e2637 100644 --- a/gcc/tree-cfg.h +++ b/gcc/tree-cfg.h @@ -33,7 +33,7 @@ extern basic_block label_to_block_fn (struct function *, tree); #define label_to_block(t) (label_to_block_fn (cfun, t)) extern void make_abnormal_goto_edges (basic_block, bool); extern void cleanup_dead_labels (void); -extern void group_case_labels_stmt (gimple); +extern void group_case_labels_stmt (gimple_switch); extern void group_case_labels (void); extern void replace_uses_by (tree, tree); extern basic_block single_noncomplex_succ (basic_block bb); diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index c83229f..d62aa0a 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -704,7 +704,7 @@ maybe_record_in_goto_queue (struct leh_state *state, gimple stmt) of the labels will leave outer GIMPLE_TRY_FINALLY nodes. Verify this. */ static void -verify_norecord_switch_expr (struct leh_state *state, gimple switch_expr) +verify_norecord_switch_expr (struct leh_state *state, gimple_switch switch_expr) { struct leh_tf_state *tf = state->tf; size_t i, n; @@ -2048,7 +2048,7 @@ lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi) break; case GIMPLE_SWITCH: - verify_norecord_switch_expr (state, stmt); + verify_norecord_switch_expr (state, (gimple_switch)stmt); break; case GIMPLE_TRY: diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index e4c80a7..bd74949 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -3727,15 +3727,18 @@ estimate_num_insns (gimple stmt, eni_weights *weights) break; case GIMPLE_SWITCH: - /* Take into account cost of the switch + guess 2 conditional jumps for - each case label. - - TODO: once the switch expansion logic is sufficiently separated, we can - do better job on estimating cost of the switch. */ - if (weights->time_based) - cost = floor_log2 (gimple_switch_num_labels (stmt)) * 2; - else - cost = gimple_switch_num_labels (stmt) * 2; + { + gimple_switch switch_stmt = (gimple_switch)stmt; + /* Take into account cost of the switch + guess 2 conditional jumps for + each case label. + + TODO: once the switch expansion logic is sufficiently separated, we can + do better job on estimating cost of the switch. */ + if (weights->time_based) + cost = floor_log2 (gimple_switch_num_labels (switch_stmt)) * 2; + else + cost = gimple_switch_num_labels (switch_stmt) * 2; + } break; case GIMPLE_CALL: diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 353ce24..c0cd9ea 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -679,8 +679,9 @@ generate_loops_for_partition (struct loop *loop, partition_t partition, } else if (gimple_code (stmt) == GIMPLE_SWITCH) { + gimple_switch switch_stmt = (gimple_switch)stmt; gimple_switch_set_index - (stmt, CASE_LOW (gimple_switch_label (stmt, 1))); + (switch_stmt, CASE_LOW (gimple_switch_label (switch_stmt, 1))); update_stmt (stmt); } else diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 211bfcf..e563366 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -1755,19 +1755,20 @@ record_edge_info (basic_block bb) if (gimple_code (stmt) == GIMPLE_SWITCH) { + gimple_switch switch_stmt = (gimple_switch)stmt; tree index = gimple_switch_index (stmt); if (TREE_CODE (index) == SSA_NAME) { int i; - int n_labels = gimple_switch_num_labels (stmt); + int n_labels = gimple_switch_num_labels (switch_stmt); tree *info = XCNEWVEC (tree, last_basic_block); edge e; edge_iterator ei; for (i = 0; i < n_labels; i++) { - tree label = gimple_switch_label (stmt, i); + tree label = gimple_switch_label (switch_stmt, i); basic_block target_bb = label_to_block (CASE_LABEL (label)); if (CASE_HIGH (label) || !CASE_LOW (label) diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 6ad45c9..116ab27 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -1272,7 +1272,7 @@ simplify_not_neg_expr (gimple_stmt_iterator *gsi_p) have values outside the range of the new type. */ static void -simplify_gimple_switch_label_vec (gimple stmt, tree index_type) +simplify_gimple_switch_label_vec (gimple_switch stmt, tree index_type) { unsigned int branch_num = gimple_switch_num_labels (stmt); vec<tree> labels; @@ -1345,7 +1345,7 @@ simplify_gimple_switch_label_vec (gimple stmt, tree index_type) the condition which we may be able to optimize better. */ static bool -simplify_gimple_switch (gimple stmt) +simplify_gimple_switch (gimple_switch stmt) { tree cond = gimple_switch_index (stmt); tree def, to, ti; @@ -3502,7 +3502,7 @@ ssa_forward_propagate_and_combine (void) } case GIMPLE_SWITCH: - changed = simplify_gimple_switch (stmt); + changed = simplify_gimple_switch ((gimple_switch)stmt); break; case GIMPLE_COND: diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c index 71c1f5d..6a32b26 100644 --- a/gcc/tree-ssa-uncprop.c +++ b/gcc/tree-ssa-uncprop.c @@ -166,12 +166,13 @@ associate_equivalences_with_edges (void) target block creates an equivalence. */ else if (gimple_code (stmt) == GIMPLE_SWITCH) { - tree cond = gimple_switch_index (stmt); + gimple_switch switch_stmt = (gimple_switch)stmt; + tree cond = gimple_switch_index (switch_stmt); if (TREE_CODE (cond) == SSA_NAME && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (cond)) { - int i, n_labels = gimple_switch_num_labels (stmt); + int i, n_labels = gimple_switch_num_labels (switch_stmt); tree *info = XCNEWVEC (tree, last_basic_block); /* Walk over the case label vector. Record blocks @@ -179,7 +180,7 @@ associate_equivalences_with_edges (void) a single value. */ for (i = 0; i < n_labels; i++) { - tree label = gimple_switch_label (stmt, i); + tree label = gimple_switch_label (switch_stmt, i); basic_block bb = label_to_block (CASE_LABEL (label)); if (CASE_HIGH (label) diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 46b9efe..4adb758 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -292,7 +292,7 @@ case_bit_test_cmp (const void *p1, const void *p2) node targets. */ static void -emit_case_bit_tests (gimple swtch, tree index_expr, +emit_case_bit_tests (gimple_switch swtch, tree index_expr, tree minval, tree range) { struct case_bit_test test[MAX_CASE_BIT_TESTS]; @@ -604,7 +604,7 @@ struct switch_conv_info /* Collect information about GIMPLE_SWITCH statement SWTCH into INFO. */ static void -collect_switch_conv_info (gimple swtch, struct switch_conv_info *info) +collect_switch_conv_info (gimple_switch swtch, struct switch_conv_info *info) { unsigned int branch_num = gimple_switch_num_labels (swtch); tree min_case, max_case; @@ -848,7 +848,7 @@ gather_default_values (tree default_case, struct switch_conv_info *info) order of phi nodes. SWTCH is the switch statement being converted. */ static void -build_constructors (gimple swtch, struct switch_conv_info *info) +build_constructors (gimple_switch swtch, struct switch_conv_info *info) { unsigned i, branch_num = gimple_switch_num_labels (swtch); tree pos = info->range_min; @@ -940,7 +940,7 @@ constructor_contains_same_values_p (vec<constructor_elt, va_gc> *vec) all the constants. */ static tree -array_value_type (gimple swtch, tree type, int num, +array_value_type (gimple_switch swtch, tree type, int num, struct switch_conv_info *info) { unsigned int i, len = vec_safe_length (info->constructors[num]); @@ -1017,7 +1017,7 @@ array_value_type (gimple swtch, tree type, int num, new array. */ static void -build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi, +build_one_array (gimple_switch swtch, int num, tree arr_index_type, gimple phi, tree tidx, struct switch_conv_info *info) { tree name, cst; @@ -1083,7 +1083,7 @@ build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi, them. */ static void -build_arrays (gimple swtch, struct switch_conv_info *info) +build_arrays (gimple_switch swtch, struct switch_conv_info *info) { tree arr_index_type; tree tidx, sub, utype; @@ -1204,7 +1204,7 @@ fix_phi_nodes (edge e1f, edge e2f, basic_block bbf, */ static void -gen_inbound_check (gimple swtch, struct switch_conv_info *info) +gen_inbound_check (gimple_switch swtch, struct switch_conv_info *info) { tree label_decl1 = create_artificial_label (UNKNOWN_LOCATION); tree label_decl2 = create_artificial_label (UNKNOWN_LOCATION); @@ -1324,7 +1324,7 @@ gen_inbound_check (gimple swtch, struct switch_conv_info *info) conversion failed. */ static const char * -process_switch (gimple swtch) +process_switch (gimple_switch swtch) { struct switch_conv_info info; @@ -1429,7 +1429,7 @@ do_switchconv (void) putc ('\n', dump_file); } - failure_reason = process_switch (stmt); + failure_reason = process_switch ((gimple_switch)stmt); if (! failure_reason) { if (dump_file) diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index d3a07f3..bd470f9 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -158,7 +158,7 @@ static bool values_propagated; static int *vr_phi_edge_counts; typedef struct { - gimple stmt; + gimple_switch stmt; tree vec; } switch_update; @@ -5668,7 +5668,7 @@ compare_case_labels (const void *p1, const void *p2) list of assertions for the corresponding operands. */ static bool -find_switch_asserts (basic_block bb, gimple last) +find_switch_asserts (basic_block bb, gimple_switch last) { bool need_assert; gimple_stmt_iterator bsi; @@ -5839,7 +5839,7 @@ find_assert_locations_1 (basic_block bb, sbitmap live) if (last && gimple_code (last) == GIMPLE_SWITCH && !ZERO_SSA_OPERANDS (last, SSA_OP_USE)) - need_assert |= find_switch_asserts (bb, last); + need_assert |= find_switch_asserts (bb, (gimple_switch)last); /* Traverse all the statements in BB marking used names and looking for statements that may infer assertions for their used operands. */ @@ -7176,7 +7176,7 @@ vrp_visit_cond_stmt (gimple stmt, edge *taken_edge_p) returned. */ static bool -find_case_label_index (gimple stmt, size_t start_idx, tree val, size_t *idx) +find_case_label_index (gimple_switch stmt, size_t start_idx, tree val, size_t *idx) { size_t n = gimple_switch_num_labels (stmt); size_t low, high; @@ -7226,7 +7226,7 @@ find_case_label_index (gimple stmt, size_t start_idx, tree val, size_t *idx) Returns true if the default label is not needed. */ static bool -find_case_label_range (gimple stmt, tree min, tree max, size_t *min_idx, +find_case_label_range (gimple_switch stmt, tree min, tree max, size_t *min_idx, size_t *max_idx) { size_t i, j; @@ -7282,7 +7282,7 @@ find_case_label_range (gimple stmt, tree min, tree max, size_t *min_idx, Returns true if the default label is not needed. */ static bool -find_case_label_ranges (gimple stmt, value_range_t *vr, size_t *min_idx1, +find_case_label_ranges (gimple_switch stmt, value_range_t *vr, size_t *min_idx1, size_t *max_idx1, size_t *min_idx2, size_t *max_idx2) { @@ -7360,7 +7360,7 @@ find_case_label_ranges (gimple stmt, value_range_t *vr, size_t *min_idx1, SSA_PROP_VARYING. */ static enum ssa_prop_result -vrp_visit_switch_stmt (gimple stmt, edge *taken_edge_p) +vrp_visit_switch_stmt (gimple_switch stmt, edge *taken_edge_p) { tree op, val; value_range_t *vr; @@ -7476,7 +7476,7 @@ vrp_visit_stmt (gimple stmt, edge *taken_edge_p, tree *output_p) else if (gimple_code (stmt) == GIMPLE_COND) return vrp_visit_cond_stmt (stmt, taken_edge_p); else if (gimple_code (stmt) == GIMPLE_SWITCH) - return vrp_visit_switch_stmt (stmt, taken_edge_p); + return vrp_visit_switch_stmt ((gimple_switch)stmt, taken_edge_p); /* All other statements produce nothing of interest for VRP, so mark their outputs varying and prevent further simulation. */ @@ -8928,7 +8928,7 @@ simplify_cond_using_ranges (gimple stmt) argument. */ static bool -simplify_switch_using_ranges (gimple stmt) +simplify_switch_using_ranges (gimple_switch stmt) { tree op = gimple_switch_index (stmt); value_range_t *vr; @@ -9234,7 +9234,7 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi) else if (gimple_code (stmt) == GIMPLE_COND) return simplify_cond_using_ranges (stmt); else if (gimple_code (stmt) == GIMPLE_SWITCH) - return simplify_switch_using_ranges (stmt); + return simplify_switch_using_ranges ((gimple_switch)stmt); return false; } ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) 2013-11-08 19:23 ` David Malcolm @ 2013-11-14 8:38 ` Jeff Law 2013-11-14 15:06 ` Michael Matz 2013-11-14 18:32 ` David Malcolm 0 siblings, 2 replies; 116+ messages in thread From: Jeff Law @ 2013-11-14 8:38 UTC (permalink / raw) To: David Malcolm; +Cc: Michael Matz, Andrew MacLeod, gcc-patches On 11/08/13 12:02, David Malcolm wrote: >> I wouldn't mind seeing a small example proof of concept posted to help >> those who don't see where this is going understand the goal. I would >> recommend against posting another large patch for inclusion at this time. > Attached is a proof-of-concept patch which uses the > gimple_statement_switch subclass (as a "gimple_switch" typedef). This > is one of the subclasses that the earlier patch added, which has no new > fields, but which carries the invariant that, if non-NULL, > gimple_code (gs) == GIMPLE_SWITCH. [ ... ] Thanks. It's pretty much what I expected. Obviously for other codes there may be a lot more changes that you have to slog through, but I think this example shows the main concepts. Presumably in this new world order, the various gimple statement types will continue to inherit from a base class. That seems somewhat inevitable and implies a certain amount of downcasting (via whatever means we agree upon). The worry, in my mind is how pervasive the downcasting will be and how much of it we can get rid of over time. I may be wrong, but ISTM some of the downcasting is a result of not providing certain capabilities via (pure?) virtual methods. For example, expand_gimple_stmt_1 seems ripe for implementing as virtual methods. ISTM you could also have virtuals to build the statements, dump/pretty-print them, verify them, branch/edge redirection, estimations for inlining, etc. ISTM that would eliminate a good chunk of the downcasting. Just to be clear, I'm not asking you to make those changes, just for your thoughts on approaches to eliminate the downcasting based on what we've seen so far. Thanks for pulling this together to help illustrate how some of this might look in practice. I hope others take the time to look closely as this example and think about what it means in terms of how we would be writing code 6 months from now. Jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) 2013-11-14 8:38 ` Jeff Law @ 2013-11-14 15:06 ` Michael Matz 2013-11-14 18:32 ` David Malcolm 1 sibling, 0 replies; 116+ messages in thread From: Michael Matz @ 2013-11-14 15:06 UTC (permalink / raw) To: Jeff Law; +Cc: David Malcolm, Andrew MacLeod, gcc-patches Hi, On Thu, 14 Nov 2013, Jeff Law wrote: > Thanks. It's pretty much what I expected. Obviously for other codes > there may be a lot more changes that you have to slog through, but I > think this example shows the main concepts. > > Presumably in this new world order, the various gimple statement types > will continue to inherit from a base class. That seems somewhat > inevitable and implies a certain amount of downcasting (via whatever > means we agree upon). The worry, in my mind is how pervasive the > downcasting will be and how much of it we can get rid of over time. > > I may be wrong, but ISTM some of the downcasting is a result of not > providing certain capabilities via (pure?) virtual methods. For > example, expand_gimple_stmt_1 seems ripe for implementing as virtual > methods. Please no. A class with many methods hints at a bad design. If we were to add virtual methods for every piece of the hundred passes that have to do different things per instruction code we'd arrive at exactly that. Even though most of these methods would be more related to the pass they're in they would actually have to be implemented in the gimple class (and their inherited ones). I wouldn't want to see methods ala expand_me(), remove_me(), remove_me_for_predcom(), remove_me_for_some_other_pass(), optimize_me_for_{this,that,another}() and so on. > ISTM you could also have virtuals to build the statements, Virtual to build things? You mean constructors. > dump/pretty-print them, True. > verify them, Depends. Part of them can be verified without context information, and that would perhaps be sensible in some virtual methods. Part of the verification depends on context, other insns, the call graph, the CFG. Those should IMHO not be methods of gimple. > branch/edge redirection, That seems to me more related to the cfg, not to statements. Some statements need to be modified, true, but only very few subclasses (those that can transfer control). > estimations for inlining, Part of that (again the things you can determine with a statement alone, without much context, yes. > etc. ISTM that would eliminate a good chunk > of the downcasting. > > Just to be clear, I'm not asking you to make those changes, just for > your thoughts on approaches to eliminate the downcasting based on what > we've seen so far. Before adding a vtable pointer to gimple (or any other central, heavily used data structure) I'd go through great pain to avoid that. Ciao, Michael. ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) 2013-11-14 8:38 ` Jeff Law 2013-11-14 15:06 ` Michael Matz @ 2013-11-14 18:32 ` David Malcolm 2013-11-15 2:49 ` Jeff Law 1 sibling, 1 reply; 116+ messages in thread From: David Malcolm @ 2013-11-14 18:32 UTC (permalink / raw) To: Jeff Law; +Cc: Michael Matz, Andrew MacLeod, gcc-patches On Thu, 2013-11-14 at 00:13 -0700, Jeff Law wrote: > On 11/08/13 12:02, David Malcolm wrote: > >> I wouldn't mind seeing a small example proof of concept posted to help > >> those who don't see where this is going understand the goal. I would > >> recommend against posting another large patch for inclusion at this time. > > Attached is a proof-of-concept patch which uses the > > gimple_statement_switch subclass (as a "gimple_switch" typedef). This > > is one of the subclasses that the earlier patch added, which has no new > > fields, but which carries the invariant that, if non-NULL, > > gimple_code (gs) == GIMPLE_SWITCH. > [ ... ] > > Thanks. It's pretty much what I expected. Obviously for other codes > there may be a lot more changes that you have to slog through, but I > think this example shows the main concepts. > > Presumably in this new world order, the various gimple statement types > will continue to inherit from a base class. That seems somewhat > inevitable and implies a certain amount of downcasting (via whatever > means we agree upon). The worry, in my mind is how pervasive the > downcasting will be and how much of it we can get rid of over time. > > I may be wrong, but ISTM some of the downcasting is a result of not > providing certain capabilities via (pure?) virtual methods. For > example, expand_gimple_stmt_1 seems ripe for implementing as virtual > methods. ISTM you could also have virtuals to build the statements, > dump/pretty-print them, verify them, branch/edge redirection, > estimations for inlining, etc. ISTM that would eliminate a good chunk > of the downcasting. FWIW, I prefer the downcasts to adding virtual functions; what I've tried to do is create a very direct mapping from the status quo, introducing inheritance to gain the benefits listed earlier in the thread, whilst only changing "surface syntax". It seems to me that we're considering the general problem of type-safe code dispatch: given a type hierarchy, and various sites that want to vary behavior based on what types they see, how best to invoke the appropriate code, ensuring that the code that's called "knows" that its dealing with the appropriate subclass i.e. in a typesafe manner. There are various idioms for doing this kind of dispatch in C++, a non-exhaustive list is: (a) switches and if/then tests on the GIMPLE_CODE (stmt) - the status quo, and what my proposed patch continues to do, albeit gaining some compile-time typechecking using as_a<> for the switch and dyn_cast<> for the if/then. This is changing some surface syntax without making major changes, and gains us compile-time typesafety and IMHO more readable code, though clearly opinions vary here. In my (brief) testing, (a) has no significant effect on compiler performance. (b) adding virtual functions to gimple would be another way to handle type-safe dispatch, but they carry costs: (i) they would implicitly add a vtable ptr to the top of every gimple statement, increasing the memory consumption of the process (ii) it's my belief that a virtual function call is more expensive than the kinds of switch/if+then branching that we're currently doing on the code - though I don't have measurements to back this up (iii) what I call "link-time granularity". A vtable references every method within it. I'd love to have a libgimple.so, but to do so, every vtable would need to be populated with a particular set of operations at link time - where do we draw the line for "core" gimple operations, the dispatches performed by every core pass? The set of operations will never be complete: some plugin may want to add a new set of per-gimple-subclass behaviors for some custom gimple pass. (c) the "Visitor" design pattern [1] - rather than adding virtual functions to gimple, instead add them to a visitor class e.g.: class gimple_visitor { public: /* Visit a statement. This will dispatch to the appropriate handler below, based on GIMPLE_CODE (stmt), encapsulating the appropriate downcast within a big switch statement. */ void visit_stmt (gimple stmt); protected: /* Each gimple code gets its own handler. This class provides an empty implementation of each. If we want to force overrides, we could have an abstract_gimple_visitor base class above this one that has all of these be pure virtual. */ virtual void visit_cond (gimple_cond stmt) {} virtual void visit_switch (gimple_switch stmt) {} virtual void visit_assign (gimple_assign stmt) {} virtual void visit_phi (gimple_phi phi) {} /* etc */ }; Example of a subclass: class gimple_pretty_printer : public gimple_visitor { protected: /* Each of these implements the subclass-specific pretty-printing logic. */ void visit_cond (gimple_cond stmt); void visit_switch (gimple_switch stmt); void visit_assign (gimple_assign stmt); void visit_phi (gimple_phi phi); /* etc */ }; so that the dispatch can be written like this: gimple_pretty_printer pp; pp.visit_stmt (stmt); (the above isn't *exactly* the Visitor pattern from the Gang of Four book, I'm doing things in the visitor in order avoiding adding vfuncs to gimple). This approach avoids adding an implicit vtable field to the top of gimple [(i) above], and keeps the vtables with the code using them [(iii) above]. However it still would mean (ii) changing from switch/if-then control flow to vfunc calls, with unknown impact on performance. I'd be nervous about adding virtual functions anywhere where we're not already jumping though function ptrs. [Aside: this approach also gives us a natural place to store state relating to the dispatch (as fields of the visitor subclass), which may help in removing global state from the compiler. (Doesn't help with GTY state though)] (d) The status quo, with the drawback of doing the type-checking either at run-time (checked build) or not at all (release build). We have 41 gimple codes (and adding new ones is a relatively rare event), but many more dispatch sites, I think - a first estimate might be: [gcc] $ grep -nH -e "gimple_code (" *.c | wc -l 772 So we have (I think) a large number of sites that dispatch to code based on a (relatively) small fixed set of types - this suggests to me the use of the Visitor pattern: (c) above, but I think (a) is the conservative approach that gives many benefits for relatively low risk, and gives us an easy transition path to (c) if measurement establishes the lack of significant performance impact. Such a transition could be done piecemeal. > Just to be clear, I'm not asking you to make those changes, just for > your thoughts on approaches to eliminate the downcasting based on what > we've seen so far. (nods). Note that I don't regard the downcasting as inherently bad, just one approach to the generic issue of typesafe dynamic code dispatch. Yes, in many OO textbooks, it's regarded as a code smell, but then again "goto" has its uses :) > Thanks for pulling this together to help illustrate how some of this > might look in practice. I hope others take the time to look closely as > this example and think about what it means in terms of how we would be > writing code 6 months from now. On the subject of "6 months from now", my dream is that we can have a libgimple.so and a librtl.so (.a in the regular builds). I've love to build a pluggable static analyzer on top of the gimple code - so I'm trying to think of how we can structure the gimple code in such a way that it's reusable in a modular way. FWIW, I don't like the implicit "pointerness" of types within my proposed patch, I'd rather have, say, the "gimple_switch" type be the underlying _struct_, and spell out "gimple_switch *" to make it clear that the latter is a pointer. Doing so would make the is-a.h API somewhat less clunky, so that one could write: if (gimple_switch *swtch = dyn_cast<gimple_switch> (stmt)) { // do switchy stuff on swtch. } rather than: if (gimple_switch swtch = dyn_cast<gimple_statement_switch> (stmt)) { // do switchy stuff on swtch. } Another tweak to the patch series could be to only introduce the leaf subclasses one at a time, each time making use of the new subclass. For example, the "gimple_switch" subclass would be added at the same time as a patch that makes use of it to improve compile-time typesafety, so each patch would contain its own justification, as it were (applying the YAGNI principle). Sorry for the long email; thanks for reading to the end. Dave [1] see the Gang of Four "Design Pattens" book, or e.g. http://en.wikipedia.org/wiki/Visitor_pattern ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) 2013-11-14 18:32 ` David Malcolm @ 2013-11-15 2:49 ` Jeff Law 0 siblings, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-15 2:49 UTC (permalink / raw) To: David Malcolm; +Cc: Michael Matz, Andrew MacLeod, gcc-patches On 11/14/13 10:49, David Malcolm wrote: > > FWIW, I prefer the downcasts to adding virtual functions; what I've > tried to do is create a very direct mapping from the status quo, > introducing inheritance to gain the benefits listed earlier in the > thread, whilst only changing "surface syntax". I understand (and I probably encouraged you to stay close as close to the status quo as possible while still moving this stuff forward ;-) > > It seems to me that we're considering the general problem of type-safe > code dispatch: given a type hierarchy, and various sites that want to > vary behavior based on what types they see, how best to invoke the > appropriate code, ensuring that the code that's called "knows" that its > dealing with the appropriate subclass i.e. in a typesafe manner. Right. Certainly in my quick browsing, this is primarily a dispatch problem. I think Andrew had one in his Cauldron slide deck as well. > > There are various idioms for doing this kind of dispatch in C++, a > non-exhaustive list is: > > (a) switches and if/then tests on the GIMPLE_CODE (stmt) - the status > quo, Right. And probably appropriate for now. But I do want us to think about better ways to handle this. > > (b) adding virtual functions to gimple would be another way to handle > type-safe dispatch, but they carry costs: > (i) they would implicitly add a vtable ptr to the top of every > gimple statement, increasing the memory consumption of the process Thats my biggest concern. > (ii) it's my belief that a virtual function call is more expensive > than the kinds of switch/if+then branching that we're currently doing on > the code - though I don't have measurements to back this up The virtual call is probably more expensive, but probably not as much as you might think as the switch likely compiles down to a multi-way branch which is on-par with an indirect call. > > (c) the "Visitor" design pattern [1] - rather than adding virtual > functions to gimple, instead add them to a visitor class e.g.: Basically this just puts the vtable in a different class. But doesn't the wrapping visitor need to know about the underlying details of the gimple statement class? If we're trying to encapsulate things better, doesn't a visitor break the encapsulation? > > (the above isn't *exactly* the Visitor pattern from the Gang of Four > book, I'm doing things in the visitor in order avoiding adding vfuncs to > gimple). Right. My mental model when I wrote my last message as a visit method which dispatched to the statement specific bits, but with the method as a part of the gimple base class. > > This approach avoids adding an implicit vtable field to the top of > gimple [(i) above], and keeps the vtables with the code using them > [(iii) above]. Right. > > However it still would mean (ii) changing from switch/if-then control > flow to vfunc calls, with unknown impact on performance. I'd be nervous > about adding virtual functions anywhere where we're not already jumping > though function ptrs. As noted above, jumping through a function pointer probably isn't much different performance-wise than a multi-way branch. Anyway, just wanted to get the conversation around this started as cleaning this stuff up is a natural follow-on at some point. > > (nods). Note that I don't regard the downcasting as inherently bad, > just one approach to the generic issue of typesafe dynamic code > dispatch. Yes, in many OO textbooks, it's regarded as a code smell, > but then again "goto" has its uses :) Again, my opinions come from working on large codes which did a lot of downcasting (and sadly upcasting too) and it was a major PITA to get sorted out. Thanks, jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) 2013-11-07 6:19 ` David Malcolm 2013-11-07 7:08 ` Jeff Law @ 2013-11-07 14:57 ` Michael Matz 1 sibling, 0 replies; 116+ messages in thread From: Michael Matz @ 2013-11-07 14:57 UTC (permalink / raw) To: David Malcolm; +Cc: Andrew MacLeod, Jeff Law, gcc-patches Hi, On Wed, 6 Nov 2013, David Malcolm wrote: > > I don't like that. The empty classes are just useless, they imply a > > structure that isn't really there, some of the separate gimple codes > > are basically selectors of specific subtypes of a generic concept, > > without additional data or methods; creating a type for those is > > confusing. > > A type system does more than just express memory layouts: I know all that. But there's a point on the scale from a void* type system to a different-type-for-everything system where the advantages of a more complex type system are anulled by the disadvantages of a more complex type system. And I'm merely of the opinion that you crossed that point with this separation. You know we could have a typesystem where every different natural number is a type (and with C++ we _really_ could do that). Obviously that's also a reductio ad absurdum, but it demonstrates the point that there _are_ type systems with a too low complexity to expressiveness ratio. > * it permits the proof of absence of certain bugs > * it supports abstraction > * it documents the intent of the code Well, yes. You can document code with other things than types, you can add abstractions via different means, and certain bugs can indeed only be ruled out by different static types. In my mind types should abstract different larger concepts foremost (and not every little aspect of a concept). Only _then_ should they be used for other effects like the above, and only if the disadvantages don't overshadow that. Disadvantages being mostly simply more complexity: which types relate to others in which way; what are the methods you can do with that but not the other type; which are the members of the 100 types there are (and if a type system is too large to be used only by IDEs with code completion, then it's too complex); and of course also simply having to write more text when you can't use the same gimple variable for several statements. > To give an example from the patch, the proposed gimple_statement_switch > subclass of gimple_statement_with_ops adds no extra fields, but it adds > the invariant that (assuming the ptr is non-NULL), that code == > GIMPLE_SWITCH, or, more intuitively, "it's a switch statement". > > This means that if we have a gimple_statement_switch, that both a human > reading the code and the compiler can "know" at compile-time that the > code == GIMPLE_SWITCH. But a gimple switch is actually a special case of a gimple conditional jump (the normal GIMPLE_COND being another) which itself is a special case of a gimple control transfer (a thing causing one or multiple outgoing edges and ending a basic block). That enlightens that your hierarchy might not actually be the best split of types, it's merely a formal translation of gimple codes into types. And I question exactly that automatic introduction of types. There's not enough human thought put into the hierarchy to warrant the change. Types are a fundament and they shouldn't be introduced lightly. As gimple codes are simply flat it doesn't matter so much that the inherent structure of gimple statements isn't reflected (although there _is_ some structure by having the with_ops and with_mem_ops codes be together). But for a _type hierarchy_ I would pretty much require that real thought and insights are put into it. > Consider tree-switch-conversion.c: this contains various "gimple" > variables but they don't work on arbitrary gimple; they require code == > GIMPLE_SWITCH: > ... > We could be doing this directly in the type system, and using the > compiler to check it. Then please do that while introducing one new type. > > The fewer > > types the better IMO. > > There's a reductio ad absurdum of that argument: See above for my variant of that showing that it also goes into the other direction of more types. Ciao, Michael. P.S.: And do away with the "_statement" part of the type, gimple_switch ought to be enough. ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) 2013-11-06 16:53 ` Michael Matz 2013-11-07 6:19 ` David Malcolm @ 2013-11-08 0:07 ` Alec Teal 2013-11-08 14:31 ` Michael Matz 1 sibling, 1 reply; 116+ messages in thread From: Alec Teal @ 2013-11-08 0:07 UTC (permalink / raw) To: Michael Matz; +Cc: David Malcolm, Andrew MacLeod, gcc-patches Hello On 06/11/13 15:32, Michael Matz wrote: > Hi, > > On Tue, 5 Nov 2013, David Malcolm wrote: > >> Here's a followup patch which ensures that every gimple code has its own >> subclass, by adding empty subclasses derived from the GSS_-based >> subclasses as appropriate (I don't bother for gimple codes that already >> have their own subclass due to having their own GSS layout). I also >> copied the comments from gimple.def into gimple.h, so that Doxygen picks >> up on the descriptions and uses them to describe each subclass. > I don't like that. The empty classes are just useless, they imply a > structure that isn't really there, some of the separate gimple codes are > basically selectors of specific subtypes of a generic concept, without > additional data or methods; creating a type for those is confusing. > > Generally I don't like complicating the type system without good reasons > (as in actually also making use of the complicated types). The fewer > types the better IMO. How would you do this? The types are different even if there is no actual difference, much like there are different gimple codes in the first place. He is trying to create a bijection between what we did have and what we now have so nothing breaks. > > > Ciao, > Michael. ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) 2013-11-08 0:07 ` Alec Teal @ 2013-11-08 14:31 ` Michael Matz 0 siblings, 0 replies; 116+ messages in thread From: Michael Matz @ 2013-11-08 14:31 UTC (permalink / raw) To: Alec Teal; +Cc: David Malcolm, Andrew MacLeod, gcc-patches Hi, On Thu, 7 Nov 2013, Alec Teal wrote: > > > subclass, by adding empty subclasses derived from the GSS_-based > > > subclasses as appropriate (I don't bother for gimple codes that already > > > have their own subclass due to having their own GSS layout). I also > > > copied the comments from gimple.def into gimple.h, so that Doxygen picks > > > up on the descriptions and uses them to describe each subclass. > > I don't like that. The empty classes are just useless, they imply a > > structure that isn't really there, some of the separate gimple codes are > > basically selectors of specific subtypes of a generic concept, without > > additional data or methods; creating a type for those is confusing. > > > > Generally I don't like complicating the type system without good reasons > > (as in actually also making use of the complicated types). The fewer > > types the better IMO. > How would you do this? How would I do what? Making use of new types? Well, like the opportunity that David already identified in tree-switching, I'd introduce the new type together with a patch to that pass to make use of it. Further I'd try to think about how that new type represents a concept, how that would be generalized, and how it would fit in a really designed type hierarchy of gimple statements. Then I would try to think about interaction of those new types with others we already have, in particular containers (should those become specialized as well? I would say no from my gut, but that question does need some pondering). > The types are different even if there is no actual difference, much like > there are different gimple codes in the first place. He is trying to > create a bijection between what we did have and what we now have Yes, I understood that, and that's IMO the wrong way to introduce new types. It really deserves some more than "we have these dozen gimple codes, let's create a dozen new types". So, while a bijection between codes and types is simple to create, I'm pretty sure that's not the best mapping. > so nothing breaks. Currently nothing is broken, so that's certainly not the reason to introduce new types. Ciao, Michael. ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-01 21:36 ` Andrew MacLeod ` (2 preceding siblings ...) 2013-11-05 17:23 ` [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) David Malcolm @ 2013-11-05 18:22 ` Andrew MacLeod 3 siblings, 0 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-11-05 18:22 UTC (permalink / raw) To: David Malcolm; +Cc: gcc-patches, Richard Biener, Jeff Law, Jakub Jelinek On 11/01/2013 05:36 PM, Andrew MacLeod wrote: > On 10/31/2013 12:26 PM, David Malcolm wrote: >> [Shamelessly hijacking Andrew's thread about gimple.h refactoring, >> since this seems on-topic for that, and I'm keen to hear from Andrew on >> how the following would interact with his work - I *think* our two >> cleanups are orthogonal. > <...> > > That all said, this change enables that work to proceed if someone > wants to do it. > > My question is: Is anyone going to do it, and if so, who and when? :-) So in case the waters have gotten muddy... I am not resisting this patch for 4.9... I think its a reasonable cleanup and was pointing out another way it could be useful down the road.. I'd be happy to see some form of it go in. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-10-31 16:41 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) David Malcolm ` (7 preceding siblings ...) 2013-11-01 21:36 ` Andrew MacLeod @ 2013-11-05 21:33 ` Jeff Law 2013-11-05 22:01 ` David Malcolm ` (2 more replies) 2013-11-14 8:40 ` Jeff Law 9 siblings, 3 replies; 116+ messages in thread From: Jeff Law @ 2013-11-05 21:33 UTC (permalink / raw) To: David Malcolm, gcc-patches, Andrew MacLeod On 10/31/13 10:26, David Malcolm wrote: > The gimple statement types are currently implemented using a hand-coded > C inheritance scheme, with a "union gimple_statement_d" holding the > various possible structs for a statement. > > The following series of patches convert it to a C++ hierarchy, using the > existing structs, eliminating the union. The "gimple" typedef changes > from being a > (union gimple_statement_d *) > to being a: > (struct gimple_statement_base *) > > There are no virtual functions in the new code: the sizes of the various > structs are unchanged. > > It makes use of "is-a.h", using the as_a <T> template function to > perform downcasts, which are checked (via gcc_checking_assert) in an > ENABLE_CHECKING build, and are simple casts in an unchecked build, > albeit it in an inlined function rather than a macro. > > For example, one can write: > > gimple_statement_phi *phi = > as_a <gimple_statement_phi> (gsi_stmt (gsi)); > > and then directly access the fields of the phi, as a phi. The existing > accessor functions in gimple.h become somewhat redundant in this > scheme, but are preserved. > > The earlier versions of the patches made all of the types GTY((user)) > and provided hand-written implementations of the gc and pch marker > routines. In this new version we rely on the support for simple > inheritance that I recently added to gengtype, by adding a "desc" > to the GTY marking for the base class, and a "tag" to the marking > for all of the concrete subclasses. (I say "class", but all the types > remain structs since their fields are all publicly accessible). > > As noted in the earlier patch, I believe this is a superior scheme to > the C implementation: > > * We can get closer to compile-time type-safety, checking the gimple > code once and downcasting with an as_a, then directly accessing > fields, rather than going through accessor functions that check > each time. In some places we may want to replace a "gimple" with > a subclass e.g. phis are always of the phi subclass, to get full > compile-time type-safety. > > * This scheme is likely to be easier for newbies to understand. > > * Currently in gdb, dereferencing a gimple leads to screenfuls of text, > showing all the various union values. With this, you get just the base > class, and can cast it to the appropriate subclass. > > * With this, we're working directly with the language constructs, > rather than rolling our own, and thus other tools can better > understand the code. (e.g. doxygen). > > Again, as noted in the earlier patch series, the names of the structs > are rather verbose. I would prefer to also rename them all to eliminate > the "_statement" component: > "gimple_statement_base" -> "gimple_base" > "gimple_statement_phi" -> "gimple_phi" > "gimple_statement_omp" -> "gimple_omp" > etc, but I didn't do this to mimimize the patch size. But if the core > maintainers are up for that, I can redo the patch series with that > change also, or do that as a followup. > > The patch is in 6 parts; all of them are needed together. And that's part of the problem. There's understandable resistance to (for example) the as_a casting. There's a bit of natural tension between the desire to keep patches small and self-contained and the size/scope of the changes necessary to do any serious reorganization work. This set swings too far in the latter direction :-) Is there any way to go forward without the is_a/as_a stuff? ie, is there're a simpler step towards where we're trying to go that allows most of this to go forward now rather than waiting? > > * Patch 1 of 6: This patch adds inheritance to the various gimple > types, eliminating the initial baseclass fields, and eliminating the > union gimple_statement_d. All the types remain structs. They > become marked with GTY(()), gaining GSS_ tag values. > > * Patch 2 of 6: This patch ports various accessor functions within > gimple.h to the new scheme. > > * Patch 3 of 6: This patch is autogenerated by "refactor_gimple.py" > from https://github.com/davidmalcolm/gcc-refactoring-scripts > There is a test suite "test_refactor_gimple.py" which may give a > clearer idea of the changes that the script makes (and add > confidence that it's doing the right thing). > The patch converts code of the form: > { > GIMPLE_CHECK (gs, SOME_CODE); > gimple_subclass_get/set_some_field (gs, value); > } > to code of this form: > { > some_subclass *stmt = as_a <some_subclass> (gs); > stmt->some_field = value; > } > It also autogenerates specializations of > is_a_helper <T>::test > equivalent to a GIMPLE_CHECK() for use by is_a and as_a. Conceptually I'm fine with #1-#3. > > * Patch 4 of 6: This patch implement further specializations of > is_a_helper <T>::test, for gimple_has_ops and gimple_has_mem_ops. Here's where I start to get more concerned. > > * Patch 5 of 6: This patch does the rest of porting from union access > to subclass access (all the fiddly places that the script in patch 3 > couldn't handle). > > * Patch 6 of 6: This patch updates the gdb python pretty-printing > hook. Conceptually #5 and #6 shouldn't be terribly controversial. THe question is can we move forward without patch #4, even if that means we aren't getting the static typechecking we want? Jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-05 21:33 ` Jeff Law @ 2013-11-05 22:01 ` David Malcolm 2013-11-05 22:17 ` Jeff Law 2013-11-05 22:24 ` Andrew MacLeod 2013-11-05 22:12 ` Andrew MacLeod 2013-11-06 9:37 ` Richard Biener 2 siblings, 2 replies; 116+ messages in thread From: David Malcolm @ 2013-11-05 22:01 UTC (permalink / raw) To: Jeff Law; +Cc: gcc-patches, Andrew MacLeod On Tue, 2013-11-05 at 14:18 -0700, Jeff Law wrote: > On 10/31/13 10:26, David Malcolm wrote: > > The gimple statement types are currently implemented using a hand-coded > > C inheritance scheme, with a "union gimple_statement_d" holding the > > various possible structs for a statement. > > > > The following series of patches convert it to a C++ hierarchy, using the > > existing structs, eliminating the union. The "gimple" typedef changes > > from being a > > (union gimple_statement_d *) > > to being a: > > (struct gimple_statement_base *) > > > > There are no virtual functions in the new code: the sizes of the various > > structs are unchanged. > > > > It makes use of "is-a.h", using the as_a <T> template function to > > perform downcasts, which are checked (via gcc_checking_assert) in an > > ENABLE_CHECKING build, and are simple casts in an unchecked build, > > albeit it in an inlined function rather than a macro. > > > > For example, one can write: > > > > gimple_statement_phi *phi = > > as_a <gimple_statement_phi> (gsi_stmt (gsi)); > > > > and then directly access the fields of the phi, as a phi. The existing > > accessor functions in gimple.h become somewhat redundant in this > > scheme, but are preserved. > > > > The earlier versions of the patches made all of the types GTY((user)) > > and provided hand-written implementations of the gc and pch marker > > routines. In this new version we rely on the support for simple > > inheritance that I recently added to gengtype, by adding a "desc" > > to the GTY marking for the base class, and a "tag" to the marking > > for all of the concrete subclasses. (I say "class", but all the types > > remain structs since their fields are all publicly accessible). > > > > As noted in the earlier patch, I believe this is a superior scheme to > > the C implementation: > > > > * We can get closer to compile-time type-safety, checking the gimple > > code once and downcasting with an as_a, then directly accessing > > fields, rather than going through accessor functions that check > > each time. In some places we may want to replace a "gimple" with > > a subclass e.g. phis are always of the phi subclass, to get full > > compile-time type-safety. > > > > * This scheme is likely to be easier for newbies to understand. > > > > * Currently in gdb, dereferencing a gimple leads to screenfuls of text, > > showing all the various union values. With this, you get just the base > > class, and can cast it to the appropriate subclass. > > > > * With this, we're working directly with the language constructs, > > rather than rolling our own, and thus other tools can better > > understand the code. (e.g. doxygen). > > > > Again, as noted in the earlier patch series, the names of the structs > > are rather verbose. I would prefer to also rename them all to eliminate > > the "_statement" component: > > "gimple_statement_base" -> "gimple_base" > > "gimple_statement_phi" -> "gimple_phi" > > "gimple_statement_omp" -> "gimple_omp" > > etc, but I didn't do this to mimimize the patch size. But if the core > > maintainers are up for that, I can redo the patch series with that > > change also, or do that as a followup. > > > > The patch is in 6 parts; all of them are needed together. > And that's part of the problem. There's understandable resistance to > (for example) the as_a casting. > > There's a bit of natural tension between the desire to keep patches > small and self-contained and the size/scope of the changes necessary to > do any serious reorganization work. This set swings too far in the > latter direction :-) > > Is there any way to go forward without the is_a/as_a stuff? ie, is > there're a simpler step towards where we're trying to go that allows > most of this to go forward now rather than waiting? > > > > > * Patch 1 of 6: This patch adds inheritance to the various gimple > > types, eliminating the initial baseclass fields, and eliminating the > > union gimple_statement_d. All the types remain structs. They > > become marked with GTY(()), gaining GSS_ tag values. > > > > * Patch 2 of 6: This patch ports various accessor functions within > > gimple.h to the new scheme. > > > > * Patch 3 of 6: This patch is autogenerated by "refactor_gimple.py" > > from https://github.com/davidmalcolm/gcc-refactoring-scripts > > There is a test suite "test_refactor_gimple.py" which may give a > > clearer idea of the changes that the script makes (and add > > confidence that it's doing the right thing). > > The patch converts code of the form: > > { > > GIMPLE_CHECK (gs, SOME_CODE); > > gimple_subclass_get/set_some_field (gs, value); > > } > > to code of this form: > > { > > some_subclass *stmt = as_a <some_subclass> (gs); > > stmt->some_field = value; > > } > > It also autogenerates specializations of > > is_a_helper <T>::test > > equivalent to a GIMPLE_CHECK() for use by is_a and as_a. > Conceptually I'm fine with #1-#3. > > > > > * Patch 4 of 6: This patch implement further specializations of > > is_a_helper <T>::test, for gimple_has_ops and gimple_has_mem_ops. > Here's where I start to get more concerned. Thanks for looking through this. Both you and Andrew objected to my use of the is-a.h stuff. Is this due to the use of C++ templates in that code? If I were to rewrite things in a more C idiom, would that be acceptable? For instance, rather than, say: p = as_a <gimple_statement_asm> ( gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK, ninputs + noutputs + nclobbers + nlabels)); we could have an inlined as_a equivalent in C syntax: p = gimple_as_a_gimple_asm ( gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK, ninputs + noutputs + nclobbers + nlabels)); where there could be, say, a pair of functions like this (to handle const vs non-const): inline gimple_asm gimple_as_a_gimple_asm (gimple gs) { GIMPLE_CHECK (gs->code == GIMPLE_ASM); return (gimple_asm)gs; } inline const_gimple_asm gimple_as_a_gimple_asm (const_gimple gs) { GIMPLE_CHECK (gs->code == GIMPLE_ASM); return (const_gimple_asm)gs; } (where typedef gimple_statement_asm *gimple_asm) That would avoid template usage within the patch, leaving the use of C++ inheritance as the only overtly C++ish aspect. We could do the above using preprocessor magic, but I'd prefer to have actual code to do it. Similarly, instead of: const gimple_statement_with_ops *ops_stmt = dyn_cast <const gimple_statement_with_ops> (g); if (!ops_stmt) return NULL; we could have: const_gimple_with_ops ops_stmt = gimple_dyn_cast_gimple_with_ops (g); if (!ops_stmt) return NULL; > > * Patch 5 of 6: This patch does the rest of porting from union access > > to subclass access (all the fiddly places that the script in patch 3 > > couldn't handle). > > > > * Patch 6 of 6: This patch updates the gdb python pretty-printing > > hook. > Conceptually #5 and #6 shouldn't be terribly controversial. (...though they're implicitly using the template specializations from #3 and #4) > THe question is can we move forward without patch #4, even if that means > we aren't getting the static typechecking we want? Maybe. If the above idea is still too far, we could keep the GIMPLE_CHECK checking, and cast by hand. I suspect the results would be more ugly (though it's clear that beauty is in the eye of the beholder here :)) BTW, how do you feel about static_cast<> vs C-style casts? Thanks Dave ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-05 22:01 ` David Malcolm @ 2013-11-05 22:17 ` Jeff Law 2013-11-06 1:14 ` Ian Lance Taylor 2013-11-05 22:24 ` Andrew MacLeod 1 sibling, 1 reply; 116+ messages in thread From: Jeff Law @ 2013-11-05 22:17 UTC (permalink / raw) To: David Malcolm; +Cc: gcc-patches, Andrew MacLeod On 11/05/13 14:57, David Malcolm wrote: > > Thanks for looking through this. > > Both you and Andrew objected to my use of the is-a.h stuff. Is this due > to the use of C++ templates in that code? If I were to rewrite things > in a more C idiom, would that be acceptable? I can't speak for Andrew, but my experience with this kind of object type casting in a large C++ project is that it's a red flag for a design problem. You could certainly argue that the design problem already exists. You could further argue that what you're doing is marking those warts visible in the code rather than in the data structures. Whether or not that's a good thing I haven't pondered much. For me personally it's less about the syntax. Others may have other opinions. I strongly suggest they chime in with them ;-) > > Maybe. If the above idea is still too far, we could keep the > GIMPLE_CHECK checking, and cast by hand. I suspect the results would be > more ugly (though it's clear that beauty is in the eye of the beholder > here :)) > > BTW, how do you feel about static_cast<> vs C-style casts? Dislike them both :-) jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-05 22:17 ` Jeff Law @ 2013-11-06 1:14 ` Ian Lance Taylor 2013-11-06 20:49 ` Jeff Law 0 siblings, 1 reply; 116+ messages in thread From: Ian Lance Taylor @ 2013-11-06 1:14 UTC (permalink / raw) To: Jeff Law; +Cc: David Malcolm, gcc-patches, Andrew MacLeod On Tue, Nov 5, 2013 at 2:12 PM, Jeff Law <law@redhat.com> wrote: > > I can't speak for Andrew, but my experience with this kind of object type > casting in a large C++ project is that it's a red flag for a design problem. I'm going to chime in to say that I think it's a pretty typical way to represent a compiler IR in C++. There is a base type that a lot of code uses, but there is also a real type, and the way to get to that real type is to use a cast. We could do it all with virtual functions, but those carry a different cost. In effect, using virtual functions increases the size of the code field from 16 bits to 64 bits. It adds up. Also this seems to be a pretty direct version of the data structures we already have. Ian ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 1:14 ` Ian Lance Taylor @ 2013-11-06 20:49 ` Jeff Law 2013-11-06 20:57 ` Trevor Saunders 0 siblings, 1 reply; 116+ messages in thread From: Jeff Law @ 2013-11-06 20:49 UTC (permalink / raw) To: Ian Lance Taylor; +Cc: David Malcolm, gcc-patches, Andrew MacLeod On 11/05/13 16:23, Ian Lance Taylor wrote: > On Tue, Nov 5, 2013 at 2:12 PM, Jeff Law <law@redhat.com> wrote: >> >> I can't speak for Andrew, but my experience with this kind of object type >> casting in a large C++ project is that it's a red flag for a design problem. > > I'm going to chime in to say that I think it's a pretty typical way to > represent a compiler IR in C++. There is a base type that a lot of > code uses, but there is also a real type, and the way to get to that > real type is to use a cast. We could do it all with virtual > functions, but those carry a different cost. In effect, using virtual > functions increases the size of the code field from 16 bits to 64 > bits. It adds up. > > Also this seems to be a pretty direct version of the data structures > we already have. Certainly and to some degree these casts in one form or another are a necessity. My concern is we use them as a crutch (as I've seen in other projects) and we end up not getting the level of compile time static type checking that we want. If the bulk are temporary in nature and we as a project agree to look at the refactoring necessary to minimize the is-a/as-a uses to a few low level idioms, then I'll hesitatingly go along. If that's the choice we make, then folks should know I'll probably look at each is-a/as-a in patches I review and ask for a justification for their use. jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 20:49 ` Jeff Law @ 2013-11-06 20:57 ` Trevor Saunders 0 siblings, 0 replies; 116+ messages in thread From: Trevor Saunders @ 2013-11-06 20:57 UTC (permalink / raw) To: gcc-patches On Wed, Nov 06, 2013 at 01:38:23PM -0700, Jeff Law wrote: > On 11/05/13 16:23, Ian Lance Taylor wrote: > >On Tue, Nov 5, 2013 at 2:12 PM, Jeff Law <law@redhat.com> wrote: > >> > >>I can't speak for Andrew, but my experience with this kind of object type > >>casting in a large C++ project is that it's a red flag for a design problem. > > > >I'm going to chime in to say that I think it's a pretty typical way to > >represent a compiler IR in C++. There is a base type that a lot of > >code uses, but there is also a real type, and the way to get to that > >real type is to use a cast. We could do it all with virtual > >functions, but those carry a different cost. In effect, using virtual > >functions increases the size of the code field from 16 bits to 64 > >bits. It adds up. > > > >Also this seems to be a pretty direct version of the data structures > >we already have. > Certainly and to some degree these casts in one form or another are > a necessity. My concern is we use them as a crutch (as I've seen in > other projects) and we end up not getting the level of compile time > static type checking that we want. So, thinking about this more the is_a / as_a is more or less just a translation of the "union casting" we're already doing, which means while we may not be getting everything we would like we're atleast getting as good or better than what we have modulo stylistic tastes. > If the bulk are temporary in nature and we as a project agree to > look at the refactoring necessary to minimize the is-a/as-a uses to > a few low level idioms, then I'll hesitatingly go along. If that's > the choice we make, then folks should know I'll probably look at > each is-a/as-a in patches I review and ask for a justification for > their use. I think that's a reasonable thing to do fwiw. Trev > > > jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-05 22:01 ` David Malcolm 2013-11-05 22:17 ` Jeff Law @ 2013-11-05 22:24 ` Andrew MacLeod 1 sibling, 0 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-11-05 22:24 UTC (permalink / raw) To: David Malcolm; +Cc: Jeff Law, gcc-patches On 11/05/2013 04:57 PM, David Malcolm wrote: > > Thanks for looking through this. > > Both you and Andrew objected to my use of the is-a.h stuff. Is this due > to the use of C++ templates in that code? If I were to rewrite things > in a more C idiom, would that be acceptable? Thats too strong a statement. I don't like as_a<>, but it has a use. The follow on stuff you were showing was full of as_a<>'s which was what I was objecting to. I think the as_a<>'s in this patch set is mostly necessary in order to carry out the conversion and leave it there.. The only way to get rid of them is to continue through with the rest of what I talked about... which isn't happening soon. But when we do, it should start to reduce the numbert of as_a<>'s, not increase them. I don't really object to them in this patchset.. we're replacing GIMPLE_CHECK() with an as_a<> call, so to me thats pretty much a wash in most ways. And its a means to an end. > For instance, rather than, say: > > p = as_a <gimple_statement_asm> ( > gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK, > ninputs + noutputs + nclobbers + nlabels)); > > we could have an inlined as_a equivalent in C syntax: > > p = gimple_as_a_gimple_asm ( > gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK, > ninputs + noutputs + nclobbers + nlabels)); > > where there could be, say, a pair of functions like this (to handle > const vs non-const): > > inline gimple_asm > gimple_as_a_gimple_asm (gimple gs) > { > GIMPLE_CHECK (gs->code == GIMPLE_ASM); > return (gimple_asm)gs; > } > > inline const_gimple_asm > gimple_as_a_gimple_asm (const_gimple gs) > { > GIMPLE_CHECK (gs->code == GIMPLE_ASM); > return (const_gimple_asm)gs; > } I really don't think we need to bend over and jump through hoops in order to implement as_a<> in a different way. That's just more hackery, and we're trying to get away from that. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-05 21:33 ` Jeff Law 2013-11-05 22:01 ` David Malcolm @ 2013-11-05 22:12 ` Andrew MacLeod 2013-11-06 9:37 ` Richard Biener 2 siblings, 0 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-11-05 22:12 UTC (permalink / raw) To: Jeff Law; +Cc: David Malcolm, gcc-patches On 11/05/2013 04:18 PM, Jeff Law wrote: > >> >> * Patch 4 of 6: This patch implement further specializations of >> is_a_helper <T>::test, for gimple_has_ops and gimple_has_mem_ops. > Here's where I start to get more concerned. > >> >> * Patch 5 of 6: This patch does the rest of porting from union access >> to subclass access (all the fiddly places that the script in >> patch 3 >> couldn't handle). >> >> * Patch 6 of 6: This patch updates the gdb python pretty-printing >> hook. > Conceptually #5 and #6 shouldn't be terribly controversial. > > THe question is can we move forward without patch #4, even if that > means we aren't getting the static typechecking we want? > I doubt it. Patch 3 is full of as_a<> in order to convert the accessor functions to work with just a base gimple parameter. At this early stage of conversion it is pretty hard to avoid as_a<> at this lowest level in order to support the same interface functions we've been using. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-05 21:33 ` Jeff Law 2013-11-05 22:01 ` David Malcolm 2013-11-05 22:12 ` Andrew MacLeod @ 2013-11-06 9:37 ` Richard Biener 2013-11-06 11:20 ` Bernd Schmidt 2013-11-06 21:26 ` Jeff Law 2 siblings, 2 replies; 116+ messages in thread From: Richard Biener @ 2013-11-06 9:37 UTC (permalink / raw) To: Jeff Law; +Cc: David Malcolm, GCC Patches, Andrew MacLeod On Tue, Nov 5, 2013 at 10:18 PM, Jeff Law <law@redhat.com> wrote: > On 10/31/13 10:26, David Malcolm wrote: >> >> The gimple statement types are currently implemented using a hand-coded >> C inheritance scheme, with a "union gimple_statement_d" holding the >> various possible structs for a statement. >> >> The following series of patches convert it to a C++ hierarchy, using the >> existing structs, eliminating the union. The "gimple" typedef changes >> from being a >> (union gimple_statement_d *) >> to being a: >> (struct gimple_statement_base *) >> >> There are no virtual functions in the new code: the sizes of the various >> structs are unchanged. >> >> It makes use of "is-a.h", using the as_a <T> template function to >> perform downcasts, which are checked (via gcc_checking_assert) in an >> ENABLE_CHECKING build, and are simple casts in an unchecked build, >> albeit it in an inlined function rather than a macro. >> >> For example, one can write: >> >> gimple_statement_phi *phi = >> as_a <gimple_statement_phi> (gsi_stmt (gsi)); >> >> and then directly access the fields of the phi, as a phi. The existing >> accessor functions in gimple.h become somewhat redundant in this >> scheme, but are preserved. >> >> The earlier versions of the patches made all of the types GTY((user)) >> and provided hand-written implementations of the gc and pch marker >> routines. In this new version we rely on the support for simple >> inheritance that I recently added to gengtype, by adding a "desc" >> to the GTY marking for the base class, and a "tag" to the marking >> for all of the concrete subclasses. (I say "class", but all the types >> remain structs since their fields are all publicly accessible). >> >> As noted in the earlier patch, I believe this is a superior scheme to >> the C implementation: >> >> * We can get closer to compile-time type-safety, checking the gimple >> code once and downcasting with an as_a, then directly accessing >> fields, rather than going through accessor functions that check >> each time. In some places we may want to replace a "gimple" with >> a subclass e.g. phis are always of the phi subclass, to get full >> compile-time type-safety. >> >> * This scheme is likely to be easier for newbies to understand. >> >> * Currently in gdb, dereferencing a gimple leads to screenfuls of text, >> showing all the various union values. With this, you get just the >> base >> class, and can cast it to the appropriate subclass. >> >> * With this, we're working directly with the language constructs, >> rather than rolling our own, and thus other tools can better >> understand the code. (e.g. doxygen). >> >> Again, as noted in the earlier patch series, the names of the structs >> are rather verbose. I would prefer to also rename them all to eliminate >> the "_statement" component: >> "gimple_statement_base" -> "gimple_base" >> "gimple_statement_phi" -> "gimple_phi" >> "gimple_statement_omp" -> "gimple_omp" >> etc, but I didn't do this to mimimize the patch size. But if the core >> maintainers are up for that, I can redo the patch series with that >> change also, or do that as a followup. >> >> The patch is in 6 parts; all of them are needed together. > > And that's part of the problem. There's understandable resistance to (for > example) the as_a casting. > > There's a bit of natural tension between the desire to keep patches small > and self-contained and the size/scope of the changes necessary to do any > serious reorganization work. This set swings too far in the latter > direction :-) > > Is there any way to go forward without the is_a/as_a stuff? ie, is there're > a simpler step towards where we're trying to go that allows most of this to > go forward now rather than waiting? We decided to move to C++. As part of a later discussion we decided to go with a single general dynamic-casting style, mimicing the "real" C++ variant which is dynamic_cast < ... >. Which resulted in is-a.h. So yes, we've decided to go C++ so we have to live with certain uglinesses of that decisions (and maybe over time those uglinesses will fade away and we get used to it and like it). Thus, there isn't another option besides using the is-a.h machinery and enabling and using RTTI. Sticking to C for gimple doesn't seem to be consistent with the decision to move to C++. Oh, I'm not saying I'm a big fan of as_a / is_a or C++ in general as it plays out right now. But well, we've had the discussion and had a decision. Execute. Richard. > >> >> * Patch 1 of 6: This patch adds inheritance to the various gimple >> types, eliminating the initial baseclass fields, and eliminating the >> union gimple_statement_d. All the types remain structs. They >> become marked with GTY(()), gaining GSS_ tag values. >> >> * Patch 2 of 6: This patch ports various accessor functions within >> gimple.h to the new scheme. >> >> * Patch 3 of 6: This patch is autogenerated by "refactor_gimple.py" >> from https://github.com/davidmalcolm/gcc-refactoring-scripts >> There is a test suite "test_refactor_gimple.py" which may give a >> clearer idea of the changes that the script makes (and add >> confidence that it's doing the right thing). >> The patch converts code of the form: >> { >> GIMPLE_CHECK (gs, SOME_CODE); >> gimple_subclass_get/set_some_field (gs, value); >> } >> to code of this form: >> { >> some_subclass *stmt = as_a <some_subclass> (gs); >> stmt->some_field = value; >> } >> It also autogenerates specializations of >> is_a_helper <T>::test >> equivalent to a GIMPLE_CHECK() for use by is_a and as_a. > > Conceptually I'm fine with #1-#3. > > >> >> * Patch 4 of 6: This patch implement further specializations of >> is_a_helper <T>::test, for gimple_has_ops and gimple_has_mem_ops. > > Here's where I start to get more concerned. > > >> >> * Patch 5 of 6: This patch does the rest of porting from union access >> to subclass access (all the fiddly places that the script in patch 3 >> couldn't handle). >> >> * Patch 6 of 6: This patch updates the gdb python pretty-printing >> hook. > > Conceptually #5 and #6 shouldn't be terribly controversial. > > THe question is can we move forward without patch #4, even if that means we > aren't getting the static typechecking we want? > > Jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 9:37 ` Richard Biener @ 2013-11-06 11:20 ` Bernd Schmidt 2013-11-06 11:43 ` Richard Biener ` (2 more replies) 2013-11-06 21:26 ` Jeff Law 1 sibling, 3 replies; 116+ messages in thread From: Bernd Schmidt @ 2013-11-06 11:20 UTC (permalink / raw) To: Richard Biener; +Cc: Jeff Law, David Malcolm, GCC Patches, Andrew MacLeod On 11/06/2013 10:31 AM, Richard Biener wrote: > We decided to move to C++. As part of a later discussion we decided > to go with a single general dynamic-casting style, mimicing the "real" > C++ variant which is dynamic_cast < ... >. Which resulted in > is-a.h. > > So yes, we've decided to go C++ so we have to live with certain > uglinesses of that decisions (and maybe over time those uglinesses > will fade away and we get used to it and like it). > > Thus, there isn't another option besides using the is-a.h machinery > and enabling and using RTTI. Sticking to C for gimple doesn't seem > to be consistent with the decision to move to C++. > > Oh, I'm not saying I'm a big fan of as_a / is_a or C++ in general > as it plays out right now. But well, we've had the discussion and > had a decision. Maybe we need to revisit it? As one of those who were not in favour of the C++ move, can I ask you guys to step back for a moment and think about - what do all of these changes buy us, exactly? Imagine the state at the end, where everything is converted and supposedly the temporary ugliness is gone, what have we gained over the code as it is now? I still think all this effort is misdirected and distracts us from making changes that improve gcc for its users. Bernd ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 11:20 ` Bernd Schmidt @ 2013-11-06 11:43 ` Richard Biener 2013-11-06 11:53 ` Jakub Jelinek ` (3 more replies) 2013-11-06 11:56 ` Eric Botcazou 2013-11-06 20:51 ` Jeff Law 2 siblings, 4 replies; 116+ messages in thread From: Richard Biener @ 2013-11-06 11:43 UTC (permalink / raw) To: Bernd Schmidt; +Cc: Jeff Law, David Malcolm, GCC Patches, Andrew MacLeod On Wed, Nov 6, 2013 at 12:02 PM, Bernd Schmidt <bernds@codesourcery.com> wrote: > On 11/06/2013 10:31 AM, Richard Biener wrote: >> We decided to move to C++. As part of a later discussion we decided >> to go with a single general dynamic-casting style, mimicing the "real" >> C++ variant which is dynamic_cast < ... >. Which resulted in >> is-a.h. >> >> So yes, we've decided to go C++ so we have to live with certain >> uglinesses of that decisions (and maybe over time those uglinesses >> will fade away and we get used to it and like it). >> >> Thus, there isn't another option besides using the is-a.h machinery >> and enabling and using RTTI. Sticking to C for gimple doesn't seem >> to be consistent with the decision to move to C++. >> >> Oh, I'm not saying I'm a big fan of as_a / is_a or C++ in general >> as it plays out right now. But well, we've had the discussion and >> had a decision. > > Maybe we need to revisit it? As one of those who were not in favour of > the C++ move, can I ask you guys to step back for a moment and think > about - what do all of these changes buy us, exactly? Imagine the state > at the end, where everything is converted and supposedly the temporary > ugliness is gone, what have we gained over the code as it is now? as_a gains us less runtime checking and more static type checking which is good. > I still think all this effort is misdirected and distracts us from > making changes that improve gcc for its users. That I agree to. Instead of fixing the less than optimal separation / boundary between frontends and the middle-end, or fixing several other long-standing issues with GCC we spend a lot of time refactoring things to be C++. But that was kind of part of the decision (though I remember that we mainly wanted to convert containters and isolated stuff, not gimple or trees (I bet that'll be next)). Of course I don't see contributors of "changes that improve gcc for its users" now wasting their time with converting code to C++. That conversion may slow down those people, but only so much. It'll get more interesting with branch maintainance ... Richard. > > Bernd > ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 11:43 ` Richard Biener @ 2013-11-06 11:53 ` Jakub Jelinek 2013-11-06 13:14 ` Richard Biener ` (2 more replies) 2013-11-06 12:42 ` Bernd Schmidt ` (2 subsequent siblings) 3 siblings, 3 replies; 116+ messages in thread From: Jakub Jelinek @ 2013-11-06 11:53 UTC (permalink / raw) To: Richard Biener Cc: Bernd Schmidt, Jeff Law, David Malcolm, GCC Patches, Andrew MacLeod On Wed, Nov 06, 2013 at 12:31:00PM +0100, Richard Biener wrote: > > Maybe we need to revisit it? As one of those who were not in favour of > > the C++ move, can I ask you guys to step back for a moment and think > > about - what do all of these changes buy us, exactly? Imagine the state > > at the end, where everything is converted and supposedly the temporary > > ugliness is gone, what have we gained over the code as it is now? > > as_a gains us less runtime checking and more static type checking > which is good. But that really affects --enable-checking=yes builds (and only cases where things aren't inlined). If the price for that is uglier and less readable code, then the price is just too high. > > I still think all this effort is misdirected and distracts us from > > making changes that improve gcc for its users. > > That I agree to. Instead of fixing the less than optimal separation / boundary > between frontends and the middle-end, or fixing several other long-standing > issues with GCC we spend a lot of time refactoring things to be C++. > But that was kind of part of the decision (though I remember that we > mainly wanted to convert containters and isolated stuff, not gimple > or trees (I bet that'll be next)). > > Of course I don't see contributors of "changes that improve gcc for its users" > now wasting their time with converting code to C++. That conversion > may slow down those people, but only so much. It'll get more interesting > with branch maintainance ... If the changes are done at least with some for users useful goal (like perhaps making gcc usable as a library for JITting etc.), then I can see the benefit, but as_s<> uglification doesn't seem to be beneficial to users at all, and IMNSHO much better would be to instead spend time on what is beneficial to users (restrict, vectorizer cost model, vectorizer improvements, better diagnostics (say range locations), ...). Jakub ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 11:53 ` Jakub Jelinek @ 2013-11-06 13:14 ` Richard Biener 2013-11-06 13:23 ` Jakub Jelinek 2013-11-06 13:31 ` Joseph S. Myers 2013-11-06 21:09 ` Jeff Law 2 siblings, 1 reply; 116+ messages in thread From: Richard Biener @ 2013-11-06 13:14 UTC (permalink / raw) To: Jakub Jelinek Cc: Bernd Schmidt, Jeff Law, David Malcolm, GCC Patches, Andrew MacLeod On Wed, Nov 6, 2013 at 12:42 PM, Jakub Jelinek <jakub@redhat.com> wrote: > On Wed, Nov 06, 2013 at 12:31:00PM +0100, Richard Biener wrote: >> > Maybe we need to revisit it? As one of those who were not in favour of >> > the C++ move, can I ask you guys to step back for a moment and think >> > about - what do all of these changes buy us, exactly? Imagine the state >> > at the end, where everything is converted and supposedly the temporary >> > ugliness is gone, what have we gained over the code as it is now? >> >> as_a gains us less runtime checking and more static type checking >> which is good. > > But that really affects --enable-checking=yes builds (and only cases where > things aren't inlined). If the price for that is uglier and less readable > code, then the price is just too high. > >> > I still think all this effort is misdirected and distracts us from >> > making changes that improve gcc for its users. >> >> That I agree to. Instead of fixing the less than optimal separation / boundary >> between frontends and the middle-end, or fixing several other long-standing >> issues with GCC we spend a lot of time refactoring things to be C++. >> But that was kind of part of the decision (though I remember that we >> mainly wanted to convert containters and isolated stuff, not gimple >> or trees (I bet that'll be next)). >> >> Of course I don't see contributors of "changes that improve gcc for its users" >> now wasting their time with converting code to C++. That conversion >> may slow down those people, but only so much. It'll get more interesting >> with branch maintainance ... > > If the changes are done at least with some for users useful goal (like > perhaps making gcc usable as a library for JITting etc.), then I can see > the benefit, but as_s<> uglification doesn't seem to be beneficial to > users at all, and IMNSHO much better would be to instead > spend time on what is beneficial to users (restrict, vectorizer > cost model, vectorizer improvements, better diagnostics (say range > locations), ...). Well, what else, besides as_a<> or keeping the current global accessor functions would you propose? Richard. > Jakub ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 13:14 ` Richard Biener @ 2013-11-06 13:23 ` Jakub Jelinek 2013-11-06 16:42 ` David Malcolm 0 siblings, 1 reply; 116+ messages in thread From: Jakub Jelinek @ 2013-11-06 13:23 UTC (permalink / raw) To: Richard Biener Cc: Bernd Schmidt, Jeff Law, David Malcolm, GCC Patches, Andrew MacLeod On Wed, Nov 06, 2013 at 02:00:56PM +0100, Richard Biener wrote: > Well, what else, besides as_a<> or keeping the current > global accessor functions would you propose? I'd prefer to keep the current accessors. Whether there is a class hierarchy or we keep unions doesn't affect the code too much (unless it makes debugging experience harder, as numerous past C++ification changes have done :( ). Jakub ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 13:23 ` Jakub Jelinek @ 2013-11-06 16:42 ` David Malcolm 2013-11-06 16:55 ` Jakub Jelinek 0 siblings, 1 reply; 116+ messages in thread From: David Malcolm @ 2013-11-06 16:42 UTC (permalink / raw) To: Jakub Jelinek Cc: Richard Biener, Bernd Schmidt, Jeff Law, GCC Patches, Andrew MacLeod On Wed, 2013-11-06 at 14:11 +0100, Jakub Jelinek wrote: > On Wed, Nov 06, 2013 at 02:00:56PM +0100, Richard Biener wrote: > > Well, what else, besides as_a<> or keeping the current > > global accessor functions would you propose? > > I'd prefer to keep the current accessors. Whether there is a class > hierarchy or we keep unions doesn't affect the code too much (unless > it makes debugging experience harder, as numerous past C++ification changes > have done :( ). What specific things have become more difficult to debug due to the changes you refer to? I can have a look at improving them by extending gdbhooks.py, if that is desirable. Thanks Dave ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 16:42 ` David Malcolm @ 2013-11-06 16:55 ` Jakub Jelinek 2013-11-06 18:34 ` Tom Tromey 0 siblings, 1 reply; 116+ messages in thread From: Jakub Jelinek @ 2013-11-06 16:55 UTC (permalink / raw) To: David Malcolm Cc: Richard Biener, Bernd Schmidt, Jeff Law, GCC Patches, Andrew MacLeod On Wed, Nov 06, 2013 at 11:25:31AM -0500, David Malcolm wrote: > On Wed, 2013-11-06 at 14:11 +0100, Jakub Jelinek wrote: > > On Wed, Nov 06, 2013 at 02:00:56PM +0100, Richard Biener wrote: > > > Well, what else, besides as_a<> or keeping the current > > > global accessor functions would you propose? > > > > I'd prefer to keep the current accessors. Whether there is a class > > hierarchy or we keep unions doesn't affect the code too much (unless > > it makes debugging experience harder, as numerous past C++ification changes > > have done :( ). > > What specific things have become more difficult to debug due to the > changes you refer to? > I can have a look at improving them by extending gdbhooks.py, if that is > desirable. I'm refering to various things that have been mentioned already multiple times, mostly from the switch to C++, like: 1) p debug_tree (0x7ffff18b3690) not working anymore, typically one would use this when just cut'n'pasting addresses seen in backtrace, other debug_tree etc., one now has to add explicitly a cast p debug_tree ((tree)0x7ffff18b3690). Perhaps this can be cured just by adding extra overloads for a few most popular debug_* routines that weren't initially overloaded, add them an overload with uintptr_t type or similar that will just cast it to the right type and call the original routine 2) tab completion often not working well for hundreds of functions, say type p gimple_can_m<tab> When gcc was written in C, this would complete it just fine into p gimple_can_merge_blocks_p but GDB is confused by the forward declarations and offers you: p gimple_can_merge_blocks_p(basic_block and doesn't autocomplete further from there, so, for functions that aren't really overloaded (fortunately so far most of them) one has to manually remove all the cruft until and including the (, or has to complete from memory or similar. The issue is that gdb sees: gimple_can_merge_blocks_p(basic_block, basic_block) gimple_can_merge_blocks_p(basic_block_def*, basic_block_def*) gimple_can_merge_blocks_p(basic_block_def*, basic_block_def*)::__FUNCTION__ and considers the two different thing, but of course: typedef struct basic_block_def *basic_block; and thus you really don't care which one is chosen from these, but preferrably just one, not both. 3) step got significantly worse over time, we have skip_file tree.h, but with all the recent header reorganizations gdbinit.in hasn't been updated on which other headers would greatly benefit from being skipped by default. Certainly gimple.h IMHO, and various new headers that just contain small inline accessors 4) the gdbhooks.py printing is nice, but (talking just from memory), it is tied to just one spelling of various types, so say if something has basic_block type, it is printed nicely, but if it has basic_block_def * type, it isn't 5) the new "improved" C++ vec.h is harder to use in the debugger This list is still very much incomplete. Jakub ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 16:55 ` Jakub Jelinek @ 2013-11-06 18:34 ` Tom Tromey 2013-11-06 19:15 ` Jeff Law 0 siblings, 1 reply; 116+ messages in thread From: Tom Tromey @ 2013-11-06 18:34 UTC (permalink / raw) To: Jakub Jelinek Cc: David Malcolm, Richard Biener, Bernd Schmidt, Jeff Law, GCC Patches, Andrew MacLeod >>>>> "Jakub" == Jakub Jelinek <jakub@redhat.com> writes: Jakub> 1) p debug_tree (0x7ffff18b3690) Jakub> not working anymore, typically one would use this when just Jakub> cut'n'pasting addresses seen in backtrace, other debug_tree Jakub> etc., one now has to add explicitly a cast p debug_tree Jakub> ((tree)0x7ffff18b3690). Perhaps this can be cured just by Jakub> adding extra overloads for a few most popular debug_* routines Jakub> that weren't initially overloaded, add them an overload with Jakub> uintptr_t type or similar that will just cast it to the right Jakub> type and call the original routine Last time this came up, we added the feature to gdb. You have to enable it, though. Use "set check type off". Tom ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 18:34 ` Tom Tromey @ 2013-11-06 19:15 ` Jeff Law 2013-11-06 20:05 ` Tom Tromey 0 siblings, 1 reply; 116+ messages in thread From: Jeff Law @ 2013-11-06 19:15 UTC (permalink / raw) To: Tom Tromey, Jakub Jelinek Cc: David Malcolm, Richard Biener, Bernd Schmidt, GCC Patches, Andrew MacLeod On 11/06/13 11:04, Tom Tromey wrote: >>>>>> "Jakub" == Jakub Jelinek <jakub@redhat.com> writes: > > Jakub> 1) p debug_tree (0x7ffff18b3690) > Jakub> not working anymore, typically one would use this when just > Jakub> cut'n'pasting addresses seen in backtrace, other debug_tree > Jakub> etc., one now has to add explicitly a cast p debug_tree > Jakub> ((tree)0x7ffff18b3690). Perhaps this can be cured just by > Jakub> adding extra overloads for a few most popular debug_* routines > Jakub> that weren't initially overloaded, add them an overload with > Jakub> uintptr_t type or similar that will just cast it to the right > Jakub> type and call the original routine > > Last time this came up, we added the feature to gdb. You have to enable > it, though. Use "set check type off". I'd been mildly annoyed by this behaviour, but not so much as to look for a solution and I can certainly see why gdb is doing what it's doing. I certainly don't consider this something that should stand in the way of moving forward. ISTM that one liner belongs in GCC's .gdbinit. Until then, I'm adding it to my own :-) jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 19:15 ` Jeff Law @ 2013-11-06 20:05 ` Tom Tromey 2013-11-06 20:45 ` Jeff Law 0 siblings, 1 reply; 116+ messages in thread From: Tom Tromey @ 2013-11-06 20:05 UTC (permalink / raw) To: Jeff Law Cc: Jakub Jelinek, David Malcolm, Richard Biener, Bernd Schmidt, GCC Patches, Andrew MacLeod >>>>> "Jeff" == Jeff Law <law@redhat.com> writes: Jeff> ISTM that one liner belongs in GCC's .gdbinit. Until then, I'm adding Jeff> it to my own :-) Yeah, I think that would be reasonable. It seems like it isn't appropriate in many cases, so we left it off by default. Tom ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 20:05 ` Tom Tromey @ 2013-11-06 20:45 ` Jeff Law 0 siblings, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-06 20:45 UTC (permalink / raw) To: Tom Tromey Cc: Jakub Jelinek, David Malcolm, Richard Biener, Bernd Schmidt, GCC Patches, Andrew MacLeod [-- Attachment #1: Type: text/plain, Size: 395 bytes --] On 11/06/13 13:01, Tom Tromey wrote: >>>>>> "Jeff" == Jeff Law <law@redhat.com> writes: > > Jeff> ISTM that one liner belongs in GCC's .gdbinit. Until then, I'm adding > Jeff> it to my own :-) > > Yeah, I think that would be reasonable. > It seems like it isn't appropriate in many cases, so we left it off by > default. Here's the patch I installed for GCC. Thanks for the suggestion! Jeff [-- Attachment #2: patch --] [-- Type: text/plain, Size: 876 bytes --] diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dfaf4e3..43ebbda 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2013-11-06 Jeff Law <law@redhat.com> + Tom Tromey <tromey@redhat.com> + + * gdbinit.in: Disable strict type checking. + 2013-11-06 Vladimir Makarov <vmakarov@redhat.com> * tree-pass.h (make_pass_live_range_shrinkage): New external. diff --git a/gcc/gdbinit.in b/gcc/gdbinit.in index 503ef24..c60cab1 100644 --- a/gcc/gdbinit.in +++ b/gcc/gdbinit.in @@ -205,6 +205,11 @@ set complaints 0 b exit b abort +# Disable strict type checking. This allows developers to (for example) +# make inferior calls without casting absolute address to a suitable +# pointer type. +set check type off + # Skip all inline functions in tree.h. # These are used in accessor macros. # Note that this is added at the end because older gdb versions ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 11:53 ` Jakub Jelinek 2013-11-06 13:14 ` Richard Biener @ 2013-11-06 13:31 ` Joseph S. Myers 2013-11-06 21:25 ` Jeff Law 2013-11-06 21:09 ` Jeff Law 2 siblings, 1 reply; 116+ messages in thread From: Joseph S. Myers @ 2013-11-06 13:31 UTC (permalink / raw) To: Jakub Jelinek Cc: Richard Biener, Bernd Schmidt, Jeff Law, David Malcolm, GCC Patches, Andrew MacLeod On Wed, 6 Nov 2013, Jakub Jelinek wrote: > On Wed, Nov 06, 2013 at 12:31:00PM +0100, Richard Biener wrote: > > > Maybe we need to revisit it? As one of those who were not in favour of > > > the C++ move, can I ask you guys to step back for a moment and think > > > about - what do all of these changes buy us, exactly? Imagine the state > > > at the end, where everything is converted and supposedly the temporary > > > ugliness is gone, what have we gained over the code as it is now? > > > > as_a gains us less runtime checking and more static type checking > > which is good. > > But that really affects --enable-checking=yes builds (and only cases where > things aren't inlined). If the price for that is uglier and less readable > code, then the price is just too high. I see static type checking as being about preventing certain sorts of bugs getting in the compiler at all, rather than about saving time on runtime checks for --enable-checking=yes. I don't have advice on the gimple case. But certainly trees and RTL could both do with more static typing. There, I'm thinking of different types of objects (types, expressions, ...) logically being completely separate static types, not inheriting from a common "tree" base class at all. But if inheritance and as_a can be used as intermediate steps to allow an incremental transition to completely separate static types, where otherwise the whole source tree would need converting at once, that seems reasonable to me. (I have no comments about what things should look like in cases where completely separate static types don't make sense but there is still some sort of inheritance structure.) -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 13:31 ` Joseph S. Myers @ 2013-11-06 21:25 ` Jeff Law 0 siblings, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-06 21:25 UTC (permalink / raw) To: Joseph S. Myers, Jakub Jelinek Cc: Richard Biener, Bernd Schmidt, David Malcolm, GCC Patches, Andrew MacLeod On 11/06/13 06:23, Joseph S. Myers wrote: > On Wed, 6 Nov 2013, Jakub Jelinek wrote: > >> On Wed, Nov 06, 2013 at 12:31:00PM +0100, Richard Biener wrote: >>>> Maybe we need to revisit it? As one of those who were not in favour of >>>> the C++ move, can I ask you guys to step back for a moment and think >>>> about - what do all of these changes buy us, exactly? Imagine the state >>>> at the end, where everything is converted and supposedly the temporary >>>> ugliness is gone, what have we gained over the code as it is now? >>> >>> as_a gains us less runtime checking and more static type checking >>> which is good. >> >> But that really affects --enable-checking=yes builds (and only cases where >> things aren't inlined). If the price for that is uglier and less readable >> code, then the price is just too high. > > I see static type checking as being about preventing certain sorts of bugs > getting in the compiler at all, rather than about saving time on runtime > checks for --enable-checking=yes. Amen! When I've described RTL & trees to other folks in the business that work(ed) on other compilers, most gasped in horror. Doubly so when I did this prior to the introduction of the tree/rtl checking systems. > > I don't have advice on the gimple case. But certainly trees and RTL could > both do with more static typing. There, I'm thinking of different types > of objects (types, expressions, ...) logically being completely separate > static types, not inheriting from a common "tree" base class at all. But > if inheritance and as_a can be used as intermediate steps to allow an > incremental transition to completely separate static types, where > otherwise the whole source tree would need converting at once, that seems > reasonable to me. (I have no comments about what things should look like > in cases where completely separate static types don't make sense but there > is still some sort of inheritance structure.) I hadn't really thought of it that way -- specifically that when we're done we don't necessarily need to have decls, types, expressions inheriting from a common tree base class. I must say, I like it as a guiding principle. Jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 11:53 ` Jakub Jelinek 2013-11-06 13:14 ` Richard Biener 2013-11-06 13:31 ` Joseph S. Myers @ 2013-11-06 21:09 ` Jeff Law 2 siblings, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-06 21:09 UTC (permalink / raw) To: Jakub Jelinek, Richard Biener Cc: Bernd Schmidt, David Malcolm, GCC Patches, Andrew MacLeod On 11/06/13 04:42, Jakub Jelinek wrote: > On Wed, Nov 06, 2013 at 12:31:00PM +0100, Richard Biener wrote: >>> Maybe we need to revisit it? As one of those who were not in favour of >>> the C++ move, can I ask you guys to step back for a moment and think >>> about - what do all of these changes buy us, exactly? Imagine the state >>> at the end, where everything is converted and supposedly the temporary >>> ugliness is gone, what have we gained over the code as it is now? >> >> as_a gains us less runtime checking and more static type checking >> which is good. > > But that really affects --enable-checking=yes builds (and only cases where > things aren't inlined). If the price for that is uglier and less readable > code, then the price is just too high. I totally disagree. Getting to a better static typed system is good. All the tree/rtl checking bits are really working around the sad fact that we don't have a statically typed system. The checking stuff has been a big help to ensure we're not doing something stupid. But those problems really need to be caught at compile time, not a runtime. jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 11:43 ` Richard Biener 2013-11-06 11:53 ` Jakub Jelinek @ 2013-11-06 12:42 ` Bernd Schmidt 2013-11-06 21:04 ` Jeff Law 2013-11-06 21:06 ` Andrew MacLeod 3 siblings, 0 replies; 116+ messages in thread From: Bernd Schmidt @ 2013-11-06 12:42 UTC (permalink / raw) To: Richard Biener; +Cc: Jeff Law, David Malcolm, GCC Patches, Andrew MacLeod On 11/06/2013 12:31 PM, Richard Biener wrote: > That I agree to. Instead of fixing the less than optimal separation / boundary > between frontends and the middle-end, or fixing several other long-standing > issues with GCC we spend a lot of time refactoring things to be C++. > But that was kind of part of the decision (though I remember that we > mainly wanted to convert containters and isolated stuff, not gimple > or trees (I bet that'll be next)). What I seem to remember is being told that we'd use C++ mostly for new code and not engage in a wholesale rewrite of the compiler. Instead things happened exactly as predicted, we're getting immense amounts of churn for little real gain, and in some cases the C++ changes are not even improvements and look like really strange examples of C++ code. I'll offer as evidence the pass manager with its bizarre has_gate and has_execute variables, member functions for gate and execute wrapping non-member functions, and a separate pass_data outside of its class (not even as a static member). Now that the question of what would happen after a C++ conversion is no longer theoretical but has been answered, can we maybe just stop and think for a while whether this is really the way we should be going? Bernd ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 11:43 ` Richard Biener 2013-11-06 11:53 ` Jakub Jelinek 2013-11-06 12:42 ` Bernd Schmidt @ 2013-11-06 21:04 ` Jeff Law 2013-11-06 21:06 ` Andrew MacLeod 3 siblings, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-06 21:04 UTC (permalink / raw) To: Richard Biener, Bernd Schmidt; +Cc: David Malcolm, GCC Patches, Andrew MacLeod On 11/06/13 04:31, Richard Biener wrote: > On Wed, Nov 6, 2013 at 12:02 PM, Bernd Schmidt <bernds@codesourcery.com> wrote: >> On 11/06/2013 10:31 AM, Richard Biener wrote: >>> We decided to move to C++. As part of a later discussion we decided >>> to go with a single general dynamic-casting style, mimicing the "real" >>> C++ variant which is dynamic_cast < ... >. Which resulted in >>> is-a.h. >>> >>> So yes, we've decided to go C++ so we have to live with certain >>> uglinesses of that decisions (and maybe over time those uglinesses >>> will fade away and we get used to it and like it). >>> >>> Thus, there isn't another option besides using the is-a.h machinery >>> and enabling and using RTTI. Sticking to C for gimple doesn't seem >>> to be consistent with the decision to move to C++. >>> >>> Oh, I'm not saying I'm a big fan of as_a / is_a or C++ in general >>> as it plays out right now. But well, we've had the discussion and >>> had a decision. >> >> Maybe we need to revisit it? As one of those who were not in favour of >> the C++ move, can I ask you guys to step back for a moment and think >> about - what do all of these changes buy us, exactly? Imagine the state >> at the end, where everything is converted and supposedly the temporary >> ugliness is gone, what have we gained over the code as it is now? > > as_a gains us less runtime checking and more static type checking > which is good. Absolutely. > That I agree to. Instead of fixing the less than optimal separation / boundary > between frontends and the middle-end, or fixing several other long-standing > issues with GCC we spend a lot of time refactoring things to be C++. > But that was kind of part of the decision (though I remember that we > mainly wanted to convert containters and isolated stuff, not gimple > or trees (I bet that'll be next)). That's a reasonable bet given what's already been said on this list WRT gimple. > > Of course I don't see contributors of "changes that improve gcc for its users" > now wasting their time with converting code to C++. That conversion > may slow down those people, but only so much. It'll get more interesting > with branch maintainance ... True. But that's probabl more of an artifact of the engineers involved. David (who's by far the most gung-ho on the C++ front) is fairly new to GCC and isn't really in a position right now to drive much user visible stuff. So he's doing what he can right now. jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 11:43 ` Richard Biener ` (2 preceding siblings ...) 2013-11-06 21:04 ` Jeff Law @ 2013-11-06 21:06 ` Andrew MacLeod 2013-11-06 21:52 ` Jeff Law ` (2 more replies) 3 siblings, 3 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-11-06 21:06 UTC (permalink / raw) To: Richard Biener; +Cc: Bernd Schmidt, Jeff Law, David Malcolm, GCC Patches On 11/06/2013 06:31 AM, Richard Biener wrote: > On Wed, Nov 6, 2013 at 12:02 PM, Bernd Schmidt <bernds@codesourcery.com> wrote: >> >> Maybe we need to revisit it? As one of those who were not in favour of >> the C++ move, can I ask you guys to step back for a moment and think >> about - what do all of these changes buy us, exactly? Imagine the state >> at the end, where everything is converted and supposedly the temporary >> ugliness is gone, what have we gained over the code as it is now? > as_a gains us less runtime checking and more static type checking > which is good. > >> I still think all this effort is misdirected and distracts us from >> making changes that improve gcc for its users. > That I agree to. Instead of fixing the less than optimal separation / boundary > between frontends and the middle-end, or fixing several other long-standing > issues with GCC we spend a lot of time refactoring things to be C++. > But that was kind of part of the decision (though I remember that we > mainly wanted to convert containters and isolated stuff, not gimple > or trees (I bet that'll be next)). > > Of course I don't see contributors of "changes that improve gcc for its users" > now wasting their time with converting code to C++. That conversion > may slow down those people, but only so much. It'll get more interesting > with branch maintainance ... > > What does it buy us? I won't comment on the merit of other changes, but I will reiterate what I'm doing. 1 - I think the code restructuring to enable the changes I proposed is quite worthwhile. Our includes are a mess and prototypes locations are all over the map. I think this is a worthwhile cleanup that I probably wouldn't be doing otherwise. 2 - I really believe gimple needs a type system different from front end trees, that is my primary motivation. I'm tired of jumping through hoops to do anything slightly different, and I got fed up with it. With a separate type system for gimple, we can rid ourselves of all the stuff that isn't related to optimization and codegen... Could we do this with trees? possibly, but if I'm going to go to the effort of converting the front end tree types into a new or reduced-type subset, I might as well put that effort into something that is more appropriate right from the start. 3 - Trees are very polymorphic and as a result, its difficult to tell where types are being used. By replacing those uses with an actual type, we'll get static type checking which is another improvement. There is only one way to move the middle/back end off of types as trees that I can see. Go through the source base and find all the places which use trees as types, and replace them with an actual type. This can't be done all at once, its too big a job... So I propose a plan which allows a new gimple type and current trees to coexist. Once the conversion is complete we can easily implement a type system that has the features and traits we want. 4 - I realized that if I am going through the entire code base to find all the type locations, its very little extra work to also do the same for decls and expressions. Then we'll have static type checking for those as well. 5 - When done we will be significantly closer to having the ability to create a self contained IL that we can strictly define... That alone seems a worthwhile goal to me. The IL then becomes appropriate for streaming at any point in during compilation. This means any front end or tool can easily generate or consume a gimple stream which opens up numerous opportunities... That is pretty hard to enable today. Im going to do the initial bits on a branch for the first couple of months, and during that time convert a number of files over to the new gimple interface. Then we can look at it, measure it, comment on it, tweak it, whatever. You can see exactly what we'll be getting into before we fully commit. I think it will be an improvement over what we have today and much easier to work with. If the consensus is that it bites, then we leave it on the branch, and what have we lost? a few months of my time and we've gained some really useful knowledge. And no, if I can get trees out of gimple, I don't intend to ever touch them again! :-) Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 21:06 ` Andrew MacLeod @ 2013-11-06 21:52 ` Jeff Law 2013-11-07 10:29 ` Richard Biener 2013-11-10 12:35 ` Richard Sandiford 2 siblings, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-06 21:52 UTC (permalink / raw) To: Andrew MacLeod, Richard Biener; +Cc: Bernd Schmidt, David Malcolm, GCC Patches On 11/06/13 13:56, Andrew MacLeod wrote: > > 5 - When done we will be significantly closer to having the ability to > create a self contained IL that we can strictly define... That alone > seems a worthwhile goal to me. The IL then becomes appropriate for > streaming at any point in during compilation. This means any front end > or tool can easily generate or consume a gimple stream which opens up > numerous opportunities... That is pretty hard to enable today. And I think that when we get to this point we're going to find the capability to be quite a boon to our efficiency as developers. jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 21:06 ` Andrew MacLeod 2013-11-06 21:52 ` Jeff Law @ 2013-11-07 10:29 ` Richard Biener 2013-11-07 14:01 ` Joseph S. Myers 2013-11-07 14:53 ` Andrew MacLeod 2013-11-10 12:35 ` Richard Sandiford 2 siblings, 2 replies; 116+ messages in thread From: Richard Biener @ 2013-11-07 10:29 UTC (permalink / raw) To: Andrew MacLeod; +Cc: Bernd Schmidt, Jeff Law, David Malcolm, GCC Patches On Wed, Nov 6, 2013 at 9:56 PM, Andrew MacLeod <amacleod@redhat.com> wrote: > On 11/06/2013 06:31 AM, Richard Biener wrote: >> >> On Wed, Nov 6, 2013 at 12:02 PM, Bernd Schmidt <bernds@codesourcery.com> >> wrote: >>> >>> >>> Maybe we need to revisit it? As one of those who were not in favour of >>> the C++ move, can I ask you guys to step back for a moment and think >>> about - what do all of these changes buy us, exactly? Imagine the state >>> at the end, where everything is converted and supposedly the temporary >>> ugliness is gone, what have we gained over the code as it is now? >> >> as_a gains us less runtime checking and more static type checking >> which is good. >> >>> I still think all this effort is misdirected and distracts us from >>> making changes that improve gcc for its users. >> >> That I agree to. Instead of fixing the less than optimal separation / >> boundary >> between frontends and the middle-end, or fixing several other >> long-standing >> issues with GCC we spend a lot of time refactoring things to be C++. >> But that was kind of part of the decision (though I remember that we >> mainly wanted to convert containters and isolated stuff, not gimple >> or trees (I bet that'll be next)). >> >> Of course I don't see contributors of "changes that improve gcc for its >> users" >> now wasting their time with converting code to C++. That conversion >> may slow down those people, but only so much. It'll get more interesting >> with branch maintainance ... >> >> > What does it buy us? I won't comment on the merit of other changes, but I > will reiterate what I'm doing. > > 1 - I think the code restructuring to enable the changes I proposed is > quite worthwhile. Our includes are a mess and prototypes locations are all > over the map. I think this is a worthwhile cleanup that I probably wouldn't > be doing otherwise. True. > 2 - I really believe gimple needs a type system different from front end > trees, that is my primary motivation. I'm tired of jumping through hoops to > do anything slightly different, and I got fed up with it. With a separate > type system for gimple, we can rid ourselves of all the stuff that isn't > related to optimization and codegen... Could we do this with trees? > possibly, but if I'm going to go to the effort of converting the front end > tree types into a new or reduced-type subset, I might as well put that > effort into something that is more appropriate right from the start. I'm not sure. Especially the idea of wrapping everything in a I'm-not-a-tree-well-but-I-really-still-am scares the hell out of me. And I put that into the very same basket of things you now complain about. > 3 - Trees are very polymorphic and as a result, its difficult to tell where > types are being used. It's a feature. Now the type vs. object thing may be something to change (historically the reason they are entangled is that things like a vector and a list also were trees - which is a feature). > By replacing those uses with an actual type, we'll get > static type checking which is another improvement. There is only one way > to move the middle/back end off of types as trees that I can see. Go > through the source base and find all the places which use trees as types, > and replace them with an actual type. This can't be done all at once, its > too big a job... So I propose a plan which allows a new gimple type and > current trees to coexist. Once the conversion is complete we can easily > implement a type system that has the features and traits we want. Note that on 'gimple' there are no types ... the types are on the objects 'gimple' refers to and those are 'tree's. So you'd need to change the 'tree's to have TREE_TYPE not be a 'tree'. Or simply subclass 'tree' so you can distinguish a tree type from a tree non-type statically (a bit awkward with the current union setup). But maybe I'm confusing what you call 'type'. > 4 - I realized that if I am going through the entire code base to find all > the type locations, its very little extra work to also do the same for decls > and expressions. Then we'll have static type checking for those as well. > > 5 - When done we will be significantly closer to having the ability to > create a self contained IL that we can strictly define... That alone seems > a worthwhile goal to me. The IL then becomes appropriate for streaming at > any point in during compilation. This means any front end or tool can > easily generate or consume a gimple stream which opens up numerous > opportunities... That is pretty hard to enable today. Have fun with dealing with our legacy frontends ;) Or didn't you actually mean "any point" during compilation? ... oh, you talk about GIMPLE. So no plans for Frontend ASTs aka GENERIC for our legacy frontends? > Im going to do the initial bits on a branch for the first couple of months, > and during that time convert a number of files over to the new gimple > interface. Then we can look at it, measure it, comment on it, tweak it, > whatever. You can see exactly what we'll be getting into before we fully > commit. Before we fully commit we want to see the underlying object changes. Because I still doubt this all will work out without seriously restructuring the entanglement of our tree-based frontends and the middle-end (say "fold"). That is, I still think you are starting this at the wrong end. You first need to solve the entanglement issue before you can seriously consider making any real change to the data structures GIMPLE relies on. > I think it will be an improvement over what we have today and much > easier to work with. If the consensus is that it bites, then we leave it on > the branch, and what have we lost? a few months of my time and we've gained > some really useful knowledge. > > And no, if I can get trees out of gimple, I don't intend to ever touch them > again! :-) Well, I'm betting that you'll re-invent sth like 'tree' just don't call it 'tree' ;) You need to transparently refer to constants, SSA names and decls (at least) as GIMPLE statement operands. You probably will make a "gimple statement operand" base class. Well - that's a 'tree' ;) Richard. > Andrew > ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-07 10:29 ` Richard Biener @ 2013-11-07 14:01 ` Joseph S. Myers 2013-11-07 14:42 ` Richard Biener 2013-11-07 14:53 ` Andrew MacLeod 1 sibling, 1 reply; 116+ messages in thread From: Joseph S. Myers @ 2013-11-07 14:01 UTC (permalink / raw) To: Richard Biener Cc: Andrew MacLeod, Bernd Schmidt, Jeff Law, David Malcolm, GCC Patches On Thu, 7 Nov 2013, Richard Biener wrote: > Well, I'm betting that you'll re-invent sth like 'tree' just don't > call it 'tree' ;) > You need to transparently refer to constants, SSA names and decls > (at least) as GIMPLE statement operands. You probably will make > a "gimple statement operand" base class. Well - that's a 'tree' ;) Uses of constants and decls in expressions are why it's not obvious that those get a static type different from expressions (or at least, they probably do need a common base class). But my model of how "tree" should ideally be split up has expressions (maybe including decls) as a completely separate static type from types, and identifiers as yet another static type, none of those inheriting from a common base class "tree". -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-07 14:01 ` Joseph S. Myers @ 2013-11-07 14:42 ` Richard Biener 0 siblings, 0 replies; 116+ messages in thread From: Richard Biener @ 2013-11-07 14:42 UTC (permalink / raw) To: Joseph S. Myers Cc: Andrew MacLeod, Bernd Schmidt, Jeff Law, David Malcolm, GCC Patches On Thu, Nov 7, 2013 at 2:44 PM, Joseph S. Myers <joseph@codesourcery.com> wrote: > On Thu, 7 Nov 2013, Richard Biener wrote: > >> Well, I'm betting that you'll re-invent sth like 'tree' just don't >> call it 'tree' ;) >> You need to transparently refer to constants, SSA names and decls >> (at least) as GIMPLE statement operands. You probably will make >> a "gimple statement operand" base class. Well - that's a 'tree' ;) > > Uses of constants and decls in expressions are why it's not obvious that > those get a static type different from expressions (or at least, they > probably do need a common base class). But my model of how "tree" should > ideally be split up has expressions (maybe including decls) as a > completely separate static type from types, and identifiers as yet another > static type, none of those inheriting from a common base class "tree". Sure. Also you make containers no longer trees (TREE_CHAIN anyone, TREE_VEC, TREE_LIST ...). Should be the first step I think (already started some time ago with using VECs for some pieces). Richard. > -- > Joseph S. Myers > joseph@codesourcery.com ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-07 10:29 ` Richard Biener 2013-11-07 14:01 ` Joseph S. Myers @ 2013-11-07 14:53 ` Andrew MacLeod 1 sibling, 0 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-11-07 14:53 UTC (permalink / raw) To: Richard Biener; +Cc: Bernd Schmidt, Jeff Law, David Malcolm, GCC Patches On 11/07/2013 05:08 AM, Richard Biener wrote: > >> 2 - I really believe gimple needs a type system different from front end >> trees, that is my primary motivation. I'm tired of jumping through hoops to >> do anything slightly different, and I got fed up with it. With a separate >> type system for gimple, we can rid ourselves of all the stuff that isn't >> related to optimization and codegen... Could we do this with trees? >> possibly, but if I'm going to go to the effort of converting the front end >> tree types into a new or reduced-type subset, I might as well put that >> effort into something that is more appropriate right from the start. > I'm not sure. Especially the idea of wrapping everything in a > I'm-not-a-tree-well-but-I-really-still-am scares the hell out of me. > And I put that into the very same basket of things you now complain about. Well, this first phase is a transitional one... If it were possible, I'd change them all at once to not use a tree... but I don't think that is feasible. There is too much to find and change, and the source base is constantly changing. We can't just freeze the base for a year. so until I can get them all changes, they have to act like trees and interact like trees, so we make them trees under the covers. Short term pain and discomfort... If it helps, during the transition you can view it as replacing trees with oddly named tree subclasses which provide static type checking instead of run time GIMPLE_CHECK() calls :-) >> By replacing those uses with an actual type, we'll get >> static type checking which is another improvement. There is only one way >> to move the middle/back end off of types as trees that I can see. Go >> through the source base and find all the places which use trees as types, >> and replace them with an actual type. This can't be done all at once, its >> too big a job... So I propose a plan which allows a new gimple type and >> current trees to coexist. Once the conversion is complete we can easily >> implement a type system that has the features and traits we want. > Note that on 'gimple' there are no types ... the types are on the objects > 'gimple' refers to and those are 'tree's. So you'd need to change the > 'tree's to have TREE_TYPE not be a 'tree'. Or simply subclass > 'tree' so you can distinguish a tree type from a tree non-type statically > (a bit awkward with the current union setup). > > But maybe I'm confusing what you call 'type'. Im talking about changing the type gimple statements refer to, and also what decls and expressions will refer to... making that the gimple_type. Today, thats a TREE_TYPE tree. During the transition period this gimple_type is indeed a tree under the covers.. so that all the existing code can work even if it hasnt been converted yet. Once everything is converted, then gimple_type has the tree removed from its declaration and we replace it with the bits we need/want... and it will no longer function as a tree.. gimplification will create these from the trees the front end created. >> 4 - I realized that if I am going through the entire code base to find all >> the type locations, its very little extra work to also do the same for decls >> and expressions. Then we'll have static type checking for those as well. >> >> 5 - When done we will be significantly closer to having the ability to >> create a self contained IL that we can strictly define... That alone seems >> a worthwhile goal to me. The IL then becomes appropriate for streaming at >> any point in during compilation. This means any front end or tool can >> easily generate or consume a gimple stream which opens up numerous >> opportunities... That is pretty hard to enable today. > Have fun with dealing with our legacy frontends ;) Or didn't you > actually mean "any point" during compilation? ... oh, you talk about > GIMPLE. So no plans for Frontend ASTs aka GENERIC for our legacy > frontends? I meant any point where we are in gimple... Thats the only point we really care about. Once control is passed to the middle end. No plans to touch GENERIC at all... in fact, GENERIC and 'tree' will become true synonyms when I'm done, because gimple wont have any trees in it anywhere. And rtl will also refer to gimple nodes. It just wont matter what warts are in trees. >> Im going to do the initial bits on a branch for the first couple of months, >> and during that time convert a number of files over to the new gimple >> interface. Then we can look at it, measure it, comment on it, tweak it, >> whatever. You can see exactly what we'll be getting into before we fully >> commit. > Before we fully commit we want to see the underlying object changes. > Because I still doubt this all will work out without seriously restructuring > the entanglement of our tree-based frontends and the middle-end > (say "fold"). > > That is, I still think you are starting this at the wrong end. You first > need to solve the entanglement issue before you can seriously consider > making any real change to the data structures GIMPLE relies on. That is part of the experiment. RIght now I don't know for sure what the real issues will be. I learned a valuable lesson long time ago... measure a problem to determine the cause rather than assume you know where it is. This process will show exactly where there are entanglements are that need to be dealt with. It may be that by the time stage 1 rolls around, I will have identified a few other things that really need to be addressed first. And then I'll then work to address them. Fold is indeed one of them, but that is one of the reasons why there is also a plan in motion (sort of) to reduce the folding in the front end to a bare minimum... and either have its own minimal folder, or provide an interface through gimplification to a gimple folder to do what it needs. This is all in the original document. The operating theory is that front ends can do whatever the do today, and the gimplification process will turn trees into whatever gimple object is needed: expr, decl, type, whatever. Today, gimplification only addresses turning tcc_statement trees into gimple statements. What I am proposing effectively does this for all the rest of the tree class nodes. >> I think it will be an improvement over what we have today and much >> easier to work with. If the consensus is that it bites, then we leave it on >> the branch, and what have we lost? a few months of my time and we've gained >> some really useful knowledge. >> >> And no, if I can get trees out of gimple, I don't intend to ever touch them >> again! :-) > Well, I'm betting that you'll re-invent sth like 'tree' just don't > call it 'tree' ;) > You need to transparently refer to constants, SSA names and decls > (at least) as GIMPLE statement operands. You probably will make > a "gimple statement operand" base class. Well - that's a 'tree' ;) > > Certainly at the beginning when I have to mimic trees there will be a base gimple_operand of some sort which is effectively a 'typed' node... It's required for compatibility. But once trees are no longer required, we are then free to change this. The definition of a gimple_stmt can remove the operand array of 'like objects' (ie trees), and replace it with more context.. One possibility is that gimple_assign could be expanded to have multiple forms of statically typed operands inheriting from the gimple_assign class... ie. decl = const, decl = decl op const (or possibly just decl = gimple_2op_expr or some such thing.. i dont know what gimple_exprs will look like yet) decl = decl mem_expr = const etc. and whatever else is needed. This will help define and enforce a formal definition of the gimple IL... There are other options, but which one to use would be best determined once we have a handle on the other gimple objects and, more importantly, the ability to change their behaviour. Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 21:06 ` Andrew MacLeod 2013-11-06 21:52 ` Jeff Law 2013-11-07 10:29 ` Richard Biener @ 2013-11-10 12:35 ` Richard Sandiford 2013-11-10 15:27 ` Richard Biener 2 siblings, 1 reply; 116+ messages in thread From: Richard Sandiford @ 2013-11-10 12:35 UTC (permalink / raw) To: Andrew MacLeod Cc: Richard Biener, Bernd Schmidt, Jeff Law, David Malcolm, GCC Patches Andrew MacLeod <amacleod@redhat.com> writes: > 2 - I really believe gimple needs a type system different from front end > trees, that is my primary motivation. I'm tired of jumping through > hoops to do anything slightly different, and I got fed up with it. With > a separate type system for gimple, we can rid ourselves of all the stuff > that isn't related to optimization and codegen... Could we do this > with trees? possibly, but if I'm going to go to the effort of converting > the front end tree types into a new or reduced-type subset, I might as > well put that effort into something that is more appropriate right from > the start. But what types specifically are you hoping to drop? Would there still be enough information for proper TBAA, for instance? Having two different type representations just sounds like it's going to lead to code duplication for common operations. Plus I'd really not like to see targets have to deal with two different representations of types. Sometimes the things that the target has to do only make sense "at the tree level" (e.g. providing the definition of va_list). Some are on the boundary, such as lowering va_arg into gimple. Some could potentially be used in both places, e.g. the hook to determine the correct alignment for a vector. (I can imagine we'd want to be able to call that at the tree level for user-defined vectors passed to __alignof, say, but also at the gimple level when vectorising.) Others are called during expand, e.g. PROMOTE_MODE. Thanks, Richard ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-10 12:35 ` Richard Sandiford @ 2013-11-10 15:27 ` Richard Biener 0 siblings, 0 replies; 116+ messages in thread From: Richard Biener @ 2013-11-10 15:27 UTC (permalink / raw) To: Richard Sandiford, Andrew MacLeod Cc: Bernd Schmidt, Jeff Law, David Malcolm, GCC Patches Richard Sandiford <rdsandiford@googlemail.com> wrote: >Andrew MacLeod <amacleod@redhat.com> writes: >> 2 - I really believe gimple needs a type system different from front >end >> trees, that is my primary motivation. I'm tired of jumping through >> hoops to do anything slightly different, and I got fed up with it. >With >> a separate type system for gimple, we can rid ourselves of all the >stuff >> that isn't related to optimization and codegen... Could we do this >> with trees? possibly, but if I'm going to go to the effort of >converting >> the front end tree types into a new or reduced-type subset, I might >as >> well put that effort into something that is more appropriate right >from >> the start. > >But what types specifically are you hoping to drop? Would there still >be enough information for proper TBAA, for instance? > >Having two different type representations just sounds like it's going >to lead to code duplication for common operations. > >Plus I'd really not like to see targets have to deal with two different >representations of types. Sometimes the things that the target >has to do only make sense "at the tree level" (e.g. providing the >definition of va_list). Some are on the boundary, such as lowering >va_arg into gimple. Some could potentially be used in both places, >e.g. the hook to determine the correct alignment for a vector. >(I can imagine we'd want to be able to call that at the tree level for >user-defined vectors passed to __alignof, say, but also at the gimple >level when vectorising.) Others are called during expand, e.g. >PROMOTE_MODE. I can see that a change of the representation of types makes sense to better isolate frontend dependent things. In theory we have lang_type for that but frontend specific things are unfortunately not limited to that. That said, the idea of doing it on our own in gimple isn't the best - rather the existing tree representation should be changed and with it all affected frontends. Even with trees not all things need to remain trees btw, types could get a non-tree structure. But then start at the root of the problem that trees are ubiquitous - remove the remaining tree container structures and its uses. In the past a lot of work has already been done here, but it's not yet complete. Richard. >Thanks, >Richard ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 11:20 ` Bernd Schmidt 2013-11-06 11:43 ` Richard Biener @ 2013-11-06 11:56 ` Eric Botcazou 2013-11-06 20:51 ` Jeff Law 2 siblings, 0 replies; 116+ messages in thread From: Eric Botcazou @ 2013-11-06 11:56 UTC (permalink / raw) To: Bernd Schmidt Cc: gcc-patches, Richard Biener, Jeff Law, David Malcolm, Andrew MacLeod > Maybe we need to revisit it? As one of those who were not in favour of > the C++ move, can I ask you guys to step back for a moment and think > about - what do all of these changes buy us, exactly? Imagine the state > at the end, where everything is converted and supposedly the temporary > ugliness is gone, what have we gained over the code as it is now? Without going as far as revisiting the decision, I'd like to ask whether the impact of the recent changes on the speed of the compiler has been evaluated. I didn't conduct real measurements but bootstrap times on mainline, which were slightly increasing as usual over the course of the year, started to increase at a faster pace over the last couple of months, at least for me. -- Eric Botcazou ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 11:20 ` Bernd Schmidt 2013-11-06 11:43 ` Richard Biener 2013-11-06 11:56 ` Eric Botcazou @ 2013-11-06 20:51 ` Jeff Law 2 siblings, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-06 20:51 UTC (permalink / raw) To: Bernd Schmidt, Richard Biener; +Cc: David Malcolm, GCC Patches, Andrew MacLeod On 11/06/13 04:02, Bernd Schmidt wrote: > On 11/06/2013 10:31 AM, Richard Biener wrote: >> We decided to move to C++. As part of a later discussion we decided >> to go with a single general dynamic-casting style, mimicing the "real" >> C++ variant which is dynamic_cast < ... >. Which resulted in >> is-a.h. >> >> So yes, we've decided to go C++ so we have to live with certain >> uglinesses of that decisions (and maybe over time those uglinesses >> will fade away and we get used to it and like it). >> >> Thus, there isn't another option besides using the is-a.h machinery >> and enabling and using RTTI. Sticking to C for gimple doesn't seem >> to be consistent with the decision to move to C++. >> >> Oh, I'm not saying I'm a big fan of as_a / is_a or C++ in general >> as it plays out right now. But well, we've had the discussion and >> had a decision. > > Maybe we need to revisit it? As one of those who were not in favour of > the C++ move, can I ask you guys to step back for a moment and think > about - what do all of these changes buy us, exactly? Imagine the state > at the end, where everything is converted and supposedly the temporary > ugliness is gone, what have we gained over the code as it is now? I think Andrew outlined much of this at the Cauldron. I'd strongly recommend reviewing the talk/slides. My personal favorite is the type checking and everything that implies. For example, most/all of the tree checking crap just goes away as you'll almost always know what kind of tree you're working with. Checking becomes limited to locations where we we have to do conversions. It becomes a lot harder to mess something up. > > I still think all this effort is misdirected and distracts us from > making changes that improve gcc for its users. I disagree. This effort is meant to restructure GCC so that we can continue to improve it without going insane. In many respects it's similar to the tree-ssa work we undertook 10+ years ago and to some degree it's cleaning up things we decided not to deal with at that time -- namely reusing trees in gimple/ssa. jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-11-06 9:37 ` Richard Biener 2013-11-06 11:20 ` Bernd Schmidt @ 2013-11-06 21:26 ` Jeff Law 1 sibling, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-06 21:26 UTC (permalink / raw) To: Richard Biener; +Cc: David Malcolm, GCC Patches, Andrew MacLeod On 11/06/13 02:31, Richard Biener wrote: > > We decided to move to C++. As part of a later discussion we decided > to go with a single general dynamic-casting style, mimicing the "real" > C++ variant which is dynamic_cast < ... >. Which resulted in > is-a.h. > > So yes, we've decided to go C++ so we have to live with certain > uglinesses of that decisions (and maybe over time those uglinesses > will fade away and we get used to it and like it). > > Thus, there isn't another option besides using the is-a.h machinery > and enabling and using RTTI. Sticking to C for gimple doesn't seem > to be consistent with the decision to move to C++. > > Oh, I'm not saying I'm a big fan of as_a / is_a or C++ in general > as it plays out right now. But well, we've had the discussion and > had a decision. > > Execute. OK. I'll hold my nose when I see the as_a/is_a stuff and try to get past them :-) jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) 2013-10-31 16:41 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) David Malcolm ` (8 preceding siblings ...) 2013-11-05 21:33 ` Jeff Law @ 2013-11-14 8:40 ` Jeff Law 9 siblings, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-14 8:40 UTC (permalink / raw) To: David Malcolm, gcc-patches, Andrew MacLeod On 10/31/13 10:26, David Malcolm wrote: > > The following series of patches convert it to a C++ hierarchy, using the > existing structs, eliminating the union. The "gimple" typedef changes > from being a > (union gimple_statement_d *) > to being a: > (struct gimple_statement_base *) > > There are no virtual functions in the new code: the sizes of the various > structs are unchanged. Seems like a reasonable place to start (no virtuals). As I mentioned in my earlier reply today, virtuals may be one way to cut down on the downcasting. They have obvious downsides, but I think we now have some code samples to think about so we can sensibly evaluate downcasting vs adding virtual functions and how each affects the code we write. > > Again, as noted in the earlier patch series, the names of the structs > are rather verbose. I would prefer to also rename them all to eliminate > the "_statement" component: > "gimple_statement_base" -> "gimple_base" > "gimple_statement_phi" -> "gimple_phi" > "gimple_statement_omp" -> "gimple_omp" > etc, but I didn't do this to mimimize the patch size. But if the core > maintainers are up for that, I can redo the patch series with that > change also, or do that as a followup. If we do that, I think it'd be a followup -- it's a fair amount of churn with marginal benefit though, IMHO. Jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* [patch] Create gimple-expr..[ch] ... was Re: RFC: gimple.[ch] break apart 2013-10-31 5:45 RFC: gimple.[ch] break apart Andrew MacLeod 2013-10-31 6:15 ` Jeff Law 2013-10-31 16:41 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) David Malcolm @ 2013-11-05 16:58 ` Andrew MacLeod 2013-11-05 17:52 ` Jeff Law 2013-11-07 10:58 ` Basile Starynkevitch 2 siblings, 2 replies; 116+ messages in thread From: Andrew MacLeod @ 2013-11-05 16:58 UTC (permalink / raw) To: gcc-patches, Richard Biener, Jeff Law, Diego Novillo [-- Attachment #1: Type: text/plain, Size: 3393 bytes --] On 10/30/2013 11:18 PM, Andrew MacLeod wrote: > > > As a result, any gimple queries regarding types, decls, or expressions > are actually tree queries. They are sprinkled throughout gimple.[ch] and > gimplify.[ch], not to mention tree.[ch] as well as other parts of the > compiler where they happened to be needed. This has caused various > ordering issues among the inline functions when I tried to split out the > stmt, iterator, and gimplification bits from gimple.[ch]. Not to > mention a lack of an obvious home for some of these functions. > > I'd like to move these as I encounter them into a new file, > gimple-decl.[ch]. When I'm working on the other gimple classes, this > will be further split into gimple-decl, gimple-type and gimple-expr as > appropriate but it seems reasonable to create just the one file now to > clump them since there is no other formal organization. So any function > which is actually querying/setting/building a decl, type, or expression > for gimple would go here. I decided to name the new file gimple-expr.[ch] instead of gimple-decl.... This will eventually split into gimple-type.[ch], gimple-decl.[ch], and gimple-expr.[ch]. I could split them that way now if desired, but isn't critical yet. maybe I should just do that... Anyway, of the 3 files, gimple-expr will depend on the other 2, and thus is likely to be the one #included in places like the rtl generation files that need access to all these gimple dictionary/expression routines. (eventually those rtl files will include only gimple-expr.h and not tree.h :-). In any case, I had to do this split from gimple.h first since gimple-stmt.[ch] and the others require some of these basic routines, and I can't split anything else out first without then getting an include dependency cycle between gimple.h and gimple-stmt.h for instance. This way gimple-stmt.h can include gimple-expr.h, and then gimple.h can include gimpe-stmt.h and no chicken/egg situation. This contains just the functions that are in either in, or prototyped in, gimple.h, and is just the first cut. There are more things that will eventually get put here from gimple.c, but their prototypes are in places like tree.h and more include cycles or poor requirements on files to include are exposed if I move them now since front ends or rtl files are using those routines (like get_base_address). There are also a few I wanted to hold off on and see how things work out before moving them. In any case, I tried to pull out the functions that operated on trees currently and performed an operation on a type, decl, or expression. My litmus test was usually, "Is this liekly going to be a method of a type, decl or expr class relating to the object itself." and moved it if it seemed so. The slightly iffier ones were extract_ops_from_tree*() and gimple_cond_get_ops_from_tree()... Those clearly worked on expressions and not statements, but are utilized in places like rtl land that don't deal with stmts... so they need to be exposed via the expression processing and interface. Its also quite possible those will end up in gimplify.[ch] once I get that far... I do expect there will still be a little bit of fine tuning, but this is the first cut to enable me to split out gimple-stmts.[ch] next. Bootstraps on x86_64-unknown-linux-gnu with no new regressions. OK? Andrew [-- Attachment #2: gexpr.patch --] [-- Type: text/x-patch, Size: 63834 bytes --] * gimple.h: Move some prototypes to gimple-expr.h and add to include list. (extract_ops_from_tree, gimple_call_addr_fndecl, is_gimple_reg_type): Move to gimple-expr.h. * gimple-expr.h: New file. Relocate some prototypes from gimple.h. (types_compatible_p, is_gimple_reg_type, is_gimple_variable, is_gimple_id, virtual_operand_p, is_gimple_addressable, is_gimple_constant, extract_ops_from_tree, gimple_call_addr_fndecl): Relocate here. * gimple.c (extract_ops_from_tree_1, gimple_cond_get_ops_from_tree, gimple_set_body, gimple_body, gimple_has_body_p, is_gimple_lvalue, is_gimple_condexpr, is_gimple_addressable, is_gimple_constant, is_gimple_address, is_gimple_invariant_address, is_gimple_ip_invariant_address, is_gimple_min_invariant, is_gimple_ip_invariant, is_gimple_variable, is_gimple_id, virtual_operand_p, is_gimple_reg, is_gimple_val, is_gimple_asm_val, is_gimple_min_lval, is_gimple_call_addr, is_gimple_mem_ref_addr, gimple_decl_printable_name, useless_type_conversion_p, types_compatible_p, gimple_can_coalesce_p, copy_var_decl): Move to gimple-expr.[ch]. * gimple-expr.c: New File. (useless_type_conversion_p, gimple_set_body, gimple_body, gimple_has_body_p, gimple_decl_printable_name, copy_var_decl, gimple_can_coalesce_p, extract_ops_from_tree_1, gimple_cond_get_ops_from_tree, is_gimple_lvalue, is_gimple_condexpr, is_gimple_address, is_gimple_invariant_address, is_gimple_ip_invariant_address, is_gimple_min_invariant, is_gimple_ip_invariant, is_gimple_reg, is_gimple_val, is_gimple_asm_val, is_gimple_min_lval, is_gimple_call_addr, is_gimple_mem_ref_addr): Relocate here. * Makefile.in (OBJS): Add gimple-expr.o. Index: gimple.h =================================================================== *** gimple.h (revision 204350) --- gimple.h (working copy) *************** along with GCC; see the file COPYING3. *** 31,36 **** --- 31,37 ---- #include "internal-fn.h" #include "gimple-fold.h" #include "tree-eh.h" + #include "gimple-expr.h" typedef gimple gimple_seq_node; *************** gimple gimple_build_return (tree); *** 745,752 **** gimple gimple_build_assign_stat (tree, tree MEM_STAT_DECL); #define gimple_build_assign(l,r) gimple_build_assign_stat (l, r MEM_STAT_INFO) - void extract_ops_from_tree_1 (tree, enum tree_code *, tree *, tree *, tree *); - gimple gimple_build_assign_with_ops (enum tree_code, tree, tree, tree CXX_MEM_STAT_INFO); --- 746,751 ---- *************** gimple gimple_build_predict (enum br_pre *** 809,817 **** enum gimple_statement_structure_enum gss_for_assign (enum tree_code); void sort_case_labels (vec<tree> ); void preprocess_case_label_vec_for_gimple (vec<tree> , tree, tree *); - void gimple_set_body (tree, gimple_seq); - gimple_seq gimple_body (tree); - bool gimple_has_body_p (tree); gimple_seq gimple_seq_alloc (void); void gimple_seq_free (gimple_seq); void gimple_seq_add_seq (gimple_seq *, gimple_seq); --- 808,813 ---- *************** tree gimple_get_lhs (const_gimple); *** 832,838 **** void gimple_set_lhs (gimple, tree); void gimple_replace_lhs (gimple, tree); gimple gimple_copy (gimple); - void gimple_cond_get_ops_from_tree (tree, enum tree_code *, tree *, tree *); gimple gimple_build_cond_from_tree (tree, tree, tree); void gimple_cond_set_condition_from_tree (gimple, tree); bool gimple_has_side_effects (const_gimple); --- 828,833 ---- *************** bool empty_body_p (gimple_seq); *** 844,891 **** unsigned get_gimple_rhs_num_ops (enum tree_code); #define gimple_alloc(c, n) gimple_alloc_stat (c, n MEM_STAT_INFO) gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL); - const char *gimple_decl_printable_name (tree, int); - - /* Returns true iff T is a virtual ssa name decl. */ - extern bool virtual_operand_p (tree); - /* Returns true iff T is a scalar register variable. */ - extern bool is_gimple_reg (tree); - /* Returns true iff T is any sort of variable. */ - extern bool is_gimple_variable (tree); - /* Returns true iff T is any sort of symbol. */ - extern bool is_gimple_id (tree); - /* Returns true iff T is a variable or an INDIRECT_REF (of a variable). */ - extern bool is_gimple_min_lval (tree); - /* Returns true iff T is something whose address can be taken. */ - extern bool is_gimple_addressable (tree); - /* Returns true iff T is any valid GIMPLE lvalue. */ - extern bool is_gimple_lvalue (tree); - - /* Returns true iff T is a GIMPLE address. */ - bool is_gimple_address (const_tree); - /* Returns true iff T is a GIMPLE invariant address. */ - bool is_gimple_invariant_address (const_tree); - /* Returns true iff T is a GIMPLE invariant address at interprocedural - level. */ - bool is_gimple_ip_invariant_address (const_tree); - /* Returns true iff T is a valid GIMPLE constant. */ - bool is_gimple_constant (const_tree); - /* Returns true iff T is a GIMPLE restricted function invariant. */ - extern bool is_gimple_min_invariant (const_tree); - /* Returns true iff T is a GIMPLE restricted interprecodural invariant. */ - extern bool is_gimple_ip_invariant (const_tree); - /* Returns true iff T is a GIMPLE rvalue. */ - extern bool is_gimple_val (tree); - /* Returns true iff T is a GIMPLE asm statement input. */ - extern bool is_gimple_asm_val (tree); - /* Returns true iff T is a valid address operand of a MEM_REF. */ - bool is_gimple_mem_ref_addr (tree); - - /* Returns true iff T is a valid if-statement condition. */ - extern bool is_gimple_condexpr (tree); - - /* Returns true iff T is a valid call address expression. */ - extern bool is_gimple_call_addr (tree); /* Return TRUE iff stmt is a call to a built-in function. */ extern bool is_gimple_builtin_call (gimple stmt); --- 839,844 ---- *************** extern bool gimple_ior_addresses_taken ( *** 906,913 **** extern bool gimple_call_builtin_p (gimple, enum built_in_class); extern bool gimple_call_builtin_p (gimple, enum built_in_function); extern bool gimple_asm_clobbers_memory_p (const_gimple); - extern bool useless_type_conversion_p (tree, tree); - extern bool types_compatible_p (tree, tree); /* In gimplify.c */ extern tree create_tmp_var_raw (tree, const char *); --- 859,864 ---- *************** extern tree gimple_boolify (tree); *** 1086,1094 **** extern gimple_predicate rhs_predicate_for (tree); extern tree canonicalize_cond_expr_cond (tree); extern void dump_decl_set (FILE *, bitmap); - extern bool gimple_can_coalesce_p (tree, tree); extern bool nonfreeing_call_p (gimple); - extern tree copy_var_decl (tree, tree, tree); /* In trans-mem.c. */ extern void diagnose_tm_safe_errors (tree); --- 1037,1043 ---- *************** gimple_assign_set_rhs_with_ops (gimple_s *** 2042,2059 **** gimple_assign_set_rhs_with_ops_1 (gsi, code, op1, op2, NULL); } - /* A wrapper around extract_ops_from_tree_1, for callers which expect - to see only a maximum of two operands. */ - - static inline void - extract_ops_from_tree (tree expr, enum tree_code *code, tree *op0, - tree *op1) - { - tree op2; - extract_ops_from_tree_1 (expr, code, op0, op1, &op2); - gcc_assert (op2 == NULL_TREE); - } - /* Returns true if GS is a nontemporal move. */ static inline bool --- 1991,1996 ---- *************** gimple_call_set_internal_fn (gimple gs, *** 2316,2340 **** } - /* Given a valid GIMPLE_CALL function address return the FUNCTION_DECL - associated with the callee if known. Otherwise return NULL_TREE. */ - - static inline tree - gimple_call_addr_fndecl (const_tree fn) - { - if (fn && TREE_CODE (fn) == ADDR_EXPR) - { - tree fndecl = TREE_OPERAND (fn, 0); - if (TREE_CODE (fndecl) == MEM_REF - && TREE_CODE (TREE_OPERAND (fndecl, 0)) == ADDR_EXPR - && integer_zerop (TREE_OPERAND (fndecl, 1))) - fndecl = TREE_OPERAND (TREE_OPERAND (fndecl, 0), 0); - if (TREE_CODE (fndecl) == FUNCTION_DECL) - return fndecl; - } - return NULL_TREE; - } - /* If a given GIMPLE_CALL's callee is a FUNCTION_DECL, return it. Otherwise return NULL. This function is analogous to get_callee_fndecl in tree land. */ --- 2253,2258 ---- *************** gimple_expr_type (const_gimple stmt) *** 5398,5411 **** return void_type_node; } - /* Return true if TYPE is a suitable type for a scalar register variable. */ - - static inline bool - is_gimple_reg_type (tree type) - { - return !AGGREGATE_TYPE_P (type); - } - /* Return a new iterator pointing to GIMPLE_SEQ's first statement. */ static inline gimple_stmt_iterator --- 5316,5321 ---- Index: gimple-expr.h =================================================================== *** gimple-expr.h (revision 0) --- gimple-expr.h (working copy) *************** *** 0 **** --- 1,171 ---- + /* Header file for gimple decl, type and expressions. + Copyright (C) 2013 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + + #ifndef GCC_GIMPLE_EXPR_H + #define GCC_GIMPLE_EXPR_H + + extern bool useless_type_conversion_p (tree, tree); + + extern void gimple_set_body (tree, gimple_seq); + extern gimple_seq gimple_body (tree); + extern bool gimple_has_body_p (tree); + extern const char *gimple_decl_printable_name (tree, int); + extern tree copy_var_decl (tree, tree, tree); + extern bool gimple_can_coalesce_p (tree, tree); + + extern void extract_ops_from_tree_1 (tree, enum tree_code *, tree *, tree *, + tree *); + extern void gimple_cond_get_ops_from_tree (tree, enum tree_code *, tree *, + tree *); + extern bool is_gimple_lvalue (tree); + extern bool is_gimple_condexpr (tree); + extern bool is_gimple_address (const_tree); + extern bool is_gimple_invariant_address (const_tree); + extern bool is_gimple_ip_invariant_address (const_tree); + extern bool is_gimple_min_invariant (const_tree); + extern bool is_gimple_ip_invariant (const_tree); + extern bool is_gimple_reg (tree); + extern bool is_gimple_val (tree); + extern bool is_gimple_asm_val (tree); + extern bool is_gimple_min_lval (tree); + extern bool is_gimple_call_addr (tree); + extern bool is_gimple_mem_ref_addr (tree); + + /* Return true if a conversion from either type of TYPE1 and TYPE2 + to the other is not required. Otherwise return false. */ + + static inline bool + types_compatible_p (tree type1, tree type2) + { + return (type1 == type2 + || (useless_type_conversion_p (type1, type2) + && useless_type_conversion_p (type2, type1))); + } + + /* Return true if TYPE is a suitable type for a scalar register variable. */ + + static inline bool + is_gimple_reg_type (tree type) + { + return !AGGREGATE_TYPE_P (type); + } + + /* Return true if T is a variable. */ + + static inline bool + is_gimple_variable (tree t) + { + return (TREE_CODE (t) == VAR_DECL + || TREE_CODE (t) == PARM_DECL + || TREE_CODE (t) == RESULT_DECL + || TREE_CODE (t) == SSA_NAME); + } + + /* Return true if T is a GIMPLE identifier (something with an address). */ + + static inline bool + is_gimple_id (tree t) + { + return (is_gimple_variable (t) + || TREE_CODE (t) == FUNCTION_DECL + || TREE_CODE (t) == LABEL_DECL + || TREE_CODE (t) == CONST_DECL + /* Allow string constants, since they are addressable. */ + || TREE_CODE (t) == STRING_CST); + } + + /* Return true if OP, an SSA name or a DECL is a virtual operand. */ + + static inline bool + virtual_operand_p (tree op) + { + if (TREE_CODE (op) == SSA_NAME) + { + op = SSA_NAME_VAR (op); + if (!op) + return false; + } + + if (TREE_CODE (op) == VAR_DECL) + return VAR_DECL_IS_VIRTUAL_OPERAND (op); + + return false; + } + + /* Return true if T is something whose address can be taken. */ + + static inline bool + is_gimple_addressable (tree t) + { + return (is_gimple_id (t) || handled_component_p (t) + || TREE_CODE (t) == MEM_REF); + } + + /* Return true if T is a valid gimple constant. */ + + static inline bool + is_gimple_constant (const_tree t) + { + switch (TREE_CODE (t)) + { + case INTEGER_CST: + case REAL_CST: + case FIXED_CST: + case STRING_CST: + case COMPLEX_CST: + case VECTOR_CST: + return true; + + default: + return false; + } + } + + /* A wrapper around extract_ops_from_tree_1, for callers which expect + to see only a maximum of two operands. */ + + static inline void + extract_ops_from_tree (tree expr, enum tree_code *code, tree *op0, + tree *op1) + { + tree op2; + extract_ops_from_tree_1 (expr, code, op0, op1, &op2); + gcc_assert (op2 == NULL_TREE); + } + + /* Given a valid GIMPLE_CALL function address return the FUNCTION_DECL + associated with the callee if known. Otherwise return NULL_TREE. */ + + static inline tree + gimple_call_addr_fndecl (const_tree fn) + { + if (fn && TREE_CODE (fn) == ADDR_EXPR) + { + tree fndecl = TREE_OPERAND (fn, 0); + if (TREE_CODE (fndecl) == MEM_REF + && TREE_CODE (TREE_OPERAND (fndecl, 0)) == ADDR_EXPR + && integer_zerop (TREE_OPERAND (fndecl, 1))) + fndecl = TREE_OPERAND (TREE_OPERAND (fndecl, 0), 0); + if (TREE_CODE (fndecl) == FUNCTION_DECL) + return fndecl; + } + return NULL_TREE; + } + + #endif /* GCC_GIMPLE_EXPR_H */ Index: gimple.c =================================================================== *** gimple.c (revision 204350) --- gimple.c (working copy) *************** gimple_call_get_nobnd_arg_index (const_g *** 386,432 **** } - /* Extract the operands and code for expression EXPR into *SUBCODE_P, - *OP1_P, *OP2_P and *OP3_P respectively. */ - - void - extract_ops_from_tree_1 (tree expr, enum tree_code *subcode_p, tree *op1_p, - tree *op2_p, tree *op3_p) - { - enum gimple_rhs_class grhs_class; - - *subcode_p = TREE_CODE (expr); - grhs_class = get_gimple_rhs_class (*subcode_p); - - if (grhs_class == GIMPLE_TERNARY_RHS) - { - *op1_p = TREE_OPERAND (expr, 0); - *op2_p = TREE_OPERAND (expr, 1); - *op3_p = TREE_OPERAND (expr, 2); - } - else if (grhs_class == GIMPLE_BINARY_RHS) - { - *op1_p = TREE_OPERAND (expr, 0); - *op2_p = TREE_OPERAND (expr, 1); - *op3_p = NULL_TREE; - } - else if (grhs_class == GIMPLE_UNARY_RHS) - { - *op1_p = TREE_OPERAND (expr, 0); - *op2_p = NULL_TREE; - *op3_p = NULL_TREE; - } - else if (grhs_class == GIMPLE_SINGLE_RHS) - { - *op1_p = expr; - *op2_p = NULL_TREE; - *op3_p = NULL_TREE; - } - else - gcc_unreachable (); - } - - /* Build a GIMPLE_ASSIGN statement. LHS of the assignment. --- 386,391 ---- *************** gimple_build_cond (enum tree_code pred_c *** 526,562 **** return p; } - - /* Extract operands for a GIMPLE_COND statement out of COND_EXPR tree COND. */ - - void - gimple_cond_get_ops_from_tree (tree cond, enum tree_code *code_p, - tree *lhs_p, tree *rhs_p) - { - gcc_assert (TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison - || TREE_CODE (cond) == TRUTH_NOT_EXPR - || is_gimple_min_invariant (cond) - || SSA_VAR_P (cond)); - - extract_ops_from_tree (cond, code_p, lhs_p, rhs_p); - - /* Canonicalize conditionals of the form 'if (!VAL)'. */ - if (*code_p == TRUTH_NOT_EXPR) - { - *code_p = EQ_EXPR; - gcc_assert (*lhs_p && *rhs_p == NULL_TREE); - *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p)); - } - /* Canonicalize conditionals of the form 'if (VAL)' */ - else if (TREE_CODE_CLASS (*code_p) != tcc_comparison) - { - *code_p = NE_EXPR; - gcc_assert (*lhs_p && *rhs_p == NULL_TREE); - *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p)); - } - } - - /* Build a GIMPLE_COND statement from the conditional expression tree COND. T_LABEL and F_LABEL are as in gimple_build_cond. */ --- 485,490 ---- *************** walk_gimple_stmt (gimple_stmt_iterator * *** 1906,1950 **** } - /* Set sequence SEQ to be the GIMPLE body for function FN. */ - - void - gimple_set_body (tree fndecl, gimple_seq seq) - { - struct function *fn = DECL_STRUCT_FUNCTION (fndecl); - if (fn == NULL) - { - /* If FNDECL still does not have a function structure associated - with it, then it does not make sense for it to receive a - GIMPLE body. */ - gcc_assert (seq == NULL); - } - else - fn->gimple_body = seq; - } - - - /* Return the body of GIMPLE statements for function FN. After the - CFG pass, the function body doesn't exist anymore because it has - been split up into basic blocks. In this case, it returns - NULL. */ - - gimple_seq - gimple_body (tree fndecl) - { - struct function *fn = DECL_STRUCT_FUNCTION (fndecl); - return fn ? fn->gimple_body : NULL; - } - - /* Return true when FNDECL has Gimple body either in unlowered - or CFG form. */ - bool - gimple_has_body_p (tree fndecl) - { - struct function *fn = DECL_STRUCT_FUNCTION (fndecl); - return (gimple_body (fndecl) || (fn && fn->cfg)); - } - /* Return true if calls C1 and C2 are known to go to the same function. */ bool --- 1834,1839 ---- *************** const unsigned char gimple_rhs_class_tab *** 2602,2926 **** #undef DEFTREECODE #undef END_OF_BASE_TREE_CODES - /* For the definitive definition of GIMPLE, see doc/tree-ssa.texi. */ - - /* Validation of GIMPLE expressions. */ - - /* Return true if T is a valid LHS for a GIMPLE assignment expression. */ - - bool - is_gimple_lvalue (tree t) - { - return (is_gimple_addressable (t) - || TREE_CODE (t) == WITH_SIZE_EXPR - /* These are complex lvalues, but don't have addresses, so they - go here. */ - || TREE_CODE (t) == BIT_FIELD_REF); - } - - /* Return true if T is a GIMPLE condition. */ - - bool - is_gimple_condexpr (tree t) - { - return (is_gimple_val (t) || (COMPARISON_CLASS_P (t) - && !tree_could_throw_p (t) - && is_gimple_val (TREE_OPERAND (t, 0)) - && is_gimple_val (TREE_OPERAND (t, 1)))); - } - - /* Return true if T is something whose address can be taken. */ - - bool - is_gimple_addressable (tree t) - { - return (is_gimple_id (t) || handled_component_p (t) - || TREE_CODE (t) == MEM_REF); - } - - /* Return true if T is a valid gimple constant. */ - - bool - is_gimple_constant (const_tree t) - { - switch (TREE_CODE (t)) - { - case INTEGER_CST: - case REAL_CST: - case FIXED_CST: - case STRING_CST: - case COMPLEX_CST: - case VECTOR_CST: - return true; - - default: - return false; - } - } - - /* Return true if T is a gimple address. */ - - bool - is_gimple_address (const_tree t) - { - tree op; - - if (TREE_CODE (t) != ADDR_EXPR) - return false; - - op = TREE_OPERAND (t, 0); - while (handled_component_p (op)) - { - if ((TREE_CODE (op) == ARRAY_REF - || TREE_CODE (op) == ARRAY_RANGE_REF) - && !is_gimple_val (TREE_OPERAND (op, 1))) - return false; - - op = TREE_OPERAND (op, 0); - } - - if (CONSTANT_CLASS_P (op) || TREE_CODE (op) == MEM_REF) - return true; - - switch (TREE_CODE (op)) - { - case PARM_DECL: - case RESULT_DECL: - case LABEL_DECL: - case FUNCTION_DECL: - case VAR_DECL: - case CONST_DECL: - return true; - - default: - return false; - } - } - - /* Return true if T is a gimple invariant address. */ - - bool - is_gimple_invariant_address (const_tree t) - { - const_tree op; - - if (TREE_CODE (t) != ADDR_EXPR) - return false; - - op = strip_invariant_refs (TREE_OPERAND (t, 0)); - if (!op) - return false; - - if (TREE_CODE (op) == MEM_REF) - { - const_tree op0 = TREE_OPERAND (op, 0); - return (TREE_CODE (op0) == ADDR_EXPR - && (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)) - || decl_address_invariant_p (TREE_OPERAND (op0, 0)))); - } - - return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op); - } - - /* Return true if T is a gimple invariant address at IPA level - (so addresses of variables on stack are not allowed). */ - - bool - is_gimple_ip_invariant_address (const_tree t) - { - const_tree op; - - if (TREE_CODE (t) != ADDR_EXPR) - return false; - - op = strip_invariant_refs (TREE_OPERAND (t, 0)); - if (!op) - return false; - - if (TREE_CODE (op) == MEM_REF) - { - const_tree op0 = TREE_OPERAND (op, 0); - return (TREE_CODE (op0) == ADDR_EXPR - && (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)) - || decl_address_ip_invariant_p (TREE_OPERAND (op0, 0)))); - } - - return CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op); - } - - /* Return true if T is a GIMPLE minimal invariant. It's a restricted - form of function invariant. */ - - bool - is_gimple_min_invariant (const_tree t) - { - if (TREE_CODE (t) == ADDR_EXPR) - return is_gimple_invariant_address (t); - - return is_gimple_constant (t); - } - - /* Return true if T is a GIMPLE interprocedural invariant. It's a restricted - form of gimple minimal invariant. */ - - bool - is_gimple_ip_invariant (const_tree t) - { - if (TREE_CODE (t) == ADDR_EXPR) - return is_gimple_ip_invariant_address (t); - - return is_gimple_constant (t); - } - - /* Return true if T is a variable. */ - - bool - is_gimple_variable (tree t) - { - return (TREE_CODE (t) == VAR_DECL - || TREE_CODE (t) == PARM_DECL - || TREE_CODE (t) == RESULT_DECL - || TREE_CODE (t) == SSA_NAME); - } - - /* Return true if T is a GIMPLE identifier (something with an address). */ - - bool - is_gimple_id (tree t) - { - return (is_gimple_variable (t) - || TREE_CODE (t) == FUNCTION_DECL - || TREE_CODE (t) == LABEL_DECL - || TREE_CODE (t) == CONST_DECL - /* Allow string constants, since they are addressable. */ - || TREE_CODE (t) == STRING_CST); - } - - /* Return true if OP, an SSA name or a DECL is a virtual operand. */ - - bool - virtual_operand_p (tree op) - { - if (TREE_CODE (op) == SSA_NAME) - { - op = SSA_NAME_VAR (op); - if (!op) - return false; - } - - if (TREE_CODE (op) == VAR_DECL) - return VAR_DECL_IS_VIRTUAL_OPERAND (op); - - return false; - } - - - /* Return true if T is a non-aggregate register variable. */ - - bool - is_gimple_reg (tree t) - { - if (virtual_operand_p (t)) - return false; - - if (TREE_CODE (t) == SSA_NAME) - return true; - - if (!is_gimple_variable (t)) - return false; - - if (!is_gimple_reg_type (TREE_TYPE (t))) - return false; - - /* A volatile decl is not acceptable because we can't reuse it as - needed. We need to copy it into a temp first. */ - if (TREE_THIS_VOLATILE (t)) - return false; - - /* We define "registers" as things that can be renamed as needed, - which with our infrastructure does not apply to memory. */ - if (needs_to_live_in_memory (t)) - return false; - - /* Hard register variables are an interesting case. For those that - are call-clobbered, we don't know where all the calls are, since - we don't (want to) take into account which operations will turn - into libcalls at the rtl level. For those that are call-saved, - we don't currently model the fact that calls may in fact change - global hard registers, nor do we examine ASM_CLOBBERS at the tree - level, and so miss variable changes that might imply. All around, - it seems safest to not do too much optimization with these at the - tree level at all. We'll have to rely on the rtl optimizers to - clean this up, as there we've got all the appropriate bits exposed. */ - if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)) - return false; - - /* Complex and vector values must have been put into SSA-like form. - That is, no assignments to the individual components. */ - if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE) - return DECL_GIMPLE_REG_P (t); - - return true; - } - - - /* Return true if T is a GIMPLE rvalue, i.e. an identifier or a constant. */ - - bool - is_gimple_val (tree t) - { - /* Make loads from volatiles and memory vars explicit. */ - if (is_gimple_variable (t) - && is_gimple_reg_type (TREE_TYPE (t)) - && !is_gimple_reg (t)) - return false; - - return (is_gimple_variable (t) || is_gimple_min_invariant (t)); - } - - /* Similarly, but accept hard registers as inputs to asm statements. */ - - bool - is_gimple_asm_val (tree t) - { - if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)) - return true; - - return is_gimple_val (t); - } - - /* Return true if T is a GIMPLE minimal lvalue. */ - - bool - is_gimple_min_lval (tree t) - { - if (!(t = CONST_CAST_TREE (strip_invariant_refs (t)))) - return false; - return (is_gimple_id (t) || TREE_CODE (t) == MEM_REF); - } - - /* Return true if T is a valid function operand of a CALL_EXPR. */ - - bool - is_gimple_call_addr (tree t) - { - return (TREE_CODE (t) == OBJ_TYPE_REF || is_gimple_val (t)); - } - - /* Return true if T is a valid address operand of a MEM_REF. */ - - bool - is_gimple_mem_ref_addr (tree t) - { - return (is_gimple_reg (t) - || TREE_CODE (t) == INTEGER_CST - || (TREE_CODE (t) == ADDR_EXPR - && (CONSTANT_CLASS_P (TREE_OPERAND (t, 0)) - || decl_address_invariant_p (TREE_OPERAND (t, 0))))); - } - - /* Given a memory reference expression T, return its base address. The base address of a memory reference expression is the main object being referenced. For instance, the base address for --- 2491,2496 ---- *************** gimple_ior_addresses_taken (bitmap addre *** 3642,3678 **** } - /* Return a printable name for symbol DECL. */ - - const char * - gimple_decl_printable_name (tree decl, int verbosity) - { - if (!DECL_NAME (decl)) - return NULL; - - if (DECL_ASSEMBLER_NAME_SET_P (decl)) - { - const char *str, *mangled_str; - int dmgl_opts = DMGL_NO_OPTS; - - if (verbosity >= 2) - { - dmgl_opts = DMGL_VERBOSE - | DMGL_ANSI - | DMGL_GNU_V3 - | DMGL_RET_POSTFIX; - if (TREE_CODE (decl) == FUNCTION_DECL) - dmgl_opts |= DMGL_PARAMS; - } - - mangled_str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - str = cplus_demangle_v3 (mangled_str, dmgl_opts); - return (str) ? str : mangled_str; - } - - return IDENTIFIER_POINTER (DECL_NAME (decl)); - } - /* Return TRUE iff stmt is a call to a built-in function. */ bool --- 3212,3217 ---- *************** gimple_asm_clobbers_memory_p (const_gimp *** 3763,4023 **** return false; } - - /* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a - useless type conversion, otherwise return false. - - This function implicitly defines the middle-end type system. With - the notion of 'a < b' meaning that useless_type_conversion_p (a, b) - holds and 'a > b' meaning that useless_type_conversion_p (b, a) holds, - the following invariants shall be fulfilled: - - 1) useless_type_conversion_p is transitive. - If a < b and b < c then a < c. - - 2) useless_type_conversion_p is not symmetric. - From a < b does not follow a > b. - - 3) Types define the available set of operations applicable to values. - A type conversion is useless if the operations for the target type - is a subset of the operations for the source type. For example - casts to void* are useless, casts from void* are not (void* can't - be dereferenced or offsetted, but copied, hence its set of operations - is a strict subset of that of all other data pointer types). Casts - to const T* are useless (can't be written to), casts from const T* - to T* are not. */ - - bool - useless_type_conversion_p (tree outer_type, tree inner_type) - { - /* Do the following before stripping toplevel qualifiers. */ - if (POINTER_TYPE_P (inner_type) - && POINTER_TYPE_P (outer_type)) - { - /* Do not lose casts between pointers to different address spaces. */ - if (TYPE_ADDR_SPACE (TREE_TYPE (outer_type)) - != TYPE_ADDR_SPACE (TREE_TYPE (inner_type))) - return false; - } - - /* From now on qualifiers on value types do not matter. */ - inner_type = TYPE_MAIN_VARIANT (inner_type); - outer_type = TYPE_MAIN_VARIANT (outer_type); - - if (inner_type == outer_type) - return true; - - /* If we know the canonical types, compare them. */ - if (TYPE_CANONICAL (inner_type) - && TYPE_CANONICAL (inner_type) == TYPE_CANONICAL (outer_type)) - return true; - - /* Changes in machine mode are never useless conversions unless we - deal with aggregate types in which case we defer to later checks. */ - if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type) - && !AGGREGATE_TYPE_P (inner_type)) - return false; - - /* If both the inner and outer types are integral types, then the - conversion is not necessary if they have the same mode and - signedness and precision, and both or neither are boolean. */ - if (INTEGRAL_TYPE_P (inner_type) - && INTEGRAL_TYPE_P (outer_type)) - { - /* Preserve changes in signedness or precision. */ - if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type) - || TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type)) - return false; - - /* Preserve conversions to/from BOOLEAN_TYPE if types are not - of precision one. */ - if (((TREE_CODE (inner_type) == BOOLEAN_TYPE) - != (TREE_CODE (outer_type) == BOOLEAN_TYPE)) - && TYPE_PRECISION (outer_type) != 1) - return false; - - /* We don't need to preserve changes in the types minimum or - maximum value in general as these do not generate code - unless the types precisions are different. */ - return true; - } - - /* Scalar floating point types with the same mode are compatible. */ - else if (SCALAR_FLOAT_TYPE_P (inner_type) - && SCALAR_FLOAT_TYPE_P (outer_type)) - return true; - - /* Fixed point types with the same mode are compatible. */ - else if (FIXED_POINT_TYPE_P (inner_type) - && FIXED_POINT_TYPE_P (outer_type)) - return true; - - /* We need to take special care recursing to pointed-to types. */ - else if (POINTER_TYPE_P (inner_type) - && POINTER_TYPE_P (outer_type)) - { - /* Do not lose casts to function pointer types. */ - if ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE) - && !(TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (inner_type)) == METHOD_TYPE)) - return false; - - /* We do not care for const qualification of the pointed-to types - as const qualification has no semantic value to the middle-end. */ - - /* Otherwise pointers/references are equivalent. */ - return true; - } - - /* Recurse for complex types. */ - else if (TREE_CODE (inner_type) == COMPLEX_TYPE - && TREE_CODE (outer_type) == COMPLEX_TYPE) - return useless_type_conversion_p (TREE_TYPE (outer_type), - TREE_TYPE (inner_type)); - - /* Recurse for vector types with the same number of subparts. */ - else if (TREE_CODE (inner_type) == VECTOR_TYPE - && TREE_CODE (outer_type) == VECTOR_TYPE - && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type)) - return useless_type_conversion_p (TREE_TYPE (outer_type), - TREE_TYPE (inner_type)); - - else if (TREE_CODE (inner_type) == ARRAY_TYPE - && TREE_CODE (outer_type) == ARRAY_TYPE) - { - /* Preserve string attributes. */ - if (TYPE_STRING_FLAG (inner_type) != TYPE_STRING_FLAG (outer_type)) - return false; - - /* Conversions from array types with unknown extent to - array types with known extent are not useless. */ - if (!TYPE_DOMAIN (inner_type) - && TYPE_DOMAIN (outer_type)) - return false; - - /* Nor are conversions from array types with non-constant size to - array types with constant size or to different size. */ - if (TYPE_SIZE (outer_type) - && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST - && (!TYPE_SIZE (inner_type) - || TREE_CODE (TYPE_SIZE (inner_type)) != INTEGER_CST - || !tree_int_cst_equal (TYPE_SIZE (outer_type), - TYPE_SIZE (inner_type)))) - return false; - - /* Check conversions between arrays with partially known extents. - If the array min/max values are constant they have to match. - Otherwise allow conversions to unknown and variable extents. - In particular this declares conversions that may change the - mode to BLKmode as useless. */ - if (TYPE_DOMAIN (inner_type) - && TYPE_DOMAIN (outer_type) - && TYPE_DOMAIN (inner_type) != TYPE_DOMAIN (outer_type)) - { - tree inner_min = TYPE_MIN_VALUE (TYPE_DOMAIN (inner_type)); - tree outer_min = TYPE_MIN_VALUE (TYPE_DOMAIN (outer_type)); - tree inner_max = TYPE_MAX_VALUE (TYPE_DOMAIN (inner_type)); - tree outer_max = TYPE_MAX_VALUE (TYPE_DOMAIN (outer_type)); - - /* After gimplification a variable min/max value carries no - additional information compared to a NULL value. All that - matters has been lowered to be part of the IL. */ - if (inner_min && TREE_CODE (inner_min) != INTEGER_CST) - inner_min = NULL_TREE; - if (outer_min && TREE_CODE (outer_min) != INTEGER_CST) - outer_min = NULL_TREE; - if (inner_max && TREE_CODE (inner_max) != INTEGER_CST) - inner_max = NULL_TREE; - if (outer_max && TREE_CODE (outer_max) != INTEGER_CST) - outer_max = NULL_TREE; - - /* Conversions NULL / variable <- cst are useless, but not - the other way around. */ - if (outer_min - && (!inner_min - || !tree_int_cst_equal (inner_min, outer_min))) - return false; - if (outer_max - && (!inner_max - || !tree_int_cst_equal (inner_max, outer_max))) - return false; - } - - /* Recurse on the element check. */ - return useless_type_conversion_p (TREE_TYPE (outer_type), - TREE_TYPE (inner_type)); - } - - else if ((TREE_CODE (inner_type) == FUNCTION_TYPE - || TREE_CODE (inner_type) == METHOD_TYPE) - && TREE_CODE (inner_type) == TREE_CODE (outer_type)) - { - tree outer_parm, inner_parm; - - /* If the return types are not compatible bail out. */ - if (!useless_type_conversion_p (TREE_TYPE (outer_type), - TREE_TYPE (inner_type))) - return false; - - /* Method types should belong to a compatible base class. */ - if (TREE_CODE (inner_type) == METHOD_TYPE - && !useless_type_conversion_p (TYPE_METHOD_BASETYPE (outer_type), - TYPE_METHOD_BASETYPE (inner_type))) - return false; - - /* A conversion to an unprototyped argument list is ok. */ - if (!prototype_p (outer_type)) - return true; - - /* If the unqualified argument types are compatible the conversion - is useless. */ - if (TYPE_ARG_TYPES (outer_type) == TYPE_ARG_TYPES (inner_type)) - return true; - - for (outer_parm = TYPE_ARG_TYPES (outer_type), - inner_parm = TYPE_ARG_TYPES (inner_type); - outer_parm && inner_parm; - outer_parm = TREE_CHAIN (outer_parm), - inner_parm = TREE_CHAIN (inner_parm)) - if (!useless_type_conversion_p - (TYPE_MAIN_VARIANT (TREE_VALUE (outer_parm)), - TYPE_MAIN_VARIANT (TREE_VALUE (inner_parm)))) - return false; - - /* If there is a mismatch in the number of arguments the functions - are not compatible. */ - if (outer_parm || inner_parm) - return false; - - /* Defer to the target if necessary. */ - if (TYPE_ATTRIBUTES (inner_type) || TYPE_ATTRIBUTES (outer_type)) - return comp_type_attributes (outer_type, inner_type) != 0; - - return true; - } - - /* For aggregates we rely on TYPE_CANONICAL exclusively and require - explicit conversions for types involving to be structurally - compared types. */ - else if (AGGREGATE_TYPE_P (inner_type) - && TREE_CODE (inner_type) == TREE_CODE (outer_type)) - return false; - - return false; - } - - /* Return true if a conversion from either type of TYPE1 and TYPE2 - to the other is not required. Otherwise return false. */ - - bool - types_compatible_p (tree type1, tree type2) - { - return (type1 == type2 - || (useless_type_conversion_p (type1, type2) - && useless_type_conversion_p (type2, type1))); - } - /* Dump bitmap SET (assumed to contain VAR_DECLs) to FILE. */ void --- 3302,3307 ---- *************** dump_decl_set (FILE *file, bitmap set) *** 4042,4086 **** fprintf (file, "NIL"); } - /* Given SSA_NAMEs NAME1 and NAME2, return true if they are candidates for - coalescing together, false otherwise. - - This must stay consistent with var_map_base_init in tree-ssa-live.c. */ - - bool - gimple_can_coalesce_p (tree name1, tree name2) - { - /* First check the SSA_NAME's associated DECL. We only want to - coalesce if they have the same DECL or both have no associated DECL. */ - tree var1 = SSA_NAME_VAR (name1); - tree var2 = SSA_NAME_VAR (name2); - var1 = (var1 && (!VAR_P (var1) || !DECL_IGNORED_P (var1))) ? var1 : NULL_TREE; - var2 = (var2 && (!VAR_P (var2) || !DECL_IGNORED_P (var2))) ? var2 : NULL_TREE; - if (var1 != var2) - return false; - - /* Now check the types. If the types are the same, then we should - try to coalesce V1 and V2. */ - tree t1 = TREE_TYPE (name1); - tree t2 = TREE_TYPE (name2); - if (t1 == t2) - return true; - - /* If the types are not the same, check for a canonical type match. This - (for example) allows coalescing when the types are fundamentally the - same, but just have different names. - - Note pointer types with different address spaces may have the same - canonical type. Those are rejected for coalescing by the - types_compatible_p check. */ - if (TYPE_CANONICAL (t1) - && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2) - && types_compatible_p (t1, t2)) - return true; - - return false; - } - /* Return true when CALL is a call stmt that definitely doesn't free any memory or makes it unavailable otherwise. */ bool --- 3326,3331 ---- *************** nonfreeing_call_p (gimple call) *** 4102,4125 **** return false; } - - /* Create a new VAR_DECL and copy information from VAR to it. */ - - tree - copy_var_decl (tree var, tree name, tree type) - { - tree copy = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, name, type); - - TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var); - TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var); - DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var); - DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var); - DECL_IGNORED_P (copy) = DECL_IGNORED_P (var); - DECL_CONTEXT (copy) = DECL_CONTEXT (var); - TREE_NO_WARNING (copy) = TREE_NO_WARNING (var); - TREE_USED (copy) = 1; - DECL_SEEN_IN_BIND_EXPR_P (copy) = 1; - DECL_ATTRIBUTES (copy) = DECL_ATTRIBUTES (var); - - return copy; - } --- 3347,3349 ---- Index: gimple-expr.c =================================================================== *** gimple-expr.c (revision 0) --- gimple-expr.c (working copy) *************** *** 0 **** --- 1,721 ---- + /* Gimple decl, type, and expression support functions. + + Copyright (C) 2007-2013 Free Software Foundation, Inc. + Contributed by Aldy Hernandez <aldyh@redhat.com> + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + + #include "config.h" + #include "system.h" + #include "coretypes.h" + #include "tm.h" + #include "tree.h" + #include "gimple.h" + #include "demangle.h" + + /* ----- Type related ----- */ + + /* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a + useless type conversion, otherwise return false. + + This function implicitly defines the middle-end type system. With + the notion of 'a < b' meaning that useless_type_conversion_p (a, b) + holds and 'a > b' meaning that useless_type_conversion_p (b, a) holds, + the following invariants shall be fulfilled: + + 1) useless_type_conversion_p is transitive. + If a < b and b < c then a < c. + + 2) useless_type_conversion_p is not symmetric. + From a < b does not follow a > b. + + 3) Types define the available set of operations applicable to values. + A type conversion is useless if the operations for the target type + is a subset of the operations for the source type. For example + casts to void* are useless, casts from void* are not (void* can't + be dereferenced or offsetted, but copied, hence its set of operations + is a strict subset of that of all other data pointer types). Casts + to const T* are useless (can't be written to), casts from const T* + to T* are not. */ + + bool + useless_type_conversion_p (tree outer_type, tree inner_type) + { + /* Do the following before stripping toplevel qualifiers. */ + if (POINTER_TYPE_P (inner_type) + && POINTER_TYPE_P (outer_type)) + { + /* Do not lose casts between pointers to different address spaces. */ + if (TYPE_ADDR_SPACE (TREE_TYPE (outer_type)) + != TYPE_ADDR_SPACE (TREE_TYPE (inner_type))) + return false; + } + + /* From now on qualifiers on value types do not matter. */ + inner_type = TYPE_MAIN_VARIANT (inner_type); + outer_type = TYPE_MAIN_VARIANT (outer_type); + + if (inner_type == outer_type) + return true; + + /* If we know the canonical types, compare them. */ + if (TYPE_CANONICAL (inner_type) + && TYPE_CANONICAL (inner_type) == TYPE_CANONICAL (outer_type)) + return true; + + /* Changes in machine mode are never useless conversions unless we + deal with aggregate types in which case we defer to later checks. */ + if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type) + && !AGGREGATE_TYPE_P (inner_type)) + return false; + + /* If both the inner and outer types are integral types, then the + conversion is not necessary if they have the same mode and + signedness and precision, and both or neither are boolean. */ + if (INTEGRAL_TYPE_P (inner_type) + && INTEGRAL_TYPE_P (outer_type)) + { + /* Preserve changes in signedness or precision. */ + if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type) + || TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type)) + return false; + + /* Preserve conversions to/from BOOLEAN_TYPE if types are not + of precision one. */ + if (((TREE_CODE (inner_type) == BOOLEAN_TYPE) + != (TREE_CODE (outer_type) == BOOLEAN_TYPE)) + && TYPE_PRECISION (outer_type) != 1) + return false; + + /* We don't need to preserve changes in the types minimum or + maximum value in general as these do not generate code + unless the types precisions are different. */ + return true; + } + + /* Scalar floating point types with the same mode are compatible. */ + else if (SCALAR_FLOAT_TYPE_P (inner_type) + && SCALAR_FLOAT_TYPE_P (outer_type)) + return true; + + /* Fixed point types with the same mode are compatible. */ + else if (FIXED_POINT_TYPE_P (inner_type) + && FIXED_POINT_TYPE_P (outer_type)) + return true; + + /* We need to take special care recursing to pointed-to types. */ + else if (POINTER_TYPE_P (inner_type) + && POINTER_TYPE_P (outer_type)) + { + /* Do not lose casts to function pointer types. */ + if ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE + || TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE) + && !(TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE + || TREE_CODE (TREE_TYPE (inner_type)) == METHOD_TYPE)) + return false; + + /* We do not care for const qualification of the pointed-to types + as const qualification has no semantic value to the middle-end. */ + + /* Otherwise pointers/references are equivalent. */ + return true; + } + + /* Recurse for complex types. */ + else if (TREE_CODE (inner_type) == COMPLEX_TYPE + && TREE_CODE (outer_type) == COMPLEX_TYPE) + return useless_type_conversion_p (TREE_TYPE (outer_type), + TREE_TYPE (inner_type)); + + /* Recurse for vector types with the same number of subparts. */ + else if (TREE_CODE (inner_type) == VECTOR_TYPE + && TREE_CODE (outer_type) == VECTOR_TYPE + && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type)) + return useless_type_conversion_p (TREE_TYPE (outer_type), + TREE_TYPE (inner_type)); + + else if (TREE_CODE (inner_type) == ARRAY_TYPE + && TREE_CODE (outer_type) == ARRAY_TYPE) + { + /* Preserve string attributes. */ + if (TYPE_STRING_FLAG (inner_type) != TYPE_STRING_FLAG (outer_type)) + return false; + + /* Conversions from array types with unknown extent to + array types with known extent are not useless. */ + if (!TYPE_DOMAIN (inner_type) + && TYPE_DOMAIN (outer_type)) + return false; + + /* Nor are conversions from array types with non-constant size to + array types with constant size or to different size. */ + if (TYPE_SIZE (outer_type) + && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST + && (!TYPE_SIZE (inner_type) + || TREE_CODE (TYPE_SIZE (inner_type)) != INTEGER_CST + || !tree_int_cst_equal (TYPE_SIZE (outer_type), + TYPE_SIZE (inner_type)))) + return false; + + /* Check conversions between arrays with partially known extents. + If the array min/max values are constant they have to match. + Otherwise allow conversions to unknown and variable extents. + In particular this declares conversions that may change the + mode to BLKmode as useless. */ + if (TYPE_DOMAIN (inner_type) + && TYPE_DOMAIN (outer_type) + && TYPE_DOMAIN (inner_type) != TYPE_DOMAIN (outer_type)) + { + tree inner_min = TYPE_MIN_VALUE (TYPE_DOMAIN (inner_type)); + tree outer_min = TYPE_MIN_VALUE (TYPE_DOMAIN (outer_type)); + tree inner_max = TYPE_MAX_VALUE (TYPE_DOMAIN (inner_type)); + tree outer_max = TYPE_MAX_VALUE (TYPE_DOMAIN (outer_type)); + + /* After gimplification a variable min/max value carries no + additional information compared to a NULL value. All that + matters has been lowered to be part of the IL. */ + if (inner_min && TREE_CODE (inner_min) != INTEGER_CST) + inner_min = NULL_TREE; + if (outer_min && TREE_CODE (outer_min) != INTEGER_CST) + outer_min = NULL_TREE; + if (inner_max && TREE_CODE (inner_max) != INTEGER_CST) + inner_max = NULL_TREE; + if (outer_max && TREE_CODE (outer_max) != INTEGER_CST) + outer_max = NULL_TREE; + + /* Conversions NULL / variable <- cst are useless, but not + the other way around. */ + if (outer_min + && (!inner_min + || !tree_int_cst_equal (inner_min, outer_min))) + return false; + if (outer_max + && (!inner_max + || !tree_int_cst_equal (inner_max, outer_max))) + return false; + } + + /* Recurse on the element check. */ + return useless_type_conversion_p (TREE_TYPE (outer_type), + TREE_TYPE (inner_type)); + } + + else if ((TREE_CODE (inner_type) == FUNCTION_TYPE + || TREE_CODE (inner_type) == METHOD_TYPE) + && TREE_CODE (inner_type) == TREE_CODE (outer_type)) + { + tree outer_parm, inner_parm; + + /* If the return types are not compatible bail out. */ + if (!useless_type_conversion_p (TREE_TYPE (outer_type), + TREE_TYPE (inner_type))) + return false; + + /* Method types should belong to a compatible base class. */ + if (TREE_CODE (inner_type) == METHOD_TYPE + && !useless_type_conversion_p (TYPE_METHOD_BASETYPE (outer_type), + TYPE_METHOD_BASETYPE (inner_type))) + return false; + + /* A conversion to an unprototyped argument list is ok. */ + if (!prototype_p (outer_type)) + return true; + + /* If the unqualified argument types are compatible the conversion + is useless. */ + if (TYPE_ARG_TYPES (outer_type) == TYPE_ARG_TYPES (inner_type)) + return true; + + for (outer_parm = TYPE_ARG_TYPES (outer_type), + inner_parm = TYPE_ARG_TYPES (inner_type); + outer_parm && inner_parm; + outer_parm = TREE_CHAIN (outer_parm), + inner_parm = TREE_CHAIN (inner_parm)) + if (!useless_type_conversion_p + (TYPE_MAIN_VARIANT (TREE_VALUE (outer_parm)), + TYPE_MAIN_VARIANT (TREE_VALUE (inner_parm)))) + return false; + + /* If there is a mismatch in the number of arguments the functions + are not compatible. */ + if (outer_parm || inner_parm) + return false; + + /* Defer to the target if necessary. */ + if (TYPE_ATTRIBUTES (inner_type) || TYPE_ATTRIBUTES (outer_type)) + return comp_type_attributes (outer_type, inner_type) != 0; + + return true; + } + + /* For aggregates we rely on TYPE_CANONICAL exclusively and require + explicit conversions for types involving to be structurally + compared types. */ + else if (AGGREGATE_TYPE_P (inner_type) + && TREE_CODE (inner_type) == TREE_CODE (outer_type)) + return false; + + return false; + } + + + /* ----- Decl related ----- */ + + /* Set sequence SEQ to be the GIMPLE body for function FN. */ + + void + gimple_set_body (tree fndecl, gimple_seq seq) + { + struct function *fn = DECL_STRUCT_FUNCTION (fndecl); + if (fn == NULL) + { + /* If FNDECL still does not have a function structure associated + with it, then it does not make sense for it to receive a + GIMPLE body. */ + gcc_assert (seq == NULL); + } + else + fn->gimple_body = seq; + } + + + /* Return the body of GIMPLE statements for function FN. After the + CFG pass, the function body doesn't exist anymore because it has + been split up into basic blocks. In this case, it returns + NULL. */ + + gimple_seq + gimple_body (tree fndecl) + { + struct function *fn = DECL_STRUCT_FUNCTION (fndecl); + return fn ? fn->gimple_body : NULL; + } + + /* Return true when FNDECL has Gimple body either in unlowered + or CFG form. */ + bool + gimple_has_body_p (tree fndecl) + { + struct function *fn = DECL_STRUCT_FUNCTION (fndecl); + return (gimple_body (fndecl) || (fn && fn->cfg)); + } + + /* Return a printable name for symbol DECL. */ + + const char * + gimple_decl_printable_name (tree decl, int verbosity) + { + if (!DECL_NAME (decl)) + return NULL; + + if (DECL_ASSEMBLER_NAME_SET_P (decl)) + { + const char *str, *mangled_str; + int dmgl_opts = DMGL_NO_OPTS; + + if (verbosity >= 2) + { + dmgl_opts = DMGL_VERBOSE + | DMGL_ANSI + | DMGL_GNU_V3 + | DMGL_RET_POSTFIX; + if (TREE_CODE (decl) == FUNCTION_DECL) + dmgl_opts |= DMGL_PARAMS; + } + + mangled_str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + str = cplus_demangle_v3 (mangled_str, dmgl_opts); + return (str) ? str : mangled_str; + } + + return IDENTIFIER_POINTER (DECL_NAME (decl)); + } + + + /* Create a new VAR_DECL and copy information from VAR to it. */ + + tree + copy_var_decl (tree var, tree name, tree type) + { + tree copy = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, name, type); + + TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var); + TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var); + DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var); + DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var); + DECL_IGNORED_P (copy) = DECL_IGNORED_P (var); + DECL_CONTEXT (copy) = DECL_CONTEXT (var); + TREE_NO_WARNING (copy) = TREE_NO_WARNING (var); + TREE_USED (copy) = 1; + DECL_SEEN_IN_BIND_EXPR_P (copy) = 1; + DECL_ATTRIBUTES (copy) = DECL_ATTRIBUTES (var); + + return copy; + } + + /* Given SSA_NAMEs NAME1 and NAME2, return true if they are candidates for + coalescing together, false otherwise. + + This must stay consistent with var_map_base_init in tree-ssa-live.c. */ + + bool + gimple_can_coalesce_p (tree name1, tree name2) + { + /* First check the SSA_NAME's associated DECL. We only want to + coalesce if they have the same DECL or both have no associated DECL. */ + tree var1 = SSA_NAME_VAR (name1); + tree var2 = SSA_NAME_VAR (name2); + var1 = (var1 && (!VAR_P (var1) || !DECL_IGNORED_P (var1))) ? var1 : NULL_TREE; + var2 = (var2 && (!VAR_P (var2) || !DECL_IGNORED_P (var2))) ? var2 : NULL_TREE; + if (var1 != var2) + return false; + + /* Now check the types. If the types are the same, then we should + try to coalesce V1 and V2. */ + tree t1 = TREE_TYPE (name1); + tree t2 = TREE_TYPE (name2); + if (t1 == t2) + return true; + + /* If the types are not the same, check for a canonical type match. This + (for example) allows coalescing when the types are fundamentally the + same, but just have different names. + + Note pointer types with different address spaces may have the same + canonical type. Those are rejected for coalescing by the + types_compatible_p check. */ + if (TYPE_CANONICAL (t1) + && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2) + && types_compatible_p (t1, t2)) + return true; + + return false; + } + + + /* ----- Expression related ----- */ + + /* Extract the operands and code for expression EXPR into *SUBCODE_P, + *OP1_P, *OP2_P and *OP3_P respectively. */ + + void + extract_ops_from_tree_1 (tree expr, enum tree_code *subcode_p, tree *op1_p, + tree *op2_p, tree *op3_p) + { + enum gimple_rhs_class grhs_class; + + *subcode_p = TREE_CODE (expr); + grhs_class = get_gimple_rhs_class (*subcode_p); + + if (grhs_class == GIMPLE_TERNARY_RHS) + { + *op1_p = TREE_OPERAND (expr, 0); + *op2_p = TREE_OPERAND (expr, 1); + *op3_p = TREE_OPERAND (expr, 2); + } + else if (grhs_class == GIMPLE_BINARY_RHS) + { + *op1_p = TREE_OPERAND (expr, 0); + *op2_p = TREE_OPERAND (expr, 1); + *op3_p = NULL_TREE; + } + else if (grhs_class == GIMPLE_UNARY_RHS) + { + *op1_p = TREE_OPERAND (expr, 0); + *op2_p = NULL_TREE; + *op3_p = NULL_TREE; + } + else if (grhs_class == GIMPLE_SINGLE_RHS) + { + *op1_p = expr; + *op2_p = NULL_TREE; + *op3_p = NULL_TREE; + } + else + gcc_unreachable (); + } + + /* Extract operands for a GIMPLE_COND statement out of COND_EXPR tree COND. */ + + void + gimple_cond_get_ops_from_tree (tree cond, enum tree_code *code_p, + tree *lhs_p, tree *rhs_p) + { + gcc_assert (TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison + || TREE_CODE (cond) == TRUTH_NOT_EXPR + || is_gimple_min_invariant (cond) + || SSA_VAR_P (cond)); + + extract_ops_from_tree (cond, code_p, lhs_p, rhs_p); + + /* Canonicalize conditionals of the form 'if (!VAL)'. */ + if (*code_p == TRUTH_NOT_EXPR) + { + *code_p = EQ_EXPR; + gcc_assert (*lhs_p && *rhs_p == NULL_TREE); + *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p)); + } + /* Canonicalize conditionals of the form 'if (VAL)' */ + else if (TREE_CODE_CLASS (*code_p) != tcc_comparison) + { + *code_p = NE_EXPR; + gcc_assert (*lhs_p && *rhs_p == NULL_TREE); + *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p)); + } + } + + /* Return true if T is a valid LHS for a GIMPLE assignment expression. */ + + bool + is_gimple_lvalue (tree t) + { + return (is_gimple_addressable (t) + || TREE_CODE (t) == WITH_SIZE_EXPR + /* These are complex lvalues, but don't have addresses, so they + go here. */ + || TREE_CODE (t) == BIT_FIELD_REF); + } + + /* Return true if T is a GIMPLE condition. */ + + bool + is_gimple_condexpr (tree t) + { + return (is_gimple_val (t) || (COMPARISON_CLASS_P (t) + && !tree_could_throw_p (t) + && is_gimple_val (TREE_OPERAND (t, 0)) + && is_gimple_val (TREE_OPERAND (t, 1)))); + } + + /* Return true if T is a gimple address. */ + + bool + is_gimple_address (const_tree t) + { + tree op; + + if (TREE_CODE (t) != ADDR_EXPR) + return false; + + op = TREE_OPERAND (t, 0); + while (handled_component_p (op)) + { + if ((TREE_CODE (op) == ARRAY_REF + || TREE_CODE (op) == ARRAY_RANGE_REF) + && !is_gimple_val (TREE_OPERAND (op, 1))) + return false; + + op = TREE_OPERAND (op, 0); + } + + if (CONSTANT_CLASS_P (op) || TREE_CODE (op) == MEM_REF) + return true; + + switch (TREE_CODE (op)) + { + case PARM_DECL: + case RESULT_DECL: + case LABEL_DECL: + case FUNCTION_DECL: + case VAR_DECL: + case CONST_DECL: + return true; + + default: + return false; + } + } + + /* Return true if T is a gimple invariant address. */ + + bool + is_gimple_invariant_address (const_tree t) + { + const_tree op; + + if (TREE_CODE (t) != ADDR_EXPR) + return false; + + op = strip_invariant_refs (TREE_OPERAND (t, 0)); + if (!op) + return false; + + if (TREE_CODE (op) == MEM_REF) + { + const_tree op0 = TREE_OPERAND (op, 0); + return (TREE_CODE (op0) == ADDR_EXPR + && (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)) + || decl_address_invariant_p (TREE_OPERAND (op0, 0)))); + } + + return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op); + } + + /* Return true if T is a gimple invariant address at IPA level + (so addresses of variables on stack are not allowed). */ + + bool + is_gimple_ip_invariant_address (const_tree t) + { + const_tree op; + + if (TREE_CODE (t) != ADDR_EXPR) + return false; + + op = strip_invariant_refs (TREE_OPERAND (t, 0)); + if (!op) + return false; + + if (TREE_CODE (op) == MEM_REF) + { + const_tree op0 = TREE_OPERAND (op, 0); + return (TREE_CODE (op0) == ADDR_EXPR + && (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)) + || decl_address_ip_invariant_p (TREE_OPERAND (op0, 0)))); + } + + return CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op); + } + + /* Return true if T is a GIMPLE minimal invariant. It's a restricted + form of function invariant. */ + + bool + is_gimple_min_invariant (const_tree t) + { + if (TREE_CODE (t) == ADDR_EXPR) + return is_gimple_invariant_address (t); + + return is_gimple_constant (t); + } + + /* Return true if T is a GIMPLE interprocedural invariant. It's a restricted + form of gimple minimal invariant. */ + + bool + is_gimple_ip_invariant (const_tree t) + { + if (TREE_CODE (t) == ADDR_EXPR) + return is_gimple_ip_invariant_address (t); + + return is_gimple_constant (t); + } + + /* Return true if T is a non-aggregate register variable. */ + + bool + is_gimple_reg (tree t) + { + if (virtual_operand_p (t)) + return false; + + if (TREE_CODE (t) == SSA_NAME) + return true; + + if (!is_gimple_variable (t)) + return false; + + if (!is_gimple_reg_type (TREE_TYPE (t))) + return false; + + /* A volatile decl is not acceptable because we can't reuse it as + needed. We need to copy it into a temp first. */ + if (TREE_THIS_VOLATILE (t)) + return false; + + /* We define "registers" as things that can be renamed as needed, + which with our infrastructure does not apply to memory. */ + if (needs_to_live_in_memory (t)) + return false; + + /* Hard register variables are an interesting case. For those that + are call-clobbered, we don't know where all the calls are, since + we don't (want to) take into account which operations will turn + into libcalls at the rtl level. For those that are call-saved, + we don't currently model the fact that calls may in fact change + global hard registers, nor do we examine ASM_CLOBBERS at the tree + level, and so miss variable changes that might imply. All around, + it seems safest to not do too much optimization with these at the + tree level at all. We'll have to rely on the rtl optimizers to + clean this up, as there we've got all the appropriate bits exposed. */ + if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)) + return false; + + /* Complex and vector values must have been put into SSA-like form. + That is, no assignments to the individual components. */ + if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE + || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE) + return DECL_GIMPLE_REG_P (t); + + return true; + } + + + /* Return true if T is a GIMPLE rvalue, i.e. an identifier or a constant. */ + + bool + is_gimple_val (tree t) + { + /* Make loads from volatiles and memory vars explicit. */ + if (is_gimple_variable (t) + && is_gimple_reg_type (TREE_TYPE (t)) + && !is_gimple_reg (t)) + return false; + + return (is_gimple_variable (t) || is_gimple_min_invariant (t)); + } + + /* Similarly, but accept hard registers as inputs to asm statements. */ + + bool + is_gimple_asm_val (tree t) + { + if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)) + return true; + + return is_gimple_val (t); + } + + /* Return true if T is a GIMPLE minimal lvalue. */ + + bool + is_gimple_min_lval (tree t) + { + if (!(t = CONST_CAST_TREE (strip_invariant_refs (t)))) + return false; + return (is_gimple_id (t) || TREE_CODE (t) == MEM_REF); + } + + /* Return true if T is a valid function operand of a CALL_EXPR. */ + + bool + is_gimple_call_addr (tree t) + { + return (TREE_CODE (t) == OBJ_TYPE_REF || is_gimple_val (t)); + } + + /* Return true if T is a valid address operand of a MEM_REF. */ + + bool + is_gimple_mem_ref_addr (tree t) + { + return (is_gimple_reg (t) + || TREE_CODE (t) == INTEGER_CST + || (TREE_CODE (t) == ADDR_EXPR + && (CONSTANT_CLASS_P (TREE_OPERAND (t, 0)) + || decl_address_invariant_p (TREE_OPERAND (t, 0))))); + } Index: Makefile.in =================================================================== *** Makefile.in (revision 204350) --- Makefile.in (working copy) *************** OBJS = \ *** 1230,1235 **** --- 1230,1236 ---- ggc-common.o \ gimple.o \ gimple-builder.o \ + gimple-expr.o \ gimple-iterator.o \ gimple-fold.o \ gimple-low.o \ ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [patch] Create gimple-expr..[ch] ... was Re: RFC: gimple.[ch] break apart 2013-11-05 16:58 ` [patch] Create gimple-expr..[ch] ... was Re: RFC: gimple.[ch] break apart Andrew MacLeod @ 2013-11-05 17:52 ` Jeff Law 2013-11-07 10:58 ` Basile Starynkevitch 1 sibling, 0 replies; 116+ messages in thread From: Jeff Law @ 2013-11-05 17:52 UTC (permalink / raw) To: Andrew MacLeod, gcc-patches, Richard Biener, Diego Novillo On 11/05/13 09:26, Andrew MacLeod wrote: > On 10/30/2013 11:18 PM, Andrew MacLeod wrote: >> >> >> As a result, any gimple queries regarding types, decls, or expressions >> are actually tree queries. They are sprinkled throughout gimple.[ch] and >> gimplify.[ch], not to mention tree.[ch] as well as other parts of the >> compiler where they happened to be needed. This has caused various >> ordering issues among the inline functions when I tried to split out the >> stmt, iterator, and gimplification bits from gimple.[ch]. Not to >> mention a lack of an obvious home for some of these functions. >> >> I'd like to move these as I encounter them into a new file, >> gimple-decl.[ch]. When I'm working on the other gimple classes, this >> will be further split into gimple-decl, gimple-type and gimple-expr as >> appropriate but it seems reasonable to create just the one file now to >> clump them since there is no other formal organization. So any function >> which is actually querying/setting/building a decl, type, or expression >> for gimple would go here. > > I decided to name the new file gimple-expr.[ch] instead of > gimple-decl.... This will eventually split into gimple-type.[ch], > gimple-decl.[ch], and gimple-expr.[ch]. I could split them that way now > if desired, but isn't critical yet. maybe I should just do that... > Anyway, of the 3 files, gimple-expr will depend on the other 2, and thus > is likely to be the one #included in places like the rtl generation > files that need access to all these gimple dictionary/expression > routines. (eventually those rtl files will include only gimple-expr.h > and not tree.h :-). > > In any case, I had to do this split from gimple.h first since > gimple-stmt.[ch] and the others require some of these basic routines, > and I can't split anything else out first without then getting an > include dependency cycle between gimple.h and gimple-stmt.h for > instance. This way gimple-stmt.h can include gimple-expr.h, and then > gimple.h can include gimpe-stmt.h and no chicken/egg situation. > > This contains just the functions that are in either in, or prototyped > in, gimple.h, and is just the first cut. There are more things that > will eventually get put here from gimple.c, but their prototypes are in > places like tree.h and more include cycles or poor requirements on files > to include are exposed if I move them now since front ends or rtl files > are using those routines (like get_base_address). There are also a few > I wanted to hold off on and see how things work out before moving them. > > In any case, I tried to pull out the functions that operated on trees > currently and performed an operation on a type, decl, or expression. My > litmus test was usually, "Is this liekly going to be a method of a type, > decl or expr class relating to the object itself." and moved it if it > seemed so. > > The slightly iffier ones were extract_ops_from_tree*() and > gimple_cond_get_ops_from_tree()... Those clearly worked on expressions > and not statements, but are utilized in places like rtl land that don't > deal with stmts... so they need to be exposed via the expression > processing and interface. Its also quite possible those will end up in > gimplify.[ch] once I get that far... > > I do expect there will still be a little bit of fine tuning, but this is > the first cut to enable me to split out gimple-stmts.[ch] next. > > Bootstraps on x86_64-unknown-linux-gnu with no new regressions. OK? OK. jeff ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [patch] Create gimple-expr..[ch] ... was Re: RFC: gimple.[ch] break apart 2013-11-05 16:58 ` [patch] Create gimple-expr..[ch] ... was Re: RFC: gimple.[ch] break apart Andrew MacLeod 2013-11-05 17:52 ` Jeff Law @ 2013-11-07 10:58 ` Basile Starynkevitch 2013-11-07 13:47 ` Andrew MacLeod 1 sibling, 1 reply; 116+ messages in thread From: Basile Starynkevitch @ 2013-11-07 10:58 UTC (permalink / raw) To: Andrew MacLeod; +Cc: gcc-patches, Richard Biener, Jeff Law, Diego Novillo On Tue, Nov 05, 2013 at 11:26:46AM -0500, Andrew MacLeod wrote: > > I decided to name the new file gimple-expr.[ch] instead of > gimple-decl.... This will eventually split into gimple-type.[ch], > gimple-decl.[ch], and gimple-expr.[ch]. Since we are adding *new* C++ files, can't we please name them *.cc for the implementation part, so at least create gimple-expr.h and gimple-expr.cc but not gimple-expr.c, please! There are some reasons to keep existing *.c files containing C++ code (IMHO the reasons are bad ones, and related to poor habits and to deficiencies in the version control system we have to use, but I really don't want to open that debate again). But for **NEW** files which are definitely in C++, I don't understand why they should be named .c files; this is confusing for all (and, for instance, when compiling them with Clang we are getting -IMHO rightly- some warnings about the file naming). If I remember well, there have been (in the discussion about naming C++ source files of GCC) a suggestion (and perhaps even a consensus), probably by Diego Novillo, to name *.cc our new files which are in C++. Having old C++ files named *.c is already a big frustration (most editors are by default configured to handle them as C, not as C++, files and most developers, notably newbies to GCC contributions, are expecting them to be C files not C++ ones). But IMHO having new source files inside GCC coded in C++ with a *.c file extension is non-sense; such files should have a .cc (or maybe .cpp or .cxx) extension, not a .c extension. Regards. -- Basile STARYNKEVITCH http://starynkevitch.net/Basile/ email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359 8, rue de la Faiencerie, 92340 Bourg La Reine, France *** opinions {are only mines, sont seulement les miennes} *** ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [patch] Create gimple-expr..[ch] ... was Re: RFC: gimple.[ch] break apart 2013-11-07 10:58 ` Basile Starynkevitch @ 2013-11-07 13:47 ` Andrew MacLeod 2013-11-07 18:13 ` Diego Novillo 0 siblings, 1 reply; 116+ messages in thread From: Andrew MacLeod @ 2013-11-07 13:47 UTC (permalink / raw) To: Basile Starynkevitch; +Cc: gcc-patches, Richard Biener, Jeff Law, Diego Novillo On 11/07/2013 05:36 AM, Basile Starynkevitch wrote: > On Tue, Nov 05, 2013 at 11:26:46AM -0500, Andrew MacLeod wrote: >> I decided to name the new file gimple-expr.[ch] instead of >> gimple-decl.... This will eventually split into gimple-type.[ch], >> gimple-decl.[ch], and gimple-expr.[ch]. > > Since we are adding *new* C++ files, can't we please name them *.cc > for the implementation part, so at least create gimple-expr.h and > gimple-expr.cc but not gimple-expr.c, please! Assuming we put this into stage 1 next year, I would imagine we'd rename a number of things, including .cc, drop the tree-* from the tree-ssa-blah.[c]h files, etc etc. There have been a few things people have suggested renaming... I think if we do renaming, they ought to be all at one time to minimize the pain. At the moment, the new gimple-* files I'm creating are still C, so they are .c files... Andrew ^ permalink raw reply [flat|nested] 116+ messages in thread
* Re: [patch] Create gimple-expr..[ch] ... was Re: RFC: gimple.[ch] break apart 2013-11-07 13:47 ` Andrew MacLeod @ 2013-11-07 18:13 ` Diego Novillo 0 siblings, 0 replies; 116+ messages in thread From: Diego Novillo @ 2013-11-07 18:13 UTC (permalink / raw) To: Andrew MacLeod Cc: Basile Starynkevitch, gcc-patches, Richard Biener, Jeff Law On Thu, Nov 7, 2013 at 8:23 AM, Andrew MacLeod <amacleod@redhat.com> wrote: > On 11/07/2013 05:36 AM, Basile Starynkevitch wrote: >> >> On Tue, Nov 05, 2013 at 11:26:46AM -0500, Andrew MacLeod wrote: >>> >>> I decided to name the new file gimple-expr.[ch] instead of >>> gimple-decl.... This will eventually split into gimple-type.[ch], >>> gimple-decl.[ch], and gimple-expr.[ch]. >> >> >> Since we are adding *new* C++ files, can't we please name them *.cc >> for the implementation part, so at least create gimple-expr.h and >> gimple-expr.cc but not gimple-expr.c, please! > > Assuming we put this into stage 1 next year, I would imagine we'd rename a > number of things, including .cc, drop the tree-* from the tree-ssa-blah.[c]h > files, etc etc. There have been a few things people have suggested > renaming... I think if we do renaming, they ought to be all at one time to > minimize the pain. > > At the moment, the new gimple-* files I'm creating are still C, so they are > .c files... Agreed. When we start shuffling files around seems a better time. Doing both operations at once will be easier than going through two phases of naming changes. Diego. ^ permalink raw reply [flat|nested] 116+ messages in thread
end of thread, other threads:[~2014-07-29 8:07 UTC | newest] Thread overview: 116+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-10-31 5:45 RFC: gimple.[ch] break apart Andrew MacLeod 2013-10-31 6:15 ` Jeff Law 2013-10-31 16:41 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) David Malcolm 2013-10-31 16:27 ` [PATCH 2/6] Hand-written port of various accessors within gimple.h David Malcolm 2013-11-14 9:53 ` Jeff Law 2013-10-31 16:27 ` [PATCH 4/6] Implement is_a_helper <>::test specializations for various gimple types David Malcolm 2013-11-14 9:41 ` Jeff Law 2013-11-18 19:51 ` David Malcolm 2013-11-18 20:10 ` Andrew MacLeod 2013-11-18 20:15 ` Jeff Law 2013-10-31 16:27 ` [PATCH 1/6] Convert gimple types from a union to C++ inheritance David Malcolm 2013-11-14 23:00 ` Jeff Law 2013-11-19 0:22 ` David Malcolm 2013-11-19 8:49 ` Jeff Law 2013-10-31 16:31 ` [PATCH 3/6] Automated part of conversion of gimple types to use " David Malcolm 2013-11-14 9:43 ` Jeff Law 2013-11-18 22:17 ` [PATCH] Updated automated patch (was Re: [PATCH 3/6] Automated part of conversion of gimple types to use C++ inheritance) David Malcolm 2013-11-19 8:49 ` Jeff Law 2013-11-19 16:36 ` David Malcolm 2013-11-22 0:27 ` Jakub Jelinek 2013-11-22 0:35 ` Jeff Law 2013-11-22 1:51 ` Jakub Jelinek 2013-11-22 2:52 ` Andrew MacLeod 2013-11-22 3:48 ` David Malcolm 2013-11-25 18:09 ` [PATCH] Fix checking of gimple types David Malcolm 2013-11-25 18:42 ` Michael Matz 2013-11-25 22:18 ` Jeff Law 2013-11-27 8:54 ` David Malcolm 2014-07-23 13:16 ` Thomas Schwinge 2014-07-24 1:50 ` David Malcolm 2014-07-29 8:11 ` Thomas Schwinge 2013-10-31 16:46 ` [PATCH 6/6] Update gdb hooks to reflect changes to " David Malcolm 2013-11-14 9:10 ` Jeff Law 2013-10-31 16:49 ` [PATCH 5/6] Port various places from union access to subclass access David Malcolm 2013-11-14 9:23 ` Jeff Law 2013-11-19 0:52 ` David Malcolm 2013-10-31 18:43 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) Basile Starynkevitch 2013-11-01 21:36 ` Andrew MacLeod 2013-11-01 21:41 ` Jakub Jelinek 2013-11-01 21:47 ` Andrew MacLeod 2013-11-01 21:57 ` Jakub Jelinek 2013-11-01 22:58 ` David Malcolm 2013-11-04 13:23 ` Andrew MacLeod 2013-11-04 21:52 ` David Malcolm 2013-11-04 22:09 ` David Malcolm 2013-11-04 22:31 ` Andrew MacLeod 2013-11-05 21:27 ` Jeff Law 2013-11-04 22:43 ` Andrew MacLeod 2013-11-04 22:28 ` Jakub Jelinek 2013-11-04 22:49 ` Andrew MacLeod 2013-11-05 21:09 ` Jeff Law 2013-11-05 11:53 ` Richard Biener 2013-11-05 12:33 ` David Malcolm 2013-11-05 12:52 ` Richard Biener 2013-11-04 14:00 ` Andrew MacLeod 2013-11-04 14:01 ` Jakub Jelinek 2013-11-04 14:15 ` Andrew MacLeod 2013-11-04 18:23 ` Jeff Law 2013-11-01 22:43 ` David Malcolm 2013-11-01 23:43 ` Trevor Saunders 2013-11-04 13:15 ` Andrew MacLeod 2013-11-05 17:23 ` [PATCH] Add gimple subclasses for every gimple code (was Re: [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3)) David Malcolm 2013-11-06 16:53 ` Michael Matz 2013-11-07 6:19 ` David Malcolm 2013-11-07 7:08 ` Jeff Law 2013-11-08 19:23 ` David Malcolm 2013-11-14 8:38 ` Jeff Law 2013-11-14 15:06 ` Michael Matz 2013-11-14 18:32 ` David Malcolm 2013-11-15 2:49 ` Jeff Law 2013-11-07 14:57 ` Michael Matz 2013-11-08 0:07 ` Alec Teal 2013-11-08 14:31 ` Michael Matz 2013-11-05 18:22 ` [PATCH 0/6] Conversion of gimple types to C++ inheritance (v3) Andrew MacLeod 2013-11-05 21:33 ` Jeff Law 2013-11-05 22:01 ` David Malcolm 2013-11-05 22:17 ` Jeff Law 2013-11-06 1:14 ` Ian Lance Taylor 2013-11-06 20:49 ` Jeff Law 2013-11-06 20:57 ` Trevor Saunders 2013-11-05 22:24 ` Andrew MacLeod 2013-11-05 22:12 ` Andrew MacLeod 2013-11-06 9:37 ` Richard Biener 2013-11-06 11:20 ` Bernd Schmidt 2013-11-06 11:43 ` Richard Biener 2013-11-06 11:53 ` Jakub Jelinek 2013-11-06 13:14 ` Richard Biener 2013-11-06 13:23 ` Jakub Jelinek 2013-11-06 16:42 ` David Malcolm 2013-11-06 16:55 ` Jakub Jelinek 2013-11-06 18:34 ` Tom Tromey 2013-11-06 19:15 ` Jeff Law 2013-11-06 20:05 ` Tom Tromey 2013-11-06 20:45 ` Jeff Law 2013-11-06 13:31 ` Joseph S. Myers 2013-11-06 21:25 ` Jeff Law 2013-11-06 21:09 ` Jeff Law 2013-11-06 12:42 ` Bernd Schmidt 2013-11-06 21:04 ` Jeff Law 2013-11-06 21:06 ` Andrew MacLeod 2013-11-06 21:52 ` Jeff Law 2013-11-07 10:29 ` Richard Biener 2013-11-07 14:01 ` Joseph S. Myers 2013-11-07 14:42 ` Richard Biener 2013-11-07 14:53 ` Andrew MacLeod 2013-11-10 12:35 ` Richard Sandiford 2013-11-10 15:27 ` Richard Biener 2013-11-06 11:56 ` Eric Botcazou 2013-11-06 20:51 ` Jeff Law 2013-11-06 21:26 ` Jeff Law 2013-11-14 8:40 ` Jeff Law 2013-11-05 16:58 ` [patch] Create gimple-expr..[ch] ... was Re: RFC: gimple.[ch] break apart Andrew MacLeod 2013-11-05 17:52 ` Jeff Law 2013-11-07 10:58 ` Basile Starynkevitch 2013-11-07 13:47 ` Andrew MacLeod 2013-11-07 18:13 ` Diego Novillo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).