From a41e5e86c0bbcb0dca6311a5e6dab8d7e005a076 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Mon, 5 Jul 2010 14:51:16 +0000 Subject: [PATCH] tree.c (reference_alias_ptr_type): New function. 2010-07-05 Richard Guenther * tree.c (reference_alias_ptr_type): New function. * tree.h (reference_alias_ptr_type): Declare. * tree-ssa-loop-ivopts.c (copy_ref_info): Restructure to allow non-TARGET_MEM_REF new refs. (rewrite_use_address): Pass old alias pointer type to create_mem_ref. * tree-ssa-address.c (create_mem_ref_raw): Get alias pointer type. Build a MEM_REF instead of a TARGET_MEM_REF if possible. (create_mem_ref): Get alias pointer type. Adjust calls to create_mem_ref_raw. (maybe_fold_tmr): Likewise. * tree-flow.h (create_mem_ref): Adjust prototype. From-SVN: r161840 --- gcc/ChangeLog | 15 +++++++++ gcc/tree-flow.h | 2 +- gcc/tree-ssa-address.c | 36 +++++++++++++++------ gcc/tree-ssa-loop-ivopts.c | 65 ++++++++++++++++++++++---------------- gcc/tree.c | 19 +++++++++++ gcc/tree.h | 1 + 6 files changed, 100 insertions(+), 38 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3e7eaa36552a..f4ad9076a1ba 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2010-07-05 Richard Guenther + + * tree.c (reference_alias_ptr_type): New function. + * tree.h (reference_alias_ptr_type): Declare. + * tree-ssa-loop-ivopts.c (copy_ref_info): Restructure to + allow non-TARGET_MEM_REF new refs. + (rewrite_use_address): Pass old alias pointer type to + create_mem_ref. + * tree-ssa-address.c (create_mem_ref_raw): Get alias pointer type. + Build a MEM_REF instead of a TARGET_MEM_REF if possible. + (create_mem_ref): Get alias pointer type. Adjust calls to + create_mem_ref_raw. + (maybe_fold_tmr): Likewise. + * tree-flow.h (create_mem_ref): Adjust prototype. + 2010-07-05 Jakub Jelinek PR c++/44808 diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index fb1373a1ad0a..fd9a5425368e 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -833,7 +833,7 @@ struct mem_address }; struct affine_tree_combination; -tree create_mem_ref (gimple_stmt_iterator *, tree, +tree create_mem_ref (gimple_stmt_iterator *, tree, tree, struct affine_tree_combination *, tree, bool); rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool); void get_address_description (tree, struct mem_address *); diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c index 3abfffe25ec8..cf7a81d66d00 100644 --- a/gcc/tree-ssa-address.c +++ b/gcc/tree-ssa-address.c @@ -338,7 +338,7 @@ valid_mem_ref_p (enum machine_mode mode, addr_space_t as, TARGET_MEM_REF. */ static tree -create_mem_ref_raw (tree type, struct mem_address *addr) +create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr) { if (!valid_mem_ref_p (TYPE_MODE (type), TYPE_ADDR_SPACE (type), addr)) return NULL_TREE; @@ -349,6 +349,24 @@ create_mem_ref_raw (tree type, struct mem_address *addr) if (addr->offset && integer_zerop (addr->offset)) addr->offset = NULL_TREE; + /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF. */ + if (alias_ptr_type + && !addr->index + && !addr->step) + { + tree base, offset; + gcc_assert (!addr->symbol ^ !addr->base); + if (addr->symbol) + base = build_fold_addr_expr (addr->symbol); + else + base = addr->base; + if (addr->offset) + offset = fold_convert (alias_ptr_type, addr->offset); + else + offset = build_int_cst (alias_ptr_type, 0); + return fold_build2 (MEM_REF, type, base, offset); + } + return build6 (TARGET_MEM_REF, type, addr->symbol, addr->base, addr->index, addr->step, addr->offset, NULL); @@ -628,8 +646,8 @@ gimplify_mem_ref_parts (gimple_stmt_iterator *gsi, struct mem_address *parts) of created memory reference. */ tree -create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr, - tree base_hint, bool speed) +create_mem_ref (gimple_stmt_iterator *gsi, tree type, tree alias_ptr_type, + aff_tree *addr, tree base_hint, bool speed) { tree mem_ref, tmp; tree atype; @@ -637,7 +655,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr, addr_to_parts (type, addr, base_hint, &parts, speed); gimplify_mem_ref_parts (gsi, &parts); - mem_ref = create_mem_ref_raw (type, &parts); + mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts); if (mem_ref) return mem_ref; @@ -653,7 +671,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr, true, NULL_TREE, true, GSI_SAME_STMT); parts.step = NULL_TREE; - mem_ref = create_mem_ref_raw (type, &parts); + mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts); if (mem_ref) return mem_ref; } @@ -688,7 +706,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr, parts.base = tmp; parts.symbol = NULL_TREE; - mem_ref = create_mem_ref_raw (type, &parts); + mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts); if (mem_ref) return mem_ref; } @@ -709,7 +727,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr, parts.base = parts.index; parts.index = NULL_TREE; - mem_ref = create_mem_ref_raw (type, &parts); + mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts); if (mem_ref) return mem_ref; } @@ -731,7 +749,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr, parts.offset = NULL_TREE; - mem_ref = create_mem_ref_raw (type, &parts); + mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts); if (mem_ref) return mem_ref; } @@ -819,7 +837,7 @@ maybe_fold_tmr (tree ref) if (!changed) return NULL_TREE; - ret = create_mem_ref_raw (TREE_TYPE (ref), &addr); + ret = create_mem_ref_raw (TREE_TYPE (ref), NULL_TREE, &addr); if (!ret) return NULL_TREE; diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 740db68fee06..db56b93470b3 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -5547,33 +5547,41 @@ unshare_and_remove_ssa_names (tree ref) static void copy_ref_info (tree new_ref, tree old_ref) { - if (TREE_CODE (old_ref) == TARGET_MEM_REF) - copy_mem_ref_info (new_ref, old_ref); - else - { - TMR_ORIGINAL (new_ref) = unshare_and_remove_ssa_names (old_ref); - TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (old_ref); - TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (old_ref); - /* We can transfer points-to information from an old pointer - or decl base to the new one. */ - if (TMR_BASE (new_ref) - && TREE_CODE (TMR_BASE (new_ref)) == SSA_NAME - && POINTER_TYPE_P (TREE_TYPE (TMR_BASE (new_ref))) - && !SSA_NAME_PTR_INFO (TMR_BASE (new_ref))) + tree new_ptr_base = NULL_TREE; + + if (TREE_CODE (old_ref) == TARGET_MEM_REF + && TREE_CODE (new_ref) == TARGET_MEM_REF) + TMR_ORIGINAL (new_ref) = TMR_ORIGINAL (old_ref); + else if (TREE_CODE (new_ref) == TARGET_MEM_REF) + TMR_ORIGINAL (new_ref) = unshare_and_remove_ssa_names (old_ref); + + TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (old_ref); + TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (old_ref); + + if (TREE_CODE (new_ref) == TARGET_MEM_REF) + new_ptr_base = TMR_BASE (new_ref); + else if (TREE_CODE (new_ref) == MEM_REF) + new_ptr_base = TREE_OPERAND (new_ref, 0); + + /* We can transfer points-to information from an old pointer + or decl base to the new one. */ + if (new_ptr_base + && TREE_CODE (new_ptr_base) == SSA_NAME + && POINTER_TYPE_P (TREE_TYPE (new_ptr_base)) + && !SSA_NAME_PTR_INFO (new_ptr_base)) + { + tree base = get_base_address (old_ref); + if ((INDIRECT_REF_P (base) + || TREE_CODE (base) == MEM_REF) + && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME) + duplicate_ssa_name_ptr_info + (new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))); + else if (TREE_CODE (base) == VAR_DECL + || TREE_CODE (base) == PARM_DECL + || TREE_CODE (base) == RESULT_DECL) { - tree base = get_base_address (old_ref); - if ((INDIRECT_REF_P (base) - || TREE_CODE (base) == MEM_REF) - && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME) - duplicate_ssa_name_ptr_info - (TMR_BASE (new_ref), SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))); - else if (TREE_CODE (base) == VAR_DECL - || TREE_CODE (base) == PARM_DECL - || TREE_CODE (base) == RESULT_DECL) - { - struct ptr_info_def *pi = get_ptr_info (TMR_BASE (new_ref)); - pt_solution_set_var (&pi->pt, base); - } + struct ptr_info_def *pi = get_ptr_info (new_ptr_base); + pt_solution_set_var (&pi->pt, base); } } } @@ -5608,8 +5616,9 @@ rewrite_use_address (struct ivopts_data *data, if (cand->iv->base_object) base_hint = var_at_stmt (data->current_loop, cand, use->stmt); - ref = create_mem_ref (&bsi, TREE_TYPE (*use->op_p), &aff, base_hint, - data->speed); + ref = create_mem_ref (&bsi, TREE_TYPE (*use->op_p), + reference_alias_ptr_type (*use->op_p), + &aff, base_hint, data->speed); copy_ref_info (ref, *use->op_p); *use->op_p = ref; } diff --git a/gcc/tree.c b/gcc/tree.c index cb2c276b7156..e6deacce0f79 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -3913,6 +3913,25 @@ mem_ref_offset (const_tree t) TYPE_PRECISION (TREE_TYPE (toff))); } +/* Return the pointer-type relevant for TBAA purposes from the + gimple memory reference tree T. This is the type to be used for + the offset operand of MEM_REF or TARGET_MEM_REF replacements of T. */ + +tree +reference_alias_ptr_type (const_tree t) +{ + const_tree base = t; + while (handled_component_p (base)) + base = TREE_OPERAND (base, 0); + if (TREE_CODE (base) == MEM_REF) + return TREE_TYPE (TREE_OPERAND (base, 1)); + else if (TREE_CODE (base) == TARGET_MEM_REF + || TREE_CODE (base) == MISALIGNED_INDIRECT_REF) + return NULL_TREE; + else + return build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (base))); +} + /* Similar except don't specify the TREE_TYPE and leave the TREE_SIDE_EFFECTS as 0. It is permissible for arguments to be null, diff --git a/gcc/tree.h b/gcc/tree.h index ca4ec2ab8546..934de7de68e3 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4965,6 +4965,7 @@ extern tree build_simple_mem_ref_loc (location_t, tree); #define build_simple_mem_ref(T)\ build_simple_mem_ref_loc (UNKNOWN_LOCATION, T) extern double_int mem_ref_offset (const_tree); +extern tree reference_alias_ptr_type (const_tree); extern tree constant_boolean_node (int, tree); extern tree div_if_zero_remainder (enum tree_code, const_tree, const_tree); -- 2.39.5