1 /* { dg-do compile } */
2 /* { dg-options "-O2 -fno-strict-aliasing -fdump-ipa-sra-details -fdump-tree-optimized" } */
3
4 typedef _Bool bool;
5
6 enum {
7 false = 0,
8 true = 1
9 };
10
11 struct xarray {
12 unsigned int xa_lock;
13 unsigned int xa_flags;
14 void * xa_head;
15
16 };
17
18 struct list_head {
19 struct list_head *next, *prev;
20 };
21
22 struct callback_head {
23 struct callback_head *next;
24 void (*func)(struct callback_head *head);
25 } __attribute__((aligned(sizeof(void *))));
26
27 struct xa_node {
28 unsigned char shift;
29 unsigned char offset;
30 unsigned char count;
31 unsigned char nr_values;
32 struct xa_node *parent;
33 struct xarray *array;
34 union {
35 struct list_head private_list;
36 struct callback_head callback_head;
37 };
38 void *slots[(1UL << (0 ? 4 : 6))];
39 union {
40 unsigned long tags[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))];
41 unsigned long marks[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))];
42 };
43 };
44
45 static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long shift_maxindex(unsigned int shift)
46 {
47 return ((1UL << (0 ? 4 : 6)) << shift) - 1;
48 }
49
50 static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long node_maxindex(const struct xa_node *node)
51 {
52 return shift_maxindex(node->shift);
53 }
54
55 static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) struct xa_node *entry_to_node(void *ptr)
56 {
57 return (void *)((unsigned long)ptr & ~2UL);
58 }
59
60 static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) bool radix_tree_is_internal_node(void *ptr)
61 {
62 return ((unsigned long)ptr & 3UL) ==
63 2UL;
64 }
65
66 static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) void *xa_mk_internal(unsigned long v)
67 {
68 return (void *)((v << 2) | 2);
69 }
70
71 static unsigned radix_tree_load_root(const struct xarray *root,
72 struct xa_node **nodep, unsigned long *maxindex)
73 {
74 struct xa_node *node =
75 ({
76 typeof(root->xa_head) ________p1 = ({(*(const volatile typeof(root->xa_head) *)&(root->xa_head)); });
77 ((typeof(*root->xa_head) *)(________p1));
78 });
79
80 *nodep = node;
81
82 if (__builtin_expect(!!(radix_tree_is_internal_node(node)), 1)) {
83 node = entry_to_node(node);
84 *maxindex = node_maxindex(node);
85 return node->shift + (0 ? 4 : 6);
86 }
87
88 *maxindex = 0;
89 return 0;
90 }
91
92 void *__radix_tree_lookup(const struct xarray *root,
93 unsigned long index, struct xa_node **nodep,
94 void ***slotp)
95 {
96 struct xa_node *node, *parent;
97 unsigned long maxindex;
98
99 restart:
100 parent = ((void *)0);
101 radix_tree_load_root(root, &node, &maxindex);
102 while (radix_tree_is_internal_node(node)) {
103
104 parent = entry_to_node(node);
105 if (node == xa_mk_internal(256))
106 goto restart;
107 if (parent->shift == 0)
108 break;
109 }
110 if (nodep)
111 *nodep = parent;
112
113 return node;
114 }
115
116 /* { dg-final { scan-ipa-dump-not "IPA_PARAM_OP_SPLIT" "sra" } } */
117 /* { dg-final { scan-tree-dump " ={v} " "optimized" } } */