alias.c (adjust_offset_for_component_ref): Use component_ref_field_offset.

* alias.c (adjust_offset_for_component_ref): Use
	component_ref_field_offset.
	* c-decl.c (build_array_declarator): Add news args for ARRAY_REF.
	* c-gimplify.c (gimplify_expr_stmt): Use alloc_stmt_list.
	(gimplify_decl_stmt): Call gimplify_type_sizes for type.
	For decl, call gimplify_one_sizepos and use statement list.
	(gimplify_compound_literal_expr): New arg PRE_P.
	Add statement to PRE_P list and return DECL.
	(c_gimplify_expr, case COMPOUND_LITERAL_EXPR): Add arg to
	gimplify_compound_literal_expr.
	* c-tree.h (getdecls): Deleted.
	* c-typeck.c (build_component_ref): Add operand for COMPONENT_REF.
	(build_array_ref): Add two operands for ARRAY_REF.
	(build_unary_op): Set TREE_INVARIANT and TREE_CONSTANT for
	COMPOUND_LITERAL_EXPR.
	* coverage.c (tree_coverage_counter_ref): Add new operands
	for ARRAY_REF.
	* emit-rtl.c (component_ref_for_mem_expr): Add new operand
	for COMPONENT_REF.
	(set_mem_attributes_minus_bitpos): Use array_ref_low_bound
	and array_ref_element_size.
	(widen_memory_access):Use component_ref_field_offset.
	* explow.c (update_nonlocal_goto_save_area): Add two operands
	for ARRAY_REF.
	* expr.c (array_ref_element_size, array_ref_low_bound): New functions.
	(component_ref_field_offset): Likewise.
	(get_inner_reference): Use them.
	(expand_expr_real_1, case ARRAY_REF): Use array_ref_low_bound.
	* fold-const.c (fold, case EQ_EXPR): Properly handle DECL_SIZE.
	(fold_read_from_constant_string): Use array_ref_low_bound.
	Verify that result is a character type.
	(build_fold_indirect_ref): Add two operands for ARRAY_REF.
	* function.c (expand_function_start): Likewise.
	* gimple-low.c (expand_var_p): Delete duplicated line.
	* gimplify.c: Add static decls for local functions.
	(cgraph.h): Now included.
	(create_tmp_var): Remove check for ARRAY_TYPE.
	(copy_if_shared_r): Look at bounds and sizes of types.
	(build_and_jump): Return alloc_stmt_list instead of build_empty_stmt.
	(gimplify_exit_expr, shortcut_cond_expr): Likewise.
	(gimplify_save_expr, gimple_push_cleanup): Likewise.
	(gimplify_init_constructor): Likewise.
	WANT_VALUE now bool.
	If empty list with no result wanted, return GS_UNHANDLED.
	Add additional operands for ARRAY_REF and COMPONENT_REF.
	(canonicalize_component_ref): Convert to &array[L].
	(gimplify_array_ref_to_plus): Use array_ref_element_size and
	array_ref_lower_bound.
	(build_addr_expr_with_type, build_addr_expr): New functions.
	(gimplify_compound_lval): WANT_LVALUE now bool.
	Major rework to allow handle_component_p and initialize and
	gimplify new operands for ARRAY_REF, ARRAY_RANGE_REF, and
	COMPONENT_REF.
	(gimplify_array_ref): Deleted.
	(gimplify_self_mod_expr): WANT_VALUE now bool.
	(gimplify_modify_expr): Gimplify to_p and from_p later.
	Factor out code into gimplify_modify_expr_rhs and call twice.
	Move variable-size code earlier and handle PLACEHOLDER_EXPR.
	(gimplify_modify_expr_rhs, gimplify_variable_sized_compare): New fns.
	(gimplify_addr_expr, case VIEW_CONVERT_EXPR): New case.
	(gimplify_expr, case ARRAY_REF): Delete special case.
	Instead handle like COMPONENT_REF; also do ARRAY_RANGE_REF,
	IMAGPART, and REALPART the same way.
	(gimplify_expr, case VIEW_CONVERT_EXPR): New case.
	(gimplify_expr): Call gimplify_variable_sized_compare if applicable.
	Call alloc_stmt_list instead of build_empty_stmt.
	Deal with _REF that's volatile.
	(gimplify_type_sizes, gimplify_one_sizepos): New functions.
	(unshare_body, unvisit_body): New functions.
	(gimplify_body): Call them.
	* stmt.c (expand_stack_alloc): Don't expand TYPE_MAX_VALUE.
	* stor-layout.c (get_pending_sizes): Don't change SAVE_EXPR_CONTEXT.
	* tree-alias-common.c (get_alias_var): Also skip ARRAY_RANGE_REF.
	* tree-cfg.c (tree_node_can_be_shared): Treat ARRAY_RANGE_REF
	like ARRAY_REF.
	(verify_expr, case ADDR_EXPR): Use handled_component_p.
	* tree-dfa.c (get_virtual_var): Likewise.
	* tree-dump.c (dequeue_and_dump, case COMPONENT_REF, ARRAY_REF):
	New cases to dump new operands; likewise for ARRAY_RANGE_REF.
	* tree-eh.c (tree_could_trap, case ARRAY_RANGE_REF): Like ARRAY_REF.
	* tree-gimple.c (is_gimple_addr_expr_arg): Add ARRAY_RANGE_REF
	and INDIRECT_REF.
	(get_base_address): Use handled_component_p.
	* tree-gimple.h (gimplify_type_sizes, gimplify_one_sizepos): New.
	* tree-line.c (walk_tree): Walk more things for types and decls.
	* tree-mudflap.c (mf_build_check_statement_for): Add new operands
	for ARRAY_REF and COMPONENT_REF.
	(mx_xform_derefs_1): Clean up usage of decl sizes.
	* tree-nested.c (build_addr): Use handled_component_p.
	(walk_stmts, case CATCH_EXPR): Add missing "break".
	(get_static_chain, get_frame_field): Add new operand for COMPONENT_REF.
	(finalize_nesting_tree_1): Likewise.
	(convert_nonlocal_reference, case ARRAY_RANGE_REF): Like ARRAY_REF
	and process additional operands.
	(convert_local_reference): Likewise.
	* tree-outof-ssa.c (discover_nonconstant_array_refs_r): Treat
	ARRAY_RANGE_REF similarly to ARRAY_REF.
	* tree-pretty-print.c (dump_generic_node, case QUAL_UNION_TYPE): Handle
	like RECORD_TYPE.
	(dump_generic_node, case COMPONENT_REF): Print offset operand.
	(dump_generic_node, case ARRAY_RANGE_REF): Treat like ARRAY_REF
	and print lower bound and element size for both.
	(op_prio, case ARRAY_RANGE_REF): Like ARRAY_REF.
	* tree-sra.c (csc_build_component_ref): Add new operand.
	(scalarize_call_expr): Use get_base_address.
	* tree-ssa-ccp.c (widen_bitfield): Clean up size handling.
	(maybe_fold_offset_to_array_ref): Rework to handle input having an
	ARRAY_REF, refine handling of lower bound, and add new operands
	for ARRAY_REF.
	(maybe_fold_to_component_ref): Add new operand for COMPONENT_REF.
	(maybe_fold_stmt_indirect): Only fold *&B to B if types match.
	(maybe_fold_stmt_addition): Only handle constant lower bound.
	* tree-ssa-operands.c (get_expr_operands): Minor rearrangements.
	Treat ARRAY_REF and ARRAY_RANGE_REF the same; look at extra operands.
	Look at new offset operand of COMPONENT_REF.
	* tree-ssa.c (set_is_used): Use handled_component_p.
	* tree.c (substitute_in_expr, case COMPONENT_REF): Add new operand.
	(stabilize_reference, case COMPONENT_REF): Likewise.
	(stabilize_reference, case ARRAY_RANGE_REF, ARRAY_REF): Similarly.
	(recompute_tree_invariant_for_addr_expr): Completely rework to
	be more precise.  Also set TREE_SIDE_EFFECTS.
	(build1_stat, case ARRAY_EXPR): Don't handle TREE_SIDE_EFFECTS here.
	(build2_stat, build3_stat, build4_stat): For references,
	propagate TREE_THIS_VOLATILE.
	(get_unwidened): Add new operand for COMPONENT_REF.
	(get_narrower): Likewise; use host_integerp for DECL_SIZE.
	* tree.def (COMPONENT_REF): Add new operand.
	(ARRAY_REF, ARRAY_RANGE_REF): Add two new operands.
	* tree.h (array_ref_element_size, array_ref_low_bound): New decls.
	(component_ref_field_offset): Likewise.
	* config/alpha/alpha.c (alpha_va_start): Add new op for COMPONENT_REF.
	(alpha_gimplify_va_arg): Likewise.
	* config/i386/i386.c (ix86_va_start, ix86_gimplify_va_arg): Likewise.
	* config/i860/i860.c (i860_va_start, i860_va_arg): Likewise.
	* config/iq2000/iq2000.c (iq2000_va_arg): Likewise.
	* config/mips/mips.c (mips_va_start, mips_va_arg): Likewise.
	* config/rs6000/rs6000.c (rs6000_va_start, rs6000_gimplify_va_arg):
	Likewise.
	* config/s390/s390.c (s390_va_start, s390_gimplify_va_arg): Likewise.
	* config/sh/sh.c (sh_va_start, sh_va_arg): Likewise.
	* config/stormy16/stormy16.c (xstormy1_expand_builin_va_start):
	Likewise.
	(xstormy16_expand_builtin_va_arg): Likewise.
	* config/xtensa/xtensa.c (xtensa_va_start, xtensa_va_arg): Likewise.

	* cp/call.c (build_vfield_ref): Add new operand for COMPONENT_REF.
	(build_new_method_call): Likewise.
	* cp/decl.c (local_variable_p_walkfn): Don't walk into types.
	* cp/decl2.c (grok_array_decl): Add new operands for ARRAY_REF.
	(build_anon_union_vars): Add new operand for COMPONENT_REF.
	* cp/init.c (buld_new): Add new operand for ARRAY_REF.
	* cp/method.c (do_build_copy_constructor): New op for COMPONENT_REF.
	(do_build_assign_ref): Likewise.
	* cp/parser.c (cp_parser_direct_new_declarator): Add new operands
	for ARRAY_REF.
	(cp_parser_direct_declarator): Likewise.
	* cp/pt.c (tsubst): Likewise.
	(tsubst_copy, tsubst_copy_and_build): Likewise; also add new operand
 	for COMPONENT_REF.
	* cp/semantics.c (finish_non_static_data_member): Add new operand
	for COMPONENT_REF.
	* cp/typeck.c (build_class_member_access_expr): Likewise.
	(build_class_member_access_expr, finish_class_member_access_expr):
	Likewise.
	(build_ptrmemfunc_access_expr): Likewise.
	(build_array_ref): Add new operands for ARRAY_REF.
	* cp/typeck2.c (split_nonconstant_init_1): Likewise; COMPONENT_REF too.
	* cp/tree.c (count_trees_r, no_linkage_helper): Don't walk in types.

	* fortran/f95-lang.c (LANG_HOOKS_GIMPLE_BEFORE_INLINING): Deleted.
	* fortran/trans-array.c (gfc_conv_descriptor_data): Add operand
	for COMPONENT_REF.
	(gfc_conv_descriptor_offset, gfc_conv_descriptor_dtype): Likewise.
	(gfc_conv_descriptor_dimension, gfc_conv_descriptor_stride): Likewise.
	(gfc_conv_descriptor_lbound, gfc_conv_descriptor_ubound): Likewise.
	* fortran/trans-common.c (create_common): Likewise.
	* fortran/trans-expr.c (gfc_conv_component_ref): Likewise.
	* fortran/trans-io.c (set_parameter_value): Likewise.
	(set_parameter_ref, set_string, set_flag, io_result): Likewise.
	(transfer_expr): Likewise.
	* fortran/trans-decl.c (gfc_trans_auto_character_variable):
	Set up to get DECL_SIZE and DECL_SIZE_UNIT gimplified.
	(gfc_simplify_function): New function.
	(gfc_generate_function-code): Properly handle nested functions.
	* fortran/trans.c (gfc_build_array_ref): Add two new operands
	for ARRAY_REF.

	* java/class.c (build_class_ref): Add new operand for COMPONENT_REF.
	(build_static_field_ref): Likewise and add new operands for ARRAY_REF.
	* java/constants.c (build_ref_from_constant_pool): Likewise.
	* java/expr.c (build_java_array_length_access): Likewise.
	(build_get_class, build_field_ref, build_known_method_ref): Likewise.
	(invoke_build_dtable, build_invokevirtual): Likewise.
	(build_invokeinterface, java_expand_expr): Likewise.
	(emit_init_test_initialization): Likewise.
	* java/java-gimplify.c (java_gimplify_new_array_init): Likewise.
	* java/parse.y (make_qualifed_name, build_array_ref): Likewise.

	* objc/ojbc-act.c (generate_static_references): Add additional
	operands to ARRAY_REF.
	(generate_strings, build_method_prototype_list_template): Likewise.
	(generate_protocol_list): Likewise.

From-SVN: r83474
This commit is contained in:
Richard Kenner 2004-06-22 03:07:05 +00:00 committed by Richard Kenner
parent 6264b0a68d
commit 44de5aeb00
72 changed files with 1653 additions and 785 deletions

View file

