Hi!

On Wed, 25 Feb 2015 18:00:54 +0100, Jakub Jelinek <ja...@redhat.com> wrote:
> On Wed, Feb 25, 2015 at 11:28:12AM +0100, Thomas Schwinge wrote:
> > Am I on the right track with my assumption that it is correct that
> > nvptx.c:nvptx_option_override is not invoked in the offloading code path,
> > so we'd need a new target hook (?) to consolidate/override the options in
> > this scenario?
> > 
> > 
> > Using this to forcefully disable -fvar-tracking (as done in
> > nvptx_option_override), should then allow me to drop the following
> > beautiful specimen of a patch (which I didn't commit anywhere, so far):
> 
> Supposedly you could just disable var-tracking for
> targetm.no_register_allocation case, or change that assert to
> allow pseudos for targetm.no_register_allocation?

Just changing the assert, or handling this configuration differently:

diff --git gcc/var-tracking.c gcc/var-tracking.c
index 9ec5d8b..e37dc19 100644
--- gcc/var-tracking.c
+++ gcc/var-tracking.c
@@ -5439,6 +5449,10 @@ use_type (rtx loc, struct count_use_info *cui, 
machine_mode *modep)
 
   if (REG_P (loc))
     {
+      if (targetm.no_register_allocation)
+       if (REGNO (loc) >= FIRST_PSEUDO_REGISTER)
+         return MO_CLOBBER;
+
       gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
 
       if (loc == cfa_base_rtx)

... is not enough: by the looks of it, the var-tracking code is just not
prepared to see pseudo registers, for example:

    /* Structure holding the IN or OUT set for a basic block.  */
    typedef struct dataflow_set_def
    {
    [...]
      /* Attributes for registers (lists of attrs).  */
      attrs regs[FIRST_PSEUDO_REGISTER];
    [...]

..., which is asserted in several places (one of which we stumbled over;
I added more in the attached var-tracking-asserts.patch).  I tried
disabling it:

diff --git gcc/var-tracking.c gcc/var-tracking.c
index 9ec5d8b..e37dc19 100644
--- gcc/var-tracking.c
+++ gcc/var-tracking.c
@@ -10404,7 +10421,10 @@ public:
   /* opt_pass methods: */
   virtual bool gate (function *)
     {
-      return (flag_var_tracking && !targetm.delay_vartrack);
+      return (flag_var_tracking
+             && !targetm.delay_vartrack
+             /* This code is not prepared to handle pseudo registers.  */
+             && !targetm.no_register_allocation);
     }
 
   virtual unsigned int execute (function *)

..., but then we run into:

    $ build-gcc/gcc/xgcc -Bbuild-gcc/gcc/ 
-Bbuild-gcc/x86_64-unknown-linux-gnu/lib{gomp,gfortran}/ 
-Bbuild-gcc/x86_64-unknown-linux-gnu/lib{gomp,gfortran}/.libs 
-Ibuild-gcc/x86_64-unknown-linux-gnu/lib{gomp,gfortran} 
-Isource-gcc/{include,lib{gomp,gfortran}} 
-Lbuild-gcc/x86_64-unknown-linux-gnu/lib{gomp,gfortran}/.libs 
-Wl,-rpath,"$PWD"/build-gcc/x86_64-unknown-linux-gnu/lib{gomp,gfortran}/.libs 
source-gcc/libgomp/testsuite/libgomp.fortran/examples-4/e.50.1.f90 -Wall 
-Wextra -O2 -fopenmp -lgfortran -g
    source-gcc/libgomp/testsuite/libgomp.fortran/examples-4/e.50.1.f90: In 
function '__e_50_1_mod_MOD_vec_mult._omp_fn.1':
    source-gcc/libgomp/testsuite/libgomp.fortran/examples-4/e.50.1.f90:31:0: 
internal compiler error: in get_insn_template, at final.c:2124
             p(i) = v1(i) * v2(i)
     ^
    0x6b3765 get_insn_template(int, rtx_def*)
            [...]/source-gcc/gcc/final.c:2124
    0x6b55de final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*)
            [...]/source-gcc/gcc/final.c:2986
    0x6b6bff final(rtx_insn*, _IO_FILE*, int)
            [...]/source-gcc/gcc/final.c:2089
    0x6b76e9 rest_of_handle_final
            [...]/source-gcc/gcc/final.c:4488
    0x6b76e9 execute
            [...]/source-gcc/gcc/final.c:4563
    [...]
    mkoffload: fatal error: 
build-gcc/gcc/x86_64-unknown-linux-gnu-accel-nvptx-none-gcc returned 1 exit 
status
    [...]

Is this not the right way to skip it, or, Bernd, is this because we're
not yet handling some debug stuff in nvptx?  (I tested that
<http://news.gmane.org/find-root.php?message_id=%3C5466473A.1090809%40codesourcery.com%3E>
does not help with that.)  The following does make it work (that is,
resolve the ICEs), but that feels a bit too much ;-) of a hack:

--- gcc/var-tracking.c
+++ gcc/var-tracking.c
@@ -10305,7 +10322,8 @@ variable_tracking_main_1 (void)
 {
   bool success;
 
-  if (flag_var_tracking_assignments < 0)
+  if (flag_var_tracking_assignments < 0
+      || targetm.no_register_allocation)
     {
       delete_debug_insns ();
       return 0;


> Anyway, if var-tracking is never useful for NVPTX, if you want to override
> it early, flag_var_tracking* options are Optimization options, thus you'd
> need a target hook similar to the one I've added today, but instead of
> TARGET_OPTION_NODE do something similar for OPTIMIZATION_NODE streaming.


Grüße,
 Thomas


diff --git gcc/var-tracking.c gcc/var-tracking.c
index 9ec5d8b..e37dc19 100644
--- gcc/var-tracking.c
+++ gcc/var-tracking.c
@@ -1854,6 +1854,7 @@ var_reg_decl_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
   if (decl_p)
     dv = dv_from_decl (var_debug_decl (dv_as_decl (dv)));
 
+  gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
   for (node = set->regs[REGNO (loc)]; node; node = node->next)
     if (dv_as_opaque (node->dv) == dv_as_opaque (dv)
 	&& node->offset == offset)
@@ -1925,6 +1926,7 @@ var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify,
   if (initialized == VAR_INIT_STATUS_UNKNOWN)
     initialized = get_init_value (set, loc, dv_from_decl (decl));
 
+  gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
   nextp = &set->regs[REGNO (loc)];
   for (node = *nextp; node; node = next)
     {
@@ -1954,6 +1956,7 @@ var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify,
 static void
 var_reg_delete (dataflow_set *set, rtx loc, bool clobber)
 {
+  gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
   attrs *nextp = &set->regs[REGNO (loc)];
   attrs node, next;
 
@@ -1986,6 +1989,7 @@ var_reg_delete (dataflow_set *set, rtx loc, bool clobber)
 static void
 var_regno_delete (dataflow_set *set, int regno)
 {
+  gcc_assert (regno < FIRST_PSEUDO_REGISTER);
   attrs *reg = &set->regs[regno];
   attrs node, next;
 
@@ -2630,6 +2634,7 @@ val_resolve (dataflow_set *set, rtx val, rtx loc, rtx_insn *insn)
     {
       attrs node, found = NULL;
 
+      gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
       for (node = set->regs[REGNO (loc)]; node; node = node->next)
 	if (dv_is_value_p (node->dv)
 	    && GET_MODE (dv_as_value (node->dv)) == GET_MODE (loc))
@@ -3784,6 +3789,7 @@ canonicalize_values_star (variable_def **slot, dataflow_set *set)
 	  }
 	else if (GET_CODE (node->loc) == REG)
 	  {
+	    gcc_assert (REGNO (node->loc) < FIRST_PSEUDO_REGISTER);
 	    attrs list = set->regs[REGNO (node->loc)], *listp;
 
 	    /* Change an existing attribute referring to dv so that it
@@ -4045,6 +4051,7 @@ variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
 	{
 	  attrs list;
 
+	  gcc_assert (REGNO (node->loc) < FIRST_PSEUDO_REGISTER);
 	  for (list = dst->regs[REGNO (node->loc)]; list; list = list->next)
 	    if (GET_MODE (node->loc) == GET_MODE (list->loc)
 		&& dv_is_value_p (list->dv))
@@ -4426,6 +4433,7 @@ variable_post_merge_new_vals (variable_def **slot, dfset_post_merge *dfpm)
 		  goto restart;
 		}
 
+	      gcc_assert (REGNO (node->loc) < FIRST_PSEUDO_REGISTER);
 	      for (attp = &set->regs[REGNO (node->loc)]; (att = *attp);
 		   attp = &att->next)
 		if (att->offset == 0
@@ -4466,6 +4474,7 @@ variable_post_merge_new_vals (variable_def **slot, dfset_post_merge *dfpm)
 		      dataflow_set_init (*dfpm->permp);
 		    }
 
+		  gcc_assert (REGNO (node->loc) < FIRST_PSEUDO_REGISTER);
 		  for (att = (*dfpm->permp)->regs[REGNO (node->loc)];
 		       att; att = att->next)
 		    if (GET_MODE (att->loc) == GET_MODE (node->loc))
@@ -4561,6 +4570,7 @@ variable_post_merge_perm_vals (variable_def **pslot, dfset_post_merge *dfpm)
       val_reset (set, dv);
     }
 
+  gcc_assert (REGNO (pnode->loc) < FIRST_PSEUDO_REGISTER);
   for (att = set->regs[REGNO (pnode->loc)]; att; att = att->next)
     if (att->offset == 0
 	&& GET_MODE (att->loc) == GET_MODE (pnode->loc)
@@ -7837,6 +7853,7 @@ clobber_slot_part (dataflow_set *set, rtx loc, variable_def **slot,
 		     list, but preserve any other variable parts
 		     that might be regarded as live in that same
 		     register.  */
+		  gcc_assert (REGNO (node->loc) < FIRST_PSEUDO_REGISTER);
 		  anextp = &set->regs[REGNO (node->loc)];
 		  for (anode = *anextp; anode; anode = anext)
 		    {

Attachment: pgp1TSM7avf1R.pgp
Description: PGP signature

Reply via email to