blob: 65dd86f5c1540c5f142f7627fceaa5259f94c264 [file] [log] [blame]
/* { dg-do compile } */
/* { dg-options "-O2 -fno-strict-aliasing -fdump-ipa-sra-details -fdump-tree-optimized" } */
typedef _Bool bool;
enum {
false = 0,
true = 1
};
struct xarray {
unsigned int xa_lock;
unsigned int xa_flags;
void * xa_head;
};
struct list_head {
struct list_head *next, *prev;
};
struct callback_head {
struct callback_head *next;
void (*func)(struct callback_head *head);
} __attribute__((aligned(sizeof(void *))));
struct xa_node {
unsigned char shift;
unsigned char offset;
unsigned char count;
unsigned char nr_values;
struct xa_node *parent;
struct xarray *array;
union {
struct list_head private_list;
struct callback_head callback_head;
};
void *slots[(1UL << (0 ? 4 : 6))];
union {
unsigned long tags[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))];
unsigned long marks[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))];
};
};
static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long shift_maxindex(unsigned int shift)
{
return ((1UL << (0 ? 4 : 6)) << shift) - 1;
}
static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long node_maxindex(const struct xa_node *node)
{
return shift_maxindex(node->shift);
}
static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) struct xa_node *entry_to_node(void *ptr)
{
return (void *)((unsigned long)ptr & ~2UL);
}
static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) bool radix_tree_is_internal_node(void *ptr)
{
return ((unsigned long)ptr & 3UL) ==
2UL;
}
static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) void *xa_mk_internal(unsigned long v)
{
return (void *)((v << 2) | 2);
}
static unsigned radix_tree_load_root(const struct xarray *root,
struct xa_node **nodep, unsigned long *maxindex)
{
struct xa_node *node =
({
typeof(root->xa_head) ________p1 = ({(*(const volatile typeof(root->xa_head) *)&(root->xa_head)); });
((typeof(*root->xa_head) *)(________p1));
});
*nodep = node;
if (__builtin_expect(!!(radix_tree_is_internal_node(node)), 1)) {
node = entry_to_node(node);
*maxindex = node_maxindex(node);
return node->shift + (0 ? 4 : 6);
}
*maxindex = 0;
return 0;
}
void *__radix_tree_lookup(const struct xarray *root,
unsigned long index, struct xa_node **nodep,
void ***slotp)
{
struct xa_node *node, *parent;
unsigned long maxindex;
restart:
parent = ((void *)0);
radix_tree_load_root(root, &node, &maxindex);
while (radix_tree_is_internal_node(node)) {
parent = entry_to_node(node);
if (node == xa_mk_internal(256))
goto restart;
if (parent->shift == 0)
break;
}
if (nodep)
*nodep = parent;
return node;
}
/* { dg-final { scan-ipa-dump-not "IPA_PARAM_OP_SPLIT" "sra" } } */
/* { dg-final { scan-tree-dump " ={v} " "optimized" } } */