From: Tomas Bily Date: Wed, 3 Dec 2008 13:35:13 +0000 (+0100) Subject: re PR middle-end/38250 (ICE with -O2 -ftree-loop-distribution) X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3661e899786b93d537873fa8508255e1e44190c7;p=platform%2Fupstream%2Fgcc.git re PR middle-end/38250 (ICE with -O2 -ftree-loop-distribution) PR middle-end/38250 * tree-loop-distribution.c (build_size_arg): New function. (generate_memset_zero): Checks if DR_STEP(de) is NULL. Reorganized generating of stmts. * testsuite/gcc.dg/tree-ssa/pr38250.c: New file. * tree-data-ref.c (dr_analyze_innermost): Returns bool. Indicate if analysis succeed. * tree-data-ref.h (dr_analyze_innermost): Returns bool. * tree-predcom.c (valid_initializer_p, find_looparound_phi): Uses new definition of dr_analyze_innermost. From-SVN: r142394 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e62cbdc..03da741 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2008-12-03 Tomas Bily + + PR middle-end/38250 + * tree-loop-distribution.c (build_size_arg): New function. + (generate_memset_zero): Checks if dr_analyze_innermost succeed. + Reorganized generating of stmts. + * testsuite/gcc.dg/tree-ssa/pr38250.c: New file. + * tree-data-ref.c (dr_analyze_innermost): Returns bool. + Indicate if analysis succeed. + * tree-data-ref.h (dr_analyze_innermost): Returns bool. + * tree-predcom.c (valid_initializer_p, find_looparound_phi): + Uses new definition of dr_analyze_innermost. + 2008-12-03 Ben Elliston * tree-ssa-pre.c (do_regular_insertion): Initialise edoubleprime. diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 4f1a9fd..2715339 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -667,9 +667,9 @@ canonicalize_base_object_address (tree addr) } /* Analyzes the behavior of the memory reference DR in the innermost loop that - contains it. */ + contains it. Returns true if analysis succeed or false otherwise. */ -void +bool dr_analyze_innermost (struct data_reference *dr) { gimple stmt = DR_STMT (dr); @@ -693,7 +693,7 @@ dr_analyze_innermost (struct data_reference *dr) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "failed: bit offset alignment.\n"); - return; + return false; } base = build_fold_addr_expr (base); @@ -701,7 +701,7 @@ dr_analyze_innermost (struct data_reference *dr) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "failed: evolution of base is not affine.\n"); - return; + return false; } if (!poffset) { @@ -712,7 +712,7 @@ dr_analyze_innermost (struct data_reference *dr) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "failed: evolution of offset is not affine.\n"); - return; + return false; } init = ssize_int (pbitpos / BITS_PER_UNIT); @@ -735,6 +735,8 @@ dr_analyze_innermost (struct data_reference *dr) if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "success.\n"); + + return true; } /* Determines the base object and the list of indices of memory reference diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h index bd36d237..3c2f1b2 100644 --- a/gcc/tree-data-ref.h +++ b/gcc/tree-data-ref.h @@ -381,7 +381,7 @@ DEF_VEC_O (data_ref_loc); DEF_VEC_ALLOC_O (data_ref_loc, heap); bool get_references_in_stmt (gimple, VEC (data_ref_loc, heap) **); -void dr_analyze_innermost (struct data_reference *); +bool dr_analyze_innermost (struct data_reference *); extern bool compute_data_dependences_for_loop (struct loop *, bool, VEC (data_reference_p, heap) **, VEC (ddr_p, heap) **); diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index bd6a932..062ab48 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -216,13 +216,30 @@ generate_loops_for_partition (struct loop *loop, bitmap partition, bool copy_p) return true; } +/* Build size argument. */ + +static inline tree +build_size_arg (tree nb_iter, tree op, gimple_seq* stmt_list) +{ + tree nb_bytes; + gimple_seq stmts = NULL; + + nb_bytes = fold_build2 (MULT_EXPR, TREE_TYPE (nb_iter), + nb_iter, TYPE_SIZE_UNIT (TREE_TYPE (op))); + nb_bytes = force_gimple_operand (nb_bytes, &stmts, true, NULL); + gimple_seq_add_seq (stmt_list, stmts); + + return nb_bytes; +} + /* Generate a call to memset. Return true when the operation succeeded. */ static bool generate_memset_zero (gimple stmt, tree op0, tree nb_iter, gimple_stmt_iterator bsi) { - tree t, nb_bytes, addr_base; + tree t, addr_base; + tree nb_bytes = NULL; bool res = false; gimple_seq stmts = NULL, stmt_list = NULL; gimple fn_call; @@ -231,14 +248,10 @@ generate_memset_zero (gimple stmt, tree op0, tree nb_iter, ssa_op_iter iter; struct data_reference *dr = XCNEW (struct data_reference); - nb_bytes = fold_build2 (MULT_EXPR, TREE_TYPE (nb_iter), - nb_iter, TYPE_SIZE_UNIT (TREE_TYPE (op0))); - nb_bytes = force_gimple_operand (nb_bytes, &stmts, true, NULL); - gimple_seq_add_seq (&stmt_list, stmts); - DR_STMT (dr) = stmt; DR_REF (dr) = op0; - dr_analyze_innermost (dr); + if (!dr_analyze_innermost (dr)) + goto end; /* Test for a positive stride, iterating over every element. */ if (integer_zerop (fold_build2 (MINUS_EXPR, integer_type_node, DR_STEP (dr), @@ -253,6 +266,7 @@ generate_memset_zero (gimple stmt, tree op0, tree nb_iter, TYPE_SIZE_UNIT (TREE_TYPE (op0)), DR_STEP (dr)))) { + nb_bytes = build_size_arg (nb_iter, op0, &stmt_list); addr_base = size_binop (PLUS_EXPR, DR_OFFSET (dr), DR_INIT (dr)); addr_base = fold_build2 (MINUS_EXPR, sizetype, addr_base, nb_bytes); addr_base = force_gimple_operand (addr_base, &stmts, true, NULL); @@ -272,6 +286,8 @@ generate_memset_zero (gimple stmt, tree op0, tree nb_iter, fntype = TREE_TYPE (fndecl); fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl); + if (!nb_bytes) + nb_bytes = build_size_arg (nb_iter, op0, &stmt_list); fn_call = gimple_build_call (fn, 3, mem, integer_zero_node, nb_bytes); gimple_seq_add_stmt (&stmt_list, fn_call); diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index b6ccfd7..54e0b7f 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -1026,9 +1026,6 @@ valid_initializer_p (struct data_reference *ref, aff_tree diff, base, step; double_int off; - if (!DR_BASE_ADDRESS (ref)) - return false; - /* Both REF and ROOT must be accessing the same object. */ if (!operand_equal_p (DR_BASE_ADDRESS (ref), DR_BASE_ADDRESS (root), 0)) return false; @@ -1115,7 +1112,8 @@ find_looparound_phi (struct loop *loop, dref ref, dref root) memset (&init_dr, 0, sizeof (struct data_reference)); DR_REF (&init_dr) = init_ref; DR_STMT (&init_dr) = phi; - dr_analyze_innermost (&init_dr); + if (!dr_analyze_innermost (&init_dr)) + return NULL; if (!valid_initializer_p (&init_dr, ref->distance + 1, root->ref)) return NULL;