@ -1,3 +1,153 @@
2004-06-21 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* alias.c (adjust_offset_for_component_ref): Use
component_ref_field_offset.
* c-decl.c (build_array_declarator): Add news args for ARRAY_REF.
* c-gimplify.c (gimplify_expr_stmt): Use alloc_stmt_list.
(gimplify_decl_stmt): Call gimplify_type_sizes for type.
For decl, call gimplify_one_sizepos and use statement list.
(gimplify_compound_literal_expr): New arg PRE_P.
Add statement to PRE_P list and return DECL.
(c_gimplify_expr, case COMPOUND_LITERAL_EXPR): Add arg to
gimplify_compound_literal_expr.
* c-tree.h (getdecls): Deleted.
* c-typeck.c (build_component_ref): Add operand for COMPONENT_REF.
(build_array_ref): Add two operands for ARRAY_REF.
(build_unary_op): Set TREE_INVARIANT and TREE_CONSTANT for
COMPOUND_LITERAL_EXPR.
* coverage.c (tree_coverage_counter_ref): Add new operands
for ARRAY_REF.
* emit-rtl.c (component_ref_for_mem_expr): Add new operand
for COMPONENT_REF.
(set_mem_attributes_minus_bitpos): Use array_ref_low_bound
and array_ref_element_size.
(widen_memory_access):Use component_ref_field_offset.
* explow.c (update_nonlocal_goto_save_area): Add two operands
for ARRAY_REF.
* expr.c (array_ref_element_size, array_ref_low_bound): New functions.
(component_ref_field_offset): Likewise.
(get_inner_reference): Use them.
(expand_expr_real_1, case ARRAY_REF): Use array_ref_low_bound.
* fold-const.c (fold, case EQ_EXPR): Properly handle DECL_SIZE.
(fold_read_from_constant_string): Use array_ref_low_bound.
Verify that result is a character type.
(build_fold_indirect_ref): Add two operands for ARRAY_REF.
* function.c (expand_function_start): Likewise.
* gimple-low.c (expand_var_p): Delete duplicated line.
* gimplify.c: Add static decls for local functions.
(cgraph.h): Now included.
(create_tmp_var): Remove check for ARRAY_TYPE.
(copy_if_shared_r): Look at bounds and sizes of types.
(build_and_jump): Return alloc_stmt_list instead of build_empty_stmt.
(gimplify_exit_expr, shortcut_cond_expr): Likewise.
(gimplify_save_expr, gimple_push_cleanup): Likewise.
(gimplify_init_constructor): Likewise.
WANT_VALUE now bool.
If empty list with no result wanted, return GS_UNHANDLED.
Add additional operands for ARRAY_REF and COMPONENT_REF.
(canonicalize_component_ref): Convert to &array[L].
(gimplify_array_ref_to_plus): Use array_ref_element_size and
array_ref_lower_bound.
(build_addr_expr_with_type, build_addr_expr): New functions.
(gimplify_compound_lval): WANT_LVALUE now bool.
Major rework to allow handle_component_p and initialize and
gimplify new operands for ARRAY_REF, ARRAY_RANGE_REF, and
COMPONENT_REF.
(gimplify_array_ref): Deleted.
(gimplify_self_mod_expr): WANT_VALUE now bool.
(gimplify_modify_expr): Gimplify to_p and from_p later.
Factor out code into gimplify_modify_expr_rhs and call twice.
Move variable-size code earlier and handle PLACEHOLDER_EXPR.
(gimplify_modify_expr_rhs, gimplify_variable_sized_compare): New fns.
(gimplify_addr_expr, case VIEW_CONVERT_EXPR): New case.
(gimplify_expr, case ARRAY_REF): Delete special case.
Instead handle like COMPONENT_REF; also do ARRAY_RANGE_REF,
IMAGPART, and REALPART the same way.
(gimplify_expr, case VIEW_CONVERT_EXPR): New case.
(gimplify_expr): Call gimplify_variable_sized_compare if applicable.
Call alloc_stmt_list instead of build_empty_stmt.
Deal with _REF that's volatile.
(gimplify_type_sizes, gimplify_one_sizepos): New functions.
(unshare_body, unvisit_body): New functions.
(gimplify_body): Call them.
* stmt.c (expand_stack_alloc): Don't expand TYPE_MAX_VALUE.
* stor-layout.c (get_pending_sizes): Don't change SAVE_EXPR_CONTEXT.
* tree-alias-common.c (get_alias_var): Also skip ARRAY_RANGE_REF.
* tree-cfg.c (tree_node_can_be_shared): Treat ARRAY_RANGE_REF
like ARRAY_REF.
(verify_expr, case ADDR_EXPR): Use handled_component_p.
* tree-dfa.c (get_virtual_var): Likewise.
* tree-dump.c (dequeue_and_dump, case COMPONENT_REF, ARRAY_REF):
New cases to dump new operands; likewise for ARRAY_RANGE_REF.
* tree-eh.c (tree_could_trap, case ARRAY_RANGE_REF): Like ARRAY_REF.
* tree-gimple.c (is_gimple_addr_expr_arg): Add ARRAY_RANGE_REF
and INDIRECT_REF.
(get_base_address): Use handled_component_p.
* tree-gimple.h (gimplify_type_sizes, gimplify_one_sizepos): New.
* tree-inline.c (walk_tree): Walk more things for types and decls.
* tree-mudflap.c (mf_build_check_statement_for): Add new operands
for ARRAY_REF and COMPONENT_REF.
(mx_xform_derefs_1): Clean up usage of decl sizes.
* tree-nested.c (build_addr): Use handled_component_p.
(walk_stmts, case CATCH_EXPR): Add missing "break".
(get_static_chain, get_frame_field): Add new operand for COMPONENT_REF.
(finalize_nesting_tree_1): Likewise.
(convert_nonlocal_reference, case ARRAY_RANGE_REF): Like ARRAY_REF
and process additional operands.
(convert_local_reference): Likewise.
* tree-outof-ssa.c (discover_nonconstant_array_refs_r): Treat
ARRAY_RANGE_REF similarly to ARRAY_REF.
* tree-pretty-print.c (dump_generic_node, case QUAL_UNION_TYPE): Handle
like RECORD_TYPE.
(dump_generic_node, case COMPONENT_REF): Print offset operand.
(dump_generic_node, case ARRAY_RANGE_REF): Treat like ARRAY_REF
and print lower bound and element size for both.
(op_prio, case ARRAY_RANGE_REF): Like ARRAY_REF.
* tree-sra.c (csc_build_component_ref): Add new operand.
(scalarize_call_expr): Use get_base_address.
* tree-ssa-ccp.c (widen_bitfield): Clean up size handling.
(maybe_fold_offset_to_array_ref): Rework to handle input having an
ARRAY_REF, refine handling of lower bound, and add new operands
for ARRAY_REF.
(maybe_fold_to_component_ref): Add new operand for COMPONENT_REF.
(maybe_fold_stmt_indirect): Only fold *&B to B if types match.
(maybe_fold_stmt_addition): Only handle constant lower bound.
* tree-ssa-operands.c (get_expr_operands): Minor rearrangements.
Treat ARRAY_REF and ARRAY_RANGE_REF the same; look at extra operands.
Look at new offset operand of COMPONENT_REF.
* tree-ssa.c (set_is_used): Use handled_component_p.
* tree.c (substitute_in_expr, case COMPONENT_REF): Add new operand.
(stabilize_reference, case COMPONENT_REF): Likewise.
(stabilize_reference, case ARRAY_RANGE_REF, ARRAY_REF): Similarly.
(recompute_tree_invariant_for_addr_expr): Completely rework to
be more precise. Also set TREE_SIDE_EFFECTS.
(build1_stat, case ARRAY_EXPR): Don't handle TREE_SIDE_EFFECTS here.
(build2_stat, build3_stat, build4_stat): For references,
propagate TREE_THIS_VOLATILE.
(get_unwidened): Add new operand for COMPONENT_REF.
(get_narrower): Likewise; use host_integerp for DECL_SIZE.
* tree.def (COMPONENT_REF): Add new operand.
(ARRAY_REF, ARRAY_RANGE_REF): Add two new operands.
* tree.h (array_ref_element_size, array_ref_low_bound): New decls.
(component_ref_field_offset): Likewise.
* config/alpha/alpha.c (alpha_va_start): Add new op for COMPONENT_REF.
(alpha_gimplify_va_arg): Likewise.
* config/i386/i386.c (ix86_va_start, ix86_gimplify_va_arg): Likewise.
* config/i860/i860.c (i860_va_start, i860_va_arg): Likewise.
* config/iq2000/iq2000.c (iq2000_va_arg): Likewise.
* config/mips/mips.c (mips_va_start, mips_va_arg): Likewise.
* config/rs6000/rs6000.c (rs6000_va_start, rs6000_gimplify_va_arg):
Likewise.
* config/s390/s390.c (s390_va_start, s390_gimplify_va_arg): Likewise.
* config/sh/sh.c (sh_va_start, sh_va_arg): Likewise.
* config/stormy16/stormy16.c (xstormy1_expand_builin_va_start):
Likewise.
(xstormy16_expand_builtin_va_arg): Likewise.
* config/xtensa/xtensa.c (xtensa_va_start, xtensa_va_arg): Likewise.
* objc/objc-act.c (generate_static_references): Likewise.
(generate_strings, build_method_prototype_list_template): Likewise.
(generate_protocol_list): Likewise.
2004-06-21 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR rtl-optimization/14782

View file

@ -2015,11 +2015,12 @@ adjust_offset_for_component_ref (tree x, rtx offset)
ioffset = INTVAL (offset);
do
{
tree offset = component_ref_field_offset (x);
tree field = TREE_OPERAND (x, 1);
if (! host_integerp (DECL_FIELD_OFFSET (field), 1))
if (! host_integerp (offset, 1))
return NULL_RTX;
ioffset += (tree_low_cst (DECL_FIELD_OFFSET (field), 1)
ioffset += (tree_low_cst (offset, 1)
+ (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
/ BITS_PER_UNIT));

View file

@ -2508,7 +2508,7 @@ tree
build_array_declarator (tree expr, tree quals, int static_p, int vla_unspec_p)
{
tree decl;
decl = build_nt (ARRAY_REF, NULL_TREE, expr);
decl = build_nt (ARRAY_REF, NULL_TREE, expr, NULL_TREE, NULL_TREE);
TREE_TYPE (decl) = quals;
TREE_STATIC (decl) = (static_p ? 1 : 0);
if (pedantic && !flag_isoc99)

View file

@ -243,7 +243,7 @@ gimplify_expr_stmt (tree *stmt_p)
}
if (stmt == NULL_TREE)
stmt = build_empty_stmt ();
stmt = alloc_stmt_list ();
*stmt_p = stmt;
@ -475,8 +475,6 @@ gimplify_decl_stmt (tree *stmt_p)
{
tree stmt = *stmt_p;
tree decl = DECL_STMT_DECL (stmt);
tree pre = NULL_TREE;
tree post = NULL_TREE;
if (TREE_TYPE (decl) == error_mark_node)
{
@ -485,38 +483,34 @@ gimplify_decl_stmt (tree *stmt_p)
}
if (TREE_CODE (decl) == TYPE_DECL)
{
tree type = TREE_TYPE (decl);
if (TYPE_SIZE_UNIT (type)
&& !TREE_CONSTANT (TYPE_SIZE_UNIT (type)))
{
/* This is a variable-sized array type. Simplify its size. */
tree temp = TYPE_SIZE_UNIT (type);
gimplify_expr (&temp, &pre, &post, is_gimple_val, fb_rvalue);
}
}
*stmt_p = gimplify_type_sizes (TREE_TYPE (decl));
if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
{
tree init = DECL_INITIAL (decl);
*stmt_p = NULL_TREE;
gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
if (!TREE_CONSTANT (DECL_SIZE (decl)))
{
tree pt_type = build_pointer_type (TREE_TYPE (decl));
tree alloc, size;
/* This is a variable-sized decl. Simplify its size and mark it
for deferred expansion. Note that mudflap depends on the format
of the emitted code: see mx_register_decls(). */
size = get_initialized_tmp_var (DECL_SIZE_UNIT (decl), &pre, &post);
tree pt_type = build_pointer_type (TREE_TYPE (decl));
tree alloc_stmt
= (build_function_call_expr
(implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
tree_cons (NULL_TREE,
build1 (ADDR_EXPR, pt_type, decl),
tree_cons (NULL_TREE, DECL_SIZE_UNIT (decl),
NULL_TREE))));
gimplify_stmt (&alloc_stmt);
append_to_statement_list(alloc_stmt, stmt_p);
DECL_DEFER_OUTPUT (decl) = 1;
alloc = build_function_call_expr
(implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
tree_cons (NULL_TREE,
build1 (ADDR_EXPR, pt_type, decl),
tree_cons (NULL_TREE, size, NULL_TREE)));
append_to_compound_expr (alloc, &pre);
}
if (init && init != error_mark_node)
@ -531,14 +525,13 @@ gimplify_decl_stmt (tree *stmt_p)
DECL_INITIAL (decl) = NULL_TREE;
init = build (MODIFY_EXPR, void_type_node, decl, init);
append_to_compound_expr (init, &pre);
gimplify_stmt (&init);
append_to_statement_list (init, stmt_p);
}
else
{
/* We must still examine initializers for static variables
as they may contain a label address. */
walk_tree (&init, force_labels_r, NULL, NULL);
}
/* We must still examine initializers for static variables
as they may contain a label address. */
walk_tree (&init, force_labels_r, NULL, NULL);
}
/* This decl isn't mentioned in the enclosing block, so add it to the
@ -547,10 +540,10 @@ gimplify_decl_stmt (tree *stmt_p)
if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
gimple_add_tmp_var (decl);
}
else
*stmt_p = alloc_stmt_list ();
append_to_compound_expr (post, &pre);
*stmt_p = pre;
return GS_OK;
return GS_ALL_DONE;
}
/* Gimplification of expression trees. */
@ -560,7 +553,7 @@ gimplify_decl_stmt (tree *stmt_p)
instead. */
static enum gimplify_status
gimplify_compound_literal_expr (tree *expr_p)
gimplify_compound_literal_expr (tree *expr_p, tree *pre_p)
{
tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
tree decl = DECL_STMT_DECL (decl_s);
@ -572,7 +565,8 @@ gimplify_compound_literal_expr (tree *expr_p)
gimple_add_tmp_var (decl);
gimplify_decl_stmt (&decl_s);
*expr_p = decl_s ? decl_s : decl;
append_to_statement_list (decl_s, pre_p);
*expr_p = decl;
return GS_OK;
}
@ -586,7 +580,7 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
switch (code)
{
case COMPOUND_LITERAL_EXPR:
return gimplify_compound_literal_expr (expr_p);
return gimplify_compound_literal_expr (expr_p, pre_p);
case FOR_STMT:
return gimplify_for_stmt (expr_p, pre_p);

View file

@ -147,7 +147,6 @@ extern int c_in_iteration_stmt;
extern int c_in_case_stmt;
extern int global_bindings_p (void);
extern tree getdecls (void);
extern void push_scope (void);
extern tree pop_scope (void);
extern void insert_block (tree);

View file

@ -1222,10 +1222,10 @@ default_function_array_conversion (tree exp)
if (TREE_CODE (exp) == VAR_DECL)
{
/* ??? This is not really quite correct
in that the type of the operand of ADDR_EXPR
is not the target type of the type of the ADDR_EXPR itself.
Question is, can this lossage be avoided? */
/* We are making an ADDR_EXPR of ptrtype. This is a valid
ADDR_EXPR because it's the best way of representing what
happens in C when we take the address of an array and place
it in a pointer to the element type. */
adr = build1 (ADDR_EXPR, ptrtype, exp);
if (!c_mark_addressable (exp))
return error_mark_node;
@ -1483,7 +1483,8 @@ build_component_ref (tree datum, tree component)
if (TREE_TYPE (subdatum) == error_mark_node)
return error_mark_node;
ref = build (COMPONENT_REF, TREE_TYPE (subdatum), datum, subdatum);
ref = build (COMPONENT_REF, TREE_TYPE (subdatum), datum, subdatum,
NULL_TREE);
if (TREE_READONLY (datum) || TREE_READONLY (subdatum))
TREE_READONLY (ref) = 1;
if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (subdatum))
@ -1636,7 +1637,7 @@ build_array_ref (tree array, tree index)
}
type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
rval = build (ARRAY_REF, type, array, index);
rval = build (ARRAY_REF, type, array, index, NULL_TREE, NULL_TREE);
/* Array ref is const/volatile if the array elements are
or if the array is. */
TREE_READONLY (rval)
@ -2562,6 +2563,9 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
else
addr = build1 (code, argtype, arg);
if (TREE_CODE (arg) == COMPOUND_LITERAL_EXPR)
TREE_INVARIANT (addr) = TREE_CONSTANT (addr) = 1;
return addr;
}

View file

@ -6274,9 +6274,9 @@ alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
offset_field = TREE_CHAIN (base_field);
base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
valist, base_field);
valist, base_field, NULL_TREE);
offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
valist, offset_field);
valist, offset_field, NULL_TREE);
t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
t = build (PLUS_EXPR, ptr_type_node, t, build_int_2 (offset, 0));
@ -6383,9 +6383,9 @@ alpha_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
base_field = TYPE_FIELDS (va_list_type_node);
offset_field = TREE_CHAIN (base_field);
base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
valist, base_field);
valist, base_field, NULL_TREE);
offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
valist, offset_field);
valist, offset_field, NULL_TREE);
/* Pull the fields of the structure out into temporaries. Since we never
modify the base field, we can use a formal temporary. Sign-extend the

View file

@ -3136,10 +3136,10 @@ ix86_va_start (tree valist, rtx nextarg)
f_sav = TREE_CHAIN (f_ovf);
valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
/* Count number of gp and fp argument registers used. */
words = current_function_args_info.words;
@ -3202,10 +3202,10 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
f_sav = TREE_CHAIN (f_ovf);
valist = build_fold_indirect_ref (valist);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
size = int_size_in_bytes (type);
if (size == -1)

View file

@ -1877,10 +1877,10 @@ i860_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
f_fpr = TREE_CHAIN (f_gpr);
#endif
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem, NULL_TREE);
/* Initialize the `mem_ptr' field to the address of the first anonymous
stack argument. */
@ -1943,10 +1943,10 @@ i860_va_arg (tree valist, tree type)
f_fpr = TREE_CHAIN (f_gpr);
#endif
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem, NULL_TREE);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
size = int_size_in_bytes (type);

View file

@ -1656,11 +1656,11 @@ iq2000_va_arg (tree valist, tree type)
f_goff = TREE_CHAIN (f_ftop);
f_foff = TREE_CHAIN (f_goff);
ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl);
gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop);
ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop);
goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff);
foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff);
ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl, NULL_TREE);
gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop, NULL_TREE);
ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop, NULL_TREE);
goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff, NULL_TREE);
foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff, NULL_TREE);
lab_false = gen_label_rtx ();
lab_over = gen_label_rtx ();

View file

@ -4045,11 +4045,16 @@ mips_va_start (tree valist, rtx nextarg)
f_goff = TREE_CHAIN (f_ftop);
f_foff = TREE_CHAIN (f_goff);
ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl);
gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop);
ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop);
goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff);
foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff);
ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
NULL_TREE);
gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
NULL_TREE);
ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
NULL_TREE);
goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
NULL_TREE);
foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
NULL_TREE);
/* Emit code to initialize OVFL, which points to the next varargs
stack argument. CUM->STACK_WORDS gives the number of stack
@ -4212,12 +4217,15 @@ mips_va_arg (tree valist, tree type)
lab_false = gen_label_rtx ();
lab_over = gen_label_rtx ();
ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl);
ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
NULL_TREE);
if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT
&& GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FPVALUE)
{
top = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop);
off = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff);
top = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
NULL_TREE);
off = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
NULL_TREE);
/* When floating-point registers are saved to the stack,
each one will take up UNITS_PER_HWFPVALUE bytes, regardless
@ -4245,8 +4253,10 @@ mips_va_arg (tree valist, tree type)
}
else
{
top = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop);
off = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff);
top = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
NULL_TREE);
off = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
NULL_TREE);
if (rsize > UNITS_PER_WORD)
{
/* [1] Emit code for: off &= -rsize. */

View file

@ -5026,10 +5026,10 @@ rs6000_va_start (tree valist, rtx nextarg)
f_sav = TREE_CHAIN (f_ovf);
valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
/* Count number of gp and fp argument registers used. */
words = current_function_args_info.words;
@ -5131,10 +5131,10 @@ rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
f_sav = TREE_CHAIN (f_ovf);
valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
size = int_size_in_bytes (type);
rsize = (size + 3) / 4;

