8sa1-gcc/gcc/java/builtins.c
Sandra Loosemore 5039610b96 tree.h (enum tree_code_class): Add tcc_vl_exp.
2007-02-15  Sandra Loosemore  <sandra@codesourcery.com>
	    Brooks Moses  <brooks.moses@codesourcery.com>
	    Lee Millward  <lee.millward@codesourcery.com>

	* tree.h (enum tree_code_class): Add tcc_vl_exp.
	(VL_EXP_CLASS_P): New.
	(TREE_OPERAND_CHECK): Use TREE_OPERAND_LENGTH instead of
	TREE_CODE_LENGTH.
	(TREE_OPERAND_CHECK_CODE): Likewise.
	(GIMPLE_STMT_OPERAND_CHECK): Likewise.
	(TREE_RTL_OPERAND_CHECK): Likewise.
	(tree_operand_check_failed): Make second parameter the whole tree
	instead of its code.  Fixed callers.
	(VL_EXP_CHECK): New.
	(TREE_OPERAND_LENGTH): New.
	(VL_EXP_OPERAND_LENGTH): New.
	(CALL_EXPR_FN): New.
	(CALL_EXPR_STATIC_CHAIN): New.
	(CALL_EXPR_ARGS): New.
	(CALL_EXPR_ARG): New.
	(call_expr_nargs): New.
	(CALL_EXPR_ARGP): New.
	(build_nt_call_list): Declare.
	(build_vl_exp_stat): Declare.
	(build_vl_exp): New.
	(build_call_list): Declare.
	(build_call_nary): Declare.
	(build_call_valist): Declare.
	(build_call_array): Declare.
	(call_expr_arg): Declare.
	(call_expr_argp): Declare.
	(call_expr_arglist): Declare.
	(fold_build_call_list): Declare.
	(fold_build_call_list_initializer): Declare.
	(fold_call_expr): Declare to replace fold_builtin.
	(fold_builtin_fputs): Update to agree with modified definition.
	(fold_builtin_strcpy): Likewise.
	(fold_builtin_strncpy): Likewise.
	(fold_builtin_memory_chk): Likewise.
	(fold_builtin_stxcpy_chk): Likewise.
	(fold_builtin_strncpy_chk): Likewise.
	(fold_builtin_next_arg): Likewise.
	(fold_build_call_expr): Declare.
	(fold_builtin_call_list): Declare.
	(fold_builtin_call_valist): Declare.
	(build_call_expr): Declare.
	(validate_arglist): Update to agree with modified definition.
	(tree_operand_length): New.
	(call_expr_arg_iterator): New.
	(init_call_expr_arg_iterator): New.
	(next_call_expr_arg): New.
	(first_call_expr_arg): New.
	(more_call_expr_args_p): New.
	(FOR_EACH_CALL_EXPR_ARG): New.

	* tree.c (tree_code_class_string): Add entries for tcc_vl_exp
	and tcc_gimple_stmt.
	(tree_code_size): Update documentation.  Use sizeof (tree) rather
	than sizeof (char *).
	(tree_size): Likewise.  Add case for tcc_vl_exp.
	(tree_node_structure): Add case for tcc_vl_exp.
	(contains_placeholder_p): Likewise.
	(substitute_in_expr): Likewise.
	(substitute_placeholder_in_expr): Likewise.
	(stabilize_reference_1): Likewise.
	(build3_stat): Remove logic for CALL_EXPRs.  Replace with assertion
	to diagnose breakage of this interface for constructing CALL_EXPRs.
	(build_nt): Add similar assertion here.
	(build_nt_call_list): New.
	(simple_cst_equal) <CALL_EXPR>: Rewrite to use new accessors.
	(iterative_hash_expr): Use TREE_OPERAND_LENGTH instead of
	TREE_CODE_LENGTH.
	(get_callee_fndecl): Use new CALL_EXPR accessors.
	(tree_operand_check_failed): Change parameters to pass entire node
	instead of its code, so that we can call TREE_OPERAND_LENGTH on it.
	(process_call_operands): New.
	(build_vl_exp_stat): New.
	(build_call_list): New.
	(build_call_nary): New.
	(build_call_valist): New.
	(build_call_array): New.
	(walk_tree): Use TREE_OPERAND_LENGTH instead of TREE_CODE_LENGTH.
	(call_expr_arglist): New.

	* tree.def (CALL_EXPR): Change representation of CALL_EXPRs to use
	tcc_vl_exp instead of a fixed-size tcc_expression.

	* doc/c-tree.texi (CALL_EXPR): Document new representation and
	accessors for CALL_EXPRs.
	(AGGR_INIT_EXPR): Likewise.

