diff mbox

[1/2] add staticly checked label_nuses accessors

Message ID 1409931158-6374-1-git-send-email-tsaunders@mozilla.com
State New
Headers show

Commit Message

Trevor Saunders Sept. 5, 2014, 3:32 p.m. UTC
From: Trevor Saunders <tsaunders@mozilla.com>

Hi,

 Doing this means we get to remove a fair chunk of runtime checking.

bootstrapped + regtested on x86_64-unknown-linux-gnu with no regressions.
config-list.mk with this and the next patch is ongoing. ok?

Trev

gcc/

	* config/i386/i386.c, config/i386/i386.md, config/mep/mep.c,
	config/mips/mips.c, config/nios2/nios2.c, config/s390/s390.c,
	config/sh/sh.c, reorg.c: Use rtx_code_label::nuses and
	rtx_code_label::set_nuses where possible.
	* rtl.h (rtx_code_label::nuses): New member function.
	(rtx_code_label::set_nuses): Likewise.
---
 gcc/config/i386/i386.c   | 56 ++++++++++++++++++++++++------------------------
 gcc/config/i386/i386.md  | 14 ++++++------
 gcc/config/mep/mep.c     |  2 +-
 gcc/config/mips/mips.c   |  2 +-
 gcc/config/nios2/nios2.c |  4 ++--
 gcc/config/s390/s390.c   |  4 ++--
 gcc/config/sh/sh.c       |  2 +-
 gcc/reorg.c              |  6 +++---
 gcc/rtl.h                |  9 ++++++++
 9 files changed, 54 insertions(+), 45 deletions(-)

Comments

Jeff Law Sept. 5, 2014, 4:43 p.m. UTC | #1
On 09/05/14 09:32, tsaunders@mozilla.com wrote:
> From: Trevor Saunders <tsaunders@mozilla.com>
>
> Hi,
>
>   Doing this means we get to remove a fair chunk of runtime checking.
>
> bootstrapped + regtested on x86_64-unknown-linux-gnu with no regressions.
> config-list.mk with this and the next patch is ongoing. ok?
>
> Trev
>
> gcc/
>
> 	* config/i386/i386.c, config/i386/i386.md, config/mep/mep.c,
> 	config/mips/mips.c, config/nios2/nios2.c, config/s390/s390.c,
> 	config/sh/sh.c, reorg.c: Use rtx_code_label::nuses and
> 	rtx_code_label::set_nuses where possible.
> 	* rtl.h (rtx_code_label::nuses): New member function.
> 	(rtx_code_label::set_nuses): Likewise.
Is there some reason why we don't fix every reference to LABEL_NUSES to 
use the new member functions?  My concern here is that we've now got two 
ways actively used to get at that information, the old LABEL_NUSES and 
the new member functions.  Obviously we really just want one blessed way 
to get/set that information.  If this is a short term situation, then 
I'd be inclined to say OK, but I don't see further patches which sort 
out the ~200 or so LABEL_NUSES users.

THe approach David has taken for similar situations has been to first 
introduce the get/set methods, convert everything to set the get/set 
method, dealing with the type fallout that occurrs around that, then 
collapsing back to the old macro.  Is there some reason we can not or 
should not do that here?

jeff
Trevor Saunders Sept. 5, 2014, 5:12 p.m. UTC | #2
On Fri, Sep 05, 2014 at 10:43:45AM -0600, Jeff Law wrote:
> On 09/05/14 09:32, tsaunders@mozilla.com wrote:
> >From: Trevor Saunders <tsaunders@mozilla.com>
> >
> >Hi,
> >
> >  Doing this means we get to remove a fair chunk of runtime checking.
> >
> >bootstrapped + regtested on x86_64-unknown-linux-gnu with no regressions.
> >config-list.mk with this and the next patch is ongoing. ok?
> >
> >Trev
> >
> >gcc/
> >
> >	* config/i386/i386.c, config/i386/i386.md, config/mep/mep.c,
> >	config/mips/mips.c, config/nios2/nios2.c, config/s390/s390.c,
> >	config/sh/sh.c, reorg.c: Use rtx_code_label::nuses and
> >	rtx_code_label::set_nuses where possible.
> >	* rtl.h (rtx_code_label::nuses): New member function.
> >	(rtx_code_label::set_nuses): Likewise.
> Is there some reason why we don't fix every reference to LABEL_NUSES to use
> the new member functions?  My concern here is that we've now got two ways

 The reason I left some as is was because we didn't already have an
 rtx_code_label * there, so I was going to handle those later.  Though
 actually I guess we could adjust the macro to be

 #define LABEL_NUSES(l) as_a<rtx_code_label *> (l)->nuses ()

