Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:11.4
libgcj43
pr34043-5.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pr34043-5.diff of Package libgcj43
2008-02-29 Richard Guenther <rguenther@suse.de> PR tree-optimization/34043 PR tree-optimization/33989 * tree-ssa-pre.c (get_sccvn_value): Build a value handle for to be inserted expressions. (substitute_leaders_in_expr): New function. (eliminate): If we do not have a fully redundant leader but can insert an alternate simplified expression, do so with all operands replaced with their leader. * tree-ssa-sccvn.h (struct vn_ssa_aux): Add needs_insertion flag. * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Value-number union member access based on its size, not type and member. (visit_reference_op_load): For a weak match from union type punning create a fake SSA_NAME to attach a value-number for the result VIEW_CONVERTed to the correct type. (free_scc_vn): Release fake SSA_NAMEs again. * gcc.dg/tree-ssa/ssa-fre-7.c: New testcase. * gcc.dg/tree-ssa/ssa-fre-8.c: Likewise. Index: gcc-4.3.2-20080715/gcc/tree-ssa-pre.c =================================================================== *** gcc-4.3.2-20080715.orig/gcc/tree-ssa-pre.c 2008-07-15 15:13:10.000000000 +0200 --- gcc-4.3.2-20080715/gcc/tree-ssa-pre.c 2008-07-15 15:14:23.000000000 +0200 *************** clear_expression_ids (void) *** 284,290 **** VEC_free (vuse_vec, heap, expression_vuses); } ! static bool in_fre = false; /* An unordered bitmap set. One bitmap tracks values, the other, expressions. */ --- 284,290 ---- VEC_free (vuse_vec, heap, expression_vuses); } ! bool in_fre = false; /* An unordered bitmap set. One bitmap tracks values, the other, expressions. */ *************** get_sccvn_value (tree name) *** 3244,3254 **** bool is_invariant = is_gimple_min_invariant (val); tree valvh = !is_invariant ? get_value_handle (val) : NULL_TREE; /* We may end up with situations where SCCVN has chosen a representative for the equivalence set that we have not visited yet. In this case, just create the value handle for it. */ ! if (!valvh && !is_invariant) { tree defstmt = SSA_NAME_DEF_STMT (val); --- 3244,3259 ---- bool is_invariant = is_gimple_min_invariant (val); tree valvh = !is_invariant ? get_value_handle (val) : NULL_TREE; + /* In the case SCCVN has created a dummy SSA_NAME to value + number a simplified expression, just create a value handle + for it. */ + if (!valvh && !is_invariant && VN_INFO (val)->needs_insertion) + valvh = vn_lookup_or_add (VN_INFO (val)->expr); /* We may end up with situations where SCCVN has chosen a representative for the equivalence set that we have not visited yet. In this case, just create the value handle for it. */ ! else if (!valvh && !is_invariant) { tree defstmt = SSA_NAME_DEF_STMT (val); *************** compute_avail (void) *** 3597,3602 **** --- 3602,3655 ---- free (worklist); } + /* Substitutes leaders for all operands in EXPR supposed to replace + the rhs of STMT in basic-block BB. + Returns an available expression if that succeeds, NULL_TREE otherwise. */ + + static tree + substitute_leaders_in_expr (basic_block bb, tree stmt, tree expr) + { + switch (TREE_CODE_CLASS (TREE_CODE (expr))) + { + case tcc_reference: + if (TREE_CODE (expr) != VIEW_CONVERT_EXPR + && TREE_CODE (expr) != REALPART_EXPR + && TREE_CODE (expr) != IMAGPART_EXPR) + return NULL_TREE; + + /* Fallthrough. */ + case tcc_unary: + if (is_gimple_min_invariant (TREE_OPERAND (expr, 0))) + return expr; + if (TREE_CODE (TREE_OPERAND (expr, 0)) == SSA_NAME) + { + tree def_stmt; + tree tmp = get_value_handle (TREE_OPERAND (expr, 0)); + tmp = bitmap_find_leader (AVAIL_OUT (bb), tmp); + if (!tmp) + return NULL_TREE; + /* tmp can still be unavailable if it is defined in the same + basic-block, but after stmt. libgomp.fortran/retval1.f90:f5 */ + def_stmt = SSA_NAME_DEF_STMT (tmp); + if (def_stmt + && TREE_CODE (def_stmt) != PHI_NODE + && bb_for_stmt (def_stmt) == bb) + { + block_stmt_iterator bsi = bsi_start (bb); + while (bsi_stmt (bsi) != def_stmt) + { + if (bsi_stmt (bsi) == stmt) + return NULL_TREE; + bsi_next (&bsi); + } + } + return build1 (TREE_CODE (expr), TREE_TYPE (expr), tmp); + } + + default:; + } + return NULL_TREE; + } /* Eliminate fully redundant computations. */ *************** eliminate (void) *** 3629,3634 **** --- 3682,3703 ---- sprime = bitmap_find_leader (AVAIL_OUT (b), get_value_handle (lhs)); + /* If we didn't find a leader but have an expression + we can insert, use that as replacement. */ + if (sprime + && sprime == lhs + && VN_INFO (lhs)->valnum != VN_TOP + /* Instead of VN_TOP we also can end up with a + constant value. g++.dg/opt/reload1.C */ + && TREE_CODE (VN_INFO (lhs)->valnum) == SSA_NAME + && VN_INFO (VN_INFO (lhs)->valnum)->needs_insertion) + { + tree tmp = VN_INFO (VN_INFO (lhs)->valnum)->expr; + tmp = substitute_leaders_in_expr (b, stmt, tmp); + if (tmp) + sprime = tmp; + } + if (sprime && sprime != lhs && (TREE_CODE (*rhs_p) != SSA_NAME Index: gcc-4.3.2-20080715/gcc/tree-ssa-sccvn.c =================================================================== *** gcc-4.3.2-20080715.orig/gcc/tree-ssa-sccvn.c 2008-07-15 15:13:10.000000000 +0200 --- gcc-4.3.2-20080715/gcc/tree-ssa-sccvn.c 2008-07-15 15:17:01.000000000 +0200 *************** along with GCC; see the file COPYING3. *** 103,108 **** --- 103,110 ---- structure copies. */ + extern bool in_fre; + /* The set of hashtables and alloc_pool's for their items. */ typedef struct vn_tables_s *************** copy_reference_ops_from_ref (tree ref, V *** 538,546 **** temp.op1 = TREE_OPERAND (ref, 2); break; case COMPONENT_REF: ! /* Record field as operand. */ ! temp.op0 = TREE_OPERAND (ref, 1); ! temp.op1 = TREE_OPERAND (ref, 2); break; case ARRAY_RANGE_REF: case ARRAY_REF: --- 540,562 ---- temp.op1 = TREE_OPERAND (ref, 2); break; case COMPONENT_REF: ! /* If this is a reference to a union member, record the union ! member size as operand. */ ! if (in_fre ! && TREE_CODE (DECL_CONTEXT (TREE_OPERAND (ref, 1))) == UNION_TYPE ! && integer_zerop (DECL_FIELD_OFFSET (TREE_OPERAND (ref, 1))) ! && integer_zerop (DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1))) ! && !TREE_OPERAND (ref, 2)) ! { ! temp.type = NULL_TREE; ! temp.op0 = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (ref, 1))); ! } ! else ! { ! /* Record field as operand. */ ! temp.op0 = TREE_OPERAND (ref, 1); ! temp.op1 = TREE_OPERAND (ref, 2); ! } break; case ARRAY_RANGE_REF: case ARRAY_REF: *************** defs_to_varying (tree stmt) *** 1109,1114 **** --- 1125,1133 ---- return changed; } + static tree + try_to_simplify (tree stmt, tree rhs); + /* Visit a copy between LHS and RHS, return true if the value number changed. */ *************** visit_reference_op_load (tree lhs, tree *** 1181,1188 **** bool changed = false; tree result = vn_reference_lookup (op, shared_vuses_from_stmt (stmt)); ! if (result) ! { changed = set_ssa_val_to (lhs, result); } else --- 1200,1252 ---- bool changed = false; tree result = vn_reference_lookup (op, shared_vuses_from_stmt (stmt)); ! /* We handle type-punning through unions by value-numbering based ! on offset and size of the access. Be prepared to handle a ! type-mismatch here via creating a VIEW_CONVERT_EXPR. ! Do this only after the iteration converged as introducing new ! SSA_NAMEs will let it never finish otherwise. */ ! if (result ! && (useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (op)) ! || current_info == valid_info)) ! { ! if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (op))) ! { ! tree val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (op), ! result); ! /* Make sure to simplify with earlier conversions as otherwise ! our dummy SSA_NAMEs start to leak all over. */ ! if (TREE_CODE (val) == VIEW_CONVERT_EXPR) ! { ! tree tem = try_to_simplify (stmt, val); ! if (tem) ! val = tem; ! } ! result = val; ! if (result != lhs ! && !is_gimple_min_invariant (val) ! && TREE_CODE (val) != SSA_NAME) ! /* Finally do a lookup to not create redundant conversions. */ ! result = vn_unary_op_lookup (val); ! if (!result) ! { ! /* Create a new temporary SSA_NAME to attach the ! conversion expression to. */ ! result = make_ssa_name (SSA_NAME_VAR (lhs), NULL_TREE); ! VN_INFO_GET (result)->valnum = result; ! VN_INFO (result)->expr = val; ! VN_INFO (result)->needs_insertion = true; ! /* And insert the conversion so we can find it later. */ ! vn_unary_op_insert (val, result); ! if (dump_file && (dump_flags & TDF_DETAILS)) ! { ! fprintf (dump_file, "Inserting name "); ! print_generic_expr (dump_file, result, 0); ! fprintf (dump_file, " for expression "); ! print_generic_expr (dump_file, val, 0); ! fprintf (dump_file, "\n"); ! } ! } ! } changed = set_ssa_val_to (lhs, result); } else *************** free_scc_vn (void) *** 2140,2145 **** --- 2204,2212 ---- if (SSA_NAME_VALUE (name) && TREE_CODE (SSA_NAME_VALUE (name)) == VALUE_HANDLE) SSA_NAME_VALUE (name) = NULL; + if (name + && VN_INFO (name)->needs_insertion) + release_ssa_name (name); } } Index: gcc-4.3.2-20080715/gcc/tree-ssa-sccvn.h =================================================================== *** gcc-4.3.2-20080715.orig/gcc/tree-ssa-sccvn.h 2008-02-19 10:55:59.000000000 +0100 --- gcc-4.3.2-20080715/gcc/tree-ssa-sccvn.h 2008-07-15 15:14:23.000000000 +0200 *************** typedef struct vn_ssa_aux *** 44,49 **** --- 44,53 ---- once. It cannot be used to avoid visitation for SSA_NAME's involved in non-singleton SCC's. */ unsigned use_processed : 1; + + /* True, if this SSA_NAME doesn't have a defining statement. + Insertion of such with expr or replacement with expr is necessary. */ + unsigned needs_insertion : 1; } *vn_ssa_aux_t; /* Return the value numbering info for an SSA_NAME. */ Index: gcc-4.3.2-20080715/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c =================================================================== *** /dev/null 1970-01-01 00:00:00.000000000 +0000 --- gcc-4.3.2-20080715/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c 2008-07-15 15:14:23.000000000 +0200 *************** *** 0 **** --- 1,30 ---- + /* { dg-do compile } */ + /* { dg-options "-O -fdump-tree-fre-details -fdump-tree-optimized" } */ + + struct X { + int i; + union { + int j; + int k; + float f; + } u; + }; + + int foo(int j) + { + struct X a; + + a.u.j = j; + a.u.f = a.u.f; + a.u.f = a.u.f; + a.u.j = a.u.j; + a.u.f = a.u.f; + return a.u.k; + } + + /* { dg-final { scan-tree-dump "Replaced a.u.f with VIEW_CONVERT_EXPR" "fre" } } */ + /* { dg-final { scan-tree-dump "Replaced a.u.j with j" "fre" } } */ + /* { dg-final { scan-tree-dump "Replaced a.u.k with j" "fre" } } */ + /* { dg-final { scan-tree-dump "return j" "optimized" } } */ + /* { dg-final { cleanup-tree-dump "fre" } } */ + /* { dg-final { cleanup-tree-dump "optimized" } } */ Index: gcc-4.3.2-20080715/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c =================================================================== *** /dev/null 1970-01-01 00:00:00.000000000 +0000 --- gcc-4.3.2-20080715/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c 2008-07-15 15:14:23.000000000 +0200 *************** *** 0 **** --- 1,26 ---- + /* { dg-do compile } */ + /* { dg-options "-O -fdump-tree-fre-details" } */ + + union U { + int i; + float f; + }; + int foo(int i, int b) + { + union U u; + if (b) + { + i = i << 2; + u.i = i; + return u.f; + } + else + { + i = i << 2; + u.i = i; + return u.f; + } + } + + /* { dg-final { scan-tree-dump-times "Replaced u.f with VIEW_CONVERT_EXPR" 2 "fre" } } */ + /* { dg-final { cleanup-tree-dump "fre" } } */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor