This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix PR40321


Sure, if you want to fix it this way, that's fine, as long as it
actually works :)
The last time we had things defined by phis in the maximal set, bits
could get added that would never go away.  There was no avail_out
check in clean, the only way things fell out of the set past their
definition point was through being in TMP_GEN, and PHI's weren't in
there, so PHI's would be considered ANTIC well before their definition
points.



On Fri, Jul 17, 2009 at 4:59 AM, Richard Guenther<rguenther@suse.de> wrote:
>
> This fixes PR40321 where the issue is that we have a too small maximal
> set (it misses PHI arguments) which in turn causes oscillations during
> antic computation.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu. ?Ok for trunk
> and the 4.4 branch after a while?
>
> Thanks,
> Richard.
>
> 2009-07-17 ?Richard Guenther ?<rguenther@suse.de>
>
> ? ? ? ?PR tree-optimization/40321
> ? ? ? ?* tree-ssa-pre.c (add_to_exp_gen): Also add names defined by
> ? ? ? ?PHI nodes to the maximal set.
> ? ? ? ?(make_values_for_phi): Add PHI arguments to the maximal set.
> ? ? ? ?(execute_pre): Dump PHI_GEN and the maximal set.
>
> ? ? ? ?* gcc.c-torture/compile/pr40321.c: New testcase.
> ? ? ? ?* g++.dg/torture/pr40321.C: Likewise.
>
> Index: gcc/tree-ssa-pre.c
> ===================================================================
> *** gcc/tree-ssa-pre.c.orig ? ? 2009-07-16 16:47:07.000000000 +0200
> --- gcc/tree-ssa-pre.c ?2009-07-17 10:56:51.000000000 +0200
> *************** vro_valid_in_sets (bitmap_set_t set1, bi
> *** 1996,2003 ****
> ? ? ONLY SET2 CAN BE NULL.
> ? ? This means that we have a leader for each part of the expression
> ? ? (if it consists of values), or the expression is an SSA_NAME.
> ! ? ?For loads/calls, we also see if the vuse is killed in this block.
> ! */
>
> ?static bool
> ?valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, pre_expr expr,
> --- 1996,2002 ----
> ? ? ONLY SET2 CAN BE NULL.
> ? ? This means that we have a leader for each part of the expression
> ? ? (if it consists of values), or the expression is an SSA_NAME.
> ! ? ?For loads/calls, we also see if the vuse is killed in this block. ?*/
>
> ?static bool
> ?valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, pre_expr expr,
> *************** insert (void)
> *** 3625,3635 ****
> ?}
>
>
> ! /* Add OP to EXP_GEN (block), and possibly to the maximal set if it is
> ! ? ?not defined by a phi node.
> ! ? ?PHI nodes can't go in the maximal sets because they are not in
> ! ? ?TMP_GEN, so it is possible to get into non-monotonic situations
> ! ? ?during ANTIC calculation, because it will *add* bits. ?*/
>
> ?static void
> ?add_to_exp_gen (basic_block block, tree op)
> --- 3624,3630 ----
> ?}
>
>
> ! /* Add OP to EXP_GEN (block), and possibly to the maximal set. ?*/
>
> ?static void
> ?add_to_exp_gen (basic_block block, tree op)
> *************** add_to_exp_gen (basic_block block, tree
> *** 3641,3649 ****
> ? ? ? ?return;
> ? ? ? ?result = get_or_alloc_expr_for_name (op);
> ? ? ? ?bitmap_value_insert_into_set (EXP_GEN (block), result);
> ! ? ? ? if (TREE_CODE (op) != SSA_NAME
> ! ? ? ? ? || gimple_code (SSA_NAME_DEF_STMT (op)) != GIMPLE_PHI)
> ! ? ? ? bitmap_value_insert_into_set (maximal_set, result);
> ? ? ?}
> ?}
>
> --- 3636,3642 ----
> ? ? ? ?return;
> ? ? ? ?result = get_or_alloc_expr_for_name (op);
> ? ? ? ?bitmap_value_insert_into_set (EXP_GEN (block), result);
> ! ? ? ? bitmap_value_insert_into_set (maximal_set, result);
> ? ? ?}
> ?}
>
> *************** make_values_for_phi (gimple phi, basic_b
> *** 3662,3667 ****
> --- 3655,3674 ----
> ? ? ? ?add_to_value (get_expr_value_id (e), e);
> ? ? ? ?bitmap_insert_into_set (PHI_GEN (block), e);
> ? ? ? ?bitmap_value_insert_into_set (AVAIL_OUT (block), e);
> + ? ? ? if (!in_fre)
> + ? ? ? {
> + ? ? ? ? unsigned i;
> + ? ? ? ? for (i = 0; i < gimple_phi_num_args (phi); ++i)
> + ? ? ? ? ? {
> + ? ? ? ? ? ? tree arg = gimple_phi_arg_def (phi, i);
> + ? ? ? ? ? ? if (TREE_CODE (arg) == SSA_NAME)
> + ? ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? ? e = get_or_alloc_expr_for_name (arg);
> + ? ? ? ? ? ? ? ? add_to_value (get_expr_value_id (e), e);
> + ? ? ? ? ? ? ? ? bitmap_value_insert_into_set (maximal_set, e);
> + ? ? ? ? ? ? ? }
> + ? ? ? ? ? }
> + ? ? ? }
> ? ? ?}
> ?}
>
> *************** execute_pre (bool do_fre ATTRIBUTE_UNUSE
> *** 4509,4519 ****
> ? ? ? ?FOR_ALL_BB (bb)
> ? ? ? ?{
> ? ? ? ? ?print_bitmap_set (dump_file, EXP_GEN (bb), "exp_gen", bb->index);
> ! ? ? ? ? print_bitmap_set (dump_file, TMP_GEN (bb), "tmp_gen",
> ! ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? bb->index);
> ! ? ? ? ? print_bitmap_set (dump_file, AVAIL_OUT (bb), "avail_out",
> ! ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? bb->index);
> ? ? ? ?}
> ? ? ?}
>
> ? ?/* Insert can get quite slow on an incredibly large number of basic
> --- 4516,4527 ----
> ? ? ? ?FOR_ALL_BB (bb)
> ? ? ? ?{
> ? ? ? ? ?print_bitmap_set (dump_file, EXP_GEN (bb), "exp_gen", bb->index);
> ! ? ? ? ? print_bitmap_set (dump_file, PHI_GEN (bb), "phi_gen", bb->index);
> ! ? ? ? ? print_bitmap_set (dump_file, TMP_GEN (bb), "tmp_gen", bb->index);
> ! ? ? ? ? print_bitmap_set (dump_file, AVAIL_OUT (bb), "avail_out", bb->index);
> ? ? ? ?}
> +
> + ? ? ? print_bitmap_set (dump_file, maximal_set, "maximal", 0);
> ? ? ?}
>
> ? ?/* Insert can get quite slow on an incredibly large number of basic
> Index: gcc/testsuite/gcc.c-torture/compile/pr40321.c
> ===================================================================
> *** /dev/null ? 1970-01-01 00:00:00.000000000 +0000
> --- gcc/testsuite/gcc.c-torture/compile/pr40321.c ? ? ? 2009-07-17 10:56:27.000000000 +0200
> ***************
> *** 0 ****
> --- 1,12 ----
> + struct X { int flag; int pos; };
> + int foo(struct X *a, struct X *b)
> + {
> + ? while (1)
> + ? ? {
> + ? ? ? if (a->flag)
> + ? ? ? break;
> + ? ? ? ({ struct X *tmp = a; a = b; b = tmp; });
> + ? ? }
> +
> + ? return a->pos + b->pos;
> + }
> Index: gcc/testsuite/g++.dg/torture/pr40321.C
> ===================================================================
> *** /dev/null ? 1970-01-01 00:00:00.000000000 +0000
> --- gcc/testsuite/g++.dg/torture/pr40321.C ? ? ?2009-07-17 10:56:27.000000000 +0200
> ***************
> *** 0 ****
> --- 1,25 ----
> + /* { dg-do compile } */
> +
> + struct VectorD2
> + {
> + ? VectorD2() : x(0), y(0) { }
> + ? VectorD2(int _x, int _y) : x(_x), y(_y) { }
> + ? int x, y;
> + ? int GetLength2() const { return x*x + y*y; };
> + ? VectorD2 operator+(const VectorD2 vec) const {
> + ? ? ? return VectorD2(x+vec.x,y+vec.y);
> + ? }
> + };
> + struct Shape
> + {
> + ? enum Type { ST_RECT, ST_CIRCLE } type;
> + ? VectorD2 pos;
> + ? VectorD2 radius;
> + ? bool CollisionWith(const Shape& s) const;
> + };
> + bool Shape::CollisionWith(const Shape& s) const
> + {
> + ? if(type == ST_CIRCLE && s.type == ST_RECT)
> + ? ? return s.CollisionWith(*this);
> + ? return (pos + s.pos).GetLength2() < (radius + s.radius).GetLength2();
> + }
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]