mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-08 12:18:42 +00:00
Filter: Implement constant promotion for multiple dispatch methods
This commit is contained in:
parent
e886959131
commit
f0d1396073
@ -379,7 +379,8 @@ m4_undivert(102)m4_dnl
|
|||||||
[[m4_dnl The one case in The Big Switch inside interpreter
|
[[m4_dnl The one case in The Big Switch inside interpreter
|
||||||
case INST_NAME():
|
case INST_NAME():
|
||||||
#define whati (&(what->i_]]INST_NAME()[[))
|
#define whati (&(what->i_]]INST_NAME()[[))
|
||||||
m4_ifelse(m4_eval(INST_INVAL() > 0), 1, [[if (fstk->vcnt < INST_INVAL()) runtime("Stack underflow"); fstk->vcnt -= INST_INVAL(); ]])
|
m4_ifelse(m4_eval(INST_INVAL() > 0), 1, [[if (fstk->vcnt < INST_INVAL()) runtime("Stack underflow");
|
||||||
|
fstk->vcnt -= INST_INVAL();]])
|
||||||
m4_undivert(108)m4_dnl
|
m4_undivert(108)m4_dnl
|
||||||
#undef whati
|
#undef whati
|
||||||
break;
|
break;
|
||||||
@ -572,8 +573,8 @@ fi_constant(struct f_inst *what, struct f_val val)
|
|||||||
return what;
|
return what;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
f_const_promotion(struct f_inst *arg, enum f_type want)
|
f_const_promotion_(struct f_inst *arg, enum f_type want, int update)
|
||||||
{
|
{
|
||||||
if (arg->fi_code != FI_CONSTANT)
|
if (arg->fi_code != FI_CONSTANT)
|
||||||
return 0;
|
return 0;
|
||||||
@ -581,15 +582,17 @@ f_const_promotion(struct f_inst *arg, enum f_type want)
|
|||||||
struct f_val *c = &arg->i_FI_CONSTANT.val;
|
struct f_val *c = &arg->i_FI_CONSTANT.val;
|
||||||
|
|
||||||
if ((c->type == T_IP) && ipa_is_ip4(c->val.ip) && (want == T_QUAD)) {
|
if ((c->type == T_IP) && ipa_is_ip4(c->val.ip) && (want == T_QUAD)) {
|
||||||
*c = (struct f_val) {
|
if (update)
|
||||||
.type = T_QUAD,
|
*c = (struct f_val) {
|
||||||
.val.i = ipa_to_u32(c->val.ip),
|
.type = T_QUAD,
|
||||||
};
|
.val.i = ipa_to_u32(c->val.ip),
|
||||||
|
};
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((c->type == T_SET) && (!c->val.t) && (want == T_PREFIX_SET)) {
|
else if ((c->type == T_SET) && (!c->val.t) && (want == T_PREFIX_SET)) {
|
||||||
*c = f_const_empty_prefix_set;
|
if (update)
|
||||||
|
*c = f_const_empty_prefix_set;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,16 @@ const char *f_instruction_name_(enum f_instruction_code fi);
|
|||||||
static inline const char *f_instruction_name(enum f_instruction_code fi)
|
static inline const char *f_instruction_name(enum f_instruction_code fi)
|
||||||
{ return f_instruction_name_(fi) + 3; }
|
{ return f_instruction_name_(fi) + 3; }
|
||||||
|
|
||||||
|
|
||||||
|
int f_const_promotion_(struct f_inst *arg, enum f_type want, int update);
|
||||||
|
|
||||||
|
static inline int f_const_promotion(struct f_inst *arg, enum f_type want)
|
||||||
|
{ return f_const_promotion_(arg, want, 1); }
|
||||||
|
|
||||||
|
static inline int f_try_const_promotion(struct f_inst *arg, enum f_type want)
|
||||||
|
{ return f_const_promotion_(arg, want, 0); }
|
||||||
|
|
||||||
|
|
||||||
struct f_arg {
|
struct f_arg {
|
||||||
struct symbol *arg;
|
struct symbol *arg;
|
||||||
struct f_arg *next;
|
struct f_arg *next;
|
||||||
|
@ -48,7 +48,8 @@ f_match_signature(const struct f_method *dsc, struct f_inst *args)
|
|||||||
int i, arg_num = (int) dsc->arg_num;
|
int i, arg_num = (int) dsc->arg_num;
|
||||||
|
|
||||||
for (i = 1; args && (i < arg_num); args = args->next, i++)
|
for (i = 1; args && (i < arg_num); args = args->next, i++)
|
||||||
if (dsc->args_type[i] && (args->type != dsc->args_type[i]))
|
if (dsc->args_type[i] && (args->type != dsc->args_type[i]) &&
|
||||||
|
!f_try_const_promotion(args, dsc->args_type[i]))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return !args && !(i < arg_num);
|
return !args && !(i < arg_num);
|
||||||
@ -61,7 +62,8 @@ f_match_signature_err(const struct f_method *dsc, struct f_inst *args, int *pos,
|
|||||||
int i, arg_num = (int) dsc->arg_num;
|
int i, arg_num = (int) dsc->arg_num;
|
||||||
|
|
||||||
for (i = 1; args && (i < arg_num); args = args->next, i++)
|
for (i = 1; args && (i < arg_num); args = args->next, i++)
|
||||||
if (dsc->args_type[i] && (args->type != dsc->args_type[i]))
|
if (dsc->args_type[i] && (args->type != dsc->args_type[i]) &&
|
||||||
|
!f_try_const_promotion(args, dsc->args_type[i]))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
*pos = i;
|
*pos = i;
|
||||||
|
Loading…
Reference in New Issue
Block a user