View file

@ -6381,10 +6381,10 @@ s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
f_sav = TREE_CHAIN (f_ovf);
valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
/* Count number of gp and fp argument registers used. */
@ -6462,10 +6462,10 @@ s390_gimplify_va_arg (tree valist, tree type, tree *pre_p,
f_sav = TREE_CHAIN (f_ovf);
valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
size = int_size_in_bytes (type);

View file

@ -6237,14 +6237,16 @@ sh_va_start (tree valist, rtx nextarg)
f_next_fp_limit = TREE_CHAIN (f_next_fp);
f_next_stack = TREE_CHAIN (f_next_fp_limit);
next_o = build (COMPONENT_REF, TREE_TYPE (f_next_o), valist, f_next_o);
next_o = build (COMPONENT_REF, TREE_TYPE (f_next_o), valist, f_next_o,
NULL_TREE);
next_o_limit = build (COMPONENT_REF, TREE_TYPE (f_next_o_limit),
valist, f_next_o_limit);
next_fp = build (COMPONENT_REF, TREE_TYPE (f_next_fp), valist, f_next_fp);
valist, f_next_o_limit, NULL_TREE);
next_fp = build (COMPONENT_REF, TREE_TYPE (f_next_fp), valist, f_next_fp,
NULL_TREE);
next_fp_limit = build (COMPONENT_REF, TREE_TYPE (f_next_fp_limit),
valist, f_next_fp_limit);
valist, f_next_fp_limit, NULL_TREE);
next_stack = build (COMPONENT_REF, TREE_TYPE (f_next_stack),
valist, f_next_stack);
valist, f_next_stack, NULL_TREE);
/* Call __builtin_saveregs. */
u = make_tree (ptr_type_node, expand_builtin_saveregs ());
@ -6317,15 +6319,16 @@ sh_va_arg (tree valist, tree type)
f_next_fp_limit = TREE_CHAIN (f_next_fp);
f_next_stack = TREE_CHAIN (f_next_fp_limit);
next_o = build (COMPONENT_REF, TREE_TYPE (f_next_o), valist, f_next_o);
next_o = build (COMPONENT_REF, TREE_TYPE (f_next_o), valist, f_next_o,
NULL_TREE);
next_o_limit = build (COMPONENT_REF, TREE_TYPE (f_next_o_limit),
valist, f_next_o_limit);
valist, f_next_o_limit, NULL_TREE);
next_fp = build (COMPONENT_REF, TREE_TYPE (f_next_fp),
valist, f_next_fp);
valist, f_next_fp, NULL_TREE);
next_fp_limit = build (COMPONENT_REF, TREE_TYPE (f_next_fp_limit),
valist, f_next_fp_limit);
valist, f_next_fp_limit, NULL_TREE);
next_stack = build (COMPONENT_REF, TREE_TYPE (f_next_stack),
valist, f_next_stack);
valist, f_next_stack, NULL_TREE);
/* Structures with a single member with a distinct mode are passed
like their member. This is relevant if the latter has a REAL_TYPE

View file

@ -1285,8 +1285,9 @@ xstormy16_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
f_base = TYPE_FIELDS (va_list_type_node);
f_count = TREE_CHAIN (f_base);
base = build (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base);
count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count);
base = build (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base, NULL_TREE);
count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count,
NULL_TREE);
t = make_tree (TREE_TYPE (base), virtual_incoming_args_rtx);
t = build (PLUS_EXPR, TREE_TYPE (base), t,
@ -1320,8 +1321,9 @@ xstormy16_expand_builtin_va_arg (tree valist, tree type)
f_base = TYPE_FIELDS (va_list_type_node);
f_count = TREE_CHAIN (f_base);
base = build (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base);
count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count);
base = build (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base, NULL_TREE);
count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count,
NULL_TREE);
must_stack = MUST_PASS_IN_STACK (TYPE_MODE (type), type);
size_tree = round_up (size_in_bytes (type), UNITS_PER_WORD);

View file

@ -2430,9 +2430,9 @@ xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
f_reg = TREE_CHAIN (f_stk);
f_ndx = TREE_CHAIN (f_reg);
stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk);
reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg);
ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx);
stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg, NULL_TREE);
ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx, NULL_TREE);
/* Call __builtin_saveregs; save the result in __va_reg */
u = make_tree (ptr_type_node, expand_builtin_saveregs ());
@ -2494,9 +2494,9 @@ xtensa_va_arg (tree valist, tree type)
f_reg = TREE_CHAIN (f_stk);
f_ndx = TREE_CHAIN (f_reg);
stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk);
reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg);
ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx);
stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg, NULL_TREE);
ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx, NULL_TREE);
type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));

View file

@ -428,16 +428,18 @@ rtl_coverage_counter_ref (unsigned counter, unsigned no)
tree
tree_coverage_counter_ref (unsigned counter, unsigned no)
{
tree t;
tree domain_type = TYPE_DOMAIN (TREE_TYPE (tree_ctr_tables[counter]));
if (no >= fn_n_ctrs[counter] - fn_b_ctrs[counter])
abort ();
no += prg_n_ctrs[counter] + fn_b_ctrs[counter];
/* "no" here is an array index, scaled to bytes later. */
t = build (ARRAY_REF, GCOV_TYPE_NODE, tree_ctr_tables[counter],
build_int_2 (no, 0));
return t;
return build (ARRAY_REF, GCOV_TYPE_NODE, tree_ctr_tables[counter],
fold_convert (domain_type, build_int_2 (no, 0)),
TYPE_MIN_VALUE (domain_type),
size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (GCOV_TYPE_NODE),
size_int (TYPE_ALIGN (GCOV_TYPE_NODE))));
}
/* Generate a checksum for a string. CHKSUM is the current

View file

@ -1,3 +1,29 @@
2004-06-21 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* call.c (build_vfield_ref): Add new operand for COMPONENT_REF.
(build_new_method_call): Likewise.
* decl.c (local_variable_p_walkfn): Don't walk into types.
* decl2.c (grok_array_decl): Add new operands for ARRAY_REF.
(build_anon_union_vars): Add new operand for COMPONENT_REF.
* init.c (buld_new): Add new operand for ARRAY_REF.
* method.c (do_build_copy_constructor): New op for COMPONENT_REF.
(do_build_assign_ref): Likewise.
* parser.c (cp_parser_direct_new_declarator): Add new operands
for ARRAY_REF.
(cp_parser_direct_declarator): Likewise.
* pt.c (tsubst): Likewise.
(tsubst_copy, tsubst_copy_and_build): Likewise; also add new operand
for COMPONENT_REF.
* semantics.c (finish_non_static_data_member): Add new operand
for COMPONENT_REF.
* typeck.c (build_class_member_access_expr): Likewise.
(build_class_member_access_expr, finish_class_member_access_expr):
Likewise.
(build_ptrmemfunc_access_expr): Likewise.
(build_array_ref): Add new operands for ARRAY_REF.
* typeck2.c (split_nonconstant_init_1): Likewise; COMPONENT_REF too.
* tree.c (count_trees_r, no_linkage_helper): Don't walk in types.
2004-06-21 Richard Henderson <rth@redhat.com>
* dump.c (cp_dump_tree): Don't use dump_next_stmt.

View file

@ -203,7 +203,7 @@ build_vfield_ref (tree datum, tree type)
datum = convert_to_base (datum, type, /*check_access=*/false);
return build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)),
datum, TYPE_VFIELD (type));
datum, TYPE_VFIELD (type), NULL_TREE);
}
/* Returns nonzero iff the destructor name specified in NAME
@ -3868,8 +3868,7 @@ builtin:
return build_conditional_expr (arg1, arg2, arg3);
case MEMBER_REF:
return build_m_component_ref
(build_indirect_ref (arg1, NULL), arg2);
return build_m_component_ref (build_indirect_ref (arg1, NULL), arg2);
/* The caller will deal with these. */
case ADDR_EXPR:
@ -5360,7 +5359,7 @@ build_new_method_call (tree instance, tree fns, tree args,
if (processing_template_decl && call != error_mark_node)
call = (build_min_non_dep
(CALL_EXPR, call,
build_min_nt (COMPONENT_REF, orig_instance, orig_fns),
build_min_nt (COMPONENT_REF, orig_instance, orig_fns, NULL_TREE),
orig_args, NULL_TREE));
/* Free all the conversions we allocated. */

View file

@ -8508,14 +8508,18 @@ nonstatic_local_decl_p (tree t)
function. */
static tree
local_variable_p_walkfn (tree* tp,
int* walk_subtrees ATTRIBUTE_UNUSED ,
void* data ATTRIBUTE_UNUSED )
local_variable_p_walkfn (tree *tp, int *walk_subtrees,
void *data ATTRIBUTE_UNUSED)
{
return ((local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp))
? *tp : NULL_TREE);
if (local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp))
return *tp;
else if (TYPE_P (*tp))
*walk_subtrees = 0;
return NULL_TREE;
}
/* Check that ARG, which is a default-argument expression for a
parameter DECL, is valid. Returns ARG, or ERROR_MARK_NODE, if
something goes wrong. DECL may also be a _TYPE node, rather than a

View file

@ -369,7 +369,8 @@ grok_array_decl (tree array_expr, tree index_exp)
{
if (type_dependent_expression_p (array_expr)
|| type_dependent_expression_p (index_exp))
return build_min_nt (ARRAY_REF, array_expr, index_exp);
return build_min_nt (ARRAY_REF, array_expr, index_exp,
NULL_TREE, NULL_TREE);
array_expr = build_non_dependent_expr (array_expr);
index_exp = build_non_dependent_expr (index_exp);
}
@ -426,8 +427,8 @@ grok_array_decl (tree array_expr, tree index_exp)
expr = build_array_ref (array_expr, index_exp);
}
if (processing_template_decl && expr != error_mark_node)
return build_min_non_dep (ARRAY_REF, expr,
orig_array_expr, orig_index_exp);
return build_min_non_dep (ARRAY_REF, expr, orig_array_expr, orig_index_exp,
NULL_TREE, NULL_TREE);
return expr;
}
@ -1175,7 +1176,8 @@ build_anon_union_vars (tree object)
cp_pedwarn_at ("protected member `%#D' in anonymous union", field);
if (processing_template_decl)
ref = build_min_nt (COMPONENT_REF, object, DECL_NAME (field));
ref = build_min_nt (COMPONENT_REF, object,
DECL_NAME (field), NULL_TREE);
else
ref = build_class_member_access_expr (object, field, NULL_TREE,
false);

View file

@ -1777,7 +1777,8 @@ build_new (tree placement, tree decl, tree init, int use_global_new)
{
if (has_array)
t = tree_cons (tree_cons (NULL_TREE, type, NULL_TREE),
build_min_nt (ARRAY_REF, NULL_TREE, nelts),
build_min_nt (ARRAY_REF, NULL_TREE, nelts,
NULL_TREE, NULL_TREE),
NULL_TREE);
else
t = type;
@ -1815,7 +1816,7 @@ build_new (tree placement, tree decl, tree init, int use_global_new)
}
if (has_array)
t = build_nt (ARRAY_REF, type, nelts);
t = build_nt (ARRAY_REF, type, nelts, NULL_TREE, NULL_TREE);
else
t = type;

View file

@ -591,7 +591,7 @@ do_build_copy_constructor (tree fndecl)
expr_type = TREE_TYPE (field);
if (TREE_CODE (expr_type) != REFERENCE_TYPE)
expr_type = cp_build_qualified_type (expr_type, cvquals);
init = build (COMPONENT_REF, expr_type, init, field);
init = build (COMPONENT_REF, expr_type, init, field, NULL_TREE);
init = build_tree_list (NULL_TREE, init);
member_init_list
@ -687,10 +687,11 @@ do_build_assign_ref (tree fndecl)
else
continue;
comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field);
comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field,
NULL_TREE);
init = build (COMPONENT_REF,
cp_build_qualified_type (TREE_TYPE (field), cvquals),
init, field);
init, field, NULL_TREE);
if (DECL_NAME (field))
finish_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));

View file

@ -4767,7 +4767,8 @@ cp_parser_direct_new_declarator (cp_parser* parser)
cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'");
/* Add this bound to the declarator. */
declarator = build_nt (ARRAY_REF, declarator, expression);
declarator = build_nt (ARRAY_REF, declarator, expression,
NULL_TREE, NULL_TREE);
/* If the next token is not a `[', then there are no more
bounds. */
@ -10714,7 +10715,8 @@ cp_parser_direct_declarator (cp_parser* parser,
break;
}
declarator = build_nt (ARRAY_REF, declarator, bounds);
declarator = build_nt (ARRAY_REF, declarator, bounds,
NULL_TREE, NULL_TREE);
}
else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
{

View file

@ -7201,7 +7201,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (e1 == error_mark_node || e2 == error_mark_node)
return error_mark_node;
return build_nt (ARRAY_REF, e1, e2);
return build_nt (ARRAY_REF, e1, e2, NULL_TREE, NULL_TREE);
}
case CALL_EXPR:
@ -7563,7 +7563,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
in_decl);
else
name = tsubst_copy (name, args, complain, in_decl);
return build_nt (COMPONENT_REF, object, name);
return build_nt (COMPONENT_REF, object, name, NULL_TREE);
}
case PLUS_EXPR:
@ -8143,7 +8143,7 @@ tsubst_copy_and_build (tree t,
if (object)
return build (COMPONENT_REF, TREE_TYPE (template),
object, template);
object, template, NULL_TREE);
else
return template;
}
@ -8255,7 +8255,8 @@ tsubst_copy_and_build (tree t,
if (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl)
== NULL_TREE)
/* new-type-id */
return build_nt (ARRAY_REF, NULL_TREE, RECUR (TREE_OPERAND (t, 1)));
return build_nt (ARRAY_REF, NULL_TREE, RECUR (TREE_OPERAND (t, 1)),
NULL_TREE, NULL_TREE);
op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
args, complain, in_decl);

View file

@ -1233,7 +1233,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
type = cp_build_qualified_type (type, quals);
}
return build_min (COMPONENT_REF, type, object, decl);
return build_min (COMPONENT_REF, type, object, decl, NULL_TREE);
}
else
{

View file

@ -1026,11 +1026,13 @@ bind_template_template_parm (tree t, tree newargs)
/* Called from count_trees via walk_tree. */
static tree
count_trees_r (tree* tp ATTRIBUTE_UNUSED ,
int* walk_subtrees ATTRIBUTE_UNUSED ,
void* data)
count_trees_r (tree *tp, int *walk_subtrees, void *data)
{
++ *((int*) data);
++*((int *) data);
if (TYPE_P (*tp))
*walk_subtrees = 0;
return NULL_TREE;
}
@ -1107,9 +1109,8 @@ find_tree (tree t, tree x)
/* Passed to walk_tree. Checks for the use of types with no linkage. */
static tree
no_linkage_helper (tree* tp,
int* walk_subtrees ATTRIBUTE_UNUSED ,
void* data ATTRIBUTE_UNUSED )
no_linkage_helper (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
void *data ATTRIBUTE_UNUSED)
{
tree t = *tp;
@ -1118,6 +1119,7 @@ no_linkage_helper (tree* tp,
&& (decl_function_context (TYPE_MAIN_DECL (t))
|| TYPE_ANONYMOUS_P (t)))
return t;
return NULL_TREE;
}

View file

@ -1752,7 +1752,8 @@ build_class_member_access_expr (tree object, tree member,
member_type = cp_build_qualified_type (member_type, type_quals);
}
result = fold (build (COMPONENT_REF, member_type, object, member));
result = fold (build (COMPONENT_REF, member_type, object, member,
NULL_TREE));
/* Mark the expression const or volatile, as appropriate. Even
though we've dealt with the type above, we still have to mark the
@ -1779,7 +1780,7 @@ build_class_member_access_expr (tree object, tree member,
type = unknown_type_node;
/* Note that we do not convert OBJECT to the BASELINK_BINFO
base. That will happen when the function is called. */
result = build (COMPONENT_REF, type, object, member);
result = build (COMPONENT_REF, type, object, member, NULL_TREE);
}
else if (TREE_CODE (member) == CONST_DECL)
{
@ -1878,7 +1879,7 @@ finish_class_member_access_expr (tree object, tree name)
|| (TREE_CODE (name) == SCOPE_REF
&& TYPE_P (TREE_OPERAND (name, 0))
&& dependent_type_p (TREE_OPERAND (name, 0))))
return build_min_nt (COMPONENT_REF, object, name);
return build_min_nt (COMPONENT_REF, object, name, NULL_TREE);
object = build_non_dependent_expr (object);
}
@ -2005,7 +2006,7 @@ finish_class_member_access_expr (tree object, tree name)
/*preserve_reference=*/false);
if (processing_template_decl && expr != error_mark_node)
return build_min_non_dep (COMPONENT_REF, expr,
orig_object, orig_name);
orig_object, orig_name, NULL_TREE);
return expr;
}
@ -2033,7 +2034,7 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
/*want_type=*/false);
member_type = cp_build_qualified_type (TREE_TYPE (member),
cp_type_quals (ptrmem_type));
return fold (build (COMPONENT_REF, member_type, ptrmem, member));
return fold (build (COMPONENT_REF, member_type, ptrmem, member, NULL_TREE));
}
/* Given an expression PTR for a pointer, return an expression
@ -2249,7 +2250,7 @@ build_array_ref (tree array, tree idx)
}
type = TREE_TYPE (TREE_TYPE (array));
rval = build (ARRAY_REF, type, array, idx);
rval = build (ARRAY_REF, type, array, idx, NULL_TREE, NULL_TREE);
/* Array ref is const/volatile if the array elements are
or if the array is.. */
TREE_READONLY (rval)

