pike.git/
src/
las.c
Branch:
Tag:
Non-build tags
All tags
No tags
2018-11-28
2018-11-28 12:14:51 by Henrik Grubbström (Grubba) <grubba@grubba.org>
bdb12f0d4a6588ea591601b7eea7b71c79828820 (
83
lines) (+
65
/-
18
)
[
Show
|
Annotate
]
Branch:
master
Compiler: Improved propagation of optimizer flags for apply nodes.
729:
} }
+
static int apply_opt_flags_for_ref(struct program *prog, int fun);
-
+
static int apply_opt_flags_for_sval(struct svalue *s)
+
{
+
switch(TYPEOF(*s))
+
{
+
case T_FUNCTION:
+
if (SUBTYPEOF(*s) == FUNCTION_BUILTIN)
+
{
+
return s->u.efun->flags;
+
}
+
if (s->u.object->prog) {
+
return apply_opt_flags_for_ref(s->u.object->prog, SUBTYPEOF(*s));
+
}
+
yyerror("Calling function in destructed module.");
+
break;
+
+
case T_PROGRAM:
+
if (s->u.program->flags & PROGRAM_CONSTANT) {
+
return 0;
+
}
+
break;
+
+
case T_OBJECT:
+
if (!s->u.object->prog) {
+
break;
+
}
+
return apply_opt_flags_for_ref(s->u.object->prog,
+
FIND_LFUN(s->u.object->prog, LFUN_CALL));
+
}
+
return OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND;
+
}
+
+
static int apply_opt_flags_for_ref(struct program *prog, int fun)
+
{
+
if (!prog) {
+
yyerror("Calling function in destructed object.");
+
} else if (fun < 0) {
+
yyerror("Attempt to call a missing function.");
+
} else {
+
struct identifier *id = ID_FROM_INT(prog, fun);
+
struct program *p = PROG_FROM_INT(prog, fun);
+
if (IDENTIFIER_IS_FUNCTION(id->identifier_flags)) {
+
return id->opt_flags;
+
}
+
if (IDENTIFIER_IS_CONSTANT(id->identifier_flags)) {
+
DECLARE_CYCLIC();
+
struct svalue *s = &p->constants[id->func.const_info.offset].sval;
+
int ret;
+
if ((ret = (size_t)BEGIN_CYCLIC(p, s))) {
+
return ret;
+
}
+
SET_CYCLIC_RET(OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND);
+
ret = apply_opt_flags_for_sval(s);
+
END_CYCLIC();
+
return ret;
+
}
+
}
+
return OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND;
+
}
+
node *debug_mknode(int token, node *a, node *b) { node *res;
838:
case F_APPLY: { unsigned INT16 opt_flags = OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND;
-
struct identifier *i = NULL;
+
if (a) { switch(a->token) {
846:
switch(TYPEOF(a->u.sval)) { case T_FUNCTION:
-
if
(SUBTYPEOF(a->u.sval)
=
=
FUNCTION
_
BUILTIN)
-
{
-
opt_flags
= a->u.sval.u.efun->flags;
-
} else if (a->u.sval.u.object->prog) {
-
i = ID
_
FROM
_
INT(a->u.
sval
.u.object->prog, SUBTYPEOF
(a->u.sval)
)
;
-
} else {
-
yyerror("Calling function in destructed module.");
-
}
+
opt_flags
=
apply
_opt_flags_
for
_sval(
&
a->u.sval);
break; case T_PROGRAM:
875:
state = state->previous; } if (state) {
-
i
=
ID
_
FROM
_
INT
(state->new_program, a->u.integer.b);
+
opt_flags
=
apply
_
opt
_
flags_for_ref
(state->new_program,
+
a->u.integer.b);
} else { yyerror("Parent has left."); }
886:
default: res->tree_info |= a->tree_info; }
-
if (i && IDENTIFIER_IS_FUNCTION(i->identifier_flags)) {
-
res->node_info |= i->opt_flags;
-
} else {
-
res->node_info |= opt_flags;
+
}
-
} else {
-
res->node_info |= opt_flags
;
-
}
-
res->node_info
|
=
OPT_APPLY;
+
res->node_info |= opt_flags | OPT_APPLY;
if(b) res->tree_info |= b->tree_info; if (res->node_info & OPT_EXTERNAL_DEPEND) { /* Applying something that has external dependencies