2005-08-01 09:26:30 +02:00
|
|
|
/* Interprocedural analyses.
|
2007-07-26 10:37:01 +02:00
|
|
|
Copyright (C) 2005, 2007 Free Software Foundation, Inc.
|
2005-08-01 09:26:30 +02:00
|
|
|
|
|
|
|
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
|
2007-07-26 10:37:01 +02:00
|
|
|
Software Foundation; either version 3, or (at your option) any later
|
2005-08-01 09:26:30 +02:00
|
|
|
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
|
2007-07-26 10:37:01 +02:00
|
|
|
along with GCC; see the file COPYING3. If not see
|
|
|
|
<http://www.gnu.org/licenses/>. */
|
2005-08-01 09:26:30 +02:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include "system.h"
|
|
|
|
#include "coretypes.h"
|
|
|
|
#include "tree.h"
|
|
|
|
#include "langhooks.h"
|
|
|
|
#include "ggc.h"
|
|
|
|
#include "target.h"
|
|
|
|
#include "cgraph.h"
|
|
|
|
#include "ipa-prop.h"
|
|
|
|
#include "tree-flow.h"
|
|
|
|
#include "tree-pass.h"
|
2008-07-08 15:25:24 +02:00
|
|
|
#include "tree-inline.h"
|
2005-08-01 09:26:30 +02:00
|
|
|
#include "flags.h"
|
|
|
|
#include "timevar.h"
|
2008-07-08 15:25:24 +02:00
|
|
|
#include "flags.h"
|
2008-07-23 21:45:45 +02:00
|
|
|
#include "diagnostic.h"
|
2008-07-08 15:25:24 +02:00
|
|
|
|
|
|
|
/* Vector where the parameter infos are actually stored. */
|
|
|
|
VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
|
|
|
|
/* Vector where the parameter infos are actually stored. */
|
|
|
|
VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector;
|
|
|
|
|
|
|
|
/* Holders of ipa cgraph hooks: */
|
|
|
|
struct cgraph_edge_hook_list *edge_removal_hook_holder;
|
|
|
|
struct cgraph_node_hook_list *node_removal_hook_holder;
|
|
|
|
struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
|
|
|
|
struct cgraph_2node_hook_list *node_duplication_hook_holder;
|
2005-08-01 09:26:30 +02:00
|
|
|
|
2008-04-30 12:01:59 +02:00
|
|
|
/* Initialize worklist to contain all functions. */
|
|
|
|
struct ipa_func_list *
|
|
|
|
ipa_init_func_list (void)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
|
|
|
struct cgraph_node *node;
|
2008-04-30 12:01:59 +02:00
|
|
|
struct ipa_func_list * wl;
|
2005-08-01 09:26:30 +02:00
|
|
|
|
|
|
|
wl = NULL;
|
|
|
|
for (node = cgraph_nodes; node; node = node->next)
|
2008-07-17 15:23:32 +02:00
|
|
|
if (node->analyzed)
|
|
|
|
{
|
|
|
|
/* Unreachable nodes should have been eliminated before ipcp and
|
|
|
|
inlining. */
|
|
|
|
gcc_assert (node->needed || node->reachable);
|
|
|
|
ipa_push_func_to_list (&wl, node);
|
|
|
|
}
|
2005-08-01 09:26:30 +02:00
|
|
|
|
|
|
|
return wl;
|
|
|
|
}
|
|
|
|
|
2008-04-30 12:01:59 +02:00
|
|
|
/* Add cgraph node MT to the worklist. Set worklist element WL
|
2005-08-01 09:26:30 +02:00
|
|
|
to point to MT. */
|
|
|
|
void
|
2008-04-30 12:01:59 +02:00
|
|
|
ipa_push_func_to_list (struct ipa_func_list **wl, struct cgraph_node *mt)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-04-30 12:01:59 +02:00
|
|
|
struct ipa_func_list *temp;
|
2005-08-01 09:26:30 +02:00
|
|
|
|
driver-i386.c (detect_caches_amd, [...]): Fix -Wc++-compat and/or -Wcast-qual warnings.
* config/i386/driver-i386.c (detect_caches_amd,
detect_caches_intel, host_detect_local_cpu): Fix -Wc++-compat
and/or -Wcast-qual warnings.
*ggc-common.c (ggc_mark_roots, gt_pch_note_object,
gt_pch_note_reorder, relocate_ptrs, write_pch_globals,
gt_pch_save): Likewise.
* ggc-page.c (push_depth, push_by_depth, alloc_anon, alloc_page,
gt_ggc_m_S, clear_marks, ggc_pch_read): Likewise.
* global.c (compute_regsets): Likewise.
* graph.c (print_rtl_graph_with_bb, clean_graph_dump_file,
finish_graph_dump_file): Likewise.
* haifa-sched.c (schedule_block, extend_h_i_d, extend_ready,
unlink_bb_notes): Likewise.
* integrate.c (get_hard_reg_initial_val): Likewise.
* ipa-prop.c (ipa_push_func_to_list): Likewise.
* ipa-struct-reorg.c (gen_var_name, gen_cluster_name): Likewise.
* local-alloc.c (update_equiv_regs): Likewise.
* loop-invariant.c (check_invariant_table_size,
hash_invariant_expr, eq_invariant_expr, find_or_insert_inv):
Likewise.
* loop-iv.c (check_iv_ref_table_size, analyzed_for_bivness_p,
altered_reg_used, mark_altered): Likewise.
* loop-unroll.c (si_info_eq, ve_info_eq, allocate_basic_variable,
insert_var_expansion_initialization,
combine_var_copies_in_loop_exit, apply_opt_in_copies,
release_var_copies): Likewise.
* matrix-reorg.c (mat_acc_phi_hash, mat_acc_phi_eq, mtt_info_eq,
analyze_matrix_decl, add_allocation_site, analyze_transpose,
analyze_accesses_for_phi_node, check_var_notmodified_p,
check_allocation_function, find_sites_in_func,
record_all_accesses_in_func, transform_access_sites,
transform_allocation_sites): Likewise.
* omp-low.c (new_omp_region, create_omp_child_function_name,
check_omp_nesting_restrictions, check_combined_parallel,
lower_omp_2, diagnose_sb_1, diagnose_sb_2): Likewise.
* optabs.c (no_conflict_move_test, gen_libfunc, gen_fp_libfunc,
gen_intv_fp_libfunc, gen_interclass_conv_libfunc,
gen_intraclass_conv_libfunc, set_optab_libfunc, set_conv_libfunc):
Likewise.
* opts-common.c (prune_options): Likewise.
* opts.c (add_input_filename, print_filtered_help,
get_option_state): Likewise.
* params.c (add_params): Likewise.
* passes.c (set_pass_for_id, next_pass_1,
do_per_function_toporder, pass_fini_dump_file): Likewise.
* postreload.c (reload_cse_simplify_operands): Likewise.
* predict.c (tree_predicted_by_p, tree_predict_edge,
clear_bb_predictions, combine_predictions_for_bb): Likewise.
From-SVN: r137134
2008-06-26 02:18:25 +02:00
|
|
|
temp = XCNEW (struct ipa_func_list);
|
2008-04-30 12:01:59 +02:00
|
|
|
temp->node = mt;
|
|
|
|
temp->next = *wl;
|
2005-08-01 09:26:30 +02:00
|
|
|
*wl = temp;
|
|
|
|
}
|
|
|
|
|
2008-04-30 12:01:59 +02:00
|
|
|
/* Remove a function from the worklist. WL points to the first
|
2005-08-01 09:26:30 +02:00
|
|
|
element in the list, which is removed. */
|
|
|
|
struct cgraph_node *
|
2008-04-30 12:01:59 +02:00
|
|
|
ipa_pop_func_from_list (struct ipa_func_list ** wl)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-04-30 12:01:59 +02:00
|
|
|
struct ipa_func_list *first;
|
|
|
|
struct cgraph_node *return_func;
|
2005-08-01 09:26:30 +02:00
|
|
|
|
|
|
|
first = *wl;
|
2008-04-30 12:01:59 +02:00
|
|
|
*wl = (*wl)->next;
|
|
|
|
return_func = first->node;
|
2005-08-01 09:26:30 +02:00
|
|
|
free (first);
|
2008-04-30 12:01:59 +02:00
|
|
|
return return_func;
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
|
|
|
|
2008-04-30 12:01:59 +02:00
|
|
|
/* Return index of the formal whose tree is ptree in function which corresponds
|
|
|
|
to info. */
|
2005-08-01 09:26:30 +02:00
|
|
|
static int
|
2008-04-30 12:01:59 +02:00
|
|
|
ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
|
|
|
int i, count;
|
|
|
|
|
2008-04-30 12:01:59 +02:00
|
|
|
count = ipa_get_param_count (info);
|
2005-08-01 09:26:30 +02:00
|
|
|
for (i = 0; i < count; i++)
|
2008-04-30 12:01:59 +02:00
|
|
|
if (ipa_get_ith_param(info, i) == ptree)
|
2005-08-01 09:26:30 +02:00
|
|
|
return i;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-04-30 12:01:59 +02:00
|
|
|
/* Insert the formal trees to the param_decls array in function MT. */
|
2005-08-01 09:26:30 +02:00
|
|
|
void
|
2008-04-30 12:01:59 +02:00
|
|
|
ipa_create_param_decls_array (struct cgraph_node *mt)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
|
|
|
tree fndecl;
|
|
|
|
tree fnargs;
|
|
|
|
tree parm;
|
|
|
|
int param_num;
|
2008-04-30 12:01:59 +02:00
|
|
|
struct ipa_node_params *info = IPA_NODE_REF (mt);
|
2005-08-01 09:26:30 +02:00
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
if (info->param_decls)
|
|
|
|
return;
|
|
|
|
|
2008-04-30 12:01:59 +02:00
|
|
|
info->param_decls = XCNEWVEC (tree, ipa_get_param_count (info));
|
2005-08-01 09:26:30 +02:00
|
|
|
fndecl = mt->decl;
|
|
|
|
fnargs = DECL_ARGUMENTS (fndecl);
|
|
|
|
param_num = 0;
|
|
|
|
for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
|
|
|
|
{
|
2008-04-30 12:01:59 +02:00
|
|
|
info->param_decls[param_num] = parm;
|
2005-08-01 09:26:30 +02:00
|
|
|
param_num++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Count number of formals in MT. Insert the result to the
|
2008-04-30 12:01:59 +02:00
|
|
|
ipa_node_params. */
|
2005-08-01 09:26:30 +02:00
|
|
|
void
|
2008-04-30 12:01:59 +02:00
|
|
|
ipa_count_formal_params (struct cgraph_node *mt)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
|
|
|
tree fndecl;
|
|
|
|
tree fnargs;
|
|
|
|
tree parm;
|
|
|
|
int param_num;
|
|
|
|
|
|
|
|
fndecl = mt->decl;
|
|
|
|
fnargs = DECL_ARGUMENTS (fndecl);
|
|
|
|
param_num = 0;
|
|
|
|
for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
|
|
|
|
param_num++;
|
2008-04-30 12:01:59 +02:00
|
|
|
ipa_set_param_count (IPA_NODE_REF (mt), param_num);
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
/* Check STMT to detect whether a formal parameter is directly modified within
|
|
|
|
STMT, the appropriate entry is updated in the modified flags of INFO.
|
|
|
|
Directly means that this function does not check for modifications through
|
|
|
|
pointers or escaping addresses because all TREE_ADDRESSABLE parameters are
|
|
|
|
considered modified anyway. */
|
2005-08-01 09:26:30 +02:00
|
|
|
static void
|
2008-07-23 21:45:45 +02:00
|
|
|
ipa_check_stmt_modifications (struct ipa_node_params *info, tree stmt)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-23 21:45:45 +02:00
|
|
|
int j;
|
|
|
|
int index;
|
|
|
|
tree lhs;
|
2005-08-01 09:26:30 +02:00
|
|
|
|
|
|
|
switch (TREE_CODE (stmt))
|
|
|
|
{
|
2006-12-05 18:26:05 +01:00
|
|
|
case GIMPLE_MODIFY_STMT:
|
2008-07-23 21:45:45 +02:00
|
|
|
lhs = GIMPLE_STMT_OPERAND (stmt, 0);
|
|
|
|
|
|
|
|
while (handled_component_p (lhs))
|
|
|
|
lhs = TREE_OPERAND (lhs, 0);
|
|
|
|
if (TREE_CODE (lhs) == SSA_NAME)
|
|
|
|
lhs = SSA_NAME_VAR (lhs);
|
|
|
|
index = ipa_get_param_decl_index (info, lhs);
|
|
|
|
if (index >= 0)
|
|
|
|
info->param_flags[index].modified = true;
|
2005-08-01 09:26:30 +02:00
|
|
|
break;
|
2008-07-23 21:45:45 +02:00
|
|
|
|
2005-08-01 09:26:30 +02:00
|
|
|
case ASM_EXPR:
|
|
|
|
/* Asm code could modify any of the parameters. */
|
2008-07-23 21:45:45 +02:00
|
|
|
for (j = 0; j < ipa_get_param_count (info); j++)
|
|
|
|
info->param_flags[j].modified = true;
|
2005-08-01 09:26:30 +02:00
|
|
|
break;
|
2008-07-23 21:45:45 +02:00
|
|
|
|
2005-08-01 09:26:30 +02:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
/* Compute which formal parameters of function associated with NODE are locally
|
|
|
|
modified. Parameters may be modified in NODE if they are TREE_ADDRESSABLE,
|
|
|
|
if they appear on the left hand side of an assignment or if there is an
|
|
|
|
ASM_EXPR in the function. */
|
2005-08-01 09:26:30 +02:00
|
|
|
void
|
2008-07-23 21:45:45 +02:00
|
|
|
ipa_detect_param_modifications (struct cgraph_node *node)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-23 21:45:45 +02:00
|
|
|
tree decl = node->decl;
|
2005-08-01 09:26:30 +02:00
|
|
|
basic_block bb;
|
|
|
|
struct function *func;
|
|
|
|
block_stmt_iterator bsi;
|
2008-07-23 21:45:45 +02:00
|
|
|
tree stmt;
|
|
|
|
struct ipa_node_params *info = IPA_NODE_REF (node);
|
|
|
|
int i, count;
|
2005-08-01 09:26:30 +02:00
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
if (ipa_get_param_count (info) == 0 || info->modification_analysis_done)
|
2007-01-28 14:01:53 +01:00
|
|
|
return;
|
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
if (!info->param_flags)
|
|
|
|
info->param_flags = XCNEWVEC (struct ipa_param_flags,
|
|
|
|
ipa_get_param_count (info));
|
2007-01-28 14:01:53 +01:00
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
func = DECL_STRUCT_FUNCTION (decl);
|
|
|
|
FOR_EACH_BB_FN (bb, func)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-23 21:45:45 +02:00
|
|
|
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
|
|
|
{
|
|
|
|
stmt = bsi_stmt (bsi);
|
|
|
|
ipa_check_stmt_modifications (info, stmt);
|
|
|
|
}
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
2008-07-23 21:45:45 +02:00
|
|
|
|
|
|
|
count = ipa_get_param_count (info);
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
if (TREE_ADDRESSABLE (ipa_get_ith_param (info, i)))
|
|
|
|
info->param_flags[i].modified = true;
|
|
|
|
|
|
|
|
info->modification_analysis_done = 1;
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
/* Count number of arguments callsite CS has and store it in
|
2008-04-30 12:01:59 +02:00
|
|
|
ipa_edge_args structure corresponding to this callsite. */
|
2005-08-01 09:26:30 +02:00
|
|
|
void
|
2008-04-30 12:01:59 +02:00
|
|
|
ipa_count_arguments (struct cgraph_edge *cs)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
|
|
|
tree call_tree;
|
|
|
|
int arg_num;
|
|
|
|
|
2008-04-30 12:01:59 +02:00
|
|
|
call_tree = get_call_expr_in (cs->call_stmt);
|
2005-08-01 09:26:30 +02:00
|
|
|
gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
|
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-16 00:50:49 +01:00
|
|
|
arg_num = call_expr_nargs (call_tree);
|
2008-04-30 12:01:59 +02:00
|
|
|
ipa_set_cs_argument_count (IPA_EDGE_REF (cs), arg_num);
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
/* The following function prints the jump functions of all arguments on all
|
|
|
|
call graph edges going from NODE to file F. */
|
2005-08-01 09:26:30 +02:00
|
|
|
void
|
2008-07-23 21:45:45 +02:00
|
|
|
ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-23 21:45:45 +02:00
|
|
|
int i, count;
|
|
|
|
struct cgraph_edge *cs;
|
|
|
|
struct ipa_jump_func *jump_func;
|
|
|
|
enum jump_func_type type;
|
2005-08-01 09:26:30 +02:00
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
fprintf (f, "JUMP FUNCTIONS OF CALLER %s:\n", cgraph_node_name (node));
|
|
|
|
for (cs = node->callees; cs; cs = cs->next_callee)
|
|
|
|
{
|
|
|
|
if (!ipa_edge_args_info_available_for_edge_p (cs))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
fprintf (f, "callsite %s ", cgraph_node_name (node));
|
|
|
|
fprintf (f, "-> %s :: \n", cgraph_node_name (cs->callee));
|
2005-08-01 09:26:30 +02:00
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
|
|
|
|
type = jump_func->type;
|
|
|
|
|
|
|
|
fprintf (f, " param %d: ", i);
|
|
|
|
if (type == IPA_UNKNOWN)
|
|
|
|
fprintf (f, "UNKNOWN\n");
|
|
|
|
else if (type == IPA_CONST || type == IPA_CONST_REF)
|
|
|
|
{
|
|
|
|
tree val = jump_func->value.constant;
|
|
|
|
fprintf (f, "CONST: ");
|
|
|
|
print_generic_expr (f, val, 0);
|
|
|
|
fprintf (f, "\n");
|
|
|
|
}
|
|
|
|
else if (type == IPA_CONST_MEMBER_PTR)
|
|
|
|
{
|
|
|
|
fprintf (f, "CONST MEMBER PTR: ");
|
|
|
|
print_generic_expr (f, jump_func->value.member_cst.pfn, 0);
|
|
|
|
fprintf (f, ", ");
|
|
|
|
print_generic_expr (f, jump_func->value.member_cst.delta, 0);
|
|
|
|
fprintf (f, "\n");
|
|
|
|
}
|
|
|
|
else if (type == IPA_PASS_THROUGH)
|
|
|
|
{
|
|
|
|
fprintf (f, "PASS THROUGH: ");
|
|
|
|
fprintf (f, "%d\n", jump_func->value.formal_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Print ipa_jump_func data structures of all nodes in the call graph to F. */
|
|
|
|
void
|
|
|
|
ipa_print_all_jump_functions (FILE *f)
|
|
|
|
{
|
|
|
|
struct cgraph_node *node;
|
|
|
|
|
|
|
|
fprintf (f, "\nCALLSITE PARAM PRINT\n");
|
|
|
|
for (node = cgraph_nodes; node; node = node->next)
|
|
|
|
{
|
|
|
|
ipa_print_node_jump_functions (f, node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The following function determines the jump functions of scalar arguments.
|
|
|
|
Scalar means SSA names and constants of a number of selected types. INFO is
|
|
|
|
the ipa_node_params structure associated with the caller, FUNCTIONS is a
|
|
|
|
pointer to an array of jump function structures associated with CALL which
|
|
|
|
is the call statement being examined.*/
|
|
|
|
static void
|
|
|
|
compute_scalar_jump_functions (struct ipa_node_params *info,
|
|
|
|
struct ipa_jump_func *functions,
|
|
|
|
tree call)
|
|
|
|
{
|
|
|
|
call_expr_arg_iterator iter;
|
|
|
|
tree arg;
|
|
|
|
int num = 0;
|
|
|
|
|
|
|
|
FOR_EACH_CALL_EXPR_ARG (arg, iter, call)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-23 21:45:45 +02:00
|
|
|
if (TREE_CODE (arg) == INTEGER_CST
|
|
|
|
|| TREE_CODE (arg) == REAL_CST
|
|
|
|
|| TREE_CODE (arg) == FIXED_CST)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-23 21:45:45 +02:00
|
|
|
functions[num].type = IPA_CONST;
|
|
|
|
functions[num].value.constant = arg;
|
|
|
|
}
|
|
|
|
else if (TREE_CODE (arg) == ADDR_EXPR)
|
|
|
|
{
|
|
|
|
if (TREE_CODE (TREE_OPERAND (arg, 0)) == FUNCTION_DECL)
|
2007-01-28 14:01:53 +01:00
|
|
|
{
|
2008-07-23 21:45:45 +02:00
|
|
|
functions[num].type = IPA_CONST;
|
|
|
|
functions[num].value.constant = TREE_OPERAND (arg, 0);
|
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-16 00:50:49 +01:00
|
|
|
}
|
2008-07-23 21:45:45 +02:00
|
|
|
else if (TREE_CODE (TREE_OPERAND (arg, 0)) == CONST_DECL)
|
|
|
|
{
|
|
|
|
tree cst_decl = TREE_OPERAND (arg, 0);
|
|
|
|
|
|
|
|
if (TREE_CODE (DECL_INITIAL (cst_decl)) == INTEGER_CST
|
|
|
|
|| TREE_CODE (DECL_INITIAL (cst_decl)) == REAL_CST
|
|
|
|
|| TREE_CODE (DECL_INITIAL (cst_decl)) == FIXED_CST)
|
|
|
|
{
|
|
|
|
functions[num].type = IPA_CONST_REF;
|
|
|
|
functions[num].value.constant = cst_decl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ((TREE_CODE (arg) == SSA_NAME) && SSA_NAME_IS_DEFAULT_DEF (arg))
|
|
|
|
{
|
|
|
|
int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
|
|
|
|
|
|
|
|
if (index >= 0)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-23 21:45:45 +02:00
|
|
|
functions[num].type = IPA_PASS_THROUGH;
|
|
|
|
functions[num].value.formal_id = index;
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
|
|
|
}
|
2008-07-23 21:45:45 +02:00
|
|
|
|
|
|
|
num++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This function inspects the given TYPE and returns true iff it has the same
|
|
|
|
structure (the same number of fields of the same types) as a C++ member
|
|
|
|
pointer. If METHOD_PTR and DELTA are non-NULL, the trees representing the
|
|
|
|
corresponding fields are stored there. */
|
|
|
|
static bool
|
|
|
|
type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
|
|
|
|
{
|
|
|
|
tree fld;
|
|
|
|
|
|
|
|
if (TREE_CODE (type) != RECORD_TYPE)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
fld = TYPE_FIELDS (type);
|
|
|
|
if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
|
|
|
|
|| TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (method_ptr)
|
|
|
|
*method_ptr = fld;
|
|
|
|
|
|
|
|
fld = TREE_CHAIN (fld);
|
|
|
|
if (!fld || INTEGRAL_TYPE_P (fld))
|
|
|
|
return false;
|
|
|
|
if (delta)
|
|
|
|
*delta = fld;
|
|
|
|
|
|
|
|
if (TREE_CHAIN (fld))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This function goes through arguments of the CALL and for every one that
|
|
|
|
looks like a member pointer, it checks whether it can be safely declared
|
|
|
|
pass-through and if so, marks that to the corresponding item of jum
|
|
|
|
FUNCTIONS . It returns true iff there were non-pass-through member pointers
|
|
|
|
within the arguments. INFO describes formal parameters of the caller. */
|
|
|
|
static bool
|
|
|
|
compute_pass_through_member_ptrs (struct ipa_node_params *info,
|
|
|
|
struct ipa_jump_func *functions,
|
|
|
|
tree call)
|
|
|
|
{
|
|
|
|
call_expr_arg_iterator iter;
|
|
|
|
bool undecided_members = false;
|
|
|
|
int num = 0;
|
|
|
|
tree arg;
|
|
|
|
|
|
|
|
FOR_EACH_CALL_EXPR_ARG (arg, iter, call)
|
|
|
|
{
|
|
|
|
if (type_like_member_ptr_p (TREE_TYPE (arg), NULL, NULL))
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-23 21:45:45 +02:00
|
|
|
if (TREE_CODE (arg) == PARM_DECL)
|
|
|
|
{
|
|
|
|
int index = ipa_get_param_decl_index (info, arg);
|
|
|
|
|
|
|
|
gcc_assert (index >=0);
|
|
|
|
if (!ipa_is_ith_param_modified (info, index))
|
|
|
|
{
|
|
|
|
functions[num].type = IPA_PASS_THROUGH;
|
|
|
|
functions[num].value.formal_id = index;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
undecided_members = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
undecided_members = true;
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
2008-07-23 21:45:45 +02:00
|
|
|
|
|
|
|
num++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return undecided_members;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Simple function filling in a member pointer constant jump function (with PFN
|
|
|
|
and DELTA as the constant value) into JFUNC. */
|
|
|
|
static void
|
|
|
|
fill_member_ptr_cst_jump_function (struct ipa_jump_func *jfunc,
|
|
|
|
tree pfn, tree delta)
|
|
|
|
{
|
|
|
|
jfunc->type = IPA_CONST_MEMBER_PTR;
|
|
|
|
jfunc->value.member_cst.pfn = pfn;
|
|
|
|
jfunc->value.member_cst.delta = delta;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Traverse statements from CALL_STMT backwards, scanning whether the argument
|
|
|
|
ARG which is a member pointer is filled in with constant values. If it is,
|
|
|
|
fill the jump function JFUNC in appropriately. METHOD_FIELD and DELTA_FIELD
|
|
|
|
are fields of the record type of the member pointer. To give an example, we
|
|
|
|
look for a pattern looking like the following:
|
|
|
|
|
|
|
|
D.2515.__pfn ={v} printStuff;
|
|
|
|
D.2515.__delta ={v} 0;
|
|
|
|
i_1 = doprinting (D.2515); */
|
|
|
|
static void
|
|
|
|
determine_cst_member_ptr (tree call_stmt, tree arg, tree method_field,
|
|
|
|
tree delta_field, struct ipa_jump_func *jfunc)
|
|
|
|
{
|
|
|
|
block_stmt_iterator bsi;
|
|
|
|
tree method = NULL_TREE;
|
|
|
|
tree delta = NULL_TREE;
|
|
|
|
|
|
|
|
bsi = bsi_for_stmt (call_stmt);
|
|
|
|
|
|
|
|
bsi_prev (&bsi);
|
|
|
|
for (; !bsi_end_p (bsi); bsi_prev (&bsi))
|
|
|
|
{
|
|
|
|
tree stmt = bsi_stmt (bsi);
|
|
|
|
tree lhs, rhs, fld;
|
|
|
|
|
|
|
|
if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
|
|
|
|
return;
|
|
|
|
|
|
|
|
rhs = GIMPLE_STMT_OPERAND (stmt, 1);
|
|
|
|
if (TREE_CODE (rhs) == CALL_EXPR)
|
|
|
|
return;
|
|
|
|
|
|
|
|
lhs = GIMPLE_STMT_OPERAND (stmt, 0);
|
|
|
|
|
|
|
|
if (TREE_CODE (lhs) != COMPONENT_REF
|
|
|
|
|| TREE_OPERAND (lhs, 0) != arg)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
fld = TREE_OPERAND (lhs, 1);
|
|
|
|
if (!method && fld == method_field)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-23 21:45:45 +02:00
|
|
|
if (TREE_CODE (rhs) == ADDR_EXPR
|
|
|
|
&& TREE_CODE (TREE_OPERAND (rhs, 0)) == FUNCTION_DECL
|
|
|
|
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) == METHOD_TYPE)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-23 21:45:45 +02:00
|
|
|
method = TREE_OPERAND (rhs, 0);
|
|
|
|
if (delta)
|
|
|
|
{
|
|
|
|
fill_member_ptr_cst_jump_function (jfunc, method, delta);
|
|
|
|
return;
|
|
|
|
}
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
2008-07-23 21:45:45 +02:00
|
|
|
else
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!delta && fld == delta_field)
|
|
|
|
{
|
|
|
|
if (TREE_CODE (rhs) == INTEGER_CST)
|
|
|
|
{
|
|
|
|
delta = rhs;
|
|
|
|
if (method)
|
|
|
|
{
|
|
|
|
fill_member_ptr_cst_jump_function (jfunc, method, delta);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Go through the arguments of the call in CALL_STMT and for every member
|
|
|
|
pointer within tries determine whether it is a constant. If it is, create a
|
|
|
|
corresponding constant jump function in FUNCTIONS which is an array of jump
|
|
|
|
functions associated with the call. */
|
|
|
|
static void
|
|
|
|
compute_cst_member_ptr_arguments (struct ipa_jump_func *functions,
|
|
|
|
tree call_stmt)
|
|
|
|
{
|
|
|
|
call_expr_arg_iterator iter;
|
|
|
|
int num = 0;
|
|
|
|
tree call = get_call_expr_in (call_stmt);
|
|
|
|
tree arg, method_field, delta_field;
|
|
|
|
|
|
|
|
FOR_EACH_CALL_EXPR_ARG (arg, iter, call)
|
|
|
|
{
|
|
|
|
if (functions[num].type == IPA_UNKNOWN
|
|
|
|
&& type_like_member_ptr_p (TREE_TYPE (arg), &method_field,
|
|
|
|
&delta_field))
|
|
|
|
determine_cst_member_ptr (call_stmt, arg, method_field,
|
|
|
|
delta_field, &functions[num]);
|
|
|
|
|
|
|
|
num++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compute jump function for all arguments of callsite CS and insert the
|
|
|
|
information in the jump_functions array in the ipa_edge_args corresponding
|
|
|
|
to this callsite. */
|
|
|
|
void
|
|
|
|
ipa_compute_jump_functions (struct cgraph_edge *cs)
|
|
|
|
{
|
|
|
|
struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
|
|
|
|
struct ipa_edge_args *arguments = IPA_EDGE_REF (cs);
|
|
|
|
tree call;
|
|
|
|
|
|
|
|
if (ipa_get_cs_argument_count (arguments) == 0 || arguments->jump_functions)
|
|
|
|
return;
|
|
|
|
arguments->jump_functions = XCNEWVEC (struct ipa_jump_func,
|
|
|
|
ipa_get_cs_argument_count (arguments));
|
|
|
|
call = get_call_expr_in (cs->call_stmt);
|
|
|
|
|
|
|
|
/* We will deal with constants and SSA scalars first: */
|
|
|
|
compute_scalar_jump_functions (info, arguments->jump_functions, call);
|
|
|
|
|
|
|
|
/* Let's check whether there are any potential member pointers and if so,
|
|
|
|
whether we can determine their functions as pass_through. */
|
|
|
|
if (!compute_pass_through_member_ptrs (info, arguments->jump_functions, call))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Finally, let's check whether we actually pass a new constant membeer
|
|
|
|
pointer here... */
|
|
|
|
compute_cst_member_ptr_arguments (arguments->jump_functions, cs->call_stmt);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If RHS looks like a rhs of a statement loading pfn from a member pointer
|
|
|
|
formal parameter, return the parameter, otherwise return NULL. */
|
|
|
|
static tree
|
|
|
|
ipa_get_member_ptr_load_param (tree rhs)
|
|
|
|
{
|
|
|
|
tree rec, fld;
|
|
|
|
tree ptr_field;
|
|
|
|
|
|
|
|
if (TREE_CODE (rhs) != COMPONENT_REF)
|
|
|
|
return NULL_TREE;
|
|
|
|
|
|
|
|
rec = TREE_OPERAND (rhs, 0);
|
|
|
|
if (TREE_CODE (rec) != PARM_DECL
|
|
|
|
|| !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, NULL))
|
|
|
|
return NULL_TREE;
|
|
|
|
|
|
|
|
fld = TREE_OPERAND (rhs, 1);
|
|
|
|
if (fld == ptr_field)
|
|
|
|
return rec;
|
|
|
|
else
|
|
|
|
return NULL_TREE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If STMT looks like a statement loading a value from a member pointer formal
|
|
|
|
parameter, this function retuns that parameter. */
|
|
|
|
static tree
|
|
|
|
ipa_get_stmt_member_ptr_load_param (tree stmt)
|
|
|
|
{
|
|
|
|
tree rhs;
|
|
|
|
|
|
|
|
if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
|
|
|
|
return NULL_TREE;
|
|
|
|
|
|
|
|
rhs = GIMPLE_STMT_OPERAND (stmt, 1);
|
|
|
|
return ipa_get_member_ptr_load_param (rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns true iff T is an SSA_NAME defined by a statement. */
|
|
|
|
static bool
|
|
|
|
ipa_is_ssa_with_stmt_def (tree t)
|
|
|
|
{
|
|
|
|
if (TREE_CODE (t) == SSA_NAME
|
|
|
|
&& !SSA_NAME_IS_DEFAULT_DEF (t))
|
|
|
|
return true;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Creates a new note describing a call to a parameter number FORMAL_ID and
|
|
|
|
attaches it to the linked list of INFO. It also sets the called flag of the
|
|
|
|
parameter. STMT is the corresponding call statement. */
|
|
|
|
static void
|
|
|
|
ipa_note_param_call (struct ipa_node_params *info, int formal_id,
|
|
|
|
tree stmt)
|
|
|
|
{
|
|
|
|
struct ipa_param_call_note *note;
|
|
|
|
basic_block bb = bb_for_stmt (stmt);
|
|
|
|
|
|
|
|
info->param_flags[formal_id].called = 1;
|
|
|
|
|
|
|
|
note = XCNEW (struct ipa_param_call_note);
|
|
|
|
note->formal_id = formal_id;
|
|
|
|
note->stmt = stmt;
|
|
|
|
note->count = bb->count;
|
|
|
|
note->frequency = compute_call_stmt_bb_frequency (bb);
|
|
|
|
|
|
|
|
note->next = info->param_calls;
|
|
|
|
info->param_calls = note;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Analyze the CALL (which itself must be a part of statement STMT) and examine
|
|
|
|
uses of formal parameters of the caller (described by INFO). Currently it
|
|
|
|
checks whether the call calls a pointer that is a formal parameter and if
|
|
|
|
so, the parameter is marked with the called flag and a note describing the
|
|
|
|
call is created. This is very simple for ordinary pointers represented in
|
|
|
|
SSA but not-so-nice when it comes to member pointers. The ugly part of this
|
|
|
|
function does nothing more than tries to match the pattern of such a call.
|
|
|
|
An example of such a pattern is the gimple dump below, the call is on the
|
|
|
|
last line:
|
|
|
|
|
|
|
|
<bb 2>:
|
|
|
|
f$__delta_5 = f.__delta;
|
|
|
|
f$__pfn_24 = f.__pfn;
|
|
|
|
D.2496_3 = (int) f$__pfn_24;
|
|
|
|
D.2497_4 = D.2496_3 & 1;
|
|
|
|
if (D.2497_4 != 0)
|
|
|
|
goto <bb 3>;
|
|
|
|
else
|
|
|
|
goto <bb 4>;
|
|
|
|
|
|
|
|
<bb 3>:
|
|
|
|
D.2500_7 = (unsigned int) f$__delta_5;
|
|
|
|
D.2501_8 = &S + D.2500_7;
|
|
|
|
D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
|
|
|
|
D.2503_10 = *D.2502_9;
|
|
|
|
D.2504_12 = f$__pfn_24 + -1;
|
|
|
|
D.2505_13 = (unsigned int) D.2504_12;
|
|
|
|
D.2506_14 = D.2503_10 + D.2505_13;
|
|
|
|
D.2507_15 = *D.2506_14;
|
|
|
|
iftmp.11_16 = (String:: *) D.2507_15;
|
|
|
|
|
|
|
|
<bb 4>:
|
|
|
|
# iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
|
|
|
|
D.2500_19 = (unsigned int) f$__delta_5;
|
|
|
|
D.2508_20 = &S + D.2500_19;
|
|
|
|
D.2493_21 = iftmp.11_1 (D.2508_20, 4);
|
|
|
|
|
|
|
|
Such patterns are results of simple calls to a member pointer:
|
|
|
|
|
|
|
|
int doprinting (int (MyString::* f)(int) const)
|
|
|
|
{
|
|
|
|
MyString S ("somestring");
|
|
|
|
|
|
|
|
return (S.*f)(4);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
ipa_analyze_call_uses (struct ipa_node_params *info, tree call, tree stmt)
|
|
|
|
{
|
|
|
|
tree target = CALL_EXPR_FN (call);
|
|
|
|
tree var, def;
|
|
|
|
tree n1, n2;
|
|
|
|
tree d1, d2;
|
|
|
|
tree rec, rec2;
|
|
|
|
tree branch, cond;
|
|
|
|
int index;
|
|
|
|
|
|
|
|
basic_block bb, virt_bb, join;
|
|
|
|
|
|
|
|
if (TREE_CODE (target) != SSA_NAME)
|
|
|
|
return;
|
|
|
|
|
|
|
|
var = SSA_NAME_VAR (target);
|
|
|
|
if (SSA_NAME_IS_DEFAULT_DEF (target))
|
|
|
|
{
|
|
|
|
/* assuming TREE_CODE (var) == PARM_DECL */
|
|
|
|
index = ipa_get_param_decl_index (info, var);
|
|
|
|
if (index >= 0)
|
|
|
|
ipa_note_param_call (info, index, stmt);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now we need to try to match the complex pattern of calling a member
|
|
|
|
pointer. */
|
|
|
|
|
|
|
|
if (!POINTER_TYPE_P (TREE_TYPE (target))
|
|
|
|
|| TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
def = SSA_NAME_DEF_STMT (target);
|
|
|
|
if (TREE_CODE (def) != PHI_NODE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (PHI_NUM_ARGS (def) != 2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* First, we need to check whether one of these is a load from a member
|
|
|
|
pointer that is a parameter to this function. */
|
|
|
|
n1 = PHI_ARG_DEF (def, 0);
|
|
|
|
n2 = PHI_ARG_DEF (def, 1);
|
|
|
|
if (SSA_NAME_IS_DEFAULT_DEF (n1) || SSA_NAME_IS_DEFAULT_DEF (n2))
|
|
|
|
return;
|
|
|
|
d1 = SSA_NAME_DEF_STMT (n1);
|
|
|
|
d2 = SSA_NAME_DEF_STMT (n2);
|
|
|
|
|
|
|
|
if ((rec = ipa_get_stmt_member_ptr_load_param (d1)))
|
|
|
|
{
|
|
|
|
if (ipa_get_stmt_member_ptr_load_param (d2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
bb = bb_for_stmt (d1);
|
|
|
|
virt_bb = bb_for_stmt (d2);
|
|
|
|
}
|
|
|
|
else if ((rec = ipa_get_stmt_member_ptr_load_param (d2)))
|
|
|
|
{
|
|
|
|
bb = bb_for_stmt (d2);
|
|
|
|
virt_bb = bb_for_stmt (d1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Second, we need to check that the basic blocks are laid out in the way
|
|
|
|
corresponding to the pattern. */
|
|
|
|
|
|
|
|
join = bb_for_stmt (def);
|
|
|
|
if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
|
|
|
|
|| single_pred (virt_bb) != bb
|
|
|
|
|| single_succ (virt_bb) != join)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Third, let's see that the branching is done depending on the least
|
|
|
|
significant bit of the pfn. */
|
|
|
|
|
|
|
|
branch = last_stmt (bb);
|
|
|
|
if (TREE_CODE (branch) != COND_EXPR)
|
|
|
|
return;
|
|
|
|
|
|
|
|
cond = TREE_OPERAND (branch, 0);
|
|
|
|
if (TREE_CODE (cond) != NE_EXPR
|
|
|
|
|| !integer_zerop (TREE_OPERAND (cond, 1)))
|
|
|
|
return;
|
|
|
|
cond = TREE_OPERAND (cond, 0);
|
|
|
|
|
|
|
|
if (!ipa_is_ssa_with_stmt_def (cond))
|
|
|
|
return;
|
|
|
|
|
|
|
|
cond = SSA_NAME_DEF_STMT (cond);
|
|
|
|
if (TREE_CODE (cond) != GIMPLE_MODIFY_STMT)
|
|
|
|
return;
|
|
|
|
cond = GIMPLE_STMT_OPERAND (cond, 1);
|
|
|
|
if (TREE_CODE (cond) != BIT_AND_EXPR
|
|
|
|
|| !integer_onep (TREE_OPERAND (cond, 1)))
|
|
|
|
return;
|
|
|
|
cond = TREE_OPERAND (cond, 0);
|
|
|
|
if (!ipa_is_ssa_with_stmt_def (cond))
|
|
|
|
return;
|
|
|
|
|
|
|
|
cond = SSA_NAME_DEF_STMT (cond);
|
|
|
|
if (TREE_CODE (cond) != GIMPLE_MODIFY_STMT)
|
|
|
|
return;
|
|
|
|
cond = GIMPLE_STMT_OPERAND (cond, 1);
|
|
|
|
|
|
|
|
if (TREE_CODE (cond) == NOP_EXPR)
|
|
|
|
{
|
|
|
|
cond = TREE_OPERAND (cond, 0);
|
|
|
|
if (!ipa_is_ssa_with_stmt_def (cond))
|
|
|
|
return;
|
|
|
|
cond = SSA_NAME_DEF_STMT (cond);
|
|
|
|
if (TREE_CODE (cond) != GIMPLE_MODIFY_STMT)
|
|
|
|
return;
|
|
|
|
cond = GIMPLE_STMT_OPERAND (cond, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
rec2 = ipa_get_member_ptr_load_param (cond);
|
|
|
|
if (rec != rec2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
index = ipa_get_param_decl_index (info, rec);
|
|
|
|
if (index >= 0 && !ipa_is_ith_param_modified (info, index))
|
|
|
|
ipa_note_param_call (info, index, stmt);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Analyze the statement STMT with respect to formal parameters (described in
|
|
|
|
INFO) and their uses. Currently it only checks whether formal parameters
|
|
|
|
are called. */
|
|
|
|
static void
|
|
|
|
ipa_analyze_stmt_uses (struct ipa_node_params *info, tree stmt)
|
|
|
|
{
|
|
|
|
tree call = get_call_expr_in (stmt);
|
|
|
|
|
|
|
|
if (call)
|
|
|
|
ipa_analyze_call_uses (info, call, stmt);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Scan the function body of NODE and inspect the uses of formal parameters.
|
|
|
|
Store the findings in various structures of the associated ipa_node_params
|
|
|
|
structure, such as parameter flags, notes etc. */
|
|
|
|
void
|
|
|
|
ipa_analyze_params_uses (struct cgraph_node *node)
|
|
|
|
{
|
|
|
|
tree decl = node->decl;
|
|
|
|
basic_block bb;
|
|
|
|
struct function *func;
|
|
|
|
block_stmt_iterator bsi;
|
|
|
|
struct ipa_node_params *info = IPA_NODE_REF (node);
|
|
|
|
|
|
|
|
if (ipa_get_param_count (info) == 0 || info->uses_analysis_done
|
|
|
|
|| !DECL_SAVED_TREE (decl))
|
|
|
|
return;
|
|
|
|
if (!info->param_flags)
|
|
|
|
info->param_flags = XCNEWVEC (struct ipa_param_flags,
|
|
|
|
ipa_get_param_count (info));
|
|
|
|
|
|
|
|
func = DECL_STRUCT_FUNCTION (decl);
|
|
|
|
FOR_EACH_BB_FN (bb, func)
|
|
|
|
{
|
|
|
|
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
|
|
|
{
|
|
|
|
tree stmt = bsi_stmt (bsi);
|
|
|
|
ipa_analyze_stmt_uses (info, stmt);
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
|
|
|
}
|
2008-07-23 21:45:45 +02:00
|
|
|
|
|
|
|
info->uses_analysis_done = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update the jump functions assocated with call graph edge E when the call
|
|
|
|
graph edge CS is being inlined, assuming that E->caller is already (possibly
|
|
|
|
indirectly) inlined into CS->callee and that E has not been inlined. */
|
|
|
|
static void
|
|
|
|
update_jump_functions_after_inlining (struct cgraph_edge *cs,
|
|
|
|
struct cgraph_edge *e)
|
|
|
|
{
|
|
|
|
struct ipa_edge_args *top = IPA_EDGE_REF (cs);
|
|
|
|
struct ipa_edge_args *args = IPA_EDGE_REF (e);
|
|
|
|
int count = ipa_get_cs_argument_count (args);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
struct ipa_jump_func *src, *dst = ipa_get_ith_jump_func (args, i);
|
|
|
|
|
|
|
|
if (dst->type != IPA_PASS_THROUGH)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* We must check range due to calls with variable number of arguments: */
|
|
|
|
if (dst->value.formal_id >= (unsigned) ipa_get_cs_argument_count (top))
|
|
|
|
{
|
|
|
|
dst->type = IPA_BOTTOM;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
src = ipa_get_ith_jump_func (top, dst->value.formal_id);
|
|
|
|
*dst = *src;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Print out a debug message to file F that we have discovered that an indirect
|
|
|
|
call descibed by NT is in fact a call of a known constant function descibed
|
|
|
|
by JFUNC. NODE is the node where the call is. */
|
|
|
|
static void
|
|
|
|
print_edge_addition_message (FILE *f, struct ipa_param_call_note *nt,
|
|
|
|
struct ipa_jump_func *jfunc,
|
|
|
|
struct cgraph_node *node)
|
|
|
|
{
|
|
|
|
fprintf (f, "ipa-prop: Discovered an indirect call to a known target (");
|
|
|
|
if (jfunc->type == IPA_CONST_MEMBER_PTR)
|
|
|
|
{
|
|
|
|
print_node_brief (f, "", jfunc->value.member_cst.pfn, 0);
|
|
|
|
print_node_brief (f, ", ", jfunc->value.member_cst.delta, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
print_node_brief(f, "", jfunc->value.constant, 0);
|
|
|
|
|
|
|
|
fprintf (f, ") in %s: ", cgraph_node_name (node));
|
|
|
|
print_generic_stmt (f, nt->stmt, 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update the param called notes associated with NODE when CS is being inlined,
|
|
|
|
assuming NODE is (potentially indirectly) inlined into CS->callee.
|
|
|
|
Moreover, if the callee is discovered to be constant, create a new cgraph
|
|
|
|
edge for it. Newly discovered indirect edges will be added to NEW_EDGES,
|
|
|
|
unless it is NULL. */
|
|
|
|
static void
|
|
|
|
update_call_notes_after_inlining (struct cgraph_edge *cs,
|
|
|
|
struct cgraph_node *node,
|
|
|
|
VEC (cgraph_edge_p, heap) *new_edges)
|
|
|
|
{
|
|
|
|
struct ipa_node_params *info = IPA_NODE_REF (node);
|
|
|
|
struct ipa_edge_args *top = IPA_EDGE_REF (cs);
|
|
|
|
struct ipa_param_call_note *nt;
|
|
|
|
|
|
|
|
for (nt = info->param_calls; nt; nt = nt->next)
|
|
|
|
{
|
|
|
|
struct ipa_jump_func *jfunc;
|
|
|
|
|
|
|
|
if (nt->processed)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* We must check range due to calls with variable number of arguments: */
|
|
|
|
if (nt->formal_id >= (unsigned) ipa_get_cs_argument_count (top))
|
|
|
|
{
|
|
|
|
nt->processed = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
jfunc = ipa_get_ith_jump_func (top, nt->formal_id);
|
|
|
|
if (jfunc->type == IPA_PASS_THROUGH)
|
|
|
|
nt->formal_id = jfunc->value.formal_id;
|
|
|
|
else if (jfunc->type == IPA_CONST || jfunc->type == IPA_CONST_MEMBER_PTR)
|
|
|
|
{
|
|
|
|
struct cgraph_node *callee;
|
|
|
|
struct cgraph_edge *new_indirect_edge;
|
|
|
|
tree decl;
|
|
|
|
|
|
|
|
nt->processed = true;
|
|
|
|
if (jfunc->type == IPA_CONST_MEMBER_PTR)
|
|
|
|
decl = jfunc->value.member_cst.pfn;
|
|
|
|
else
|
|
|
|
decl = jfunc->value.constant;
|
|
|
|
|
|
|
|
if (TREE_CODE (decl) != FUNCTION_DECL)
|
|
|
|
continue;
|
|
|
|
callee = cgraph_node (decl);
|
|
|
|
if (!callee || !callee->local.inlinable)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (dump_file)
|
|
|
|
print_edge_addition_message (dump_file, nt, jfunc, node);
|
|
|
|
|
|
|
|
new_indirect_edge = cgraph_create_edge (node, callee, nt->stmt,
|
|
|
|
nt->count, nt->frequency,
|
|
|
|
nt->loop_nest);
|
|
|
|
new_indirect_edge->indirect_call = 1;
|
|
|
|
ipa_check_create_edge_args ();
|
|
|
|
if (new_edges)
|
|
|
|
VEC_safe_push (cgraph_edge_p, heap, new_edges, new_indirect_edge);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Recursively traverse subtree of NODE (including node) made of inlined
|
|
|
|
cgraph_edges when CS has been inlined and invoke
|
|
|
|
update_call_notes_after_inlining on all nodes and
|
|
|
|
update_jump_functions_after_inlining on all non-inlined edges that lead out
|
|
|
|
of this subtree. Newly discovered indirect edges will be added to
|
|
|
|
NEW_EDGES, unless it is NULL. */
|
|
|
|
static void
|
|
|
|
propagate_info_to_inlined_callees (struct cgraph_edge *cs,
|
|
|
|
struct cgraph_node *node,
|
|
|
|
VEC (cgraph_edge_p, heap) *new_edges)
|
|
|
|
{
|
|
|
|
struct cgraph_edge *e;
|
|
|
|
|
|
|
|
update_call_notes_after_inlining (cs, node, new_edges);
|
|
|
|
|
|
|
|
for (e = node->callees; e; e = e->next_callee)
|
|
|
|
if (!e->inline_failed)
|
|
|
|
propagate_info_to_inlined_callees (cs, e->callee, new_edges);
|
|
|
|
else
|
|
|
|
update_jump_functions_after_inlining (cs, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update jump functions and call note functions on inlining the call site CS.
|
|
|
|
CS is expected to lead to a node already cloned by
|
|
|
|
cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
|
|
|
|
NEW_EDGES, unless it is NULL. */
|
|
|
|
void
|
|
|
|
ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
|
|
|
|
VEC (cgraph_edge_p, heap) *new_edges)
|
|
|
|
{
|
|
|
|
propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
|
|
|
|
2008-07-08 15:25:24 +02:00
|
|
|
/* Frees all dynamically allocated structures that the argument info points
|
|
|
|
to. */
|
2005-08-01 09:26:30 +02:00
|
|
|
void
|
2008-07-08 15:25:24 +02:00
|
|
|
ipa_free_edge_args_substructures (struct ipa_edge_args *args)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-08 15:25:24 +02:00
|
|
|
if (args->jump_functions)
|
|
|
|
free (args->jump_functions);
|
|
|
|
|
|
|
|
memset (args, 0, sizeof (*args));
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
|
|
|
|
2008-07-08 15:25:24 +02:00
|
|
|
/* Free all ipa_edge structures. */
|
2005-08-01 09:26:30 +02:00
|
|
|
void
|
2008-07-08 15:25:24 +02:00
|
|
|
ipa_free_all_edge_args (void)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-08 15:25:24 +02:00
|
|
|
int i;
|
|
|
|
struct ipa_edge_args *args;
|
2005-08-01 09:26:30 +02:00
|
|
|
|
2008-07-08 15:25:24 +02:00
|
|
|
for (i = 0;
|
|
|
|
VEC_iterate (ipa_edge_args_t, ipa_edge_args_vector, i, args);
|
|
|
|
i++)
|
|
|
|
ipa_free_edge_args_substructures (args);
|
|
|
|
|
|
|
|
VEC_free (ipa_edge_args_t, heap, ipa_edge_args_vector);
|
|
|
|
ipa_edge_args_vector = NULL;
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
|
|
|
|
2008-07-08 15:25:24 +02:00
|
|
|
/* Frees all dynamically allocated structures that the param info points
|
|
|
|
to. */
|
2005-08-01 09:26:30 +02:00
|
|
|
void
|
2008-07-08 15:25:24 +02:00
|
|
|
ipa_free_node_params_substructures (struct ipa_node_params *info)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-08 15:25:24 +02:00
|
|
|
if (info->ipcp_lattices)
|
|
|
|
free (info->ipcp_lattices);
|
|
|
|
if (info->param_decls)
|
|
|
|
free (info->param_decls);
|
2008-07-23 21:45:45 +02:00
|
|
|
if (info->param_flags)
|
|
|
|
free (info->param_flags);
|
|
|
|
|
|
|
|
while (info->param_calls)
|
|
|
|
{
|
|
|
|
struct ipa_param_call_note *note = info->param_calls;
|
|
|
|
info->param_calls = note->next;
|
|
|
|
free (note);
|
|
|
|
}
|
2008-07-08 15:25:24 +02:00
|
|
|
|
|
|
|
memset (info, 0, sizeof (*info));
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
|
|
|
|
2008-07-08 15:25:24 +02:00
|
|
|
/* Free all ipa_node_params structures. */
|
2005-08-01 09:26:30 +02:00
|
|
|
void
|
2008-07-08 15:25:24 +02:00
|
|
|
ipa_free_all_node_params (void)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-08 15:25:24 +02:00
|
|
|
int i;
|
|
|
|
struct ipa_node_params *info;
|
2005-08-01 09:26:30 +02:00
|
|
|
|
2008-07-08 15:25:24 +02:00
|
|
|
for (i = 0;
|
|
|
|
VEC_iterate (ipa_node_params_t, ipa_node_params_vector, i, info);
|
|
|
|
i++)
|
|
|
|
ipa_free_node_params_substructures (info);
|
|
|
|
|
|
|
|
VEC_free (ipa_node_params_t, heap, ipa_node_params_vector);
|
|
|
|
ipa_node_params_vector = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Hook that is called by cgraph.c when an edge is removed. */
|
|
|
|
static void
|
|
|
|
ipa_edge_removal_hook (struct cgraph_edge *cs,
|
|
|
|
void *data __attribute__ ((unused)))
|
|
|
|
{
|
|
|
|
ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
|
|
|
|
2008-07-08 15:25:24 +02:00
|
|
|
/* Hook that is called by cgraph.c when a node is removed. */
|
|
|
|
static void
|
|
|
|
ipa_node_removal_hook (struct cgraph_node *node,
|
|
|
|
void *data __attribute__ ((unused)))
|
|
|
|
{
|
|
|
|
ipa_free_node_params_substructures (IPA_NODE_REF (node));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Helper function to duplicate an array of size N that is at SRC and store a
|
|
|
|
pointer to it to DST. Nothing is done if SRC is NULL. */
|
|
|
|
static void *
|
|
|
|
duplicate_array (void *src, size_t n)
|
|
|
|
{
|
|
|
|
void *p;
|
|
|
|
|
|
|
|
if (!src)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
p = xcalloc (1, n);
|
|
|
|
memcpy (p, src, n);
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Hook that is called by cgraph.c when a node is duplicated. */
|
|
|
|
static void
|
|
|
|
ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
|
|
|
|
void *data)
|
|
|
|
{
|
|
|
|
struct ipa_edge_args *old_args, *new_args;
|
|
|
|
int arg_count;
|
|
|
|
|
|
|
|
ipa_check_create_edge_args ();
|
|
|
|
|
|
|
|
old_args = IPA_EDGE_REF (src);
|
|
|
|
new_args = IPA_EDGE_REF (dst);
|
|
|
|
|
|
|
|
arg_count = ipa_get_cs_argument_count (old_args);
|
|
|
|
ipa_set_cs_argument_count (new_args, arg_count);
|
|
|
|
new_args->jump_functions = (struct ipa_jump_func *)
|
|
|
|
duplicate_array (old_args->jump_functions,
|
|
|
|
sizeof (struct ipa_jump_func) * arg_count);
|
|
|
|
data = data; /* Suppressing compiler warning. */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Hook that is called by cgraph.c when a node is duplicated. */
|
|
|
|
static void
|
|
|
|
ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
|
|
|
|
void *data)
|
|
|
|
{
|
|
|
|
struct ipa_node_params *old_info, *new_info;
|
2008-07-23 21:45:45 +02:00
|
|
|
struct ipa_param_call_note *note;
|
2008-07-08 15:25:24 +02:00
|
|
|
int param_count;
|
|
|
|
|
|
|
|
ipa_check_create_node_params ();
|
|
|
|
old_info = IPA_NODE_REF (src);
|
|
|
|
new_info = IPA_NODE_REF (dst);
|
|
|
|
param_count = ipa_get_param_count (old_info);
|
|
|
|
|
|
|
|
ipa_set_param_count (new_info, param_count);
|
|
|
|
new_info->ipcp_lattices = (struct ipcp_lattice *)
|
|
|
|
duplicate_array (old_info->ipcp_lattices,
|
|
|
|
sizeof (struct ipcp_lattice) * param_count);
|
|
|
|
new_info->param_decls = (tree *)
|
|
|
|
duplicate_array (old_info->param_decls, sizeof (tree) * param_count);
|
2008-07-23 21:45:45 +02:00
|
|
|
new_info->param_flags = (struct ipa_param_flags *)
|
|
|
|
duplicate_array (old_info->param_flags,
|
|
|
|
sizeof (struct ipa_param_flags) * param_count);
|
2008-07-08 15:25:24 +02:00
|
|
|
|
|
|
|
new_info->ipcp_orig_node = old_info->ipcp_orig_node;
|
|
|
|
new_info->count_scale = old_info->count_scale;
|
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
for (note = old_info->param_calls; note; note = note->next)
|
|
|
|
{
|
|
|
|
struct ipa_param_call_note *nn;
|
|
|
|
|
|
|
|
nn = (struct ipa_param_call_note *)
|
|
|
|
xcalloc (1, sizeof (struct ipa_param_call_note));
|
|
|
|
memcpy (nn, note, sizeof (struct ipa_param_call_note));
|
|
|
|
nn->next = new_info->param_calls;
|
|
|
|
new_info->param_calls = nn;
|
|
|
|
}
|
|
|
|
|
2008-07-08 15:25:24 +02:00
|
|
|
data = data; /* Suppressing compiler warning. */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Register our cgraph hooks if they are not already there. */
|
2005-08-01 09:26:30 +02:00
|
|
|
void
|
2008-07-08 15:25:24 +02:00
|
|
|
ipa_register_cgraph_hooks (void)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-08 15:25:24 +02:00
|
|
|
if (!edge_removal_hook_holder)
|
|
|
|
edge_removal_hook_holder =
|
|
|
|
cgraph_add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
|
|
|
|
if (!node_removal_hook_holder)
|
|
|
|
node_removal_hook_holder =
|
|
|
|
cgraph_add_node_removal_hook (&ipa_node_removal_hook, NULL);
|
|
|
|
if (!edge_duplication_hook_holder)
|
|
|
|
edge_duplication_hook_holder =
|
|
|
|
cgraph_add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
|
|
|
|
if (!node_duplication_hook_holder)
|
|
|
|
node_duplication_hook_holder =
|
|
|
|
cgraph_add_node_duplication_hook (&ipa_node_duplication_hook, NULL);
|
|
|
|
}
|
2005-08-01 09:26:30 +02:00
|
|
|
|
2008-07-08 15:25:24 +02:00
|
|
|
/* Unregister our cgraph hooks if they are not already there. */
|
|
|
|
static void
|
|
|
|
ipa_unregister_cgraph_hooks (void)
|
|
|
|
{
|
|
|
|
cgraph_remove_edge_removal_hook (edge_removal_hook_holder);
|
|
|
|
edge_removal_hook_holder = NULL;
|
|
|
|
cgraph_remove_node_removal_hook (node_removal_hook_holder);
|
|
|
|
node_removal_hook_holder = NULL;
|
|
|
|
cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder);
|
|
|
|
edge_duplication_hook_holder = NULL;
|
|
|
|
cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
|
|
|
|
node_duplication_hook_holder = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free all ipa_node_params and all ipa_edge_args structures if they are no
|
|
|
|
longer needed after ipa-cp. */
|
|
|
|
void
|
|
|
|
free_all_ipa_structures_after_ipa_cp (void)
|
2008-07-23 21:45:45 +02:00
|
|
|
{
|
2008-07-25 15:11:32 +02:00
|
|
|
if (!flag_indirect_inlining)
|
2008-07-23 21:45:45 +02:00
|
|
|
{
|
|
|
|
ipa_free_all_edge_args ();
|
|
|
|
ipa_free_all_node_params ();
|
|
|
|
ipa_unregister_cgraph_hooks ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free all ipa_node_params and all ipa_edge_args structures if they are no
|
|
|
|
longer needed after indirect inlining. */
|
|
|
|
void
|
|
|
|
free_all_ipa_structures_after_iinln (void)
|
2008-07-08 15:25:24 +02:00
|
|
|
{
|
|
|
|
ipa_free_all_edge_args ();
|
|
|
|
ipa_free_all_node_params ();
|
|
|
|
ipa_unregister_cgraph_hooks ();
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
|
|
|
|
2008-04-30 12:01:59 +02:00
|
|
|
/* Print ipa_tree_map data structures of all functions in the
|
2005-08-01 09:26:30 +02:00
|
|
|
callgraph to F. */
|
|
|
|
void
|
2008-04-30 12:01:59 +02:00
|
|
|
ipa_print_all_tree_maps (FILE * f)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
|
|
|
int i, count;
|
|
|
|
tree temp;
|
|
|
|
struct cgraph_node *node;
|
|
|
|
|
|
|
|
fprintf (f, "\nPARAM TREE MAP PRINT\n");
|
|
|
|
for (node = cgraph_nodes; node; node = node->next)
|
|
|
|
{
|
2008-07-17 15:23:32 +02:00
|
|
|
struct ipa_node_params *info;
|
|
|
|
|
|
|
|
if (!node->analyzed)
|
|
|
|
continue;
|
|
|
|
info = IPA_NODE_REF (node);
|
2008-04-30 12:01:59 +02:00
|
|
|
fprintf (f, "function %s Trees :: \n", cgraph_node_name (node));
|
|
|
|
count = ipa_get_param_count (info);
|
2005-08-01 09:26:30 +02:00
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
2008-04-30 12:01:59 +02:00
|
|
|
temp = ipa_get_ith_param (info, i);
|
2005-08-01 09:26:30 +02:00
|
|
|
if (TREE_CODE (temp) == PARM_DECL)
|
|
|
|
fprintf (f, " param [%d] : %s\n", i,
|
|
|
|
(*lang_hooks.decl_printable_name) (temp, 2));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
/* Print param_flags data structures of the NODE to F. */
|
2005-08-01 09:26:30 +02:00
|
|
|
void
|
2008-07-23 21:45:45 +02:00
|
|
|
ipa_print_node_param_flags (FILE * f, struct cgraph_node *node)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
|
|
|
int i, count;
|
2008-07-23 21:45:45 +02:00
|
|
|
struct ipa_node_params *info;
|
2005-08-01 09:26:30 +02:00
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
if (!node->analyzed)
|
|
|
|
return;
|
|
|
|
info = IPA_NODE_REF (node);
|
|
|
|
fprintf (f, "PARAM FLAGS of function %s: \n", cgraph_node_name (node));
|
|
|
|
count = ipa_get_param_count (info);
|
|
|
|
for (i = 0; i < count; i++)
|
2005-08-01 09:26:30 +02:00
|
|
|
{
|
2008-07-23 21:45:45 +02:00
|
|
|
fprintf (f, " param %d flags:", i);
|
|
|
|
if (ipa_is_ith_param_modified (info, i))
|
|
|
|
fprintf (f, " modified");
|
|
|
|
if (ipa_is_ith_param_called (info, i))
|
|
|
|
fprintf (f, " called");
|
|
|
|
fprintf (f, "\n");
|
2005-08-01 09:26:30 +02:00
|
|
|
}
|
|
|
|
}
|
2008-04-30 12:01:59 +02:00
|
|
|
|
2008-07-23 21:45:45 +02:00
|
|
|
/* Print param_flags data structures of all functions in the
|
|
|
|
callgraph to F. */
|
|
|
|
void
|
|
|
|
ipa_print_all_param_flags (FILE * f)
|
|
|
|
{
|
|
|
|
struct cgraph_node *node;
|
|
|
|
|
|
|
|
fprintf (f, "\nIPA PARAM FLAGS DUMP\n");
|
|
|
|
for (node = cgraph_nodes; node; node = node->next)
|
|
|
|
ipa_print_node_param_flags (f, node);
|
|
|
|
}
|