|
View:
New views
3 Messages
—
Rating Filter:
Alert me
|
|
|
[vta, PR41926, graphite?] track debug uses during vectorizationPR debug/41926 was a case in which a debug use outside a vectorized loop
remained, referencing an SSA DEF that no longer dominated the use because of vectorization. In order to fix this, I extended the live-tracking information so as to record debug uses in addition to nondebug uses. Then, if a name in the vectorized loop is found to be referenced outside the loop only by debug insns (case in which we won't create a PHI node at the join point), we reset the debug use. I managed to convert the testcase to C, but it requires the patch I've just posted to exercise the bug fixed by the patch below. I'm not happy with the options-management in this testcase, though. I need -ffast-math and -funroll-loops to trigger it, so the standard names handled by vect.exp don't work, and I can't add options to the default per-machine vectorization options vect.exp sets up. So I made in x86-only, but I'd appreciate suggestions on how to make it better. Anyone? Bootstrapped on x86_64-linux-gnu; regstrapping on that and ia64-linux-gnu. Ok to install? for gcc/ChangeLog from Alexandre Oliva <aoliva@...> PR debug/41926 * tree-vectorizer.h (enum vect_live): New. (struct _stmt_vec_info): Change type of live to it. (STMT_VINFO_LIVE_P): Adjust. (STMT_VINFO_LIVE): New. (STMT_VINFO_LIVE_IN_DEBUG_ONLY_P): New. * tree-vect-loop.c (vect_loop_kill_debug_uses): New. (vect_transform_loop): Call it. * tree-vect-stmts.c (vect_mark_relevant): Use new type and macros. (vect_stmt_relevant_p): Use new enum type and values. (process_use): Use new type. Adjust comments. (vect_mark_stmts_to_be_vectorized): Likewise. (new_stmt_vec_info): Use new enum type and values. for gcc/testsuite/ChangeLog from Alexandre Oliva <aoliva@...> PR debug/41926 * gcc.dg/vect/vect-debug-pr41926.c: New. Index: gcc/tree-vectorizer.h =================================================================== --- gcc/tree-vectorizer.h.orig 2009-11-05 04:26:06.000000000 -0200 +++ gcc/tree-vectorizer.h 2009-11-05 04:36:47.000000000 -0200 @@ -359,6 +359,14 @@ enum vect_relevant { vect_used_in_scope }; +/* Indicates how a variable is used outside the loop. This is used + sort of like an array of booleans. */ +enum vect_live { + vect_dead = 0, + vect_live_for_debug = 1, + vect_live_for_real = 2 +}; + /* The type of vectorization that can be applied to the stmt: regular loop-based vectorization; pure SLP - the stmt is a part of SLP instances and does not have uses outside SLP instances; or hybrid SLP and loop-based - the stmt is @@ -403,7 +411,7 @@ typedef struct _stmt_vec_info { /* Indicates whether this stmts is part of a computation whose result is used outside the loop. */ - bool live; + enum vect_live live; /* The vector type to be used. */ tree vectype; @@ -489,7 +497,11 @@ typedef struct _stmt_vec_info { #define STMT_VINFO_LOOP_VINFO(S) (S)->loop_vinfo #define STMT_VINFO_BB_VINFO(S) (S)->bb_vinfo #define STMT_VINFO_RELEVANT(S) (S)->relevant -#define STMT_VINFO_LIVE_P(S) (S)->live +#define STMT_VINFO_LIVE(S) (S)->live +#define STMT_VINFO_LIVE_P(S) (STMT_VINFO_LIVE (S) \ + > vect_live_for_debug) +#define STMT_VINFO_LIVE_IN_DEBUG_ONLY_P(S) (STMT_VINFO_LIVE (S) \ + == vect_live_for_debug) #define STMT_VINFO_VECTYPE(S) (S)->vectype #define STMT_VINFO_VEC_STMT(S) (S)->vectorized_stmt #define STMT_VINFO_DATA_REF(S) (S)->data_ref_info Index: gcc/tree-vect-loop.c =================================================================== --- gcc/tree-vect-loop.c.orig 2009-11-05 04:26:06.000000000 -0200 +++ gcc/tree-vect-loop.c 2009-11-05 04:36:47.000000000 -0200 @@ -4112,6 +4112,44 @@ vectorizable_live_operation (gimple stmt return true; } +/* Kill any debug uses outside LOOP of SSA names defined in STMT. */ + +static void +vect_loop_kill_debug_uses (struct loop *loop, gimple stmt) +{ + ssa_op_iter op_iter; + imm_use_iterator imm_iter; + def_operand_p def_p; + gimple ustmt; + + FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF) + { + FOR_EACH_IMM_USE_STMT (ustmt, imm_iter, DEF_FROM_PTR (def_p)) + { + basic_block bb; + + if (!is_gimple_debug (ustmt)) + continue; + + bb = gimple_bb (ustmt); + + if (!flow_bb_inside_loop_p (loop, bb)) + { + if (gimple_debug_bind_p (ustmt)) + { + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "killing debug use"); + + gimple_debug_bind_reset_value (ustmt); + update_stmt (ustmt); + } + else + gcc_unreachable (); + } + } + } +} + /* Function vect_transform_loop. The analysis phase has determined that the loop is vectorizable. @@ -4202,7 +4240,11 @@ vect_transform_loop (loop_vec_info loop_ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !STMT_VINFO_LIVE_P (stmt_info)) - continue; + { + if (STMT_VINFO_LIVE_IN_DEBUG_ONLY_P (stmt_info)) + vect_loop_kill_debug_uses (loop, phi); + continue; + } if ((TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info)) != (unsigned HOST_WIDE_INT) vectorization_factor) @@ -4242,6 +4284,8 @@ vect_transform_loop (loop_vec_info loop_ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !STMT_VINFO_LIVE_P (stmt_info)) { + if (STMT_VINFO_LIVE_IN_DEBUG_ONLY_P (stmt_info)) + vect_loop_kill_debug_uses (loop, stmt); gsi_next (&si); continue; } Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c.orig 2009-11-05 04:26:06.000000000 -0200 +++ gcc/tree-vect-stmts.c 2009-11-05 04:36:47.000000000 -0200 @@ -49,14 +49,14 @@ along with GCC; see the file COPYING3. static void vect_mark_relevant (VEC(gimple,heap) **worklist, gimple stmt, - enum vect_relevant relevant, bool live_p) + enum vect_relevant relevant, enum vect_live live) { stmt_vec_info stmt_info = vinfo_for_stmt (stmt); enum vect_relevant save_relevant = STMT_VINFO_RELEVANT (stmt_info); - bool save_live_p = STMT_VINFO_LIVE_P (stmt_info); + enum vect_live save_live = STMT_VINFO_LIVE (stmt_info); if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "mark relevant %d, live %d.", relevant, live_p); + fprintf (vect_dump, "mark relevant %d, live %d.", relevant, live); if (STMT_VINFO_IN_PATTERN_P (stmt_info)) { @@ -74,16 +74,17 @@ vect_mark_relevant (VEC(gimple,heap) **w stmt_info = vinfo_for_stmt (pattern_stmt); gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt); save_relevant = STMT_VINFO_RELEVANT (stmt_info); - save_live_p = STMT_VINFO_LIVE_P (stmt_info); + save_live = STMT_VINFO_LIVE (stmt_info); stmt = pattern_stmt; } - STMT_VINFO_LIVE_P (stmt_info) |= live_p; + STMT_VINFO_LIVE (stmt_info) = (enum vect_live) + (STMT_VINFO_LIVE (stmt_info) | live); if (relevant > STMT_VINFO_RELEVANT (stmt_info)) STMT_VINFO_RELEVANT (stmt_info) = relevant; if (STMT_VINFO_RELEVANT (stmt_info) == save_relevant - && STMT_VINFO_LIVE_P (stmt_info) == save_live_p) + && STMT_VINFO_LIVE (stmt_info) == save_live) { if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "already marked relevant/live."); @@ -108,7 +109,7 @@ vect_mark_relevant (VEC(gimple,heap) **w static bool vect_stmt_relevant_p (gimple stmt, loop_vec_info loop_vinfo, - enum vect_relevant *relevant, bool *live_p) + enum vect_relevant *relevant, enum vect_live *live) { struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); ssa_op_iter op_iter; @@ -117,7 +118,7 @@ vect_stmt_relevant_p (gimple stmt, loop_ def_operand_p def_p; *relevant = vect_unused_in_scope; - *live_p = false; + *live = vect_dead; /* cond stmt other than loop exit cond. */ if (is_ctrl_stmt (stmt) @@ -146,19 +147,22 @@ vect_stmt_relevant_p (gimple stmt, loop_ fprintf (vect_dump, "vec_stmt_relevant_p: used out of loop."); if (is_gimple_debug (USE_STMT (use_p))) - continue; + { + *live = vect_live_for_debug; + continue; + } /* We expect all such uses to be in the loop exit phis (because of loop closed form) */ gcc_assert (gimple_code (USE_STMT (use_p)) == GIMPLE_PHI); gcc_assert (bb == single_exit (loop)->dest); - *live_p = true; + *live = vect_live_for_real; } } } - return (*live_p || *relevant); + return (*live || *relevant); } @@ -212,14 +216,14 @@ exist_non_indexing_operands_for_use_p (t Inputs: - a USE in STMT in a loop represented by LOOP_VINFO - - LIVE_P, RELEVANT - enum values to be set in the STMT_VINFO of the stmt + - LIVE, RELEVANT - enum values to be set in the STMT_VINFO of the stmt that defined USE. This is done by calling mark_relevant and passing it the WORKLIST (to add DEF_STMT to the WORKLIST in case it is relevant). Outputs: - Generally, LIVE_P and RELEVANT are used to define the liveness and + Generally, LIVE and RELEVANT are used to define the liveness and relevance info of the DEF_STMT of this USE: - STMT_VINFO_LIVE_P (DEF_STMT_info) <-- live_p + STMT_VINFO_LIVE (DEF_STMT_info) <-- live STMT_VINFO_RELEVANT (DEF_STMT_info) <-- relevant Exceptions: - case 1: If USE is used only for address computations (e.g. array indexing), @@ -233,8 +237,9 @@ exist_non_indexing_operands_for_use_p (t Return true if everything is as expected. Return false otherwise. */ static bool -process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p, - enum vect_relevant relevant, VEC(gimple,heap) **worklist) +process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, + enum vect_live live, enum vect_relevant relevant, + VEC(gimple,heap) **worklist) { struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); @@ -360,7 +365,7 @@ process_use (gimple stmt, tree use, loop } } - vect_mark_relevant (worklist, def_stmt, relevant, live_p); + vect_mark_relevant (worklist, def_stmt, relevant, live); return true; } @@ -394,7 +399,7 @@ vect_mark_stmts_to_be_vectorized (loop_v stmt_vec_info stmt_vinfo; basic_block bb; gimple phi; - bool live_p; + enum vect_live live; enum vect_relevant relevant, tmp_relevant; enum vect_def_type def_type; @@ -416,8 +421,8 @@ vect_mark_stmts_to_be_vectorized (loop_v print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM); } - if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p)) - vect_mark_relevant (&worklist, phi, relevant, live_p); + if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live)) + vect_mark_relevant (&worklist, phi, relevant, live); } for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) { @@ -428,8 +433,8 @@ vect_mark_stmts_to_be_vectorized (loop_v print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); } - if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant, &live_p)) - vect_mark_relevant (&worklist, stmt, relevant, live_p); + if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant, &live)) + vect_mark_relevant (&worklist, stmt, relevant, live); } } @@ -451,16 +456,16 @@ vect_mark_stmts_to_be_vectorized (loop_v liveness and relevance properties of STMT. */ stmt_vinfo = vinfo_for_stmt (stmt); relevant = STMT_VINFO_RELEVANT (stmt_vinfo); - live_p = STMT_VINFO_LIVE_P (stmt_vinfo); + live = STMT_VINFO_LIVE (stmt_vinfo); /* Generally, the liveness and relevance properties of STMT are propagated as is to the DEF_STMTs of its USEs: - live_p <-- STMT_VINFO_LIVE_P (STMT_VINFO) + live <-- STMT_VINFO_LIVE (STMT_VINFO) relevant <-- STMT_VINFO_RELEVANT (STMT_VINFO) One exception is when STMT has been identified as defining a reduction variable; in this case we set the liveness/relevance as follows: - live_p = false + live &= vect_live_for_debug relevant = vect_used_by_reduction This is because we distinguish between two kinds of relevant stmts - those that are used by a reduction computation, and those that are @@ -492,7 +497,7 @@ vect_mark_stmts_to_be_vectorized (loop_v return false; } - live_p = false; + live = (enum vect_live) (live & vect_live_for_debug); break; case vect_nested_cycle: @@ -507,7 +512,7 @@ vect_mark_stmts_to_be_vectorized (loop_v return false; } - live_p = false; + live = (enum vect_live) (live & vect_live_for_debug); break; case vect_double_reduction_def: @@ -521,7 +526,7 @@ vect_mark_stmts_to_be_vectorized (loop_v return false; } - live_p = false; + live = (enum vect_live) (live & vect_live_for_debug); break; default: @@ -531,7 +536,7 @@ vect_mark_stmts_to_be_vectorized (loop_v FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE) { tree op = USE_FROM_PTR (use_p); - if (!process_use (stmt, op, loop_vinfo, live_p, relevant, &worklist)) + if (!process_use (stmt, op, loop_vinfo, live, relevant, &worklist)) { VEC_free (gimple, heap, worklist); return false; @@ -4319,7 +4324,7 @@ new_stmt_vec_info (gimple stmt, loop_vec STMT_VINFO_LOOP_VINFO (res) = loop_vinfo; STMT_VINFO_BB_VINFO (res) = bb_vinfo; STMT_VINFO_RELEVANT (res) = vect_unused_in_scope; - STMT_VINFO_LIVE_P (res) = false; + STMT_VINFO_LIVE (res) = vect_dead; STMT_VINFO_VECTYPE (res) = NULL; STMT_VINFO_VEC_STMT (res) = NULL; STMT_VINFO_IN_PATTERN_P (res) = false; Index: gcc/testsuite/gcc.dg/vect/vect-debug-pr41926.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ gcc/testsuite/gcc.dg/vect/vect-debug-pr41926.c 2009-11-05 04:36:47.000000000 -0200 @@ -0,0 +1,20 @@ +/* PR debug/41926 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g -ffast-math -funroll-loops -ftree-vectorize -msse2" { target { i?86-*-* x86_64-*-* } } } */ + +void +foo (double (*__restrict p)[4], double (*__restrict q)[4], + double *__restrict prim, double scale, double pp, double pq) +{ + int md, mc, mb, ma, p_index = 0; + + for (md = 0; md < 1; md++) + for (mc = 0; mc < 1; mc++) + for (mb = 0; mb < 1; mb++) + for (ma = 0; ma < 4; ma++) + { + double tmp = scale * prim[p_index++]; + p[md][ma] = p[md][ma] - tmp * pp; + q[mc][ma] = q[mc][ma] - tmp * pq; + } +} -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist Red Hat Brazil Compiler Engineer |
|
|
Re: [vta, PR41926, graphite?] track debug uses during vectorizationOn Sun, Nov 8, 2009 at 9:07 AM, Alexandre Oliva <aoliva@...> wrote:
> PR debug/41926 was a case in which a debug use outside a vectorized loop > remained, referencing an SSA DEF that no longer dominated the use > because of vectorization. > > In order to fix this, I extended the live-tracking information so as to > record debug uses in addition to nondebug uses. Then, if a name in the > vectorized loop is found to be referenced outside the loop only by debug > insns (case in which we won't create a PHI node at the join point), we > reset the debug use. > > I managed to convert the testcase to C, but it requires the patch I've > just posted to exercise the bug fixed by the patch below. I'm not happy > with the options-management in this testcase, though. I need > -ffast-math and -funroll-loops to trigger it, so the standard names > handled by vect.exp don't work, and I can't add options to the default > per-machine vectorization options vect.exp sets up. So I made in > x86-only, but I'd appreciate suggestions on how to make it better. > Anyone? > > Bootstrapped on x86_64-linux-gnu; regstrapping on that and > ia64-linux-gnu. Ok to install? Ugh. You could simplify the patch if you'd unconditionally do if (!STMT_VINFO_RELEVANT_P (stmt_info) && !STMT_VINFO_LIVE_P (stmt_info)) { if (MAY_HAVE_DEBUG_STMTS) vect_loop_kill_debug_uses (loop, phi); continue; } it looks wrong to have a tri-state liveness to me, at least it confuses the occasional reader and the enum casts are ugly anyway. If the above works out for you a patch along the above is pre-approved. Thanks, Richard. > > > > -- > Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ > You must be the change you wish to see in the world. -- Gandhi > Be Free! -- http://FSFLA.org/ FSF Latin America board member > Free Software Evangelist Red Hat Brazil Compiler Engineer > > |
|
|
Re: [vta, PR41926, graphite?] track debug uses during vectorizationOn Nov 8, 2009, Richard Guenther <richard.guenther@...> wrote:
> Ugh. You could simplify the patch if you'd unconditionally do > if (!STMT_VINFO_RELEVANT_P (stmt_info) > && !STMT_VINFO_LIVE_P (stmt_info)) > { > if (MAY_HAVE_DEBUG_STMTS) > vect_loop_kill_debug_uses (loop, phi); > continue; > } > If the above works out for you a patch along the above is pre-approved. Thanks, here's what I checked in. for gcc/ChangeLog from Alexandre Oliva <aoliva@...> PR debug/41926 * tree-vect-loop.c (vect_loop_kill_debug_uses): New. (vect_transform_loop): Call it. for gcc/testsuite/ChangeLog from Alexandre Oliva <aoliva@...> PR debug/41926 * gcc.dg/vect/vect-debug-pr41926.c: New. Index: gcc/tree-vect-loop.c =================================================================== --- gcc/tree-vect-loop.c.orig 2009-11-16 20:25:28.000000000 -0200 +++ gcc/tree-vect-loop.c 2009-11-16 20:27:24.000000000 -0200 @@ -4112,6 +4112,44 @@ vectorizable_live_operation (gimple stmt return true; } +/* Kill any debug uses outside LOOP of SSA names defined in STMT. */ + +static void +vect_loop_kill_debug_uses (struct loop *loop, gimple stmt) +{ + ssa_op_iter op_iter; + imm_use_iterator imm_iter; + def_operand_p def_p; + gimple ustmt; + + FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF) + { + FOR_EACH_IMM_USE_STMT (ustmt, imm_iter, DEF_FROM_PTR (def_p)) + { + basic_block bb; + + if (!is_gimple_debug (ustmt)) + continue; + + bb = gimple_bb (ustmt); + + if (!flow_bb_inside_loop_p (loop, bb)) + { + if (gimple_debug_bind_p (ustmt)) + { + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "killing debug use"); + + gimple_debug_bind_reset_value (ustmt); + update_stmt (ustmt); + } + else + gcc_unreachable (); + } + } + } +} + /* Function vect_transform_loop. The analysis phase has determined that the loop is vectorizable. @@ -4202,7 +4240,11 @@ vect_transform_loop (loop_vec_info loop_ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !STMT_VINFO_LIVE_P (stmt_info)) - continue; + { + if (MAY_HAVE_DEBUG_STMTS) + vect_loop_kill_debug_uses (loop, phi); + continue; + } if ((TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info)) != (unsigned HOST_WIDE_INT) vectorization_factor) @@ -4242,6 +4284,8 @@ vect_transform_loop (loop_vec_info loop_ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !STMT_VINFO_LIVE_P (stmt_info)) { + if (MAY_HAVE_DEBUG_STMTS) + vect_loop_kill_debug_uses (loop, stmt); gsi_next (&si); continue; } Index: gcc/testsuite/gcc.dg/vect/vect-debug-pr41926.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ gcc/testsuite/gcc.dg/vect/vect-debug-pr41926.c 2009-11-16 20:27:24.000000000 -0200 @@ -0,0 +1,20 @@ +/* PR debug/41926 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g -ffast-math -funroll-loops -ftree-vectorize -msse2" { target { i?86-*-* x86_64-*-* } } } */ + +void +foo (double (*__restrict p)[4], double (*__restrict q)[4], + double *__restrict prim, double scale, double pp, double pq) +{ + int md, mc, mb, ma, p_index = 0; + + for (md = 0; md < 1; md++) + for (mc = 0; mc < 1; mc++) + for (mb = 0; mb < 1; mb++) + for (ma = 0; ma < 4; ma++) + { + double tmp = scale * prim[p_index++]; + p[md][ma] = p[md][ma] - tmp * pp; + q[mc][ma] = q[mc][ma] - tmp * pq; + } +} -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist Red Hat Brazil Compiler Engineer |
| Free embeddable forum powered by Nabble | Forum Help |