Patchwork Print location for conflicting global regs in warning

login
register
mail settings
Submitter Andi Kleen
Date June 8, 2011, 10:11 a.m.
Message ID <20110608101110.GM27166@one.firstfloor.org>
Download mbox | patch
Permalink /patch/99395/
State New
Headers show

Comments

Andi Kleen - June 8, 2011, 10:11 a.m.
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?

2011-06-06  Andi Kleen  <ak@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(-)
Richard Guenther - June 8, 2011, 10:24 a.m.
On Wed, Jun 8, 2011 at 12:11 PM, Andi Kleen <andi@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  <ak@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
>
> --
> ak@linux.intel.com -- Speaking for myself only.
>

Patch

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.  */