View file

@ -320,9 +320,11 @@ split_nonconstant_init_1 (tree dest, tree init)
if (TREE_CODE (value) == CONSTRUCTOR)
{
if (array_type_p)
sub = build (ARRAY_REF, inner_type, dest, field_index);
sub = build (ARRAY_REF, inner_type, dest, field_index,
NULL_TREE, NULL_TREE);
else
sub = build (COMPONENT_REF, inner_type, dest, field_index);
sub = build (COMPONENT_REF, inner_type, dest, field_index,
NULL_TREE);
split_nonconstant_init_1 (sub, value);
}
@ -331,9 +333,11 @@ split_nonconstant_init_1 (tree dest, tree init)
*pelt = TREE_CHAIN (elt);
if (array_type_p)
sub = build (ARRAY_REF, inner_type, dest, field_index);
sub = build (ARRAY_REF, inner_type, dest, field_index,
NULL_TREE, NULL_TREE);
else
sub = build (COMPONENT_REF, inner_type, dest, field_index);
sub = build (COMPONENT_REF, inner_type, dest, field_index,
NULL_TREE);
code = build (MODIFY_EXPR, inner_type, sub, value);
code = build_stmt (EXPR_STMT, code);

View file

@ -1460,8 +1460,8 @@ component_ref_for_mem_expr (tree ref)
if (inner == TREE_OPERAND (ref, 0))
return ref;
else
return build (COMPONENT_REF, TREE_TYPE (ref), inner,
TREE_OPERAND (ref, 1));
return build (COMPONENT_REF, TREE_TYPE (ref), inner, TREE_OPERAND (ref, 1),
NULL_TREE);
}
/* Returns 1 if both MEM_EXPR can be considered equal
@ -1625,28 +1625,22 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
do
{
tree index = TREE_OPERAND (t2, 1);
tree array = TREE_OPERAND (t2, 0);
tree domain = TYPE_DOMAIN (TREE_TYPE (array));
tree low_bound = (domain ? TYPE_MIN_VALUE (domain) : 0);
tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (array)));
tree low_bound = array_ref_low_bound (t2);
tree unit_size = array_ref_element_size (t2);
/* We assume all arrays have sizes that are a multiple of a byte.
First subtract the lower bound, if any, in the type of the
index, then convert to sizetype and multiply by the size of the
array element. */
if (low_bound != 0 && ! integer_zerop (low_bound))
index, then convert to sizetype and multiply by the size of
the array element. */
if (! integer_zerop (low_bound))
index = fold (build (MINUS_EXPR, TREE_TYPE (index),
index, low_bound));
/* If the index has a self-referential type, instantiate it;
likewise for the component size. */
index = SUBSTITUTE_PLACEHOLDER_IN_EXPR (index, t2);
unit_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (unit_size, array);
off_tree
= fold (build (PLUS_EXPR, sizetype,
fold (build (MULT_EXPR, sizetype,
index, unit_size)),
off_tree));
off_tree = size_binop (PLUS_EXPR,
size_binop (MULT_EXPR, convert (sizetype,
index),
unit_size),
off_tree);
t2 = TREE_OPERAND (t2, 0);
}
while (TREE_CODE (t2) == ARRAY_REF);
@ -2042,6 +2036,7 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
if (TREE_CODE (expr) == COMPONENT_REF)
{
tree field = TREE_OPERAND (expr, 1);
tree offset = component_ref_field_offset (expr);
if (! DECL_SIZE_UNIT (field))
{
@ -2056,17 +2051,18 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
&& INTVAL (memoffset) >= 0)
break;
if (! host_integerp (DECL_FIELD_OFFSET (field), 1))
if (! host_integerp (offset, 1))
{
expr = NULL_TREE;
break;
}
expr = TREE_OPERAND (expr, 0);
memoffset = (GEN_INT (INTVAL (memoffset)
+ tree_low_cst (DECL_FIELD_OFFSET (field), 1)
+ (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
/ BITS_PER_UNIT)));
memoffset
= (GEN_INT (INTVAL (memoffset)
+ tree_low_cst (offset, 1)
+ (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
/ BITS_PER_UNIT)));
}
/* Similarly for the decl. */
else if (DECL_P (expr)

View file

@ -1100,7 +1100,7 @@ update_nonlocal_goto_save_area (void)
STACK_SAVEAREA_MODE. Create a reference to array index 1, the first
of the stack save area slots. */
t_save = build (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area,
integer_one_node);
integer_one_node, NULL_TREE, NULL_TREE);
r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
emit_stack_save (SAVE_NONLOCAL, &r_save, NULL_RTX);

View file

@ -5591,15 +5591,13 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
else if (TREE_CODE (exp) == COMPONENT_REF)
{
tree field = TREE_OPERAND (exp, 1);
tree this_offset = DECL_FIELD_OFFSET (field);
tree this_offset = component_ref_field_offset (exp);
/* If this field hasn't been filled in yet, don't go
past it. This should only happen when folding expressions
made during type construction. */
if (this_offset == 0)
break;
else
this_offset = SUBSTITUTE_PLACEHOLDER_IN_EXPR (this_offset, exp);
offset = size_binop (PLUS_EXPR, offset, this_offset);
bit_offset = size_binop (PLUS_EXPR, bit_offset,
@ -5612,23 +5610,17 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
|| TREE_CODE (exp) == ARRAY_RANGE_REF)
{
tree index = TREE_OPERAND (exp, 1);
tree array = TREE_OPERAND (exp, 0);
tree domain = TYPE_DOMAIN (TREE_TYPE (array));
tree low_bound = (domain ? TYPE_MIN_VALUE (domain) : 0);
tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (array)));
tree low_bound = array_ref_low_bound (exp);
tree unit_size = array_ref_element_size (exp);
/* We assume all arrays have sizes that are a multiple of a byte.
First subtract the lower bound, if any, in the type of the
index, then convert to sizetype and multiply by the size of the
array element. */
if (low_bound != 0 && ! integer_zerop (low_bound))
if (! integer_zerop (low_bound))
index = fold (build (MINUS_EXPR, TREE_TYPE (index),
index, low_bound));
/* If the index has a self-referential type, instantiate it with
the object; likewise for the component size. */
index = SUBSTITUTE_PLACEHOLDER_IN_EXPR (index, exp);
unit_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (unit_size, array);
offset = size_binop (PLUS_EXPR, offset,
size_binop (MULT_EXPR,
convert (sizetype, index),
@ -5676,6 +5668,70 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
return exp;
}
/* Return a tree of sizetype representing the size, in bytes, of the element
of EXP, an ARRAY_REF. */
tree
array_ref_element_size (tree exp)
{
tree aligned_size = TREE_OPERAND (exp, 3);
tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)));
/* If a size was specified in the ARRAY_REF, it's the size measured
in alignment units of the element type. So multiply by that value. */
if (aligned_size)
return size_binop (MULT_EXPR, aligned_size,
size_int (TYPE_ALIGN (elmt_type) / BITS_PER_UNIT));
/* Otherwise, take the size from that of the element type. Substitute
any PLACEHOLDER_EXPR that we have. */
else
return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (elmt_type), exp);
}
/* Return a tree representing the lower bound of the array mentioned in
EXP, an ARRAY_REF. */
tree
array_ref_low_bound (tree exp)
{
tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
/* If a lower bound is specified in EXP, use it. */
if (TREE_OPERAND (exp, 2))
return TREE_OPERAND (exp, 2);
/* Otherwise, if there is a domain type and it has a lower bound, use it,
substituting for a PLACEHOLDER_EXPR as needed. */
if (domain_type && TYPE_MIN_VALUE (domain_type))
return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MIN_VALUE (domain_type), exp);
/* Otherwise, return a zero of the appropriate type. */
return fold_convert (TREE_TYPE (TREE_OPERAND (exp, 1)), integer_zero_node);
}
/* Return a tree representing the offset, in bytes, of the field referenced
by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */
tree
component_ref_field_offset (tree exp)
{
tree aligned_offset = TREE_OPERAND (exp, 2);
tree field = TREE_OPERAND (exp, 1);
/* If an offset was specified in the COMPONENT_REF, it's the offset measured
in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT. So multiply by that
value. */
if (aligned_offset)
return size_binop (MULT_EXPR, aligned_offset,
size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT));
/* Otherwise, take the offset from that of the field. Substitute
any PLACEHOLDER_EXPR that we have. */
else
return SUBSTITUTE_PLACEHOLDER_IN_EXPR (DECL_FIELD_OFFSET (field), exp);
}
/* Return 1 if T is an expression that get_inner_reference handles. */
int
@ -7001,8 +7057,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
{
tree array = TREE_OPERAND (exp, 0);
tree domain = TYPE_DOMAIN (TREE_TYPE (array));
tree low_bound = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node;
tree low_bound = array_ref_low_bound (exp);
tree index = convert (sizetype, TREE_OPERAND (exp, 1));
HOST_WIDE_INT i;

View file

@ -2019,9 +2019,9 @@ non_lvalue (tree x)
case COMPONENT_REF:
case INDIRECT_REF:
case ARRAY_REF:
case ARRAY_RANGE_REF:
case BIT_FIELD_REF:
case BUFFER_REF:
case ARRAY_RANGE_REF:
case VTABLE_REF:
case REALPART_EXPR:
@ -7901,24 +7901,26 @@ fold (tree expr)
/* If VAROP is a reference to a bitfield, we must mask
the constant by the width of the field. */
if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
&& DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (varop, 0), 1)))
&& DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (varop, 0), 1))
&& host_integerp (DECL_SIZE (TREE_OPERAND
(TREE_OPERAND (varop, 0), 1)), 1))
{
tree fielddecl = TREE_OPERAND (TREE_OPERAND (varop, 0), 1);
int size = TREE_INT_CST_LOW (DECL_SIZE (fielddecl));
HOST_WIDE_INT size = tree_low_cst (DECL_SIZE (fielddecl), 1);
tree folded_compare, shift;
/* First check whether the comparison would come out
always the same. If we don't do that we would
change the meaning with the masking. */
folded_compare = fold (build2 (code, type,
TREE_OPERAND (varop, 0),
arg1));
TREE_OPERAND (varop, 0), arg1));
if (integer_zerop (folded_compare)
|| integer_onep (folded_compare))
return omit_one_operand (type, folded_compare, varop);
shift = build_int_2 (TYPE_PRECISION (TREE_TYPE (varop)) - size,
0);
shift = fold_convert (TREE_TYPE (varop), shift);
newconst = fold (build2 (LSHIFT_EXPR, TREE_TYPE (varop),
newconst, shift));
newconst = fold (build2 (RSHIFT_EXPR, TREE_TYPE (varop),
@ -10106,13 +10108,10 @@ fold_read_from_constant_string (tree exp)
tree string;
if (TREE_CODE (exp) == INDIRECT_REF)
{
string = string_constant (exp1, &index);
}
string = string_constant (exp1, &index);
else
{
tree domain = TYPE_DOMAIN (TREE_TYPE (exp1));
tree low_bound = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node;
tree low_bound = array_ref_low_bound (exp);
index = fold_convert (sizetype, TREE_OPERAND (exp, 1));
/* Optimize the special-case of a zero lower bound.
@ -10129,6 +10128,7 @@ fold_read_from_constant_string (tree exp)
}
if (string
&& TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (string))
&& TREE_CODE (string) == STRING_CST
&& TREE_CODE (index) == INTEGER_CST
&& compare_tree_int (index, TREE_STRING_LENGTH (string)) < 0
@ -10456,7 +10456,7 @@ build_fold_indirect_ref (tree t)
/* *(foo *)&fooarray => fooarray[0] */
else if (TREE_CODE (optype) == ARRAY_TYPE
&& lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
return build2 (ARRAY_REF, type, op, size_zero_node);
return build4 (ARRAY_REF, type, op, size_zero_node, NULL_TREE, NULL_TREE);
}
/* *(foo *)fooarrptr => (*fooarrptr)[0] */
@ -10465,7 +10465,7 @@ build_fold_indirect_ref (tree t)
&& lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
{
sub = build_fold_indirect_ref (sub);
return build2 (ARRAY_REF, type, sub, size_zero_node);
return build4 (ARRAY_REF, type, sub, size_zero_node, NULL_TREE, NULL_TREE);
}
return build1 (INDIRECT_REF, type, t);

View file

@ -1,3 +1,22 @@
2004-06-21 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* f95-lang.c (LANG_HOOKS_GIMPLE_BEFORE_INLINING): Deleted.
* trans-array.c (gfc_conv_descriptor_data): Add operand
for COMPONENT_REF.
(gfc_conv_descriptor_offset, gfc_conv_descriptor_dtype): Likewise.
(gfc_conv_descriptor_dimension, gfc_conv_descriptor_stride): Likewise.
(gfc_conv_descriptor_lbound, gfc_conv_descriptor_ubound): Likewise.
* trans-common.c (create_common): Likewise.
* trans-expr.c (gfc_conv_component_ref): Likewise.
* trans-io.c (set_parameter_value): Likewise.
(set_parameter_ref, set_string, set_flag, io_result): Likewise.
(transfer_expr): Likewise.
* trans-decl.c (gfc_trans_auto_character_variable):
Set up to get DECL_SIZE and DECL_SIZE_UNIT gimplified.
(gfc_simplify_function): New function.
(gfc_generate_function-code): Properly handle nested functions.
* trans.c (gfc_build_array_ref): Add two new operands for ARRAY_REF.
2004-06-22 Janne Blomqvist <jblomqvi@cc.hut.fi>
PR fortran/15750

View file

@ -122,7 +122,6 @@ static void gfc_expand_function (tree);
#undef LANG_HOOKS_UNSIGNED_TYPE
#undef LANG_HOOKS_SIGNED_TYPE
#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
#undef LANG_HOOKS_GIMPLE_BEFORE_INLINING
#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
/* Define lang hooks. */
@ -141,7 +140,6 @@ static void gfc_expand_function (tree);
#define LANG_HOOKS_UNSIGNED_TYPE gfc_unsigned_type
#define LANG_HOOKS_SIGNED_TYPE gfc_signed_type
#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE gfc_signed_or_unsigned_type
#define LANG_HOOKS_GIMPLE_BEFORE_INLINING false
#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION gfc_expand_function
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;

View file

@ -189,7 +189,7 @@ gfc_conv_descriptor_data (tree desc)
&& TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == ARRAY_TYPE);
return build (COMPONENT_REF, TREE_TYPE (field), desc, field);
return build (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
}
tree
@ -204,7 +204,7 @@ gfc_conv_descriptor_offset (tree desc)
field = gfc_advance_chain (TYPE_FIELDS (type), OFFSET_FIELD);
assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
return build (COMPONENT_REF, TREE_TYPE (field), desc, field);
return build (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
}
tree
@ -219,7 +219,7 @@ gfc_conv_descriptor_dtype (tree desc)
field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
return build (COMPONENT_REF, TREE_TYPE (field), desc, field);
return build (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
}
static tree
@ -237,7 +237,7 @@ gfc_conv_descriptor_dimension (tree desc, tree dim)
&& TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
tmp = build (COMPONENT_REF, TREE_TYPE (field), desc, field);
tmp = build (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
tmp = gfc_build_array_ref (tmp, dim);
return tmp;
}
@ -253,7 +253,7 @@ gfc_conv_descriptor_stride (tree desc, tree dim)
field = gfc_advance_chain (field, STRIDE_SUBFIELD);
assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field);
tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
return tmp;
}
@ -268,7 +268,7 @@ gfc_conv_descriptor_lbound (tree desc, tree dim)
field = gfc_advance_chain (field, LBOUND_SUBFIELD);
assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field);
tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
return tmp;
}
@ -283,7 +283,7 @@ gfc_conv_descriptor_ubound (tree desc, tree dim)
field = gfc_advance_chain (field, UBOUND_SUBFIELD);
assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field);
tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
return tmp;
}

View file

@ -425,7 +425,7 @@ create_common (gfc_symbol *sym)
for (h = current_common; h; h = next_s)
{
h->sym->backend_decl = build (COMPONENT_REF, TREE_TYPE (h->field),
decl, h->field);
decl, h->field, NULL_TREE);
next_s = h->next;
gfc_free (h);

