libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / testsuite / gcc.dg / vect / pr113576.c
blobba171b7c1f2ca2700e6756c680ed5cdfad62a333
1 /* { dg-additional-options "-O3" } */
2 /* { dg-additional-options "-march=skylake-avx512" { target avx512f } } */
4 #include "tree-vect.h"
6 #include<stdbool.h>
7 #include<stdlib.h>
8 #include<stddef.h>
9 #include<string.h>
11 #define SBITMAP_ELT_BITS ((unsigned) 64)
12 #define SBITMAP_ELT_TYPE unsigned long long
13 #define SBITMAP_SIZE_BYTES(BITMAP) ((BITMAP)->size * sizeof (SBITMAP_ELT_TYPE))
14 #define do_popcount(x) __builtin_popcountll(x)
16 typedef struct simple_bitmap_def
18 unsigned char *popcount; /* Population count. */
19 unsigned int n_bits; /* Number of bits. */
20 unsigned int size; /* Size in elements. */
21 SBITMAP_ELT_TYPE elms[1]; /* The elements. */
22 } *sbitmap;
23 typedef const struct simple_bitmap_def *const_sbitmap;
25 /* The iterator for sbitmap. */
26 typedef struct {
27 /* The pointer to the first word of the bitmap. */
28 const SBITMAP_ELT_TYPE *ptr;
30 /* The size of the bitmap. */
31 unsigned int size;
33 /* The current word index. */
34 unsigned int word_num;
36 /* The current bit index (not modulo SBITMAP_ELT_BITS). */
37 unsigned int bit_num;
39 /* The words currently visited. */
40 SBITMAP_ELT_TYPE word;
41 } sbitmap_iterator;
43 static inline void
44 sbitmap_iter_init (sbitmap_iterator *i, const_sbitmap bmp, unsigned int min)
46 i->word_num = min / (unsigned int) SBITMAP_ELT_BITS;
47 i->bit_num = min;
48 i->size = bmp->size;
49 i->ptr = bmp->elms;
51 if (i->word_num >= i->size)
52 i->word = 0;
53 else
54 i->word = (i->ptr[i->word_num]
55 >> (i->bit_num % (unsigned int) SBITMAP_ELT_BITS));
58 /* Return true if we have more bits to visit, in which case *N is set
59 to the index of the bit to be visited. Otherwise, return
60 false. */
62 static inline bool
63 sbitmap_iter_cond (sbitmap_iterator *i, unsigned int *n)
65 /* Skip words that are zeros. */
66 for (; i->word == 0; i->word = i->ptr[i->word_num])
68 i->word_num++;
70 /* If we have reached the end, break. */
71 if (i->word_num >= i->size)
72 return false;
74 i->bit_num = i->word_num * SBITMAP_ELT_BITS;
77 /* Skip bits that are zero. */
78 for (; (i->word & 1) == 0; i->word >>= 1)
79 i->bit_num++;
81 *n = i->bit_num;
83 return true;
86 /* Advance to the next bit. */
88 static inline void
89 sbitmap_iter_next (sbitmap_iterator *i)
91 i->word >>= 1;
92 i->bit_num++;
95 #define SBITMAP_SET_SIZE(N) (((N) + SBITMAP_ELT_BITS - 1) / SBITMAP_ELT_BITS)
96 /* Allocate a simple bitmap of N_ELMS bits. */
98 sbitmap
99 sbitmap_alloc (unsigned int n_elms)
101 unsigned int bytes, size, amt;
102 sbitmap bmap;
104 size = SBITMAP_SET_SIZE (n_elms);
105 bytes = size * sizeof (SBITMAP_ELT_TYPE);
106 amt = (sizeof (struct simple_bitmap_def)
107 + bytes - sizeof (SBITMAP_ELT_TYPE));
108 bmap = (sbitmap) malloc (amt);
109 bmap->n_bits = n_elms;
110 bmap->size = size;
111 bmap->popcount = NULL;
112 return bmap;
115 #define sbitmap_free(MAP) (free((MAP)->popcount), free((MAP)))
116 /* Loop over all elements of SBITMAP, starting with MIN. In each
117 iteration, N is set to the index of the bit being visited. ITER is
118 an instance of sbitmap_iterator used to iterate the bitmap. */
120 #define EXECUTE_IF_SET_IN_SBITMAP(SBITMAP, MIN, N, ITER) \
121 for (sbitmap_iter_init (&(ITER), (SBITMAP), (MIN)); \
122 sbitmap_iter_cond (&(ITER), &(N)); \
123 sbitmap_iter_next (&(ITER)))
126 __attribute__((noinline))
127 sbitmap_first_set_bit (const_sbitmap bmap)
129 unsigned int n = 0;
130 sbitmap_iterator sbi;
132 EXECUTE_IF_SET_IN_SBITMAP (bmap, 0, n, sbi)
133 return n;
134 return -1;
137 void
138 sbitmap_zero (sbitmap bmap)
140 memset (bmap->elms, 0, SBITMAP_SIZE_BYTES (bmap));
141 if (bmap->popcount)
142 memset (bmap->popcount, 0, bmap->size * sizeof (unsigned char));
145 int main ()
147 check_vect ();
149 sbitmap tmp = sbitmap_alloc(1856);
150 sbitmap_zero (tmp);
151 int res = sbitmap_first_set_bit (tmp);
152 if (res != -1)
153 abort ();
154 sbitmap_free (tmp);
155 return 0;