This implements TARGET_BUILTIN_DECL which is needed to make
LTO work with target-specific built-ins.
struct avr_builtin_description gets a new field .fndecl which is
initialized during avr_init_builtins and looked up in new hook
avr_builtin_decl.
The built-ins are initialized in such a way that there is always
avr_bdesc[x].id == x
i.e. .id is superfluous and avr_expand_builtin can use id to access
the array and need no search loop to find built-in id.
Johann
Ok?
gcc/
PR target/52692
* config/avr/avr.c (TARGET_BUILTIN_DECL): New define.
(avr_builtin_decl): New static function.
(struct avr_builtin_description, avr_bdesc): Move up.
Add GTY marker. Add field fndecl. Remove redundant field id.
(avr_init_builtins): Initialize avr_bdesc[ID].fndecl.
(avr_expand_builtin): Code cleanup because .id is removed.
testsuite/
* gcc.target/avr/torture/builtins-2.c: New test.
Index: config/avr/avr.c
===
--- config/avr/avr.c (revision 185792)
+++ config/avr/avr.c (working copy)
@@ -10285,6 +10285,42 @@ enum avr_builtin_id
AVR_BUILTIN_COUNT
};
+struct GTY(()) avr_builtin_description
+{
+ enum insn_code icode;
+ const char *name;
+ int n_args;
+ tree fndecl;
+};
+
+
+/* Notice that avr_bdesc[] and avr_builtin_id are initialized in such a way
+ that a built-in's ID can be used to access the built-in by means of
+ avr_bdesc[ID] */
+
+static GTY(()) struct avr_builtin_description
+avr_bdesc[AVR_BUILTIN_COUNT] =
+ {
+
+#define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, ICODE) \
+{ ICODE, NAME, N_ARGS, NULL_TREE },
+#include builtins.def
+#undef DEF_BUILTIN
+ };
+
+
+/* Implement `TARGET_BUILTIN_DECL'. */
+
+static tree
+avr_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
+{
+ if (id AVR_BUILTIN_COUNT)
+return avr_bdesc[id].fndecl;
+
+ return error_mark_node;
+}
+
+
static void
avr_init_builtin_int24 (void)
{
@@ -10295,6 +10331,7 @@ avr_init_builtin_int24 (void)
(*lang_hooks.types.register_builtin_type) (uint24_type, __uint24);
}
+
/* Implement `TARGET_INIT_BUILTINS' */
/* Set up all builtin functions for this target. */
@@ -10348,7 +10385,9 @@ avr_init_builtins (void)
NULL);
#define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, CODE) \
- add_builtin_function (NAME, TYPE, ID, BUILT_IN_MD, NULL, NULL_TREE);
+ gcc_assert (ID AVR_BUILTIN_COUNT); \
+ avr_bdesc[ID].fndecl \
+= add_builtin_function (NAME, TYPE, ID, BUILT_IN_MD, NULL, NULL_TREE);
#include builtins.def
#undef DEF_BUILTIN
@@ -10356,27 +10395,6 @@ avr_init_builtins (void)
}
-struct avr_builtin_description
-{
- enum insn_code icode;
- const char *name;
- enum avr_builtin_id id;
- int n_args;
-};
-
-static const struct avr_builtin_description
-avr_bdesc[] =
- {
-
-#define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, ICODE) \
-{ ICODE, NAME, ID, N_ARGS },
-#include builtins.def
-#undef DEF_BUILTIN
-
-{ CODE_FOR_nothing, NULL, 0, -1 }
- };
-
-
/* Subroutine of avr_expand_builtin to take care of unop insns. */
static rtx
@@ -10545,6 +10563,7 @@ avr_expand_triop_builtin (enum insn_code
}
+/* Implement `TARGET_EXPAND_BUILTIN'. */
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
(and in mode MODE if that's convenient).
@@ -10557,13 +10576,15 @@ avr_expand_builtin (tree exp, rtx target
enum machine_mode mode ATTRIBUTE_UNUSED,
int ignore ATTRIBUTE_UNUSED)
{
- size_t i;
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
const char* bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
unsigned int id = DECL_FUNCTION_CODE (fndecl);
+ const struct avr_builtin_description *d = avr_bdesc[id];
tree arg0;
rtx op0;
+ gcc_assert (id AVR_BUILTIN_COUNT);
+
switch (id)
{
case AVR_BUILTIN_NOP:
@@ -10597,29 +10618,22 @@ avr_expand_builtin (tree exp, rtx target
}
}
- for (i = 0; avr_bdesc[i].name; i++)
+ /* No special treatment needed: vanilla expand. */
+
+ switch (d-n_args)
{
- const struct avr_builtin_description *d = avr_bdesc[i];
+case 0:
+ emit_insn ((GEN_FCN (d-icode)) (target));
+ return 0;
- if (d-id == id)
-switch (d-n_args)
- {
- case 0:
-emit_insn ((GEN_FCN (d-icode)) (target));
-return 0;
-
- case 1:
-return avr_expand_unop_builtin (d-icode, exp, target);
-
- case 2:
-return avr_expand_binop_builtin (d-icode, exp, target);
-
- case 3:
-return avr_expand_triop_builtin (d-icode, exp, target);
-
- default:
-gcc_unreachable();
-}
+