From c3a9c1491f5e4ec2fe1faae609bd2287e4fce011 Mon Sep 17 00:00:00 2001 From: kenner Date: Mon, 1 Oct 2001 23:22:24 +0000 Subject: [PATCH] * alias.c (get_alias_set): Try to replace PLACEHOLDER_EXPR. Loop through NOPs, placeholders, and components. Don't go through NOPs if change mode. (record_alias_subset): Do nothing if SUBSET and SET are the same. * emit-rtl.c (set_mem_alias_set): Enable check. * expr.c (find_placeholder): New function. (expand_expr, case PLACEHOLDER_EXPR): Use it. (expand_expr, case COMPONENT_EXPR): Always copy OP0 when we need to modify it and avoid unneeded copies. * expr.h (expand_expr): Always define. (find_placeholder): New declaration. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@45931 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 14 ++++++ gcc/alias.c | 45 +++++++++++------ gcc/emit-rtl.c | 2 - gcc/expr.c | 154 ++++++++++++++++++++++++++++++++------------------------- gcc/expr.h | 10 +++- 5 files changed, 138 insertions(+), 87 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8c22804e8a0..1762d1ebcdc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +Mon Oct 1 19:20:57 2001 Richard Kenner + + * alias.c (get_alias_set): Try to replace PLACEHOLDER_EXPR. + Loop through NOPs, placeholders, and components. + Don't go through NOPs if change mode. + (record_alias_subset): Do nothing if SUBSET and SET are the same. + * emit-rtl.c (set_mem_alias_set): Enable check. + * expr.c (find_placeholder): New function. + (expand_expr, case PLACEHOLDER_EXPR): Use it. + (expand_expr, case COMPONENT_EXPR): Always copy OP0 when we need + to modify it and avoid unneeded copies. + * expr.h (expand_expr): Always define. + (find_placeholder): New declaration. + 2001-10-01 Stephane Carrez * config/m68hc11/m68hc11.md ("add-split"): Fix add split when diff --git a/gcc/alias.c b/gcc/alias.c index bf7c5e33e4f..37a8790c2ee 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -470,16 +470,32 @@ get_alias_set (t) return 0; /* We can be passed either an expression or a type. This and the - language-specific routine may make mutually-recursive calls to - each other to figure out what to do. At each juncture, we see if - this is a tree that the language may need to handle specially. - First handle things that aren't types and start by removing nops - since we care only about the actual object. */ + language-specific routine may make mutually-recursive calls to each other + to figure out what to do. At each juncture, we see if this is a tree + that the language may need to handle specially. First handle things that + aren't types and start by removing nops since we care only about the + actual object. Also replace PLACEHOLDER_EXPRs and pick up the outermost + object that we could have a pointer to. */ if (! TYPE_P (t)) { - while (TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR - || TREE_CODE (t) == NON_LVALUE_EXPR) - t = TREE_OPERAND (t, 0); + /* Remove any NOPs and see what any PLACEHOLD_EXPRs will expand to. */ + while (((TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR) + && (TYPE_MODE (TREE_TYPE (t)) + == TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 0))))) + || TREE_CODE (t) == NON_LVALUE_EXPR + || TREE_CODE (t) == PLACEHOLDER_EXPR + || (handled_component_p (t) && ! can_address_p (t))) + { + /* Give the language a chance to do something with this tree + before we go inside it. */ + if ((set = lang_get_alias_set (t)) != -1) + return set; + + if (TREE_CODE (t) == PLACEHOLDER_EXPR) + t = find_placeholder (t, 0); + else + t = TREE_OPERAND (t, 0); + } /* Now give the language a chance to do something but record what we gave it this time. */ @@ -487,15 +503,9 @@ get_alias_set (t) if ((set = lang_get_alias_set (t)) != -1) return set; - /* Now loop the same way as get_inner_reference and get the alias - set to use. Pick up the outermost object that we could have - a pointer to. */ - while (handled_component_p (t) && ! can_address_p (t)) - t = TREE_OPERAND (t, 0); - + /* Check for accesses through restrict-qualified pointers. */ if (TREE_CODE (t) == INDIRECT_REF) { - /* Check for accesses through restrict-qualified pointers. */ tree decl = find_base_decl (TREE_OPERAND (t, 0)); if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl)) @@ -587,6 +597,11 @@ record_alias_subset (superset, subset) alias_set_entry superset_entry; alias_set_entry subset_entry; + /* It is possible in complex type situations for both sets to be the same, + in which case we can ignore this operation. */ + if (superset == subset) + return; + if (superset == 0) abort (); diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index eeb5128fec9..ea0eef2c29b 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1716,13 +1716,11 @@ set_mem_alias_set (mem, set) HOST_WIDE_INT set; { /* It would be nice to enable this check, but we can't quite yet. */ -#if 0 #ifdef ENABLE_CHECKING /* If the new and old alias sets don't conflict, something is wrong. */ if (!alias_sets_conflict_p (set, MEM_ALIAS_SET (mem))) abort (); #endif -#endif MEM_ATTRS (mem) = get_mem_attrs (set, MEM_DECL (mem), MEM_OFFSET (mem), MEM_SIZE (mem), MEM_ALIGN (mem)); diff --git a/gcc/expr.c b/gcc/expr.c index 7d23c7ac824..52f9cc0f2e0 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5955,6 +5955,69 @@ check_max_integer_computation_mode (exp) } #endif +/* Return an object on the placeholder list that matches EXP, a + PLACEHOLDER_EXPR. An object "matches" if it is of the type of the + PLACEHOLDER_EXPR or a pointer type to it. For further information, + see tree.def. If no such object is found, abort. If PLIST is nonzero, + it is a location into which a pointer into the placeholder list at + which the object is found is placed. */ + +tree +find_placeholder (exp, plist) + tree exp; + tree *plist; +{ + tree type = TREE_TYPE (exp); + tree placeholder_expr; + + for (placeholder_expr = placeholder_list; placeholder_expr != 0; + placeholder_expr = TREE_CHAIN (placeholder_expr)) + { + tree need_type = TYPE_MAIN_VARIANT (type); + tree elt; + + /* Find the outermost reference that is of the type we want. If none, + see if any object has a type that is a pointer to the type we + want. */ + for (elt = TREE_PURPOSE (placeholder_expr); elt != 0; + elt = ((TREE_CODE (elt) == COMPOUND_EXPR + || TREE_CODE (elt) == COND_EXPR) + ? TREE_OPERAND (elt, 1) + : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r' + || TREE_CODE_CLASS (TREE_CODE (elt)) == '1' + || TREE_CODE_CLASS (TREE_CODE (elt)) == '2' + || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e') + ? TREE_OPERAND (elt, 0) : 0)) + if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type) + { + if (plist) + *plist = placeholder_expr; + return elt; + } + + for (elt = TREE_PURPOSE (placeholder_expr); elt != 0; + elt + = ((TREE_CODE (elt) == COMPOUND_EXPR + || TREE_CODE (elt) == COND_EXPR) + ? TREE_OPERAND (elt, 1) + : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r' + || TREE_CODE_CLASS (TREE_CODE (elt)) == '1' + || TREE_CODE_CLASS (TREE_CODE (elt)) == '2' + || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e') + ? TREE_OPERAND (elt, 0) : 0)) + if (POINTER_TYPE_P (TREE_TYPE (elt)) + && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt))) + == need_type)) + { + if (plist) + *plist = placeholder_expr; + return build1 (INDIRECT_REF, need_type, elt); + } + } + + abort (); +} + /* expand_expr: generate code for computing expression EXP. An rtx for the computed value is returned. The value is never null. In the case of a void EXP, const0_rtx is returned. @@ -6482,66 +6545,14 @@ expand_expr (exp, target, tmode, modifier) case PLACEHOLDER_EXPR: { + tree old_list = placeholder_list; tree placeholder_expr; - /* If there is an object on the head of the placeholder list, - see if some object in it of type TYPE or a pointer to it. For - further information, see tree.def. */ - for (placeholder_expr = placeholder_list; - placeholder_expr != 0; - placeholder_expr = TREE_CHAIN (placeholder_expr)) - { - tree need_type = TYPE_MAIN_VARIANT (type); - tree object = 0; - tree old_list = placeholder_list; - tree elt; - - /* Find the outermost reference that is of the type we want. - If none, see if any object has a type that is a pointer to - the type we want. */ - for (elt = TREE_PURPOSE (placeholder_expr); - elt != 0 && object == 0; - elt - = ((TREE_CODE (elt) == COMPOUND_EXPR - || TREE_CODE (elt) == COND_EXPR) - ? TREE_OPERAND (elt, 1) - : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r' - || TREE_CODE_CLASS (TREE_CODE (elt)) == '1' - || TREE_CODE_CLASS (TREE_CODE (elt)) == '2' - || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e') - ? TREE_OPERAND (elt, 0) : 0)) - if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type) - object = elt; - - for (elt = TREE_PURPOSE (placeholder_expr); - elt != 0 && object == 0; - elt - = ((TREE_CODE (elt) == COMPOUND_EXPR - || TREE_CODE (elt) == COND_EXPR) - ? TREE_OPERAND (elt, 1) - : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r' - || TREE_CODE_CLASS (TREE_CODE (elt)) == '1' - || TREE_CODE_CLASS (TREE_CODE (elt)) == '2' - || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e') - ? TREE_OPERAND (elt, 0) : 0)) - if (POINTER_TYPE_P (TREE_TYPE (elt)) - && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt))) - == need_type)) - object = build1 (INDIRECT_REF, need_type, elt); - - if (object != 0) - { - /* Expand this object skipping the list entries before - it was found in case it is also a PLACEHOLDER_EXPR. - In that case, we want to translate it using subsequent - entries. */ - placeholder_list = TREE_CHAIN (placeholder_expr); - temp = expand_expr (object, original_target, tmode, - ro_modifier); - placeholder_list = old_list; - return temp; - } - } + exp = find_placeholder (exp, &placeholder_expr); + placeholder_list = TREE_CHAIN (placeholder_expr); + temp = expand_expr (exp, original_target, tmode, ro_modifier); + placeholder_list = old_list; + return temp; } /* We can't find the object or there was a missing WITH_RECORD_EXPR. */ @@ -6923,6 +6934,7 @@ expand_expr (exp, target, tmode, modifier) tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1, &unsignedp, &volatilep, &alignment); + rtx orig_op0; /* If we got back the original object, something is wrong. Perhaps we are evaluating an expression too early. In any event, don't @@ -6934,15 +6946,16 @@ expand_expr (exp, target, tmode, modifier) computation, since it will need a temporary and TARGET is known to have to do. This occurs in unchecked conversion in Ada. */ - op0 = expand_expr (tem, - (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE - && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem))) - != INTEGER_CST) - ? target : NULL_RTX), - VOIDmode, - (modifier == EXPAND_INITIALIZER - || modifier == EXPAND_CONST_ADDRESS) - ? modifier : EXPAND_NORMAL); + orig_op0 = op0 + = expand_expr (tem, + (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE + && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem))) + != INTEGER_CST) + ? target : NULL_RTX), + VOIDmode, + (modifier == EXPAND_INITIALIZER + || modifier == EXPAND_CONST_ADDRESS) + ? modifier : EXPAND_NORMAL); /* If this is a constant, put it into a register if it is a legitimate constant and OFFSET is 0 and memory if it isn't. */ @@ -7031,7 +7044,9 @@ expand_expr (exp, target, tmode, modifier) /* Don't forget about volatility even if this is a bitfield. */ if (GET_CODE (op0) == MEM && volatilep && ! MEM_VOLATILE_P (op0)) { - op0 = copy_rtx (op0); + if (op0 == orig_op0) + op0 = copy_rtx (op0); + MEM_VOLATILE_P (op0) = 1; } @@ -7173,6 +7188,9 @@ expand_expr (exp, target, tmode, modifier) else op0 = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT); + if (op0 == orig_op0) + op0 = copy_rtx (op0); + set_mem_attributes (op0, exp, 0); if (GET_CODE (XEXP (op0, 0)) == REG) mark_reg_pointer (XEXP (op0, 0), alignment); diff --git a/gcc/expr.h b/gcc/expr.h index 9addf7f7326..62e90b0d211 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -498,13 +498,19 @@ extern rtx store_expr PARAMS ((tree, rtx, int)); Useful after calling expand_expr with 1 as sum_ok. */ extern rtx force_operand PARAMS ((rtx, rtx)); -#ifdef TREE_CODE +/* Return an object on the placeholder list that matches EXP, a + PLACEHOLDER_EXPR. An object "matches" if it is of the type of the + PLACEHOLDER_EXPR or a pointer type to it. For further information, + see tree.def. If no such object is found, abort. If PLIST is nonzero, + it is a location into which a pointer into the placeholder list at + which the object is found is placed. */ +extern tree find_placeholder PARAMS ((tree, tree *)); + /* Generate code for computing expression EXP. An rtx for the computed value is returned. The value is never null. In the case of a void EXP, const0_rtx is returned. */ extern rtx expand_expr PARAMS ((tree, rtx, enum machine_mode, enum expand_modifier)); -#endif /* At the start of a function, record that we have no previously-pushed arguments waiting to be popped. */ -- 2.11.0