This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Infrastructure to let ipcp to remove unused arguments from calls
> On Wed, Aug 27, 2008 at 11:39, Jan Hubicka <jh@suse.cz> wrote:
>
> > +
> > + /* 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);
>
> Why not use build_variant_type_copy() here?
I didn't noticed existence of this function so far ;). The variant handling
is copied from type duplication in tree-inline.
In meantime I however noticed problem with java, where constant
propagating THIS pointer to method (that happens quite often in libjava
build with clonning) confuse debug output as METHOD_TYPE is supposed to
always have THIS pointer as first operand.
I think I need to translate the type to FUNCTION_TYPE and I guess only
way is to build type from scratch via build_function_type.
This is patch I tested in meantime (+the renaming), I guess
build_variant_type_copy does not give us much benefit here...
Honza
Index: tree.c
===================================================================
*** tree.c (revision 139571)
--- tree.c (working copy)
*************** build_function_type (tree value_type, tr
*** 5878,5883 ****
--- 5878,5958 ----
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. */
*************** build_function_type_list_1 (bool vaargs,
*** 5893,5901 ****
if (vaargs)
{
! last = args;
! if (args != NULL_TREE)
! args = nreverse (args);
gcc_assert (args != NULL_TREE && last != void_list_node);
}
else if (args == NULL_TREE)
--- 5968,5976 ----
if (vaargs)
{
! last = args;
! if (args != NULL_TREE)
! args = nreverse (args);
gcc_assert (args != NULL_TREE && last != void_list_node);
}
else if (args == NULL_TREE)
Index: tree.h
===================================================================
*** tree.h (revision 139571)
--- tree.h (working copy)
*************** extern tree build_index_2_type (tree, tr
*** 3994,3999 ****
--- 3994,4001 ----
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);
Index: gimple.c
===================================================================
*** gimple.c (revision 139571)
--- gimple.c (working copy)
*************** canonicalize_cond_expr_cond (tree t)
*** 3180,3183 ****
--- 3180,3216 ----
return NULL_TREE;
}
+ /* Build call same as STMT but skipping arguments ARGS_TO_SKIP. */
+ gimple
+ gimple_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"
Index: gimple.h
===================================================================
*** gimple.h (revision 139571)
--- gimple.h (working copy)
*************** basic_block gsi_insert_on_edge_immediate
*** 4471,4476 ****
--- 4471,4477 ----
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 gimple_copy_call_skip_args (gimple, bitmap);
/* Convenience routines to walk all statements of a gimple function.