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) {
pgp1TSM7avf1R.pgp
Description: PGP signature