diff mbox series

[PR,91831] Copy PARM_DECLs of artificial thunks

Message ID ri6h85354po.fsf@suse.cz
State New
Headers show
Series [PR,91831] Copy PARM_DECLs of artificial thunks | expand

Commit Message

Martin Jambor Sept. 23, 2019, 4:59 p.m. UTC
Hi,

I am quite surprised I did not catch this before but the new
ipa-param-manipulation does not copy PARM_DECLs when creating artificial
thinks (I think it originally did but then I somehow removed during one
cleanups).  Fixed below by adding the capability at the natural place.
It is triggered whenever context of the PARM_DECL that is just taken
from the original function does not match the target fndecl rather than
by some constructor parameter because in such situation it is always the
correct thing to do.

Bootstrapped and tested on x86_64-linux.  OK for trunk?

Thanks,

Martin

2019-09-23  Martin Jambor  <mjambor@suse.cz>

	PR ipa/91831
	* ipa-param-manipulation.c (carry_over_param): Make a method of
	ipa_param_body_adjustments, remove now unnecessary argument.  Also copy
	in case of a context mismatch.
	(ipa_param_body_adjustments::common_initialization): Adjust call to
	carry_over_param.
	* ipa-param-manipulation.h (class ipa_param_body_adjustments): Add
	private method carry_over_param.

	testsuite/
	* g++.dg/ipa/pr91831.C: New test.
---
 gcc/ipa-param-manipulation.c       | 22 ++++++++++++++--------
 gcc/ipa-param-manipulation.h       |  1 +
 gcc/testsuite/g++.dg/ipa/pr91831.C | 19 +++++++++++++++++++
 3 files changed, 34 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ipa/pr91831.C

Comments

Richard Biener Sept. 24, 2019, 8:22 a.m. UTC | #1
On Mon, Sep 23, 2019 at 6:59 PM Martin Jambor <mjambor@suse.cz> wrote:
>
> Hi,
>
> I am quite surprised I did not catch this before but the new
> ipa-param-manipulation does not copy PARM_DECLs when creating artificial
> thinks (I think it originally did but then I somehow removed during one
> cleanups).  Fixed below by adding the capability at the natural place.
> It is triggered whenever context of the PARM_DECL that is just taken
> from the original function does not match the target fndecl rather than
> by some constructor parameter because in such situation it is always the
> correct thing to do.
>
> Bootstrapped and tested on x86_64-linux.  OK for trunk?

OK.

Thanks,
Richard.

