/* Interprocedural analyses.
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2007 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
ipa_method_tree_map_create (struct cgraph_node *mt)
{
IPA_NODE_REF (mt)->ipa_param_tree =
- xcalloc (ipa_method_formal_count (mt), sizeof (tree));
+ XCNEWVEC (tree, ipa_method_formal_count (mt));
}
/* Create modify structure for MT. */
ipa_method_modify_create (struct cgraph_node *mt)
{
((struct ipa_node *) mt->aux)->ipa_mod =
- xcalloc (ipa_method_formal_count (mt), sizeof (bool));
+ XCNEWVEC (bool, ipa_method_formal_count (mt));
}
/* Set modify of I-th formal of MT to VAL. */
ipa_method_modify_stmt (struct cgraph_node *mt, tree stmt)
{
int i, j;
+ tree parm_decl;
switch (TREE_CODE (stmt))
{
- case MODIFY_EXPR:
- if (TREE_CODE (TREE_OPERAND (stmt, 0)) == PARM_DECL)
+ case GIMPLE_MODIFY_STMT:
+ if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == PARM_DECL)
{
- i = ipa_method_tree_map (mt, TREE_OPERAND (stmt, 0));
+ parm_decl = GIMPLE_STMT_OPERAND (stmt, 0);
+ i = ipa_method_tree_map (mt, parm_decl);
if (i >= 0)
- ipa_method_modify_set (mt, i, true);
+ ipa_method_modify_set (mt, i, true);
}
break;
case ASM_EXPR:
block_stmt_iterator bsi;
tree stmt, parm_tree;
+ if (ipa_method_formal_count (mt) == 0)
+ return;
+
ipa_method_modify_init (mt);
decl = mt->decl;
count = ipa_method_formal_count (mt);
/* ??? Handle pending sizes case. Set all parameters
of the method to be modified. */
+
if (DECL_UNINLINABLE (decl))
{
for (j = 0; j < count; j++)
for (j = 0; j < count; j++)
{
parm_tree = ipa_method_get_tree (mt, j);
- if (TREE_ADDRESSABLE (parm_tree))
+ if (!is_gimple_reg (parm_tree)
+ && TREE_ADDRESSABLE (parm_tree))
ipa_method_modify_set (mt, j, true);
}
body = DECL_SAVED_TREE (decl);
/* Set int-valued INFO_TYPE1 as 'info_type' field of
jump function (ipa_jump_func struct) of argument I of callsite CS. */
static inline void
-ipa_callsite_param_set_info_type (struct cgraph_edge *cs, int i, tree info_type1)
+ipa_callsite_param_set_info_type (struct cgraph_edge *cs, int i,
+ tree info_type1)
{
ipa_callsite_param (cs, i)->info_type.value = info_type1;
}
ipa_callsite_param_map_create (struct cgraph_edge *cs)
{
IPA_EDGE_REF (cs)->ipa_param_map =
- xcalloc (ipa_callsite_param_count (cs), sizeof (struct ipa_jump_func));
+ XCNEWVEC (struct ipa_jump_func, ipa_callsite_param_count (cs));
}
/* Return the call expr tree related to callsite CS. */
ipa_callsite_compute_count (struct cgraph_edge *cs)
{
tree call_tree;
- tree arg;
int arg_num;
call_tree = get_call_expr_in (ipa_callsite_tree (cs));
gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
- arg = TREE_OPERAND (call_tree, 1);
- arg_num = 0;
- for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
- arg_num++;
+ arg_num = call_expr_nargs (call_tree);
ipa_callsite_param_count_set (cs, arg_num);
}
int arg_num;
int i;
struct cgraph_node *mt;
+ tree parm_decl;
+ struct function *curr_cfun;
+ call_expr_arg_iterator iter;
if (ipa_callsite_param_count (cs) == 0)
return;
ipa_callsite_param_map_create (cs);
call_tree = get_call_expr_in (ipa_callsite_tree (cs));
gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
- arg = TREE_OPERAND (call_tree, 1);
arg_num = 0;
- for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
+ FOR_EACH_CALL_EXPR_ARG (arg, iter, call_tree)
{
/* If the formal parameter was passed as argument, we store
FORMAL_IPATYPE and its index in the caller as the jump function
of this argument. */
- if (TREE_CODE (TREE_VALUE (arg)) == PARM_DECL)
+ if ((TREE_CODE (arg) == SSA_NAME
+ && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
+ || TREE_CODE (arg) == PARM_DECL)
{
mt = ipa_callsite_caller (cs);
- i = ipa_method_tree_map (mt, TREE_VALUE (arg));
- if (i < 0 || ipa_method_is_modified (mt, i))
+ parm_decl = TREE_CODE (arg) == PARM_DECL ? arg : SSA_NAME_VAR (arg);
+
+ i = ipa_method_tree_map (mt, parm_decl);
+ if (TREE_CODE (arg) == SSA_NAME && IS_VALID_TREE_MAP_INDEX (i))
+ {
+ curr_cfun = DECL_STRUCT_FUNCTION (mt->decl);
+ if (!gimple_default_def (curr_cfun, parm_decl)
+ || gimple_default_def (curr_cfun, parm_decl) != arg)
+ ipa_method_modify_set (mt, i, true);
+ }
+ if (!IS_VALID_TREE_MAP_INDEX (i) || ipa_method_is_modified (mt, i))
ipa_callsite_param_set_type (cs, arg_num, UNKNOWN_IPATYPE);
else
{
/* If a constant value was passed as argument,
we store CONST_IPATYPE and its value as the jump function
of this argument. */
- else if (TREE_CODE (TREE_VALUE (arg)) == INTEGER_CST
- || TREE_CODE (TREE_VALUE (arg)) == REAL_CST)
+ else if (TREE_CODE (arg) == INTEGER_CST
+ || TREE_CODE (arg) == REAL_CST
+ || TREE_CODE (arg) == FIXED_CST)
{
ipa_callsite_param_set_type (cs, arg_num, CONST_IPATYPE);
- ipa_callsite_param_set_info_type (cs, arg_num,
- TREE_VALUE (arg));
+ ipa_callsite_param_set_info_type (cs, arg_num, arg);
}
/* This is for the case of Fortran. If the address of a const_decl
was passed as argument then we store
CONST_IPATYPE_REF/CONST_IPATYPE_REF and the constant
value as the jump function corresponding to this argument. */
- else if (TREE_CODE (TREE_VALUE (arg)) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (TREE_VALUE (arg), 0)) ==
- CONST_DECL)
+ else if (TREE_CODE (arg) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (arg, 0)) == CONST_DECL)
{
- cst_decl = TREE_OPERAND (TREE_VALUE (arg), 0);
+ 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)) == REAL_CST
+ || TREE_CODE (DECL_INITIAL (cst_decl)) == FIXED_CST)
{
ipa_callsite_param_set_type (cs, arg_num,
CONST_IPATYPE_REF);