On Wed, 2014-06-25 at 14:39 -0600, Jeff Law wrote: > On 06/25/14 03:36, Richard Sandiford wrote: > > > > I think this is an example of another problem with gcc coding style: > > that we're far too afraid of temporary variables. In David's scheme > > I think this would be: > Historical coding style :( It's particularly bad in RTL land, but you > see the same problems in places like fold-const. > > > > > > if (rtx_mem *mem = as_a <rtx_mem *> (XEXP (x, 0))) > > *total = address_cost (XEXP (mem, 0), GET_MODE (mem), > > MEM_ADDR_SPACE (mem), true); > > > > which with members would become: > > > > if (rtx_mem *mem = as_a <rtx_mem *> (...)) > > *total = address_cost (mem->address (), mem->mode (), > > mem->address_space (), > > true); > > > > (although if we go down that route, I hope we can add an exception to the > > formatting rule so that no space should be used before "()".) > There was some talk of revamping the rules of parens for member function > calls. I don't recall what the final outcome was. > > I prefer the latter, but I tend to worry about making David's patches > even more invasive than they already are :-)
:) Yeah, that's probably my primary concern here. The patch kit is going to be big (currently at 133 patches [1]), and so I want something that we can sanely keep track of, that is easily reviewable, and will be as easy as possible to merge. i.e. I don't want to get bogged down in a big revamp of the rest of the RTL interface if I can help it. I'm attempting to focus on splitting out insns from expressions. As mentioned before, in the v1 of this patch kit I also introduced rtx subclasses for various core types like INSN_LIST, SEQUENCE, etc - but in this iteration I'm attempting to do it without those - not yet sure if it's possible. If it's desirable to actually make insns be a separate class, I'm considering the goal of making the attributes of insns become actual fields, something like: class rtx_insn /* we can bikeshed over the name */ { public: rtx_insn *m_prev; rtx_insn *m_next; int m_uid; }; #define PREV_INSN(INSN) ((INSN)->m_prev) #define NEXT_INSN(INSN) ((INSN)->m_next) #define INSN_UID(INSN) ((INSN)->m_uid) /* or we could convert them to functions returning references, I guess */ ...etc for the subclasses, giving something that gdb can print sanely, and, I hope, more amenable to optimization when gcc itself is compiled. But even if we don't get there and simply keep insns as subclasses of rtx, I think that having insn-handling code marked as such in the type-system is a win from a readability standpoint. Either way, I think this should be much more "grokkable" by new contributors. My own experience is that RTL was the aspect of GCC I had most difficulty with when I was a newbie - hence my motivation to "drain this swamp". Hope these ideas sound sane Dave [1] FWIW the latest version of the patches is here: http://dmalcolm.fedorapeople.org/gcc/patch-backups/rtx-classes/v9/ at 133 patches (as before it's relative to r211061). I'm aiming for lots of *small* patches. Successful bootstrap and regrtest on x86_64; builds on 187 configurations. Perhaps the biggest change since last time is that the "scaffolding" phase of the patches introduces a hack into the generated inns-*.c so that the .md files see rtx_insn * rather than plain rtx (for "insn" and "curr_insn"), which should allow lots of target-specific hooks used from .md files to be similarly converted: http://dmalcolm.fedorapeople.org/gcc/patch-backups/rtx-classes/v9/0036-Use-rtx_insn-internally-within-generated-functions.patch > > I suppose with the magic values it would be: > > > > if (rtx_mem mem = as_a <rtx_mem> (x[0])) > > *total = address_cost (mem[0], mem.mode (), mem.address_space (), > > true); > > > > but I'm not sure that that would really be more readable. > Please, no... > > > > > > But like you say, I'm not sure whether it would really be a win in the end. > > I think what makes this example so hard to read is again that we refuse > > to put XEXP (x, 0) in a temporary variable and just write it out in full > > 4 times instead. > > > > if ((GET_CODE (op0) == SMAX || GET_CODE (op0) == SMIN) > > && CONST_INT_P (XEXP (op0, 1)) > > && REG_P (XEXP (op0, 0)) > > && CONST_INT_P (op1)) > > > > is a bit more obvious. > And probably faster as well since we've CSE'd the memory reference. In > this specific example it probably doesn't matter, but often there's a > call somewhere between XEXPs that we'd like to CSE that destroys our > ability to CSE away memory references. > > This kind of problem is prevasive in the RTL analysis/optimizers. >