This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]