In PR51280, LTO does ICE because the object file uses TM builtin but the
TM is not enabled.
In the patch, it displays a error message if the builtin is not defined
and due to TM.
I moved is_tm_builtin() from calls.c to trans-mem.c. I splitted it into
2 functions is_tm_builtin/is_tm_builtin_code. In is_tm_builtin_code, I
added some missing builtins (TM_START, TM_GETTMCLONE_SAFE, TM_MALLOC,
TM_CALLOC, TM_FREE). Finally, I declared them into tree.h to be usable
in calls.c and tree-streamer-in.c.
Bootstrapped and LTO/TM regtested on Linux/i686.
(If ok, please commit it. Thanks.)
Patrick Marlier.
2011-12-15 Patrick Marlier <patrick.marl...@gmail.com>
PR lto/51280
* tree.h (is_tm_builtin): Declare.
(is_tm_builtin_code): Declare.
* calls.c (is_tm_builtin): Move to...
* trans-mem.c (is_tm_builtin): ...here.
(is_tm_builtin_code): New, add missing builtins.
* lto-streamer-in.c (streamer_get_builtin_tree): Use it.
Index: tree.h
===================================================================
--- tree.h (revision 182376)
+++ tree.h (working copy)
@@ -5871,6 +5871,8 @@ extern bool is_tm_safe (const_tree);
extern bool is_tm_pure (const_tree);
extern bool is_tm_may_cancel_outer (tree);
extern bool is_tm_ending_fndecl (tree);
+extern bool is_tm_builtin_code (enum built_in_function);
+extern bool is_tm_builtin (const_tree);
extern void record_tm_replacement (tree, tree);
extern void tm_malloc_replacement (tree);
Index: trans-mem.c
===================================================================
--- trans-mem.c (revision 182376)
+++ trans-mem.c (working copy)
@@ -406,6 +406,83 @@ is_tm_abort (tree fndecl)
&& DECL_FUNCTION_CODE (fndecl) == BUILT_IN_TM_ABORT);
}
+/* Return TRUE if FCODE is a TM builtin function. */
+
+bool
+is_tm_builtin_code (enum built_in_function fcode)
+{
+ switch (fcode)
+ {
+ case BUILT_IN_TM_START:
+ case BUILT_IN_TM_COMMIT:
+ case BUILT_IN_TM_COMMIT_EH:
+ case BUILT_IN_TM_ABORT:
+ case BUILT_IN_TM_IRREVOCABLE:
+ case BUILT_IN_TM_MEMCPY:
+ case BUILT_IN_TM_MEMMOVE:
+ case BUILT_IN_TM_MEMSET:
+ case BUILT_IN_TM_GETTMCLONE_IRR:
+ case BUILT_IN_TM_GETTMCLONE_SAFE:
+ case BUILT_IN_TM_MALLOC:
+ case BUILT_IN_TM_CALLOC:
+ case BUILT_IN_TM_FREE:
+ CASE_BUILT_IN_TM_STORE (1):
+ CASE_BUILT_IN_TM_STORE (2):
+ CASE_BUILT_IN_TM_STORE (4):
+ CASE_BUILT_IN_TM_STORE (8):
+ CASE_BUILT_IN_TM_STORE (FLOAT):
+ CASE_BUILT_IN_TM_STORE (DOUBLE):
+ CASE_BUILT_IN_TM_STORE (LDOUBLE):
+ CASE_BUILT_IN_TM_STORE (M64):
+ CASE_BUILT_IN_TM_STORE (M128):
+ CASE_BUILT_IN_TM_STORE (M256):
+ CASE_BUILT_IN_TM_LOAD (1):
+ CASE_BUILT_IN_TM_LOAD (2):
+ CASE_BUILT_IN_TM_LOAD (4):
+ CASE_BUILT_IN_TM_LOAD (8):
+ CASE_BUILT_IN_TM_LOAD (FLOAT):
+ CASE_BUILT_IN_TM_LOAD (DOUBLE):
+ CASE_BUILT_IN_TM_LOAD (LDOUBLE):
+ CASE_BUILT_IN_TM_LOAD (M64):
+ CASE_BUILT_IN_TM_LOAD (M128):
+ CASE_BUILT_IN_TM_LOAD (M256):
+ case BUILT_IN_TM_LOG:
+ case BUILT_IN_TM_LOG_1:
+ case BUILT_IN_TM_LOG_2:
+ case BUILT_IN_TM_LOG_4:
+ case BUILT_IN_TM_LOG_8:
+ case BUILT_IN_TM_LOG_FLOAT:
+ case BUILT_IN_TM_LOG_DOUBLE:
+ case BUILT_IN_TM_LOG_LDOUBLE:
+ case BUILT_IN_TM_LOG_M64:
+ case BUILT_IN_TM_LOG_M128:
+ case BUILT_IN_TM_LOG_M256:
+ return true;
+ default:
+ break;
+ }
+ return false;
+
+}
+
+/* Return TRUE if FNDECL is either a TM builtin or a TM cloned
+ function. Return FALSE otherwise. */
+
+bool
+is_tm_builtin (const_tree fndecl)
+{
+ if (fndecl == NULL)
+ return false;
+
+ if (decl_is_tm_clone (fndecl))
+ return true;
+
+ if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+ && is_tm_builtin_code (DECL_FUNCTION_CODE (fndecl)))
+ return true;
+ return false;
+}
+
/* Build a GENERIC tree for a user abort. This is called by front ends
while transforming the __tm_abort statement. */
Index: calls.c
===================================================================
--- calls.c (revision 182376)
+++ calls.c (working copy)
@@ -611,69 +611,6 @@ alloca_call_p (const_tree exp)
return false;
}
-/* Return TRUE if FNDECL is either a TM builtin or a TM cloned
- function. Return FALSE otherwise. */
-
-static bool
-is_tm_builtin (const_tree fndecl)
-{
- if (fndecl == NULL)
- return false;
-
- if (decl_is_tm_clone (fndecl))
- return true;
-
- if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
- {
- switch (DECL_FUNCTION_CODE (fndecl))
- {
- case BUILT_IN_TM_COMMIT:
- case BUILT_IN_TM_COMMIT_EH:
- case BUILT_IN_TM_ABORT:
- case BUILT_IN_TM_IRREVOCABLE:
- case BUILT_IN_TM_GETTMCLONE_IRR:
- case BUILT_IN_TM_MEMCPY:
- case BUILT_IN_TM_MEMMOVE:
- case BUILT_IN_TM_MEMSET:
- CASE_BUILT_IN_TM_STORE (1):
- CASE_BUILT_IN_TM_STORE (2):
- CASE_BUILT_IN_TM_STORE (4):
- CASE_BUILT_IN_TM_STORE (8):
- CASE_BUILT_IN_TM_STORE (FLOAT):
- CASE_BUILT_IN_TM_STORE (DOUBLE):
- CASE_BUILT_IN_TM_STORE (LDOUBLE):
- CASE_BUILT_IN_TM_STORE (M64):
- CASE_BUILT_IN_TM_STORE (M128):
- CASE_BUILT_IN_TM_STORE (M256):
- CASE_BUILT_IN_TM_LOAD (1):
- CASE_BUILT_IN_TM_LOAD (2):
- CASE_BUILT_IN_TM_LOAD (4):
- CASE_BUILT_IN_TM_LOAD (8):
- CASE_BUILT_IN_TM_LOAD (FLOAT):
- CASE_BUILT_IN_TM_LOAD (DOUBLE):
- CASE_BUILT_IN_TM_LOAD (LDOUBLE):
- CASE_BUILT_IN_TM_LOAD (M64):
- CASE_BUILT_IN_TM_LOAD (M128):
- CASE_BUILT_IN_TM_LOAD (M256):
- case BUILT_IN_TM_LOG:
- case BUILT_IN_TM_LOG_1:
- case BUILT_IN_TM_LOG_2:
- case BUILT_IN_TM_LOG_4:
- case BUILT_IN_TM_LOG_8:
- case BUILT_IN_TM_LOG_FLOAT:
- case BUILT_IN_TM_LOG_DOUBLE:
- case BUILT_IN_TM_LOG_LDOUBLE:
- case BUILT_IN_TM_LOG_M64:
- case BUILT_IN_TM_LOG_M128:
- case BUILT_IN_TM_LOG_M256:
- return true;
- default:
- break;
- }
- }
- return false;
-}
-
/* Detect flags (function attributes) from the function decl or type node. */
int
Index: tree-streamer-in.c
===================================================================
--- tree-streamer-in.c (revision 182376)
+++ tree-streamer-in.c (working copy)
@@ -1055,6 +1055,8 @@ streamer_get_builtin_tree (struct lto_input_block
if (fcode >= END_BUILTINS)
fatal_error ("machine independent builtin code out of range");
result = builtin_decl_explicit (fcode);
+ if (!result && !flag_tm && is_tm_builtin_code (fcode))
+ fatal_error ("transactional memory builtin without support enabled");
gcc_assert (result);
}
else if (fclass == BUILT_IN_MD)