Whcih also has the advantage it doesn't compile if you pass in an
rtx_code_label *, and so you need to change to the newer form.

> actively used to get at that information, the old LABEL_NUSES and the new
> member functions.  Obviously we really just want one blessed way to get/set
> that information.  If this is a short term situation, then I'd be inclined
> to say OK, but I don't see further patches which sort out the ~200 or so
> LABEL_NUSES users.

because they haven't been written yet :) but I'd expect as types are
made more specific that situation will get better.

> THe approach David has taken for similar situations has been to first
> introduce the get/set methods, convert everything to set the get/set method,
> dealing with the type fallout that occurrs around that, then collapsing back
> to the old macro.  Is there some reason we can not or should not do that
> here?

I'd say we're doing the first parts of that here, but its not complete
yet.  That is I added the getters, and converted some but not all users
over.  There's certainly more patches to write though.

yes, basically the same thing is true for the other patch though we may
be much closer to finishing that conversion.

Trev

> 
> jeff
>
David Malcolm Sept. 5, 2014, 9:57 p.m. UTC | #3
On Fri, 2014-09-05 at 10:43 -0600, Jeff Law wrote:
> On 09/05/14 09:32, tsaunders@mozilla.com wrote:
> > From: Trevor Saunders <tsaunders@mozilla.com>
> >
> > Hi,
> >
> >   Doing this means we get to remove a fair chunk of runtime checking.
> >
> > bootstrapped + regtested on x86_64-unknown-linux-gnu with no regressions.
> > config-list.mk with this and the next patch is ongoing. ok?
> >
> > Trev
> >
> > gcc/
> >
> > 	* config/i386/i386.c, config/i386/i386.md, config/mep/mep.c,
> > 	config/mips/mips.c, config/nios2/nios2.c, config/s390/s390.c,
> > 	config/sh/sh.c, reorg.c: Use rtx_code_label::nuses and
> > 	rtx_code_label::set_nuses where possible.
> > 	* rtl.h (rtx_code_label::nuses): New member function.
> > 	(rtx_code_label::set_nuses): Likewise.
> Is there some reason why we don't fix every reference to LABEL_NUSES to 
> use the new member functions?  My concern here is that we've now got two 
> ways actively used to get at that information, the old LABEL_NUSES and 
> the new member functions.  Obviously we really just want one blessed way 
> to get/set that information.  If this is a short term situation, then 
> I'd be inclined to say OK, but I don't see further patches which sort 
> out the ~200 or so LABEL_NUSES users.
> 
> THe approach David has taken for similar situations has been to first 
> introduce the get/set methods, convert everything to set the get/set 
> method, dealing with the type fallout that occurrs around that, then 
> collapsing back to the old macro.  Is there some reason we can not or 
> should not do that here?

If it's a macro that's simply a direct field access into a struct (e.g.
BB_HEADER), then yes, but for those that are wrappers around e.g. XEXP
I've been keeping them as inline functions, so that the type system
detects incorrect node types as compile-time errors.

One other aspect of my approach is that (believe it or not) I'm trying
to minimize the size of the changes, to avoid introducing pain when
backporting bugfixes from trunk to the branches.

My goal here is type-safety, with readability as a secondary benefit.  I
think it's a good idea for us to add methods that let us replace e.g.
XEXP (x, 0) accessors with descriptive names, and have been doing so,
and I prefer doing this as methods for new code.  However, when the
accessor already has a descriptive name, like LABEL_NUSES, I think it's
enough to convert them to inline functions and tighten up the params and
return type to express things.  I'm not sure the cost/benefit of
*additionally* converting them to be methods is worth it, given that it
means changing the spelling at every callsite.

