16#define MAX_SLOTS (MAX_RULES * 4)
18#define USE_SEMI_PERFECT_HASH 1
28 printf(
"static const uint32_t _ir_fold_hash[%d] = {\n",
count + 1);
29 for (i = 0; i <
count; i++) {
30 printf(
"\t0x%08x,\n", mask[i]);
37static uint32_t hash_shl2(uint32_t mask, uint32_t r1, uint32_t r2)
39 return ((mask << r1) - mask) << r2;
44#define ir_rol(x, n) (((x)<<(n)) | ((x)>>(-(int)(n)&(8*sizeof(x)-1))))
45#define ir_ror(x, n) (((x)<<(-(int)(n)&(8*sizeof(x)-1))) | ((x)>>(n)))
47static uint32_t hash_rol2(uint32_t mask, uint32_t r1, uint32_t r2)
49 return ir_rol((ir_rol(mask, r1) - mask), r2);
57 uint32_t
n, r1, r2, i, h;
60#if USE_SEMI_PERFECT_HASH
64 for (r1 = 0; r1 < 31; r1++) {
65 for (r2 = 0; r2 < 32; r2++) {
68 for (i = 0; i <
count; i++) {
69 h = hash_shl2(mask[i] & 0x1fffff, r1, r2) %
n;
71#if USE_SEMI_PERFECT_HASH
85#if USE_SEMI_PERFECT_HASH
87 printf(
"#define IR_FOLD_SEMI_PERFECT_HASH\n\n");
90 printf(
"static uint32_t _ir_fold_hashkey(uint32_t h)\n{\n\treturn (((h << %d) - h) << %d) %% %d;\n}\n", r1, r2,
n);
96 for (i = 0; i <
count; i++) {
97 h = hash_rol2(mask[i] & 0x1fffff, r1, r2) %
n;
99#if USE_SEMI_PERFECT_HASH
113#if USE_SEMI_PERFECT_HASH
115 printf(
"#define IR_FOLD_SEMI_PERFECT_HASH\n\n");
118 printf(
"static uint32_t _ir_fold_hashkey(uint32_t h)\n{\nreturn ir_rol32((ir_rol32(h, %d) - h), %d) %% %d;\n}\n", r1, r2,
n);
128 printf(
"static uint32_t _ir_fold_hashkey(uint32_t h)\n{\n\treturn 0;\n}\n");
132static int find_op(
const char *
s,
size_t len)
137static int parse_rule(
const char *
buf)
139 const char *
p =
buf +
sizeof(
"IR_FOLD(") - 1;
143 while (*
p ==
' ' || *
p ==
'\t') {
146 if (*
p <
'A' || *
p >
'Z') {
150 while ((*q >=
'A' && *q <=
'Z')
151 || (*q >=
'0' && *q <=
'9')
155 op = find_op(
p, q -
p);
161 while (*q ==
' ' || *q ==
'\t') {
166 }
else if (*q !=
'(') {
171 while (*
p ==
' ' || *
p ==
'\t') {
176 }
else if (*
p >=
'A' && *
p <=
'Z') {
178 while ((*q >=
'A' && *q <=
'Z')
179 || (*q >=
'0' && *q <=
'9')
183 op = find_op(
p, q -
p);
192 while (*q ==
' ' || *q ==
'\t') {
197 }
else if (*q !=
',') {
202 while (*
p ==
' ' || *
p ==
'\t') {
207 }
else if (*
p >=
'A' && *
p <=
'Z') {
209 while ((*q >=
'A' && *q <=
'Z')
210 || (*q >=
'0' && *q <=
'9')
214 op = find_op(
p, q -
p);
223 while (*q ==
' ' || *q ==
'\t') {
231 while (*q ==
' ' || *q ==
'\t') {
253#define IR_OP_ADD(name, flags, op1, op2, op3) \
254 ir_strtab_lookup(&strtab, #name, sizeof(#name) - 1, IR_ ## name + 1);
268 if (
len >=
sizeof(
"IR_FOLD(")-1
269 && memcmp(
buf,
"IR_FOLD(",
sizeof(
"IR_FOLD(")-1) == 0) {
271 fprintf(stderr,
"ERROR: Too many rules\n");
276 fprintf(stderr,
"ERROR: Incorrect '%s' rule on line %d\n",
buf,
line);
281 mask[rules] = i | (rules << 21);
288 for (i = 0; i < rules; i++) {
289 printf(
"0x%08x\n", mask[i]);
293 printf(
"/* This file is generated from \"ir_fold.h\". Do not edit! */\n\n");
294 printf(
"typedef enum _ir_fold_rule_id {\n");
295 for (i = 0; i < rules; i++) {
296 printf(
"\tIR_RULE_%d,\n", rule[i]);
298 printf(
"\t_IR_RULE_LAST\n");
299 printf(
"} ir_fold_rule_id;\n\n");
302 fprintf(stderr,
"ERROR: Cannot find a good hash function\n");
fprintf($stream, string $format, mixed ... $values)
printf(string $format, mixed ... $values)
count(Countable|array $value, int $mode=COUNT_NORMAL)
fgets($stream, ?int $length=null)
memset(ptr, 0, type->size)
zend_ffi_ctype_name_buf buf
int find_hash(uint32_t *mask, uint32_t count)
#define IR_OP_ADD(name, flags, op1, op2, op3)
void print_hash(uint32_t *mask, uint32_t count)
hash(string $algo, string $data, bool $binary=false, array $options=[])
ir_ref ir_strtab_find(const ir_strtab *strtab, const char *str, uint32_t len)
ir_ref ir_strtab_lookup(ir_strtab *strtab, const char *str, uint32_t len, ir_ref val)
struct _ir_strtab ir_strtab
void ir_strtab_free(ir_strtab *strtab)
void ir_strtab_init(ir_strtab *strtab, uint32_t count, uint32_t buf_size)