[PATCH 3/3] Remove known_type jump functions, type_preserved flags and more from ipa-prop

Jan Hubicka hubicka@ucw.cz
Fri Nov 14 18:09:00 GMT 2014


> Hi,
> 
> this patch removes now completely unnecessary KNOWN_TYPE jump
> functions, type_preserved fields from PASS_THROUGH and ANCESTOR jump
> functions and type field from ANCESTOR jump functions because the
> previous patch makes them unused.
> 
> This means most of dynamic type change detection is removed.  The only
> one that is kept is the one ipa_analyze_virtual_call_uses where
> indirect_infos are populated.  The main reason is that so far I have
> not verified I can remove it there too but if so I'd prefer to do that
> in a separate patch anyway.
> 
> The patch performs 30 insertions, 410 deletions and simplifies things
> quite a bit so I'd like to see it committed along with the previous
> two.  A very similar patch has passed bootstrap and testing on
> x86_64-linux, testing of exactly this one is also underway.  I also
> pan more tests on i686-linux and ppc64-aix.  OK for trunk if all goes
> well?
> 
> Thanks,
> 
> Martin
> 
> 
> 2014-11-14  Martin Jambor  <mjambor@suse.cz>
> 
> 	* ipa-prop.h (jump_func_type): Removed value IPA_JF_KNOWN_TYPE.
> 	(ipa_pass_through_data): Removed field type_preserved.
> 	(ipa_ancestor_jf_data): removed fields type and type_preserved.
> 	(ipa_jump_func): Removed field known_type.
> 	(ipa_get_jf_known_type_offset): Removed.
> 	(ipa_get_jf_known_type_base_type): Likewise.
> 	(ipa_get_jf_known_type_component_type): Likewise.
> 	(ipa_get_jf_ancestor_type): Likewise.
> 	* ipa-cp.c (print_ipcp_constant_value): Removed BINFO handling.
> 	(ipa_get_jf_pass_through_result): Likewise.
> 	(ipa_get_jf_ancestor_result): Always build ptr_node_type accesses.
> 	(values_equal_for_ipcp_p): Removed BINFO handling.
> 	(ipa_get_indirect_edge_target_1): Updated comment.
> 	* ipa-prop.c (ipa_print_node_jump_functions_for_edge): Removed handling
> 	of IPA_JF_KNOWN_TYPE jump functions.  Do not print removed fields.
> 	(ipa_set_jf_known_type): Removed.
> 	(ipa_set_jf_simple_pass_through): Do not set removed fields.  Update
> 	all callers.
> 	(ipa_set_jf_arith_pass_through): Likewise.
> 	(ipa_set_ancestor_jf): Likewise.
> 	(ipa_binfo_from_known_type_jfunc): Removed.
> 	(prop_type_change_info): Removed fields known_current_type and
> 	multiple_types_encountered.
> 	(extr_type_from_vtbl_ptr_store): Removed.
> 	(check_stmt_for_type_change): Do not attempt to identify changed type.
> 	(detect_type_change_from_memory_writes): Do not set the removed fields,
> 	always set jfunc to unknown.
> 	(compute_complex_assign_jump_func): Do not detect dynamic type change.
> 	(compute_complex_ancestor_jump_func): Likewise.
> 	(compute_known_type_jump_func): Removed.
> 	(ipa_compute_jump_functions_for_edge): Do not detect dynamic type
> 	change.  Do not comute known type jump functions.
> 	(combine_known_type_and_ancestor_jfs): Removed.
> 	(update_jump_functions_after_inlining): Removed handling of
> 	IPA_JF_KNOWN_TYPE jump functions.  Do not set removed fields.
> 	(ipa_write_jump_function): Do not stream removed fields or known type
> 	jump functions.
> 	(ipa_read_jump_function): Likewise.

OK,
the type preserved tracking will need to go back otherwise we get missed
optimization (using agg preserved is very conservative estimate), but the
implementation needs to be different anyway. I will try to do that soon.