2007-02-15  Sandra Loosemore  <sandra@codesourcery.com>
	    Brooks Moses  <brooks.moses@codesourcery.com>
	    Lee Millward  <lee.millward@codesourcery.com>

	* builtins.c (c_strlen): Return NULL_TREE instead of 0.
	(expand_builtin_nonlocal_goto): Change parameter to be entire
	CALL_EXPR instead of an arglist.  Use new CALL_EXPR accessors.
	(expand_builtin_prefetch): Likewise.
	(expand_builtin_classify_type): Likewise.
	(mathfn_built_in): Return NULL_TREE instead of 0.
	(expand_errno_check): Use new CALL_EXPR accessors.
	(expand_builtin_mathfn): Use new CALL_EXPR accessors and constructors.
	Return NULL_RTX instead of 0.
	(expand_builtin_mathfn_2): Likewise.
	(expand_builtin_mathfn_3): Likewise.
	(expand_builtin_interclass_mathfn): Likewise.
	(expand_builtin_sincos): Likewise.
	(expand_builtin_cexpi): Likewise.
	(expand_builtin_int_roundingfn): Likewise.
	(expand_builtin_int_roundingfn_2): Likewise.
	(expand_builtin_pow): Likewise.
	(expand_builtin_powi): Likewise.
	(expand_builtin_strlen): Pass entire CALL_EXPR as parameter instead
	of arglist, fixing callers appropriately.  Use new CALL_EXPR
	accessors and constructors.  Return NULL_RTX instead of 0.
	(expand_builtin_strstr): Likewise.
	(expand_builtin_strchr): Likewise.
	(expand_builtin_strrchr): Likewise.
	(expand_builtin_strpbrk): Likewise.
	(expand_builtin_memcpy): Likewise.
	(expand_builtin_mempcpy): Likewise.
	(expand_builtin_mempcpy_args): New.
	(expand_builtin_memmove): Similarly to expand_builtin_mempcpy.
	(expand_builtin_memmove_args): New.
	(expand_builtin_bcopy): Similarly to expand_builtin_mempcpy.
	(expand_movstr): Likewise.
	(expand_builtin_strcpy): Likewise.
	(expand_builtin_strcpy_args): New.
	(expand_builtin_stpcpy): Similarly to expand_builtin_strcpy.
	(expand_builtin_strncpy): Likewise.
	(expand_builtin_memset): Likewise.
	(expand_builtin_memset_args): New.
	(expand_builtin_bzero): Similarly to expand_builtin_memset.
	(expand_builtin_memcmp): Likewise.
	(expand_builtin_strcmp): Likewise.
	(expand_builtin_strncmp): Likewise.
	(expand_builtin_strcat): Likewise.
	(expand_builtin_strncat): Likewise.
	(expand_builtin_strspn): Likewise.
	(expand_builtin_strcspn): Likewise.
	(expand_builtin_args_info): Likewise.
	(expand_builtin_va_start): Likewise.
	(gimplify_va_arg_expr): Likewise.
	(expand_builtin_va_end): Likewise.
	(expand_builtin_va_copy): Likewise.
	(expand_builtin_frame_address): Likewise.
	(expand_builtin_alloca): Likewise.
	(expand_builtin_bswap): Likewise.
	(expand_builtin_unop): Likewise.
	(expand_builtin_fputs): Likewise.
	(expand_builtin_expect): Likewise.
	(expand_builtin_fabs): Likewise.
	(expand_builtin_copysign): Likewise.
	(expand_builtin_printf): Likewise.
	(expand_builtin_fprintf): Likewise.
	(expand_builtin_sprintf): Likewise.
	(expand_builtin_init_trampoline): Likewise.
	(expand_builtin_signbit): Likewise.
	(expand_builtin_fork_or_exec): Likewise.
	(expand_builtin_sync_operation): Likewise.
	(expand_builtin_compare_and_swap): Likewise.
	(expand_builtin_lock_test_and_set): Likewise.
	(expand_builtin_lock_release): Likewise.
	(expand_builtin): Likewise.
	(builtin_mathfn_code): Likewise.

	(fold_builtin_constant_p): Pass call arguments individually instead
	of as an arglist, fixing callers appropriately.  Use new CALL_EXPR
	accessors and constructors.  Return NULL_TREE instead of 0.
	(fold_builtin_expect): Likewise.
	(fold_builtin_classify_type): Likewise.
	(fold_builtin_strlen): Likewise.
	(fold_builtin_nan): Likewise.
	(integer_valued_real_p): Likewise.
	(fold_trunc_transparent_mathfn): Likewise.
	(fold_fixed_mathfn): Likewise.
	(fold_builtin_cabs): Likewise.
	(fold_builtin_sqrt): Likewise.
	(fold_builtin_cbrt): Likewise.
	(fold_builtin_cos): Likewise.
	(fold_builtin_cosh): Likewise.
	(fold_builtin_tan): Likewise.
	(fold_builtin_sincos): Likewise.
	(fold_builtin_cexp): Likewise.
	(fold_builtin_trunc): Likewise.
	(fold_builtin_floor): Likewise.
	(fold_builtin_ceil): Likewise.
	(fold_builtin_round): Likewise.
	(fold_builtin_int_roundingfn): Likewise.
	(fold_builtin_bitop): Likewise.
	(fold_builtin_bswap): Likewise.
	(fold_builtin_logarithm): Likewise.
	(fold_builtin_hypot): Likewise.
	(fold_builtin_pow): Likewise.
	(fold_builtin_powi): Likewise.
	(fold_builtin_exponent): Likewise.
	(fold_builtin_memset): Likewise.
	(fold_builtin_bzero): Likewise.
	(fold_builtin_memory_op): Likewise.
	(fold_builtin_bcopy): Deleted; call site changed to invoke
	fold_builtin_memory_op directly.
	(fold_builtin_strcpy): Similarly as for fold_builtin_memory_op.
	(fold_builtin_strncpy): Likewise.
	(fold_builtin_memcmp): Likewise.
	(fold_builtin_strcmp): Likewise.
	(fold_builtin_strncmp): Likewise.
	(fold_builtin_signbit): Likewise.
	(fold_builtin_copysign): Likewise.
	(fold_builtin_isascii): Likewise.
	(fold_builtin_toascii): Likewise.
	(fold_builtin_isdigit): Likewise.
	(fold_builtin_fabs): Likewise.
	(fold_builtin_abs): Likewise.
	(fold_builtin_fmin_fmax): Likewise.
	(fold_builtin_carg): Likewise.
	(fold_builtin_classify): Likewise.
	(fold_builtin_unordered_cmp): Likewise.

	(fold_builtin_0, fold_builtin_2, fold_builtin_3, fold_builtin_4):
	New functions split out from fold_builtin_1.
	(fold_builtin_n): New.
	(fold_builtin_varargs): New.
	(fold_builtin): Deleted.  Most callers changed to use fold_call_expr
	instead.
	(fold_call_expr): New.
	(build_function_call_expr): Rewrite to use new helper function.
	(fold_builtin_call_list): New.
	(build_call_expr): New.
	(fold_builtin_call_valist): New.
	(rewrite_call_expr): New.
	(validate_arg): New.
	(validate_arglist): Change parameter to be entire CALL_EXPR instead
	of an arglist.  Change return type to bool.  Use new CALL_EXPR
	accessors.

	(fold_builtin_strstr):  Pass call arguments individually instead
	of as an arglist, fixing callers appropriately.  Use new CALL_EXPR
	accessors and constructors.  Return NULL_TREE instead of 0.
	(fold_builtin_strchr): Likewise.
	(fold_builtin_strrchr): Likewise.
	(fold_builtin_strpbrk): Likewise.
	(fold_builtin_strcat): Likewise.
	(fold_builtin_strncat): Likewise.
	(fold_builtin_strspn): Likewise.
	(fold_builtin_strcspn): Likewise.
	(fold_builtin_fputs): Likewise.
	(fold_builtin_next_arg): Likewise.
	(fold_builtin_sprintf): Likewise.

	(expand_builtin_object_size): Use new CALL_EXPR accessors.  Use
	NULL_RTX instead of 0.
	(expand_builtin_memory_chk): Likewise.
	(maybe_emit_chk_warning): Likewise.
	(maybe_emit_sprintf_chk_warning): Likewise.

	(fold_builtin_object_size): Pass call arguments individually instead
	of as an arglist, fixing callers appropriately.  Use new CALL_EXPR
	accessors and constructors.  Return NULL_TREE instead of 0.
	(fold_builtin_memory_chk): Likewise.
	(fold_builtin_stxcpy_chk): Likewise.
	(fold_builtin_strncpy_chk): Likewise.
	(fold_builtin_strcat_chk): Likewise.
	(fold_builtin_strcat_chk): Likewise.
	(fold_builtin_strncat_chk): Likewise.
	(fold_builtin_sprintf_chk): Likewise.
	(fold_builtin_snprintf_chk): Likewise.
	(fold_builtin_printf): Likewise.
	(fold_builtin_vprintf): Likewise.

	* fold-const.c (negate_expr_p): Use new CALL_EXPR accessors and
	constructors.
	(operand_equal_p): Add separate tcc_vl_exp/CALL_EXPR case.
	(make_range): Use TREE_OPERAND_LENGTH instead of TREE_CODE_LENGTH.
	(extract_muldiv_1): Add VL_EXP_CLASS_P case.
	(fold_mathfn_compare): Use new CALL_EXPR accessors and constructors.
	(fold_unary): Likewise.
	(fold_binary): Likewise.
	(fold_ternary): Remove CALL_EXPR case, since they are no longer
	ternary expressions.
	(fold): Add logic for tcc_vl_exp.
	(fold_checksum_tree):  Make it know about tcc_vl_exp.  Use
	TREE_OPERAND_LENGTH instead of TREE_CODE_LENGTH.
	(fold_build3_stat): Add assertion to flag broken interface for
	constructing CALL_EXPRs.
	(fold_build_call_list): New.
	(fold_build_call_list_initializer): New.
	(tree_expr_nonnegative_p): Use new CALL_EXPR accessors and
	constructors.
	(fold_strip_sign_ops): Likewise.

2007-02-15  Sandra Loosemore  <sandra@codesourcery.com>
	    Brooks Moses  <brooks.moses@codesourcery.com>
	    Lee Millward  <lee.millward@codesourcery.com>

	* tree-dump.c (dequeue_and_dump) <CALL_EXPR>: Use new CALL_EXPR
	accessors and dump arguments explicitly.

	* tree-pretty-print.c (do_niy): Use TREE_OPERAND_LENGTH instead of
	TREE_CODE_LENGTH.
	(dump_generic_node): Use new CALL_EXPR accessors and walk arguments
	explicitly.
	(print_call_name): Use new CALL_EXPR accessors.

	* print-tree.c (print_node): Add case tcc_vl_exp.  Print
	CALL_EXPR arguments explicitly instead of as a list.  Use
	TREE_OPERAND_LENGTH instead of TREE_CODE_LENGTH.

	* tree-vrp.c (stmt_interesting_for_vrp): Use new CALL_EXPR accessors.
	(vrp_visit_stmt): Likewise.

	* tree-ssa-loop-im.c (outermost_invariant_loop_expr):  Make it
	know about tcc_vl_exp.  Use TREE_OPERAND_LENGTH instead of
	TREE_CODE_LENGTH.
	(force_move_till_expr): Likewise.

	* targhooks.c (default_external_stack_protect_fail): Use
	build_call_expr instead of build_function_call_expr.
	(default_hidden_stack_protect_fail): Likewise.

	* tree-complex.c (expand_complex_libcall): Use build_call_expr to
	build the call.

	* cgraphbuild.c (build_cgraph_edges): Use new CALL_EXPR accessors
	and walk arguments explicitly.

	* tree-ssa-loop-niter.c (simplify_replace_tree): Use
	TREE_OPERAND_LENGTH instead of TREE_CODE_LENGTH.
	(expand_simple_operations): Likewise.
	(infer_loop_bounds_from_array): Use new CALL_EXPR accessors.

	* gengtype.c (adjust_field_tree_exp): Use TREE_OPERAND_LENGTH instead
	of TREE_CODE_LENGTH.
	(walk_type): Tweak walking of arrays not to blow up on CALL_EXPRs.

	* optabs.c (expand_widen_pattern-expr): Use TREE_OPERAND_LENGTH
	instead of TREE_CODE_LENGTH.

	* value_prof.c (tree_ic): Use new CALL_EXPR accessors.
	(tree_ic_transform): Likewise.
	(interesting_stringop_to_profile_p): Pass entire CALL_EXPR as
	parameter instead of arglist.  Fix callers.
	(tree_stringop_fixed_value): Use new CALL_EXPR accessors.
	(tree_stringops_transform): Likewise.
	(tree_indirect_call_to_profile): Likewise.
	(tree_stringops_values_to_profile): Likewise.

	* tree-tailcall.c (find_tail_calls): Use new CALL_EXPR iterator.
	(eliminate_tail_call): Likewise.

	* ipa-cp.c (ipcp_update_callgraph): Use new CALL_EXPR accessors.

	* tree-scalar-evolution.c (chrec_contains_symbols_defined_in_loop):
	Use TREE_OPERAND_LENGTH and generalize to handle any number of
	operands.
	(instantiate_parameters_1): Can't handle tcc_vl_exp here.

	* omp-low.c (build_omp_barrier): Use build_call_expr.
	(lower_rec_input_clauses): Likewise.
	(lower_reduction_clauses): Likewise.
	(expand_parallel_call): Likewise.
	(maybe_catch_exception): Likewise.
	(expand_omp_for_generic): Likewise.
	(expand_omp_for_static_nochunk): Likewise.
	(expand_omp_sections): Likewise.
	(lower_omp_single_simple): Likewise.
	(lower_omp_single_copy): Likewise.
	(lower_omp_master): Likewise.
	(lower_omp_ordered): Likewise.
	(lower_omp_critical): Likewise.

	* ipa-reference.c (check-call): Use new CALL_EXPR iterator.
	(scan_for_static_refs): Create tcc_vl_exp case for CALL_EXPR.

	* tree-gimple.c (is_gimple_call_addr): Fix doc.
	(recalculate_side_effects): Use TREE_OPERAND_LENGTH instead of
	TREE_CODE_LENGTH.  Add tcc_vl_exp case.

	* tree-chrec.c (chrec_contains_symbols): Use TREE_OPERAND_LENGTH
	and generalize to handle any number of operands.
	(chrec_contains_undetermined): Likewise.
	(tree_contains_chrecs): Likewise.
	(evolution_function_is_invariant_rec_p): Use TREE_OPERAND_LENGTH.

	* cgraphunit.c (update_call_expr): Use new CALL_EXPR accessors.

	* tree-ssa-ccp.c (ccp_fold): Use new CALL_EXPR accessors.  Use
	fold_call_expr instead of fold_builtin.
	(ccp_fold_builtin): Likewise.  Update calls into builtins.c to
	match declarations there.
	(fold_stmt): Use new CALL_EXPR constructor and accessors.  Doc
	updates.

	* tree-ssa-loop-ivopts.c (expr_invariant_in_loop_p): Use
	TREE_OPERAND_LENGTH instead of TREE_CODE_LENGTH.

	* ipa-pure-const.c (check_call): Use new CALL_EXPR accessors.
	(scan_function): Add case tcc_vl_exp for CALL_EXPR.

	* tree-stdarg.c (execute_optimize_stdarg): Use new CALL_EXPR
	accessors.

	* tree-ssa-math-opts.c (execute_cse_sincos_1): Use build_call_expr.
	(execute_cse_sincos): Use new CALL_EXPR accessors.

	* tree-ssa-alias.c (find_used_portions): Use new CALL_EXPR iterator.

	* gimple-low.c (lower_function_body): Use build_call_expr.
	(lower_builtin_setjmp): Likewise.

	* expr.c (emit_block_move_via_libcall): Use build_call_expr.
	(set_storage_via_libcall): Likewise.
	(safe_from_p): Add tcc_vl_exp case.  Use TREE_OPERAND_LENGTH
	instead of TREE_CODE_LENGTH.
	(expand_expr_real_1): Use new CALL_EXPR accessors.

	* tree-browser.c (store_child_info): Use TREE_OPERAND_LENGTH and
	generalize to handle any number of operands.
	(TB_parent_eq): Likewise.

	* predict.c (expr_expected_value): Use new CALL_EXPR accessors.
	(strip_builtin_expect): Likewise.

	* function.c (gimplify_parameters): Use build_call_expr.

	* tree-vectorizer.c (vect_is_simple_reduction): Use TREE_OPERAND_LENGTH
	instead of TREE_CODE_LENGTH.

	* ipa-type-escape.c (check_call): Use new CALL_EXPR iterators.
	(scan_for_refs): Add case tcc_vl_exp for CALL_EXPR.

	* tree-data-ref.c (get_references_in_stmt): Use new CALL_EXPR
	iterators.

	* gimplify.c (build_stack_save_restore): Use build_call_expr.
	(gimplify_decl_expr): Likewise.
	(gimplify_call_expr): Use fold_call_expr instead of fold_builtin.
	Use new CALL_EXPR iterators.
	(gimplify_modify_expr_to_memcpy): Use build_call_expr.
	(gimplify_modify_expr_to_memset): Likewise.
	(gimplify_variable_sized_compare): Likewise.
	(gimplify_omp_atomic_fetch_op): Likewise.
	(gimplify_omp_atomic_pipeline): Likewise.
	(gimplify_omp_atomic_mutex): Likewise.
	(gimplify_function_tree): Likewise.

	* calls.c (alloca_call_p): Use new CALL_EXPR accessors.
	(call_expr_flags): Likewise.
	(expand_call): Likewise.

	* except.c (expand_builtin_eh_return_data_regno): Pass entire
	CALL_EXPR as parameter instead of arglist.  Use new CALL_EXPR 
        accessors.

	* coverage.c (create_coverage): Use build_call_expr.

	* tree-ssa-pre.c (expression_node_pool, list_node_pool): Delete.
	(temp_call_expr_obstack): New.
	(pool_copy_list): Delete.
	(temp_copy_call_expr): New.
	(phi_translate): Add case tcc_vl_exp for CALL_EXPR.  Use new
	CALL_EXPR accessors.  Get rid of special goo for copying argument
	lists and use temp_copy_call_expr instead.
	(valid_in_sets): Add case tcc_vl_exp for CALL_EXPR.  Use new
	CALL_EXPR accessors.
	(create_expression_by_pieces): Likewise.  Use build_call_array
	to construct the result instead of fold_build3.
	(create_value_expr_from): Add tcc_vl_exp.  Delete special goo for
	dealing with argument lists.
	(init_pre): Remove references to expression_node_pool and
	list_node_pool.  Init temp_call_expr_obstack instead.
	(fini_pre): Remove references to expression_node_pool and
	list_node_pool.

	* tree-sra.c (sra_walk_call_expr): Use new CALL_EXPR accessors
	and walk arguments explicitly instead of as a list.

	* tree-mudflap.c (mf_build_check_statement_for): Use build_call_expr.
	(mx_register_decls): Likewise.
	(mudflap_register_call): Likewise.
	(mudflap_finish_file): Likewise.

	* ipa-prop.c (ipa_callsite_compute_count): Use new CALL_EXPR accessors.
	(ipa_callsite_compute_param): Likewise.

	* tree-vect-patterns.c (vect_recog_pow_pattern): Use new CALL_EXPR
	accessors and constructor.

	* tree-nested.c (convert_nl_goto_reference): Use new CALL_EXPR
	accessors and constructor.
	(convert_tramp_reference): Likewise. 
	(convert_call_expr): Likewise.
	(finalize_nesting_tree_1): Likewise.

	* tree-ssa.c (tree_ssa_useless_type_conversion): Use new CALL_EXPR
	accessors.

	* tree-ssa-loop-prefetch.c (issue_prefetch_ref): Use build_call_expr.

	* tree-inline.c (initialize_inlined_parameters): Pass entire
	CALL_EXPR as parameter instead of arglist.  Use new CALL_EXPR
	accessors.
	(estimate_num_insns_1): Use new CALL_EXPR accessors.
	(expand_call_inline): Tidy up call to initialize_inlined_parameters.

	* tree-vect-transform.c (vect_create_epilog_for_reduction):  Use
	TREE_OPERAND_LENGTH instead of TREE_CODE_LENGTH.
	(vectorizable_reduction): Likewise.
	(vectorizable_call): Use new CALL_EXPR iterators.
	(vectorizable_conversion): Use build_call_expr.
	(vectorizable_operation): Use TREE_OPERAND_LENGTH.
	(vect_gen_widened_results_half): Use build_call_expr.
	(vect_setup_realignment): Likewise.
	(vectorizable_live_operation): Use TREE_OPERAND_LENGTH.

	* tree-object-size.c (alloc_object_size): Use new CALL_EXPR accessors.
	(pass_through_call): Likewise.
	(compute_object_sizes): Likewise.  Use fold_call_expr instead of
	fold_builtin.

	* tree-profile.c (tree_gen_interval_profiler): Use build_call_expr.
	(tree_gen_pow2_profiler): Likewise.
	(tree_gen_one_value_profiler): Likewise.
	(tree_gen_ic_func_profiler): Likewise.
	(tree_gen_average_profiler): Likewise.
	(tree_gen_ior_profiler): Likewise.

	* tree-ssa-structalias.c (get_constraint_for): Add case tcc_vl_exp.
	(find_func_aliases): Use new CALL_EXPR accessors.  Add case
	tcc_vl_exp.  Use TREE_OPERAND_LENGTH instead of TREE_CODE_LENGTH.

	* tree-ssa-reassoc.c (get_rank): Use TREE_OPERAND_LENGTH instead
	of TREE_CODE_LENGTH.

	* stmt.c (warn_if_unused_value): Use TREE_OPERAND_LENGTH instead
	of TREE_CODE_LENGTH.

	* convert.c (convert_to_real): Use new CALL_EXPR accessors and
	constructor.
	(convert_to_integer): Likewise.

	* tree-ssa-operands.c (get_call_expr_operands): Use new CALL_EXPR
	accessors.

2007-02-15  Sandra Loosemore  <sandra@codesourcery.com>
	    Brooks Moses  <brooks.moses@codesourcery.com>
	    Lee Millward  <lee.millward@codesourcery.com>

	* config/alpha/alpha.c (alpha_expand_builtin): Use new CALL_EXPR
	accessors.
	* config/frv/frv.c (frv_expand_builtin): Likewise.
	* config/s390/s390.c (s390_expand_builtin): Likewise.

	* config/sparc/sparc.c (sparc_gimplify_va_arg): Use build_call_expr.
	(sparc_expand_builtin): Use new CALL_EXPR accessors.

	* config/i386/i386.c (ix86_function_ok_for_sibcall): Likewise.
	(ix86_expand_binop_builtin): Pass entire CALL_EXPR as parameter
	instead of arglist.  Use new CALL_EXPR accessors on it.  Fix callers.
	(ix86_expand_store_builtin): Likewise.
	(ix86_expand_unop_builtin): Likewise.
	(ix86_expand_unop1_builtin): Likewise.
	(ix86_expand_sse_compare): Likewise.
	(ix86_expand_sse_comi): Likewise.
	(ix86_expand_vec_init_builtin): Likewise.
	(ix86_expand_vec_ext_builtin): Likewise.
	(ix86_expand_vec_set_builtin): Likewise.
	(ix86_expand_builtin): Use new CALL_EXPR accessors.

	* config/sh/sh.c (sh_expand_builtin): Use new CALL_EXPR accessors.
	* config/c4x/c4x.c (c4x_expand_builtin): Likewise.

	* config/iq2000/iq2000.c (expand_one_builtin): Pass entire CALL_EXPR
	instead of arglist.  Use new CALL_EXPR accessors.  Fix callers.
	(iq2000_expand_builtin): Use new CALL_EXPR accessors.

	* config/rs6000/rs6000-c.c (altivec_build_resolved_builtin): Use
	build_call_expr.
	* config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Likewise.
	(rs6000_expand_unop_builtin): Pass entire CALL_EXPR instead of
	arglist.  Use new CALL_EXPR accessors.  Fix callers.
	(altivec_expand_abs_builtin): Likewise.
	(rs6000_expand_binop_builtin): Likewise.
	(altivec_expand_predicate_builtin): Likewise.
	(altivec_expand_lv_builtin): Likewise.
	(spe_expand_stv_builtin): Likewise.
	(altivec_expand_stv_builtin): Likewise.
	(rs6000_expand_ternop_builtin): Likewise.
	(altivec_expand_ld_builtin): Use new CALL_EXPR accessors.
	(altivec_expand_st_builtin): Likewise.
	(altivec_expand_dst_builtin): Likewise.
	(altivec_expand_vec_init_builtin): Pass entire CALL_EXPR instead of
	arglist.  Use new CALL_EXPR accessors.  Fix callers.
	(altivec_expand_vec_set_builtin): Likewise.
	(altivec_expand_vec_ext_builtin): Likewise.
	(altivec_expand_builtin): Use new CALL_EXPR accessors.
	(spe_expand_builtin): Likewise.
	(spe_expand_predicate_builtin): Pass entire CALL_EXPR instead of
	arglist.  Use new CALL_EXPR accessors.  Fix callers.
	(spe_expand_evsel_builtin): Likewise.
	(rs6000_expand_builtin): Use new CALL_EXPR accessors.  VCFUX and
	FCFSX cases must construct whole new CALL_EXPR, not just arglist.

	* config/arm/arm.c (arm_expand_binop_builtin): Pass entire CALL_EXPR
	instead of arglist.  Use new CALL_EXPR accessors.  Fix callers.
	(arm_expand_unop_builtin): Likewise.
	(arm_expand_builtin): Use new CALL_EXPR accessors.

	* config/mips/mips.c (mips_expand_builtin):  Use new CALL_EXPR
	accessors.

	* config/bfin/bfin.c (bfin_expand_binop_builtin): Pass entire CALL_EXPR
	instead of arglist.  Use new CALL_EXPR accessors.  Fix callers.
	(bfin_expand_unop_builtin): Likewise.
	(bfin_expand_builtin): Use new CALL_EXPR accessors.

2007-02-15  Sandra Loosemore  <sandra@codesourcery.com>
	    Brooks Moses  <brooks.moses@codesourcery.com>
	    Lee Millward  <lee.millward@codesourcery.com>

	* c-semantics.c (build_stmt): Add internal diagnostic check.

	* c-pretty-print.c (pp_c_postfix_expression): Use new CALL_EXPR
	accessors.  Print arguments explicitly instead of as a list.

	* c-typeck.c (build_function_call): Use new CALL_EXPR constructors.

	* c-omp.c (c_finish_omp_barrier): Use build_call_expr.
	(c_finish_omp_flish): Likewise.

	* c-common.c (verify_tree): Use new CALL_EXPR accessors.  Traverse
	arguments explicitly instead of as a list.  Use TREE_OPERAND_LENGTH
	instead of TREE_CODE_LENGTH.
	(check_function_arguments_recurse): Use new CALL_EXPR accessors.
	(c_warn_unused_result): Likewise.

2007-02-15  Sandra Loosemore  <sandra@codesourcery.com>
	    Brooks Moses  <brooks.moses@codesourcery.com>
	    Lee Millward  <lee.millward@codesourcery.com>

	* cp-tree.def (AGGR_INIT_EXPR): Adjust documentation.
	Change class to tcc_vl_exp.

	* call.c (build_call): Use build_call_list instead 
	of build3. 
	(build_over_call): Likewise.
	(build_new_method_call): Use build_min_non_dep_call_list 
	instead of build_min_non_dep.

	* error.c (dump_call_expr_args): New function.
	(dump_aggr_init_expr_args): New function.
	(dump_expr) <AGGR_INIT_EXPR, CALL_EXPR, INDIRECT_REF>: Use them. 
	Update to use new CALL_EXPR and AGGR_INIT_EXPR accessor macros.

	* cvt.c (convert_to_void): Use build_call_array instead
	of build3; use new AGGR_INIT_EXPR accessor macros.

	* mangle.c (write_expression): Use TREE_OPERAND_LENGTH
	instead of TREE_CODE_LENGTH.

	* dump.c (cp_dump_tree) <AGGR_INIT_EXPR>: Update to use new
	AGGR_INIT_EXPR accessor macros.

	* cp-gimplify.c (cp_gimplify_init_expr): Use 
	AGGR_INIT_EXPR_SLOT to set the slot operand.

	* cp-tree.h (AGGR_INIT_EXPR_FN): New macro.
	(AGGR_INIT_EXPR_SLOT): New macro.
	(AGGR_INIT_EXPR_ARG): New macro.
	(aggr_init_expr_nargs): New macro.
	(AGGR_INIT_EXPR_ARGP): New macro.
	(aggr_init_expr_arg_iterator): New.
	(init_aggr_init_expr_arg_iterator): New.
	(next_aggr_init_expr_arg): New.
	(first_aggr_init_expr_arg): New.
	(more_aggr_init_expr_args_p): New.
	(FOR_EACH_AGGR_INIT_EXPR_ARG): New.
	(stabilize_aggr_init): New declaration.
	(build_min_non_dep_call_list): Likewise.

	* tree.c (process_aggr_init_operands): New function.
	(build_aggr_init_array) New function.
	(build_cplus_new): Update to use new CALL_EXPR and
	AGGR_INIT_EXPR accessor macros. Replace use of build3 with
	build_aggr_init_array.
	(build_min_non_dep_call_list) New function.
	(build_min_nt): Assert input code parameter is not a variable
	length expression class.
	(build_min, build_min_non_dep): Likewise.
	(cp_tree_equal) <CALL_EXPR>: Iterate through the arguments
	to check for equality instead of recursing. Handle tcc_vl_exp
	tree code classes.
	(stabilize_call): Update to only handle CALL_EXPRs, not 
	AGGR_INIT_EXPRs; use new CALL_EXPR accessor macros.
	(stabilize_aggr_init): New function.
	(stabilize_init): Use it.

	* cxx-pretty-print.c (pp_cxx_postfix_expression)
	<AGGR_INIT_EXPR, CALL_EXPR>: Update to use new CALL_EXPR and
	AGGR_INIT_EXPR accessor macros and argument iterators.
	
	* pt.c (tsubst_copy) <CALL_EXPR>: Replace build_nt with
	build_vl_exp. Iterate through the operands, recursively 
	processing each one.
	(tsubst_copy_and_build) <CALL_EXPR>: Update to use new
	CALL_EXPR accessor macros.
	(value_dependent_expression_p) <default>: Handle tcc_vl_exp
	tree code classes. Use TREE_OPERAND_LENGTH instead of 
	TREE_CODE_LENGTH.

	* semantics.c (finish_call_expr): Use build_nt_call_list
	instead of build_nt.
	(simplify_aggr_init_expr): Update to use new AGGR_INIT_EXPR 
	accessor macros. Use build_call_array to construct the 
	CALL_EXPR node instead of build3
	
	* decl2.c (build_offset_ref_call_from_tree): Use 
	build_nt_call_list and build_min_non_dep_call_list instead
	of build_min_nt and build_min_non_dep.

	* parser.c (cp_parser_postfix_expression) <CPP_OPEN_PAREN>:
	Use build_nt_call_list instead of build_min_nt.

2007-02-15  Sandra Loosemore  <sandra@codesourcery.com>
	    Brooks Moses  <brooks.moses@codesourcery.com>
	    Lee Millward  <lee.millward@codesourcery.com>

	* java-tree.h (BUILD_MONITOR_ENTER): Use build_call_nary instead
	of build3.
	(BUILD_MONITOR_EXIT): Likewise.

	* java-gimplify.c (java_gimplify_component_ref): Use build_call_expr.
	(java_gimplify_modify_expr): Likewise.

	* class.c (cache_this_class_ref): Use build_call_expr.
	(build_static_field_ref): Likewise.
	(emit_indirect_register_classes): Likewise.
	(emit_register_classes): Likewise.

	* resource.c (write_resource_constructor): Use build_call_expr.

	* builtins.c (builtin_creator_function): Change interpretation of
	the second parameter to be the whole CALL_EXPR instead of the arglist.
	(max_builtin): Tweak parameter list.  Use new CALL_EXPR accessors.
	(min_builtin): Likewise.
	(abs_builtin): Likewise.
	(java_build_function_call_expr): Likewise.
	(convert_real): Likewise.
	(UNMARSHAL3): Likewise.
	(UNMARSHAL4): Likewise.
	(UNMARSHAL5): Likewise.
	(build_arglist_for_builtin): Delete.  Fix callers to use
	build_call_expr instead.
	(putObject_builtin): Tweak parameter list.  Use new CALL_EXPR
	accessors.
	(compareAndSwapInt_builtin): Likewise.
	(compareAndSwapLong_builtin): Likewise.
	(compareAndSwapObject_builtin): Likewise.
	(putVolatile_builtin): Likewise.
	(getVolatile_builtin): Likewise.
	(VMSupportsCS8_builtin): Likewise.
	(check_for_builtin): Pass entire CALL_EXPR to builtin expander
	instead of arglist.

	* expr.c (build_java_athrow): Use build_call_nary instead of build3.
	(build_java_throw_out_of_bounds_exception): Likewise.
	(java_check_reference): Likewise.
	(build_java_arraystore_check): Likewise.
	(build_newarray): Likewise.
	(build_anewarray): Likewise.
	(expand_java_multinewarray): Use build_call_list instead of build3.
	(build_java_monitor): Use build_call_nary instead of build3.
	(java_create_object): Likewise.
	(expand_java_NEW): Likewise.
	(build_instanceof): Likewise.
	(expand_java_CHECKCAST): Likewise.
	(build_java_soft_divmod): Likewise.
	(build_java_binop): Likewise.
	(build_field_ref): Likewise.
	(build_class_init): Likewise.
	(rewrite_arglist_getcaller): Use build_call_expr.
	(build_invokeinterface):  Use build_call_nary instead of build3.
	(expand_invoke): Use build_call_list instead of build3.
	(build_jni_stub): Use build_call_nary, build_call_list, or
	build_call_expr instead	of build3.
	(expand_java_field_op): Use build_call_expr instead of build3.
	(force_evaluation_order): Use new CALL_EXPR accessors.

	* lang.c (java_get_callee_fndecl): Use new CALL_EXPR accessors.

2007-02-15  Sandra Loosemore  <sandra@codesourcery.com>
	    Brooks Moses  <brooks.moses@codesourcery.com>
	    Lee Millward  <lee.millward@codesourcery.com>

	* objc-act.c (receiver_is_class_object): Use new CALL_EXPR accessors.
	(objc_get_callee_fndecl): Likewise.

