mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-05 01:34:12 +08:00
tree.def (VIEW_CONVERT_EXPR): New tree code.
* tree.def (VIEW_CONVERT_EXPR): New tree code. * tree.h (handled_component_p): New declaration. * alias.c (handled_component_p): Move function from here ... * expr.c (handled_component_p): ... to here and non longer static. (is_zeros_p, case VIEW_CONVERT_EXPR): New case. (store_field): Remove unneeded MEM_COPY_ATTRIBUTES call. (get_inner_reference): Handle VIEW_CONVERT_EXPR. (expand_expr, case VAR_DECL): Clean up handling of re-layout case. (expand_expr, case VIEW_CONVERT_EXPR): New case. (expand_expr, cse ADDR_EXPR): No need to copy if already BIGGEST_ALIGNMENT. * fold-const.c (fold, case VIEW_CONVERT_EXPR): New case. * varasm.c (initializer_constant_value_p, case VIEW_CONVERT_EXPR): New. (output_constant): Handle VIEW_CONVERT_EXPR. * dwarf2out.c (loc-descriptor_from_tree, add_bound_info): Add new case for VIEW_CONVERT_EXPR. From-SVN: r47179
This commit is contained in:
parent
a5a9cb26e5
commit
ed239f5a43
@ -1,3 +1,22 @@
|
||||
Mon Nov 19 15:13:43 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
* tree.def (VIEW_CONVERT_EXPR): New tree code.
|
||||
* tree.h (handled_component_p): New declaration.
|
||||
* alias.c (handled_component_p): Move function from here ...
|
||||
* expr.c (handled_component_p): ... to here and non longer static.
|
||||
(is_zeros_p, case VIEW_CONVERT_EXPR): New case.
|
||||
(store_field): Remove unneeded MEM_COPY_ATTRIBUTES call.
|
||||
(get_inner_reference): Handle VIEW_CONVERT_EXPR.
|
||||
(expand_expr, case VAR_DECL): Clean up handling of re-layout case.
|
||||
(expand_expr, case VIEW_CONVERT_EXPR): New case.
|
||||
(expand_expr, cse ADDR_EXPR): No need to copy if already
|
||||
BIGGEST_ALIGNMENT.
|
||||
* fold-const.c (fold, case VIEW_CONVERT_EXPR): New case.
|
||||
* varasm.c (initializer_constant_value_p, case VIEW_CONVERT_EXPR): New.
|
||||
(output_constant): Handle VIEW_CONVERT_EXPR.
|
||||
* dwarf2out.c (loc-descriptor_from_tree, add_bound_info):
|
||||
Add new case for VIEW_CONVERT_EXPR.
|
||||
|
||||
2001-11-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* a29k/unix.h (ASM_FILE_START): Const-ify.
|
||||
|
26
gcc/alias.c
26
gcc/alias.c
@ -95,7 +95,6 @@ static void record_set PARAMS ((rtx, rtx, void *));
|
||||
static rtx find_base_term PARAMS ((rtx));
|
||||
static int base_alias_check PARAMS ((rtx, rtx, enum machine_mode,
|
||||
enum machine_mode));
|
||||
static int handled_component_p PARAMS ((tree));
|
||||
static rtx find_base_value PARAMS ((rtx));
|
||||
static int mems_in_disjoint_alias_sets_p PARAMS ((rtx, rtx));
|
||||
static int insert_subset_children PARAMS ((splay_tree_node, void*));
|
||||
@ -399,31 +398,6 @@ find_base_decl (t)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return 1 if T is an expression that get_inner_reference handles. */
|
||||
|
||||
static int
|
||||
handled_component_p (t)
|
||||
tree t;
|
||||
{
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case BIT_FIELD_REF:
|
||||
case COMPONENT_REF:
|
||||
case ARRAY_REF:
|
||||
case ARRAY_RANGE_REF:
|
||||
case NON_LVALUE_EXPR:
|
||||
return 1;
|
||||
|
||||
case NOP_EXPR:
|
||||
case CONVERT_EXPR:
|
||||
return (TYPE_MODE (TREE_TYPE (t))
|
||||
== TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 0))));
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return 1 if all the nested component references handled by
|
||||
get_inner_reference in T are such that we can address the object in T. */
|
||||
|
||||
|
@ -7929,6 +7929,7 @@ loc_descriptor_from_tree (loc, addressp)
|
||||
case NOP_EXPR:
|
||||
case CONVERT_EXPR:
|
||||
case NON_LVALUE_EXPR:
|
||||
case VIEW_CONVERT_EXPR:
|
||||
case SAVE_EXPR:
|
||||
return loc_descriptor_from_tree (TREE_OPERAND (loc, 0), addressp);
|
||||
|
||||
@ -8849,6 +8850,7 @@ add_bound_info (subrange_die, bound_attr, bound)
|
||||
case CONVERT_EXPR:
|
||||
case NOP_EXPR:
|
||||
case NON_LVALUE_EXPR:
|
||||
case VIEW_CONVERT_EXPR:
|
||||
add_bound_info (subrange_die, bound_attr, TREE_OPERAND (bound, 0));
|
||||
break;
|
||||
|
||||
|
119
gcc/expr.c
119
gcc/expr.c
@ -4360,6 +4360,7 @@ is_zeros_p (exp)
|
||||
case CONVERT_EXPR:
|
||||
case NOP_EXPR:
|
||||
case NON_LVALUE_EXPR:
|
||||
case VIEW_CONVERT_EXPR:
|
||||
return is_zeros_p (TREE_OPERAND (exp, 0));
|
||||
|
||||
case INTEGER_CST:
|
||||
@ -5151,7 +5152,6 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, unsignedp, type,
|
||||
rtx blk_object = copy_rtx (object);
|
||||
|
||||
PUT_MODE (blk_object, BLKmode);
|
||||
MEM_COPY_ATTRIBUTES (blk_object, object);
|
||||
|
||||
if (bitsize != (HOST_WIDE_INT) GET_MODE_BITSIZE (GET_MODE (target)))
|
||||
emit_move_insn (object, target);
|
||||
@ -5451,6 +5451,7 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
|
||||
continue;
|
||||
}
|
||||
else if (TREE_CODE (exp) != NON_LVALUE_EXPR
|
||||
&& TREE_CODE (exp) != VIEW_CONVERT_EXPR
|
||||
&& ! ((TREE_CODE (exp) == NOP_EXPR
|
||||
|| TREE_CODE (exp) == CONVERT_EXPR)
|
||||
&& (TYPE_MODE (TREE_TYPE (exp))
|
||||
@ -5479,6 +5480,32 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
|
||||
return exp;
|
||||
}
|
||||
|
||||
/* Return 1 if T is an expression that get_inner_reference handles. */
|
||||
|
||||
int
|
||||
handled_component_p (t)
|
||||
tree t;
|
||||
{
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case BIT_FIELD_REF:
|
||||
case COMPONENT_REF:
|
||||
case ARRAY_REF:
|
||||
case ARRAY_RANGE_REF:
|
||||
case NON_LVALUE_EXPR:
|
||||
case VIEW_CONVERT_EXPR:
|
||||
return 1;
|
||||
|
||||
case NOP_EXPR:
|
||||
case CONVERT_EXPR:
|
||||
return (TYPE_MODE (TREE_TYPE (t))
|
||||
== TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 0))));
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Subroutine of expand_exp: compute memory_usage from modifier. */
|
||||
|
||||
static enum memory_use_mode
|
||||
@ -6287,9 +6314,19 @@ expand_expr (exp, target, tmode, modifier)
|
||||
if (DECL_SIZE (exp) == 0 && COMPLETE_TYPE_P (TREE_TYPE (exp))
|
||||
&& (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
|
||||
{
|
||||
rtx value = DECL_RTL_IF_SET (exp);
|
||||
|
||||
layout_decl (exp, 0);
|
||||
PUT_MODE (DECL_RTL (exp), DECL_MODE (exp));
|
||||
set_mem_align (DECL_RTL (exp), DECL_ALIGN (exp));
|
||||
|
||||
/* If the RTL was already set, update its mode and memory
|
||||
attributes. */
|
||||
if (value != 0)
|
||||
{
|
||||
PUT_MODE (value, DECL_MODE (exp));
|
||||
SET_DECL_RTL (exp, 0);
|
||||
set_mem_attributes (value, exp, 1);
|
||||
SET_DECL_RTL (exp, value);
|
||||
}
|
||||
}
|
||||
|
||||
/* Although static-storage variables start off initialized, according to
|
||||
@ -7500,6 +7537,79 @@ expand_expr (exp, target, tmode, modifier)
|
||||
TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
|
||||
return target;
|
||||
|
||||
case VIEW_CONVERT_EXPR:
|
||||
op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, 0);
|
||||
|
||||
/* 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. */
|
||||
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
|
||||
{
|
||||
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 (GET_MODE (target) == BLKmode)
|
||||
emit_block_move (target, op0,
|
||||
expr_size (TREE_OPERAND (exp, 0)));
|
||||
else
|
||||
emit_move_insn (target, op0);
|
||||
|
||||
op0 = target;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
&& MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
|
||||
{
|
||||
tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
|
||||
HOST_WIDE_INT temp_size = MAX (int_size_in_bytes (inner_type),
|
||||
GET_MODE_SIZE (TYPE_MODE (type)));
|
||||
rtx new = assign_stack_temp_for_type (TYPE_MODE (type),
|
||||
temp_size, 0, type);
|
||||
rtx new_with_op0_mode = copy_rtx (new);
|
||||
|
||||
PUT_MODE (new_with_op0_mode, GET_MODE (op0));
|
||||
if (GET_MODE (op0) == BLKmode)
|
||||
emit_block_move (new_with_op0_mode, op0,
|
||||
GEN_INT (GET_MODE_SIZE (TYPE_MODE (type))));
|
||||
else
|
||||
emit_move_insn (new_with_op0_mode, op0);
|
||||
|
||||
op0 = new;
|
||||
}
|
||||
|
||||
PUT_MODE (op0, TYPE_MODE (type));
|
||||
}
|
||||
|
||||
return op0;
|
||||
|
||||
case PLUS_EXPR:
|
||||
/* We come here from MINUS_EXPR when the second operand is a
|
||||
constant. */
|
||||
@ -8668,7 +8778,8 @@ expand_expr (exp, target, tmode, modifier)
|
||||
strict alignment. */
|
||||
if (STRICT_ALIGNMENT && GET_MODE (op0) == BLKmode
|
||||
&& (TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0)))
|
||||
> MEM_ALIGN (op0)))
|
||||
> MEM_ALIGN (op0))
|
||||
&& MEM_ALIGN (op0) < BIGGEST_ALIGNMENT)
|
||||
{
|
||||
tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
|
||||
rtx new
|
||||
|
@ -5308,6 +5308,12 @@ fold (expr)
|
||||
}
|
||||
return fold_convert (t, arg0);
|
||||
|
||||
case VIEW_CONVERT_EXPR:
|
||||
if (TREE_CODE (TREE_OPERAND (t, 0)) == VIEW_CONVERT_EXPR)
|
||||
return build1 (VIEW_CONVERT_EXPR, type,
|
||||
TREE_OPERAND (TREE_OPERAND (t, 0), 0));
|
||||
return t;
|
||||
|
||||
#if 0 /* This loses on &"foo"[0]. */
|
||||
case ARRAY_REF:
|
||||
{
|
||||
|
@ -691,6 +691,13 @@ DEFTREECODE (NOP_EXPR, "nop_expr", '1', 1)
|
||||
/* Value is same as argument, but guaranteed not an lvalue. */
|
||||
DEFTREECODE (NON_LVALUE_EXPR, "non_lvalue_expr", '1', 1)
|
||||
|
||||
/* Represents viewing something of one type as being of a second type.
|
||||
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. */
|
||||
DEFTREECODE (VIEW_CONVERT_EXPR, "view_convert_expr", '1', 1)
|
||||
|
||||
/* Represents something we computed once and will use multiple times.
|
||||
First operand is that expression. Second is the function decl
|
||||
in which the SAVE_EXPR was created. The third operand is the RTL,
|
||||
|
@ -2587,6 +2587,10 @@ extern tree get_inner_reference PARAMS ((tree, HOST_WIDE_INT *,
|
||||
enum machine_mode *, int *,
|
||||
int *));
|
||||
|
||||
/* Return 1 if T is an expression that get_inner_reference handles. */
|
||||
|
||||
extern int handled_component_p PARAMS ((tree));
|
||||
|
||||
/* Given a DECL or TYPE, return the scope in which it was declared, or
|
||||
NUL_TREE if there is no containing scope. */
|
||||
|
||||
|
14
gcc/varasm.c
14
gcc/varasm.c
@ -4288,6 +4288,7 @@ initializer_constant_valid_p (value, endtype)
|
||||
case FDESC_EXPR:
|
||||
return staticp (TREE_OPERAND (value, 0)) ? TREE_OPERAND (value, 0) : 0;
|
||||
|
||||
case VIEW_CONVERT_EXPR:
|
||||
case NON_LVALUE_EXPR:
|
||||
return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
|
||||
|
||||
@ -4442,10 +4443,9 @@ output_constant (exp, size, align)
|
||||
{
|
||||
enum tree_code code = TREE_CODE (TREE_TYPE (exp));
|
||||
|
||||
/* Some front-ends use constants other than the standard
|
||||
language-indepdent varieties, but which may still be output
|
||||
directly. Give the front-end a chance to convert EXP to a
|
||||
language-independent representation. */
|
||||
/* Some front-ends use constants other than the standard language-indepdent
|
||||
varieties, but which may still be output directly. Give the front-end a
|
||||
chance to convert EXP to a language-independent representation. */
|
||||
if (lang_expand_constant)
|
||||
{
|
||||
exp = (*lang_expand_constant) (exp);
|
||||
@ -4462,9 +4462,9 @@ output_constant (exp, size, align)
|
||||
while ((TREE_CODE (exp) == NOP_EXPR
|
||||
&& (TREE_TYPE (exp) == TREE_TYPE (TREE_OPERAND (exp, 0))
|
||||
|| AGGREGATE_TYPE_P (TREE_TYPE (exp))))
|
||||
|| (TREE_CODE (exp) == CONVERT_EXPR
|
||||
&& code == UNION_TYPE)
|
||||
|| TREE_CODE (exp) == NON_LVALUE_EXPR)
|
||||
|| (TREE_CODE (exp) == CONVERT_EXPR && code == UNION_TYPE)
|
||||
|| TREE_CODE (exp) == NON_LVALUE_EXPR
|
||||
|| TREE_CODE (exp) == VIEW_CONVERT_EXPR)
|
||||
{
|
||||
exp = TREE_OPERAND (exp, 0);
|
||||
code = TREE_CODE (TREE_TYPE (exp));
|
||||
|
Loading…
Reference in New Issue
Block a user