Dave
Trevor Saunders Sept. 5, 2014, 10:38 p.m. UTC | #4
On Fri, Sep 05, 2014 at 05:57:13PM -0400, David Malcolm wrote:
> On Fri, 2014-09-05 at 10:43 -0600, Jeff Law wrote:
> > On 09/05/14 09:32, tsaunders@mozilla.com wrote:
> > > From: Trevor Saunders <tsaunders@mozilla.com>
> > >
> > > Hi,
> > >
> > >   Doing this means we get to remove a fair chunk of runtime checking.
> > >
> > > bootstrapped + regtested on x86_64-unknown-linux-gnu with no regressions.
> > > config-list.mk with this and the next patch is ongoing. ok?
> > >
> > > Trev
> > >
> > > gcc/
> > >
> > > 	* config/i386/i386.c, config/i386/i386.md, config/mep/mep.c,
> > > 	config/mips/mips.c, config/nios2/nios2.c, config/s390/s390.c,
> > > 	config/sh/sh.c, reorg.c: Use rtx_code_label::nuses and
> > > 	rtx_code_label::set_nuses where possible.
> > > 	* rtl.h (rtx_code_label::nuses): New member function.
> > > 	(rtx_code_label::set_nuses): Likewise.
> > Is there some reason why we don't fix every reference to LABEL_NUSES to 
> > use the new member functions?  My concern here is that we've now got two 
> > ways actively used to get at that information, the old LABEL_NUSES and 
> > the new member functions.  Obviously we really just want one blessed way 
> > to get/set that information.  If this is a short term situation, then 
> > I'd be inclined to say OK, but I don't see further patches which sort 
> > out the ~200 or so LABEL_NUSES users.
> > 
> > THe approach David has taken for similar situations has been to first 
> > introduce the get/set methods, convert everything to set the get/set 
> > method, dealing with the type fallout that occurrs around that, then 
> > collapsing back to the old macro.  Is there some reason we can not or 
> > should not do that here?
> 
> If it's a macro that's simply a direct field access into a struct (e.g.
> BB_HEADER), then yes, but for those that are wrappers around e.g. XEXP
> I've been keeping them as inline functions, so that the type system
> detects incorrect node types as compile-time errors.
> 
> One other aspect of my approach is that (believe it or not) I'm trying
> to minimize the size of the changes, to avoid introducing pain when
> backporting bugfixes from trunk to the branches.
> 
> My goal here is type-safety, with readability as a secondary benefit.  I
> think it's a good idea for us to add methods that let us replace e.g.
> XEXP (x, 0) accessors with descriptive names, and have been doing so,
> and I prefer doing this as methods for new code.  However, when the
> accessor already has a descriptive name, like LABEL_NUSES, I think it's
> enough to convert them to inline functions and tighten up the params and
> return type to express things.  I'm not sure the cost/benefit of
> *additionally* converting them to be methods is worth it, given that it
> means changing the spelling at every callsite.

So, in this case it seems to me you basically have two options

A. change the macro to an inline function, and fix up all the callers to
pass the right type.  Then rebase that into some sort of reasonable
patch series.

b. add a function with a different name and convert users piece meal,
and then remove the old macro (I guess you can then rename the new
function to the old macro if you like).

of those I prefer b because it means you can convert call sites one at a
time and its easy to know which have been delt with.

I also do think the advantages of using members outways the cost.

For one thing functions with all caps names are just weird.  I think the
more important reason though is that it will help make rtx_insn be a
separate class sometime in the far future, since at some point we can
make its inheritance from rtx_def protected to chase down things that
try to convert from rtx_insn to rtx.  There's also the argument that its
inconsistant to have some things be members and others be functions.

Trev

> 
> Dave
>
Richard Sandiford Sept. 9, 2014, 3:17 p.m. UTC | #5
Trevor Saunders <tsaunders@mozilla.com> writes:
> I also do think the advantages of using members outways the cost.
>
> For one thing functions with all caps names are just weird.  I think the
> more important reason though is that it will help make rtx_insn be a
> separate class sometime in the far future, since at some point we can
> make its inheritance from rtx_def protected to chase down things that
> try to convert from rtx_insn to rtx.  There's also the argument that its
> inconsistant to have some things be members and others be functions.

