tree.c (build_function_type_skip_args, [...]): New functions.
* tree.c (build_function_type_skip_args, build_function_decl_skip_args): New functions. * tree.h (build_function_type_skip_args, build_function_decl_skip_args): Declare. * gimple.c (giple_copy_call_skip_args): New function. (giple_copy_call_skip_args): Declare. * cgraph.h (cgraph_function_versioning): Add skip_args arugmnet * ipa-cp.c (ipcp_node_not_modifiable_p): Rename to ... (ipcp_node_modifiable_p): ... this one; use tree_versionable_function_p. (ipcp_create_replace_map): Improve debug output. (ipcp_need_redirect_p): Return false when not clonning. (ipcp_update_callgraph): Skip args. (ipcp_insert_stage): UPdate call of !ipcp_node_modifiable_p; skip args. * cgraphunit.c (cgraph_function_versioning): Add skip_args argument. (save_inline_function_body): Update call of tree_function_versioning. * ipa-prop.c (ipa_edge_removal_hook): Do not ICE on unanalyzed nodes. * tree-inline.c (copy_arguments_for_versioning): Add skip_args argument. (tree_function_versioning): Likewise. * tree-inline.h (tree_function_versioning): Update prototype. From-SVN: r139761
This commit is contained in:
parent
efd8f7507b
commit
c6f7cfc15e
11 changed files with 267 additions and 51 deletions
|
@ -1,3 +1,27 @@
|
|||
2008-08-29 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* tree.c (build_function_type_skip_args, build_function_decl_skip_args):
|
||||
New functions.
|
||||
* tree.h (build_function_type_skip_args, build_function_decl_skip_args):
|
||||
Declare.
|
||||
* gimple.c (giple_copy_call_skip_args): New function.
|
||||
(giple_copy_call_skip_args): Declare.
|
||||
|
||||
* cgraph.h (cgraph_function_versioning): Add skip_args arugmnet
|
||||
* ipa-cp.c (ipcp_node_not_modifiable_p): Rename to ...
|
||||
(ipcp_node_modifiable_p): ... this one; use tree_versionable_function_p.
|
||||
(ipcp_create_replace_map): Improve debug output.
|
||||
(ipcp_need_redirect_p): Return false when not clonning.
|
||||
(ipcp_update_callgraph): Skip args.
|
||||
(ipcp_insert_stage): UPdate call of !ipcp_node_modifiable_p;
|
||||
skip args.
|
||||
* cgraphunit.c (cgraph_function_versioning): Add skip_args argument.
|
||||
(save_inline_function_body): Update call of tree_function_versioning.
|
||||
* ipa-prop.c (ipa_edge_removal_hook): Do not ICE on unanalyzed nodes.
|
||||
* tree-inline.c (copy_arguments_for_versioning): Add skip_args argument.
|
||||
(tree_function_versioning): Likewise.
|
||||
* tree-inline.h (tree_function_versioning): Update prototype.
|
||||
|
||||
2008-08-29 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* loop-unswitch.c (unswitch_single_loop): Use optimize_loop_for_speed_p.
|
||||
|
|
|
@ -351,7 +351,8 @@ void cgraph_reset_static_var_maps (void);
|
|||
void init_cgraph (void);
|
||||
struct cgraph_node *cgraph_function_versioning (struct cgraph_node *,
|
||||
VEC(cgraph_edge_p,heap)*,
|
||||
varray_type);
|
||||
varray_type,
|
||||
bitmap);
|
||||
void cgraph_analyze_function (struct cgraph_node *);
|
||||
struct cgraph_node *save_inline_function_body (struct cgraph_node *);
|
||||
void record_references_in_initializer (tree);
|
||||
|
|
|
@ -1496,12 +1496,15 @@ cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
|
|||
TREE_MAP is a mapping of tree nodes we want to replace with
|
||||
new ones (according to results of prior analysis).
|
||||
OLD_VERSION_NODE is the node that is versioned.
|
||||
It returns the new version's cgraph node. */
|
||||
It returns the new version's cgraph node.
|
||||
ARGS_TO_SKIP lists arguments to be omitted from functions
|
||||
*/
|
||||
|
||||
struct cgraph_node *
|
||||
cgraph_function_versioning (struct cgraph_node *old_version_node,
|
||||
VEC(cgraph_edge_p,heap) *redirect_callers,
|
||||
varray_type tree_map)
|
||||
varray_type tree_map,
|
||||
bitmap args_to_skip)
|
||||
{
|
||||
tree old_decl = old_version_node->decl;
|
||||
struct cgraph_node *new_version_node = NULL;
|
||||
|
@ -1512,7 +1515,10 @@ cgraph_function_versioning (struct cgraph_node *old_version_node,
|
|||
|
||||
/* Make a new FUNCTION_DECL tree node for the
|
||||
new version. */
|
||||
new_decl = copy_node (old_decl);
|
||||
if (!args_to_skip)
|
||||
new_decl = copy_node (old_decl);
|
||||
else
|
||||
new_decl = build_function_decl_skip_args (old_decl, args_to_skip);
|
||||
|
||||
/* Create the new version's call-graph node.
|
||||
and update the edges of the new node. */
|
||||
|
@ -1521,7 +1527,7 @@ cgraph_function_versioning (struct cgraph_node *old_version_node,
|
|||
redirect_callers);
|
||||
|
||||
/* Copy the OLD_VERSION_NODE function tree to the new version. */
|
||||
tree_function_versioning (old_decl, new_decl, tree_map, false);
|
||||
tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip);
|
||||
/* Update the call_expr on the edges to call the new version node. */
|
||||
update_call_expr (new_version_node);
|
||||
|
||||
|
@ -1560,7 +1566,7 @@ save_inline_function_body (struct cgraph_node *node)
|
|||
gcc_assert (first_clone == cgraph_node (first_clone->decl));
|
||||
|
||||
/* Copy the OLD_VERSION_NODE function tree to the new version. */
|
||||
tree_function_versioning (node->decl, first_clone->decl, NULL, true);
|
||||
tree_function_versioning (node->decl, first_clone->decl, NULL, true, NULL);
|
||||
|
||||
DECL_EXTERNAL (first_clone->decl) = 0;
|
||||
DECL_ONE_ONLY (first_clone->decl) = 0;
|
||||
|
|
33
gcc/gimple.c
33
gcc/gimple.c
|
@ -3180,4 +3180,37 @@ canonicalize_cond_expr_cond (tree t)
|
|||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Build call same as STMT but skipping arguments ARGS_TO_SKIP. */
|
||||
gimple
|
||||
giple_copy_call_skip_args (gimple stmt, bitmap args_to_skip)
|
||||
{
|
||||
int i;
|
||||
tree fn = gimple_call_fn (stmt);
|
||||
int nargs = gimple_call_num_args (stmt);
|
||||
VEC(tree, heap) *vargs = VEC_alloc (tree, heap, nargs);
|
||||
gimple new_stmt;
|
||||
|
||||
for (i = 0; i < nargs; i++)
|
||||
if (!bitmap_bit_p (args_to_skip, i))
|
||||
VEC_quick_push (tree, vargs, gimple_call_arg (stmt, i));
|
||||
|
||||
new_stmt = gimple_build_call_vec (fn, vargs);
|
||||
VEC_free (tree, heap, vargs);
|
||||
if (gimple_call_lhs (stmt))
|
||||
gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
|
||||
|
||||
gimple_set_block (new_stmt, gimple_block (stmt));
|
||||
if (gimple_has_location (stmt))
|
||||
gimple_set_location (new_stmt, gimple_location (stmt));
|
||||
|
||||
/* Carry all the flags to the new GIMPLE_CALL. */
|
||||
gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
|
||||
gimple_call_set_tail (new_stmt, gimple_call_tail_p (stmt));
|
||||
gimple_call_set_cannot_inline (new_stmt, gimple_call_cannot_inline_p (stmt));
|
||||
gimple_call_set_return_slot_opt (new_stmt, gimple_call_return_slot_opt_p (stmt));
|
||||
gimple_call_set_from_thunk (new_stmt, gimple_call_from_thunk_p (stmt));
|
||||
gimple_call_set_va_arg_pack (new_stmt, gimple_call_va_arg_pack_p (stmt));
|
||||
return new_stmt;
|
||||
}
|
||||
|
||||
#include "gt-gimple.h"
|
||||
|
|
|
@ -4471,6 +4471,7 @@ basic_block gsi_insert_on_edge_immediate (edge, gimple);
|
|||
basic_block gsi_insert_seq_on_edge_immediate (edge, gimple_seq);
|
||||
void gsi_commit_one_edge_insert (edge, basic_block *);
|
||||
void gsi_commit_edge_inserts (void);
|
||||
gimple giple_copy_call_skip_args (gimple, bitmap);
|
||||
|
||||
|
||||
/* Convenience routines to walk all statements of a gimple function.
|
||||
|
|
107
gcc/ipa-cp.c
107
gcc/ipa-cp.c
|
@ -560,12 +560,11 @@ ipcp_iterate_stage (void)
|
|||
/* Check conditions to forbid constant insertion to function described by
|
||||
NODE. */
|
||||
static inline bool
|
||||
ipcp_node_not_modifiable_p (struct cgraph_node *node)
|
||||
ipcp_node_modifiable_p (struct cgraph_node *node)
|
||||
{
|
||||
/* ??? Handle pending sizes case. */
|
||||
if (DECL_UNINLINABLE (node->decl))
|
||||
return true;
|
||||
return false;
|
||||
/* Once we will be able to do in-place replacement, we can be more
|
||||
lax here. */
|
||||
return tree_versionable_function_p (node->decl);
|
||||
}
|
||||
|
||||
/* Print count scale data structures. */
|
||||
|
@ -745,9 +744,15 @@ ipcp_create_replace_map (tree parm_tree, struct ipcp_lattice *lat)
|
|||
tree const_val;
|
||||
|
||||
replace_map = XCNEW (struct ipa_replace_map);
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "replacing param with const\n");
|
||||
const_val = build_const_val (lat, TREE_TYPE (parm_tree));
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file, " replacing param ");
|
||||
print_generic_expr (dump_file, parm_tree, 0);
|
||||
fprintf (dump_file, " with const ");
|
||||
print_generic_expr (dump_file, const_val, 0);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
replace_map->old_tree = parm_tree;
|
||||
replace_map->new_tree = const_val;
|
||||
replace_map->replace_p = true;
|
||||
|
@ -766,6 +771,9 @@ ipcp_need_redirect_p (struct cgraph_edge *cs)
|
|||
struct ipa_jump_func *jump_func;
|
||||
struct cgraph_node *node = cs->callee, *orig;
|
||||
|
||||
if (!flag_ipa_cp_clone)
|
||||
return false;
|
||||
|
||||
if ((orig = ipcp_get_orig_node (node)) != NULL)
|
||||
node = orig;
|
||||
if (ipcp_get_orig_node (cs->caller))
|
||||
|
@ -791,26 +799,59 @@ ipcp_need_redirect_p (struct cgraph_edge *cs)
|
|||
static void
|
||||
ipcp_update_callgraph (void)
|
||||
{
|
||||
struct cgraph_node *node, *orig_callee;
|
||||
struct cgraph_edge *cs;
|
||||
struct cgraph_node *node;
|
||||
|
||||
for (node = cgraph_nodes; node; node = node->next)
|
||||
{
|
||||
/* want to fix only original nodes */
|
||||
if (!node->analyzed || ipcp_node_is_clone (node))
|
||||
continue;
|
||||
for (cs = node->callees; cs; cs = cs->next_callee)
|
||||
if (ipcp_node_is_clone (cs->callee))
|
||||
if (node->analyzed && ipcp_node_is_clone (node))
|
||||
{
|
||||
bitmap args_to_skip = BITMAP_ALLOC (NULL);
|
||||
struct cgraph_node *orig_node = ipcp_get_orig_node (node);
|
||||
struct ipa_node_params *info = IPA_NODE_REF (orig_node);
|
||||
int i, count = ipa_get_param_count (info);
|
||||
struct cgraph_edge *cs, *next;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
/* Callee is a cloned node */
|
||||
orig_callee = ipcp_get_orig_node (cs->callee);
|
||||
if (ipcp_need_redirect_p (cs))
|
||||
struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i);
|
||||
tree parm_tree = ipa_get_ith_param (info, i);
|
||||
|
||||
/* We can proactively remove obviously unused arguments. */
|
||||
if (is_gimple_reg (parm_tree)
|
||||
&& !gimple_default_def (DECL_STRUCT_FUNCTION (orig_node->decl),
|
||||
parm_tree))
|
||||
{
|
||||
cgraph_redirect_edge_callee (cs, orig_callee);
|
||||
gimple_call_set_fndecl (cs->call_stmt, orig_callee->decl);
|
||||
bitmap_set_bit (args_to_skip, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lat->type == IPA_CONST_VALUE)
|
||||
bitmap_set_bit (args_to_skip, i);
|
||||
}
|
||||
for (cs = node->callers; cs; cs = next)
|
||||
{
|
||||
next = cs->next_caller;
|
||||
if (ipcp_node_is_clone (cs->caller) || !ipcp_need_redirect_p (cs))
|
||||
{
|
||||
gimple new_stmt;
|
||||
gimple_stmt_iterator gsi;
|
||||
|
||||
current_function_decl = cs->caller->decl;
|
||||
push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
|
||||
|
||||
new_stmt = giple_copy_call_skip_args (cs->call_stmt, args_to_skip);
|
||||
gsi = gsi_for_stmt (cs->call_stmt);
|
||||
gsi_replace (&gsi, new_stmt, true);
|
||||
cgraph_set_call_stmt (cs, new_stmt);
|
||||
pop_cfun ();
|
||||
current_function_decl = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
cgraph_redirect_edge_callee (cs, orig_node);
|
||||
gimple_call_set_fndecl (cs->call_stmt, orig_node->decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update all cfg basic blocks in NODE according to SCALE. */
|
||||
|
@ -989,7 +1030,7 @@ ipcp_insert_stage (void)
|
|||
{
|
||||
struct ipa_node_params *info;
|
||||
/* Propagation of the constant is forbidden in certain conditions. */
|
||||
if (!node->analyzed || ipcp_node_not_modifiable_p (node))
|
||||
if (!node->analyzed || !ipcp_node_modifiable_p (node))
|
||||
continue;
|
||||
info = IPA_NODE_REF (node);
|
||||
if (ipa_is_called_with_var_arguments (info))
|
||||
|
@ -1004,6 +1045,7 @@ ipcp_insert_stage (void)
|
|||
{
|
||||
struct ipa_node_params *info;
|
||||
int growth = 0;
|
||||
bitmap args_to_skip;
|
||||
|
||||
node = (struct cgraph_node *)fibheap_extract_min (heap);
|
||||
node->aux = NULL;
|
||||
|
@ -1033,20 +1075,27 @@ ipcp_insert_stage (void)
|
|||
|
||||
VARRAY_GENERIC_PTR_INIT (replace_trees, ipcp_const_param_count (node),
|
||||
"replace_trees");
|
||||
args_to_skip = BITMAP_ALLOC (NULL);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i);
|
||||
parm_tree = ipa_get_ith_param (info, i);
|
||||
|
||||
if (lat->type == IPA_CONST_VALUE
|
||||
/* Do not count obviously unused arguments. */
|
||||
&& (!is_gimple_reg (parm_tree)
|
||||
|| gimple_default_def (DECL_STRUCT_FUNCTION (node->decl),
|
||||
parm_tree)))
|
||||
/* We can proactively remove obviously unused arguments. */
|
||||
if (is_gimple_reg (parm_tree)
|
||||
&& !gimple_default_def (DECL_STRUCT_FUNCTION (node->decl),
|
||||
parm_tree))
|
||||
{
|
||||
bitmap_set_bit (args_to_skip, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lat->type == IPA_CONST_VALUE)
|
||||
{
|
||||
replace_param =
|
||||
ipcp_create_replace_map (parm_tree, lat);
|
||||
VARRAY_PUSH_GENERIC_PTR (replace_trees, replace_param);
|
||||
bitmap_set_bit (args_to_skip, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1061,7 +1110,9 @@ ipcp_insert_stage (void)
|
|||
/* Redirecting all the callers of the node to the
|
||||
new versioned node. */
|
||||
node1 =
|
||||
cgraph_function_versioning (node, redirect_callers, replace_trees);
|
||||
cgraph_function_versioning (node, redirect_callers, replace_trees,
|
||||
args_to_skip);
|
||||
BITMAP_FREE (args_to_skip);
|
||||
VEC_free (cgraph_edge_p, heap, redirect_callers);
|
||||
VARRAY_CLEAR (replace_trees);
|
||||
if (node1 == NULL)
|
||||
|
|
|
@ -1057,6 +1057,10 @@ static void
|
|||
ipa_edge_removal_hook (struct cgraph_edge *cs,
|
||||
void *data __attribute__ ((unused)))
|
||||
{
|
||||
/* During IPA-CP updating we can be called on not-yet analyze clones. */
|
||||
if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
|
||||
<= (unsigned)cs->uid)
|
||||
return;
|
||||
ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
|
||||
}
|
||||
|
||||
|
|
|
@ -4089,19 +4089,37 @@ copy_decl_maybe_to_var (tree decl, copy_body_data *id)
|
|||
|
||||
/* Return a copy of the function's argument tree. */
|
||||
static tree
|
||||
copy_arguments_for_versioning (tree orig_parm, copy_body_data * id)
|
||||
copy_arguments_for_versioning (tree orig_parm, copy_body_data * id,
|
||||
bitmap args_to_skip, tree *vars)
|
||||
{
|
||||
tree *arg_copy, *parg;
|
||||
tree arg, *parg;
|
||||
tree new_parm = NULL;
|
||||
int i = 0;
|
||||
|
||||
arg_copy = &orig_parm;
|
||||
for (parg = arg_copy; *parg; parg = &TREE_CHAIN (*parg))
|
||||
{
|
||||
tree new_tree = remap_decl (*parg, id);
|
||||
lang_hooks.dup_lang_specific_decl (new_tree);
|
||||
TREE_CHAIN (new_tree) = TREE_CHAIN (*parg);
|
||||
*parg = new_tree;
|
||||
}
|
||||
return orig_parm;
|
||||
parg = &new_parm;
|
||||
|
||||
for (arg = orig_parm; arg; arg = TREE_CHAIN (arg), i++)
|
||||
if (!args_to_skip || !bitmap_bit_p (args_to_skip, i))
|
||||
{
|
||||
tree new_tree = remap_decl (arg, id);
|
||||
lang_hooks.dup_lang_specific_decl (new_tree);
|
||||
*parg = new_tree;
|
||||
parg = &TREE_CHAIN (new_tree);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make an equivalent VAR_DECL. If the argument was used
|
||||
as temporary variable later in function, the uses will be
|
||||
replaced by local variable. */
|
||||
tree var = copy_decl_to_var (arg, id);
|
||||
get_var_ann (var);
|
||||
add_referenced_var (var);
|
||||
insert_decl_map (id, arg, var);
|
||||
/* Declare this new variable. */
|
||||
TREE_CHAIN (var) = *vars;
|
||||
*vars = var;
|
||||
}
|
||||
return new_parm;
|
||||
}
|
||||
|
||||
/* Return a copy of the function's static chain. */
|
||||
|
@ -4146,7 +4164,7 @@ tree_versionable_function_p (tree fndecl)
|
|||
of edges of clones of the function will be updated. */
|
||||
void
|
||||
tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
|
||||
bool update_clones)
|
||||
bool update_clones, bitmap args_to_skip)
|
||||
{
|
||||
struct cgraph_node *old_version_node;
|
||||
struct cgraph_node *new_version_node;
|
||||
|
@ -4214,7 +4232,8 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
|
|||
/* Copy the function's arguments. */
|
||||
if (DECL_ARGUMENTS (old_decl) != NULL_TREE)
|
||||
DECL_ARGUMENTS (new_decl) =
|
||||
copy_arguments_for_versioning (DECL_ARGUMENTS (old_decl), &id);
|
||||
copy_arguments_for_versioning (DECL_ARGUMENTS (old_decl), &id,
|
||||
args_to_skip, &vars);
|
||||
|
||||
DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id);
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ int estimate_num_insns (gimple, eni_weights *);
|
|||
int estimate_num_insns_fn (tree, eni_weights *);
|
||||
int count_insns_seq (gimple_seq, eni_weights *);
|
||||
bool tree_versionable_function_p (tree);
|
||||
void tree_function_versioning (tree, tree, varray_type, bool);
|
||||
void tree_function_versioning (tree, tree, varray_type, bool, bitmap);
|
||||
bool tree_can_inline_p (tree, tree);
|
||||
|
||||
extern gimple_seq remap_gimple_seq (gimple_seq, copy_body_data *);
|
||||
|
|
81
gcc/tree.c
81
gcc/tree.c
|
@ -5878,6 +5878,81 @@ build_function_type (tree value_type, tree arg_types)
|
|||
return t;
|
||||
}
|
||||
|
||||
/* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP. */
|
||||
|
||||
tree
|
||||
build_function_type_skip_args (tree orig_type, bitmap args_to_skip)
|
||||
{
|
||||
tree new_type = NULL;
|
||||
tree args, new_args = NULL, t;
|
||||
tree new_reversed;
|
||||
int i = 0;
|
||||
|
||||
for (args = TYPE_ARG_TYPES (orig_type); args && args != void_list_node;
|
||||
args = TREE_CHAIN (args), i++)
|
||||
if (!bitmap_bit_p (args_to_skip, i))
|
||||
new_args = tree_cons (NULL_TREE, TREE_VALUE (args), new_args);
|
||||
|
||||
new_reversed = nreverse (new_args);
|
||||
if (args)
|
||||
{
|
||||
if (new_reversed)
|
||||
TREE_CHAIN (new_args) = void_list_node;
|
||||
else
|
||||
new_reversed = void_list_node;
|
||||
}
|
||||
gcc_assert (new_reversed);
|
||||
|
||||
/* Use copy_node to preserve as much as possible from original type
|
||||
(debug info, attribute lists etc.)
|
||||
Exception is METHOD_TYPEs must have THIS argument.
|
||||
When we are asked to remove it, we need to build new FUNCTION_TYPE
|
||||
instead. */
|
||||
if (TREE_CODE (orig_type) != METHOD_TYPE
|
||||
|| !bitmap_bit_p (args_to_skip, 0))
|
||||
{
|
||||
new_type = copy_node (orig_type);
|
||||
TYPE_ARG_TYPES (new_type) = new_reversed;
|
||||
}
|
||||
else
|
||||
new_type = build_function_type (TREE_TYPE (orig_type), new_reversed);
|
||||
|
||||
/* This is a new type, not a copy of an old type. Need to reassociate
|
||||
variants. We can handle everything except the main variant lazily. */
|
||||
t = TYPE_MAIN_VARIANT (orig_type);
|
||||
if (orig_type != t)
|
||||
{
|
||||
TYPE_MAIN_VARIANT (new_type) = t;
|
||||
TYPE_NEXT_VARIANT (new_type) = TYPE_NEXT_VARIANT (t);
|
||||
TYPE_NEXT_VARIANT (t) = new_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
TYPE_MAIN_VARIANT (new_type) = new_type;
|
||||
TYPE_NEXT_VARIANT (new_type) = NULL;
|
||||
}
|
||||
return new_type;
|
||||
}
|
||||
|
||||
/* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP.
|
||||
|
||||
Arguments from DECL_ARGUMENTS list can't be removed now, since they are
|
||||
linked by TREE_CHAIN directly. It is caller responsibility to eliminate
|
||||
them when they are being duplicated (i.e. copy_arguments_for_versioning). */
|
||||
|
||||
tree
|
||||
build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip)
|
||||
{
|
||||
tree new_decl = copy_node (orig_decl);
|
||||
tree new_type;
|
||||
|
||||
new_type = TREE_TYPE (orig_decl);
|
||||
if (prototype_p (new_type))
|
||||
new_type = build_function_type_skip_args (new_type, args_to_skip);
|
||||
TREE_TYPE (orig_decl) = new_type;
|
||||
return new_decl;
|
||||
}
|
||||
|
||||
/* Build a function type. The RETURN_TYPE is the type returned by the
|
||||
function. If VAARGS is set, no void_type_node is appended to the
|
||||
the list. ARGP muse be alway be terminated be a NULL_TREE. */
|
||||
|
@ -5893,9 +5968,9 @@ build_function_type_list_1 (bool vaargs, tree return_type, va_list argp)
|
|||
|
||||
if (vaargs)
|
||||
{
|
||||
last = args;
|
||||
if (args != NULL_TREE)
|
||||
args = nreverse (args);
|
||||
last = args;
|
||||
if (args != NULL_TREE)
|
||||
args = nreverse (args);
|
||||
gcc_assert (args != NULL_TREE && last != void_list_node);
|
||||
}
|
||||
else if (args == NULL_TREE)
|
||||
|
|
|
@ -3994,6 +3994,8 @@ extern tree build_index_2_type (tree, tree);
|
|||
extern tree build_array_type (tree, tree);
|
||||
extern tree build_function_type (tree, tree);
|
||||
extern tree build_function_type_list (tree, ...);
|
||||
extern tree build_function_type_skip_args (tree, bitmap);
|
||||
extern tree build_function_decl_skip_args (tree, bitmap);
|
||||
extern tree build_varargs_function_type_list (tree, ...);
|
||||
extern tree build_method_type_directly (tree, tree, tree);
|
||||
extern tree build_method_type (tree, tree);
|
||||
|
|
Loading…
Add table
Reference in a new issue