View file

@ -1645,6 +1645,14 @@ gfc_trans_auto_character_variable (gfc_symbol * sym, tree fnbody)
DECL_DEFER_OUTPUT (decl) = 1;
/* Since we don't use a DECL_STMT or equivalent, we have to deal
with getting these gimplified. But we can't gimplify it yet since
we're still generating statements.
??? This should be cleaned up and handled like other front ends. */
gfc_add_expr_to_block (&body, save_expr (DECL_SIZE (decl)));
gfc_add_expr_to_block (&body, save_expr (DECL_SIZE_UNIT (decl)));
/* Generate code to allocate the automatic variable. It will be freed
automatically. */
tmp = gfc_build_addr_expr (NULL, decl);
@ -1949,6 +1957,24 @@ gfc_finalize (tree decl)
cgraph_finalize_function (decl, false);
}
/* Convert FNDECL's code to GIMPLE and handle any nested functions. */
static void
gfc_gimplify_function (tree fndecl)
{
struct cgraph_node *cgn;
gimplify_function_tree (fndecl);
dump_function (TDI_generic, fndecl);
/* Convert all nested functions to GIMPLE now. We do things in this order
so that items like VLA sizes are expanded properly in the context of the
correct function. */
cgn = cgraph_node (fndecl);
for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
gfc_gimplify_function (cgn->decl);
}
/* Generate code for a function. */
void
@ -2120,26 +2146,17 @@ gfc_generate_function_code (gfc_namespace * ns)
current_function_decl = old_context;
if (decl_function_context (fndecl))
{
/* Register this function with cgraph just far enough to get it
added to our parent's nested function list. */
(void) cgraph_node (fndecl);
/* Lowering nested functions requires gimple input. */
gimplify_function_tree (fndecl);
}
/* Register this function with cgraph just far enough to get it
added to our parent's nested function list. */
(void) cgraph_node (fndecl);
else
{
if (cgraph_node (fndecl)->nested)
{
gimplify_function_tree (fndecl);
lower_nested_functions (fndecl);
}
gfc_gimplify_function (fndecl);
lower_nested_functions (fndecl);
gfc_finalize (fndecl);
}
}
void
gfc_generate_constructors (void)
{

View file

@ -221,7 +221,7 @@ gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
field = c->backend_decl;
assert (TREE_CODE (field) == FIELD_DECL);
decl = se->expr;
tmp = build (COMPONENT_REF, TREE_TYPE (field), decl, field);
tmp = build (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
se->expr = tmp;

View file

@ -359,7 +359,7 @@ set_parameter_value (stmtblock_t * block, tree var, gfc_expr * e)
gfc_conv_expr_type (&se, e, TREE_TYPE (var));
gfc_add_block_to_block (block, &se.pre);
tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var);
tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
gfc_add_modify_expr (block, tmp, se.expr);
}
@ -379,7 +379,7 @@ set_parameter_ref (stmtblock_t * block, tree var, gfc_expr * e)
gfc_conv_expr_type (&se, e, TREE_TYPE (var));
gfc_add_block_to_block (block, &se.pre);
tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var);
tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
gfc_add_modify_expr (block, tmp, se.expr);
}
@ -400,8 +400,9 @@ set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
gfc_init_se (&se, NULL);
gfc_conv_expr (&se, e);
io = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var);
len = build (COMPONENT_REF, TREE_TYPE (var_len), ioparm_var, var_len);
io = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
len = build (COMPONENT_REF, TREE_TYPE (var_len), ioparm_var, var_len,
NULL_TREE);
/* Integer variable assigned a format label. */
if (e->ts.type == BT_INTEGER && e->symtree->n.sym->attr.assign == 1)
@ -433,7 +434,7 @@ set_flag (stmtblock_t *block, tree var)
{
tree tmp;
tmp = build (COMPONENT_REF, TREE_TYPE(var), ioparm_var, var);
tmp = build (COMPONENT_REF, TREE_TYPE(var), ioparm_var, var, NULL_TREE);
gfc_add_modify_expr (block, tmp, integer_one_node);
}
@ -496,7 +497,7 @@ io_result (stmtblock_t * block, gfc_st_label * err_label,
tmp = gfc_finish_block (&body);
rc = build (COMPONENT_REF, TREE_TYPE (ioparm_library_return), ioparm_var,
ioparm_library_return);
ioparm_library_return, NULL_TREE);
tmp = build_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
@ -1127,7 +1128,8 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr)
field = c->backend_decl;
assert (field && TREE_CODE (field) == FIELD_DECL);
tmp = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
tmp = build (COMPONENT_REF, TREE_TYPE (field), expr, field,
NULL_TREE);
if (c->ts.type == BT_CHARACTER)
{

View file

@ -306,7 +306,7 @@ gfc_build_array_ref (tree base, tree offset)
if (DECL_P (base))
TREE_ADDRESSABLE (base) = 1;
return build (ARRAY_REF, type, base, offset);
return build (ARRAY_REF, type, base, offset, NULL_TREE, NULL_TREE);
}

View file

@ -6544,7 +6544,7 @@ expand_function_start (tree subr, int parms_have_cleanups)
expand_var (TREE_OPERAND (cfun->nonlocal_goto_save_area, 0));
t_save = build (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area,
integer_zero_node);
integer_zero_node, NULL_TREE, NULL_TREE);
r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
emit_move_insn (r_save, virtual_stack_vars_rtx);

View file

@ -476,8 +476,6 @@ expand_var_p (tree var)
if (TREE_CODE (var) != VAR_DECL)
return true;
ann = var_ann (var);
/* Remove all unused, unaliased temporaries. Also remove unused, unaliased
local variables during highly optimizing compilations. */
ann = var_ann (var);

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,16 @@
2004-06-21 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* class.c (build_class_ref): Add new operand for COMPONENT_REF.
(build_static_field_ref): Likewise and add new operands for ARRAY_REF.
* constants.c (build_ref_from_constant_pool): Likewise.
* expr.c (build_java_array_length_access): Likewise.
(build_get_class, build_field_ref, build_known_method_ref): Likewise.
(invoke_build_dtable, build_invokevirtual): Likewise.
(build_invokeinterface, java_expand_expr): Likewise.
(emit_init_test_initialization): Likewise.
* java-gimplify.c (java_gimplify_new_array_init): Likewise.
* parse.y (make_qualifed_name, build_array_ref): Likewise.
2004-06-21 Andrew Haley <aph@redhat.com>
* java-gimplify.c (java_gimplify_block): set TREE_USED on the new

View file

@ -1023,7 +1023,7 @@ build_class_ref (tree type)
prim_class = lookup_class (get_identifier (prim_class_name));
return build (COMPONENT_REF, NULL_TREE,
prim_class, TYPE_identifier_node);
prim_class, TYPE_identifier_node, NULL_TREE);
}
decl_name = TYPE_NAME (type);
if (TREE_CODE (decl_name) == TYPE_DECL)
@ -1088,7 +1088,8 @@ build_static_field_ref (tree fdecl)
(fdecl, &TYPE_ATABLE_METHODS (output_class)), 0);
tree field_address
= build (ARRAY_REF, build_pointer_type (TREE_TYPE (fdecl)),
TYPE_ATABLE_DECL (output_class), table_index);
TYPE_ATABLE_DECL (output_class), table_index,
NULL_TREE, NULL_TREE);
return fold (build1 (INDIRECT_REF, TREE_TYPE (fdecl),
field_address));
}
@ -1101,7 +1102,8 @@ build_static_field_ref (tree fdecl)
int field_index = 0;
ref = build1 (INDIRECT_REF, class_type_node, ref);
ref = build (COMPONENT_REF, field_ptr_type_node, ref,
lookup_field (&class_type_node, fields_ident));
lookup_field (&class_type_node, fields_ident),
NULL_TREE);
for (fld = TYPE_FIELDS (fclass); ; fld = TREE_CHAIN (fld))
{
@ -1118,9 +1120,11 @@ build_static_field_ref (tree fdecl)
ref, build_int_2 (field_index, 0)));
ref = build1 (INDIRECT_REF, field_type_node, ref);
ref = build (COMPONENT_REF, field_info_union_node,
ref, lookup_field (&field_type_node, info_ident));
ref, lookup_field (&field_type_node, info_ident),
NULL_TREE);
ref = build (COMPONENT_REF, ptr_type_node,
ref, TREE_CHAIN (TYPE_FIELDS (field_info_union_node)));
ref, TREE_CHAIN (TYPE_FIELDS (field_info_union_node)),
NULL_TREE);
return fold (build1 (INDIRECT_REF, TREE_TYPE(fdecl), ref));
}
}

View file

@ -424,7 +424,8 @@ build_ref_from_constant_pool (int index)
{
tree d = build_constant_data_ref ();
tree i = build_int_2 (index, 0);
return build (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i);
return build (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i,
NULL_TREE, NULL_TREE);
}
/* Build an initializer for the constants field of the current constant pool.

View file

@ -698,7 +698,8 @@ build_java_array_length_access (tree node)
node = build (COMPONENT_REF, int_type_node,
build_java_indirect_ref (array_type, node,
flag_check_references),
lookup_field (&array_type, get_identifier ("length")));
lookup_field (&array_type, get_identifier ("length")),
NULL_TREE);
IS_ARRAY_LENGTH_ACCESS (node) = 1;
return node;
}
@ -780,9 +781,9 @@ build_java_arrayaccess (tree array, tree type, tree index)
ref = build (COMPONENT_REF, TREE_TYPE (data_field),
build_java_indirect_ref (array_type, array,
flag_check_references),
data_field);
data_field, NULL_TREE);
node = build (ARRAY_REF, type, ref, index);
node = build (ARRAY_REF, type, ref, index, NULL_TREE, NULL_TREE);
return node;
}
@ -1181,8 +1182,8 @@ build_get_class (tree value)
build (COMPONENT_REF, dtable_ptr_type,
build_java_indirect_ref (object_type_node, value,
flag_check_references),
vtable_field)),
class_field);
vtable_field, NULL_TREE)),
class_field, NULL_TREE);
}
/* This builds the tree representation of the `instanceof' operator.
@ -1531,13 +1532,16 @@ build_field_ref (tree self_value, tree self_class, tree name)
in the same translation unit as output_class. If it is,
we can make a direct reference. */
{
tree otable_index =
build_int_2 (get_symbol_table_index
(field_decl, &TYPE_OTABLE_METHODS (output_class)), 0);
tree field_offset =
build (ARRAY_REF, integer_type_node, TYPE_OTABLE_DECL (output_class),
otable_index);
tree otable_index
= build_int_2 (get_symbol_table_index
(field_decl, &TYPE_OTABLE_METHODS (output_class)),
0);
tree field_offset
= build (ARRAY_REF, integer_type_node,
TYPE_OTABLE_DECL (output_class), otable_index,
NULL_TREE, NULL_TREE);
tree address;
field_offset = fold (convert (sizetype, field_offset));
address
= fold (build (PLUS_EXPR,
@ -1549,7 +1553,7 @@ build_field_ref (tree self_value, tree self_class, tree name)
self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
self_value, check);
return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
self_value, field_decl));
self_value, field_decl, NULL_TREE));
}
}
@ -1826,12 +1830,12 @@ build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
}
else
{
tree table_index =
build_int_2 (get_symbol_table_index
(method, &TYPE_ATABLE_METHODS (output_class)), 0);
func =
build (ARRAY_REF, method_ptr_type_node,
TYPE_ATABLE_DECL (output_class), table_index);
tree table_index
= build_int_2 (get_symbol_table_index
(method, &TYPE_ATABLE_METHODS (output_class)), 0);
func = build (ARRAY_REF, method_ptr_type_node,
TYPE_ATABLE_DECL (output_class), table_index,
NULL_TREE, NULL_TREE);
}
func = convert (method_ptr_type_node, func);
}
@ -1858,7 +1862,7 @@ build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
if (methods_ident == NULL_TREE)
methods_ident = get_identifier ("methods");
ref = build (COMPONENT_REF, method_ptr_type_node, ref,
lookup_field (&class_type_node, methods_ident));
lookup_field (&class_type_node, methods_ident), NULL_TREE);
for (meth = TYPE_METHODS (self_type);
; meth = TREE_CHAIN (meth))
{
@ -1874,8 +1878,8 @@ build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
ref, build_int_2 (method_index, 0)));
ref = build1 (INDIRECT_REF, method_type_node, ref);
func = build (COMPONENT_REF, nativecode_ptr_type_node,
ref,
lookup_field (&method_type_node, ncode_ident));
ref, lookup_field (&method_type_node, ncode_ident),
NULL_TREE);
}
return func;
}
@ -1899,7 +1903,7 @@ invoke_build_dtable (int is_invoke_interface, tree arg_list)
dtable = build_java_indirect_ref (object_type_node, objectref,
flag_check_references);
dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
lookup_field (&object_type_node, dtable_ident));
lookup_field (&object_type_node, dtable_ident), NULL_TREE);
return dtable;
}
@ -1955,7 +1959,7 @@ build_invokevirtual (tree dtable, tree method)
(method, &TYPE_OTABLE_METHODS (output_class)), 0);
method_index = build (ARRAY_REF, integer_type_node,
TYPE_OTABLE_DECL (output_class),
otable_index);
otable_index, NULL_TREE, NULL_TREE);
}
else
{
@ -2001,7 +2005,7 @@ build_invokeinterface (tree dtable, tree method)
dtable = build_java_indirect_ref (dtable_type, dtable,
flag_check_references);
dtable = build (COMPONENT_REF, class_ptr_type, dtable,
lookup_field (&dtable_type, class_ident));
lookup_field (&dtable_type, class_ident), NULL_TREE);
interface = DECL_CONTEXT (method);
if (! CLASS_INTERFACE (TYPE_NAME (interface)))
@ -2010,17 +2014,15 @@ build_invokeinterface (tree dtable, tree method)
if (flag_indirect_dispatch)
{
otable_index =
build_int_2 (get_symbol_table_index
(method, &TYPE_OTABLE_METHODS (output_class)), 0);
idx =
build (ARRAY_REF, integer_type_node, TYPE_OTABLE_DECL (output_class),
otable_index);
otable_index
= build_int_2 (get_symbol_table_index
(method, &TYPE_OTABLE_METHODS (output_class)), 0);
idx = build (ARRAY_REF, integer_type_node,
TYPE_OTABLE_DECL (output_class), otable_index,
NULL_TREE, NULL_TREE);
}
else
{
idx = build_int_2 (get_interface_method_index (method, interface), 0);
}
idx = build_int_2 (get_interface_method_index (method, interface), 0);
lookup_arg = tree_cons (NULL_TREE, dtable,
tree_cons (NULL_TREE, build_class_ref (interface),
@ -2577,7 +2579,8 @@ java_expand_expr (tree exp, rtx target, enum machine_mode tmode,
expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
build_java_indirect_ref (array_type,
array_decl, flag_check_references),
data_fld), init, 0);
data_fld, NULL_TREE),
init, 0);
return tmp;
}
case BLOCK:
@ -3460,7 +3463,8 @@ emit_init_test_initialization (void **entry, void *x ATTRIBUTE_UNUSED)
build (COMPONENT_REF, byte_type_node,
build1 (INDIRECT_REF, class_type_node, klass),
lookup_field (&class_type_node,
get_identifier ("state"))),
get_identifier ("state")),
NULL_TREE),
build_int_2 (JV_STATE_DONE, 0));
expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node,

View file

@ -1,5 +1,4 @@
/* Java(TM) language-specific gimplification routines.
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@ -223,10 +222,11 @@ java_gimplify_new_array_init (tree exp)
bounds checking. */
tree lhs = build (COMPONENT_REF, TREE_TYPE (data_field),
build_java_indirect_ref (array_type, tmp, 0),
data_field);
data_field, NULL_TREE);
tree assignment = build (MODIFY_EXPR, element_type,
build (ARRAY_REF, element_type, lhs,
build_int_2 (index++, 0)),
build_int_2 (index++, 0),
NULL_TREE, NULL_TREE),
TREE_VALUE (values));
body = build (COMPOUND_EXPR, element_type, body, assignment);
values = TREE_CHAIN (values);

View file

