Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-19 Thread Richard Biener
On Tue, Nov 18, 2014 at 10:04 PM, David Malcolm dmalc...@redhat.com wrote:
 On Tue, 2014-11-18 at 10:53 +0100, Richard Biener wrote:
 On Tue, Nov 18, 2014 at 2:59 AM, David Malcolm dmalc...@redhat.com wrote:
  On Mon, 2014-11-17 at 11:06 +0100, Richard Biener wrote:
  On Sat, Nov 15, 2014 at 12:00 PM, David Malcolm dmalc...@redhat.com 
  wrote:
   On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
   On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm dmalc...@redhat.com 
   wrote:
On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com 
wrote:
 On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
 On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
  On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
   To be constructive here - the above case is from within a
   GIMPLE_ASSIGN case label
   and thus I'd have expected
  
   case GIMPLE_ASSIGN:
 {
   gassign *a1 = as_a gassign * (s1);
   gassign *a2 = as_a gassign * (s2);
 lhs1 = gimple_assign_lhs (a1);
 lhs2 = gimple_assign_lhs (a2);
 if (TREE_CODE (lhs1) != SSA_NAME
  TREE_CODE (lhs2) != SSA_NAME)
   return (operand_equal_p (lhs1, lhs2, 0)
gimple_operand_equal_value_p 
   (gimple_assign_rhs1 (a1),

   gimple_assign_rhs1 (a2)));
 else if (TREE_CODE (lhs1) == SSA_NAME
   TREE_CODE (lhs2) == SSA_NAME)
   return vn_valueize (lhs1) == vn_valueize (lhs2);
 return false;
 }
  
   instead.  That's the kind of changes I have expected and 
   have approved of.
 
  But even that looks like just adding extra work for all 
  developers, with no
  gain.  You only have to add extra code and extra temporaries, 
  in switches
  typically also have to add {} because of the temporaries and 
  thus extra
  indentation level, and it doesn't simplify anything in the 
  code.

 The branch attempts to use the C++ typesystem to capture 
 information
 about the kinds of gimple statement we expect, both:
   (A) so that the compiler can detect type errors, and
   (B) as a comprehension aid to the human reader of the code

 The ideal here is when function params and struct field can be
 strengthened from gimple to a subclass ptr.  This captures the
 knowledge that every use of a function or within a struct has a 
 given
 gimple code.

 I just don't like all the as_a/is_a stuff enforced everywhere,
 it means more typing, more temporaries, more indentation.
 So, as I view it, instead of the checks being done cheaply (yes, 
 I think
 the gimple checking as we have right now is very cheap) under the
 hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those 
 changes
 put the burden on the developers, who has to check that manually 
 through
 the as_a/is_a stuff everywhere, more typing and uglier syntax.
 I just don't see that as a step forward, instead a huge step 
 backwards.
 But perhaps I'm alone with this.
 Can you e.g. compare the size of - lines in your patchset 
 combined, and
 size of + lines in your patchset?  As in, if your changes lead to 
 less
 typing or more.
   
I see two ways out here.  One is to add overloads to all the 
functions
taking the special types like
   
tree
gimple_assign_rhs1 (gimple *);
   
or simply add
   
gassign *operator ()(gimple *g) { return as_a gassign * (g); }
   
into a gimple-compat.h header which you include in places that
are not converted nicely.
   
Thanks for the suggestions.
   
Am I missing something, or is the gimple-compat.h idea above not 
valid C
++?
   
Note that gimple is still a typedef to
  gimple_statement_base *
(as noted before, the gimple - gimple * change would break everyone
else's patches, so we talked about that as a followup patch for early
stage3).
   
Given that, if I try to create an operator () outside of a class, I
get this error:
   
‘gassign* operator()(gimple)’ must be a nonstatic member function
   
which is emitted from cp/decl.c's grok_op_properties:
  /* An operator function must either be a non-static member 
function
 or have at least one parameter of a class, a reference to a 
class,
 an enumeration, or a reference to an enumeration.  13.4.0.6 
*/
   
I tried making it a member function of gimple_statement_base, but 
that
doesn't work either: we want a conversion
  from a gimple_statement_base * to a gassign *, not
  from a gimple_statement_base   to a gassign *.
   
Is there some syntactic 

Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-18 Thread Richard Biener
On Tue, Nov 18, 2014 at 2:59 AM, David Malcolm dmalc...@redhat.com wrote:
 On Mon, 2014-11-17 at 11:06 +0100, Richard Biener wrote:
 On Sat, Nov 15, 2014 at 12:00 PM, David Malcolm dmalc...@redhat.com wrote:
  On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
  On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm dmalc...@redhat.com 
  wrote:
   On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
   On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com 
   wrote:
On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
 On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
  To be constructive here - the above case is from within a
  GIMPLE_ASSIGN case label
  and thus I'd have expected
 
  case GIMPLE_ASSIGN:
{
  gassign *a1 = as_a gassign * (s1);
  gassign *a2 = as_a gassign * (s2);
lhs1 = gimple_assign_lhs (a1);
lhs2 = gimple_assign_lhs (a2);
if (TREE_CODE (lhs1) != SSA_NAME
 TREE_CODE (lhs2) != SSA_NAME)
  return (operand_equal_p (lhs1, lhs2, 0)
   gimple_operand_equal_value_p 
  (gimple_assign_rhs1 (a1),
   
  gimple_assign_rhs1 (a2)));
else if (TREE_CODE (lhs1) == SSA_NAME
  TREE_CODE (lhs2) == SSA_NAME)
  return vn_valueize (lhs1) == vn_valueize (lhs2);
return false;
}
 
  instead.  That's the kind of changes I have expected and have 
  approved of.

 But even that looks like just adding extra work for all 
 developers, with no
 gain.  You only have to add extra code and extra temporaries, in 
 switches
 typically also have to add {} because of the temporaries and thus 
 extra
 indentation level, and it doesn't simplify anything in the code.
   
The branch attempts to use the C++ typesystem to capture information
about the kinds of gimple statement we expect, both:
  (A) so that the compiler can detect type errors, and
  (B) as a comprehension aid to the human reader of the code
   
The ideal here is when function params and struct field can be
strengthened from gimple to a subclass ptr.  This captures the
knowledge that every use of a function or within a struct has a 
given
gimple code.
   
