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]

[PATCH] Fix pr40914


This is my first foray into gimple stuff... beware!

This patch fixes a failure in the IPA inlining code where we miss an
opportunity to simplify a pointer-to-member function call on machines
where the vbit is stored in the delta rather than the function pointer.
The two code paths are sufficiently similar that we simply need to
detect the use of the delta field rather than the pfn when checking
whether the bit is being tested.

Tested on an arm-eabi cross, fixing g++.dg/ipa/iinline.C.

<date> Richard Earnshaw  <rearnsha@arm.com>

	* ipa-prop.c (ipa_get_ptr_load_param): New argument use_delta,
	if set, then check the delta field of the PMF record.
	(ipa_get_stmt_member_ptr_load_param): Propagate new param use_delta.
	(ipa_analyze_call_uses): Handle machines where the vbit for a PMF
	call is stored in the delta.

*** ipa-prop.c	(revision 150275)
--- ipa-prop.c	(local)
*************** ipa_compute_jump_functions (struct cgrap
*** 585,609 ****
    compute_cst_member_ptr_arguments (arguments->jump_functions, call);
  }
  
! /* If RHS looks like a rhs of a statement loading pfn from a member pointer
!    formal parameter, return the parameter, otherwise return NULL.  */
  
  static tree
! ipa_get_member_ptr_load_param (tree rhs)
  {
    tree rec, fld;
    tree ptr_field;
  
    if (TREE_CODE (rhs) != COMPONENT_REF)
      return NULL_TREE;
  
    rec = TREE_OPERAND (rhs, 0);
    if (TREE_CODE (rec) != PARM_DECL
!       || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, NULL))
      return NULL_TREE;
  
    fld = TREE_OPERAND (rhs, 1);
!   if (fld == ptr_field)
      return rec;
    else
      return NULL_TREE;
--- 585,612 ----
    compute_cst_member_ptr_arguments (arguments->jump_functions, call);
  }
  
! /* If RHS looks like a rhs of a statement loading pfn from a member
!    pointer formal parameter, return the parameter, otherwise return
!    NULL.  If USE_DELTA, then we look for a use of the delta field
!    rather than the pfn.  */
  
  static tree
! ipa_get_member_ptr_load_param (tree rhs, bool use_delta)
  {
    tree rec, fld;
    tree ptr_field;
+   tree delta_field;
  
    if (TREE_CODE (rhs) != COMPONENT_REF)
      return NULL_TREE;
  
    rec = TREE_OPERAND (rhs, 0);
    if (TREE_CODE (rec) != PARM_DECL
!       || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field))
      return NULL_TREE;
  
    fld = TREE_OPERAND (rhs, 1);
!   if (use_delta ? (fld == delta_field) : (fld == ptr_field))
      return rec;
    else
      return NULL_TREE;
*************** ipa_get_member_ptr_load_param (tree rhs)
*** 613,619 ****
     parameter, this function returns that parameter.  */
  
  static tree
! ipa_get_stmt_member_ptr_load_param (gimple stmt)
  {
    tree rhs;
  
--- 616,622 ----
     parameter, this function returns that parameter.  */
  
  static tree
! ipa_get_stmt_member_ptr_load_param (gimple stmt, bool use_delta)
  {
    tree rhs;
  
*************** ipa_get_stmt_member_ptr_load_param (gimp
*** 621,627 ****
      return NULL_TREE;
  
    rhs = gimple_assign_rhs1 (stmt);
!   return ipa_get_member_ptr_load_param (rhs);
  }
  
  /* Returns true iff T is an SSA_NAME defined by a statement.  */
--- 624,630 ----
      return NULL_TREE;
  
    rhs = gimple_assign_rhs1 (stmt);
!   return ipa_get_member_ptr_load_param (rhs, use_delta);
  }
  
  /* Returns true iff T is an SSA_NAME defined by a statement.  */
*************** ipa_analyze_call_uses (struct ipa_node_p
*** 756,770 ****
    d1 = SSA_NAME_DEF_STMT (n1);
    d2 = SSA_NAME_DEF_STMT (n2);
  
!   if ((rec = ipa_get_stmt_member_ptr_load_param (d1)))
      {
!       if (ipa_get_stmt_member_ptr_load_param (d2))
  	return;
  
        bb = gimple_bb (d1);
        virt_bb = gimple_bb (d2);
      }
!   else if ((rec = ipa_get_stmt_member_ptr_load_param (d2)))
      {
        bb = gimple_bb (d2);
        virt_bb = gimple_bb (d1);
--- 759,773 ----
    d1 = SSA_NAME_DEF_STMT (n1);
    d2 = SSA_NAME_DEF_STMT (n2);
  
!   if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false)))
      {
!       if (ipa_get_stmt_member_ptr_load_param (d2, false))
  	return;
  
        bb = gimple_bb (d1);
        virt_bb = gimple_bb (d2);
      }
!   else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false)))
      {
        bb = gimple_bb (d2);
        virt_bb = gimple_bb (d1);
*************** ipa_analyze_call_uses (struct ipa_node_p
*** 817,823 ****
        def = SSA_NAME_DEF_STMT (cond);
      }
  
!   rec2 = ipa_get_stmt_member_ptr_load_param (def);
    if (rec != rec2)
      return;
  
--- 820,829 ----
        def = SSA_NAME_DEF_STMT (cond);
      }
  
!   rec2 = ipa_get_stmt_member_ptr_load_param (def,
! 					     (TARGET_PTRMEMFUNC_VBIT_LOCATION
! 					      == ptrmemfunc_vbit_in_delta));
! 
    if (rec != rec2)
      return;
  

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