diff mbox

[avr] : PR target/52692: Imlpement TARGET_BUILTIN_DECL

Message ID 4F7079B2.6030009@gjlay.de
State New
Headers show

Commit Message

Georg-Johann Lay March 26, 2012, 2:14 p.m. UTC
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.

Comments

Denis Chertykov March 26, 2012, 6:55 p.m. UTC | #1
2012/3/26 Georg-Johann Lay <avr@gjlay.de>:
> 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.

Please, apply.

Denis.
diff mbox

Patch

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();
-        }
+    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);
     }
   
   gcc_unreachable ();
@@ -10878,6 +10892,9 @@  avr_fold_builtin (tree fndecl, int n_arg
 #undef  TARGET_INIT_BUILTINS
 #define TARGET_INIT_BUILTINS avr_init_builtins
 
+#undef  TARGET_BUILTIN_DECL
+#define TARGET_BUILTIN_DECL avr_builtin_decl
+
 #undef  TARGET_EXPAND_BUILTIN
 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
 
Index: testsuite/gcc.target/avr/torture/builtins-2.c
===================================================================
--- testsuite/gcc.target/avr/torture/builtins-2.c	(revision 0)
+++ testsuite/gcc.target/avr/torture/builtins-2.c	(revision 0)
@@ -0,0 +1,46 @@ 
+/* { dg-options "-std=gnu99 -Tavr51-flash1.x" } */
+/* { dg-do run } */
+
+#include <stdlib.h>
+#include "../progmem.h"
+
+int volatile a;
+
+void f1 (void) 
+{
+  __builtin_avr_sei (); 
+  __builtin_avr_cli (); 
+  __builtin_avr_wdr (); 
+  __builtin_avr_sleep (); 
+  __builtin_avr_nop ();
+  a = __builtin_avr_swap (a);
+  a = __builtin_avr_fmul (1,a);
+  a = __builtin_avr_fmuls (1,a);
+  a = __builtin_avr_fmulsu (1,a);
+  a = __builtin_avr_insert_bits (0x1f2f5364, a, a);
+}
+
+const __flash char c0 = 1;
+const __flash1 char c1 = 1;
+
+int main (void) 
+{
+  const __memx void *p;
+
+  f1();
+  __builtin_avr_delay_cycles (1000);
+
+  p = &c0;
+  if (__builtin_avr_flash_segment (p) != 0)
+    abort();
+
+  p = &c1;
+  if (__builtin_avr_flash_segment (p) != 1)
+    abort();
+
+  if (__builtin_avr_flash_segment ("p") != -1)
+    abort();
+
+  exit (0);
+  return 0; 
+}