On 11/19/2014 05:28 PM, David Malcolm wrote:
On Wed, 2014-11-19 at 17:24 -0500, David Malcolm wrote:
On Wed, 2014-11-19 at 22:36 +0100, Richard Biener wrote:
On November 19, 2014 10:09:56 PM CET, Andrew MacLeod <amacl...@redhat.com>
wrote:
On 11/19/2014 03:43 PM, Richard Biener wrote:
On November 19, 2014 8:26:23 PM CET, Andrew MacLeod
<amacl...@redhat.com> wrote:
On 11/19/2014 01:12 PM, David Malcolm wrote:
(A) could become:
greturn *stmt = gsi->as_a_greturn ();
(B) could become:
stmt = gsi->dyn_cast <gcall *> ();
if (!stmt)
or:
stmt = gsi->dyn_cast_gcall ();
if (!stmt)
or maybe:
stmt = gsi->is_a_gcall ();
if (!stmt)
An earlier version of my patches had casting methods within the
gimple_statement_base class, which were rejected; the above
proposals
would instead put them within gimple_stmt_iterator.
I would like all gsi routines to be consistent, not a mix of
functions
and methods.
so something like
stmt = gsi_as_call (gsi);
stmt = gsi_dyn_call (gsi);
or we need to change gsi_stmt() and friends into methods and access
them
as gsi->stmt ().. which is possibly better, but that much more
intrusive again (another 2000+ locations).
If we switched to methods everywhere for gsi, I'd prefer something
like
gsi->as_a_call ()
gsi->is_a_call ()
gsi->dyn_cast_call ()
I think its more readable... and it removes a dependency on the
implementation.. so if we ever decide to change the name of 'gcall'
down
the road to using a namespace, and make it gimple::call or whatever,
we
wont have to change every single gsi-> location which has a
templated
use of the type.
I'm also think this sort of thing could probably wait until next
stage
1..
my 2 cents...
Why not as_a <gassign *> (*gsi)? It would
Add operator* to gsi of course.
Richard.
I could live with that form too.
we often have an instance of gimple_stmt_iterator rather than a pointer
to it, so wouldn't "operator gimple *()" to implicitly call gsi_stmt()
when needed work better? (or "operator gimple ()" before the next
change) ..
Not sure. The * matches how iterators work in STL...
Note that for the cases where we pass a pointer to an iterator we can change
those to use references to avoid writing **gsi.
Richard.
Andrew
I had a go at adding an operator * to gimple_stmt_iterator, using it
everywhere that we do an as_a<> or dyn_cast<> on the result of a
gsi_stmt, to abbreviate the gsi_stmt call down to one character.
Patch attached; only lightly smoketested; am posting it for the sake of
discussion.
I don't think this API will make the non-C++-fans happier; I think the
objection to the work I just merged is that it's adding more C++ than
those people are comfortable with.
So although the attached patch makes things shorter (good), it's taking
things in a "more C++" direction (questionable). I'd hoped to paper
over the C++ somewhat.
I suspect that any API which requires the of < > characters within the
implementation of a gimple pass to mean a template is going to give
those less happy with C++ a visceral "ugh" reaction. I wonder if
there's a way to spell these things that's concise and which doesn't
involve <> ?
Answering my own question, user-defined conversion operators, though
should they as_a or dyn_cast?
Here's an example where they mean "as_a", radically shortening the
conversion (shorter, in fact, that the pre-merger code):
diff --git a/gcc/asan.c b/gcc/asan.c
index be28ede..890e58b 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1902,7 +1902,7 @@ instrument_builtin_call (gimple_stmt_iterator *iter)
return false;
bool iter_advanced_p = false;
- gcall *call = as_a <gcall *> (gsi_stmt (*iter));
+ gcall *call = *iter;
gcc_checking_assert (gimple_call_builtin_p (call, BUILT_IN_NORMAL));
diff --git a/gcc/gimple-iterator.h b/gcc/gimple-iterator.h
index fb6cc07..52106fa 100644
--- a/gcc/gimple-iterator.h
+++ b/gcc/gimple-iterator.h
@@ -33,6 +33,8 @@ struct gimple_stmt_iterator
block/sequence is removed. */
gimple_seq *seq;
basic_block bb;
+
+ operator gcall * ();
};
/* Iterator over GIMPLE_PHI statements. */
@@ -331,4 +333,11 @@ gsi_seq (gimple_stmt_iterator i)
return *i.seq;
}
+inline
+gimple_stmt_iterator::operator gcall * ()
+{
+ return as_a <gcall *> (gsi_stmt (*this));
+}
+
+
#endif /* GCC_GIMPLE_ITERATOR_H */
(again, I only checked that it compiles)
Dave
I think the problem is different people will naturally think they should
do different things, and I see the logic to both.
In my various tree experiments, for a while I used the user defined
conversion as a dyn_cast because that is what seemed "right" to me. I
can assure you that can be flawed... mostly because if its something you
didn't anticipate, you just get a NULL back and things proceed... in
particular when calling functions. When I disabled that
auto-conversion, I discovered a whole bunch of code that was silently wrong.
At least with as_a you will catch it immediately during compilation if
things are wrong... but it still feels a little wrong to me. Likewise
you could overload the operator= to do similar things but you wouldn't
get unexpected auto-conversions as function parameters.
SInce there are multiple ways of viewing it, I think its probably better
to be explicit somehow.
Andrew
PS. this whole area sounds like a "best practices" decent C++ projects
probably figured out a decade ago... or at least should have :-)