@ -9254,7 +9254,7 @@ static tree
make_qualified_name (tree left, tree right, int location)
{
#ifdef USE_COMPONENT_REF
tree node = build (COMPONENT_REF, NULL_TREE, left, right);
tree node = build (COMPONENT_REF, NULL_TREE, left, right, NULL_TREE);
EXPR_WFL_LINECOL (node) = location;
return node;
#else
@ -14353,7 +14353,7 @@ build_null_of_type (tree type)
static tree
build_array_ref (int location, tree array, tree index)
{
tree node = build (ARRAY_REF, NULL_TREE, array, index);
tree node = build (ARRAY_REF, NULL_TREE, array, index, NULL_TREE, NULL_TREE);
EXPR_WFL_LINECOL (node) = location;
return node;
}

View file

@ -1975,7 +1975,7 @@ generate_static_references (void)
sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
ident = get_identifier (buf);
expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
build_tree_list (NULL_TREE,
ridpointers[(int) RID_STATIC]));
@ -2014,7 +2014,7 @@ generate_static_references (void)
decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
ident = get_identifier ("_OBJC_STATIC_INSTANCES");
expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
build_tree_list (NULL_TREE,
ridpointers[(int) RID_STATIC]));
@ -2044,7 +2044,8 @@ generate_strings (void)
sc_spec
= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
NULL_TREE, NULL_TREE);
decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
DECL_CONTEXT (decl) = NULL_TREE;
string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
@ -2059,7 +2060,8 @@ generate_strings (void)
sc_spec
= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
NULL_TREE, NULL_TREE);
decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
DECL_CONTEXT (decl) = NULL_TREE;
string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
@ -2074,7 +2076,8 @@ generate_strings (void)
sc_spec
= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
NULL_TREE, NULL_TREE);
decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
DECL_CONTEXT (decl) = NULL_TREE;
string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
@ -3521,7 +3524,7 @@ build_method_prototype_list_template (tree list_type, int size)
decl_specs = build_tree_list (NULL_TREE, list_type);
field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
build_int_2 (size, 0));
build_int_2 (size, 0), NULL_TREE, NULL_TREE);
field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
@ -4405,7 +4408,7 @@ build_ivar_list_template (tree list_type, int size)
decl_specs = build_tree_list (NULL_TREE, list_type);
field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
build_int_2 (size, 0));
build_int_2 (size, 0), NULL_TREE, NULL_TREE);
field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
@ -4453,7 +4456,7 @@ build_method_list_template (tree list_type, int size)
decl_specs = build_tree_list (NULL_TREE, list_type);
field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
build_int_2 (size, 0));
build_int_2 (size, 0), NULL_TREE, NULL_TREE);
field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
@ -4860,18 +4863,18 @@ generate_protocol_list (tree i_or_p)
expr_decl = build_nt (ARRAY_REF,
synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
i_or_p),
build_int_2 (size + 2, 0));
build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
expr_decl = build_nt (ARRAY_REF,
synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
i_or_p),
build_int_2 (size + 2, 0));
build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
expr_decl
= build_nt (ARRAY_REF,
synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
i_or_p),
build_int_2 (size + 2, 0));
build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
else
abort ();

View file

@ -3391,12 +3391,6 @@ expand_stack_alloc (tree alloc, tree t_size)
type = TREE_TYPE (var);
/* In function-at-a-time mode, variable_size doesn't expand this,
so do it now. */
if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
expand_expr (TYPE_MAX_VALUE (TYPE_DOMAIN (type)),
const0_rtx, VOIDmode, 0);
/* Compute the variable's size, in bytes. */
size = expand_expr (t_size, NULL_RTX, VOIDmode, 0);
free_temp_slots ();

View file

@ -93,11 +93,6 @@ tree
get_pending_sizes (void)
{
tree chain = pending_sizes;
tree t;
/* Put each SAVE_EXPR into the current function. */
for (t = chain; t; t = TREE_CHAIN (t))
SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = current_function_decl;
pending_sizes = 0;
return chain;

View file

@ -207,12 +207,15 @@ get_alias_var (tree expr)
switch (TREE_CODE (expr))
{
case ARRAY_REF:
case ARRAY_RANGE_REF:
{
/* Find the first non-array ref, and return it's alias
variable */
/* Find the first non-array ref, and return its alias variable. */
tree p;
for (p = expr; TREE_CODE (p) == ARRAY_REF;
p = TREE_OPERAND (p, 0));
for (p = expr;
TREE_CODE (p) == ARRAY_REF || TREE_CODE (p) == ARRAY_RANGE_REF;
p = TREE_OPERAND (p, 0))
;
return get_alias_var (p);
}
break;

View file

@ -3156,12 +3156,10 @@ verify_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
break;
case ADDR_EXPR:
x = TREE_OPERAND (t, 0);
while (TREE_CODE (x) == ARRAY_REF
|| TREE_CODE (x) == COMPONENT_REF
|| TREE_CODE (x) == REALPART_EXPR
|| TREE_CODE (x) == IMAGPART_EXPR)
x = TREE_OPERAND (x, 0);
for (x = TREE_OPERAND (t, 0); handled_component_p (x);
x = TREE_OPERAND (x, 0))
;
if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
return NULL;
if (!TREE_ADDRESSABLE (x))
@ -3309,7 +3307,7 @@ tree_node_can_be_shared (tree t)
|| TREE_CODE (t) == SSA_NAME)
return true;
while ((TREE_CODE (t) == ARRAY_REF
while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
/* We check for constants explicitly since they are not considered
gimple invariants if they overflowed. */
&& (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 1))) == 'c'

View file

@ -926,24 +926,17 @@ add_referenced_var (tree var, struct walk_state *walk_state)
tree
get_virtual_var (tree var)
{
enum tree_code code;
STRIP_NOPS (var);
if (TREE_CODE (var) == SSA_NAME)
var = SSA_NAME_VAR (var);
code = TREE_CODE (var);
while (code == ARRAY_REF
|| code == COMPONENT_REF
|| code == REALPART_EXPR
|| code == IMAGPART_EXPR)
{
if (TREE_CODE (var) == REALPART_EXPR || TREE_CODE (var) == IMAGPART_EXPR)
var = TREE_OPERAND (var, 0);
else
while (handled_component_p (var))
var = TREE_OPERAND (var, 0);
code = TREE_CODE (var);
}
#ifdef ENABLE_CHECKING
/* Treating GIMPLE registers as virtual variables makes no sense.
Also complain if we couldn't extract a _DECL out of the original

View file

@ -536,9 +536,7 @@ dequeue_and_dump (dump_info_p di)
case TRUTH_ORIF_EXPR:
case INIT_EXPR:
case MODIFY_EXPR:
case COMPONENT_REF:
case COMPOUND_EXPR:
case ARRAY_REF:
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
@ -548,6 +546,20 @@ dequeue_and_dump (dump_info_p di)
dump_child ("op 1", TREE_OPERAND (t, 1));
break;
case COMPONENT_REF:
dump_child ("op 0", TREE_OPERAND (t, 0));
dump_child ("op 1", TREE_OPERAND (t, 1));
dump_child ("op 2", TREE_OPERAND (t, 2));
break;
case ARRAY_REF:
case ARRAY_RANGE_REF:
dump_child ("op 0", TREE_OPERAND (t, 0));
dump_child ("op 1", TREE_OPERAND (t, 1));
dump_child ("op 2", TREE_OPERAND (t, 2));
dump_child ("op 3", TREE_OPERAND (t, 3));
break;
case COND_EXPR:
dump_child ("op 0", TREE_OPERAND (t, 0));
dump_child ("op 1", TREE_OPERAND (t, 1));

View file

@ -1682,6 +1682,7 @@ tree_could_trap_p (tree expr)
switch (code)
{
case ARRAY_REF:
case ARRAY_RANGE_REF:
case COMPONENT_REF:
case REALPART_EXPR:
case IMAGPART_EXPR:

View file

@ -119,17 +119,34 @@ Boston, MA 02111-1307, USA. */
min-lval: ID | '*' ID
bitfieldref :
BIT_FIELD_REF
op0 -> compref | min-lval
op0 -> inner_compref
op1 -> CONST
op2 -> CONST
op2 -> var
compref :
COMPONENT_REF
op0 -> compref | min-lval
op0 -> inner_compref
| ARRAY_REF
op0 -> compref | min-lval
op0 -> inner_compref
op1 -> val
op2 -> val
op3 -> val
| ARRAY_RANGE_REF
op0 -> inner_compref
op1 -> val
op2 -> val
op3 -> val
| REALPART_EXPR
op0 -> inner_compref
| IMAGPART_EXPR
op0 -> inner_compref
inner_compref : compref | min_lval
| VIEW_CONVERT_EXPR
op0 -> inner_compref
| NOP_EXPR
op0 -> inner_compref
| CONVERT_EXPR
op0 -> inner_compref
condition : val | val relop val
val : ID | CONST
@ -284,9 +301,11 @@ is_gimple_addr_expr_arg (tree t)
{
return (is_gimple_id (t)
|| TREE_CODE (t) == ARRAY_REF
|| TREE_CODE (t) == ARRAY_RANGE_REF
|| TREE_CODE (t) == COMPONENT_REF
|| TREE_CODE (t) == REALPART_EXPR
|| TREE_CODE (t) == IMAGPART_EXPR);
|| TREE_CODE (t) == IMAGPART_EXPR
|| TREE_CODE (t) == INDIRECT_REF);
}
/* Return nonzero if T is function invariant. Or rather a restricted
@ -581,19 +600,12 @@ get_base_address (tree t)
|| TREE_CODE (t) == INDIRECT_REF)
return t;
switch (TREE_CODE (t))
{
case ARRAY_REF:
case COMPONENT_REF:
case REALPART_EXPR:
case IMAGPART_EXPR:
case BIT_FIELD_REF:
t = TREE_OPERAND (t, 0);
break;
default:
return NULL_TREE;
}
if (TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR)
t = TREE_OPERAND (t, 0);
else if (handled_component_p (t))
t = get_base_address (TREE_OPERAND (t, 0));
else
return NULL_TREE;
}
while (t);

View file

@ -42,45 +42,45 @@ extern void annotate_all_with_locus (tree *, location_t);
underlying nodes are also of the right form. */
/* Returns true iff T is a valid GIMPLE statement. */
bool is_gimple_stmt (tree);
extern bool is_gimple_stmt (tree);
/* Returns true iff TYPE is a valid type for a scalar register variable. */
bool is_gimple_reg_type (tree);
extern bool is_gimple_reg_type (tree);
/* Returns true iff T is a scalar register variable. */
bool is_gimple_reg (tree);
extern bool is_gimple_reg (tree);
/* Returns true iff T is any sort of variable. */
bool is_gimple_variable (tree);
extern bool is_gimple_variable (tree);
/* Returns true iff T is a variable or an INDIRECT_REF (of a variable). */
bool is_gimple_min_lval (tree);
extern bool is_gimple_min_lval (tree);
/* Returns true iff T is an lvalue other than an INDIRECT_REF. */
bool is_gimple_addr_expr_arg (tree);
extern bool is_gimple_addr_expr_arg (tree);
/* Returns true iff T is any valid GIMPLE lvalue. */
bool is_gimple_lvalue (tree);
extern bool is_gimple_lvalue (tree);
/* Returns true iff T is a GIMPLE restricted function invariant. */
bool is_gimple_min_invariant (tree);
extern bool is_gimple_min_invariant (tree);
/* Returns true iff T is a GIMPLE rvalue. */
bool is_gimple_val (tree);
extern bool is_gimple_val (tree);
/* Returns true iff T is a valid rhs for a MODIFY_EXPR. */
bool is_gimple_rhs (tree);
extern bool is_gimple_rhs (tree);
/* Returns true iff T is a valid if-statement condition. */
bool is_gimple_condexpr (tree);
extern bool is_gimple_condexpr (tree);
/* Returns true iff T is a type conversion. */
bool is_gimple_cast (tree);
extern bool is_gimple_cast (tree);
/* Returns true iff T is a valid CONSTRUCTOR element (either an rvalue or
another CONSTRUCTOR). */
bool is_gimple_constructor_elt (tree);
extern bool is_gimple_constructor_elt (tree);
/* Returns true iff T is a variable that does not need to live in memory. */
bool is_gimple_non_addressable (tree t);
extern bool is_gimple_non_addressable (tree t);
/* If T makes a function call, returns the CALL_EXPR operand. */
tree get_call_expr_in (tree t);
extern tree get_call_expr_in (tree t);
void recalculate_side_effects (tree);
extern void recalculate_side_effects (tree);
void append_to_compound_expr (tree, tree *);
extern void append_to_compound_expr (tree, tree *);
/* FIXME we should deduce this from the predicate. */
typedef enum fallback_t {
@ -98,29 +98,31 @@ enum gimplify_status {
GS_ALL_DONE = 1 /* The expression is fully gimplified. */
};
enum gimplify_status gimplify_expr (tree *, tree *, tree *,
bool (*) (tree), fallback_t);
void gimplify_stmt (tree *);
void gimplify_to_stmt_list (tree *);
void gimplify_body (tree *, tree);
void push_gimplify_context (void);
void pop_gimplify_context (tree);
void gimplify_and_add (tree, tree *);
extern enum gimplify_status gimplify_expr (tree *, tree *, tree *,
bool (*) (tree), fallback_t);
extern tree gimplify_type_sizes (tree);
extern void gimplify_one_sizepos (tree *, tree *);
extern void gimplify_stmt (tree *);
extern void gimplify_to_stmt_list (tree *);
extern void gimplify_body (tree *, tree);
extern void push_gimplify_context (void);
extern void pop_gimplify_context (tree);
extern void gimplify_and_add (tree, tree *);
/* Miscellaneous helpers. */
tree get_base_address (tree t);
void gimple_add_tmp_var (tree);
tree gimple_current_bind_expr (void);
void gimple_push_bind_expr (tree);
void gimple_pop_bind_expr (void);
void unshare_all_trees (tree);
tree voidify_wrapper_expr (tree, tree);
tree gimple_build_eh_filter (tree, tree, tree);
tree build_and_jump (tree *);
tree alloc_stmt_list (void);
void free_stmt_list (tree);
tree force_labels_r (tree *, int *, void *);
enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *);
extern tree get_base_address (tree t);
extern void gimple_add_tmp_var (tree);
extern tree gimple_current_bind_expr (void);
extern void gimple_push_bind_expr (tree);
extern void gimple_pop_bind_expr (void);
extern void unshare_all_trees (tree);
extern tree voidify_wrapper_expr (tree, tree);
extern tree gimple_build_eh_filter (tree, tree, tree);
extern tree build_and_jump (tree *);
extern tree alloc_stmt_list (void);
extern void free_stmt_list (tree);
extern tree force_labels_r (tree *, int *, void *);
extern enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *);
/* In tree-nested.c. */
extern void lower_nested_functions (tree);

View file

@ -2054,8 +2054,14 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
}
#endif
}
else if (TREE_CODE_CLASS (code) == 'd')
/* Look inside the sizes of decls, but we don't ever use the values for
FIELD_DECL and RESULT_DECL, so ignore them. */
else if (TREE_CODE_CLASS (code) == 'd'
&& code != FIELD_DECL && code != RESULT_DECL)
{
WALK_SUBTREE (DECL_SIZE (*tp));
WALK_SUBTREE (DECL_SIZE_UNIT (*tp));
WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
}
else
@ -2077,23 +2083,20 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
case REAL_CST:
case VECTOR_CST:
case STRING_CST:
case REAL_TYPE:
case COMPLEX_TYPE:
case VECTOR_TYPE:
case VOID_TYPE:
case BOOLEAN_TYPE:
case UNION_TYPE:
case ENUMERAL_TYPE:
case BLOCK:
case RECORD_TYPE:
case PLACEHOLDER_EXPR:
case SSA_NAME:
case FIELD_DECL:
case RESULT_DECL:
/* None of thse have subtrees other than those already walked
above. */
break;
case POINTER_TYPE:
case REFERENCE_TYPE:
case COMPLEX_TYPE:
WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
break;
@ -2126,6 +2129,7 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
case METHOD_TYPE:
WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
/* Fall through. */
case FUNCTION_TYPE:
@ -2139,12 +2143,43 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
}
break;
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
{
tree field;
for (field = TYPE_FIELDS (*tp); field; field = TREE_CHAIN (field))
{
/* We would like to look at the type of the field, but we
can easily get infinite recursion. So assume it's
pointed to elsewhere in the tree. Also, ignore things that
aren't fields. */
if (TREE_CODE (field) != FIELD_DECL)
continue;
WALK_SUBTREE (DECL_FIELD_OFFSET (field));
WALK_SUBTREE (DECL_SIZE (field));
WALK_SUBTREE (DECL_SIZE_UNIT (field));
if (code == QUAL_UNION_TYPE)
WALK_SUBTREE (DECL_QUALIFIER (field));
}
}
break;
case ARRAY_TYPE:
WALK_SUBTREE (TREE_TYPE (*tp));
/* Don't follow this nodes's type if a pointer for fear that we'll
have infinite recursion. Those types are uninteresting anyway. */
if (!POINTER_TYPE_P (TREE_TYPE (*tp))
&& TREE_CODE (TREE_TYPE (*tp)) != OFFSET_TYPE)
WALK_SUBTREE (TREE_TYPE (*tp));
WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
case BOOLEAN_TYPE:
case ENUMERAL_TYPE:
case INTEGER_TYPE:
case CHAR_TYPE:
case REAL_TYPE:
WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
@ -2166,8 +2201,8 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
/* Walk the DECL_INITIAL and DECL_SIZE. We don't want to walk
into declarations that are just mentioned, rather than
declared; they don't really belong to this part of the tree.
And, we can see cycles: the initializer for a declaration can
refer to the declaration itself. */
And, we can see cycles: the initializer for a declaration
can refer to the declaration itself. */
WALK_SUBTREE (DECL_INITIAL (decl));
WALK_SUBTREE (DECL_SIZE (decl));
WALK_SUBTREE (DECL_SIZE_UNIT (decl));
@ -2185,7 +2220,9 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
break;
default:
abort ();
/* ??? This could be a language-defined node. We really should make
a hook for it, but right now just ignore it. */
break;
}
}

