gcase() clean up

remove tail recursion, simplify
This commit is contained in:
Pavlas, Zdenek 2016-10-11 01:29:56 -07:00
parent 7dddd65b46
commit 7bd30a488a

View File

@ -4906,7 +4906,35 @@ static int gcase(struct case_t **base, int len, int case_reg, int *bsym)
{ {
struct case_t *p; struct case_t *p;
int e; int e;
if (len <= 4) { while (len > 4) {
/* binary search */
p = base[len/2];
vseti(case_reg, 0);
vdup();
vpushi(p->v2);
gen_op(TOK_LE);
e = gtst(1, 0);
case_reg = gv(RC_INT);
vpop();
vseti(case_reg, 0);
vdup();
vpushi(p->v1);
gen_op(TOK_GE);
gtst_addr(0, p->sym); /* v1 <= x <= v2 */
case_reg = gv(RC_INT);
vpop();
/* x < v1 */
case_reg = gcase(base, len/2, case_reg, bsym);
if (cur_switch->def_sym)
gjmp_addr(cur_switch->def_sym);
else
*bsym = gjmp(*bsym);
/* x > v2 */
gsym(e);
e = len/2 + 1;
base += e; len -= e;
}
/* linear scan */
while (len--) { while (len--) {
p = *base++; p = *base++;
vseti(case_reg, 0); vseti(case_reg, 0);
@ -4915,8 +4943,6 @@ static int gcase(struct case_t **base, int len, int case_reg, int *bsym)
if (p->v1 == p->v2) { if (p->v1 == p->v2) {
gen_op(TOK_EQ); gen_op(TOK_EQ);
gtst_addr(0, p->sym); gtst_addr(0, p->sym);
case_reg = gv(RC_INT);
vpop();
} else { } else {
gen_op(TOK_LE); gen_op(TOK_LE);
e = gtst(1, 0); e = gtst(1, 0);
@ -4927,38 +4953,10 @@ static int gcase(struct case_t **base, int len, int case_reg, int *bsym)
vpushi(p->v1); vpushi(p->v1);
gen_op(TOK_GE); gen_op(TOK_GE);
gtst_addr(0, p->sym); gtst_addr(0, p->sym);
case_reg = gv(RC_INT);
vpop();
gsym(e); gsym(e);
} }
}
} else {
p = base[len/2];
/* mid */
vseti(case_reg, 0);
vdup();
vpushi(p->v2);
gen_op(TOK_LE);
e = gtst(1, 0);
case_reg = gv(RC_INT); case_reg = gv(RC_INT);
vpop(); vpop();
vseti(case_reg, 0);
vdup();
vpushi(p->v1);
gen_op(TOK_GE);
gtst_addr(0, p->sym);
case_reg = gv(RC_INT);
vpop();
/* left */
case_reg = gcase(base, len/2, case_reg, bsym);
if (cur_switch->def_sym)
gjmp_addr(cur_switch->def_sym);
else
*bsym = gjmp(*bsym);
/* right */
gsym(e);
e = len/2 + 1;
case_reg = gcase(base + e, len - e, case_reg, bsym);
} }
return case_reg; return case_reg;
} }
@ -5245,7 +5243,8 @@ static void block(int *bsym, int *csym, int is_expr)
b = gjmp(0); /* jump to first case */ b = gjmp(0); /* jump to first case */
sw.p = NULL; sw.n = 0; sw.def_sym = 0; sw.p = NULL; sw.n = 0; sw.def_sym = 0;
saved = cur_switch; saved = cur_switch;
cur_switch = &sw; block(&a, csym, 0); cur_switch = &sw;
block(&a, csym, 0);
a = gjmp(a); /* add implicit break */ a = gjmp(a); /* add implicit break */
/* case lookup */ /* case lookup */
gsym(b); gsym(b);