8sa1-gcc/gcc/java/java-gimplify.c
Richard Kenner 44de5aeb00 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
2004-06-21 23:07:05 -04:00

283 lines
8.1 KiB
C

/* Java(TM) language-specific gimplification routines.
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Java and all Java-based marks are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other countries.
The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "java-tree.h"
#include "tree-dump.h"
#include "tree-gimple.h"
#include "toplev.h"
static tree java_gimplify_case_expr (tree);
static tree java_gimplify_default_expr (tree);
static tree java_gimplify_block (tree);
static tree java_gimplify_new_array_init (tree);
static tree java_gimplify_try_expr (tree);
static void dump_java_tree (enum tree_dump_index, tree);
/* Convert a Java tree to GENERIC. */
void
java_genericize (tree fndecl)
{
dump_java_tree (TDI_original, fndecl);
/* Genericize with the gimplifier. */
gimplify_function_tree (fndecl);
dump_function (TDI_generic, fndecl);
}
/* Gimplify a Java tree. */
int
java_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
tree *post_p ATTRIBUTE_UNUSED)
{
char code_class = TREE_CODE_CLASS(TREE_CODE (*expr_p));
/* Java insists on strict left-to-right evaluation of expressions.
A problem may arise if a variable used in the LHS of a binary
operation is altered by an assignment to that value in the RHS
before we've performed the operation. So, we always copy every
LHS to a temporary variable.
FIXME: Are there any other cases where we should do this?
Parameter lists, maybe? Or perhaps that's unnecessary because
the front end already generates SAVE_EXPRs. */
if (code_class == '2')
{
tree lhs = TREE_OPERAND (*expr_p, 0);
enum gimplify_status stat
= gimplify_expr (&lhs, pre_p, post_p, is_gimple_tmp_var, fb_rvalue);
if (stat == GS_ERROR)
return stat;
TREE_OPERAND (*expr_p, 0) = lhs;
}
switch (TREE_CODE (*expr_p))
{
case BLOCK:
*expr_p = java_gimplify_block (*expr_p);
break;
case EXPR_WITH_FILE_LOCATION:
input_location.file = EXPR_WFL_FILENAME (*expr_p);
input_location.line = EXPR_WFL_LINENO (*expr_p);
*expr_p = EXPR_WFL_NODE (*expr_p);
annotate_with_locus (*expr_p, input_location);
break;
case CASE_EXPR:
*expr_p = java_gimplify_case_expr (*expr_p);
break;
case DEFAULT_EXPR:
*expr_p = java_gimplify_default_expr (*expr_p);
break;
case NEW_ARRAY_INIT:
*expr_p = java_gimplify_new_array_init (*expr_p);
break;
case TRY_EXPR:
*expr_p = java_gimplify_try_expr (*expr_p);
break;
case JAVA_CATCH_EXPR:
*expr_p = TREE_OPERAND (*expr_p, 0);
break;
case JAVA_EXC_OBJ_EXPR:
*expr_p = build_exception_object_ref (TREE_TYPE (*expr_p));
break;
/* These should already be lowered before we get here. */
case URSHIFT_EXPR:
case COMPARE_EXPR:
case COMPARE_L_EXPR:
case COMPARE_G_EXPR:
case UNARY_PLUS_EXPR:
case NEW_ARRAY_EXPR:
case NEW_ANONYMOUS_ARRAY_EXPR:
case NEW_CLASS_EXPR:
case THIS_EXPR:
case SYNCHRONIZED_EXPR:
case CONDITIONAL_EXPR:
case INSTANCEOF_EXPR:
case CLASS_LITERAL:
abort ();
default:
return GS_UNHANDLED;
}
return GS_OK;
}
static tree
java_gimplify_case_expr (tree expr)
{
tree label = create_artificial_label ();
return build (CASE_LABEL_EXPR, void_type_node,
TREE_OPERAND (expr, 0), NULL_TREE, label);
}
static tree
java_gimplify_default_expr (tree expr ATTRIBUTE_UNUSED)
{
tree label = create_artificial_label ();
return build (CASE_LABEL_EXPR, void_type_node, NULL_TREE, NULL_TREE, label);
}
/* Gimplify BLOCK into a BIND_EXPR. */
static tree
java_gimplify_block (tree java_block)
{
tree decls = BLOCK_VARS (java_block);
tree body = BLOCK_EXPR_BODY (java_block);
tree outer = gimple_current_bind_expr ();
tree block;
/* Don't bother with empty blocks. */
if (! body)
return build_empty_stmt ();
if (IS_EMPTY_STMT (body))
return body;
/* Make a proper block. Java blocks are unsuitable for BIND_EXPR
because they use BLOCK_SUBBLOCKS for another purpose. */
block = make_node (BLOCK);
BLOCK_VARS (block) = decls;
/* The TREE_USED flag on a block determines whether the debug ouput
routines generate info for the variables in that block. */
TREE_USED (block) = 1;
if (outer != NULL_TREE)
{
outer = BIND_EXPR_BLOCK (outer);
BLOCK_SUBBLOCKS (outer) = chainon (BLOCK_SUBBLOCKS (outer), block);
}
return build (BIND_EXPR, TREE_TYPE (java_block), decls, body, block);
}
/* Gimplify a NEW_ARRAY_INIT node into array/element assignments. */
static tree
java_gimplify_new_array_init (tree exp)
{
tree array_type = TREE_TYPE (TREE_TYPE (exp));
tree data_field = lookup_field (&array_type, get_identifier ("data"));
tree element_type = TYPE_ARRAY_ELEMENT (array_type);
HOST_WIDE_INT ilength = java_array_type_length (array_type);
tree length = build_int_2 (ilength, 0);
tree init = TREE_OPERAND (exp, 0);
tree values = CONSTRUCTOR_ELTS (init);
tree array_ptr_type = build_pointer_type (array_type);
tree block = build (BLOCK, array_ptr_type);
tree tmp = build_decl (VAR_DECL, get_identifier ("<tmp>"), array_ptr_type);
tree array = build_decl (VAR_DECL, get_identifier ("<array>"), array_ptr_type);
tree body = build (MODIFY_EXPR, array_ptr_type, tmp,
build_new_array (element_type, length));
int index = 0;
DECL_CONTEXT (array) = current_function_decl;
DECL_CONTEXT (tmp) = current_function_decl;
/* FIXME: try to allocate array statically? */
while (values != NULL_TREE)
{
/* FIXME: Should use build_java_arrayaccess here, but avoid
bounds checking. */
tree lhs = build (COMPONENT_REF, TREE_TYPE (data_field),
build_java_indirect_ref (array_type, tmp, 0),
data_field, NULL_TREE);
tree assignment = build (MODIFY_EXPR, element_type,
build (ARRAY_REF, element_type, lhs,
build_int_2 (index++, 0),
NULL_TREE, NULL_TREE),
TREE_VALUE (values));
body = build (COMPOUND_EXPR, element_type, body, assignment);
values = TREE_CHAIN (values);
}
body = build (COMPOUND_EXPR, array_ptr_type, body,
build (MODIFY_EXPR, array_ptr_type, array, tmp));
TREE_CHAIN (tmp) = array;
BLOCK_VARS (block) = tmp;
BLOCK_EXPR_BODY (block) = body;
return java_gimplify_block (block);
}
static tree
java_gimplify_try_expr (tree try_expr)
{
tree body = TREE_OPERAND (try_expr, 0);
tree handler = TREE_OPERAND (try_expr, 1);
tree catch = NULL_TREE;
/* Build a CATCH_EXPR for each handler. */
while (handler)
{
tree java_catch = TREE_OPERAND (handler, 0);
tree catch_type = TREE_TYPE (TREE_TYPE (BLOCK_EXPR_DECLS (java_catch)));
tree expr = build (CATCH_EXPR, void_type_node,
prepare_eh_table_type (catch_type),
handler);
if (catch)
catch = build (COMPOUND_EXPR, void_type_node, catch, expr);
else
catch = expr;
handler = TREE_CHAIN (handler);
}
return build (TRY_CATCH_EXPR, void_type_node, body, catch);
}
/* Dump a tree of some kind. This is a convenience wrapper for the
dump_* functions in tree-dump.c. */
static void
dump_java_tree (enum tree_dump_index phase, tree t)
{
FILE *stream;
int flags;
stream = dump_begin (phase, &flags);
flags |= TDF_SLIM;
if (stream)
{
dump_node (t, flags, stream);
dump_end (phase, stream);
}
}