Hi! On Wed, 25 Feb 2015 18:00:54 +0100, Jakub Jelinek <[email protected]> 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)
{
pgp1TSM7avf1R.pgp
Description: PGP signature
