aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2008-08-29 13:31:40 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2008-08-29 11:31:40 +0000
commitc6f7cfc15e7480f86aa3e4d407932f38fd635c89 (patch)
treed057c22936747f4672fd349b48d59df2628ab832 /gcc/tree.c
parentefd8f7507b3ce6e4cc00c7eac4f011736ca4f14d (diff)
downloadgcc-c6f7cfc15e7480f86aa3e4d407932f38fd635c89.zip
gcc-c6f7cfc15e7480f86aa3e4d407932f38fd635c89.tar.gz
gcc-c6f7cfc15e7480f86aa3e4d407932f38fd635c89.tar.bz2
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
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c81
1 files changed, 78 insertions, 3 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index f058fd7..5b92459 100644
--- a/gcc/tree.c
+++ b/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)