+1 FWIW.  I think after conversion all rtx fields should be accessed
using the same style, rather than a mixture of caps-functions for some
fields and member functions for others.

Thanks,
Richard
Jeff Law Sept. 11, 2014, 8:55 p.m. UTC | #6
On 09/05/14 16:38, Trevor Saunders wrote:
>
> So, in this case it seems to me you basically have two options
>
> A. change the macro to an inline function, and fix up all the callers to
> pass the right type.  Then rebase that into some sort of reasonable
> patch series.
>
> b. add a function with a different name and convert users piece meal,
> and then remove the old macro (I guess you can then rename the new
> function to the old macro if you like).
>
> of those I prefer b because it means you can convert call sites one at a
> time and its easy to know which have been delt with.
My worry with piecemeal is obviously an incomplete transition.  While we 
have that to some extent with David's patches, we don't generally have 
two ways to get at the same hunk of data.




>
> I also do think the advantages of using members outways the cost.
I don't think it's always the case, but my general preference will be to 
go to member functions.


>
> For one thing functions with all caps names are just weird.  I think the
> more important reason though is that it will help make rtx_insn be a
> separate class sometime in the far future, since at some point we can
> make its inheritance from rtx_def protected to chase down things that
> try to convert from rtx_insn to rtx.  There's also the argument that its
> inconsistant to have some things be members and others be functions.
Yes, the all caps is weird.  There was a time when the all caps 
designated that we were using a macro and it was expected to be very 
efficient.  When calling a function we were supposed to use lowercase to 
signify the likely high overhead.

I'd tend to lean towards #1.  If we want to convert to methods, I think 
that can be a follow-up.  Type safety is my focus right now, not pushing 
towards member functions.

Jeff
Jeff Law Sept. 11, 2014, 8:59 p.m. UTC | #7
On 09/05/14 15:57, David Malcolm wrote:
> One other aspect of my approach is that (believe it or not) I'm trying
> to minimize the size of the changes, to avoid introducing pain when
> backporting bugfixes from trunk to the branches.
Right.  I believe and know you're trying to avoid unnecessary pain :-)

>
> My goal here is type-safety, with readability as a secondary benefit.
Agreed.  However, consistency with access is also important.  But, yes, 
we're really focused on moving on type safety here.



   I
> think it's a good idea for us to add methods that let us replace e.g.
> XEXP (x, 0) accessors with descriptive names, and have been doing so,
> and I prefer doing this as methods for new code.
As you undoubtly know, there's some resistance to that ;-)  But in cases 
where we can carve off things easily (like the list stuff) converting to 
members, at least IMHO, is much cleaner.  But I think we're a long way 
from converting RTL as a whole.



  However, when the
> accessor already has a descriptive name, like LABEL_NUSES, I think it's
> enough to convert them to inline functions and tighten up the params and
> return type to express things.  I'm not sure the cost/benefit of
> *additionally* converting them to be methods is worth it, given that it
> means changing the spelling at every callsite.
My feelings as well.

jeff
Trevor Saunders Sept. 11, 2014, 9:12 p.m. UTC | #8
On Thu, Sep 11, 2014 at 02:55:43PM -0600, Jeff Law wrote:
> On 09/05/14 16:38, Trevor Saunders wrote:
> >
> >So, in this case it seems to me you basically have two options
> >
> >A. change the macro to an inline function, and fix up all the callers to
> >pass the right type.  Then rebase that into some sort of reasonable
> >patch series.
> >
> >b. add a function with a different name and convert users piece meal,
> >and then remove the old macro (I guess you can then rename the new
> >function to the old macro if you like).
> >
> >of those I prefer b because it means you can convert call sites one at a
> >time and its easy to know which have been delt with.
> My worry with piecemeal is obviously an incomplete transition.  While we
> have that to some extent with David's patches, we don't generally have two
> ways to get at the same hunk of data.

yeah, I'd expect there's enough incentive for conversions to be
finished, but really I should probably know better ;)

fortunately I have a patch that just needs a ChangeLog finishing the
conversion of INSN_DELETED_P (though to a member function).  LABEL_NUSES
is harder in large part due to JUMP_LABEL, so that will probably have to
wait.