> Thanks,
>
> Martin
>
> 2019-09-23  Martin Jambor  <mjambor@suse.cz>
>
>         PR ipa/91831
>         * ipa-param-manipulation.c (carry_over_param): Make a method of
>         ipa_param_body_adjustments, remove now unnecessary argument.  Also copy
>         in case of a context mismatch.
>         (ipa_param_body_adjustments::common_initialization): Adjust call to
>         carry_over_param.
>         * ipa-param-manipulation.h (class ipa_param_body_adjustments): Add
>         private method carry_over_param.
>
>         testsuite/
>         * g++.dg/ipa/pr91831.C: New test.
> ---
>  gcc/ipa-param-manipulation.c       | 22 ++++++++++++++--------
>  gcc/ipa-param-manipulation.h       |  1 +
>  gcc/testsuite/g++.dg/ipa/pr91831.C | 19 +++++++++++++++++++
>  3 files changed, 34 insertions(+), 8 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/ipa/pr91831.C
>
> diff --git a/gcc/ipa-param-manipulation.c b/gcc/ipa-param-manipulation.c
> index 7f52e9c2506..913b96fefa4 100644
> --- a/gcc/ipa-param-manipulation.c
> +++ b/gcc/ipa-param-manipulation.c
> @@ -906,18 +906,24 @@ ipa_param_body_adjustments::register_replacement (ipa_adjusted_param *apm,
>    m_replacements.safe_push (psr);
>  }
>
> -/* Copy or not, as appropriate given ID, a pre-existing PARM_DECL T so that
> -   it can be included in the parameters of the modified function.  */
> +/* Copy or not, as appropriate given m_id and decl context, a pre-existing
> +   PARM_DECL T so that it can be included in the parameters of the modified
> +   function.  */
>
> -static tree
> -carry_over_param (tree t, struct copy_body_data *id)
> +tree
> +ipa_param_body_adjustments::carry_over_param (tree t)
>  {
>    tree new_parm;
> -  if (id)
> +  if (m_id)
>      {
> -      new_parm = remap_decl (t, id);
> +      new_parm = remap_decl (t, m_id);
>        if (TREE_CODE (new_parm) != PARM_DECL)
> -       new_parm = id->copy_decl (t, id);
> +       new_parm = m_id->copy_decl (t, m_id);
> +    }
> +  else if (DECL_CONTEXT (t) != m_fndecl)
> +    {
> +      new_parm = copy_node (t);
> +      DECL_CONTEXT (new_parm) = m_fndecl;
>      }
>    else
>      new_parm = t;
> @@ -982,7 +988,7 @@ ipa_param_body_adjustments::common_initialization (tree old_fndecl,
>           || apm->prev_clone_adjustment)
>         {
>           kept[prev_index] = true;
> -         new_parm = carry_over_param (m_oparms[prev_index], m_id);
> +         new_parm = carry_over_param (m_oparms[prev_index]);
>           m_new_decls.quick_push (new_parm);
>         }
>        else if (apm->op == IPA_PARAM_OP_NEW
> diff --git a/gcc/ipa-param-manipulation.h b/gcc/ipa-param-manipulation.h
> index 34477da51b7..8e9554563e4 100644
> --- a/gcc/ipa-param-manipulation.h
> +++ b/gcc/ipa-param-manipulation.h
> @@ -370,6 +370,7 @@ public:
>  private:
>    void common_initialization (tree old_fndecl, tree *vars,
>                               vec<ipa_replace_map *, va_gc> *tree_map);
> +  tree carry_over_param (tree t);
>    unsigned get_base_index (ipa_adjusted_param *apm);
>    ipa_param_body_replacement *lookup_replacement_1 (tree base,
>                                                     unsigned unit_offset);
> diff --git a/gcc/testsuite/g++.dg/ipa/pr91831.C b/gcc/testsuite/g++.dg/ipa/pr91831.C
> new file mode 100644
> index 00000000000..66e4b693151
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/ipa/pr91831.C
> @@ -0,0 +1,19 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 --param uninlined-thunk-insns=1000"  } */
> +
> +struct A {
> +  virtual void m_fn1();
> +};
> +struct B {
> +  virtual void *m_fn2(int, int) = 0;
> +};
> +struct C : A, B {
> +  void *m_fn2(int, int) { return this; }
> +};
> +void *fn1(B &p1) { return p1.m_fn2(0, 0); }
> +
> +int main() {
> +  C c;
> +  fn1(c);
> +  return 0;
> +}
> --
> 2.23.0
>
diff mbox series

Patch

diff --git a/gcc/ipa-param-manipulation.c b/gcc/ipa-param-manipulation.c
index 7f52e9c2506..913b96fefa4 100644
--- a/gcc/ipa-param-manipulation.c
+++ b/gcc/ipa-param-manipulation.c
@@ -906,18 +906,24 @@  ipa_param_body_adjustments::register_replacement (ipa_adjusted_param *apm,
   m_replacements.safe_push (psr);
 }
 
-/* Copy or not, as appropriate given ID, a pre-existing PARM_DECL T so that
-   it can be included in the parameters of the modified function.  */
+/* Copy or not, as appropriate given m_id and decl context, a pre-existing
+   PARM_DECL T so that it can be included in the parameters of the modified
+   function.  */
 
-static tree
-carry_over_param (tree t, struct copy_body_data *id)
+tree
+ipa_param_body_adjustments::carry_over_param (tree t)
 {
   tree new_parm;
-  if (id)
+  if (m_id)
     {
-      new_parm = remap_decl (t, id);
+      new_parm = remap_decl (t, m_id);
       if (TREE_CODE (new_parm) != PARM_DECL)
-	new_parm = id->copy_decl (t, id);
+	new_parm = m_id->copy_decl (t, m_id);
+    }
+  else if (DECL_CONTEXT (t) != m_fndecl)
+    {
+      new_parm = copy_node (t);
+      DECL_CONTEXT (new_parm) = m_fndecl;
     }
   else
     new_parm = t;
@@ -982,7 +988,7 @@  ipa_param_body_adjustments::common_initialization (tree old_fndecl,
 	  || apm->prev_clone_adjustment)
 	{
 	  kept[prev_index] = true;
-	  new_parm = carry_over_param (m_oparms[prev_index], m_id);
+	  new_parm = carry_over_param (m_oparms[prev_index]);
 	  m_new_decls.quick_push (new_parm);
 	}
       else if (apm->op == IPA_PARAM_OP_NEW
diff --git a/gcc/ipa-param-manipulation.h b/gcc/ipa-param-manipulation.h
index 34477da51b7..8e9554563e4 100644
--- a/gcc/ipa-param-manipulation.h
+++ b/gcc/ipa-param-manipulation.h
@@ -370,6 +370,7 @@  public:
 private:
   void common_initialization (tree old_fndecl, tree *vars,
 			      vec<ipa_replace_map *, va_gc> *tree_map);
+  tree carry_over_param (tree t);
   unsigned get_base_index (ipa_adjusted_param *apm);
   ipa_param_body_replacement *lookup_replacement_1 (tree base,
 						    unsigned unit_offset);
diff --git a/gcc/testsuite/g++.dg/ipa/pr91831.C b/gcc/testsuite/g++.dg/ipa/pr91831.C
new file mode 100644
index 00000000000..66e4b693151
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr91831.C
@@ -0,0 +1,19 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 --param uninlined-thunk-insns=1000"  } */
+
+struct A {
+  virtual void m_fn1();
+};
+struct B {
+  virtual void *m_fn2(int, int) = 0;
+};
+struct C : A, B {
+  void *m_fn2(int, int) { return this; }
+};
+void *fn1(B &p1) { return p1.m_fn2(0, 0); }
+
+int main() {
+  C c;
+  fn1(c);
+  return 0;
+}