diff options
author | Richard Kenner <kenner@vlsi1.ultra.nyu.edu> | 2001-11-21 23:32:03 +0000 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 2001-11-21 18:32:03 -0500 |
commit | c11c10d87b229fc9bfa4a1e0a5a342e3344f737d (patch) | |
tree | c9328a6f72e26ab58f5c08b5f144508cc16878e1 | |
parent | 2e7d5318fc0902a682ef1a2b1e43df40f7f3de29 (diff) | |
download | gcc-c11c10d87b229fc9bfa4a1e0a5a342e3344f737d.zip gcc-c11c10d87b229fc9bfa4a1e0a5a342e3344f737d.tar.gz gcc-c11c10d87b229fc9bfa4a1e0a5a342e3344f737d.tar.bz2 |
expr.c (expand_expr, [...]): Refine slightly and also support TREE_ADDRESSABLE.
* expr.c (expand_expr, case VIEW_CONVERT_EXPR): Refine slightly
and also support TREE_ADDRESSABLE.
* tree.def (VIEW_CONVERT_EXPR): Document TREE_ADDRESSABLE.
From-SVN: r47249
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/expr.c | 47 | ||||
-rw-r--r-- | gcc/tree.def | 7 |
3 files changed, 35 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c62584..9b9595f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Wed Nov 21 17:37:16 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> + + * expr.c (expand_expr, case VIEW_CONVERT_EXPR): Refine slightly + and also support TREE_ADDRESSABLE. + * tree.def (VIEW_CONVERT_EXPR): Document TREE_ADDRESSABLE. + 2001-11-21 David Edelsohn <edelsohn@gnu.org> * rs6000.md (cmptf_internal1): Replace %$ with $. @@ -7542,47 +7542,43 @@ expand_expr (exp, target, tmode, modifier) /* If the input and output modes are both the same, we are done. Otherwise, if neither mode is BLKmode and both are within a word, we - can use gen_lowpart. If neither is true, store the operand into - memory and convert the MEM to the new mode. */ + can use gen_lowpart. If neither is true, make sure the operand is + in memory and convert the MEM to the new mode. */ if (TYPE_MODE (type) == GET_MODE (op0)) ; else if (TYPE_MODE (type) != BLKmode && GET_MODE (op0) != BLKmode && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD && GET_MODE_SIZE (GET_MODE (op0)) <= UNITS_PER_WORD) op0 = gen_lowpart (TYPE_MODE (type), op0); - else + else if (GET_CODE (op0) != MEM) { + /* If the operand is not a MEM, force it into memory. Since we + are going to be be changing the mode of the MEM, don't call + force_const_mem for constants because we don't allow pool + constants to change mode. */ tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0)); - enum machine_mode non_blkmode - = GET_MODE (op0) == BLKmode ? TYPE_MODE (type) : GET_MODE (op0); - if (CONSTANT_P (op0)) - op0 = validize_mem (force_const_mem (TYPE_MODE (inner_type), op0)); - else - { - if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type)) - target - = assign_stack_temp_for_type (TYPE_MODE (inner_type), - GET_MODE_SIZE (non_blkmode), - 0, inner_type); + if (TREE_ADDRESSABLE (exp)) + abort (); - if (GET_MODE (target) == BLKmode) - emit_block_move (target, op0, - expr_size (TREE_OPERAND (exp, 0))); - else - emit_move_insn (target, op0); + if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type)) + target + = assign_stack_temp_for_type + (TYPE_MODE (inner_type), + GET_MODE_SIZE (TYPE_MODE (inner_type)), 0, inner_type); - op0 = target; - } + emit_move_insn (target, op0); + op0 = target; } + /* At this point, OP0 is in the correct mode. If the output type is such + that the operand is known to be aligned, indicate that it is. + Otherwise, we need only be concerned about alignment for non-BLKmode + results. */ if (GET_CODE (op0) == MEM) { op0 = copy_rtx (op0); - /* If the output type is such that the operand is known to be - aligned, indicate that it is. Otherwise, we need only be - concerned about alignment for non-BLKmode results. */ if (TYPE_ALIGN_OK (type)) set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type))); else if (TYPE_MODE (type) != BLKmode && STRICT_ALIGNMENT @@ -7595,6 +7591,9 @@ expand_expr (exp, target, tmode, modifier) temp_size, 0, type); rtx new_with_op0_mode = copy_rtx (new); + if (TREE_ADDRESSABLE (exp)) + abort (); + PUT_MODE (new_with_op0_mode, GET_MODE (op0)); if (GET_MODE (op0) == BLKmode) emit_block_move (new_with_op0_mode, op0, diff --git a/gcc/tree.def b/gcc/tree.def index c4f08cf..39ea31c 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -695,7 +695,12 @@ DEFTREECODE (NON_LVALUE_EXPR, "non_lvalue_expr", '1', 1) This corresponds to an "Unchecked Conversion" in Ada and roughly to the idiom *(type2 *)&X in C. The only operand is the value to be viewed as being of another type. It is undefined if the type of the - input and of the expression have different sizes. */ + input and of the expression have different sizes. + + This code may also be used within the LHS of a MODIFY_EXPR, in which + case no actual data motion may occur. TREE_ADDRESSABLE will be set in + this case and GCC must abort if it could not do the operation without + generating insns. */ DEFTREECODE (VIEW_CONVERT_EXPR, "view_convert_expr", '1', 1) /* Represents something we computed once and will use multiple times. |