> >I also do think the advantages of using members outways the cost.
> I don't think it's always the case, but my general preference will be to go
> to member functions.
> 
> 
> >
> >For one thing functions with all caps names are just weird.  I think the
> >more important reason though is that it will help make rtx_insn be a
> >separate class sometime in the far future, since at some point we can
> >make its inheritance from rtx_def protected to chase down things that
> >try to convert from rtx_insn to rtx.  There's also the argument that its
> >inconsistant to have some things be members and others be functions.
> Yes, the all caps is weird.  There was a time when the all caps designated
> that we were using a macro and it was expected to be very efficient.  When
> calling a function we were supposed to use lowercase to signify the likely
> high overhead.

I actually care because if I suspect its a macro I'm going to grep for
'define XXX' and if its a function '^xxx', but I guess I should just
remember to use ctags :p

> I'd tend to lean towards #1.  If we want to convert to methods, I think that
> can be a follow-up.  Type safety is my focus right now, not pushing towards
> member functions.

yeah, if you don't want to change things incrementally I think there's
less incentive to change this at the same time.

Trev

> 
> Jeff
diff mbox

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a117718..e2b4a00 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -12136,7 +12136,7 @@  ix86_expand_split_stack_prologue (void)
     }
 
   emit_label (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   /* If this function calls va_start, we now have to set the scratch
      register for the case where we do not call __morestack.  In this
@@ -12148,7 +12148,7 @@  ix86_expand_split_stack_prologue (void)
 					    GEN_INT (UNITS_PER_WORD))));
 
       emit_label (varargs_label);
-      LABEL_NUSES (varargs_label) = 1;
+      varargs_label->set_nuses (1);
     }
 }
 
@@ -23129,7 +23129,7 @@  expand_movmem_epilogue (rtx destmem, rtx srcmem,
 	  dest = change_address (destmem, SImode, destptr);
 	  emit_insn (gen_strmov (destptr, dest, srcptr, src));
 	  emit_label (label);
-	  LABEL_NUSES (label) = 1;
+	  label->set_nuses (1);
 	}
       if (max_size > 2)
 	{
@@ -23138,7 +23138,7 @@  expand_movmem_epilogue (rtx destmem, rtx srcmem,
 	  dest = change_address (destmem, HImode, destptr);
 	  emit_insn (gen_strmov (destptr, dest, srcptr, src));
 	  emit_label (label);
-	  LABEL_NUSES (label) = 1;
+	  label->set_nuses (1);
 	}
       if (max_size > 1)
 	{
@@ -23147,7 +23147,7 @@  expand_movmem_epilogue (rtx destmem, rtx srcmem,
 	  dest = change_address (destmem, QImode, destptr);
 	  emit_insn (gen_strmov (destptr, dest, srcptr, src));
 	  emit_label (label);
-	  LABEL_NUSES (label) = 1;
+	  label->set_nuses (1);
 	}
     }
   else
@@ -23166,7 +23166,7 @@  expand_movmem_epilogue (rtx destmem, rtx srcmem,
 	  if (tmp != offset)
 	    emit_move_insn (offset, tmp);
 	  emit_label (label);
-	  LABEL_NUSES (label) = 1;
+	  label->set_nuses (1);
 	}
       if (max_size > 2)
 	{
@@ -23181,7 +23181,7 @@  expand_movmem_epilogue (rtx destmem, rtx srcmem,
 	  if (tmp != offset)
 	    emit_move_insn (offset, tmp);
 	  emit_label (label);
-	  LABEL_NUSES (label) = 1;
+	  label->set_nuses (1);
 	}
       if (max_size > 1)
 	{
@@ -23192,7 +23192,7 @@  expand_movmem_epilogue (rtx destmem, rtx srcmem,
 	  dest = change_address (destmem, QImode, tmp);
 	  emit_move_insn (dest, src);
 	  emit_label (label);
-	  LABEL_NUSES (label) = 1;
+	  label->set_nuses (1);
 	}
     }
 }
@@ -23321,7 +23321,7 @@  expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx vec_value,
 	  emit_insn (gen_strset (destptr, dest, value));
 	}
       emit_label (label);
-      LABEL_NUSES (label) = 1;
+      label->set_nuses (1);
     }
   if (max_size > 8)
     {
@@ -23339,7 +23339,7 @@  expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx vec_value,
 	  emit_insn (gen_strset (destptr, dest, value));
 	}
       emit_label (label);
-      LABEL_NUSES (label) = 1;
+      label->set_nuses (1);
     }
   if (max_size > 4)
     {
@@ -23347,7 +23347,7 @@  expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx vec_value,
       dest = change_address (destmem, SImode, destptr);
       emit_insn (gen_strset (destptr, dest, gen_lowpart (SImode, value)));
       emit_label (label);
-      LABEL_NUSES (label) = 1;
+      label->set_nuses (1);
     }
   if (max_size > 2)
     {
@@ -23355,7 +23355,7 @@  expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx vec_value,
       dest = change_address (destmem, HImode, destptr);
       emit_insn (gen_strset (destptr, dest, gen_lowpart (HImode, value)));
       emit_label (label);
-      LABEL_NUSES (label) = 1;
+      label->set_nuses (1);
     }
   if (max_size > 1)
     {
@@ -23363,7 +23363,7 @@  expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx vec_value,
       dest = change_address (destmem, QImode, destptr);
       emit_insn (gen_strset (destptr, dest, gen_lowpart (QImode, value)));
       emit_label (label);
-      LABEL_NUSES (label) = 1;
+      label->set_nuses (1);
     }
 }
 
@@ -23395,7 +23395,7 @@  expand_set_or_movmem_prologue (rtx destmem, rtx srcmem,
 	    destmem = emit_memmov (destmem, &srcmem, destptr, srcptr, i);
 	  ix86_adjust_counter (count, i);
 	  emit_label (label);
-	  LABEL_NUSES (label) = 1;
+	  label->set_nuses (1);
 	  set_mem_align (destmem, i * 2 * BITS_PER_UNIT);
 	}
     }
@@ -23478,7 +23478,7 @@  expand_small_movmem_or_setmem (rtx destmem, rtx srcmem,
   emit_barrier ();
 
   emit_label (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 }
 
 /* Handle small memcpy (up to SIZE that is supposed to be small power of 2.
@@ -23608,7 +23608,7 @@  expand_set_or_movmem_prologue_epilogue_by_misaligned_moves (rtx destmem, rtx src
 	}
 
       emit_label (label);
-      LABEL_NUSES (label) = 1;
+      label->set_nuses (1);
       emit_jump_insn (gen_jump (*done_label));
       emit_barrier ();
     }
@@ -23620,7 +23620,7 @@  expand_set_or_movmem_prologue_epilogue_by_misaligned_moves (rtx destmem, rtx src
   if (loop_label)
     {
        emit_label (loop_label);
-       LABEL_NUSES (loop_label) = 1;
+       loop_label->set_nuses (1);
     }
 
   /* Copy first desired_align bytes.  */
@@ -24505,7 +24505,7 @@  ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
   if (label && size_needed == 1)
     {
       emit_label (label);
-      LABEL_NUSES (label) = 1;
+      label->set_nuses (1);
       label = NULL;
       epilogue_size_needed = 1;
       if (issetmem)
@@ -24576,7 +24576,7 @@  ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
 	    emit_move_insn (count_exp, tmp);
 	}
       emit_label (label);
-      LABEL_NUSES (label) = 1;
+      label->set_nuses (1);
     }
 
   if (count_exp != const0_rtx && epilogue_size_needed > 1)