View file

@ -463,7 +463,7 @@ mf_build_check_statement_for (tree addr, tree size,
(flag_mudflap_threads ? mf_cache_mask_decl : mf_cache_mask_decl_l));
t = build (ARRAY_REF,
TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
mf_cache_array_decl, t);
mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
t = build (MODIFY_EXPR, void_type_node, mf_elem, t);
SET_EXPR_LOCUS (t, locus);
@ -487,7 +487,7 @@ mf_build_check_statement_for (tree addr, tree size,
/* Construct t <-- '__mf_elem->low > __mf_base'. */
t = build (COMPONENT_REF, mf_uintptr_type,
build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
TYPE_FIELDS (mf_cache_struct_type));
TYPE_FIELDS (mf_cache_struct_type), NULL_TREE);
t = build (GT_EXPR, boolean_type_node, t, mf_base);
/* Construct '__mf_elem->high < __mf_base + sizeof(T) - 1'.
@ -501,7 +501,7 @@ mf_build_check_statement_for (tree addr, tree size,
u = build (COMPONENT_REF, mf_uintptr_type,
build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)));
TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE);
v = convert (mf_uintptr_type,
size_binop (MINUS_EXPR, size, size_one_node));
@ -660,14 +660,14 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp,
things the hard way with PLUS. */
if (DECL_BIT_FIELD_TYPE (field))
{
size = bitsize_int (BITS_PER_UNIT);
size = size_binop (CEIL_DIV_EXPR, DECL_SIZE (field), size);
size = convert (sizetype, size);
if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST)
size = DECL_SIZE_UNIT (field);
addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
addr = convert (ptr_type_node, addr);
addr = fold_convert (ptr_type_node, addr);
addr = fold (build (PLUS_EXPR, ptr_type_node,
addr, byte_position (field)));
addr, fold_convert (ptr_type_node,
byte_position (field))));
}
else
{

View file

@ -157,8 +157,13 @@ static tree
build_addr (tree exp)
{
tree base = exp;
while (TREE_CODE (base) == COMPONENT_REF || TREE_CODE (base) == ARRAY_REF)
if (TREE_CODE (base) == REALPART_EXPR || TREE_CODE (base) == IMAGPART_EXPR)
base = TREE_OPERAND (base, 0);
else
while (handled_component_p (base))
base = TREE_OPERAND (base, 0);
if (DECL_P (base))
TREE_ADDRESSABLE (base) = 1;
@ -550,6 +555,7 @@ walk_stmts (struct walk_stmt_info *wi, tree *tp)
break;
case CATCH_EXPR:
walk_stmts (wi, &CATCH_BODY (t));
break;
case EH_FILTER_EXPR:
walk_stmts (wi, &EH_FILTER_FAILURE (t));
break;
@ -657,7 +663,7 @@ get_static_chain (struct nesting_info *info, tree target_context,
tree field = get_chain_field (i);
x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
x = build (COMPONENT_REF, TREE_TYPE (field), x, field);
x = build (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
x = init_tmp_var (info, x, tsi);
}
}
@ -691,14 +697,14 @@ get_frame_field (struct nesting_info *info, tree target_context,
tree field = get_chain_field (i);
x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
x = build (COMPONENT_REF, TREE_TYPE (field), x, field);
x = build (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
x = init_tmp_var (info, x, tsi);
}
x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
}
x = build (COMPONENT_REF, TREE_TYPE (field), x, field);
x = build (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
return x;
}
@ -800,10 +806,13 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
break;
case ARRAY_REF:
case ARRAY_RANGE_REF:
wi->val_only = false;
walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL);
wi->val_only = true;
walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference, wi, NULL);
walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi, NULL);
walk_tree (&TREE_OPERAND (t, 3), convert_nonlocal_reference, wi, NULL);
break;
case BIT_FIELD_REF:
@ -932,10 +941,13 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
break;
case ARRAY_REF:
case ARRAY_RANGE_REF:
wi->val_only = false;
walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL);
wi->val_only = true;
walk_tree (&TREE_OPERAND (t, 1), convert_local_reference, wi, NULL);
walk_tree (&TREE_OPERAND (t, 2), convert_local_reference, wi, NULL);
walk_tree (&TREE_OPERAND (t, 3), convert_local_reference, wi, NULL);
break;
case BIT_FIELD_REF:
@ -1242,7 +1254,7 @@ finalize_nesting_tree_1 (struct nesting_info *root)
x = p;
y = build (COMPONENT_REF, TREE_TYPE (field),
root->frame_decl, field);
root->frame_decl, field, NULL_TREE);
x = build (MODIFY_EXPR, TREE_TYPE (field), y, x);
append_to_statement_list (x, &stmt_list);
}
@ -1252,9 +1264,8 @@ finalize_nesting_tree_1 (struct nesting_info *root)
from chain_decl. */
if (root->chain_field)
{
tree x;
x = build (COMPONENT_REF, TREE_TYPE (root->chain_field),
root->frame_decl, root->chain_field);
tree x = build (COMPONENT_REF, TREE_TYPE (root->chain_field),
root->frame_decl, root->chain_field, NULL_TREE);
x = build (MODIFY_EXPR, TREE_TYPE (x), x, get_chain_decl (root));
append_to_statement_list (x, &stmt_list);
}
@ -1281,7 +1292,7 @@ finalize_nesting_tree_1 (struct nesting_info *root)
arg = tree_cons (NULL, x, arg);
x = build (COMPONENT_REF, TREE_TYPE (field),
root->frame_decl, field);
root->frame_decl, field, NULL_TREE);
x = build_addr (x);
arg = tree_cons (NULL, x, arg);

View file