Honza
> 
> Index: src/gcc/ipa-cp.c
> ===================================================================
> --- src.orig/gcc/ipa-cp.c	2014-11-14 01:59:11.135700073 +0100
> +++ src/gcc/ipa-cp.c	2014-11-14 01:59:11.131700073 +0100
> @@ -340,12 +340,7 @@ ipcp_lattice<valtype>::is_single_const (
>  static void
>  print_ipcp_constant_value (FILE * f, tree v)
>  {
> -  if (TREE_CODE (v) == TREE_BINFO)
> -    {
> -      fprintf (f, "BINFO ");
> -      print_generic_expr (f, BINFO_TYPE (v), 0);
> -    }
> -  else if (TREE_CODE (v) == ADDR_EXPR
> +  if (TREE_CODE (v) == ADDR_EXPR
>  	   && TREE_CODE (TREE_OPERAND (v, 0)) == CONST_DECL)
>      {
>        fprintf (f, "& ");
> @@ -842,21 +837,10 @@ ipa_get_jf_pass_through_result (struct i
>  {
>    tree restype, res;
>  
> -  if (TREE_CODE (input) == TREE_BINFO)
> -    {
> -      if (ipa_get_jf_pass_through_type_preserved (jfunc))
> -	{
> -	  gcc_checking_assert (ipa_get_jf_pass_through_operation (jfunc)
> -			       == NOP_EXPR);
> -	  return input;
> -	}
> -      return NULL_TREE;
> -    }
> -
> +  gcc_checking_assert (is_gimple_ip_invariant (input));
>    if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
>      return input;
>  
> -  gcc_checking_assert (is_gimple_ip_invariant (input));
>    if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
>        == tcc_comparison)
>      restype = boolean_type_node;
> @@ -883,9 +867,7 @@ ipa_get_jf_ancestor_result (struct ipa_j
>        tree t = TREE_OPERAND (input, 0);
>        t = build_ref_for_offset (EXPR_LOCATION (t), t,
>  				ipa_get_jf_ancestor_offset (jfunc),
> -				ipa_get_jf_ancestor_type (jfunc)
> -				? ipa_get_jf_ancestor_type (jfunc)
> -				: ptr_type_node, NULL, false);
> +				ptr_type_node, NULL, false);
>        return build_fold_addr_expr (t);
>      }
>    else
> @@ -1051,9 +1033,6 @@ values_equal_for_ipcp_p (tree x, tree y)
>    if (x == y)
>      return true;
>  
> -  if (TREE_CODE (x) == TREE_BINFO || TREE_CODE (y) == TREE_BINFO)
> -    return false;
> -
>    if (TREE_CODE (x) ==  ADDR_EXPR
>        && TREE_CODE (y) ==  ADDR_EXPR
>        && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
> @@ -1740,9 +1719,8 @@ propagate_constants_accross_call (struct
>  }
>  
>  /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
> -   (which can contain both constants and binfos), KNOWN_CONTEXTS, KNOWN_AGGS or
> -   AGG_REPS return the destination.  The latter three can be NULL.  If AGG_REPS
> -   is not NULL, KNOWN_AGGS is ignored.  */
> +   KNOWN_CONTEXTS, KNOWN_AGGS or AGG_REPS return the destination.  The latter
> +   three can be NULL.  If AGG_REPS is not NULL, KNOWN_AGGS is ignored.  */
>  
>  static tree
>  ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
> Index: src/gcc/ipa-prop.c
> ===================================================================
> --- src.orig/gcc/ipa-prop.c	2014-11-14 01:59:11.135700073 +0100
> +++ src/gcc/ipa-prop.c	2014-11-14 01:59:33.771700936 +0100
> @@ -303,15 +303,6 @@ ipa_print_node_jump_functions_for_edge (
>        fprintf (f, "       param %d: ", i);
>        if (type == IPA_JF_UNKNOWN)
>  	fprintf (f, "UNKNOWN\n");
> -      else if (type == IPA_JF_KNOWN_TYPE)
> -	{
> -	  fprintf (f, "KNOWN TYPE: base  ");
> -	  print_generic_expr (f, jump_func->value.known_type.base_type, 0);
> -	  fprintf (f, ", offset "HOST_WIDE_INT_PRINT_DEC", component ",
> -		   jump_func->value.known_type.offset);
> -	  print_generic_expr (f, jump_func->value.known_type.component_type, 0);
> -	  fprintf (f, "\n");
> -	}
>        else if (type == IPA_JF_CONST)
>  	{
>  	  tree val = jump_func->value.constant.value;
> @@ -340,21 +331,16 @@ ipa_print_node_jump_functions_for_edge (
>  	    }
>  	  if (jump_func->value.pass_through.agg_preserved)
>  	    fprintf (f, ", agg_preserved");
> -	  if (jump_func->value.pass_through.type_preserved)
> -	    fprintf (f, ", type_preserved");
>  	  fprintf (f, "\n");
>  	}
>        else if (type == IPA_JF_ANCESTOR)
>  	{
>  	  fprintf (f, "ANCESTOR: ");
> -	  fprintf (f, "%d, offset "HOST_WIDE_INT_PRINT_DEC", ",
> +	  fprintf (f, "%d, offset "HOST_WIDE_INT_PRINT_DEC,
>  		   jump_func->value.ancestor.formal_id,
>  		   jump_func->value.ancestor.offset);
> -	  print_generic_expr (f, jump_func->value.ancestor.type, 0);
>  	  if (jump_func->value.ancestor.agg_preserved)
>  	    fprintf (f, ", agg_preserved");
> -	  if (jump_func->value.ancestor.type_preserved)
> -	    fprintf (f, ", type_preserved");
>  	  fprintf (f, "\n");
>  	}
>  
> @@ -460,28 +446,6 @@ ipa_print_all_jump_functions (FILE *f)
>      }
>  }
>  
> -/* Set JFUNC to be a known type jump function.  */
> -
> -static void
> -ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
> -		       tree base_type, tree component_type)
> -{
> -  /* Recording and propagating main variants increases change that types
> -     will match.  */
> -  base_type = TYPE_MAIN_VARIANT (base_type);
> -  component_type = TYPE_MAIN_VARIANT (component_type);
> -
> -  gcc_assert (contains_polymorphic_type_p (base_type)
> -	      && contains_polymorphic_type_p (component_type));
> -  if (!flag_devirtualize)
> -    return;
> -  jfunc->type = IPA_JF_KNOWN_TYPE;
> -  jfunc->value.known_type.offset = offset,
> -  jfunc->value.known_type.base_type = base_type;
> -  jfunc->value.known_type.component_type = component_type;
> -  gcc_assert (component_type);
> -}
> -
>  /* Set JFUNC to be a copy of another jmp (to be used by jump function
>     combination code).  The two functions will share their rdesc.  */
>  
> @@ -528,14 +492,13 @@ ipa_set_jf_constant (struct ipa_jump_fun
>  /* Set JFUNC to be a simple pass-through jump function.  */
>  static void
>  ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
> -				bool agg_preserved, bool type_preserved)
> +				bool agg_preserved)
>  {
>    jfunc->type = IPA_JF_PASS_THROUGH;
>    jfunc->value.pass_through.operand = NULL_TREE;
>    jfunc->value.pass_through.formal_id = formal_id;
>    jfunc->value.pass_through.operation = NOP_EXPR;
>    jfunc->value.pass_through.agg_preserved = agg_preserved;
> -  jfunc->value.pass_through.type_preserved = type_preserved;
>  }
>  
>  /* Set JFUNC to be an arithmetic pass through jump function.  */
> @@ -549,61 +512,18 @@ ipa_set_jf_arith_pass_through (struct ip
>    jfunc->value.pass_through.formal_id = formal_id;
>    jfunc->value.pass_through.operation = operation;
>    jfunc->value.pass_through.agg_preserved = false;
> -  jfunc->value.pass_through.type_preserved = false;
>  }
>  
>  /* Set JFUNC to be an ancestor jump function.  */
>  
>  static void
>  ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
> -		     tree type, int formal_id, bool agg_preserved,
> -		     bool type_preserved)
> +		     int formal_id, bool agg_preserved)
>  {
> -  if (!flag_devirtualize)
> -    type_preserved = false;
> -  if (!type_preserved)
> -    type = NULL_TREE;
> -  if (type)
> -    type = TYPE_MAIN_VARIANT (type);
> -  if (!type || !contains_polymorphic_type_p (type))
> -    type_preserved = false;
>    jfunc->type = IPA_JF_ANCESTOR;
>    jfunc->value.ancestor.formal_id = formal_id;
>    jfunc->value.ancestor.offset = offset;
> -  jfunc->value.ancestor.type = type_preserved ? type : NULL;
>    jfunc->value.ancestor.agg_preserved = agg_preserved;
> -  jfunc->value.ancestor.type_preserved = type_preserved;
> -}
> -
> -/* Extract the acual BINFO being described by JFUNC which must be a known type
> -   jump function.  */
> -
> -tree
> -ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
> -{
> -  if (!RECORD_OR_UNION_TYPE_P (jfunc->value.known_type.base_type))
> -    return NULL_TREE;
> -
> -  tree base_binfo = TYPE_BINFO (jfunc->value.known_type.base_type);
> -
> -  if (!base_binfo)
> -    return NULL_TREE;
> -  /* FIXME: At LTO we can't propagate to non-polymorphic type, because
> -     we have no ODR equivalency on those.  This should be fixed by
> -     propagating on types rather than binfos that would make type
> -     matching here unnecesary.  */
> -  if (in_lto_p
> -      && (TREE_CODE (jfunc->value.known_type.component_type) != RECORD_TYPE
> -	  || !TYPE_BINFO (jfunc->value.known_type.component_type)
> -	  || !BINFO_VTABLE (TYPE_BINFO (jfunc->value.known_type.component_type))))
> -    {
> -      if (!jfunc->value.known_type.offset)
> -	return base_binfo;
> -      return NULL;
> -    }
> -  return get_binfo_at_offset (base_binfo,
> -			      jfunc->value.known_type.offset,
> -			      jfunc->value.known_type.component_type);
>  }
>  
>  /* Get IPA BB information about the given BB.  FBI is the context of analyzis
> @@ -627,14 +547,8 @@ struct prop_type_change_info
>    /* The declaration or SSA_NAME pointer of the base that we are checking for
>       type change.  */
>    tree object;
> -  /* If we actually can tell the type that the object has changed to, it is
> -     stored in this field.  Otherwise it remains NULL_TREE.  */
> -  tree known_current_type;
>    /* Set to true if dynamic type change has been detected.  */
>    bool type_maybe_changed;
> -  /* Set to true if multiple types have been encountered.  known_current_type
> -     must be disregarded in that case.  */
> -  bool multiple_types_encountered;
>  };
>  
>  /* Return true if STMT can modify a virtual method table pointer.
> @@ -702,57 +616,9 @@ stmt_may_be_vtbl_ptr_store (gimple stmt)
>    return true;
>  }
>  
> -/* If STMT can be proved to be an assignment to the virtual method table
> -   pointer of ANALYZED_OBJ and the type associated with the new table
> -   identified, return the type.  Otherwise return NULL_TREE.  */
> -
> -static tree
> -extr_type_from_vtbl_ptr_store (gimple stmt, struct prop_type_change_info *tci)
> -{
> -  HOST_WIDE_INT offset, size, max_size;
> -  tree lhs, rhs, base, binfo;
> -
> -  if (!gimple_assign_single_p (stmt))
> -    return NULL_TREE;
> -
> -  lhs = gimple_assign_lhs (stmt);
> -  rhs = gimple_assign_rhs1 (stmt);
> -  if (TREE_CODE (lhs) != COMPONENT_REF
> -      || !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
> -    return NULL_TREE;
> -
> -  base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
> -  if (offset != tci->offset
> -      || size != POINTER_SIZE
> -      || max_size != POINTER_SIZE)
> -    return NULL_TREE;
> -  if (TREE_CODE (base) == MEM_REF)
> -    {
> -      if (TREE_CODE (tci->object) != MEM_REF
> -	  || TREE_OPERAND (tci->object, 0) != TREE_OPERAND (base, 0)
> -	  || !tree_int_cst_equal (TREE_OPERAND (tci->object, 1),
> -				  TREE_OPERAND (base, 1)))
> -	return NULL_TREE;
> -    }
> -  else if (tci->object != base)
> -    return NULL_TREE;
> -
> -  binfo = vtable_pointer_value_to_binfo (rhs);
> -
> -  /* FIXME: vtable_pointer_value_to_binfo may return BINFO of a
> -     base of outer type.  In this case we would need to either
> -     work on binfos or translate it back to outer type and offset.
> -     KNOWN_TYPE jump functions are not ready for that, yet.  */
> -  if (!binfo || TYPE_BINFO (BINFO_TYPE (binfo)) != binfo)
> -   return NULL;
> -
> -  return BINFO_TYPE (binfo);
> -}
> -
> -/* Callback of walk_aliased_vdefs and a helper function for
> -   detect_type_change to check whether a particular statement may modify
> -   the virtual table pointer, and if possible also determine the new type of
> -   the (sub-)object.  It stores its result into DATA, which points to a
> +/* Callback of walk_aliased_vdefs and a helper function for detect_type_change
> +   to check whether a particular statement may modify the virtual table
> +   pointerIt stores its result into DATA, which points to a
>     prop_type_change_info structure.  */
>  
>  static bool
> @@ -763,14 +629,6 @@ check_stmt_for_type_change (ao_ref *ao A
>  
>    if (stmt_may_be_vtbl_ptr_store (stmt))
>      {
> -      tree type;
> -
> -      type = extr_type_from_vtbl_ptr_store (stmt, tci);
> -      gcc_assert (!type || TYPE_MAIN_VARIANT (type) == type);
> -      if (tci->type_maybe_changed
> -	  && type != tci->known_current_type)
> -	tci->multiple_types_encountered = true;
> -      tci->known_current_type = type;
>        tci->type_maybe_changed = true;
>        return true;
>      }
> @@ -885,25 +743,14 @@ detect_type_change_from_memory_writes (t
>  
>    tci.offset = offset;
>    tci.object = get_base_address (arg);
> -  tci.known_current_type = NULL_TREE;
>    tci.type_maybe_changed = false;
> -  tci.multiple_types_encountered = false;
>  
>    walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
>  		      &tci, NULL, &entry_reached);
>    if (!tci.type_maybe_changed)
>      return false;
>  
> -  if (!tci.known_current_type
> -      || tci.multiple_types_encountered
> -      || offset != 0
> -      /* When the walk reached function entry, it means that type
> -	 is set along some paths but not along others.  */
> -      || entry_reached)
> -    jfunc->type = IPA_JF_UNKNOWN;
> -  else
> -    ipa_set_jf_known_type (jfunc, 0, tci.known_current_type, comp_type);
> -
> +  jfunc->type = IPA_JF_UNKNOWN;
>    return true;
>  }
>  
> @@ -1354,13 +1201,7 @@ compute_complex_assign_jump_func (struct
>        else if (gimple_assign_single_p (stmt))
>  	{
>  	  bool agg_p = parm_ref_data_pass_through_p (fbi, index, call, tc_ssa);
> -	  bool type_p = false;
> -
> -	  if (param_type && POINTER_TYPE_P (param_type))
> -	    type_p = !detect_type_change_ssa (tc_ssa, TREE_TYPE (param_type),
> -					      call, jfunc);
> -	  if (type_p || jfunc->type == IPA_JF_UNKNOWN)
> -	    ipa_set_jf_simple_pass_through (jfunc, index, agg_p, type_p);
> +	  ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
>  	}
>        return;
>      }
> @@ -1386,16 +1227,8 @@ compute_complex_assign_jump_func (struct
>    /* Dynamic types are changed in constructors and destructors.  */
>    index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
>    if (index >= 0 && param_type && POINTER_TYPE_P (param_type))
> -    {
> -      bool type_p = (contains_polymorphic_type_p (TREE_TYPE (param_type))
> -		     && !detect_type_change (op1, base, TREE_TYPE (param_type),
> -					     call, jfunc, offset));
> -      if (type_p || jfunc->type == IPA_JF_UNKNOWN)
> -	ipa_set_ancestor_jf (jfunc, offset,
> -			     type_p ? TREE_TYPE (param_type) : NULL, index,
> -			     parm_ref_data_pass_through_p (fbi, index,
> -							   call, ssa), type_p);
> -    }
> +    ipa_set_ancestor_jf (jfunc, offset,  index,
> +			 parm_ref_data_pass_through_p (fbi, index, call, ssa));
>  }
>  
>  /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
> @@ -1468,7 +1301,7 @@ static void
>  compute_complex_ancestor_jump_func (struct func_body_info *fbi,
>  				    struct ipa_node_params *info,
>  				    struct ipa_jump_func *jfunc,
> -				    gimple call, gimple phi, tree param_type)
> +				    gimple call, gimple phi)
>  {
>    HOST_WIDE_INT offset;
>    gimple assign, cond;
> @@ -1520,56 +1353,8 @@ compute_complex_ancestor_jump_func (stru
>  	return;
>      }
>  
> -  bool type_p = false;
> -  if (param_type && POINTER_TYPE_P (param_type)
> -      && contains_polymorphic_type_p (TREE_TYPE (param_type)))
> -    type_p = !detect_type_change (obj, expr, TREE_TYPE (param_type),
> -				  call, jfunc, offset);
> -  if (type_p || jfunc->type == IPA_JF_UNKNOWN)
> -    ipa_set_ancestor_jf (jfunc, offset, type_p ? TREE_TYPE (param_type) : NULL,
> -			 index,
> -			 parm_ref_data_pass_through_p (fbi, index, call, parm),
> -			 type_p);
> -}
> -
> -/* Given OP which is passed as an actual argument to a called function,
> -   determine if it is possible to construct a KNOWN_TYPE jump function for it
> -   and if so, create one and store it to JFUNC.
> -   EXPECTED_TYPE represents a type the argument should be in  */
> -
> -static void
> -compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc,
> -			      gimple call, tree expected_type)
> -{
> -  HOST_WIDE_INT offset, size, max_size;
> -  tree base;
> -
> -  if (!flag_devirtualize
> -      || TREE_CODE (op) != ADDR_EXPR
> -      || !contains_polymorphic_type_p (TREE_TYPE (TREE_TYPE (op)))
> -      /* Be sure expected_type is polymorphic.  */
> -      || !expected_type
> -      || !contains_polymorphic_type_p (expected_type))
> -    return;
> -
> -  op = TREE_OPERAND (op, 0);
> -  base = get_ref_base_and_extent (op, &offset, &size, &max_size);
> -  if (!DECL_P (base)
> -      || max_size == -1
> -      || max_size != size
> -      || !contains_polymorphic_type_p (TREE_TYPE (base)))
> -    return;
> -
> -  if (decl_maybe_in_construction_p (base, TREE_TYPE (base),
> -				    call, current_function_decl)
> -      /* Even if the var seems to be in construction by inline call stack,
> -	 we may work out the actual type by walking memory writes.  */
> -      && (is_global_var (base)
> -	  || detect_type_change (op, base, expected_type, call, jfunc, offset)))
> -    return;
> -
> -  ipa_set_jf_known_type (jfunc, offset, TREE_TYPE (base),
> -			 expected_type);
> +  ipa_set_ancestor_jf (jfunc, offset, index,
> +		       parm_ref_data_pass_through_p (fbi, index, call, parm));
>  }
>  
>  /* Inspect the given TYPE and return true iff it has the same structure (the
> @@ -1944,7 +1729,7 @@ ipa_compute_jump_functions_for_edge (str
>  	     for cycle.  */
>  	  if (parm_preserved_before_stmt_p (fbi, index, call, arg))
>  	    {
> -	      ipa_set_jf_simple_pass_through (jfunc, index, false, false);
> +	      ipa_set_jf_simple_pass_through (jfunc, index, false);
>  	      continue;
>  	    }
>  	}
> @@ -1955,16 +1740,9 @@ ipa_compute_jump_functions_for_edge (str
>  	      int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
>  	      if (index >= 0)
>  		{
> -		  bool agg_p, type_p;
> +		  bool agg_p;
>  		  agg_p = parm_ref_data_pass_through_p (fbi, index, call, arg);
> -		  if (param_type && POINTER_TYPE_P (param_type))
> -		    type_p = !detect_type_change_ssa (arg, TREE_TYPE (param_type),
> -						      call, jfunc);
> -		  else
> -		    type_p = false;
> -		  if (type_p || jfunc->type == IPA_JF_UNKNOWN)
> -		    ipa_set_jf_simple_pass_through (jfunc, index, agg_p,
> -						    type_p);
> +		  ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
>  		}
>  	    }
>  	  else
> @@ -1975,15 +1753,9 @@ ipa_compute_jump_functions_for_edge (str
>  						  call, stmt, arg, param_type);
>  	      else if (gimple_code (stmt) == GIMPLE_PHI)
>  		compute_complex_ancestor_jump_func (fbi, info, jfunc,
> -						    call, stmt, param_type);
> +						    call, stmt);
>  	    }
>  	}
> -      else
> -	compute_known_type_jump_func (arg, jfunc, call,
> -				      param_type
> -				      && POINTER_TYPE_P (param_type)
> -				      ? TREE_TYPE (param_type)
> -				      : NULL);
>  
>        /* If ARG is pointer, we can not use its type to determine the type of aggregate
>  	 passed (because type conversions are ignored in gimple).  Usually we can
> @@ -2608,35 +2380,6 @@ ipa_analyze_node (struct cgraph_node *no
>    pop_cfun ();
>  }
>  
> -/* Update the jump function DST when the call graph edge corresponding to SRC is
> -   is being inlined, knowing that DST is of type ancestor and src of known
> -   type.  */
> -
> -static void
> -combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
> -				     struct ipa_jump_func *dst)
> -{
> -  HOST_WIDE_INT combined_offset;
> -  tree combined_type;
> -
> -  if (!ipa_get_jf_ancestor_type_preserved (dst))
> -    {
> -      dst->type = IPA_JF_UNKNOWN;
> -      return;
> -    }
> -
> -  combined_offset = ipa_get_jf_known_type_offset (src)
> -    + ipa_get_jf_ancestor_offset (dst);
> -  combined_type = ipa_get_jf_ancestor_type (dst);
> -
> -  if (combined_type)
> -    ipa_set_jf_known_type (dst, combined_offset,
> -			   ipa_get_jf_known_type_base_type (src),
> -			   combined_type);
> -  else
> -    dst->type = IPA_JF_UNKNOWN;
> -}
> -
>  /* Update the jump functions associated with call graph edge E when the call
>     graph edge CS is being inlined, assuming that E->caller is already (possibly
>     indirectly) inlined into CS->callee and that E has not been inlined.  */
> @@ -2707,16 +2450,12 @@ update_jump_functions_after_inlining (st
>  		item->offset -= dst->value.ancestor.offset;
>  	    }
>  
> -	  if (src->type == IPA_JF_KNOWN_TYPE)
> -	    combine_known_type_and_ancestor_jfs (src, dst);
> -	  else if (src->type == IPA_JF_PASS_THROUGH
> -		   && src->value.pass_through.operation == NOP_EXPR)
> +	  if (src->type == IPA_JF_PASS_THROUGH
> +	      && src->value.pass_through.operation == NOP_EXPR)
>  	    {
>  	      dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
>  	      dst->value.ancestor.agg_preserved &=
>  		src->value.pass_through.agg_preserved;
> -	      dst->value.ancestor.type_preserved &=
> -		src->value.pass_through.type_preserved;
>  	    }
>  	  else if (src->type == IPA_JF_ANCESTOR)
>  	    {
> @@ -2724,8 +2463,6 @@ update_jump_functions_after_inlining (st
>  	      dst->value.ancestor.offset += src->value.ancestor.offset;
>  	      dst->value.ancestor.agg_preserved &=
>  		src->value.ancestor.agg_preserved;
> -	      dst->value.ancestor.type_preserved &=
> -		src->value.ancestor.type_preserved;
>  	    }
>  	  else
>  	    dst->type = IPA_JF_UNKNOWN;
> @@ -2768,15 +2505,6 @@ update_jump_functions_after_inlining (st
>  		case IPA_JF_UNKNOWN:
>  		  dst->type = IPA_JF_UNKNOWN;
>  		  break;
> -		case IPA_JF_KNOWN_TYPE:
> -		  if (ipa_get_jf_pass_through_type_preserved (dst))
> -		    ipa_set_jf_known_type (dst,
> -					   ipa_get_jf_known_type_offset (src),
> -					   ipa_get_jf_known_type_base_type (src),
> -					   ipa_get_jf_known_type_component_type (src));
> -		  else
> -		    dst->type = IPA_JF_UNKNOWN;
> -		  break;
>  		case IPA_JF_CONST:
>  		  ipa_set_jf_cst_copy (dst, src);
>  		  break;
> @@ -2789,13 +2517,10 @@ update_jump_functions_after_inlining (st
>  
>  		    if (operation == NOP_EXPR)
>  		      {
> -			bool agg_p, type_p;
> +			bool agg_p;
>  			agg_p = dst_agg_p
>  			  && ipa_get_jf_pass_through_agg_preserved (src);
> -			type_p = ipa_get_jf_pass_through_type_preserved (src)
> -			  && ipa_get_jf_pass_through_type_preserved (dst);
> -			ipa_set_jf_simple_pass_through (dst, formal_id,
> -							agg_p, type_p);
> +			ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
>  		      }
>  		    else
>  		      {
> @@ -2807,16 +2532,13 @@ update_jump_functions_after_inlining (st
>  		  }
>  		case IPA_JF_ANCESTOR:
>  		  {
> -		    bool agg_p, type_p;
> +		    bool agg_p;
>  		    agg_p = dst_agg_p
>  		      && ipa_get_jf_ancestor_agg_preserved (src);
> -		    type_p = ipa_get_jf_ancestor_type_preserved (src)
> -		      && ipa_get_jf_pass_through_type_preserved (dst);
>  		    ipa_set_ancestor_jf (dst,
>  					 ipa_get_jf_ancestor_offset (src),
> -					 ipa_get_jf_ancestor_type (src),
>  					 ipa_get_jf_ancestor_formal_id (src),
> -					 agg_p, type_p);
> +					 agg_p);
>  		    break;
>  		  }
>  		default:
> @@ -4685,11 +4407,6 @@ ipa_write_jump_function (struct output_b
>      {
>      case IPA_JF_UNKNOWN:
>        break;
> -    case IPA_JF_KNOWN_TYPE:
> -      streamer_write_uhwi (ob, jump_func->value.known_type.offset);
> -      stream_write_tree (ob, jump_func->value.known_type.base_type, true);
> -      stream_write_tree (ob, jump_func->value.known_type.component_type, true);
> -      break;
>      case IPA_JF_CONST:
>        gcc_assert (
>  	  EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
> @@ -4702,7 +4419,6 @@ ipa_write_jump_function (struct output_b
>  	  streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
>  	  bp = bitpack_create (ob->main_stream);
>  	  bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
> -	  bp_pack_value (&bp, jump_func->value.pass_through.type_preserved, 1);
>  	  streamer_write_bitpack (&bp);
>  	}
>        else
> @@ -4713,11 +4429,9 @@ ipa_write_jump_function (struct output_b
>        break;
>      case IPA_JF_ANCESTOR:
>        streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
> -      stream_write_tree (ob, jump_func->value.ancestor.type, true);
>        streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
>        bp = bitpack_create (ob->main_stream);
>        bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
> -      bp_pack_value (&bp, jump_func->value.ancestor.type_preserved, 1);
>        streamer_write_bitpack (&bp);
>        break;
>      }
> @@ -4756,15 +4470,6 @@ ipa_read_jump_function (struct lto_input
>      case IPA_JF_UNKNOWN:
>        jump_func->type = IPA_JF_UNKNOWN;
>        break;
> -    case IPA_JF_KNOWN_TYPE:
> -      {
> -	HOST_WIDE_INT offset = streamer_read_uhwi (ib);
> -	tree base_type = stream_read_tree (ib, data_in);
> -	tree component_type = stream_read_tree (ib, data_in);
> -
> -	ipa_set_jf_known_type (jump_func, offset, base_type, component_type);
> -	break;
> -      }
>      case IPA_JF_CONST:
>        ipa_set_jf_constant (jump_func, stream_read_tree (ib, data_in), cs);
>        break;
> @@ -4775,9 +4480,7 @@ ipa_read_jump_function (struct lto_input
>  	  int formal_id =  streamer_read_uhwi (ib);
>  	  struct bitpack_d bp = streamer_read_bitpack (ib);
>  	  bool agg_preserved = bp_unpack_value (&bp, 1);
> -	  bool type_preserved = bp_unpack_value (&bp, 1);
> -	  ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved,
> -					  type_preserved);
> +	  ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
>  	}
>        else
>  	{
> @@ -4790,14 +4493,10 @@ ipa_read_jump_function (struct lto_input
>      case IPA_JF_ANCESTOR:
>        {
>  	HOST_WIDE_INT offset = streamer_read_uhwi (ib);
> -	tree type = stream_read_tree (ib, data_in);
>  	int formal_id = streamer_read_uhwi (ib);
>  	struct bitpack_d bp = streamer_read_bitpack (ib);
>  	bool agg_preserved = bp_unpack_value (&bp, 1);
> -	bool type_preserved = bp_unpack_value (&bp, 1);
> -
> -	ipa_set_ancestor_jf (jump_func, offset, type, formal_id, agg_preserved,
> -			     type_preserved);
> +	ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved);
>  	break;
>        }
>      }
> Index: src/gcc/ipa-prop.h
> ===================================================================
> --- src.orig/gcc/ipa-prop.h	2014-11-14 01:59:11.135700073 +0100
> +++ src/gcc/ipa-prop.h	2014-11-14 01:59:11.135700073 +0100
> @@ -51,11 +51,6 @@ along with GCC; see the file COPYING3.
>     parameter or can apply one simple binary operation to it (such jump
>     functions are called polynomial).
>  
> -   IPA_JF_KNOWN_TYPE is a special type of an "unknown" function that applies
> -   only to pointer parameters.  It means that even though we cannot prove that
> -   the passed value is an interprocedural constant, we still know the exact
> -   type of the containing object which may be valuable for devirtualization.
> -
>     Jump functions are computed in ipa-prop.c by function
>     update_call_notes_after_inlining.  Some information can be lost and jump
>     functions degraded accordingly when inlining, see
> @@ -64,7 +59,6 @@ along with GCC; see the file COPYING3.
>  enum jump_func_type
>  {
>    IPA_JF_UNKNOWN = 0,  /* newly allocated and zeroed jump functions default */
> -  IPA_JF_KNOWN_TYPE,        /* represented by field known_type */
>    IPA_JF_CONST,             /* represented by field costant */
>    IPA_JF_PASS_THROUGH,	    /* represented by field pass_through */
>    IPA_JF_ANCESTOR	    /* represented by field ancestor */
> @@ -113,11 +107,6 @@ struct GTY(()) ipa_pass_through_data
>       ipa_agg_jump_function).  The flag is used only when the operation is
>       NOP_EXPR.  */
>    unsigned agg_preserved : 1;
> -
> -  /* When set to true, we guarantee that, if there is a C++ object pointed to
> -     by this object, it does not undergo dynamic type change in the course of
> -     functions decribed by this jump function.  */
> -  unsigned type_preserved : 1;
>  };
>  
>  /* Structure holding data required to describe an ancestor pass-through
> @@ -127,18 +116,10 @@ struct GTY(()) ipa_ancestor_jf_data
>  {
>    /* Offset of the field representing the ancestor.  */
>    HOST_WIDE_INT offset;
> -  /* Type of the result.
> -     When TYPE_PRESERVED is false, TYPE is NULL, since it is only
> -     relevant for the devirtualization machinery.  */
> -  tree type;
>    /* Number of the caller's formal parameter being passed.  */
>    int formal_id;
>    /* Flag with the same meaning like agg_preserve in ipa_pass_through_data.  */
>    unsigned agg_preserved : 1;
> -  /* When set to true, we guarantee that, if there is a C++ object pointed to
> -     by this object, it does not undergo dynamic type change in the course of
> -     functions decribed by this jump function.  */
> -  unsigned type_preserved : 1;
>  };
>  
>  /* An element in an aggegate part of a jump function describing a known value
> @@ -189,7 +170,6 @@ struct GTY (()) ipa_jump_func
>       functions and member_cst holds constant c++ member functions.  */
>    union jump_func_value
>    {
> -    struct ipa_known_type_data GTY ((tag ("IPA_JF_KNOWN_TYPE"))) known_type;
>      struct ipa_constant_data GTY ((tag ("IPA_JF_CONST"))) constant;
>      struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through;
>      struct ipa_ancestor_jf_data GTY ((tag ("IPA_JF_ANCESTOR"))) ancestor;
> @@ -197,34 +177,6 @@ struct GTY (()) ipa_jump_func
>  };
>  
>  
> -/* Return the offset of the component that is described by a known type jump
> -   function JFUNC.  */
> -
> -static inline HOST_WIDE_INT
> -ipa_get_jf_known_type_offset (struct ipa_jump_func *jfunc)
> -{
> -  gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE);
> -  return jfunc->value.known_type.offset;
> -}
> -
> -/* Return the base type of a known type jump function JFUNC.  */
> -
> -static inline tree
> -ipa_get_jf_known_type_base_type (struct ipa_jump_func *jfunc)
> -{
> -  gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE);
> -  return jfunc->value.known_type.base_type;
> -}
> -
> -/* Return the component type of a known type jump function JFUNC.  */
> -
> -static inline tree
> -ipa_get_jf_known_type_component_type (struct ipa_jump_func *jfunc)
> -{
> -  gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE);
> -  return jfunc->value.known_type.component_type;
> -}
> -
>  /* Return the constant stored in a constant jump functin JFUNC.  */
>  
>  static inline tree
> @@ -297,15 +249,6 @@ ipa_get_jf_ancestor_offset (struct ipa_j
>    return jfunc->value.ancestor.offset;
>  }
>  
> -/* Return the result type of an ancestor jump function JFUNC.  */
> -
> -static inline tree
> -ipa_get_jf_ancestor_type (struct ipa_jump_func *jfunc)
> -{
> -  gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
> -  return jfunc->value.ancestor.type;
> -}
> -
>  /* Return the number of the caller's formal parameter that an ancestor jump
>     function JFUNC refers to.  */
>  



More information about the Gcc-patches mailing list