@@ -41490,7 +41490,7 @@  void ix86_emit_i387_round (rtx op0, rtx op1)
   emit_insn (gen_neg (res, res));
 
   emit_label (jump_label);
-  LABEL_NUSES (jump_label) = 1;
+  jump_label->set_nuses (1);
 
   emit_move_insn (op0, res);
 }
@@ -41935,7 +41935,7 @@  ix86_expand_lfloorceil (rtx op0, rtx op1, bool do_floor)
   emit_move_insn (ireg, tmp);
 
   emit_label (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   emit_move_insn (op0, ireg);
 }
@@ -41972,7 +41972,7 @@  ix86_expand_rint (rtx operand0, rtx operand1)
   ix86_sse_copysign_to_positive (res, xa, res, mask);
 
   emit_label (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   emit_move_insn (operand0, res);
 }
@@ -42035,7 +42035,7 @@  ix86_expand_floorceildf_32 (rtx operand0, rtx operand1, bool do_floor)
   emit_move_insn (res, tmp);
 
   emit_label (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   emit_move_insn (operand0, res);
 }
@@ -42097,7 +42097,7 @@  ix86_expand_floorceil (rtx operand0, rtx operand1, bool do_floor)
     ix86_sse_copysign_to_positive (res, res, force_reg (mode, operand1), mask);
 
   emit_label (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   emit_move_insn (operand0, res);
 }
