Re: Named parameters
On 16/03/15 17:34, Marc Glisse wrote: > On Mon, 16 Mar 2015, David Brown wrote: > >> In a discussion on comp.lang.c, the subject of "named parameters" (or >> "designated parameters") has come up again. This is a feature that some >> of us feel would be very useful in C (and in C++). I think it would be >> possible to include it in the language without leading to any conflicts >> with existing code - it is therefore something that could be made as a >> gcc extension, with a hope of adding it to the standards for a later C >> standards revision. >> >> I wanted to ask opinions on the mailing list as to the feasibility of >> the idea - there is little point in my cluttering up bugzilla with an >> enhancement request if the gcc developers can spot obvious flaws in the >> idea. > > Filing a report in bugzilla would be quite useless: language extensions > are now almost automatically rejected unless they come with a proposal > that has already been favorably seen by the standardization committee. > I'm glad I asked here first! Another poster has told me that the C++ committee rejected the idea - even though Mozilla's proposal was for C++ and slightly different syntax, the same justification for rejection would apply to my suggested syntax. > On the other hand, implementing the feature (in your own fork) is almost > a requirement if you intend to propose this for standardization. And it > should not be too hard. Certainly for the simplified version (where re-ordering is not allowed, and code generation is not affected), it should be a relatively small task. However, for the way I work, I use multiple different gcc versions and builds for different embedded targets - keeping separate forks would not be feasible. The only point of working on this in a fork would be with the aim of integrating it into mainline gcc - and it sounds like that is not going to happen. A possibility would be to use a MELT plugin - that would be a little more flexible. > >> Basically, the idea is this: >> >> int foo(int a, int b, int c); >> >> void bar(void) { >> foo(1, 2, 3);// Normal call >> foo(.a = 1, .b = 2, .c = 3)// Same as foo(1, 2, 3) >> foo(.c = 3, .b = 2, .a = 1)// Same as foo(1, 2, 3) >> } > > struct foo_args { > int a, b, c; > }; > void foo(struct foo_args); > #define foo(...) foo((struct foo_args){__VA_ARGS__}) > void g(){ > foo(1,2,3); > foo(.c=3,.b=2); > } That has two main disadvantages. First, because the argument is in a struct, it is going to be harder or impossible for the compiler to generate equally good code (for some of my uses, the difference between passing arguments in registers and passing as a struct on the stack is very significant). And secondly, it would require a wrapper macro for each function, rather than merely a prototype with parameter names (which are typically already there in existing code). But it is certainly a possibility for functions with particularly large numbers of arguments. > > In C++ you could almost get away without the macro, calling f({1,2,3}), > but f({.c=3}) currently gives "sorry, unimplemented". Maybe you would > like to work on that? > >> If only the first variant is allowed (with the named parameters in the >> order declared in the prototype), then this would not affect code >> generation at all - the designators could only be used for static error >> checking. >> >> If the second variant is allowed, then the parameters could be >> re-ordered. >> >> >> The aim of this is to make it easier and safer to call functions with a >> large number of parameters. The syntax is chosen to match that of >> designated initialisers - that should be clearer to the programmer, and >> hopefully also make implementation easier. >> >> If there is more than one declaration of the function, then the >> designators used should follow the most recent in-scope declaration. > > An error may be safer, you would at least want a warning. I'd be happy with that - I like to keep my prototypes consistent. But I know that some people are more flexible. > >> This feature could be particularly useful when combined with default >> arguments in C++, as it would allow the programmer to override later >> default arguments without specifying all earlier arguments. > > C++ is always more complicated (so many features can interact in strange > ways), I suggest you start with C. > >> At the moment, I am not asking for an implementation, or even /how/ it >> might be implemented (perhaps a MELT plugin?) - I would merely like >> opinions on whether it would be a useful and practical enhancement. > > This is not such a good list for that, comp.lang.c is better suited. > This will be a good list if you have technical issues implementing the > feature. > We've discussed it a little in comp.lang.c already, and of those who expressed an opinion, most were positive to the idea. But c.l.c. is for people who /use/ compilers - this mailing list has people who /write/ com
Unintended variable renaming in SSA replacement table
Hi, I have a problem with a transformation pass I wrote. The pass is meant to pipeline and unroll lookups in linked lists. After my pass is run, gcc renames a variable, which leads to wrong results. Part of my pass's dump, which is as I want it. ... : list_38 = list_10->next; _22 = list_10->info; _36 = _22->idx; if (_5 != _36) goto ; else goto ; : goto ; : # list_13 = PHI ... Corresponding part of the following pass. (list_join.c.148t.fab1) .. SSA replacement table N_i -> { O_1 ... O_j } means that N_i replaces O_1, ..., O_j _1 -> { _17 } _12 -> { _16 } _14 -> { _18 } _22 -> { _7 } _25 -> { _19 } _36 -> { _8 } list_38 -> { list_10 } list_41 -> { list_15 } _42 -> { _20 } ... : list_38 = list_10->next; _22 = list_38->info; _36 = _22->idx; if (_5 != _36) goto ; else goto ; : goto ; : # list_13 = PHI ... As you can see, gcc renames list_10 to list_38 in two places, which is not what I want. Why does gcc think this is possible. It seems to me that I need to update some data structure which I don't know of. What am I missing? I already did an updated_stmt in the places where I edit gimple statements. If I specify TODO_update_ssa, the same renaming already takes place in my pass. bb 19 is a copy of another basic block, maybe this is of relevance. Thank you and best regards, Benedikt signature.asc Description: Message signed with OpenPGP using GPGMail
Re: Proposal for another approach for Loop transformation with conditional in Loops.
On 03/16/2015 09:45 PM, Ajit Kumar Agarwal wrote: -Original Message- From: Jeff Law [mailto:l...@redhat.com] Sent: Monday, March 16, 2015 11:45 PM To: Ajit Kumar Agarwal; Richard Biener; gcc@gcc.gnu.org Cc: Vinod Kathail; Shail Aditya Gupta; Vidhumouli Hunsigida; Nagaraju Mekala Subject: Re: Proposal for another approach for Loop transformation with conditional in Loops. On 03/14/15 22:40, Ajit Kumar Agarwal wrote: Hello All: I am proposing the new approach to Loop transformation as given below in the example For the loops with conditional expression inside the Loops. The Loop body should be reducible control flow graph. The iteration space is partitioned into different spaces for which either the cond_expr is true or cond_expr is false. The evaluation of cond_expr for the partitioned iteration spaces can be determined statically. For the partitioned iterations and based on the analysis of cond_expr on the partitioned iterations spaces the Loops in fig (a) will be transformed to Loops in fig (b). for the iteration spaces of the conditional inside the loop is live in at the entry of the cond_expr and Live out the Control flow graph is topological ordered with the basic blocks for the conditional CFG and the partitioned iteration spaces can be formed for which the spaces can be true for conditional expr and false and unknown. Based on the above info and analysis the Loop of Fig (a) will be transformed to Loop Fig (b). This is much more optimized code as compared to the performance. The cases will be triggered for SPEC Benchmarks. Loops is partitioned to different version with different iteration spaces. Optimized in the presence Of the transformed generation of the loops without conditional. I fail to see how this is dramatically different than unswitching. You pull the condition out (it has to be loop invariant), then have two instances of the loop, one for the THEN, the other for the ELSE. You obviously select one or the other based on the condition of V. Specific examples might be helpful in understanding how you see this as different than unswitching. For ( I = 1; I < 5; i++) For ( j =1; j<=5;j++) If ( I >3 && j >3) A[i][j] = a[i+1][j-1]; Else A{i][j] = 0; End End Fig (1) For ( I = 1; I <= 3;i++) For(j= 4; j <= 5; j++) A[i][j] = 0; For( I = 4; I <= 5; i++) For(j = 4; j <=5;j++) A[i][j]= a[i+1][j-1]; For( (I = 1; I <=5 ;i++) For(j = 1; j <= 3;j++) A[i][j] = 0; Fig(2) Transformed code for Fig(1). Fig(1) is the original code and Fig(2) is the transformed code for fig(1). Ah, I see, you're changing the loop iteration space. Not sure how I missed that the first time around. How often does this happen in practice? Are there specific routines in SPEC that would benefit from this kind of transformation? jeff
Re: Proposal for another approach for Loop transformation with conditional in Loops.
On March 17, 2015 3:37:25 PM GMT+01:00, Jeff Law wrote: >On 03/16/2015 09:45 PM, Ajit Kumar Agarwal wrote: >> >> >> -Original Message- >> From: Jeff Law [mailto:l...@redhat.com] >> Sent: Monday, March 16, 2015 11:45 PM >> To: Ajit Kumar Agarwal; Richard Biener; gcc@gcc.gnu.org >> Cc: Vinod Kathail; Shail Aditya Gupta; Vidhumouli Hunsigida; Nagaraju >Mekala >> Subject: Re: Proposal for another approach for Loop transformation >with conditional in Loops. >> >> On 03/14/15 22:40, Ajit Kumar Agarwal wrote: >>> Hello All: >>> >>> I am proposing the new approach to Loop transformation as given >below >>> in the example For the loops with conditional expression inside the >>> Loops. The Loop body should be reducible control flow graph. The >>> iteration space is partitioned into different spaces for which >either >>> the cond_expr is true or cond_expr is false. The evaluation of >>> cond_expr for the partitioned iteration spaces can be determined >statically. For the partitioned iterations and based on the analysis of >cond_expr on the partitioned iterations spaces the Loops in fig (a) >will be transformed to Loops in fig (b). >>> >>> for the iteration spaces of the conditional inside the loop is live >in >>> at the entry of the cond_expr and Live out the Control flow graph is >>> topological ordered with the basic blocks for the conditional CFG >and the partitioned iteration spaces can be formed for which the spaces >can be true for conditional expr and false and unknown. >>> >>> Based on the above info and analysis the Loop of Fig (a) will be >transformed to Loop Fig (b). >>> >>> This is much more optimized code as compared to the performance. The >>> cases will be triggered for SPEC Benchmarks. Loops is partitioned to >>> different version with different iteration spaces. Optimized in the >presence Of the transformed generation of the loops without >conditional. >> I fail to see how this is dramatically different than unswitching. >You >> pull the condition out (it has to be loop invariant), then have two >instances of the loop, one for the THEN, the other for the ELSE. You >obviously select one or the other based on the condition of V. >> Specific examples might be helpful in understanding how you see >this as different than unswitching. >> >> For ( I = 1; I < 5; i++) >>For ( j =1; j<=5;j++) >> If ( I >3 && j >3) >> A[i][j] = a[i+1][j-1]; >> Else >> A{i][j] = 0; >> End >> End >> >> Fig (1) >> >> For ( I = 1; I <= 3;i++) >>For(j= 4; j <= 5; j++) >> A[i][j] = 0; >> >> For( I = 4; I <= 5; i++) >>For(j = 4; j <=5;j++) >> A[i][j]= a[i+1][j-1]; >> >> For( (I = 1; I <=5 ;i++) >>For(j = 1; j <= 3;j++) >> A[i][j] = 0; >> >> Fig(2) Transformed code for Fig(1). >> >> Fig(1) is the original code and Fig(2) is the transformed code for >fig(1). >Ah, I see, you're changing the loop iteration space. Not sure how I >missed that the first time around. > >How often does this happen in practice? Are there specific routines in > >SPEC that would benefit from this kind of transformation? It's usually an enablement transform for other transforms. In the case of hmmer it would enable vectorization. But if it is basically peeling it can also enable fusion for example. Richard. >jeff
Re: Unintended variable renaming in SSA replacement table
On 03/17/2015 06:32 AM, Benedikt Huber wrote: Hi, I have a problem with a transformation pass I wrote. The pass is meant to pipeline and unroll lookups in linked lists. After my pass is run, gcc renames a variable, which leads to wrong results. Part of my pass's dump, which is as I want it. ... : list_38 = list_10->next; _22 = list_10->info; _36 = _22->idx; if (_5 != _36) goto ; else goto ; : goto ; : # list_13 = PHI ... Corresponding part of the following pass. (list_join.c.148t.fab1) .. SSA replacement table N_i -> { O_1 ... O_j } means that N_i replaces O_1, ..., O_j _1 -> { _17 } _12 -> { _16 } _14 -> { _18 } _22 -> { _7 } _25 -> { _19 } _36 -> { _8 } list_38 -> { list_10 } list_41 -> { list_15 } _42 -> { _20 } ... : list_38 = list_10->next; _22 = list_38->info; _36 = _22->idx; if (_5 != _36) goto ; else goto ; : goto ; : # list_13 = PHI ... As you can see, gcc renames list_10 to list_38 in two places, which is not what I want. Why does gcc think this is possible. It seems to me that I need to update some data structure which I don't know of. What am I missing? I already did an updated_stmt in the places where I edit gimple statements. If I specify TODO_update_ssa, the same renaming already takes place in my pass. bb 19 is a copy of another basic block, maybe this is of relevance. Fundamentally SSA_NAMEs appearing in the graph are allowed only a single static assignment. Thus if you copy a block all SSA_NAMEs in the block have to go through an SSA update to ensure that each has one and only one single static assignment. jeff
Re: Unintended variable renaming in SSA replacement table
Thank you for the answer. I made sure that each variable is only assigned exactly once. duplicate_block already generates new names for all lhs. After that I edited all rhs to the uses I wanted for the unrolling, so SSA-form should still be intact. What I do not understand is: Why does gcc change the names on the rhs? A comment in update_ssa says: We want to replace all the uses of x_1 with the new definitions of x_10 and x_11. That is exactly what I don't want. Is there a way to tell gcc that the copy of the bb is already in SSA-form? Thank you and best regards, Benedikt On 17 Mar 2015, at 19:25, Jeff Law wrote: > On 03/17/2015 06:32 AM, Benedikt Huber wrote: >> Hi, >> >> I have a problem with a transformation pass I wrote. >> The pass is meant to pipeline and unroll lookups in linked lists. >> >> After my pass is run, gcc renames a variable, which leads to wrong results. >> >> Part of my pass's dump, which is as I want it. >> ... >> : >> list_38 = list_10->next; >> _22 = list_10->info; >> _36 = _22->idx; >> if (_5 != _36) >> goto ; >> else >> goto ; >> >> : >> goto ; >> >> : >> # list_13 = PHI > list_10(19)> >> ... >> >> >> Corresponding part of the following pass. (list_join.c.148t.fab1) >> .. >> SSA replacement table >> N_i -> { O_1 ... O_j } means that N_i replaces O_1, ..., O_j >> >> _1 -> { _17 } >> _12 -> { _16 } >> _14 -> { _18 } >> _22 -> { _7 } >> _25 -> { _19 } >> _36 -> { _8 } >> list_38 -> { list_10 } >> list_41 -> { list_15 } >> _42 -> { _20 } >> ... >> : >> list_38 = list_10->next; >> _22 = list_38->info; >> _36 = _22->idx; >> if (_5 != _36) >> goto ; >> else >> goto ; >> >> : >> goto ; >> >> : >> # list_13 = PHI > list_38(19)> >> ... >> >> As you can see, gcc renames list_10 to list_38 in two places, which is not >> what I want. >> Why does gcc think this is possible. It seems to me that I need to update >> some data structure >> which I don't know of. What am I missing? >> I already did an updated_stmt in the places where I edit gimple statements. >> >> If I specify TODO_update_ssa, the same renaming already takes place in my >> pass. >> bb 19 is a copy of another basic block, maybe this is of relevance. > Fundamentally SSA_NAMEs appearing in the graph are allowed only a single > static assignment. Thus if you copy a block all SSA_NAMEs in the block have > to go through an SSA update to ensure that each has one and only one single > static assignment. > > jeff signature.asc Description: Message signed with OpenPGP using GPGMail
Re: Unintended variable renaming in SSA replacement table
On 03/17/2015 12:54 PM, Benedikt Huber wrote: Thank you for the answer. I made sure that each variable is only assigned exactly once. duplicate_block already generates new names for all lhs. After that I edited all rhs to the uses I wanted for the unrolling, so SSA-form should still be intact. What I do not understand is: Why does gcc change the names on the rhs? Because uses that are reached by the new names obviously have to get updated. The SSA updater is supposed to relieve passes from the burden of trying to figure out how to handle updates on their own. You copy the blocks, update your cfg, remove unreachables, then let the ssa updater handle updating the ssa graph. If you're using the block copier, but doing your own updates, then you'll need some kind of hack to avoid the standard update mechanisms. I'm not immediately aware of a "blessed" way to do that. You'll need to hack somethign up. jeff
Re: GSoc-2015: Modular GCC (RFC on refactoring)
07.03.2015 18:41, Jeff Law wrote: > One potentially easy project there would be to take David Malcolm's work to > turn the RTL EXPR & INSN lists into standard C++ forward lists. Started working on this. I need to understand, if I'm moving in the right direction (i.e. whether my understanding of what needs to be done is correct). I got some basic grasp of GCC internals, but the code base is huge, and I still have a lot of questions :( 1. The list of INSNs is non-intrusive, i.e. nodes of such list no longer need to be subclasses of struct rtx_def and/or members of rtunion, right? 2. Lists, list nodes and list iterators should be objects of distinct types. In this case, header file function.h gets additional dependency, because struct rtldata contains insn/expr lists as members; currently they are pointers, so a forward declaration is sufficient. A possible workaround is to create an opaque type like it's done with struct initial_value_struct (at a cost of one additional level of indirection). Which is better? 3. List nodes can be allocated in a separate pool rather than garbage-collected memory. Not sure, what should be done with reg_notes. They use insn lists, but it seems to me that insn lists in reg_notes are a different concept than, say, lists used by scheduler and register allocator), according to rtlanal.c: /* These types of register notes use an INSN_LIST rather than an EXPR_LIST, so that copying is done right and dumps look better. */ So, should this be changed somehow? 4. I don't understand precisely, how all this stuff will interact with garbage collector. Is it possible, for example, to register an insn_list object as a GC root with custom marking function in it's constructor, and remove it, when the list is destroyed? 5. EXPR lists seem to be harder to separate from other RTL objects, because they are owned by GC-managed RTL objects. Maybe we need to have both pool-allocated and GC-managed lists? > One that's harder would be pushing the rtx_insn * class further. Basically > most of the places where we have a as-a cast between rtx_insn * and an > rtx is a good candidate for removal and further propagation of rtx_insn > * types. I'll try to figure out, if it's possible to automate this. Perhaps, by writing a plugin, which traverses C++ AST (in PLUGIN_PRE_GENERICIZE) and searches for such casts. -- Regards, Mikhail Maltsev
Re: GSoc-2015: Modular GCC (RFC on refactoring)
On 03/17/2015 09:50 PM, Mikhail Maltsev wrote: 07.03.2015 18:41, Jeff Law wrote: One potentially easy project there would be to take David Malcolm's work to turn the RTL EXPR & INSN lists into standard C++ forward lists. Started working on this. I need to understand, if I'm moving in the right direction (i.e. whether my understanding of what needs to be done is correct). I got some basic grasp of GCC internals, but the code base is huge, and I still have a lot of questions :( 1. The list of INSNs is non-intrusive, i.e. nodes of such list no longer need to be subclasses of struct rtx_def and/or members of rtunion, right? Right, they should be rtx_insn *. 2. Lists, list nodes and list iterators should be objects of distinct types. In this case, header file function.h gets additional dependency, because struct rtldata contains insn/expr lists as members; currently they are pointers, so a forward declaration is sufficient. A possible workaround is to create an opaque type like it's done with struct initial_value_struct (at a cost of one additional level of indirection). Which is better? I'd probably stick with a forward declaration. 3. List nodes can be allocated in a separate pool rather than garbage-collected memory. Not sure, what should be done with reg_notes. They use insn lists, but it seems to me that insn lists in reg_notes are a different concept than, say, lists used by scheduler and register allocator), according to rtlanal.c: /* These types of register notes use an INSN_LIST rather than an EXPR_LIST, so that copying is done right and dumps look better. */ So, should this be changed somehow? They may need to be broken out into distinct objects. 4. I don't understand precisely, how all this stuff will interact with garbage collector. Is it possible, for example, to register an insn_list object as a GC root with custom marking function in it's constructor, and remove it, when the list is destroyed? Me neither :-) I try real hard to avoid thinking hard about the gengtype bits. It might need some experimentation.. 5. EXPR lists seem to be harder to separate from other RTL objects, because they are owned by GC-managed RTL objects. Maybe we need to have both pool-allocated and GC-managed lists? Dunno. David M. was able to turn the forced_labels EXPR_LIST into a vec without too much surgery. See: https://gcc.gnu.org/ml/gcc-patches/2014-08/msg00825.html I'm not a big fan of keeping the FOR_EACH_blah style iterator and would prefer to use real C++ iterators. But it ought to give you some ideas about how to start breaking these things out. One that's harder would be pushing the rtx_insn * class further. Basically most of the places where we have a as-a cast between rtx_insn * and an rtx is a good candidate for removal and further propagation of rtx_insn * types. I'll try to figure out, if it's possible to automate this. Perhaps, by writing a plugin, which traverses C++ AST (in PLUGIN_PRE_GENERICIZE) and searches for such casts. You probably should talk do David about this kind of approach. It fits in with his style of work. I'm much more of a remove the as-a cast, then beat the code into submission :-) Jeff
Re: GSoc-2015: Modular GCC (RFC on refactoring)
On Wed, Mar 18, 2015 at 06:50:11AM +0300, Mikhail Maltsev wrote: > 07.03.2015 18:41, Jeff Law wrote: > > One potentially easy project there would be to take David Malcolm's work to > > turn the RTL EXPR & INSN lists into standard C++ forward lists. > > Started working on this. I need to understand, if I'm moving in the > right direction (i.e. whether my understanding of what needs to be done > is correct). I got some basic grasp of GCC internals, but the code base > is huge, and I still have a lot of questions :( > > 1. The list of INSNs is non-intrusive, i.e. nodes of such list no longer > need to be subclasses of struct rtx_def and/or members of rtunion, right? if by "the list of insns" you mean the chain for a set of rtx_insn_list's then yes. > 2. Lists, list nodes and list iterators should be objects of distinct > types. In this case, header file function.h gets additional dependency, > because struct rtldata contains insn/expr lists as members; currently > they are pointers, so a forward declaration is sufficient. A possible > workaround is to create an opaque type like it's done with struct > initial_value_struct (at a cost of one additional level of indirection). > Which is better? given std::forward_list isn't available in c++98 I expect you'll write your own version of it. It seems pretty reasonable to me function.h would depend on the hypothetical header containing that list template, and presumably more stuff than just rtx_insn_list's could be made to use it. > 3. List nodes can be allocated in a separate pool rather than > garbage-collected memory. Not sure, what should be done with reg_notes. > They use insn lists, but it seems to me that insn lists in reg_notes are > a different concept than, say, lists used by scheduler and register > allocator), according to rtlanal.c: > /* These types of register notes use an INSN_LIST rather than an >EXPR_LIST, so that copying is done right and dumps look >better. */ > So, should this be changed somehow? dealing with ggc is... complex :( To start its probably simplest though pretty sub optimal to keep the nodes in gc memory. > 4. I don't understand precisely, how all this stuff will interact with > garbage collector. Is it possible, for example, to register an insn_list > object as a GC root with custom marking function in it's constructor, > and remove it, when the list is destroyed? One of the few good things about ggc is that we can modify it to suite our needs. However the tricky bit is PCH writing. > 5. EXPR lists seem to be harder to separate from other RTL objects, > because they are owned by GC-managed RTL objects. Maybe we need to have > both pool-allocated and GC-managed lists? maybe, though ggc does have finalizers now, so its possible we could move all the lists out of gc memory. > > One that's harder would be pushing the rtx_insn * class further. Basically > > most of the places where we have a as-a cast between rtx_insn * and an > > rtx is a good candidate for removal and further propagation of rtx_insn > > * types. > > I'll try to figure out, if it's possible to automate this. Perhaps, by > writing a plugin, which traverses C++ AST (in PLUGIN_PRE_GENERICIZE) and > searches for such casts. you can just look by greping for as_a / dyn_cast. Trev > > -- > Regards, > Mikhail Maltsev
Re: GSoc-2015: Modular GCC (RFC on refactoring)
On 03/17/2015 10:32 PM, Trevor Saunders wrote: 2. Lists, list nodes and list iterators should be objects of distinct types. In this case, header file function.h gets additional dependency, because struct rtldata contains insn/expr lists as members; currently they are pointers, so a forward declaration is sufficient. A possible workaround is to create an opaque type like it's done with struct initial_value_struct (at a cost of one additional level of indirection). Which is better? given std::forward_list isn't available in c++98 I expect you'll write your own version of it. It seems pretty reasonable to me function.h would depend on the hypothetical header containing that list template, and presumably more stuff than just rtx_insn_list's could be made to use it. Sigh. We could just use a vec then... That would still be better in various ways than chaining things via EXPR_LIST or INSN_LIST. Jeff
Re: GSoc-2015: Modular GCC (RFC on refactoring)
On Tue, Mar 17, 2015 at 10:36:05PM -0600, Jeff Law wrote: > On 03/17/2015 10:32 PM, Trevor Saunders wrote: > > > >>2. Lists, list nodes and list iterators should be objects of distinct > >>types. In this case, header file function.h gets additional dependency, > >>because struct rtldata contains insn/expr lists as members; currently > >>they are pointers, so a forward declaration is sufficient. A possible > >>workaround is to create an opaque type like it's done with struct > >>initial_value_struct (at a cost of one additional level of indirection). > >>Which is better? > > > >given std::forward_list isn't available in c++98 I expect you'll write > >your own version of it. It seems pretty reasonable to me function.h > >would depend on the hypothetical header containing that list template, > >and presumably more stuff than just rtx_insn_list's could be made to use > >it. > Sigh. We could just use a vec then... That would still be better in > various ways than chaining things via EXPR_LIST or INSN_LIST. yeah, I even seem to remember coming across a place where both were done and wondering why. Trev > > > Jeff >