2007-02-15  Sandra Loosemore  <sandra@codesourcery.com>
	    Brooks Moses  <brooks.moses@codesourcery.com>
	    Lee Millward  <lee.millward@codesourcery.com>

	* trans-expr.c (gfc_conv_power_op): Use build_call_expr.
	(gfc_conv_string_tmp): Likewise.
	(gfc_conv_concat_op): Likewise.
	(gfc_build_compare_string): Likewise.
	(gfc_conv_function_call): Use build_call_list instead of build3.

	* trans-array.c (gfc_trans_allocate_array_storage): Use
	build_call_expr.
	(gfc_grow_array): Likewise.
	(gfc_trans_array_ctor_element): Likewise.
	(gfc_trans_array_constructor_value): Likewise.
	(gfc_array_allocate): Likewise.
	(gfc_array_deallocate): Likewise.
	(gfc_trans_auto_array_allocation): Likewise.
	(gfc_trans_dummy_array_bias): Likewise.
	(gfc_conv_array_parameter): Likewise.
	(gfc_trans_dealloc_allocated): Likewise.
	(gfc_duplicate_allocatable): Likewise.

	* trans-openmp.c (gfc_trans_omp_barrier): Use build_call_expr.
	(gfc_trans_omp_flush): Likewise.

	* trans-stmt.c (gfc_conv_elementel_dependencies): Use build_call_expr.
	(gfc_trans_pause): Likewise.
	(gfc_trans_stop): Likewise.
	(gfc_trans_character_select): Likewise.
	(gfc_do_allocate): Likewise.
	(gfc_trans_assign_need_temp): Likewise.
	(gfc_trans_pointer_assign_need_temp): Likewise.
	(gfc_trans_forall_1): Likewise.
	(gfc_trans_where_2): Likewise.
	(gfc_trans_allocate): Likewise.
	(gfc_trans_deallocate): Likewise.

	* trans.c (gfc_trans_runtime_check): Use build_call_expr.

	* trans-io.c (gfc_trans_open): Use build_call_expr.
	(gfc_trans_close): Likewise.
	(build_filepos): Likewise.
	(gfc_trans_inquire): Likewise.
	(NML_FIRST_ARG): Delete.
	(NML_ADD_ARG): Delete.
	(transfer_namelist_element): Use build_call_expr.
	(build_dt): Likewise.
	(gfc_trans_dt_end): Likewise.
	(transfer_expr): Likewise.
	(transfer_array-desc): Likewise.

	* trans-decl.c (gfc_generate_function_code): Use build_call_expr.
	(gfc_generate_constructors): Likewise.

	* trans-intrinsic.c (gfc_conv_intrinsic_ctime): Use build_call_expr.
	(gfc_conv_intrinsic_fdate): Likewise.
	(gfc_conv_intrinsic_ttynam): Likewise.
	(gfc_conv_intrinsic_array_transfer): Likewise.
	(gfc_conv_associated): Likewise.
	(gfc_conv_intrinsic_si_kind): Likewise.
	(gfc_conv_intrinsic_trim): Likewise.
	(gfc_conv_intrinsic_repeat: Likewise.
	(gfc_conv_intrinsic_iargc): Likewise.

Co-Authored-By: Brooks Moses <brooks.moses@codesourcery.com>
Co-Authored-By: Lee Millward <lee.millward@codesourcery.com>

From-SVN: r122018
2007-02-15 18:50:49 -05:00

613 lines
20 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Built-in and inline functions for gcj
Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007
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, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, 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. */
/* Written by Tom Tromey <tromey@redhat.com>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "ggc.h"
#include "flags.h"
#include "langhooks.h"
#include "java-tree.h"
#include <stdarg.h>
#include "convert.h"
#include "rtl.h"
#include "insn-codes.h"
#include "expr.h"
#include "optabs.h"
static tree max_builtin (tree, tree);
static tree min_builtin (tree, tree);
static tree abs_builtin (tree, tree);
static tree convert_real (tree, tree);
static tree java_build_function_call_expr (tree, tree);
static tree putObject_builtin (tree, tree);
static tree compareAndSwapInt_builtin (tree, tree);
static tree compareAndSwapLong_builtin (tree, tree);
static tree compareAndSwapObject_builtin (tree, tree);
static tree putVolatile_builtin (tree, tree);
static tree getVolatile_builtin (tree, tree);
static tree VMSupportsCS8_builtin (tree, tree);
/* Functions of this type are used to inline a given call. Such a
function should either return an expression, if the call is to be
inlined, or NULL_TREE if a real call should be emitted. Arguments
are method return type and the original CALL_EXPR containing the
arguments to the call. */
typedef tree builtin_creator_function (tree, tree);
/* Hold a char*, before initialization, or a tree, after
initialization. */
union string_or_tree GTY(())
{
const char * GTY ((tag ("0"))) s;
tree GTY ((tag ("1"))) t;
};
/* Used to hold a single builtin record. */
struct builtin_record GTY(())
{
union string_or_tree GTY ((desc ("1"))) class_name;
union string_or_tree GTY ((desc ("1"))) method_name;
builtin_creator_function * GTY((skip)) creator;
enum built_in_function builtin_code;
};
static GTY(()) struct builtin_record java_builtins[] =
{
{ { "java.lang.Math" }, { "min" }, min_builtin, 0 },
{ { "java.lang.Math" }, { "max" }, max_builtin, 0 },
{ { "java.lang.Math" }, { "abs" }, abs_builtin, 0 },
{ { "java.lang.Math" }, { "acos" }, NULL, BUILT_IN_ACOS },
{ { "java.lang.Math" }, { "asin" }, NULL, BUILT_IN_ASIN },
{ { "java.lang.Math" }, { "atan" }, NULL, BUILT_IN_ATAN },
{ { "java.lang.Math" }, { "atan2" }, NULL, BUILT_IN_ATAN2 },
{ { "java.lang.Math" }, { "ceil" }, NULL, BUILT_IN_CEIL },
{ { "java.lang.Math" }, { "cos" }, NULL, BUILT_IN_COS },
{ { "java.lang.Math" }, { "exp" }, NULL, BUILT_IN_EXP },
{ { "java.lang.Math" }, { "floor" }, NULL, BUILT_IN_FLOOR },
{ { "java.lang.Math" }, { "log" }, NULL, BUILT_IN_LOG },
{ { "java.lang.Math" }, { "pow" }, NULL, BUILT_IN_POW },
{ { "java.lang.Math" }, { "sin" }, NULL, BUILT_IN_SIN },
{ { "java.lang.Math" }, { "sqrt" }, NULL, BUILT_IN_SQRT },
{ { "java.lang.Math" }, { "tan" }, NULL, BUILT_IN_TAN },
{ { "java.lang.Float" }, { "intBitsToFloat" }, convert_real, 0 },
{ { "java.lang.Double" }, { "longBitsToDouble" }, convert_real, 0 },
{ { "java.lang.Float" }, { "floatToRawIntBits" }, convert_real, 0 },
{ { "java.lang.Double" }, { "doubleToRawLongBits" }, convert_real, 0 },
{ { "sun.misc.Unsafe" }, { "putInt" }, putObject_builtin, 0},
{ { "sun.misc.Unsafe" }, { "putLong" }, putObject_builtin, 0},
{ { "sun.misc.Unsafe" }, { "putObject" }, putObject_builtin, 0},
{ { "sun.misc.Unsafe" }, { "compareAndSwapInt" },
compareAndSwapInt_builtin, 0},
{ { "sun.misc.Unsafe" }, { "compareAndSwapLong" },
compareAndSwapLong_builtin, 0},
{ { "sun.misc.Unsafe" }, { "compareAndSwapObject" },
compareAndSwapObject_builtin, 0},
{ { "sun.misc.Unsafe" }, { "putOrderedInt" }, putVolatile_builtin, 0},
{ { "sun.misc.Unsafe" }, { "putOrderedLong" }, putVolatile_builtin, 0},
{ { "sun.misc.Unsafe" }, { "putOrderedObject" }, putVolatile_builtin, 0},
{ { "sun.misc.Unsafe" }, { "putIntVolatile" }, putVolatile_builtin, 0},
{ { "sun.misc.Unsafe" }, { "putLongVolatile" }, putVolatile_builtin, 0},
{ { "sun.misc.Unsafe" }, { "putObjectVolatile" }, putVolatile_builtin, 0},
{ { "sun.misc.Unsafe" }, { "getObjectVolatile" }, getVolatile_builtin, 0},
{ { "sun.misc.Unsafe" }, { "getIntVolatile" }, getVolatile_builtin, 0},
{ { "sun.misc.Unsafe" }, { "getLongVolatile" }, getVolatile_builtin, 0},
{ { "sun.misc.Unsafe" }, { "getLong" }, getVolatile_builtin, 0},
{ { "java.util.concurrent.atomic.AtomicLong" }, { "VMSupportsCS8" },
VMSupportsCS8_builtin, 0},
{ { NULL }, { NULL }, NULL, END_BUILTINS }
};
/* Internal functions which implement various builtin conversions. */
static tree
max_builtin (tree method_return_type, tree orig_call)
{
/* MAX_EXPR does not handle -0.0 in the Java style. */
if (TREE_CODE (method_return_type) == REAL_TYPE)
return NULL_TREE;
return fold_build2 (MAX_EXPR, method_return_type,
CALL_EXPR_ARG (orig_call, 0),
CALL_EXPR_ARG (orig_call, 1));
}
static tree
min_builtin (tree method_return_type, tree orig_call)
{
/* MIN_EXPR does not handle -0.0 in the Java style. */
if (TREE_CODE (method_return_type) == REAL_TYPE)
return NULL_TREE;
return fold_build2 (MIN_EXPR, method_return_type,
CALL_EXPR_ARG (orig_call, 0),
CALL_EXPR_ARG (orig_call, 1));
}
static tree
abs_builtin (tree method_return_type, tree orig_call)
{
return fold_build1 (ABS_EXPR, method_return_type,
CALL_EXPR_ARG (orig_call, 0));
}
/* Construct a new call to FN using the arguments from ORIG_CALL. */
static tree
java_build_function_call_expr (tree fn, tree orig_call)
{
int nargs = call_expr_nargs (orig_call);
switch (nargs)
{
/* Although we could handle the 0-3 argument cases using the general
logic in the default case, splitting them out permits folding to
be performed without constructing a temporary CALL_EXPR. */
case 0:
return build_call_expr (fn, 0);
case 1:
return build_call_expr (fn, 1, CALL_EXPR_ARG (orig_call, 0));
case 2:
return build_call_expr (fn, 2,
CALL_EXPR_ARG (orig_call, 0),
CALL_EXPR_ARG (orig_call, 1));
case 3:
return build_call_expr (fn, 3,
CALL_EXPR_ARG (orig_call, 0),
CALL_EXPR_ARG (orig_call, 1),
CALL_EXPR_ARG (orig_call, 2));
default:
{
tree fntype = TREE_TYPE (fn);
fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fn);
return fold (build_call_array (TREE_TYPE (fntype),
fn, nargs, CALL_EXPR_ARGP (orig_call)));
}
}
}
static tree
convert_real (tree method_return_type, tree orig_call)
{
return build1 (VIEW_CONVERT_EXPR, method_return_type,
CALL_EXPR_ARG (orig_call, 0));
}
/* Provide builtin support for atomic operations. These are
documented at length in libjava/sun/misc/Unsafe.java. */
/* FIXME. There are still a few things wrong with this logic. In
particular, atomic writes of multi-word integers are not truly
atomic: this requires more work.
In general, double-word compare-and-swap cannot portably be
implemented, so we need some kind of fallback for 32-bit machines.
*/
/* Macros to unmarshal arguments from a CALL_EXPR into a few
variables. We also convert the offset arg from a long to an
integer that is the same size as a pointer. */
#define UNMARSHAL3(METHOD_CALL) \
tree this_arg, obj_arg, offset_arg; \
do \
{ \
tree orig_method_call = METHOD_CALL; \
this_arg = CALL_EXPR_ARG (orig_method_call, 0); \
obj_arg = CALL_EXPR_ARG (orig_method_call, 1); \
offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \
CALL_EXPR_ARG (orig_method_call, 2)); \
} \
while (0)
#define UNMARSHAL4(METHOD_CALL) \
tree value_type, this_arg, obj_arg, offset_arg, value_arg; \
do \
{ \
tree orig_method_call = METHOD_CALL; \
this_arg = CALL_EXPR_ARG (orig_method_call, 0); \
obj_arg = CALL_EXPR_ARG (orig_method_call, 1); \
offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \
CALL_EXPR_ARG (orig_method_call, 2)); \
value_arg = CALL_EXPR_ARG (orig_method_call, 3); \
value_type = TREE_TYPE (value_arg); \
} \
while (0)
#define UNMARSHAL5(METHOD_CALL) \
tree value_type, this_arg, obj_arg, offset_arg, expected_arg, value_arg; \
do \
{ \
tree orig_method_call = METHOD_CALL; \
this_arg = CALL_EXPR_ARG (orig_method_call, 0); \
obj_arg = CALL_EXPR_ARG (orig_method_call, 1); \
offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \
CALL_EXPR_ARG (orig_method_call, 2)); \
expected_arg = CALL_EXPR_ARG (orig_method_call, 3); \
value_arg = CALL_EXPR_ARG (orig_method_call, 4); \
value_type = TREE_TYPE (value_arg); \
} \
while (0)
/* Add an address to an offset, forming a sum. */
static tree
build_addr_sum (tree type, tree addr, tree offset)
{
tree ptr_type = build_pointer_type (type);
return fold_build2 (PLUS_EXPR,
ptr_type,
fold_convert (ptr_type, addr), offset);
}
/* Make sure that this-arg is non-NULL. This is a security check. */
static tree
build_check_this (tree stmt, tree this_arg)
{
return build2 (COMPOUND_EXPR, TREE_TYPE (stmt),
java_check_reference (this_arg, 1), stmt);
}
/* Now the builtins. These correspond to the primitive functions in
libjava/sun/misc/natUnsafe.cc. */
static tree
putObject_builtin (tree method_return_type ATTRIBUTE_UNUSED,
tree orig_call)
{
tree addr, stmt;
UNMARSHAL4 (orig_call);
addr = build_addr_sum (value_type, obj_arg, offset_arg);
stmt = fold_build2 (MODIFY_EXPR, value_type,
build_java_indirect_ref (value_type, addr,
flag_check_references),
value_arg);
return build_check_this (stmt, this_arg);
}
static tree
compareAndSwapInt_builtin (tree method_return_type ATTRIBUTE_UNUSED,
tree orig_call)
{
enum machine_mode mode = TYPE_MODE (int_type_node);
if (sync_compare_and_swap_cc[mode] != CODE_FOR_nothing
|| sync_compare_and_swap[mode] != CODE_FOR_nothing)
{
tree addr, stmt;
UNMARSHAL5 (orig_call);
addr = build_addr_sum (int_type_node, obj_arg, offset_arg);
stmt = build_call_expr (built_in_decls[BUILT_IN_BOOL_COMPARE_AND_SWAP_4],
3, addr, expected_arg, value_arg);
return build_check_this (stmt, this_arg);
}
return NULL_TREE;
}
static tree
compareAndSwapLong_builtin (tree method_return_type ATTRIBUTE_UNUSED,
tree orig_call)
{
enum machine_mode mode = TYPE_MODE (long_type_node);
if (sync_compare_and_swap_cc[mode] != CODE_FOR_nothing
|| sync_compare_and_swap[mode] != CODE_FOR_nothing)
{
tree addr, stmt;
UNMARSHAL5 (orig_call);
addr = build_addr_sum (long_type_node, obj_arg, offset_arg);
stmt = build_call_expr (built_in_decls[BUILT_IN_BOOL_COMPARE_AND_SWAP_8],
3, addr, expected_arg, value_arg);
return build_check_this (stmt, this_arg);
}
return NULL_TREE;
}
static tree
compareAndSwapObject_builtin (tree method_return_type ATTRIBUTE_UNUSED,
tree orig_call)
{
enum machine_mode mode = TYPE_MODE (ptr_type_node);
if (sync_compare_and_swap_cc[mode] != CODE_FOR_nothing
|| sync_compare_and_swap[mode] != CODE_FOR_nothing)
{
tree addr, stmt;
int builtin;
UNMARSHAL5 (orig_call);
builtin = (POINTER_SIZE == 32
? BUILT_IN_BOOL_COMPARE_AND_SWAP_4
: BUILT_IN_BOOL_COMPARE_AND_SWAP_8);
addr = build_addr_sum (value_type, obj_arg, offset_arg);
stmt = build_call_expr (built_in_decls[builtin],
3, addr, expected_arg, value_arg);
return build_check_this (stmt, this_arg);
}
return NULL_TREE;
}
static tree
putVolatile_builtin (tree method_return_type ATTRIBUTE_UNUSED,
tree orig_call)
{
tree addr, stmt, modify_stmt;
UNMARSHAL4 (orig_call);
addr = build_addr_sum (value_type, obj_arg, offset_arg);
addr
= fold_convert (build_pointer_type (build_type_variant (value_type, 0, 1)),
addr);
stmt = build_call_expr (built_in_decls[BUILT_IN_SYNCHRONIZE], 0);
modify_stmt = fold_build2 (MODIFY_EXPR, value_type,
build_java_indirect_ref (value_type, addr,
flag_check_references),
value_arg);
stmt = build2 (COMPOUND_EXPR, TREE_TYPE (modify_stmt),
stmt, modify_stmt);
return build_check_this (stmt, this_arg);
}
static tree
getVolatile_builtin (tree method_return_type ATTRIBUTE_UNUSED,
tree orig_call)
{
tree addr, stmt, modify_stmt, tmp;
UNMARSHAL3 (orig_call);
addr = build_addr_sum (method_return_type, obj_arg, offset_arg);
addr
= fold_convert (build_pointer_type (build_type_variant
(method_return_type, 0, 1)), addr);
stmt = build_call_expr (built_in_decls[BUILT_IN_SYNCHRONIZE], 0);
tmp = build_decl (VAR_DECL, NULL, method_return_type);
DECL_IGNORED_P (tmp) = 1;
DECL_ARTIFICIAL (tmp) = 1;
pushdecl (tmp);
modify_stmt = fold_build2 (MODIFY_EXPR, method_return_type,
tmp,
build_java_indirect_ref (method_return_type, addr,
flag_check_references));
stmt = build2 (COMPOUND_EXPR, void_type_node, modify_stmt, stmt);
stmt = build2 (COMPOUND_EXPR, method_return_type, stmt, tmp);
return stmt;
}
static tree
VMSupportsCS8_builtin (tree method_return_type,
tree orig_call ATTRIBUTE_UNUSED)
{
enum machine_mode mode = TYPE_MODE (long_type_node);
gcc_assert (method_return_type == boolean_type_node);
if (sync_compare_and_swap_cc[mode] != CODE_FOR_nothing
|| sync_compare_and_swap[mode] != CODE_FOR_nothing)
return boolean_true_node;
else
return boolean_false_node;
}
#define BUILTIN_NOTHROW 1
#define BUILTIN_CONST 2
/* Define a single builtin. */
static void
define_builtin (enum built_in_function val,
const char *name,
tree type,
const char *libname,
int flags)
{
tree decl;
decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
SET_DECL_ASSEMBLER_NAME (decl, get_identifier (libname));
pushdecl (decl);
DECL_BUILT_IN_CLASS (decl) = BUILT_IN_NORMAL;
DECL_FUNCTION_CODE (decl) = val;
if (flags & BUILTIN_NOTHROW)
TREE_NOTHROW (decl) = 1;
if (flags & BUILTIN_CONST)
TREE_READONLY (decl) = 1;
implicit_built_in_decls[val] = decl;
built_in_decls[val] = decl;
}
/* Initialize the builtins. */
void
initialize_builtins (void)
{
tree double_ftype_double, double_ftype_double_double;
tree float_ftype_float, float_ftype_float_float;
tree boolean_ftype_boolean_boolean;
tree t;
int i;
for (i = 0; java_builtins[i].builtin_code != END_BUILTINS; ++i)
{
tree klass_id = get_identifier (java_builtins[i].class_name.s);
tree m = get_identifier (java_builtins[i].method_name.s);
java_builtins[i].class_name.t = klass_id;
java_builtins[i].method_name.t = m;
}
void_list_node = end_params_node;
t = tree_cons (NULL_TREE, float_type_node, end_params_node);
float_ftype_float = build_function_type (float_type_node, t);
t = tree_cons (NULL_TREE, float_type_node, t);
float_ftype_float_float = build_function_type (float_type_node, t);
t = tree_cons (NULL_TREE, double_type_node, end_params_node);
double_ftype_double = build_function_type (double_type_node, t);
t = tree_cons (NULL_TREE, double_type_node, t);
double_ftype_double_double = build_function_type (double_type_node, t);
define_builtin (BUILT_IN_FMOD, "__builtin_fmod",
double_ftype_double_double, "fmod", BUILTIN_CONST);
define_builtin (BUILT_IN_FMODF, "__builtin_fmodf",
float_ftype_float_float, "fmodf", BUILTIN_CONST);
define_builtin (BUILT_IN_ACOS, "__builtin_acos",
double_ftype_double, "_ZN4java4lang4Math4acosEJdd",
BUILTIN_CONST);
define_builtin (BUILT_IN_ASIN, "__builtin_asin",
double_ftype_double, "_ZN4java4lang4Math4asinEJdd",
BUILTIN_CONST);
define_builtin (BUILT_IN_ATAN, "__builtin_atan",
double_ftype_double, "_ZN4java4lang4Math4atanEJdd",
BUILTIN_CONST);
define_builtin (BUILT_IN_ATAN2, "__builtin_atan2",
double_ftype_double_double, "_ZN4java4lang4Math5atan2EJddd",
BUILTIN_CONST);
define_builtin (BUILT_IN_CEIL, "__builtin_ceil",
double_ftype_double, "_ZN4java4lang4Math4ceilEJdd",
BUILTIN_CONST);
define_builtin (BUILT_IN_COS, "__builtin_cos",
double_ftype_double, "_ZN4java4lang4Math3cosEJdd",
BUILTIN_CONST);
define_builtin (BUILT_IN_EXP, "__builtin_exp",
double_ftype_double, "_ZN4java4lang4Math3expEJdd",
BUILTIN_CONST);
define_builtin (BUILT_IN_FLOOR, "__builtin_floor",
double_ftype_double, "_ZN4java4lang4Math5floorEJdd",
BUILTIN_CONST);
define_builtin (BUILT_IN_LOG, "__builtin_log",
double_ftype_double, "_ZN4java4lang4Math3logEJdd",
BUILTIN_CONST);
define_builtin (BUILT_IN_POW, "__builtin_pow",
double_ftype_double_double, "_ZN4java4lang4Math3powEJddd",
BUILTIN_CONST);
define_builtin (BUILT_IN_SIN, "__builtin_sin",
double_ftype_double, "_ZN4java4lang4Math3sinEJdd",
BUILTIN_CONST);
define_builtin (BUILT_IN_SQRT, "__builtin_sqrt",
double_ftype_double, "_ZN4java4lang4Math4sqrtEJdd",
BUILTIN_CONST);
define_builtin (BUILT_IN_TAN, "__builtin_tan",
double_ftype_double, "_ZN4java4lang4Math3tanEJdd",
BUILTIN_CONST);
t = tree_cons (NULL_TREE, boolean_type_node, end_params_node);
t = tree_cons (NULL_TREE, boolean_type_node, t);
boolean_ftype_boolean_boolean = build_function_type (boolean_type_node, t);
define_builtin (BUILT_IN_EXPECT, "__builtin_expect",
boolean_ftype_boolean_boolean,
"__builtin_expect",
BUILTIN_CONST | BUILTIN_NOTHROW);
define_builtin (BUILT_IN_BOOL_COMPARE_AND_SWAP_4,
"__sync_bool_compare_and_swap_4",
build_function_type_list (boolean_type_node,
int_type_node,
build_pointer_type (int_type_node),
int_type_node, NULL_TREE),
"__sync_bool_compare_and_swap_4", 0);
define_builtin (BUILT_IN_BOOL_COMPARE_AND_SWAP_8,
"__sync_bool_compare_and_swap_8",
build_function_type_list (boolean_type_node,
long_type_node,
build_pointer_type (long_type_node),
int_type_node, NULL_TREE),
"__sync_bool_compare_and_swap_8", 0);
define_builtin (BUILT_IN_SYNCHRONIZE, "__sync_synchronize",
build_function_type (void_type_node, void_list_node),
"__sync_synchronize", BUILTIN_NOTHROW);
define_builtin (BUILT_IN_RETURN_ADDRESS, "__builtin_return_address",
build_function_type_list (ptr_type_node, int_type_node, NULL_TREE),
"__builtin_return_address", BUILTIN_NOTHROW);
build_common_builtin_nodes ();
}
/* If the call matches a builtin, return the
appropriate builtin expression instead. */
tree
check_for_builtin (tree method, tree call)
{
if (optimize && TREE_CODE (call) == CALL_EXPR)
{
int i;
tree method_class = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
tree method_name = DECL_NAME (method);
tree method_return_type = TREE_TYPE (TREE_TYPE (method));
for (i = 0; java_builtins[i].builtin_code != END_BUILTINS; ++i)
{
if (method_class == java_builtins[i].class_name.t
&& method_name == java_builtins[i].method_name.t)
{
tree fn;
if (java_builtins[i].creator != NULL)
{
tree result
= (*java_builtins[i].creator) (method_return_type, call);
return result == NULL_TREE ? call : result;
}
/* Builtin functions emit a direct call which is incompatible
with the BC-ABI. */
if (flag_indirect_dispatch)
return call;
fn = built_in_decls[java_builtins[i].builtin_code];
if (fn == NULL_TREE)
return call;
return java_build_function_call_expr (fn, call);
}
}
}
return call;
}
#include "gt-java-builtins.h"