optimize trivial recursion

This commit is contained in:
Kyryl Melekhin
2021-07-12 15:51:14 +00:00
parent ad347d54b9
commit c37ed995e3

69
pike.c
View File

@@ -117,12 +117,6 @@ rsub* newsub(int n)
return s; return s;
} }
rsub* incref(rsub *s)
{
s->ref++;
return s;
}
rsub* update(rsub *s, int i, const char *p) rsub* update(rsub *s, int i, const char *p)
{ {
rsub *s1; rsub *s1;
@@ -526,54 +520,49 @@ void cleanmarks(rcode *prog)
} }
} }
static rthread thread(int *pc, rsub *sub) static void addthread(rthreadlist *l, int *pc, rsub *sub, const char *beg, const char *sp)
{
rthread t = {pc, sub};
return t;
}
static void addthread(rthreadlist *l, rthread t, const char *beg, const char *sp)
{ {
int off; int off;
if(*t.pc & 0x80) { rec:
decref(t.sub); if(*pc & 0x80) {
decref(sub);
return; // already on list return; // already on list
} }
*t.pc |= 0x80; *pc |= 0x80;
switch(*t.pc & 0x7f) { switch(*pc & 0x7f) {
default: default:
l->t[l->n++] = t; l->t[l->n].sub = sub;
l->t[l->n++].pc = pc;
break; break;
case JMP: case JMP:
off = t.pc[1]; off = pc[1];
t.pc += 2; pc += 2 + off;
addthread(l, thread(t.pc + off, t.sub), beg, sp); goto rec;
break;
case SPLIT: case SPLIT:
off = t.pc[1]; off = pc[1];
t.pc += 2; sub->ref++;
addthread(l, thread(t.pc, incref(t.sub)), beg, sp); addthread(l, pc+2, sub, beg, sp);
addthread(l, thread(t.pc + off, t.sub), beg, sp); pc += 2 + off;
break; goto rec;
case RSPLIT: case RSPLIT:
off = t.pc[1]; off = pc[1];
t.pc += 2; pc += 2;
addthread(l, thread(t.pc + off, incref(t.sub)), beg, sp); sub->ref++;
addthread(l, thread(t.pc, t.sub), beg, sp); addthread(l, pc + off, sub, beg, sp);
break; goto rec;
case SAVE: case SAVE:
off = t.pc[1]; off = pc[1];
t.pc += 2; pc += 2;
addthread(l, thread(t.pc, update(t.sub, off, sp)), beg, sp); sub = update(sub, off, sp);
break; goto rec;
case BOL: case BOL:
if(sp == beg) if(sp == beg)
addthread(l, thread(t.pc + 1, t.sub), beg, sp); { pc++; goto rec; }
break; break;
case EOL: case EOL:
if(!*sp) if(!*sp)
addthread(l, thread(t.pc + 1, t.sub), beg, sp); { pc++; goto rec; }
break; break;
} }
} }
@@ -598,7 +587,7 @@ int re_pikevm(rcode *prog, const char *s, const char **subp, int nsubp)
sub->sub[i] = NULL; sub->sub[i] = NULL;
cleanmarks(prog); cleanmarks(prog);
addthread(clist, thread(prog->insts, sub), s, s); addthread(clist, prog->insts, sub, s, s);
for(sp=s;; sp++) { for(sp=s;; sp++) {
if(clist->n == 0) if(clist->n == 0)
break; break;
@@ -620,7 +609,7 @@ int re_pikevm(rcode *prog, const char *s, const char **subp, int nsubp)
} }
case ANY: case ANY:
addthread: addthread:
addthread(nlist, thread(pc, sub), s, sp+1); addthread(nlist, pc, sub, s, sp+1);
break; break;
case CLASS: case CLASS:
case CLASSNOT: case CLASSNOT: