This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [trans-mem] do not inline wrapper functions
On Thu, Sep 10, 2009 at 01:48:14PM +0200, Richard Guenther wrote:
> On Thu, Sep 10, 2009 at 1:43 PM, Aldy Hernandez<aldyh@redhat.com> wrote:
> > Imagine candy(), a wrapper for tootsie_roll(). ?Currently, if the
> > inliner thinks candy() can be inlined, it will do so, thus never
> > performing the tootsie_roll() replacement. ?This is because the inliner
> > runs before the TM does its thing. ?(See test below).
> >
> > I have fixed the problem by making the inliner ignore inline candidates which
> > will get wrapped.
> >
> > OK for branch?
>
> Shouldn't the frontend instead simply mark the call as
> CALL_CANNOT_INLINE_P? Or somehow make it obvious that
> the call statement call fndecl isn't the real function that gets called?
> I can think of other analysis passes that would get confused here.
Fair enough. How does this look?
I am a little concerned that every time we create a function call we
have to search in the TM replacements hash, but I suppose it's only for
the TM case and doesn't affect anyone else.
Richards, is a per function creation hash search expensive enough to
merit using a bit in `struct function` to signify "is_tm_wrapper" ?
Aldy
* tree.h (find_tm_replacement_function): Protoize.
* trans-mem.c (find_tm_replacement_function): Declare extern.
* c-typeck.c (build_function_call_vec): Do not inline TM wrapper
functions.
Index: tree.h
===================================================================
--- tree.h (revision 151563)
+++ tree.h (working copy)
@@ -5276,6 +5276,7 @@ extern bool is_tm_pure (tree);
extern bool is_tm_callable (tree);
extern bool is_tm_irrevocable (tree);
extern void record_tm_replacement (tree, tree);
+extern tree find_tm_replacement_function (tree);
/* In tree-inline.c. */
Index: testsuite/gcc.dg/tm/wrap-4.c
===================================================================
--- testsuite/gcc.dg/tm/wrap-4.c (revision 0)
+++ testsuite/gcc.dg/tm/wrap-4.c (revision 0)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-optimized -O2" } */
+
+static void candy() { candycane(); }
+
+static void tootsie_roll () __attribute__((tm_wrap (candy)));
+static void tootsie_roll () { bark(); }
+
+void foo()
+{
+ __tm_atomic candy();
+}
+
+/* { dg-final { scan-tree-dump-times "candy" 0 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
Index: trans-mem.c
===================================================================
--- trans-mem.c (revision 151577)
+++ trans-mem.c (working copy)
@@ -340,7 +340,7 @@ record_tm_replacement (tree from, tree t
/* Return a TM-aware replacement function for DECL. */
-static tree
+tree
find_tm_replacement_function (tree fndecl)
{
if (tm_wrap_map)
Index: c-typeck.c
===================================================================
--- c-typeck.c (revision 151563)
+++ c-typeck.c (working copy)
@@ -2500,7 +2500,7 @@ build_function_call_vec (location_t loc,
tree tem;
int nargs;
tree *argarray;
-
+ tree orig_function = function;
/* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
STRIP_TYPE_NOPS (function);
@@ -2638,6 +2638,14 @@ build_function_call_vec (location_t loc,
result = build_call_array_loc (loc, TREE_TYPE (fntype),
function, nargs, argarray);
+ /* Do not inline wrapper functions that will get replaced in the TM
+ pass. */
+ if (flag_tm
+ && TREE_CODE (orig_function) == FUNCTION_DECL
+ && TREE_CODE (result) == CALL_EXPR
+ && find_tm_replacement_function (orig_function) != NULL_TREE)
+ CALL_CANNOT_INLINE_P (result) = 1;
+
if (VOID_TYPE_P (TREE_TYPE (result)))
{
if (TYPE_QUALS (TREE_TYPE (result)) != TYPE_UNQUALIFIED)