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