@@ -42171,7 +42171,7 @@  ix86_expand_rounddf_32 (rtx operand0, rtx operand1)
   ix86_sse_copysign_to_positive (res, xa2, force_reg (mode, operand1), mask);
 
   emit_label (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   emit_move_insn (operand0, res);
 }
@@ -42216,7 +42216,7 @@  ix86_expand_trunc (rtx operand0, rtx operand1)
     ix86_sse_copysign_to_positive (res, res, force_reg (mode, operand1), mask);
 
   emit_label (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   emit_move_insn (operand0, res);
 }
@@ -42275,7 +42275,7 @@  ix86_expand_truncdf_32 (rtx operand0, rtx operand1)
   ix86_sse_copysign_to_positive (res, res, force_reg (mode, operand1), smask);
 
   emit_label (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   emit_move_insn (operand0, res);
 }
@@ -42325,7 +42325,7 @@  ix86_expand_round (rtx operand0, rtx operand1)
   ix86_sse_copysign_to_positive (res, xa, force_reg (mode, operand1), mask);
 
   emit_label (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   emit_move_insn (operand0, res);
 }
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index d5588c8..9b11e9c 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -9191,7 +9191,7 @@ 
   ix86_expand_clear (operands[1]);
 
   emit_label (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   DONE;
 })
@@ -9854,7 +9854,7 @@ 
   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
 				  GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
   emit_label (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   DONE;
 })
@@ -13855,7 +13855,7 @@ 
   emit_label (label);
   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
   ix86_emit_fp_unordered_jump (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   emit_move_insn (operands[0], op1);
   DONE;
@@ -13880,7 +13880,7 @@ 
   emit_label (label);
   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
   ix86_emit_fp_unordered_jump (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   /* Truncate the result properly for strict SSE math.  */
   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
@@ -13926,7 +13926,7 @@ 
   emit_label (label);
   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
   ix86_emit_fp_unordered_jump (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   emit_move_insn (operands[0], op1);
   DONE;
@@ -13952,7 +13952,7 @@ 
 
   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
   ix86_emit_fp_unordered_jump (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   /* Truncate the result properly for strict SSE math.  */
   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
@@ -18542,7 +18542,7 @@ 
   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
 
   emit_label (label);
-  LABEL_NUSES (label) = 1;
+  label->set_nuses (1);
 
   emit_move_insn (operands[0], ax_reg);
 
diff --git a/gcc/config/mep/mep.c b/gcc/config/mep/mep.c
index fcd5e0a..0f36a62 100644
--- a/gcc/config/mep/mep.c
+++ b/gcc/config/mep/mep.c
@@ -5579,7 +5579,7 @@  mep_reorg_erepeat (rtx_insn *insns)
 
 		/* Insert the erepeat after INSN's target label.  */
 		x = gen_erepeat (gen_rtx_LABEL_REF (VOIDmode, l));
-		LABEL_NUSES (l)++;
+		l->set_nuses (l->nuses () + 1);
 		emit_insn_after (x, prev);
 
 		/* Insert the erepeat label.  */
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 3e77491..76c0b33 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -14892,7 +14892,7 @@  mips16_lay_out_constants (bool split_p)
 
 	      jump = emit_jump_insn_before (gen_jump (label), insn);
 	      JUMP_LABEL (jump) = label;
-	      LABEL_NUSES (label) = 1;
+	      label->set_nuses (1);
 	      barrier = emit_barrier_after (jump);
 
 	      emit_label_after (label, barrier);
diff --git a/gcc/config/nios2/nios2.c b/gcc/config/nios2/nios2.c
index 1ab74f9..be173a6 100644
--- a/gcc/config/nios2/nios2.c
+++ b/gcc/config/nios2/nios2.c
@@ -1342,7 +1342,7 @@  nios2_emit_expensive_div (rtx *operands, enum machine_mode mode)
   emit_barrier ();
 
   emit_label (lab3);
-  LABEL_NUSES (lab3) = 1;
+  lab3->set_nuses (1);
 
   start_sequence ();
   final_result = emit_library_call_value (libfunc, NULL_RTX,
@@ -1356,7 +1356,7 @@  nios2_emit_expensive_div (rtx *operands, enum machine_mode mode)
                       gen_rtx_DIV (SImode, operands[1], operands[2]));
 
   emit_label (lab1);
-  LABEL_NUSES (lab1) = 1;
+  lab1->set_nuses (1);
 }
 
 
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 9e910cc..7b7652a 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -9895,7 +9895,7 @@  s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p)
 			     gen_rtx_EQ (VOIDmode,
 			       gen_rtx_REG (CCRAWmode, CC_REGNUM),
 			       gen_rtx_CONST_INT (VOIDmode, CC0 | CC1 | CC3)));
-      LABEL_NUSES (leave_label) = 1;
+      leave_label->set_nuses (1);
 
       /* CC2 - transient failure. Perform retry with ppa.  */
       emit_move_insn (count, retry_plus_two);
@@ -9905,7 +9905,7 @@  s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p)
 					      retry_reg,
 					      retry_reg));
       JUMP_LABEL (jump) = retry_label;
