Message ID | 20201027102245.GA58336@kam.mff.cuni.cz |
---|---|
State | New |
Headers | show |
Series | Add fnspec to C++ new and delete | expand |
On Tue, 27 Oct 2020, Jan Hubicka wrote: > Hi, > this patch makes C++ new and delete operators to be handled as > malloc/free for fnspec. > > I still do not understand why free is ".co " and not ".cO ". > I do not think we need to invalidate memory referenced to by blockbeing > freed. > > Bootstrapped/regtested x86_64-linux, OK? OK. Richard. > Honza > > gcc/ChangeLog: > > 2020-10-27 Jan Hubicka <hubicka@ucw.cz> > > * gimple.c (gimple_call_fnspec): Handle C++ new and delete. > * gimple.h (gimple_call_from_new_or_delete): Constify parameter. > > gcc/testsuite/ChangeLog: > > 2020-10-27 Jan Hubicka <hubicka@ucw.cz> > > * g++.dg/ipa/devirt-24.C: Update template. > > diff --git a/gcc/gimple.c b/gcc/gimple.c > index 469e6f369f3..1afed88e1f1 100644 > --- a/gcc/gimple.c > +++ b/gcc/gimple.c > @@ -1510,6 +1510,19 @@ gimple_call_fnspec (const gcall *stmt) > } > if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) > return builtin_fnspec (gimple_call_fndecl (stmt)); > + tree fndecl = gimple_call_fndecl (stmt); > + /* If the call is to a replaceable operator delete and results > + from a delete expression as opposed to a direct call to > + such operator, then we can treat it as free. */ > + if (fndecl > + && DECL_IS_OPERATOR_DELETE_P (fndecl) > + && gimple_call_from_new_or_delete (stmt)) > + return ".co "; > + /* Similarly operator new can be treated as malloc. */ > + if (fndecl > + && DECL_IS_OPERATOR_NEW_P (fndecl) > + && gimple_call_from_new_or_delete (stmt)) > + return "mC"; > return ""; > } > > diff --git a/gcc/gimple.h b/gcc/gimple.h > index 3c9b9965f5a..fdb00d57b07 100644 > --- a/gcc/gimple.h > +++ b/gcc/gimple.h > @@ -3405,7 +3405,7 @@ gimple_call_set_from_new_or_delete (gcall *s, bool from_new_or_delete_p) > from a new or delete expression. */ > > static inline bool > -gimple_call_from_new_or_delete (gcall *s) > +gimple_call_from_new_or_delete (const gcall *s) > { > return (s->subcode & GF_CALL_FROM_NEW_OR_DELETE) != 0; > } > diff --git a/gcc/testsuite/g++.dg/ipa/devirt-24.C b/gcc/testsuite/g++.dg/ipa/devirt-24.C > index eaef1f5b3f8..7b5b806dd05 100644 > --- a/gcc/testsuite/g++.dg/ipa/devirt-24.C > +++ b/gcc/testsuite/g++.dg/ipa/devirt-24.C > @@ -37,4 +37,4 @@ C *b = new (C); > } > } > /* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 1 "inline" { xfail *-*-* } } } */ > -/* { dg-final { scan-ipa-dump-times "Aggregate passed by reference" 1 "cp" } } */ > +/* { dg-final { scan-ipa-dump-times "Aggregate passed by reference" 2 "cp" } } */ >
Hi, On Tue, 27 Oct 2020 at 11:22, Jan Hubicka <hubicka@ucw.cz> wrote: > > Hi, > this patch makes C++ new and delete operators to be handled as > malloc/free for fnspec. > > I still do not understand why free is ".co " and not ".cO ". > I do not think we need to invalidate memory referenced to by blockbeing > freed. > > Bootstrapped/regtested x86_64-linux, OK? > > Honza > > gcc/ChangeLog: > > 2020-10-27 Jan Hubicka <hubicka@ucw.cz> > > * gimple.c (gimple_call_fnspec): Handle C++ new and delete. > * gimple.h (gimple_call_from_new_or_delete): Constify parameter. > > gcc/testsuite/ChangeLog: > > 2020-10-27 Jan Hubicka <hubicka@ucw.cz> > > * g++.dg/ipa/devirt-24.C: Update template. > This patch introduced a regression on arm-eabi (with newlib, as opposed to arm-linux* with glibc): FAIL: g++.dg/torture/pr79671.C -O1 execution test It seems this also regressed on sparc-solaris according to gcc-testresults. Christophe > diff --git a/gcc/gimple.c b/gcc/gimple.c > index 469e6f369f3..1afed88e1f1 100644 > --- a/gcc/gimple.c > +++ b/gcc/gimple.c > @@ -1510,6 +1510,19 @@ gimple_call_fnspec (const gcall *stmt) > } > if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) > return builtin_fnspec (gimple_call_fndecl (stmt)); > + tree fndecl = gimple_call_fndecl (stmt); > + /* If the call is to a replaceable operator delete and results > + from a delete expression as opposed to a direct call to > + such operator, then we can treat it as free. */ > + if (fndecl > + && DECL_IS_OPERATOR_DELETE_P (fndecl) > + && gimple_call_from_new_or_delete (stmt)) > + return ".co "; > + /* Similarly operator new can be treated as malloc. */ > + if (fndecl > + && DECL_IS_OPERATOR_NEW_P (fndecl) > + && gimple_call_from_new_or_delete (stmt)) > + return "mC"; > return ""; > } > > diff --git a/gcc/gimple.h b/gcc/gimple.h > index 3c9b9965f5a..fdb00d57b07 100644 > --- a/gcc/gimple.h > +++ b/gcc/gimple.h > @@ -3405,7 +3405,7 @@ gimple_call_set_from_new_or_delete (gcall *s, bool from_new_or_delete_p) > from a new or delete expression. */ > > static inline bool > -gimple_call_from_new_or_delete (gcall *s) > +gimple_call_from_new_or_delete (const gcall *s) > { > return (s->subcode & GF_CALL_FROM_NEW_OR_DELETE) != 0; > } > diff --git a/gcc/testsuite/g++.dg/ipa/devirt-24.C b/gcc/testsuite/g++.dg/ipa/devirt-24.C > index eaef1f5b3f8..7b5b806dd05 100644 > --- a/gcc/testsuite/g++.dg/ipa/devirt-24.C > +++ b/gcc/testsuite/g++.dg/ipa/devirt-24.C > @@ -37,4 +37,4 @@ C *b = new (C); > } > } > /* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 1 "inline" { xfail *-*-* } } } */ > -/* { dg-final { scan-ipa-dump-times "Aggregate passed by reference" 1 "cp" } } */ > +/* { dg-final { scan-ipa-dump-times "Aggregate passed by reference" 2 "cp" } } */
diff --git a/gcc/gimple.c b/gcc/gimple.c index 469e6f369f3..1afed88e1f1 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -1510,6 +1510,19 @@ gimple_call_fnspec (const gcall *stmt) } if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) return builtin_fnspec (gimple_call_fndecl (stmt)); + tree fndecl = gimple_call_fndecl (stmt); + /* If the call is to a replaceable operator delete and results + from a delete expression as opposed to a direct call to + such operator, then we can treat it as free. */ + if (fndecl + && DECL_IS_OPERATOR_DELETE_P (fndecl) + && gimple_call_from_new_or_delete (stmt)) + return ".co "; + /* Similarly operator new can be treated as malloc. */ + if (fndecl + && DECL_IS_OPERATOR_NEW_P (fndecl) + && gimple_call_from_new_or_delete (stmt)) + return "mC"; return ""; } diff --git a/gcc/gimple.h b/gcc/gimple.h index 3c9b9965f5a..fdb00d57b07 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -3405,7 +3405,7 @@ gimple_call_set_from_new_or_delete (gcall *s, bool from_new_or_delete_p) from a new or delete expression. */ static inline bool -gimple_call_from_new_or_delete (gcall *s) +gimple_call_from_new_or_delete (const gcall *s) { return (s->subcode & GF_CALL_FROM_NEW_OR_DELETE) != 0; } diff --git a/gcc/testsuite/g++.dg/ipa/devirt-24.C b/gcc/testsuite/g++.dg/ipa/devirt-24.C index eaef1f5b3f8..7b5b806dd05 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-24.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-24.C @@ -37,4 +37,4 @@ C *b = new (C); } } /* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 1 "inline" { xfail *-*-* } } } */ -/* { dg-final { scan-ipa-dump-times "Aggregate passed by reference" 1 "cp" } } */ +/* { dg-final { scan-ipa-dump-times "Aggregate passed by reference" 2 "cp" } } */