@ -1763,17 +1763,20 @@ discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees,
if (TYPE_P (t) || DECL_P (t))
*walk_subtrees = 0;
else if (TREE_CODE (t) == ARRAY_REF)
else if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
{
while ((TREE_CODE (t) == ARRAY_REF
while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
&& is_gimple_min_invariant (TREE_OPERAND (t, 1)))
|| (TREE_CODE (t) == COMPONENT_REF
|| TREE_CODE (t) == BIT_FIELD_REF
|| TREE_CODE (t) == REALPART_EXPR
|| TREE_CODE (t) == IMAGPART_EXPR))
|| TREE_CODE (t) == IMAGPART_EXPR
|| TREE_CODE (t) == VIEW_CONVERT_EXPR
|| TREE_CODE (t) == NOP_EXPR
|| TREE_CODE (t) == CONVERT_EXPR))
t = TREE_OPERAND (t, 0);
if (TREE_CODE (t) == ARRAY_REF)
if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
{
t = get_base_address (t);
if (t && DECL_P (t))

View file

@ -392,6 +392,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
/* Print the name of the structure. */
if (TREE_CODE (node) == RECORD_TYPE)
pp_string (buffer, "struct ");
@ -404,11 +405,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
print_struct_decl (buffer, node, spc, flags);
break;
case QUAL_UNION_TYPE:
NIY;
break;
case LANG_TYPE:
NIY;
break;
@ -598,6 +594,14 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
pp_character (buffer, ')');
pp_string (buffer, str);
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
if (TREE_OPERAND (node, 2)
&& TREE_CODE (TREE_OPERAND (node, 2)) != INTEGER_CST)
{
pp_string (buffer, "{off: ");
dump_generic_node (buffer, TREE_OPERAND (node, 2),
spc, flags, false);
pp_character (buffer, '}');
}
break;
case BIT_FIELD_REF:
@ -615,6 +619,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
break;
case ARRAY_REF:
case ARRAY_RANGE_REF:
op0 = TREE_OPERAND (node, 0);
if (op_prio (op0) < op_prio (node))
pp_character (buffer, '(');
@ -623,11 +628,23 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
pp_character (buffer, ')');
pp_character (buffer, '[');
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
if (TREE_CODE (node) == ARRAY_RANGE_REF)
pp_string (buffer, " ...");
pp_character (buffer, ']');
break;
case ARRAY_RANGE_REF:
NIY;
if ((TREE_OPERAND (node, 2)
&& TREE_CODE (TREE_OPERAND (node, 2)) != INTEGER_CST)
|| (TREE_OPERAND (node, 3)
&& TREE_CODE (TREE_OPERAND (node, 3)) != INTEGER_CST))
{
pp_string (buffer, "{lb: ");
dump_generic_node (buffer, TREE_OPERAND (node, 2),
spc, flags, false);
pp_string (buffer, " sz: ");
dump_generic_node (buffer, TREE_OPERAND (node, 3),
spc, flags, false);
pp_character (buffer, '}');
}
break;
case CONSTRUCTOR:
@ -1490,10 +1507,10 @@ print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
INDENT (spc);
if (TREE_CODE (node) == RECORD_TYPE)
pp_string (buffer, "struct ");
else if (TREE_CODE (node) == UNION_TYPE)
else if ((TREE_CODE (node) == UNION_TYPE
|| TREE_CODE (node) == QUAL_UNION_TYPE))
pp_string (buffer, "union ");
else
NIY;
dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
}
@ -1515,8 +1532,8 @@ print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
Maybe this could be solved by looking at the scope in which the
structure was declared. */
if (TREE_TYPE (tmp) != node
|| (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE &&
TREE_TYPE (TREE_TYPE (tmp)) != node))
|| (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
&& TREE_TYPE (TREE_TYPE (tmp)) != node))
{
print_declaration (buffer, tmp, spc+2, flags);
pp_newline (buffer);
@ -1656,6 +1673,7 @@ op_prio (tree op)
case CALL_EXPR:
case ARRAY_REF:
case ARRAY_RANGE_REF:
case COMPONENT_REF:
return 15;

View file

@ -621,7 +621,7 @@ csc_build_component_ref (tree base, tree field)
break;
}
return build (COMPONENT_REF, TREE_TYPE (field), base, field);
return build (COMPONENT_REF, TREE_TYPE (field), base, field, NULL_TREE);
}
/* Similarly for REALPART_EXPR and IMAGPART_EXPR for complex types. */
@ -1011,7 +1011,7 @@ scalarize_call_expr (block_stmt_iterator *si_p)
/* Scalarize the return value, if any. */
if (TREE_CODE (stmt) == MODIFY_EXPR)
{
tree var = TREE_OPERAND (stmt, 0);
tree var = get_base_address (TREE_OPERAND (stmt, 0));
/* If the LHS of the assignment is a scalarizable structure, insert
copies into the scalar replacements after the call. */

View file

@ -1041,40 +1041,43 @@ dump_lattice_value (FILE *outf, const char *prefix, value val)
tree
widen_bitfield (tree val, tree field, tree var)
{
unsigned var_size, field_size;
unsigned HOST_WIDE_INT var_size, field_size;
tree wide_val;
unsigned HOST_WIDE_INT mask;
unsigned i;
unsigned int i;
var_size = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE ((var))));
field_size = TREE_INT_CST_LOW (DECL_SIZE (field));
/* We can only do this if the size of the type and field and VAL are
all constants representable in HOST_WIDE_INT. */
if (!host_integerp (TYPE_SIZE (TREE_TYPE (var)), 1)
|| !host_integerp (DECL_SIZE (field), 1)
|| !host_integerp (val, 0))
return NULL_TREE;
var_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (var)), 1);
field_size = tree_low_cst (DECL_SIZE (field), 1);
/* Give up if either the bitfield or the variable are too wide. */
if (field_size > HOST_BITS_PER_WIDE_INT || var_size > HOST_BITS_PER_WIDE_INT)
return NULL;
return NULL_TREE;
#if defined ENABLE_CHECKING
if (var_size < field_size)
abort ();
#endif
/* If VAL is not an integer constant, then give up. */
if (TREE_CODE (val) != INTEGER_CST)
return NULL;
/* If the sign bit of the value is not set, or the field's type is
unsigned, then just mask off the high order bits of the value. */
if ((TREE_INT_CST_LOW (val) & (1 << (field_size - 1))) == 0
|| DECL_UNSIGNED (field))
/* If the sign bit of the value is not set or the field's type is unsigned,
just mask off the high order bits of the value. */
if (DECL_UNSIGNED (field)
|| !(tree_low_cst (val, 0) & (((HOST_WIDE_INT)1) << (field_size - 1))))
{
/* Zero extension. Build a mask with the lower 'field_size' bits
set and a BIT_AND_EXPR node to clear the high order bits of
the value. */
for (i = 0, mask = 0; i < field_size; i++)
mask |= 1 << i;
mask |= ((HOST_WIDE_INT) 1) << i;
wide_val = build (BIT_AND_EXPR, TREE_TYPE (var), val,
build_int_2 (mask, 0));
fold_convert (TREE_TYPE (var), build_int_2 (mask, 0)));
}
else
{
@ -1082,10 +1085,10 @@ widen_bitfield (tree val, tree field, tree var)
bits set and a BIT_IOR_EXPR to set the high order bits of the
value. */
for (i = 0, mask = 0; i < (var_size - field_size); i++)
mask |= 1 << (var_size - i - 1);
mask |= ((HOST_WIDE_INT) 1) << (var_size - i - 1);
wide_val = build (BIT_IOR_EXPR, TREE_TYPE (var), val,
build_int_2 (mask, 0));
fold_convert (TREE_TYPE (var), build_int_2 (mask, 0)));
}
return fold (wide_val);
@ -1493,10 +1496,26 @@ likely_value (tree stmt)
static tree
maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
{
unsigned HOST_WIDE_INT lquo, lrem;
HOST_WIDE_INT hquo, hrem;
tree elt_size, min_idx, idx;
tree array_type, elt_type;
tree min_idx, idx, elt_offset = integer_zero_node;
tree array_type, elt_type, elt_size;
/* If BASE is an ARRAY_REF, we can pick up another offset (this time
measured in units of the size of elements type) from that ARRAY_REF).
We can't do anything if either is variable.
The case we handle here is *(&A[N]+O). */
if (TREE_CODE (base) == ARRAY_REF)
{
tree low_bound = array_ref_low_bound (base);
elt_offset = TREE_OPERAND (base, 1);
if (TREE_CODE (low_bound) != INTEGER_CST
|| TREE_CODE (elt_offset) != INTEGER_CST)
return NULL_TREE;
elt_offset = int_const_binop (MINUS_EXPR, elt_offset, low_bound, 0);
base = TREE_OPERAND (base, 0);
}
/* Ignore stupid user tricks of indexing non-array variables. */
array_type = TREE_TYPE (base);
@ -1506,37 +1525,62 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
if (!lang_hooks.types_compatible_p (orig_type, elt_type))
return NULL_TREE;
/* Whee. Ignore indexing of variable sized types. */
/* If OFFSET and ELT_OFFSET are zero, we don't care about the size of the
element type (so we can use the alignment if it's not constant).
Otherwise, compute the offset as an index by using a division. If the
division isn't exact, then don't do anything. */
elt_size = TYPE_SIZE_UNIT (elt_type);
if (TREE_CODE (elt_size) != INTEGER_CST)
return NULL_TREE;
/* If the division isn't exact, then don't do anything. Equally
invalid as the above indexing of non-array variables. */
if (div_and_round_double (TRUNC_DIV_EXPR, 1,
TREE_INT_CST_LOW (offset),
TREE_INT_CST_HIGH (offset),
TREE_INT_CST_LOW (elt_size),
TREE_INT_CST_HIGH (elt_size),
&lquo, &hquo, &lrem, &hrem)
|| lrem || hrem)
return NULL_TREE;
idx = build_int_2_wide (lquo, hquo);
/* Re-bias the index by the min index of the array type. */
min_idx = TYPE_DOMAIN (TREE_TYPE (base));
if (min_idx)
if (integer_zerop (offset))
{
min_idx = TYPE_MIN_VALUE (min_idx);
if (min_idx)
{
idx = convert (TREE_TYPE (min_idx), idx);
if (!integer_zerop (min_idx))
idx = int_const_binop (PLUS_EXPR, idx, min_idx, 1);
}
if (TREE_CODE (elt_size) != INTEGER_CST)
elt_size = size_int (TYPE_ALIGN (elt_type));
idx = integer_zero_node;
}
else
{
unsigned HOST_WIDE_INT lquo, lrem;
HOST_WIDE_INT hquo, hrem;
if (TREE_CODE (elt_size) != INTEGER_CST
|| div_and_round_double (TRUNC_DIV_EXPR, 1,
TREE_INT_CST_LOW (offset),
TREE_INT_CST_HIGH (offset),
TREE_INT_CST_LOW (elt_size),
TREE_INT_CST_HIGH (elt_size),
&lquo, &hquo, &lrem, &hrem)
|| lrem || hrem)
return NULL_TREE;
idx = build_int_2_wide (lquo, hquo);
}
return build (ARRAY_REF, orig_type, base, idx);
/* Assume the low bound is zero. If there is a domain type, get the
low bound, if any, convert the index into that type, and add the
low bound. */
min_idx = integer_zero_node;
if (TYPE_DOMAIN (array_type))
{
if (TYPE_MIN_VALUE (TYPE_DOMAIN (array_type)))
min_idx = TYPE_MIN_VALUE (TYPE_DOMAIN (array_type));
else
min_idx = fold_convert (TYPE_DOMAIN (array_type), min_idx);
if (TREE_CODE (min_idx) != INTEGER_CST)
return NULL_TREE;
idx = fold_convert (TYPE_DOMAIN (array_type), idx);
elt_offset = fold_convert (TYPE_DOMAIN (array_type), elt_offset);
}
if (!integer_zerop (min_idx))
idx = int_const_binop (PLUS_EXPR, idx, min_idx, 0);
if (!integer_zerop (elt_offset))
idx = int_const_binop (PLUS_EXPR, idx, elt_offset, 0);
return build (ARRAY_REF, orig_type, base, idx, min_idx,
size_int (tree_low_cst (elt_size, 1)
/ (TYPE_ALIGN (elt_type) / BITS_PER_UNIT)));
}
/* A subroutine of fold_stmt_r. Attempts to fold *(S+O) to S.X.
@ -1617,7 +1661,7 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset,
{
if (base_is_ptr)
base = build1 (INDIRECT_REF, record_type, base);
t = build (COMPONENT_REF, field_type, base, f);
t = build (COMPONENT_REF, field_type, base, f, NULL_TREE);
return t;
}
@ -1639,7 +1683,7 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset,
nonzero offset into them. Recurse and hope for a valid match. */
if (base_is_ptr)
base = build1 (INDIRECT_REF, record_type, base);
base = build (COMPONENT_REF, field_type, base, f);
base = build (COMPONENT_REF, field_type, base, f, NULL_TREE);
t = maybe_fold_offset_to_array_ref (base, offset, orig_type);
if (t)
@ -1697,8 +1741,12 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
if (t)
return t;
/* Fold *&B to B. */
if (integer_zerop (offset))
/* Fold *&B to B. We can only do this if EXPR is the same type
as BASE. We can't do this if EXPR is the element type of an array
and BASE is the array. */
if (integer_zerop (offset)
&& lang_hooks.types_compatible_p (TREE_TYPE (base),
TREE_TYPE (expr)))
return base;
}
else
@ -1803,6 +1851,9 @@ maybe_fold_stmt_addition (tree expr)
min_idx = TYPE_MIN_VALUE (min_idx);
if (min_idx)
{
if (TREE_CODE (min_idx) != INTEGER_CST)
break;
array_idx = convert (TREE_TYPE (min_idx), array_idx);
if (!integer_zerop (min_idx))
array_idx = int_const_binop (MINUS_EXPR, array_idx,

View file

@ -897,30 +897,18 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops)
code = TREE_CODE (expr);
class = TREE_CODE_CLASS (code);
/* Expressions that make no memory references. */
if (class == 'c'
|| class == 't'
|| code == BLOCK
|| code == FUNCTION_DECL
|| code == EXC_PTR_EXPR
|| code == FILTER_EXPR
|| code == LABEL_DECL)
return;
/* We could have the address of a component, array member, etc which
has interesting variable references. */
if (code == ADDR_EXPR)
{
enum tree_code subcode = TREE_CODE (TREE_OPERAND (expr, 0));
/* Taking the address of a variable does not represent a
reference to it, but the fact that STMT takes its address will be
of interest to some passes (e.g. alias resolution). */
add_stmt_operand (expr_p, stmt, 0, NULL);
/* If the address is invariant, there may be no interesting variable
references inside. */
if (is_gimple_min_invariant (expr))
/* If the address is constant (invariant is not sufficient), there will
be no interesting variable references inside. */
if (TREE_CONSTANT (expr))
return;
/* There should be no VUSEs created, since the referenced objects are
@ -930,12 +918,22 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops)
flags |= opf_no_vops;
/* Avoid recursion. */
code = subcode;
class = TREE_CODE_CLASS (code);
expr_p = &TREE_OPERAND (expr, 0);
expr = *expr_p;
code = TREE_CODE (expr);
class = TREE_CODE_CLASS (code);
}
/* Expressions that make no memory references. */
if (class == 'c'
|| class == 't'
|| code == BLOCK
|| code == FUNCTION_DECL
|| code == EXC_PTR_EXPR
|| code == FILTER_EXPR
|| code == LABEL_DECL)
return;
/* If we found a variable, add it to DEFS or USES depending on the
operand flags. */
if (SSA_VAR_P (expr))
@ -1043,7 +1041,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops)
/* Treat array references as references to the virtual variable
representing the array. The virtual variable for an ARRAY_REF
is the VAR_DECL for the array. */
if (code == ARRAY_REF)
if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
{
/* Add the virtual variable for the ARRAY_REF to VDEFS or VUSES
according to the value of IS_DEF. Recurse if the LHS of the
@ -1054,6 +1052,8 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops)
get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags, prev_vops);
get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none, prev_vops);
get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none, prev_vops);
get_expr_operands (stmt, &TREE_OPERAND (expr, 3), opf_none, prev_vops);
return;
}
@ -1078,6 +1078,8 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops)
else
get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags, prev_vops);
if (code == COMPONENT_REF)
get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none, prev_vops);
return;
}

View file

@ -473,20 +473,11 @@ set_is_used (tree t)
if (SSA_VAR_P (t))
break;
switch (TREE_CODE (t))
{
case ARRAY_REF:
case COMPONENT_REF:
case REALPART_EXPR:
case IMAGPART_EXPR:
case BIT_FIELD_REF:
case INDIRECT_REF:
if (TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR)
t = TREE_OPERAND (t, 0);
else
while (handled_component_p (t))
t = TREE_OPERAND (t, 0);
break;
default:
return;
}
}
if (TREE_CODE (t) == SSA_NAME)

View file

@ -1927,7 +1927,8 @@ substitute_in_expr (tree exp, tree f, tree r)
if (op0 == TREE_OPERAND (exp, 0))
return exp;
new = fold (build2 (code, TREE_TYPE (exp), op0, TREE_OPERAND (exp, 1)));
new = fold (build (code, TREE_TYPE (exp), op0, TREE_OPERAND (exp, 1),
NULL_TREE));
}
else
switch (TREE_CODE_CLASS (code))
@ -2157,7 +2158,7 @@ stabilize_reference (tree ref)
case COMPONENT_REF:
result = build_nt (COMPONENT_REF,
stabilize_reference (TREE_OPERAND (ref, 0)),
TREE_OPERAND (ref, 1));
TREE_OPERAND (ref, 1), NULL_TREE);
break;
case BIT_FIELD_REF:
@ -2170,13 +2171,15 @@ stabilize_reference (tree ref)
case ARRAY_REF:
result = build_nt (ARRAY_REF,
stabilize_reference (TREE_OPERAND (ref, 0)),
stabilize_reference_1 (TREE_OPERAND (ref, 1)));
stabilize_reference_1 (TREE_OPERAND (ref, 1)),
TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3));
break;
case ARRAY_RANGE_REF:
result = build_nt (ARRAY_RANGE_REF,
stabilize_reference (TREE_OPERAND (ref, 0)),
stabilize_reference_1 (TREE_OPERAND (ref, 1)));
stabilize_reference_1 (TREE_OPERAND (ref, 1)),
TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3));
break;
case COMPOUND_EXPR:
@ -2292,41 +2295,77 @@ stabilize_reference_1 (tree e)
/* Low-level constructors for expressions. */
/* A helper function for build1 and constant folders.
Set TREE_CONSTANT and TREE_INVARIANT for an ADDR_EXPR. */
/* A helper function for build1 and constant folders. Set TREE_CONSTANT,
TREE_INVARIANT, and TREE_SIDE_EFFECTS for an ADDR_EXPR. */
void
recompute_tree_invarant_for_addr_expr (tree t)
{
tree node = TREE_OPERAND (t, 0);
bool tc = false, ti = false;
tree node;
bool tc = true, ti = true, se = false;
/* Addresses of constants and static variables are constant;
all other decl addresses are invariant. */
if (staticp (node))
tc = ti = true;
/* We started out assuming this address is both invariant and constant, but
does not have side effects. Now go down any handled components and see if
any of them involve offsets that are either non-constant or non-invariant.
Also check for side-effects.
??? Note that this code makes no attempt to deal with the case where
taking the address of something causes a copy due to misalignment. */
#define UPDATE_TITCSE(NODE) \
do { tree _node = (NODE); \
if (_node && !TREE_INVARIANT (_node)) ti = false; \
if (_node && !TREE_CONSTANT (_node)) tc = false; \
if (_node && TREE_SIDE_EFFECTS (_node)) se = true; } while (0)
for (node = TREE_OPERAND (t, 0); handled_component_p (node);
node = TREE_OPERAND (node, 0))
{
/* If the first operand doesn't have an ARRAY_TYPE, this is a bogus
array reference (probably made temporarily by the G++ front end),
so ignore all the operands. */
if ((TREE_CODE (node) == ARRAY_REF
|| TREE_CODE (node) == ARRAY_RANGE_REF)
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (node, 0))) == ARRAY_TYPE)
{
UPDATE_TITCSE (TREE_OPERAND (node, 1));
UPDATE_TITCSE (array_ref_low_bound (node));
UPDATE_TITCSE (array_ref_element_size (node));
}
/* Likewise, just because this is a COMPONENT_REF doesn't mean we have a
FIELD_DECL, apparently. The G++ front end can put something else
there, at least temporarily. */
else if (TREE_CODE (node) == COMPONENT_REF
&& TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL)
UPDATE_TITCSE (component_ref_field_offset (node));
else if (TREE_CODE (node) == BIT_FIELD_REF)
UPDATE_TITCSE (TREE_OPERAND (node, 2));
}
/* Now see what's inside. If it's an INDIRECT_REF, copy our properties from
it. If it's a decl, it's definitely invariant and it's constant if the
decl is static. (Taking the address of a volatile variable is not
volatile.) If it's a constant, the address is both invariant and
constant. Otherwise it's neither. */
if (TREE_CODE (node) == INDIRECT_REF)
UPDATE_TITCSE (node);
else if (DECL_P (node))
{
if (!staticp (node))
tc = false;
}
else if (TREE_CODE_CLASS (TREE_CODE (node)) == 'c')
;
else
{
/* Step past constant offsets. */
while (1)
{
if (TREE_CODE (node) == COMPONENT_REF
&& TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL
&& ! DECL_BIT_FIELD (TREE_OPERAND (node, 1)))
;
else if (TREE_CODE (node) == ARRAY_REF
&& TREE_CONSTANT (TREE_OPERAND (node, 1)))
;
else
break;
node = TREE_OPERAND (node, 0);
}
if (DECL_P (node))
ti = true;
ti = tc = false;
se |= TREE_SIDE_EFFECTS (node);
}
TREE_CONSTANT (t) = tc;
TREE_INVARIANT (t) = ti;
TREE_SIDE_EFFECTS (t) = se;
#undef UPDATE_TITCSE
}
/* Build an expression of code CODE, data type TYPE, and operands as
@ -2429,27 +2468,7 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
case ADDR_EXPR:
if (node)
{
recompute_tree_invarant_for_addr_expr (t);
/* The address of a volatile decl or reference does not have
side-effects. But be careful not to ignore side-effects from
other sources deeper in the expression--if node is a _REF and
one of its operands has side-effects, so do we. */
if (TREE_THIS_VOLATILE (node))
{
TREE_SIDE_EFFECTS (t) = 0;
if (!DECL_P (node))
{
int i = first_rtl_op (TREE_CODE (node)) - 1;
for (; i >= 0; --i)
{
if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, i)))
TREE_SIDE_EFFECTS (t) = 1;
}
}
}
}
recompute_tree_invarant_for_addr_expr (t);
break;
default:
@ -2516,6 +2535,8 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
TREE_CONSTANT (t) = constant;
TREE_INVARIANT (t) = invariant;
TREE_SIDE_EFFECTS (t) = side_effects;
TREE_THIS_VOLATILE (t)
= TREE_CODE_CLASS (code) == 'r' && arg0 && TREE_THIS_VOLATILE (arg0);
return t;
}
@ -2565,6 +2586,8 @@ build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
}
TREE_SIDE_EFFECTS (t) = side_effects;
TREE_THIS_VOLATILE (t)
= TREE_CODE_CLASS (code) == 'r' && arg0 && TREE_THIS_VOLATILE (arg0);
return t;
}
@ -2595,6 +2618,8 @@ build4_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
PROCESS_ARG(3);
TREE_SIDE_EFFECTS (t) = side_effects;
TREE_THIS_VOLATILE (t)
= TREE_CODE_CLASS (code) == 'r' && arg0 && TREE_THIS_VOLATILE (arg0);
return t;
}
@ -4457,8 +4482,8 @@ get_unwidened (tree op, tree for_type)
&& (for_type || ! DECL_BIT_FIELD (TREE_OPERAND (op, 1)))
&& (! uns || final_prec <= innerprec || unsignedp))
{
win = build2 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
TREE_OPERAND (op, 1));
win = build3 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
TREE_OPERAND (op, 1), NULL_TREE);
TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
}
@ -4523,7 +4548,8 @@ get_narrower (tree op, int *unsignedp_ptr)
/* Since type_for_size always gives an integer type. */
&& TREE_CODE (TREE_TYPE (op)) != REAL_TYPE
/* Ensure field is laid out already. */
&& DECL_SIZE (TREE_OPERAND (op, 1)) != 0)
&& DECL_SIZE (TREE_OPERAND (op, 1)) != 0
&& host_integerp (DECL_SIZE (TREE_OPERAND (op, 1)), 1))
{
unsigned HOST_WIDE_INT innerprec
= tree_low_cst (DECL_SIZE (TREE_OPERAND (op, 1)), 1);
@ -4546,8 +4572,8 @@ get_narrower (tree op, int *unsignedp_ptr)
{
if (first)
uns = DECL_UNSIGNED (TREE_OPERAND (op, 1));
win = build2 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
TREE_OPERAND (op, 1));
win = build3 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
TREE_OPERAND (op, 1), NULL_TREE);
TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
}

View file

@ -354,9 +354,11 @@ DEFTREECODE (TRANSLATION_UNIT_DECL, "translation_unit_decl", 'd', 0)
/* References to storage. */
/* Value is structure or union component.
Operand 0 is the structure or union (an expression);
operand 1 is the field (a node of type FIELD_DECL). */
DEFTREECODE (COMPONENT_REF, "component_ref", 'r', 2)
Operand 0 is the structure or union (an expression).
Operand 1 is the field (a node of type FIELD_DECL).
Operand 2, if present, is the value of DECL_FIELD_OFFSET, measured
in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT. */
DEFTREECODE (COMPONENT_REF, "component_ref", 'r', 3)
/* Reference to a group of bits within an object. Similar to COMPONENT_REF
except the position is given explicitly rather than via a FIELD_DECL.
@ -374,13 +376,16 @@ DEFTREECODE (INDIRECT_REF, "indirect_ref", 'r', 1)
DEFTREECODE (BUFFER_REF, "buffer_ref", 'r', 1)
/* Array indexing.
Operand 0 is the array; operand 1 is a (single) array index. */
DEFTREECODE (ARRAY_REF, "array_ref", 'r', 2)
Operand 0 is the array; operand 1 is a (single) array index.
Operand 2, if present, is a copy of TYPE_MIN_VALUE of the index.
Operand 3, if present, is the element size, measured in units of
the alignment of the element type. */
DEFTREECODE (ARRAY_REF, "array_ref", 'r', 4)
/* Likewise, except that the result is a range ("slice") of the array. The
starting index of the resulting array is taken from operand 1 and the size
of the range is taken from the type of the expression. */
DEFTREECODE (ARRAY_RANGE_REF, "array_range_ref", 'r', 2)
DEFTREECODE (ARRAY_RANGE_REF, "array_range_ref", 'r', 4)
/* Vtable indexing. Carries data useful for emitting information
for vtable garbage collection.

View file

@ -3166,6 +3166,21 @@ extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
extern int handled_component_p (tree);
/* Return a tree of sizetype representing the size, in bytes, of the element
of EXP, an ARRAY_REF. */
extern tree array_ref_element_size (tree);
/* Return a tree representing the lower bound of the array mentioned in
EXP, an ARRAY_REF. */
extern tree array_ref_low_bound (tree);
/* Return a tree representing the offset, in bytes, of the field referenced
by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */
extern tree component_ref_field_offset (tree);
/* Given a DECL or TYPE, return the scope in which it was declared, or
NUL_TREE if there is no containing scope. */