-      LABEL_NUSES (retry_label) = 1;
+      retry_label->set_nuses (1);
       emit_label (leave_label);
     }
 }
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 849867a..e85ca57 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -5355,7 +5355,7 @@  find_barrier (int num_mova, rtx_insn *mova, rtx_insn *from)
 
       from = emit_jump_insn_after (gen_jump (label), from);
       JUMP_LABEL (from) = label;
-      LABEL_NUSES (label) = 1;
+      label->set_nuses (1);
       found_barrier = emit_barrier_after (from);
       emit_label_after (label, found_barrier);
     }
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 89d500d..18717a7 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -427,7 +427,7 @@  find_end_label (rtx kind)
     {
       rtx_insn *temp = PREV_INSN (PREV_INSN (insn));
       rtx_code_label *label = gen_label_rtx ();
-      LABEL_NUSES (label) = 0;
+      label->set_nuses (0);
 
       /* Put the label before any USE insns that may precede the RETURN
 	 insn.  */
@@ -443,7 +443,7 @@  find_end_label (rtx kind)
   else
     {
       rtx_code_label *label = gen_label_rtx ();
-      LABEL_NUSES (label) = 0;
+      label->set_nuses (0);
       /* If the basic block reorder pass moves the return insn to
 	 some other place try to locate it again and put our
 	 function_return_label there.  */
@@ -496,7 +496,7 @@  find_end_label (rtx kind)
 
   /* Show one additional use for this label so it won't go away until
      we are done.  */
-  ++LABEL_NUSES (*plabel);
+  (*plabel)->set_nuses ((*plabel)->nuses () + 1);
 
   return *plabel;
 }
diff --git a/gcc/rtl.h b/gcc/rtl.h
index cd2f2e7..2d66a89 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -595,6 +595,7 @@  class GTY(()) rtx_barrier : public rtx_insn
 
 class GTY(()) rtx_code_label : public rtx_insn
 {
+public:
   /* No extra fields, but adds the invariant:
        LABEL_P (X) aka (GET_CODE (X) == CODE_LABEL)
      i.e. a label in the assembler.
@@ -602,6 +603,14 @@  class GTY(()) rtx_code_label : public rtx_insn
      This is an instance of:
        DEF_RTL_EXPR(CODE_LABEL, "code_label", "uuB00is", RTX_EXTRA)
      from rtl.def.  */
+
+  /* The number of times this label is used.  */
+
+  int nuses () const { return u.fld[4].rt_int; }
+
+  /* Set the number of times this label is used.  */
+
+  void set_nuses (int n) { u.fld[4].rt_int = n; }
 };
 
 class GTY(()) rtx_note : public rtx_insn