pike.git/
src/
las.c
Branch:
Tag:
Non-build tags
All tags
No tags
1999-11-08
1999-11-08 20:50:51 by Henrik Grubbström (Grubba) <grubba@grubba.org>
701881d42bbc411862141a129b3b2ed93fb2aa77 (
430
lines) (+
5
/-
425
)
[
Show
|
Annotate
]
Branch:
7.9
Now checks IN_TPIKE.
Rev: src/builtin_functions.c:1.204
Rev: src/las.c:1.99
Rev: src/peep.c:1.28
5:
\*/ /**/ #include "global.h"
-
RCSID("$Id: las.c,v 1.
98
1999/11/
06
01
:
38
:
12
grubba Exp $");
+
RCSID("$Id: las.c,v 1.
99
1999/11/
08
20
:
50
:
50
grubba Exp $");
#include "language.h" #include "interpret.h"
1915:
} #endif
+
#ifndef IN_TPIKE
switch(n->token) {
-
case F_APPLY:
-
if(CAR(n)->token == F_CONSTANT &&
-
CAR(n)->u.sval.type == T_FUNCTION &&
-
CAR(n)->u.sval.subtype == FUNCTION_BUILTIN && /* driver fun? */
-
CAR(n)->u.sval.u.efun->optimize)
-
{
-
if((tmp1=CAR(n)->u.sval.u.efun->optimize(n)))
-
{
-
goto use_tmp1;
-
}
-
}
-
break;
-
-
case F_CAST:
-
if (n->type == void_type_string) {
-
/* (void) const -> */
-
if (!CAR(n) || CAR(n)->token == F_CONSTANT)
-
goto zap_node;
-
-
/* (void)(X, const) -> (void)X */
-
if (CAR(n)->token == F_COMMA_EXPR &&
-
CDAR(n)->token == F_CONSTANT) {
-
tmp1 = mkcastnode(void_type_string, CAAR(n));
-
CAAR(n) = 0;
-
goto use_tmp1;
-
}
-
}
-
break;
-
-
case F_RANGE:
-
/* X[Y..Z]
-
* Warn if Z is a constant <= 0.
-
*/
-
if (CDR(n)->token == F_ARG_LIST &&
-
CDDR(n)->token == F_CONSTANT &&
-
((CDDR(n)->u.sval.type == T_INT &&
-
CDDR(n)->u.sval.u.integer <= 0) ||
-
(CDDR(n)->u.sval.type == T_FLOAT &&
-
CDDR(n)->u.sval.u.float_number <= 0.0))) {
-
yywarning(
"
Range end is not positive
."
);
-
}
-
break;
-
-
case F_COMMA_EXPR:
-
if(!CAR(n)) goto use_cdr;
-
if(!CDR(n)) goto use_car;
-
-
/* const , X -> X */
-
if (CAR(n)->token == F_CONSTANT) {
-
goto use_cdr;
-
}
-
/* (X , const) , Y -> X , Y */
-
if (CAR(n)->token == F_COMMA_EXPR &&
-
CDAR(n) && CDAR(n)->token == F_CONSTANT) {
-
tmp1 = mknode(F_COMMA_EXPR, CAAR(n), CDR(n));
-
CAAR(n) = CDR(n) = 0;
-
goto use_tmp1;
-
}
-
/* FALL_THROUGH */
-
case F_ARG_LIST:
-
case F_LVALUE_LIST:
-
if(!CAR(n)) goto use_cdr;
-
if(!CDR(n)) goto use_car;
-
-
/*
-
* { X; break; Y; } -> { X; return; }
-
* { X; return; Y; } -> { X; return; }
-
* { X; continue; Y; } -> { X; return; }
-
*/
-
if((CAR(n)->token==F_RETURN ||
-
CAR(n)->token==F_BREAK ||
-
CAR(n)->token==F_CONTINUE ||
-
(CAR(n)->token==F_ARG_LIST &&
-
CDAR(n) &&
-
(CDAR(n)->token==F_RETURN ||
-
CDAR(n)->token==F_BREAK ||
-
CDAR(n)->token==F_CONTINUE))) &&
-
!(CDR(n)->tree_info & OPT_CASE))
-
goto use_car;
-
-
break;
-
-
case F_LOR:
-
/* !x || !y -> !(x && y) */
-
if(CAR(n)->token==F_NOT && CDR(n)->token==F_NOT)
-
{
-
tmp1=mknode(F_NOT,mknode(F_LAND,CAAR(n),CADR(n)),0);
-
CAAR(n)=CADR(n)=0;
-
goto use_tmp1;
-
}
-
/* 0 || Y -> Y */
-
if (node_is_false(CAR(n))) goto use_cdr;
-
/* 1 || Y -> 1 */
-
if (node_is_true(CAR(n))) goto use_car;
-
/* (X = 0) || Y -> (X = 0) , Y */
-
if ((CAR(n)->token == F_ASSIGN) && node_is_false(CDAR(n))) {
-
tmp1 = mknode(F_COMMA_EXPR, mkcastnode(void_type_string, CAR(n)),
-
CDR(n));
-
CAR(n) = 0;
-
CDR(n) = 0;
-
goto use_tmp1;
-
}
-
break;
-
-
case F_LAND:
-
/* !x && !y -> !(x || y) */
-
if(CAR(n)->token==F_NOT && CDR(n)->token==F_NOT)
-
{
-
tmp1=mknode(F_NOT,mknode(F_LOR,CAAR(n),CADR(n)),0);
-
CAAR(n)=CADR(n)=0;
-
goto use_tmp1;
-
}
-
/* 0 && Y -> 0 */
-
if (node_is_false(CAR(n))) goto use_car;
-
/* 1 && Y -> Y */
-
if (node_is_true(CAR(n))) goto use_cdr;
-
/* (X = 1) && Y -> (X = 1) , Y */
-
if ((CAR(n)->token == F_ASSIGN) && node_is_true(CDAR(n))) {
-
tmp1 = mknode(F_COMMA_EXPR, mkcastnode(void_type_string, CAR(n)),
-
CDR(n));
-
CAR(n) = 0;
-
CDR(n) = 0;
-
goto use_tmp1;
-
}
-
break;
-
-
case '?':
-
/* (! X) ? Y : Z -> X ? Z : Y */
-
if(CAR(n)->token == F_NOT)
-
{
-
tmp1=mknode('?',CAAR(n),mknode(':',CDDR(n),CADR(n)));
-
CAAR(n)=CDDR(n)=CADR(n)=0;
-
goto use_tmp1;
-
}
-
if (CDR(n)) {
-
/* 0 ? Y : Z -> Z */
-
if (node_is_false(CAR(n))) {
-
tmp1 = CDDR(n);
-
CDDR(n) = 0;
-
goto use_tmp1;
-
}
-
/* 1 ? Y : Z -> Y */
-
if (node_is_true(CAR(n))) {
-
tmp1 = CADR(n);
-
CADR(n) = 0;
-
goto use_tmp1;
-
}
-
}
-
break;
-
-
case F_ADD_EQ:
-
if(CDR(n)->token == F_CONSTANT && CDR(n)->u.sval.type == T_INT)
-
{
-
/* a+=0 -> a */
-
if(CDR(n)->u.sval.u.integer == 0) goto use_car;
-
-
/* a+=1 -> ++a */
-
if(CDR(n)->u.sval.u.integer == 1)
-
{
-
tmp1=mknode(F_INC,CAR(n),0);
-
CAR(n)=0;
-
goto use_tmp1;
-
}
-
-
/* a+=-1 -> --a */
-
if(CDR(n)->u.sval.u.integer == -1)
-
{
-
tmp1=mknode(F_DEC, CAR(n), 0);
-
CAR(n)=0;
-
goto use_tmp1;
-
}
-
}
-
break;
-
-
case F_SUB_EQ:
-
if(CDR(n)->token == F_CONSTANT && CDR(n)->u.sval.type == T_INT)
-
{
-
/* a-=0 -> a */
-
if(CDR(n)->u.sval.u.integer == 0) goto use_car;
-
-
/* a-=-1 -> ++a */
-
if(CDR(n)->u.sval.u.integer == -1)
-
{
-
tmp1=mknode(F_INC, CAR(n), 0);
-
CAR(n)=0;
-
goto use_tmp1;
-
}
-
-
/* a-=-1 -> --a */
-
if(CDR(n)->u.sval.u.integer == 1)
-
{
-
tmp1=mknode(F_DEC, CAR(n), 0);
-
CAR(n)=0;
-
goto use_tmp1;
-
}
-
}
-
break;
-
-
case F_ARROW:
-
if(CAR(n)->token==F_CONSTANT &&
-
CAR(n)->u.sval.type==T_OBJECT &&
-
CAR(n)->u.sval.u.object->prog &&
-
CDR(n)->token==F_CONSTANT &&
-
CAR(n)->u.sval.type==T_STRING &&
-
find_identifier("`->",CAR(n)->u.sval.u.object->prog)==-1)
-
{
-
int i;
-
i=find_shared_string_identifier(CDR(n)->u.sval.u.string,
-
CAR(n)->u.sval.u.object->prog);
-
if(i)
-
{
-
struct identifier *id;
-
id=ID_FROM_INT(CAR(n)->u.sval.u.object->prog, i);
-
if(IDENTIFIER_IS_VARIABLE(id->identifier_flags)) break;
-
}
-
ref_push_object(CAR(n)->u.sval.u.object);
-
ref_push_string(CDR(n)->u.sval.u.string);
-
f_index(2);
-
tmp1=mksvaluenode(sp-1);
-
pop_stack();
-
goto use_tmp1;
-
}
-
break;
-
-
case F_FOR:
-
{
-
node **last;
-
int inc;
-
int token;
-
-
/* for(;0; X) Y; -> 0; */
-
if(node_is_false(CAR(n)))
-
{
-
tmp1=mkintnode(0);
-
goto use_tmp1;
-
}
-
-
/* for(;1;); -> for(;1;) sleep(255); (saves cpu) */
-
if(node_is_true(CAR(n)) &&
-
(!CDR(n) || (CDR(n)->token==':' && !CADR(n) && !CDDR(n))))
-
{
-
tmp1=mknode(F_FOR, CAR(n), mknode(':',mkefuncallnode("sleep",mkintnode(255)),0));
-
CAR(n)=0;
-
goto use_tmp1;
-
}
-
-
/*
-
* if X and Y are free from 'continue' or X is null,
-
* then the following optimizations can be done:
-
* for(;++e; X) Y; -> ++ne_loop(e, -1) { Y ; X }
-
* for(;e++; X) Y; -> ++ne_loop(e, 0) { Y; X }
-
* for(;--e; X) Y; -> --ne_loop(e, 1) { Y; X }
-
* for(;e--; X) Y; -> --ne_loop(e, 0) { Y; X }
-
*/
-
if(CAR(n) &&
-
(CAR(n)->token==F_INC ||
-
CAR(n)->token==F_POST_INC ||
-
CAR(n)->token==F_DEC ||
-
CAR(n)->token==F_POST_DEC ) &&
-
(!CDDR(n) || !(CDDR(n)->tree_info & OPT_CONTINUE)) &&
-
(!CADR(n) || !(CADR(n)->tree_info & OPT_CONTINUE)) )
-
{
-
/* Check which of the above cases.. */
-
switch(CAR(n)->token)
-
{
-
case F_POST_DEC: token=F_DEC_NEQ_LOOP; inc=-1; break;
-
case F_DEC: token=F_DEC_NEQ_LOOP; inc=0; break;
-
case F_POST_INC: token=F_INC_NEQ_LOOP; inc=1; break;
-
case F_INC: token=F_INC_NEQ_LOOP; inc=0; break;
-
default: fatal("Impossible error\n"); return;
-
}
-
-
/* Build new tree */
-
tmp1=mknode(token,
-
mknode(F_VAL_LVAL,
-
mkintnode(inc),
-
CAAR(n)),
-
mknode(F_ARG_LIST,
-
mkcastnode(void_type_string, CADR(n)),
-
mkcastnode(void_type_string, CDDR(n))));
-
CDDR(n)=CADR(n)=CAAR(n)=0;
-
goto use_tmp1;
-
}
-
-
/* Last is a pointer to the place where the incrementor is in the
-
* tree. This is needed so we can nullify this pointer later and
-
* free the rest of the tree
-
*/
-
last=&(CDDR(n));
-
tmp1=*last;
-
-
/* We're not interested in casts to void */
-
while(tmp1 &&
-
tmp1->token == F_CAST &&
-
tmp1->type == void_type_string)
-
{
-
last=&CAR(tmp1);
-
tmp1=*last;
-
}
-
-
/* If there is an incrementor, and it is one of x++, ++x, x-- or ++x */
-
if(tmp1 && (tmp1->token==F_INC ||
-
tmp1->token==F_POST_INC ||
-
tmp1->token==F_DEC ||
-
tmp1->token==F_POST_DEC))
-
{
-
node *opnode, **arg1, **arg2;
-
int oper;
-
-
/* does it increment or decrement ? */
-
if(tmp1->token==F_INC || tmp1->token==F_POST_INC)
-
inc=1;
-
else
-
inc=0;
-
-
/* for(; arg1 oper arg2; z ++) p; */
-
-
opnode=CAR(n);
-
-
if(opnode->token == F_APPLY &&
-
CAR(opnode) &&
-
CAR(opnode)->token == F_CONSTANT &&
-
CAR(opnode)->u.sval.type == T_FUNCTION &&
-
CAR(opnode)->u.sval.subtype == FUNCTION_BUILTIN)
-
{
-
if(CAR(opnode)->u.sval.u.efun->function == f_gt)
-
oper=F_GT;
-
else if(CAR(opnode)->u.sval.u.efun->function == f_ge)
-
oper=F_GE;
-
else if(CAR(opnode)->u.sval.u.efun->function == f_lt)
-
oper=F_LT;
-
else if(CAR(opnode)->u.sval.u.efun->function == f_le)
-
oper=F_LE;
-
else if(CAR(opnode)->u.sval.u.efun->function == f_ne)
-
oper=F_NE;
-
else
-
break;
-
}else{
-
break;
-
}
-
-
if(count_args(CDR(opnode)) != 2) break;
-
arg1=my_get_arg(&CDR(opnode), 0);
-
arg2=my_get_arg(&CDR(opnode), 1);
-
-
/* it was not on the form for(; x op y; z++) p; */
-
if(!node_is_eq(*arg1,CAR(tmp1)) || /* x == z */
-
depend_p(*arg2,*arg2) || /* does y depend on y? */
-
depend_p(*arg2,*arg1) || /* does y depend on x? */
-
depend_p(*arg2,CADR(n)) || /* does y depend on p? */
-
depend_p(*arg2,tmp1)) /* does y depend on z? */
-
{
-
/* it was not on the form for(; x op y; z++) p; */
-
if(!node_is_eq(*arg2,CAR(tmp1)) || /* y == z */
-
depend_p(*arg1,*arg2) || /* does x depend on y? */
-
depend_p(*arg1,*arg1) || /* does x depend on x? */
-
depend_p(*arg1,CADR(n)) || /* does x depend on p? */
-
depend_p(*arg1,tmp1)) /* does x depend on z? */
-
{
-
/* it was not on the form for(; x op y; y++) p; */
-
break;
-
}else{
-
node **tmparg;
-
/* for(; x op y; y++) p; -> for(; y op^-1 x; y++) p; */
-
-
switch(oper)
-
{
-
case F_LT: oper=F_GT; break;
-
case F_LE: oper=F_GE; break;
-
case F_GT: oper=F_LT; break;
-
case F_GE: oper=F_LE; break;
-
}
-
-
tmparg=arg1;
-
arg1=arg2;
-
arg2=tmparg;
-
}
-
}
-
if(inc)
-
{
-
if(oper==F_LE)
-
tmp3=mkopernode("`+",*arg2,mkintnode(1));
-
else if(oper==F_LT)
-
tmp3=*arg2;
-
else
-
break;
-
}else{
-
if(oper==F_GE)
-
tmp3=mkopernode("`-",*arg2,mkintnode(1));
-
else if(oper==F_GT)
-
tmp3=*arg2;
-
else
-
break;
-
}
-
-
*last=0;
-
if(oper==F_NE)
-
{
-
if(inc)
-
token=F_INC_NEQ_LOOP;
-
else
-
token=F_DEC_NEQ_LOOP;
-
}else{
-
if(inc)
-
token=F_INC_LOOP;
-
else
-
token=F_DEC_LOOP;
-
}
-
tmp2=mknode(token,mknode(F_VAL_LVAL,tmp3,*arg1),CADR(n));
-
*arg1 = *arg2 = CADR(n) =0;
-
-
if(inc)
-
{
-
tmp1->token=F_DEC;
-
}else{
-
tmp1->token=F_INC;
-
}
-
-
tmp1=mknode(F_ARG_LIST,mkcastnode(void_type_string,tmp1),tmp2);
-
goto use_tmp1;
-
}
-
break;
-
}
-
+
#include
"
treeopt
.
h
"
use_car: tmp1=CAR(n); CAR(n)=0;
2377:
continue; }
+
#endif /* !IN_TPIKE */
n->node_info |= OPT_OPTIMIZED; n=n->parent; }while(n);