I just don't like all the as_a/is_a stuff enforced everywhere,
it means more typing, more temporaries, more indentation.
So, as I view it, instead of the checks being done cheaply (yes, I 
think
the gimple checking as we have right now is very cheap) under the
hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
put the burden on the developers, who has to check that manually 
through
the as_a/is_a stuff everywhere, more typing and uglier syntax.
I just don't see that as a step forward, instead a huge step 
backwards.
But perhaps I'm alone with this.
Can you e.g. compare the size of - lines in your patchset combined, 
and
size of + lines in your patchset?  As in, if your changes lead to 
less
typing or more.
  
   I see two ways out here.  One is to add overloads to all the functions
   taking the special types like
  
   tree
   gimple_assign_rhs1 (gimple *);
  
   or simply add
  
   gassign *operator ()(gimple *g) { return as_a gassign * (g); }
  
   into a gimple-compat.h header which you include in places that
   are not converted nicely.
  
   Thanks for the suggestions.
  
   Am I missing something, or is the gimple-compat.h idea above not valid C
   ++?
  
   Note that gimple is still a typedef to
 gimple_statement_base *
   (as noted before, the gimple - gimple * change would break everyone
   else's patches, so we talked about that as a followup patch for early
   stage3).
  
   Given that, if I try to create an operator () outside of a class, I
   get this error:
  
   ‘gassign* operator()(gimple)’ must be a nonstatic member function
  
   which is emitted from cp/decl.c's grok_op_properties:
 /* An operator function must either be a non-static member 
   function
or have at least one parameter of a class, a reference to a 
   class,
an enumeration, or a reference to an enumeration.  13.4.0.6 */
  
   I tried making it a member function of gimple_statement_base, but that
   doesn't work either: we want a conversion
 from a gimple_statement_base * to a gassign *, not
 from a gimple_statement_base   to a gassign *.
  
   Is there some syntactic trick here that I'm missing?  Sorry if I'm being
   dumb (I can imagine there's a way of doing it by making gimple become
   some kind of wrapped ptr class, but that way lies madness, surely).
 
  Hmm.
 
  struct assign;
  struct base {
operator assign *() const { return (assign *)this; }

Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-18 Thread David Malcolm
On Tue, 2014-11-18 at 10:53 +0100, Richard Biener wrote:
 On Tue, Nov 18, 2014 at 2:59 AM, David Malcolm dmalc...@redhat.com wrote:
  On Mon, 2014-11-17 at 11:06 +0100, Richard Biener wrote:
  On Sat, Nov 15, 2014 at 12:00 PM, David Malcolm dmalc...@redhat.com 
  wrote:
   On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
   On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm dmalc...@redhat.com 
   wrote:
On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com 
wrote:
 On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
 On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
  On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
   To be constructive here - the above case is from within a
   GIMPLE_ASSIGN case label
   and thus I'd have expected
  
   case GIMPLE_ASSIGN:
 {
   gassign *a1 = as_a gassign * (s1);
   gassign *a2 = as_a gassign * (s2);
 lhs1 = gimple_assign_lhs (a1);
 lhs2 = gimple_assign_lhs (a2);
 if (TREE_CODE (lhs1) != SSA_NAME
  TREE_CODE (lhs2) != SSA_NAME)
   return (operand_equal_p (lhs1, lhs2, 0)
gimple_operand_equal_value_p 
   (gimple_assign_rhs1 (a1),

   gimple_assign_rhs1 (a2)));
 else if (TREE_CODE (lhs1) == SSA_NAME
   TREE_CODE (lhs2) == SSA_NAME)
   return vn_valueize (lhs1) == vn_valueize (lhs2);
 return false;
 }
  
   instead.  That's the kind of changes I have expected and have 
   approved of.
 
  But even that looks like just adding extra work for all 
  developers, with no
  gain.  You only have to add extra code and extra temporaries, 
  in switches
  typically also have to add {} because of the temporaries and 
  thus extra
  indentation level, and it doesn't simplify anything in the code.

 The branch attempts to use the C++ typesystem to capture 
 information
 about the kinds of gimple statement we expect, both:
   (A) so that the compiler can detect type errors, and
   (B) as a comprehension aid to the human reader of the code

 The ideal here is when function params and struct field can be
 strengthened from gimple to a subclass ptr.  This captures the
 knowledge that every use of a function or within a struct has a 
 given
 gimple code.

 I just don't like all the as_a/is_a stuff enforced everywhere,
 it means more typing, more temporaries, more indentation.
 So, as I view it, instead of the checks being done cheaply (yes, I 
 think
 the gimple checking as we have right now is very cheap) under the
 hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those 
 changes
 put the burden on the developers, who has to check that manually 
 through
 the as_a/is_a stuff everywhere, more typing and uglier syntax.
 I just don't see that as a step forward, instead a huge step 
 backwards.
 But perhaps I'm alone with this.
 Can you e.g. compare the size of - lines in your patchset 
 combined, and
 size of + lines in your patchset?  As in, if your changes lead to 
 less
 typing or more.
   
I see two ways out here.  One is to add overloads to all the 
functions
taking the special types like
   
tree
gimple_assign_rhs1 (gimple *);
   
or simply add
   
gassign *operator ()(gimple *g) { return as_a gassign * (g); }
   
into a gimple-compat.h header which you include in places that
are not converted nicely.
   
Thanks for the suggestions.
   
Am I missing something, or is the gimple-compat.h idea above not 
valid C
++?
   
Note that gimple is still a typedef to
  gimple_statement_base *
(as noted before, the gimple - gimple * change would break everyone
else's patches, so we talked about that as a followup patch for early
stage3).
   
Given that, if I try to create an operator () outside of a class, I
get this error:
   
‘gassign* operator()(gimple)’ must be a nonstatic member function
   
which is emitted from cp/decl.c's grok_op_properties:
  /* An operator function must either be a non-static member 
function
 or have at least one parameter of a class, a reference to a 
class,
 an enumeration, or a reference to an enumeration.  13.4.0.6 
*/
   
I tried making it a member function of gimple_statement_base, but that
doesn't work either: we want a conversion
  from a gimple_statement_base * to a gassign *, not
  from a gimple_statement_base   to a gassign *.
   
Is there some syntactic trick here that I'm missing?  Sorry if I'm 
being
dumb (I can imagine there's a 

Re: [PATCH] Add gimple-compat.h (was Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign)

2014-11-17 Thread Richard Biener
On Fri, Nov 14, 2014 at 4:27 PM, David Malcolm dmalc...@redhat.com wrote:
 On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
 On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm dmalc...@redhat.com wrote:
  On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
  On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com wrote:
   On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
   On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
 To be constructive here - the above case is from within a
 GIMPLE_ASSIGN case label
 and thus I'd have expected

 case GIMPLE_ASSIGN:
   {
 gassign *a1 = as_a gassign * (s1);
 gassign *a2 = as_a gassign * (s2);
   lhs1 = gimple_assign_lhs (a1);
   lhs2 = gimple_assign_lhs (a2);
   if (TREE_CODE (lhs1) != SSA_NAME
TREE_CODE (lhs2) != SSA_NAME)
 return (operand_equal_p (lhs1, lhs2, 0)
  gimple_operand_equal_value_p 
 (gimple_assign_rhs1 (a1),
  
 gimple_assign_rhs1 (a2)));
   else if (TREE_CODE (lhs1) == SSA_NAME
 TREE_CODE (lhs2) == SSA_NAME)
 return vn_valueize (lhs1) == vn_valueize (lhs2);
   return false;
   }

 instead.  That's the kind of changes I have expected and have 
 approved of.
   
But even that looks like just adding extra work for all developers, 
with no
gain.  You only have to add extra code and extra temporaries, in 
switches
typically also have to add {} because of the temporaries and thus 
extra
indentation level, and it doesn't simplify anything in the code.
  
   The branch attempts to use the C++ typesystem to capture information
   about the kinds of gimple statement we expect, both:
 (A) so that the compiler can detect type errors, and
 (B) as a comprehension aid to the human reader of the code
  
   The ideal here is when function params and struct field can be
   strengthened from gimple to a subclass ptr.  This captures the
   knowledge that every use of a function or within a struct has a given
   gimple code.
  
   I just don't like all the as_a/is_a stuff enforced everywhere,
   it means more typing, more temporaries, more indentation.
   So, as I view it, instead of the checks being done cheaply (yes, I think
   the gimple checking as we have right now is very cheap) under the
   hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
   put the burden on the developers, who has to check that manually through
   the as_a/is_a stuff everywhere, more typing and uglier syntax.
   I just don't see that as a step forward, instead a huge step backwards.
   But perhaps I'm alone with this.
   Can you e.g. compare the size of - lines in your patchset combined, and
   size of + lines in your patchset?  As in, if your changes lead to less
   typing or more.
 
  I see two ways out here.  One is to add overloads to all the functions
  taking the special types like
 
  tree
  gimple_assign_rhs1 (gimple *);
 
  or simply add
 
  gassign *operator ()(gimple *g) { return as_a gassign * (g); }
 
  into a gimple-compat.h header which you include in places that
  are not converted nicely.
 
  Thanks for the suggestions.
 
  Am I missing something, or is the gimple-compat.h idea above not valid C
  ++?
 
  Note that gimple is still a typedef to
gimple_statement_base *
  (as noted before, the gimple - gimple * change would break everyone
  else's patches, so we talked about that as a followup patch for early
  stage3).
 
  Given that, if I try to create an operator () outside of a class, I
  get this error:
 
  ‘gassign* operator()(gimple)’ must be a nonstatic member function
 
  which is emitted from cp/decl.c's grok_op_properties:
/* An operator function must either be a non-static member function
   or have at least one parameter of a class, a reference to a class,
   an enumeration, or a reference to an enumeration.  13.4.0.6 */
 
  I tried making it a member function of gimple_statement_base, but that
  doesn't work either: we want a conversion
from a gimple_statement_base * to a gassign *, not
from a gimple_statement_base   to a gassign *.
 
  Is there some syntactic trick here that I'm missing?  Sorry if I'm being
  dumb (I can imagine there's a way of doing it by making gimple become
  some kind of wrapped ptr class, but that way lies madness, surely).

 Hmm.

 struct assign;
 struct base {
   operator assign *() const { return (assign *)this; }
 };
 struct assign : base {
 };

 void foo (assign *);
 void bar (base *b)
 {
   foo (b);
 }

 doesn't work, but

 void bar (base b)
 {
   foo (b);
 }

 does.  Indeed C++ doesn't seem to provide what is necessary
 for the compat trick :(

 So the gimple-compat.h header would need to 

Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-17 Thread Richard Biener
On Sat, Nov 15, 2014 at 12:00 PM, David Malcolm dmalc...@redhat.com wrote:
 On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
 On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm dmalc...@redhat.com wrote:
  On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
  On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com wrote:
   On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
   On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
 To be constructive here - the above case is from within a
 GIMPLE_ASSIGN case label
 and thus I'd have expected

 case GIMPLE_ASSIGN:
   {
 gassign *a1 = as_a gassign * (s1);
 gassign *a2 = as_a gassign * (s2);
   lhs1 = gimple_assign_lhs (a1);
   lhs2 = gimple_assign_lhs (a2);
   if (TREE_CODE (lhs1) != SSA_NAME
TREE_CODE (lhs2) != SSA_NAME)
 return (operand_equal_p (lhs1, lhs2, 0)
  gimple_operand_equal_value_p 
 (gimple_assign_rhs1 (a1),
  
 gimple_assign_rhs1 (a2)));
   else if (TREE_CODE (lhs1) == SSA_NAME
 TREE_CODE (lhs2) == SSA_NAME)
 return vn_valueize (lhs1) == vn_valueize (lhs2);
   return false;
   }

 instead.  That's the kind of changes I have expected and have 
 approved of.
   
But even that looks like just adding extra work for all developers, 
with no
gain.  You only have to add extra code and extra temporaries, in 
switches
typically also have to add {} because of the temporaries and thus 
extra
indentation level, and it doesn't simplify anything in the code.
  
   The branch attempts to use the C++ typesystem to capture information
   about the kinds of gimple statement we expect, both:
 (A) so that the compiler can detect type errors, and
 (B) as a comprehension aid to the human reader of the code
  
   The ideal here is when function params and struct field can be
   strengthened from gimple to a subclass ptr.  This captures the
   knowledge that every use of a function or within a struct has a given
   gimple code.
  
   I just don't like all the as_a/is_a stuff enforced everywhere,
   it means more typing, more temporaries, more indentation.
   So, as I view it, instead of the checks being done cheaply (yes, I think
   the gimple checking as we have right now is very cheap) under the
   hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
   put the burden on the developers, who has to check that manually through
   the as_a/is_a stuff everywhere, more typing and uglier syntax.
   I just don't see that as a step forward, instead a huge step backwards.
   But perhaps I'm alone with this.
   Can you e.g. compare the size of - lines in your patchset combined, and
   size of + lines in your patchset?  As in, if your changes lead to less
   typing or more.
 
  I see two ways out here.  One is to add overloads to all the functions
  taking the special types like
 
  tree
  gimple_assign_rhs1 (gimple *);
 
  or simply add
 
  gassign *operator ()(gimple *g) { return as_a gassign * (g); }
 
  into a gimple-compat.h header which you include in places that
  are not converted nicely.
 
  Thanks for the suggestions.
 
  Am I missing something, or is the gimple-compat.h idea above not valid C
  ++?
 
  Note that gimple is still a typedef to
gimple_statement_base *
  (as noted before, the gimple - gimple * change would break everyone
  else's patches, so we talked about that as a followup patch for early
  stage3).
 
  Given that, if I try to create an operator () outside of a class, I
  get this error:
 
  ‘gassign* operator()(gimple)’ must be a nonstatic member function
 
  which is emitted from cp/decl.c's grok_op_properties:
/* An operator function must either be a non-static member function
   or have at least one parameter of a class, a reference to a class,
   an enumeration, or a reference to an enumeration.  13.4.0.6 */
 
  I tried making it a member function of gimple_statement_base, but that
  doesn't work either: we want a conversion
from a gimple_statement_base * to a gassign *, not
from a gimple_statement_base   to a gassign *.
 
  Is there some syntactic trick here that I'm missing?  Sorry if I'm being
  dumb (I can imagine there's a way of doing it by making gimple become
  some kind of wrapped ptr class, but that way lies madness, surely).

 Hmm.

 struct assign;
 struct base {
   operator assign *() const { return (assign *)this; }
 };
 struct assign : base {
 };

 void foo (assign *);
 void bar (base *b)
 {
   foo (b);
 }

 doesn't work, but

 void bar (base b)
 {
   foo (b);
 }

 does.  Indeed C++ doesn't seem to provide what is necessary
 for the compat trick :(

 So the gimple-compat.h header would need to 

Re: [PATCH] Add gimple-compat.h (was Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign)

2014-11-17 Thread Jeff Law

On 11/14/14 08:27, David Malcolm wrote:


I just don't like all the as_a/is_a stuff enforced everywhere,
it means more typing, more temporaries, more indentation.
So, as I view it, instead of the checks being done cheaply (yes, I think
the gimple checking as we have right now is very cheap) under the
hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
put the burden on the developers, who has to check that manually through
the as_a/is_a stuff everywhere, more typing and uglier syntax.
I just don't see that as a step forward, instead a huge step backwards.
But perhaps I'm alone with this.
Can you e.g. compare the size of - lines in your patchset combined, and
size of + lines in your patchset?  As in, if your changes lead to less
typing or more.

So, I'm chiming in a bit late, but just want to touch on a few things.

First, as I've stated before, I see as_a/is_a as generally a wart for 
things we still need to cleanup and redesign.  I do not want to see them 
sprinkled throughout GCC.  If we find ourselves adding a bunch of these, 
then we've got some redesign/rethinking that needs to be done.


Yes, I know some will be necessary and some are more like markers for 
the limits of where we are with the gimple class work, particularly 
since we're trying to stage in this work rather than convert everything 
at once (which I believe, realistically, is impossible).





I see two ways out here.  One is to add overloads to all the functions
taking the special types like
IIRC Andrew was doing similar things as a temporary measure in the 
gimple/tree type work as well.  Basically the overloads were to allow 
the two schemes to co-exist while conversions were done with the express 
intent that the overloads were to disappear when conversion is complete. 
 I'd be comfortable with a similar mechanism for this work as well.




Option 3: only convert the easy accessors: the ones I already did in
the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
which is this 92-patch kit:
   [gimple-classes, committed 00/92] Initial slew of commits:
  https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
Doing so converts about half of the gimple_foo_ accessors to taking a
gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use.   I believe
the quality of those patches was higher than the later ones on the
branch: I was doing the places that didn't require the invasive/verbose
changes seen in the later patches.  Shelve the remaining ~80
increasingly ugly patches, starting a new branch to contain just the
good ones.
And this would be my preferred option for where we are today.  That ~89 
kit was a step in the right direction.  I think going beyond that for 
the close of stage1 was ambitious :-)




Works for me as well.  The compat solution looks somewhat appealing
as we can then incrementally fix up things rather than requiring to
mass-convert everything.
Exactly.  And it's real easy to see what's depending on those overloads 
as one can simply remove them and try to build.  In many ways, I'd 
prefer the temporary overload solution for the next round of work in 
this space so that conversions can occur piecemeal instead of in large 
series patchsets.


I've got no objection if we have the compat hack in now.   I haven't 
reviewed that work, just no philosophical objections :-)  I would be 
opposed to pushing the gimple class work further than that prior to the 
next stage1 opening.



jeff



Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-17 Thread Jeff Law

On 11/17/14 03:06, Richard Biener wrote:





Also, presumably if this were merged, it would require a followup with
the gimple to gimple * fixup you wanted? (which we talked about doing as
an early stage3 thing IIRC [1]).


Yeah, that would be nice (to remind people - this is about getting rid
of const_gimple and thus avoids introducing tons of new const_
for all the subclasses).

Right.  Mirrors what we've done for INSNs in RTL as well.

jeff



Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-17 Thread David Malcolm
On Mon, 2014-11-17 at 11:06 +0100, Richard Biener wrote:
 On Sat, Nov 15, 2014 at 12:00 PM, David Malcolm dmalc...@redhat.com wrote:
  On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
  On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm dmalc...@redhat.com wrote:
   On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
   On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com wrote:
On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
 On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
  To be constructive here - the above case is from within a
  GIMPLE_ASSIGN case label
  and thus I'd have expected
 
  case GIMPLE_ASSIGN:
{
  gassign *a1 = as_a gassign * (s1);
  gassign *a2 = as_a gassign * (s2);
lhs1 = gimple_assign_lhs (a1);
lhs2 = gimple_assign_lhs (a2);
if (TREE_CODE (lhs1) != SSA_NAME
 TREE_CODE (lhs2) != SSA_NAME)
  return (operand_equal_p (lhs1, lhs2, 0)
   gimple_operand_equal_value_p 
  (gimple_assign_rhs1 (a1),
   
  gimple_assign_rhs1 (a2)));
else if (TREE_CODE (lhs1) == SSA_NAME
  TREE_CODE (lhs2) == SSA_NAME)
  return vn_valueize (lhs1) == vn_valueize (lhs2);
return false;
}
 
  instead.  That's the kind of changes I have expected and have 
  approved of.

 But even that looks like just adding extra work for all 
 developers, with no
 gain.  You only have to add extra code and extra temporaries, in 
 switches
 typically also have to add {} because of the temporaries and thus 
 extra
 indentation level, and it doesn't simplify anything in the code.
   
The branch attempts to use the C++ typesystem to capture information
about the kinds of gimple statement we expect, both:
  (A) so that the compiler can detect type errors, and
  (B) as a comprehension aid to the human reader of the code
   
The ideal here is when function params and struct field can be
strengthened from gimple to a subclass ptr.  This captures the
knowledge that every use of a function or within a struct has a given
gimple code.
   
I just don't like all the as_a/is_a stuff enforced everywhere,
it means more typing, more temporaries, more indentation.
So, as I view it, instead of the checks being done cheaply (yes, I 
think
the gimple checking as we have right now is very cheap) under the
hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
put the burden on the developers, who has to check that manually 
through
the as_a/is_a stuff everywhere, more typing and uglier syntax.
I just don't see that as a step forward, instead a huge step 
backwards.
But perhaps I'm alone with this.
Can you e.g. compare the size of - lines in your patchset combined, 
and
size of + lines in your patchset?  As in, if your changes lead to less
typing or more.
  
   I see two ways out here.  One is to add overloads to all the functions
   taking the special types like
  
   tree
   gimple_assign_rhs1 (gimple *);
  
   or simply add
  
   gassign *operator ()(gimple *g) { return as_a gassign * (g); }
  
   into a gimple-compat.h header which you include in places that
   are not converted nicely.
  
   Thanks for the suggestions.
  
   Am I missing something, or is the gimple-compat.h idea above not valid C
   ++?
  
   Note that gimple is still a typedef to
 gimple_statement_base *
   (as noted before, the gimple - gimple * change would break everyone
   else's patches, so we talked about that as a followup patch for early
   stage3).
  
   Given that, if I try to create an operator () outside of a class, I
   get this error:
  
   ‘gassign* operator()(gimple)’ must be a nonstatic member function
  
   which is emitted from cp/decl.c's grok_op_properties:
 /* An operator function must either be a non-static member function
or have at least one parameter of a class, a reference to a 
   class,
an enumeration, or a reference to an enumeration.  13.4.0.6 */
  
   I tried making it a member function of gimple_statement_base, but that
   doesn't work either: we want a conversion
 from a gimple_statement_base * to a gassign *, not
 from a gimple_statement_base   to a gassign *.
  
   Is there some syntactic trick here that I'm missing?  Sorry if I'm being
   dumb (I can imagine there's a way of doing it by making gimple become
   some kind of wrapped ptr class, but that way lies madness, surely).
 
  Hmm.
 
  struct assign;
  struct base {
operator assign *() const { return (assign *)this; }
  };
  struct assign : base {
  };
 
  void foo (assign *);
  void bar (base *b)
  {
foo 

Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-15 Thread David Malcolm
On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
 On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm dmalc...@redhat.com wrote:
  On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
  On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com wrote:
   On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
   On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
 To be constructive here - the above case is from within a
 GIMPLE_ASSIGN case label
 and thus I'd have expected

 case GIMPLE_ASSIGN:
   {
 gassign *a1 = as_a gassign * (s1);
 gassign *a2 = as_a gassign * (s2);
   lhs1 = gimple_assign_lhs (a1);
   lhs2 = gimple_assign_lhs (a2);
   if (TREE_CODE (lhs1) != SSA_NAME
TREE_CODE (lhs2) != SSA_NAME)
 return (operand_equal_p (lhs1, lhs2, 0)
  gimple_operand_equal_value_p (gimple_assign_rhs1 
 (a1),
  gimple_assign_rhs1 
 (a2)));
   else if (TREE_CODE (lhs1) == SSA_NAME
 TREE_CODE (lhs2) == SSA_NAME)
 return vn_valueize (lhs1) == vn_valueize (lhs2);
   return false;
   }

 instead.  That's the kind of changes I have expected and have 
 approved of.
   
But even that looks like just adding extra work for all developers, 
with no
gain.  You only have to add extra code and extra temporaries, in 
switches
typically also have to add {} because of the temporaries and thus 
extra
indentation level, and it doesn't simplify anything in the code.
  
   The branch attempts to use the C++ typesystem to capture information
   about the kinds of gimple statement we expect, both:
 (A) so that the compiler can detect type errors, and
 (B) as a comprehension aid to the human reader of the code
  
   The ideal here is when function params and struct field can be
   strengthened from gimple to a subclass ptr.  This captures the
   knowledge that every use of a function or within a struct has a given
   gimple code.
  
   I just don't like all the as_a/is_a stuff enforced everywhere,
   it means more typing, more temporaries, more indentation.
   So, as I view it, instead of the checks being done cheaply (yes, I think
   the gimple checking as we have right now is very cheap) under the
   hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
   put the burden on the developers, who has to check that manually through
   the as_a/is_a stuff everywhere, more typing and uglier syntax.
   I just don't see that as a step forward, instead a huge step backwards.
   But perhaps I'm alone with this.
   Can you e.g. compare the size of - lines in your patchset combined, and
   size of + lines in your patchset?  As in, if your changes lead to less
   typing or more.
 
  I see two ways out here.  One is to add overloads to all the functions
  taking the special types like
 
  tree
  gimple_assign_rhs1 (gimple *);
 
  or simply add
 
  gassign *operator ()(gimple *g) { return as_a gassign * (g); }
 
  into a gimple-compat.h header which you include in places that
  are not converted nicely.
 
  Thanks for the suggestions.
 
  Am I missing something, or is the gimple-compat.h idea above not valid C
  ++?
 
  Note that gimple is still a typedef to
gimple_statement_base *
  (as noted before, the gimple - gimple * change would break everyone
  else's patches, so we talked about that as a followup patch for early
  stage3).
 
  Given that, if I try to create an operator () outside of a class, I
  get this error:
 
  ‘gassign* operator()(gimple)’ must be a nonstatic member function
 
  which is emitted from cp/decl.c's grok_op_properties:
/* An operator function must either be a non-static member function
   or have at least one parameter of a class, a reference to a class,
   an enumeration, or a reference to an enumeration.  13.4.0.6 */
 
  I tried making it a member function of gimple_statement_base, but that
  doesn't work either: we want a conversion
from a gimple_statement_base * to a gassign *, not
from a gimple_statement_base   to a gassign *.
 
  Is there some syntactic trick here that I'm missing?  Sorry if I'm being
  dumb (I can imagine there's a way of doing it by making gimple become
  some kind of wrapped ptr class, but that way lies madness, surely).
 
 Hmm.
 
 struct assign;
 struct base {
   operator assign *() const { return (assign *)this; }
 };
 struct assign : base {
 };
 
 void foo (assign *);
 void bar (base *b)
 {
   foo (b);
 }
 
 doesn't work, but
 
 void bar (base b)
 {
   foo (b);
 }
 
 does.  Indeed C++ doesn't seem to provide what is necessary
 for the compat trick :(
 
 So the gimple-compat.h header would need to provide
 additional overloads for the affected functions like
 
 inline 

[PATCH] Add gimple-compat.h (was Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign)

2014-11-14 Thread David Malcolm
On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote:
 On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm dmalc...@redhat.com wrote:
  On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
  On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com wrote:
   On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
   On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
 To be constructive here - the above case is from within a
 GIMPLE_ASSIGN case label
 and thus I'd have expected

 case GIMPLE_ASSIGN:
   {
 gassign *a1 = as_a gassign * (s1);
 gassign *a2 = as_a gassign * (s2);
   lhs1 = gimple_assign_lhs (a1);
   lhs2 = gimple_assign_lhs (a2);
   if (TREE_CODE (lhs1) != SSA_NAME
TREE_CODE (lhs2) != SSA_NAME)
 return (operand_equal_p (lhs1, lhs2, 0)
  gimple_operand_equal_value_p (gimple_assign_rhs1 
 (a1),
  gimple_assign_rhs1 
 (a2)));
   else if (TREE_CODE (lhs1) == SSA_NAME
 TREE_CODE (lhs2) == SSA_NAME)
 return vn_valueize (lhs1) == vn_valueize (lhs2);
   return false;
   }

 instead.  That's the kind of changes I have expected and have 
 approved of.
   
But even that looks like just adding extra work for all developers, 
with no
gain.  You only have to add extra code and extra temporaries, in 
switches
typically also have to add {} because of the temporaries and thus 
extra
indentation level, and it doesn't simplify anything in the code.
  
   The branch attempts to use the C++ typesystem to capture information
   about the kinds of gimple statement we expect, both:
 (A) so that the compiler can detect type errors, and
 (B) as a comprehension aid to the human reader of the code
  
   The ideal here is when function params and struct field can be
   strengthened from gimple to a subclass ptr.  This captures the
   knowledge that every use of a function or within a struct has a given
   gimple code.
  
   I just don't like all the as_a/is_a stuff enforced everywhere,
   it means more typing, more temporaries, more indentation.
   So, as I view it, instead of the checks being done cheaply (yes, I think
   the gimple checking as we have right now is very cheap) under the
   hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
   put the burden on the developers, who has to check that manually through
   the as_a/is_a stuff everywhere, more typing and uglier syntax.
   I just don't see that as a step forward, instead a huge step backwards.
   But perhaps I'm alone with this.
   Can you e.g. compare the size of - lines in your patchset combined, and
   size of + lines in your patchset?  As in, if your changes lead to less
   typing or more.
 
  I see two ways out here.  One is to add overloads to all the functions
  taking the special types like
 
  tree
  gimple_assign_rhs1 (gimple *);
 
  or simply add
 
  gassign *operator ()(gimple *g) { return as_a gassign * (g); }
 
  into a gimple-compat.h header which you include in places that
  are not converted nicely.
 
  Thanks for the suggestions.
 
  Am I missing something, or is the gimple-compat.h idea above not valid C
  ++?
 
  Note that gimple is still a typedef to
gimple_statement_base *
  (as noted before, the gimple - gimple * change would break everyone
  else's patches, so we talked about that as a followup patch for early
  stage3).
 
  Given that, if I try to create an operator () outside of a class, I
  get this error:
 
  ‘gassign* operator()(gimple)’ must be a nonstatic member function
 
  which is emitted from cp/decl.c's grok_op_properties:
/* An operator function must either be a non-static member function
   or have at least one parameter of a class, a reference to a class,
   an enumeration, or a reference to an enumeration.  13.4.0.6 */
 
  I tried making it a member function of gimple_statement_base, but that
  doesn't work either: we want a conversion
from a gimple_statement_base * to a gassign *, not
from a gimple_statement_base   to a gassign *.
 
  Is there some syntactic trick here that I'm missing?  Sorry if I'm being
  dumb (I can imagine there's a way of doing it by making gimple become
  some kind of wrapped ptr class, but that way lies madness, surely).
 
 Hmm.
 
 struct assign;
 struct base {
   operator assign *() const { return (assign *)this; }
 };
 struct assign : base {
 };
 
 void foo (assign *);
 void bar (base *b)
 {
   foo (b);
 }
 
 doesn't work, but
 
 void bar (base b)
 {
   foo (b);
 }
 
 does.  Indeed C++ doesn't seem to provide what is necessary
 for the compat trick :(
 
 So the gimple-compat.h header would need to provide
 additional overloads for the affected functions like
 
 inline 

Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-13 Thread Richard Biener
On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm dmalc...@redhat.com wrote:
 On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
 On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com wrote:
  On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
  On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
   On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
To be constructive here - the above case is from within a
GIMPLE_ASSIGN case label
and thus I'd have expected
   
case GIMPLE_ASSIGN:
  {
gassign *a1 = as_a gassign * (s1);
gassign *a2 = as_a gassign * (s2);
  lhs1 = gimple_assign_lhs (a1);
  lhs2 = gimple_assign_lhs (a2);
  if (TREE_CODE (lhs1) != SSA_NAME
   TREE_CODE (lhs2) != SSA_NAME)
return (operand_equal_p (lhs1, lhs2, 0)
 gimple_operand_equal_value_p (gimple_assign_rhs1 
(a1),
 gimple_assign_rhs1 
(a2)));
  else if (TREE_CODE (lhs1) == SSA_NAME
TREE_CODE (lhs2) == SSA_NAME)
return vn_valueize (lhs1) == vn_valueize (lhs2);
  return false;
  }
   
instead.  That's the kind of changes I have expected and have 
approved of.
  
   But even that looks like just adding extra work for all developers, 
   with no
   gain.  You only have to add extra code and extra temporaries, in 
   switches
   typically also have to add {} because of the temporaries and thus extra
   indentation level, and it doesn't simplify anything in the code.
 
  The branch attempts to use the C++ typesystem to capture information
  about the kinds of gimple statement we expect, both:
(A) so that the compiler can detect type errors, and
(B) as a comprehension aid to the human reader of the code
 
  The ideal here is when function params and struct field can be
  strengthened from gimple to a subclass ptr.  This captures the
  knowledge that every use of a function or within a struct has a given
  gimple code.
 
  I just don't like all the as_a/is_a stuff enforced everywhere,
  it means more typing, more temporaries, more indentation.
  So, as I view it, instead of the checks being done cheaply (yes, I think
  the gimple checking as we have right now is very cheap) under the
  hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
  put the burden on the developers, who has to check that manually through
  the as_a/is_a stuff everywhere, more typing and uglier syntax.
  I just don't see that as a step forward, instead a huge step backwards.
  But perhaps I'm alone with this.
  Can you e.g. compare the size of - lines in your patchset combined, and
  size of + lines in your patchset?  As in, if your changes lead to less
  typing or more.

 I see two ways out here.  One is to add overloads to all the functions
 taking the special types like

 tree
 gimple_assign_rhs1 (gimple *);

 or simply add

 gassign *operator ()(gimple *g) { return as_a gassign * (g); }

 into a gimple-compat.h header which you include in places that
 are not converted nicely.

 Thanks for the suggestions.

 Am I missing something, or is the gimple-compat.h idea above not valid C
 ++?

 Note that gimple is still a typedef to
   gimple_statement_base *
 (as noted before, the gimple - gimple * change would break everyone
 else's patches, so we talked about that as a followup patch for early
 stage3).

 Given that, if I try to create an operator () outside of a class, I
 get this error:

 ‘gassign* operator()(gimple)’ must be a nonstatic member function

 which is emitted from cp/decl.c's grok_op_properties:
   /* An operator function must either be a non-static member function
  or have at least one parameter of a class, a reference to a class,
  an enumeration, or a reference to an enumeration.  13.4.0.6 */

 I tried making it a member function of gimple_statement_base, but that
 doesn't work either: we want a conversion
   from a gimple_statement_base * to a gassign *, not
   from a gimple_statement_base   to a gassign *.

 Is there some syntactic trick here that I'm missing?  Sorry if I'm being
 dumb (I can imagine there's a way of doing it by making gimple become
 some kind of wrapped ptr class, but that way lies madness, surely).

Hmm.

struct assign;
struct base {
  operator assign *() const { return (assign *)this; }
};
struct assign : base {
};

void foo (assign *);
void bar (base *b)
{
  foo (b);
}

doesn't work, but

void bar (base b)
{
  foo (b);
}

does.  Indeed C++ doesn't seem to provide what is necessary
for the compat trick :(

So the gimple-compat.h header would need to provide
additional overloads for the affected functions like

inline tree
gimple_assign_rhs1 (gimple *g)
{
  return gimple_assign_rhs1 (as_a gassign * (g));
}

that would work for me as well.

 Both avoid manually making the compiler happy (which the
 explicit as_a 

Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-13 Thread Jonathan Wakely
On 13 November 2014 10:45, Richard Biener wrote:

 Hmm.

 struct assign;
 struct base {
   operator assign *() const { return (assign *)this; }
 };
 struct assign : base {
 };

 void foo (assign *);
 void bar (base *b)
 {
   foo (b);
 }

 doesn't work, but

 void bar (base b)
 {
   foo (b);
 }

 does.  Indeed C++ doesn't seem to provide what is necessary
 for the compat trick :(

Right, base* is a built-in type, you can't call a member function on it.

There is no implicit conversion between unrelated pointer types, and
no implicit conversion from base* to base that would be necessary to
call the conversion operator of base.


Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-13 Thread Andrew MacLeod

On 11/13/2014 05:45 AM, Richard Biener wrote:

On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm dmalc...@redhat.com wrote:

On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:

On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com wrote:

On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:

On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:

On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:

To be constructive here - the above case is from within a
GIMPLE_ASSIGN case label
and thus I'd have expected

 case GIMPLE_ASSIGN:
   {
 gassign *a1 = as_a gassign * (s1);
 gassign *a2 = as_a gassign * (s2);
   lhs1 = gimple_assign_lhs (a1);
   lhs2 = gimple_assign_lhs (a2);
   if (TREE_CODE (lhs1) != SSA_NAME
TREE_CODE (lhs2) != SSA_NAME)
 return (operand_equal_p (lhs1, lhs2, 0)
  gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
  gimple_assign_rhs1 (a2)));
   else if (TREE_CODE (lhs1) == SSA_NAME
 TREE_CODE (lhs2) == SSA_NAME)
 return vn_valueize (lhs1) == vn_valueize (lhs2);
   return false;
   }

instead.  That's the kind of changes I have expected and have approved of.

But even that looks like just adding extra work for all developers, with no
gain.  You only have to add extra code and extra temporaries, in switches
typically also have to add {} because of the temporaries and thus extra
indentation level, and it doesn't simplify anything in the code.

The branch attempts to use the C++ typesystem to capture information
about the kinds of gimple statement we expect, both:
   (A) so that the compiler can detect type errors, and
   (B) as a comprehension aid to the human reader of the code

The ideal here is when function params and struct field can be
strengthened from gimple to a subclass ptr.  This captures the
knowledge that every use of a function or within a struct has a given
gimple code.

I just don't like all the as_a/is_a stuff enforced everywhere,
it means more typing, more temporaries, more indentation.
So, as I view it, instead of the checks being done cheaply (yes, I think
the gimple checking as we have right now is very cheap) under the
hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
put the burden on the developers, who has to check that manually through
the as_a/is_a stuff everywhere, more typing and uglier syntax.
I just don't see that as a step forward, instead a huge step backwards.
But perhaps I'm alone with this.
Can you e.g. compare the size of - lines in your patchset combined, and
size of + lines in your patchset?  As in, if your changes lead to less
typing or more.

I see two ways out here.  One is to add overloads to all the functions
taking the special types like

tree
gimple_assign_rhs1 (gimple *);

or simply add

gassign *operator ()(gimple *g) { return as_a gassign * (g); }

into a gimple-compat.h header which you include in places that
are not converted nicely.

Thanks for the suggestions.

Am I missing something, or is the gimple-compat.h idea above not valid C
++?

Note that gimple is still a typedef to
   gimple_statement_base *
(as noted before, the gimple - gimple * change would break everyone
else's patches, so we talked about that as a followup patch for early
stage3).

Given that, if I try to create an operator () outside of a class, I
get this error:

‘gassign* operator()(gimple)’ must be a nonstatic member function

which is emitted from cp/decl.c's grok_op_properties:
   /* An operator function must either be a non-static member function
  or have at least one parameter of a class, a reference to a class,
  an enumeration, or a reference to an enumeration.  13.4.0.6 */

I tried making it a member function of gimple_statement_base, but that
doesn't work either: we want a conversion
   from a gimple_statement_base * to a gassign *, not
   from a gimple_statement_base   to a gassign *.

Is there some syntactic trick here that I'm missing?  Sorry if I'm being
dumb (I can imagine there's a way of doing it by making gimple become
some kind of wrapped ptr class, but that way lies madness, surely).

Hmm.

struct assign;
struct base {
   operator assign *() const { return (assign *)this; }
};
struct assign : base {
};

void foo (assign *);
void bar (base *b)
{
   foo (b);
}

doesn't work, but

void bar (base b)
{
   foo (b);
}

does.  Indeed C++ doesn't seem to provide what is necessary
for the compat trick :(

So the gimple-compat.h header would need to provide
additional overloads for the affected functions like

inline tree
gimple_assign_rhs1 (gimple *g)
{
   return gimple_assign_rhs1 (as_a gassign * (g));
}

that would work for me as well.


Won't that defeat the desire for checking tho?  If you dont do a 
dyn_cast  in gimple_assign_rhs1 (gimple *g)  anyone can call it and 
upcast any kind of gimple into a gassign without checking 

Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-13 Thread Richard Biener
On Thu, Nov 13, 2014 at 3:24 PM, Andrew MacLeod amacl...@redhat.com wrote:
 On 11/13/2014 05:45 AM, Richard Biener wrote:

 On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm dmalc...@redhat.com
 wrote:

 On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:

 On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com wrote:

 On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:

 On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:

 On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:

 To be constructive here - the above case is from within a
 GIMPLE_ASSIGN case label
 and thus I'd have expected

  case GIMPLE_ASSIGN:
{
  gassign *a1 = as_a gassign * (s1);
  gassign *a2 = as_a gassign * (s2);
lhs1 = gimple_assign_lhs (a1);
lhs2 = gimple_assign_lhs (a2);
if (TREE_CODE (lhs1) != SSA_NAME
 TREE_CODE (lhs2) != SSA_NAME)
  return (operand_equal_p (lhs1, lhs2, 0)
   gimple_operand_equal_value_p (gimple_assign_rhs1
 (a1),
   gimple_assign_rhs1
 (a2)));
else if (TREE_CODE (lhs1) == SSA_NAME
  TREE_CODE (lhs2) == SSA_NAME)
  return vn_valueize (lhs1) == vn_valueize (lhs2);
return false;
}

 instead.  That's the kind of changes I have expected and have
 approved of.

 But even that looks like just adding extra work for all developers,
 with no
 gain.  You only have to add extra code and extra temporaries, in
 switches
 typically also have to add {} because of the temporaries and thus
 extra
 indentation level, and it doesn't simplify anything in the code.

 The branch attempts to use the C++ typesystem to capture information
 about the kinds of gimple statement we expect, both:
(A) so that the compiler can detect type errors, and
(B) as a comprehension aid to the human reader of the code

 The ideal here is when function params and struct field can be
 strengthened from gimple to a subclass ptr.  This captures the
 knowledge that every use of a function or within a struct has a given
 gimple code.

 I just don't like all the as_a/is_a stuff enforced everywhere,
 it means more typing, more temporaries, more indentation.
 So, as I view it, instead of the checks being done cheaply (yes, I
 think
 the gimple checking as we have right now is very cheap) under the
 hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
 put the burden on the developers, who has to check that manually
 through
 the as_a/is_a stuff everywhere, more typing and uglier syntax.
 I just don't see that as a step forward, instead a huge step backwards.
 But perhaps I'm alone with this.
 Can you e.g. compare the size of - lines in your patchset combined, and
 size of + lines in your patchset?  As in, if your changes lead to less
 typing or more.

 I see two ways out here.  One is to add overloads to all the functions
 taking the special types like

 tree
 gimple_assign_rhs1 (gimple *);

 or simply add

 gassign *operator ()(gimple *g) { return as_a gassign * (g); }

 into a gimple-compat.h header which you include in places that
 are not converted nicely.

 Thanks for the suggestions.

 Am I missing something, or is the gimple-compat.h idea above not valid C
 ++?

 Note that gimple is still a typedef to
gimple_statement_base *
 (as noted before, the gimple - gimple * change would break everyone
 else's patches, so we talked about that as a followup patch for early
 stage3).

 Given that, if I try to create an operator () outside of a class, I
 get this error:

 ‘gassign* operator()(gimple)’ must be a nonstatic member function

 which is emitted from cp/decl.c's grok_op_properties:
/* An operator function must either be a non-static member
 function
   or have at least one parameter of a class, a reference to a
 class,
   an enumeration, or a reference to an enumeration.  13.4.0.6 */

 I tried making it a member function of gimple_statement_base, but that
 doesn't work either: we want a conversion
from a gimple_statement_base * to a gassign *, not
from a gimple_statement_base   to a gassign *.

 Is there some syntactic trick here that I'm missing?  Sorry if I'm being
 dumb (I can imagine there's a way of doing it by making gimple become
 some kind of wrapped ptr class, but that way lies madness, surely).

 Hmm.

 struct assign;
 struct base {
operator assign *() const { return (assign *)this; }
 };
 struct assign : base {
 };

 void foo (assign *);
 void bar (base *b)
 {
foo (b);
 }

 doesn't work, but

 void bar (base b)
 {
foo (b);
 }

 does.  Indeed C++ doesn't seem to provide what is necessary
 for the compat trick :(

 So the gimple-compat.h header would need to provide
 additional overloads for the affected functions like

 inline tree
 gimple_assign_rhs1 (gimple *g)
 {
return gimple_assign_rhs1 (as_a gassign * (g));
 }

 that would work for me as well.


 

Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-13 Thread Andrew MacLeod

On 11/13/2014 09:34 AM, Richard Biener wrote:

On Thu, Nov 13, 2014 at 3:24 PM, Andrew MacLeod amacl...@redhat.com wrote:

On 11/13/2014 05:45 AM, Richard Biener wrote:

On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm dmalc...@redhat.com
wrote:

On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:

On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com wrote:

On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:

On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:

On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:

To be constructive here - the above case is from within a
GIMPLE_ASSIGN case label
and thus I'd have expected

  case GIMPLE_ASSIGN:
{
  gassign *a1 = as_a gassign * (s1);
  gassign *a2 = as_a gassign * (s2);
lhs1 = gimple_assign_lhs (a1);
lhs2 = gimple_assign_lhs (a2);
if (TREE_CODE (lhs1) != SSA_NAME
 TREE_CODE (lhs2) != SSA_NAME)
  return (operand_equal_p (lhs1, lhs2, 0)
   gimple_operand_equal_value_p (gimple_assign_rhs1
(a1),
   gimple_assign_rhs1
(a2)));
else if (TREE_CODE (lhs1) == SSA_NAME
  TREE_CODE (lhs2) == SSA_NAME)
  return vn_valueize (lhs1) == vn_valueize (lhs2);
return false;
}

instead.  That's the kind of changes I have expected and have
approved of.

But even that looks like just adding extra work for all developers,
with no
gain.  You only have to add extra code and extra temporaries, in
switches
typically also have to add {} because of the temporaries and thus
extra
indentation level, and it doesn't simplify anything in the code.

The branch attempts to use the C++ typesystem to capture information
about the kinds of gimple statement we expect, both:
(A) so that the compiler can detect type errors, and
(B) as a comprehension aid to the human reader of the code

The ideal here is when function params and struct field can be
strengthened from gimple to a subclass ptr.  This captures the
knowledge that every use of a function or within a struct has a given
gimple code.

I just don't like all the as_a/is_a stuff enforced everywhere,
it means more typing, more temporaries, more indentation.
So, as I view it, instead of the checks being done cheaply (yes, I
think
the gimple checking as we have right now is very cheap) under the
hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
put the burden on the developers, who has to check that manually
through
the as_a/is_a stuff everywhere, more typing and uglier syntax.
I just don't see that as a step forward, instead a huge step backwards.
But perhaps I'm alone with this.
Can you e.g. compare the size of - lines in your patchset combined, and
size of + lines in your patchset?  As in, if your changes lead to less
typing or more.

I see two ways out here.  One is to add overloads to all the functions
taking the special types like

tree
gimple_assign_rhs1 (gimple *);

or simply add

gassign *operator ()(gimple *g) { return as_a gassign * (g); }

into a gimple-compat.h header which you include in places that
are not converted nicely.

Thanks for the suggestions.

Am I missing something, or is the gimple-compat.h idea above not valid C
++?

Note that gimple is still a typedef to
gimple_statement_base *
(as noted before, the gimple - gimple * change would break everyone
else's patches, so we talked about that as a followup patch for early
stage3).

Given that, if I try to create an operator () outside of a class, I
get this error:

‘gassign* operator()(gimple)’ must be a nonstatic member function

which is emitted from cp/decl.c's grok_op_properties:
/* An operator function must either be a non-static member
function
   or have at least one parameter of a class, a reference to a
class,
   an enumeration, or a reference to an enumeration.  13.4.0.6 */

I tried making it a member function of gimple_statement_base, but that
doesn't work either: we want a conversion
from a gimple_statement_base * to a gassign *, not
from a gimple_statement_base   to a gassign *.

Is there some syntactic trick here that I'm missing?  Sorry if I'm being
dumb (I can imagine there's a way of doing it by making gimple become
some kind of wrapped ptr class, but that way lies madness, surely).

Hmm.

struct assign;
struct base {
operator assign *() const { return (assign *)this; }
};
struct assign : base {
};

void foo (assign *);
void bar (base *b)
{
foo (b);
}

doesn't work, but

void bar (base b)
{
foo (b);
}

does.  Indeed C++ doesn't seem to provide what is necessary
for the compat trick :(

So the gimple-compat.h header would need to provide
additional overloads for the affected functions like

inline tree
gimple_assign_rhs1 (gimple *g)
{
return gimple_assign_rhs1 (as_a gassign * (g));
}

that would work for me as well.



Won't that defeat the desire for checking 

Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-12 Thread David Malcolm
On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote:
 On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com wrote:
  On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
  On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
   On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
To be constructive here - the above case is from within a
GIMPLE_ASSIGN case label
and thus I'd have expected
   
case GIMPLE_ASSIGN:
  {
gassign *a1 = as_a gassign * (s1);
gassign *a2 = as_a gassign * (s2);
  lhs1 = gimple_assign_lhs (a1);
  lhs2 = gimple_assign_lhs (a2);
  if (TREE_CODE (lhs1) != SSA_NAME
   TREE_CODE (lhs2) != SSA_NAME)
return (operand_equal_p (lhs1, lhs2, 0)
 gimple_operand_equal_value_p (gimple_assign_rhs1 
(a1),
 gimple_assign_rhs1 
(a2)));
  else if (TREE_CODE (lhs1) == SSA_NAME
TREE_CODE (lhs2) == SSA_NAME)
return vn_valueize (lhs1) == vn_valueize (lhs2);
  return false;
  }
   
instead.  That's the kind of changes I have expected and have approved 
of.
  
   But even that looks like just adding extra work for all developers, with 
   no
   gain.  You only have to add extra code and extra temporaries, in switches
   typically also have to add {} because of the temporaries and thus extra
   indentation level, and it doesn't simplify anything in the code.
 
  The branch attempts to use the C++ typesystem to capture information
  about the kinds of gimple statement we expect, both:
(A) so that the compiler can detect type errors, and
(B) as a comprehension aid to the human reader of the code
 
  The ideal here is when function params and struct field can be
  strengthened from gimple to a subclass ptr.  This captures the
  knowledge that every use of a function or within a struct has a given
  gimple code.
 
  I just don't like all the as_a/is_a stuff enforced everywhere,
  it means more typing, more temporaries, more indentation.
  So, as I view it, instead of the checks being done cheaply (yes, I think
  the gimple checking as we have right now is very cheap) under the
  hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
  put the burden on the developers, who has to check that manually through
  the as_a/is_a stuff everywhere, more typing and uglier syntax.
  I just don't see that as a step forward, instead a huge step backwards.
  But perhaps I'm alone with this.
  Can you e.g. compare the size of - lines in your patchset combined, and
  size of + lines in your patchset?  As in, if your changes lead to less
  typing or more.
 
 I see two ways out here.  One is to add overloads to all the functions
 taking the special types like
 
 tree
 gimple_assign_rhs1 (gimple *);
 
 or simply add
 
 gassign *operator ()(gimple *g) { return as_a gassign * (g); }
 
 into a gimple-compat.h header which you include in places that
 are not converted nicely.

Thanks for the suggestions.

Am I missing something, or is the gimple-compat.h idea above not valid C
++?

Note that gimple is still a typedef to
  gimple_statement_base *
(as noted before, the gimple - gimple * change would break everyone
else's patches, so we talked about that as a followup patch for early
stage3).

Given that, if I try to create an operator () outside of a class, I
get this error:

‘gassign* operator()(gimple)’ must be a nonstatic member function

which is emitted from cp/decl.c's grok_op_properties:
  /* An operator function must either be a non-static member function
 or have at least one parameter of a class, a reference to a class,
 an enumeration, or a reference to an enumeration.  13.4.0.6 */

I tried making it a member function of gimple_statement_base, but that
doesn't work either: we want a conversion
  from a gimple_statement_base * to a gassign *, not
  from a gimple_statement_base   to a gassign *.

Is there some syntactic trick here that I'm missing?  Sorry if I'm being
dumb (I can imagine there's a way of doing it by making gimple become
some kind of wrapped ptr class, but that way lies madness, surely).

 Both avoid manually making the compiler happy (which the
 explicit as_a stuff is!  It doesn't add any checking - it's
 just placing the as_a at the callers and thus make the
 runtine ICE fire there).
 
 As much as I don't like global conversion operators I don't
 like adding overloads to all of the accessor functions even more.

(nods)

Some other options:

Option 3: only convert the easy accessors: the ones I already did in
the /89 patch kit, as reviewed by Jeff, and rebased by me recently,
which is this 92-patch kit:
  [gimple-classes, committed 00/92] Initial slew of commits:
 https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html
Doing so converts about half of the gimple_foo_ accessors to taking a

Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-12 Thread David Malcolm
On Tue, 2014-11-11 at 08:26 +0100, Jakub Jelinek wrote:
 On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
  On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
   On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
To be constructive here - the above case is from within a
GIMPLE_ASSIGN case label
and thus I'd have expected

case GIMPLE_ASSIGN:
  {
gassign *a1 = as_a gassign * (s1);
gassign *a2 = as_a gassign * (s2);
  lhs1 = gimple_assign_lhs (a1);
  lhs2 = gimple_assign_lhs (a2);
  if (TREE_CODE (lhs1) != SSA_NAME
   TREE_CODE (lhs2) != SSA_NAME)
return (operand_equal_p (lhs1, lhs2, 0)
 gimple_operand_equal_value_p (gimple_assign_rhs1 
(a1),
 gimple_assign_rhs1 
(a2)));
  else if (TREE_CODE (lhs1) == SSA_NAME
TREE_CODE (lhs2) == SSA_NAME)
return vn_valueize (lhs1) == vn_valueize (lhs2);
  return false;
  }

instead.  That's the kind of changes I have expected and have approved 
of.
   
   But even that looks like just adding extra work for all developers, with 
   no
   gain.  You only have to add extra code and extra temporaries, in switches
   typically also have to add {} because of the temporaries and thus extra
   indentation level, and it doesn't simplify anything in the code.
  
  The branch attempts to use the C++ typesystem to capture information
  about the kinds of gimple statement we expect, both:
(A) so that the compiler can detect type errors, and
(B) as a comprehension aid to the human reader of the code
  
  The ideal here is when function params and struct field can be
  strengthened from gimple to a subclass ptr.  This captures the
  knowledge that every use of a function or within a struct has a given
  gimple code.
 
 I just don't like all the as_a/is_a stuff enforced everywhere,
 it means more typing, more temporaries, more indentation.
 So, as I view it, instead of the checks being done cheaply (yes, I think
 the gimple checking as we have right now is very cheap) under the
 hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
 put the burden on the developers, who has to check that manually through
 the as_a/is_a stuff everywhere, more typing and uglier syntax.
 I just don't see that as a step forward, instead a huge step backwards.
 But perhaps I'm alone with this.

I agree with you w.r.t. my later patches.   I like my initial set of 89
patches, but I overdid things with the attempt to convert all of the
gimple_assign_ accessors.

 Can you e.g. compare the size of - lines in your patchset combined, and
 size of + lines in your patchset?  As in, if your changes lead to less
 typing or more.

I don't know if this data matches the proposed interpretation
(autoindentation in emacs is wonderful), but here goes:

Diff of my current working copy vs last merge point, ignoring ChangeLog
additions, obtaining lines starting -, piping into wc:

$ git diff fddbd0194b01f44c5b5f16379fd5405dcf6d71c0 $(git diff
fddbd0194b01f44c5b5f16379fd5405dcf6d71c0 | diffstat -lp1 | grep -v
ChangeLog) | grep -e ^- | wc
   6169   31032  272916

Likewise for lines starting with +:

$ git diff fddbd0194b01f44c5b5f16379fd5405dcf6d71c0 $(git diff
fddbd0194b01f44c5b5f16379fd5405dcf6d71c0 | diffstat -lp1 | grep -v
ChangeLog) | grep -e ^+ | wc
   7295   36566  309380

so the + lines have 13% more bytes than the - lines


Dave



Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-11 Thread Eric Botcazou
 I just don't like all the as_a/is_a stuff enforced everywhere,
 it means more typing, more temporaries, more indentation.
 So, as I view it, instead of the checks being done cheaply (yes, I think
 the gimple checking as we have right now is very cheap) under the
 hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
 put the burden on the developers, who has to check that manually through
 the as_a/is_a stuff everywhere, more typing and uglier syntax.
 I just don't see that as a step forward, instead a huge step backwards.
 But perhaps I'm alone with this.

IMO that's the sort of things some of us were afraid of when the C++ switch 
was being discussed and IIRC we were told this would not happen...

-- 
Eric Botcazou


Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-11 Thread Richard Biener
On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek ja...@redhat.com wrote:
 On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
 On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
  On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
   To be constructive here - the above case is from within a
   GIMPLE_ASSIGN case label
   and thus I'd have expected
  
   case GIMPLE_ASSIGN:
 {
   gassign *a1 = as_a gassign * (s1);
   gassign *a2 = as_a gassign * (s2);
 lhs1 = gimple_assign_lhs (a1);
 lhs2 = gimple_assign_lhs (a2);
 if (TREE_CODE (lhs1) != SSA_NAME
  TREE_CODE (lhs2) != SSA_NAME)
   return (operand_equal_p (lhs1, lhs2, 0)
gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
gimple_assign_rhs1 
   (a2)));
 else if (TREE_CODE (lhs1) == SSA_NAME
   TREE_CODE (lhs2) == SSA_NAME)
   return vn_valueize (lhs1) == vn_valueize (lhs2);
 return false;
 }
  
   instead.  That's the kind of changes I have expected and have approved 
   of.
 
  But even that looks like just adding extra work for all developers, with no
  gain.  You only have to add extra code and extra temporaries, in switches
  typically also have to add {} because of the temporaries and thus extra
  indentation level, and it doesn't simplify anything in the code.

 The branch attempts to use the C++ typesystem to capture information
 about the kinds of gimple statement we expect, both:
   (A) so that the compiler can detect type errors, and
   (B) as a comprehension aid to the human reader of the code

 The ideal here is when function params and struct field can be
 strengthened from gimple to a subclass ptr.  This captures the
 knowledge that every use of a function or within a struct has a given
 gimple code.

 I just don't like all the as_a/is_a stuff enforced everywhere,
 it means more typing, more temporaries, more indentation.
 So, as I view it, instead of the checks being done cheaply (yes, I think
 the gimple checking as we have right now is very cheap) under the
 hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
 put the burden on the developers, who has to check that manually through
 the as_a/is_a stuff everywhere, more typing and uglier syntax.
 I just don't see that as a step forward, instead a huge step backwards.
 But perhaps I'm alone with this.
 Can you e.g. compare the size of - lines in your patchset combined, and
 size of + lines in your patchset?  As in, if your changes lead to less
 typing or more.

I see two ways out here.  One is to add overloads to all the functions
taking the special types like

tree
gimple_assign_rhs1 (gimple *);

or simply add

gassign *operator ()(gimple *g) { return as_a gassign * (g); }

into a gimple-compat.h header which you include in places that
are not converted nicely.

Both avoid manually making the compiler happy (which the
explicit as_a stuff is!  It doesn't add any checking - it's
just placing the as_a at the callers and thus make the
runtine ICE fire there).

As much as I don't like global conversion operators I don't
like adding overloads to all of the accessor functions even more.

Whether you enable them generally or just for selected files
via a gimple-compat.h will be up to you (but I'd rather get
rid of them at some point).

Note this allows seamless transform of random functions
taking a gimple now but really only expecting a single kind.

Note that we don't absolutely have to rush this all in for GCC 5.
Being the very first for GCC 6 stage1 is another possibility.
We just should get it right.

Thanks,
Richard.


 Jakub


Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-11 Thread Bernd Schmidt

On 11/11/2014 09:30 AM, Eric Botcazou wrote:

I just don't like all the as_a/is_a stuff enforced everywhere,
it means more typing, more temporaries, more indentation.
So, as I view it, instead of the checks being done cheaply (yes, I think
the gimple checking as we have right now is very cheap) under the
hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
put the burden on the developers, who has to check that manually through
the as_a/is_a stuff everywhere, more typing and uglier syntax.
I just don't see that as a step forward, instead a huge step backwards.
But perhaps I'm alone with this.


IMO that's the sort of things some of us were afraid of when the C++ switch
was being discussed and IIRC we were told this would not happen...


I'm with both of you on this.


Bernd




Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-10 Thread David Malcolm
On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
 On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
  To be constructive here - the above case is from within a
  GIMPLE_ASSIGN case label
  and thus I'd have expected
  
  case GIMPLE_ASSIGN:
{
  gassign *a1 = as_a gassign * (s1);
  gassign *a2 = as_a gassign * (s2);
lhs1 = gimple_assign_lhs (a1);
lhs2 = gimple_assign_lhs (a2);
if (TREE_CODE (lhs1) != SSA_NAME
 TREE_CODE (lhs2) != SSA_NAME)
  return (operand_equal_p (lhs1, lhs2, 0)
   gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
   gimple_assign_rhs1 (a2)));
else if (TREE_CODE (lhs1) == SSA_NAME
  TREE_CODE (lhs2) == SSA_NAME)
  return vn_valueize (lhs1) == vn_valueize (lhs2);
return false;
}
  
  instead.  That's the kind of changes I have expected and have approved of.
 
 But even that looks like just adding extra work for all developers, with no
 gain.  You only have to add extra code and extra temporaries, in switches
 typically also have to add {} because of the temporaries and thus extra
 indentation level, and it doesn't simplify anything in the code.

The branch attempts to use the C++ typesystem to capture information
about the kinds of gimple statement we expect, both:
  (A) so that the compiler can detect type errors, and
  (B) as a comprehension aid to the human reader of the code

The ideal here is when function params and struct field can be
strengthened from gimple to a subclass ptr.  This captures the
knowledge that every use of a function or within a struct has a given
gimple code.

Examples of this for the initial patchkit were:

* the call_stmt field of a cgraph_edge becoming a gcall *,
  rather than a plain gimple.

* various variables in tree-into-ssa.c change from just
  vecgimple to being vecgphi *, capturing the phi-ness of
  the contents as a compile-time check

* tree-inline.h's struct copy_body_data, the field debug_stmts
  can be concretized from a vecgimple to a vecgdebug *.

A more recent example, from:
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=5bd16d92b9e928b5a5a7aebd571d92f72dd517f8
The fields arr_ref_first and arr_ref_last of
tree-switch-conversion.c's struct switch_conv_info can be strengthened
from gimple to gassign *: they are always GIMPLE_ASSIGN.

I applied cleanups to do my initial patchkit, which Jeff approved (with
some provisos), and which became the first 92 commits on the branch:

[gimple-classes, committed 00/92] Initial slew of commits:
  https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html

followed by a merger from trunk into the branch:
[gimple-classes] Merge trunk r216157-r216746 into branch:
  https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02982.html

With those commits, I was able to convert 180 accessors to taking a
concrete subclass, with 158 left taking a gimple or
const_gimple i.e. about half of them.
(My script to analyze this is gimple_typesafety.py
within https://github.com/davidmalcolm/gcc-refactoring-scripts)

I got it into my head that it was desirable to convert *all*
gimple accessors to this form, and to eliminate the GIMPLE_CHECK
macros (given that gcc development community seems to dislike
partial transitions).

I've been attempting this full conversion - convert all of the
gimple_ accessors, to require an appropriate gimple subclass
ptr, in particular focusing on the gimple_assign_ ones, but it's a *lot*
of extra work, and much more invasive than the patches
that Jeff conditionally approved.

I now suspect that it's going too far - in the initial patchkit I was
doing the clean, obvious ones, but now I'm left with the awkward ones
that would require me to uglify the code to fix.

If it's OK to only convert some of them, then I'd rather just do that.

The type-strengthening is rarely as neat as being able to simply convert
a param or field type.  Some examples:

Functions passed a gsi
==
Sometimes functions are passed a gsi, where it can be known that the gsi
currently references a stmt of known kind (although that isn't
necessarily obvious from reading the body of the function):

Example from tree-ssa-strlen.c:

handle_char_store (gimple_stmt_iterator *gsi)
 {
   int idx = -1;
   strinfo si = NULL;
-  gimple stmt = gsi_stmt (*gsi);
+  gassign *stmt = as_a gassign * (gsi_stmt (*gsi));
   tree ssaname = NULL_TREE, lhs = gimple_assign_lhs (stmt);
 
   if (TREE_CODE (lhs) == MEM_REF

from
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=78aae552f15ad5f8f5290fb825f9ae33f4a7cad9


Only acting on one kind of gimple
=

Some functions accept any kind of gimple, but only act on e.g. a
GIMPLE_ASSIGN, immediately returning if they got a different kind.

So I make this kind of change, where:

  void
  foo (gimple stmt, other params)
  {
if (!is_gimple_assign (stmt))
   

Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-10 Thread Andrew Pinski
On Mon, Nov 10, 2014 at 2:27 PM, David Malcolm dmalc...@redhat.com wrote:
 On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
 On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
  To be constructive here - the above case is from within a
  GIMPLE_ASSIGN case label
  and thus I'd have expected
 
  case GIMPLE_ASSIGN:
{
  gassign *a1 = as_a gassign * (s1);
  gassign *a2 = as_a gassign * (s2);
lhs1 = gimple_assign_lhs (a1);
lhs2 = gimple_assign_lhs (a2);
if (TREE_CODE (lhs1) != SSA_NAME
 TREE_CODE (lhs2) != SSA_NAME)
  return (operand_equal_p (lhs1, lhs2, 0)
   gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
   gimple_assign_rhs1 (a2)));
else if (TREE_CODE (lhs1) == SSA_NAME
  TREE_CODE (lhs2) == SSA_NAME)
  return vn_valueize (lhs1) == vn_valueize (lhs2);
return false;
}
 
  instead.  That's the kind of changes I have expected and have approved of.

 But even that looks like just adding extra work for all developers, with no
 gain.  You only have to add extra code and extra temporaries, in switches
 typically also have to add {} because of the temporaries and thus extra
 indentation level, and it doesn't simplify anything in the code.

 The branch attempts to use the C++ typesystem to capture information
 about the kinds of gimple statement we expect, both:
   (A) so that the compiler can detect type errors, and
   (B) as a comprehension aid to the human reader of the code

 The ideal here is when function params and struct field can be
 strengthened from gimple to a subclass ptr.  This captures the
 knowledge that every use of a function or within a struct has a given
 gimple code.

 Examples of this for the initial patchkit were:

 * the call_stmt field of a cgraph_edge becoming a gcall *,
   rather than a plain gimple.

 * various variables in tree-into-ssa.c change from just
   vecgimple to being vecgphi *, capturing the phi-ness of
   the contents as a compile-time check

 * tree-inline.h's struct copy_body_data, the field debug_stmts
   can be concretized from a vecgimple to a vecgdebug *.

 A more recent example, from:
 https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=5bd16d92b9e928b5a5a7aebd571d92f72dd517f8
 The fields arr_ref_first and arr_ref_last of
 tree-switch-conversion.c's struct switch_conv_info can be strengthened
 from gimple to gassign *: they are always GIMPLE_ASSIGN.

 I applied cleanups to do my initial patchkit, which Jeff approved (with
 some provisos), and which became the first 92 commits on the branch:

 [gimple-classes, committed 00/92] Initial slew of commits:
   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html

 followed by a merger from trunk into the branch:
 [gimple-classes] Merge trunk r216157-r216746 into branch:
   https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02982.html

 With those commits, I was able to convert 180 accessors to taking a
 concrete subclass, with 158 left taking a gimple or
 const_gimple i.e. about half of them.
 (My script to analyze this is gimple_typesafety.py
 within https://github.com/davidmalcolm/gcc-refactoring-scripts)

 I got it into my head that it was desirable to convert *all*
 gimple accessors to this form, and to eliminate the GIMPLE_CHECK
 macros (given that gcc development community seems to dislike
 partial transitions).

 I've been attempting this full conversion - convert all of the
 gimple_ accessors, to require an appropriate gimple subclass
 ptr, in particular focusing on the gimple_assign_ ones, but it's a *lot*
 of extra work, and much more invasive than the patches
 that Jeff conditionally approved.

 I now suspect that it's going too far - in the initial patchkit I was
 doing the clean, obvious ones, but now I'm left with the awkward ones
 that would require me to uglify the code to fix.

 If it's OK to only convert some of them, then I'd rather just do that.

 The type-strengthening is rarely as neat as being able to simply convert
 a param or field type.  Some examples:

 Functions passed a gsi
 ==
 Sometimes functions are passed a gsi, where it can be known that the gsi
 currently references a stmt of known kind (although that isn't
 necessarily obvious from reading the body of the function):

 Example from tree-ssa-strlen.c:

 handle_char_store (gimple_stmt_iterator *gsi)
  {
int idx = -1;
strinfo si = NULL;
 -  gimple stmt = gsi_stmt (*gsi);
 +  gassign *stmt = as_a gassign * (gsi_stmt (*gsi));


Can we have something like:
gsi_assign (*gsi)
instead so there is less typing when we want an gassign rather than a
gimple stmt.  This should allow for easier converting also and puts
most of the as_a in one place.

Thanks,
Andrew Pinski

tree ssaname = NULL_TREE, lhs = gimple_assign_lhs (stmt);

if (TREE_CODE (lhs) == MEM_REF

 from
 

Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-10 Thread Jakub Jelinek
On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote:
 On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote:
  On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
   To be constructive here - the above case is from within a
   GIMPLE_ASSIGN case label
   and thus I'd have expected
   
   case GIMPLE_ASSIGN:
 {
   gassign *a1 = as_a gassign * (s1);
   gassign *a2 = as_a gassign * (s2);
 lhs1 = gimple_assign_lhs (a1);
 lhs2 = gimple_assign_lhs (a2);
 if (TREE_CODE (lhs1) != SSA_NAME
  TREE_CODE (lhs2) != SSA_NAME)
   return (operand_equal_p (lhs1, lhs2, 0)
gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
gimple_assign_rhs1 
   (a2)));
 else if (TREE_CODE (lhs1) == SSA_NAME
   TREE_CODE (lhs2) == SSA_NAME)
   return vn_valueize (lhs1) == vn_valueize (lhs2);
 return false;
 }
   
   instead.  That's the kind of changes I have expected and have approved of.
  
  But even that looks like just adding extra work for all developers, with no
  gain.  You only have to add extra code and extra temporaries, in switches
  typically also have to add {} because of the temporaries and thus extra
  indentation level, and it doesn't simplify anything in the code.
 
 The branch attempts to use the C++ typesystem to capture information
 about the kinds of gimple statement we expect, both:
   (A) so that the compiler can detect type errors, and
   (B) as a comprehension aid to the human reader of the code
 
 The ideal here is when function params and struct field can be
 strengthened from gimple to a subclass ptr.  This captures the
 knowledge that every use of a function or within a struct has a given
 gimple code.

I just don't like all the as_a/is_a stuff enforced everywhere,
it means more typing, more temporaries, more indentation.
So, as I view it, instead of the checks being done cheaply (yes, I think
the gimple checking as we have right now is very cheap) under the
hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes
put the burden on the developers, who has to check that manually through
the as_a/is_a stuff everywhere, more typing and uglier syntax.
I just don't see that as a step forward, instead a huge step backwards.
But perhaps I'm alone with this.
Can you e.g. compare the size of - lines in your patchset combined, and
size of + lines in your patchset?  As in, if your changes lead to less
typing or more.

Jakub


Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-08 Thread Marek Polacek
On Fri, Nov 07, 2014 at 10:01:45PM +0100, Richard Biener wrote:
 Just a comment as these patches flow by - I think this is a huge step
 backwards from enforcing s1/s2 being a gimple_assign inside
 gimple_assign_rhs1 to this as_a gassign * boilerplate at _each_ callsite!

FWIW, I feel the same way.  More to type, worse readability, a lot
more of line-wrapping.

Sorry,

Marek


Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-08 Thread Richard Biener
On Fri, Nov 7, 2014 at 10:01 PM, Richard Biener
richard.guent...@gmail.com wrote:
 On Fri, Nov 7, 2014 at 4:21 PM, David Malcolm dmalc...@redhat.com wrote:
 gcc/ChangeLog.gimple-classes:
 * tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
 (gimple_equal_p): Add checked casts.
 ---
  gcc/ChangeLog.gimple-classes | 5 +
  gcc/tree-ssa-tail-merge.c| 8 +---
  2 files changed, 10 insertions(+), 3 deletions(-)

 diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
 index f43df63..0bd0421 100644
 --- a/gcc/ChangeLog.gimple-classes
 +++ b/gcc/ChangeLog.gimple-classes
 @@ -1,5 +1,10 @@
  2014-11-06  David Malcolm  dmalc...@redhat.com

 +   * tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
 +   (gimple_equal_p): Add checked casts.
 +
 +2014-11-06  David Malcolm  dmalc...@redhat.com
 +
 * tree-ssa-structalias.c (find_func_aliases): Replace
 is_gimple_assign with a dyn_cast, introducing local gassign *
 t_assign, using it in place of t for typesafety.
 diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
 index 5678657..b822214 100644
 --- a/gcc/tree-ssa-tail-merge.c
 +++ b/gcc/tree-ssa-tail-merge.c
 @@ -484,7 +484,7 @@ same_succ_hash (const_same_succ e)

hstate.add_int (gimple_code (stmt));
if (is_gimple_assign (stmt))
 -   hstate.add_int (gimple_assign_rhs_code (stmt));
 +   hstate.add_int (gimple_assign_rhs_code (as_a gassign * (stmt)));
if (!is_gimple_call (stmt))
 continue;
if (gimple_call_internal_p (stmt))
 @@ -1172,8 +1172,10 @@ gimple_equal_p (same_succ same_succ, gimple s1, 
 gimple s2)
if (TREE_CODE (lhs1) != SSA_NAME
TREE_CODE (lhs2) != SSA_NAME)
 return (operand_equal_p (lhs1, lhs2, 0)
 -gimple_operand_equal_value_p (gimple_assign_rhs1 (s1),
 -gimple_assign_rhs1 (s2)));
 +gimple_operand_equal_value_p (gimple_assign_rhs1 (
 +  as_a gassign * (s1)),
 +gimple_assign_rhs1 (
 +  as_a gassign * (s2;

 Just a comment as these patches flow by - I think this is a huge step
 backwards from enforcing s1/s2 being a gimple_assign inside
 gimple_assign_rhs1 to this as_a gassign * boilerplate at _each_ callsite!

 Which means this step of the refactoring is totally broken and probably
 requires much more manual work to avoid this kind of uglyness.

 I definitely won't approve of this kind of changes.

To be constructive here - the above case is from within a
GIMPLE_ASSIGN case label
and thus I'd have expected

case GIMPLE_ASSIGN:
  {
gassign *a1 = as_a gassign * (s1);
gassign *a2 = as_a gassign * (s2);
  lhs1 = gimple_assign_lhs (a1);
  lhs2 = gimple_assign_lhs (a2);
  if (TREE_CODE (lhs1) != SSA_NAME
   TREE_CODE (lhs2) != SSA_NAME)
return (operand_equal_p (lhs1, lhs2, 0)
 gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
 gimple_assign_rhs1 (a2)));
  else if (TREE_CODE (lhs1) == SSA_NAME
TREE_CODE (lhs2) == SSA_NAME)
return vn_valueize (lhs1) == vn_valueize (lhs2);
  return false;
  }

instead.  That's the kind of changes I have expected and have approved of.

Thanks,
Richard.

 Thanks,
 Richard.

else if (TREE_CODE (lhs1) == SSA_NAME
 TREE_CODE (lhs2) == SSA_NAME)
 return vn_valueize (lhs1) == vn_valueize (lhs2);
 --
 1.7.11.7



Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-08 Thread Jakub Jelinek
On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote:
 To be constructive here - the above case is from within a
 GIMPLE_ASSIGN case label
 and thus I'd have expected
 
 case GIMPLE_ASSIGN:
   {
 gassign *a1 = as_a gassign * (s1);
 gassign *a2 = as_a gassign * (s2);
   lhs1 = gimple_assign_lhs (a1);
   lhs2 = gimple_assign_lhs (a2);
   if (TREE_CODE (lhs1) != SSA_NAME
TREE_CODE (lhs2) != SSA_NAME)
 return (operand_equal_p (lhs1, lhs2, 0)
  gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
  gimple_assign_rhs1 (a2)));
   else if (TREE_CODE (lhs1) == SSA_NAME
 TREE_CODE (lhs2) == SSA_NAME)
 return vn_valueize (lhs1) == vn_valueize (lhs2);
   return false;
   }
 
 instead.  That's the kind of changes I have expected and have approved of.

But even that looks like just adding extra work for all developers, with no
gain.  You only have to add extra code and extra temporaries, in switches
typically also have to add {} because of the temporaries and thus extra
indentation level, and it doesn't simplify anything in the code.

Jakub


Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-08 Thread David Malcolm
On Sat, 2014-11-08 at 13:07 +0100, Richard Biener wrote:
 On Fri, Nov 7, 2014 at 10:01 PM, Richard Biener
 richard.guent...@gmail.com wrote:
  On Fri, Nov 7, 2014 at 4:21 PM, David Malcolm dmalc...@redhat.com wrote:
  gcc/ChangeLog.gimple-classes:
  * tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
  (gimple_equal_p): Add checked casts.
  ---
   gcc/ChangeLog.gimple-classes | 5 +
   gcc/tree-ssa-tail-merge.c| 8 +---
   2 files changed, 10 insertions(+), 3 deletions(-)
 
  diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
  index f43df63..0bd0421 100644
  --- a/gcc/ChangeLog.gimple-classes
  +++ b/gcc/ChangeLog.gimple-classes
  @@ -1,5 +1,10 @@
   2014-11-06  David Malcolm  dmalc...@redhat.com
 
  +   * tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
  +   (gimple_equal_p): Add checked casts.
  +
  +2014-11-06  David Malcolm  dmalc...@redhat.com
  +
  * tree-ssa-structalias.c (find_func_aliases): Replace
  is_gimple_assign with a dyn_cast, introducing local gassign *
  t_assign, using it in place of t for typesafety.
  diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
  index 5678657..b822214 100644
  --- a/gcc/tree-ssa-tail-merge.c
  +++ b/gcc/tree-ssa-tail-merge.c
  @@ -484,7 +484,7 @@ same_succ_hash (const_same_succ e)
 
 hstate.add_int (gimple_code (stmt));
 if (is_gimple_assign (stmt))
  -   hstate.add_int (gimple_assign_rhs_code (stmt));
  +   hstate.add_int (gimple_assign_rhs_code (as_a gassign * (stmt)));
 if (!is_gimple_call (stmt))
  continue;
 if (gimple_call_internal_p (stmt))
  @@ -1172,8 +1172,10 @@ gimple_equal_p (same_succ same_succ, gimple s1, 
  gimple s2)
 if (TREE_CODE (lhs1) != SSA_NAME
 TREE_CODE (lhs2) != SSA_NAME)
  return (operand_equal_p (lhs1, lhs2, 0)
  -gimple_operand_equal_value_p (gimple_assign_rhs1 (s1),
  -gimple_assign_rhs1 (s2)));
  +gimple_operand_equal_value_p (gimple_assign_rhs1 (
  +  as_a gassign * (s1)),
  +gimple_assign_rhs1 (
  +  as_a gassign * 
  (s2;
 
  Just a comment as these patches flow by - I think this is a huge step
  backwards from enforcing s1/s2 being a gimple_assign inside
  gimple_assign_rhs1 to this as_a gassign * boilerplate at _each_ callsite!
 
  Which means this step of the refactoring is totally broken and probably
  requires much more manual work to avoid this kind of uglyness.
 
  I definitely won't approve of this kind of changes.
 
 To be constructive here - the above case is from within a
 GIMPLE_ASSIGN case label
 and thus I'd have expected
 
 case GIMPLE_ASSIGN:
   {
 gassign *a1 = as_a gassign * (s1);
 gassign *a2 = as_a gassign * (s2);
   lhs1 = gimple_assign_lhs (a1);
   lhs2 = gimple_assign_lhs (a2);
   if (TREE_CODE (lhs1) != SSA_NAME
TREE_CODE (lhs2) != SSA_NAME)
 return (operand_equal_p (lhs1, lhs2, 0)
  gimple_operand_equal_value_p (gimple_assign_rhs1 (a1),
  gimple_assign_rhs1 (a2)));
   else if (TREE_CODE (lhs1) == SSA_NAME
 TREE_CODE (lhs2) == SSA_NAME)
 return vn_valueize (lhs1) == vn_valueize (lhs2);
   return false;
   }
 
 instead.  That's the kind of changes I have expected and have approved of.

I do make the above kind of change in some places within the
gimple-classes branch.

I think I didn't do it in this case because the body of the case
GIMPLE_ASSIGN doesn't yet have braces, so adding locals requires adding
them and re-indenting the case body.  I didn't spot the opportunity to
speed up the code as you do above by converting the two gimple_get_lhs
to gimple_assign_lhs.  Without that, I guess I decided to simply add the
two as_a directly in-place to avoid the reindent.   With your speedup
it's clearly better to reindent the code.


(Got to go now, sorry; I hope to write a better reply on Monday)

Thanks
Dave



[gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-07 Thread David Malcolm
gcc/ChangeLog.gimple-classes:
* tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
(gimple_equal_p): Add checked casts.
---
 gcc/ChangeLog.gimple-classes | 5 +
 gcc/tree-ssa-tail-merge.c| 8 +---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index f43df63..0bd0421 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,5 +1,10 @@
 2014-11-06  David Malcolm  dmalc...@redhat.com
 
+   * tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
+   (gimple_equal_p): Add checked casts.
+
+2014-11-06  David Malcolm  dmalc...@redhat.com
+
* tree-ssa-structalias.c (find_func_aliases): Replace
is_gimple_assign with a dyn_cast, introducing local gassign *
t_assign, using it in place of t for typesafety.
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index 5678657..b822214 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -484,7 +484,7 @@ same_succ_hash (const_same_succ e)
 
   hstate.add_int (gimple_code (stmt));
   if (is_gimple_assign (stmt))
-   hstate.add_int (gimple_assign_rhs_code (stmt));
+   hstate.add_int (gimple_assign_rhs_code (as_a gassign * (stmt)));
   if (!is_gimple_call (stmt))
continue;
   if (gimple_call_internal_p (stmt))
@@ -1172,8 +1172,10 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple 
s2)
   if (TREE_CODE (lhs1) != SSA_NAME
   TREE_CODE (lhs2) != SSA_NAME)
return (operand_equal_p (lhs1, lhs2, 0)
-gimple_operand_equal_value_p (gimple_assign_rhs1 (s1),
-gimple_assign_rhs1 (s2)));
+gimple_operand_equal_value_p (gimple_assign_rhs1 (
+  as_a gassign * (s1)),
+gimple_assign_rhs1 (
+  as_a gassign * (s2;
   else if (TREE_CODE (lhs1) == SSA_NAME
TREE_CODE (lhs2) == SSA_NAME)
return vn_valueize (lhs1) == vn_valueize (lhs2);
-- 
1.7.11.7



Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-07 Thread Richard Biener
On Fri, Nov 7, 2014 at 4:21 PM, David Malcolm dmalc...@redhat.com wrote:
 gcc/ChangeLog.gimple-classes:
 * tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
 (gimple_equal_p): Add checked casts.
 ---
  gcc/ChangeLog.gimple-classes | 5 +
  gcc/tree-ssa-tail-merge.c| 8 +---
  2 files changed, 10 insertions(+), 3 deletions(-)

 diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
 index f43df63..0bd0421 100644
 --- a/gcc/ChangeLog.gimple-classes
 +++ b/gcc/ChangeLog.gimple-classes
 @@ -1,5 +1,10 @@
  2014-11-06  David Malcolm  dmalc...@redhat.com

 +   * tree-ssa-tail-merge.c (same_succ_hash): Add checked cast.
 +   (gimple_equal_p): Add checked casts.
 +
 +2014-11-06  David Malcolm  dmalc...@redhat.com
 +
 * tree-ssa-structalias.c (find_func_aliases): Replace
 is_gimple_assign with a dyn_cast, introducing local gassign *
 t_assign, using it in place of t for typesafety.
 diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
 index 5678657..b822214 100644
 --- a/gcc/tree-ssa-tail-merge.c
 +++ b/gcc/tree-ssa-tail-merge.c
 @@ -484,7 +484,7 @@ same_succ_hash (const_same_succ e)

hstate.add_int (gimple_code (stmt));
if (is_gimple_assign (stmt))
 -   hstate.add_int (gimple_assign_rhs_code (stmt));
 +   hstate.add_int (gimple_assign_rhs_code (as_a gassign * (stmt)));
if (!is_gimple_call (stmt))
 continue;
if (gimple_call_internal_p (stmt))
 @@ -1172,8 +1172,10 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple 
 s2)
if (TREE_CODE (lhs1) != SSA_NAME
TREE_CODE (lhs2) != SSA_NAME)
 return (operand_equal_p (lhs1, lhs2, 0)
 -gimple_operand_equal_value_p (gimple_assign_rhs1 (s1),
 -gimple_assign_rhs1 (s2)));
 +gimple_operand_equal_value_p (gimple_assign_rhs1 (
 +  as_a gassign * (s1)),
 +gimple_assign_rhs1 (
 +  as_a gassign * (s2;

Just a comment as these patches flow by - I think this is a huge step
backwards from enforcing s1/s2 being a gimple_assign inside
gimple_assign_rhs1 to this as_a gassign * boilerplate at _each_ callsite!

Which means this step of the refactoring is totally broken and probably
requires much more manual work to avoid this kind of uglyness.

I definitely won't approve of this kind of changes.

Thanks,
Richard.

else if (TREE_CODE (lhs1) == SSA_NAME
 TREE_CODE (lhs2) == SSA_NAME)
 return vn_valueize (lhs1) == vn_valueize (lhs2);
 --
 1.7.11.7



Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign

2014-11-07 Thread Jakub Jelinek
On Fri, Nov 07, 2014 at 10:01:45PM +0100, Richard Biener wrote:
  --- a/gcc/tree-ssa-tail-merge.c
  +++ b/gcc/tree-ssa-tail-merge.c
  @@ -484,7 +484,7 @@ same_succ_hash (const_same_succ e)
 
 hstate.add_int (gimple_code (stmt));
 if (is_gimple_assign (stmt))
  -   hstate.add_int (gimple_assign_rhs_code (stmt));
  +   hstate.add_int (gimple_assign_rhs_code (as_a gassign * (stmt)));
 if (!is_gimple_call (stmt))
  continue;
 if (gimple_call_internal_p (stmt))
  @@ -1172,8 +1172,10 @@ gimple_equal_p (same_succ same_succ, gimple s1, 
  gimple s2)
 if (TREE_CODE (lhs1) != SSA_NAME
 TREE_CODE (lhs2) != SSA_NAME)
  return (operand_equal_p (lhs1, lhs2, 0)
  -gimple_operand_equal_value_p (gimple_assign_rhs1 (s1),
  -gimple_assign_rhs1 (s2)));
  +gimple_operand_equal_value_p (gimple_assign_rhs1 (
  +  as_a gassign * (s1)),
  +gimple_assign_rhs1 (
  +  as_a gassign * (s2;
 
 Just a comment as these patches flow by - I think this is a huge step
 backwards from enforcing s1/s2 being a gimple_assign inside
 gimple_assign_rhs1 to this as_a gassign * boilerplate at _each_ callsite!
 
 Which means this step of the refactoring is totally broken and probably
 requires much more manual work to avoid this kind of uglyness.
 
 I definitely won't approve of this kind of changes.

I have to agree with this, this is too ugly to live with.
I must say I don't find anything wrong with what we have right now,
unlike RTL checking, the gimple checking is inexpensive, and much better
to do it that way then enforce all all developers to write it this way.
Otherwise we'll end up with code as ugly as in LLVM :(.

Jakub