On Wed, Jun 8, 2011 at 12:11 PM, Andi Kleen <a...@firstfloor.org> wrote: > Print location for conflicting global regs when warning > about them. Otherwise it's hard to track down where they are. > > To review: I hope the way I use the garbage collector for the global > variable is ok? > > Passes bootstrap & test suite on x86_64-linux. Ok to commit?
Ok. Thanks, Richard. > 2011-06-06 Andi Kleen <a...@linux.intel.com> > > * reginfo.c (global_regs_decl): Add. > (globalize_reg): Add decl parameter. Compute location. > Pass location to warnings and add inform. Store decl > in global_regs_decl. > * rtl.h (globalize_reg): Update prototype. > * varasm.c (make_decl_rtl): Pass decl to globalize_reg(). > --- > gcc/reginfo.c | 18 ++++++++++++++---- > gcc/rtl.h | 2 +- > gcc/varasm.c | 2 +- > 3 files changed, 16 insertions(+), 6 deletions(-) > > diff --git a/gcc/reginfo.c b/gcc/reginfo.c > index a283a90..1da4cb8 100644 > --- a/gcc/reginfo.c > +++ b/gcc/reginfo.c > @@ -87,6 +87,9 @@ static const char initial_call_really_used_regs[] = > CALL_REALLY_USED_REGISTERS; > and are also considered fixed. */ > char global_regs[FIRST_PSEUDO_REGISTER]; > > +/* Declaration for the global register. */ > +static tree GTY(()) global_regs_decl[FIRST_PSEUDO_REGISTER]; > + > /* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used > in dataflow more conveniently. */ > regset regs_invalidated_by_call_regset; > @@ -825,8 +828,10 @@ fix_register (const char *name, int fixed, int call_used) > > /* Mark register number I as global. */ > void > -globalize_reg (int i) > +globalize_reg (tree decl, int i) > { > + location_t loc = DECL_SOURCE_LOCATION (decl); > + > #ifdef STACK_REGS > if (IN_RANGE (i, FIRST_STACK_REG, LAST_STACK_REG)) > { > @@ -836,18 +841,23 @@ globalize_reg (int i) > #endif > > if (fixed_regs[i] == 0 && no_global_reg_vars) > - error ("global register variable follows a function definition"); > + error_at (loc, "global register variable follows a function definition"); > > if (global_regs[i]) > { > - warning (0, "register used for two global register variables"); > + warning_at (loc, 0, > + "register of %qD used for multiple global register > variables", > + decl); > + inform (DECL_SOURCE_LOCATION (global_regs_decl[i]), > + "conflicts with %qD", global_regs_decl[i]); > return; > } > > if (call_used_regs[i] && ! fixed_regs[i]) > - warning (0, "call-clobbered register used for global register variable"); > + warning_at (loc, 0, "call-clobbered register used for global register > variable"); > > global_regs[i] = 1; > + global_regs_decl[i] = decl; > > /* If we're globalizing the frame pointer, we need to set the > appropriate regs_invalidated_by_call bit, even if it's already > diff --git a/gcc/rtl.h b/gcc/rtl.h > index 62b677a..f2c2983 100644 > --- a/gcc/rtl.h > +++ b/gcc/rtl.h > @@ -2451,7 +2451,7 @@ extern void mark_elimination (int, int); > /* In reginfo.c */ > extern int reg_classes_intersect_p (reg_class_t, reg_class_t); > extern int reg_class_subset_p (reg_class_t, reg_class_t); > -extern void globalize_reg (int); > +extern void globalize_reg (tree, int); > extern void init_reg_modes_target (void); > extern void init_regs (void); > extern void reinit_regs (void); > diff --git a/gcc/varasm.c b/gcc/varasm.c > index 5f4f796..a0a0582 100644 > --- a/gcc/varasm.c > +++ b/gcc/varasm.c > @@ -1241,7 +1241,7 @@ make_decl_rtl (tree decl) > #endif > nregs = hard_regno_nregs[reg_number][DECL_MODE (decl)]; > while (nregs > 0) > - globalize_reg (reg_number + --nregs); > + globalize_reg (decl, reg_number + --nregs); > } > > /* As a register variable, it has no section. */ > -- > 1.7.5.3 > > -- > a...@linux.intel.com -- Speaking for myself only. >