From patchwork Tue Jun 15 14:18:43 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [trans-mem] undefined reference to a static cloned function Date: Tue, 15 Jun 2010 04:18:43 -0000 From: Aldy Hernandez X-Patchwork-Id: 55674 Message-Id: <20100615141842.GA27062@redhat.com> To: Patrick Marlier Cc: Richard Henderson , FELBER Pascal , gcc-patches@gcc.gnu.org Here we have a testcase where the compiler can determine that it only needs the transactional version of a function, so the original function is not outputted, however we still dump the clone table entry. Ooops. I've put the original check back, since just checking the availability of the transactional clone will not do. Committing as obvious. * varasm.c (finish_tm_clone_pairs_1): Do not dump entry if the original function is not needed. Index: testsuite/gcc.dg/tm/20100615.c =================================================================== --- testsuite/gcc.dg/tm/20100615.c (revision 0) +++ testsuite/gcc.dg/tm/20100615.c (revision 0) @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-fgnu-tm -O" } */ + +/* Since the non TM version of new_node() gets optimized away, it + shouldn't appear in the clone table either. */ +/* { dg-final { scan-assembler-not "clone_table" } } */ + +#define NULL 0 +extern void *malloc (__SIZE_TYPE__); + +__attribute__((transaction_pure)) +void exit(int status); + +typedef struct node { +} node_t; + +__attribute__((transaction_safe)) +static node_t *new_node(node_t *next) +{ + node_t *node; + node = (node_t *)malloc(sizeof(node_t)); + if (node == NULL) { + exit(1); + } + return NULL; +} + +static node_t *set_new() +{ + node_t *min, *max; + __transaction [[atomic]] { + max = new_node(NULL); + min = new_node(max); + } + return min; +} + +int main(int argc, char **argv) +{ + set_new(); + return 0; +} Index: varasm.c =================================================================== --- varasm.c (revision 160590) +++ varasm.c (working copy) @@ -5850,6 +5850,7 @@ finish_tm_clone_pairs_1 (void **slot, vo bool *switched = (bool *) info; tree src = map->base.from; tree dst = map->to; + struct cgraph_node *src_n = cgraph_node (src); struct cgraph_node *dst_n = cgraph_node (dst); /* The function ipa_tm_create_version() marks the clone as needed if @@ -5861,6 +5862,11 @@ finish_tm_clone_pairs_1 (void **slot, vo if (!dst_n->needed) return 1; + /* This covers the case where we have optimized the original + function away, and only access the transactional clone. */ + if (!src_n->needed) + return 1; + if (!*switched) { switch_to_section (get_named_section (NULL, ".tm_clone_table", 3));