mirror of
https://github.com/golang/go
synced 2024-11-12 09:20:22 -07:00
switch
R=r OCL=19288 CL=19288
This commit is contained in:
parent
23c8faaf85
commit
e875055461
175
src/cmd/6g/gen.c
175
src/cmd/6g/gen.c
@ -358,15 +358,158 @@ ret:
|
||||
lineno = lno;
|
||||
}
|
||||
|
||||
Case*
|
||||
csort(Case *l, int(*f)(Case*, Case*))
|
||||
{
|
||||
Case *l1, *l2, *le;
|
||||
|
||||
if(l == 0 || l->slink == 0)
|
||||
return l;
|
||||
|
||||
l1 = l;
|
||||
l2 = l;
|
||||
for(;;) {
|
||||
l2 = l2->slink;
|
||||
if(l2 == 0)
|
||||
break;
|
||||
l2 = l2->slink;
|
||||
if(l2 == 0)
|
||||
break;
|
||||
l1 = l1->slink;
|
||||
}
|
||||
|
||||
l2 = l1->slink;
|
||||
l1->slink = 0;
|
||||
l1 = csort(l, f);
|
||||
l2 = csort(l2, f);
|
||||
|
||||
/* set up lead element */
|
||||
if((*f)(l1, l2) < 0) {
|
||||
l = l1;
|
||||
l1 = l1->slink;
|
||||
} else {
|
||||
l = l2;
|
||||
l2 = l2->slink;
|
||||
}
|
||||
le = l;
|
||||
|
||||
for(;;) {
|
||||
if(l1 == 0) {
|
||||
while(l2) {
|
||||
le->slink = l2;
|
||||
le = l2;
|
||||
l2 = l2->slink;
|
||||
}
|
||||
le->slink = 0;
|
||||
break;
|
||||
}
|
||||
if(l2 == 0) {
|
||||
while(l1) {
|
||||
le->slink = l1;
|
||||
le = l1;
|
||||
l1 = l1->slink;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if((*f)(l1, l2) < 0) {
|
||||
le->slink = l1;
|
||||
le = l1;
|
||||
l1 = l1->slink;
|
||||
} else {
|
||||
le->slink = l2;
|
||||
le = l2;
|
||||
l2 = l2->slink;
|
||||
}
|
||||
}
|
||||
le->slink = 0;
|
||||
return l;
|
||||
}
|
||||
|
||||
int
|
||||
casecmp(Case *c1, Case *c2)
|
||||
{
|
||||
int w;
|
||||
|
||||
w = whatis(c1->scase);
|
||||
if(w != whatis(c2->scase))
|
||||
fatal("casecmp");
|
||||
|
||||
switch(w) {
|
||||
case Wlitfloat:
|
||||
return mpcmpfltflt(c1->scase->val.u.fval, c2->scase->val.u.fval);
|
||||
case Wlitint:
|
||||
return mpcmpfixfix(c1->scase->val.u.xval, c2->scase->val.u.xval);
|
||||
case Wlitstr:
|
||||
return cmpslit(c1->scase, c2->scase);
|
||||
// case Wlitbool:
|
||||
// case Wlitnil:
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
swconst(Case *sa, int nc, Node *n1, Node *tmp)
|
||||
{
|
||||
Case *s, *sb;
|
||||
Prog *p1, *p2, *p3;
|
||||
int n;
|
||||
|
||||
// small number of cases --
|
||||
// test them sequentially
|
||||
if(nc < 4) {
|
||||
for(s=sa; s!=C; s=s->slink) {
|
||||
setlineno(s->scase);
|
||||
memset(n1, 0, sizeof(*n1));
|
||||
n1->op = OEQ;
|
||||
n1->left = tmp;
|
||||
n1->right = s->scase;
|
||||
walktype(n1, Erv);
|
||||
bgen(n1, 1, s->sprog);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// large number of cases --
|
||||
// find the middle and recur on each half
|
||||
|
||||
n = nc/2;
|
||||
for(s=sa; s!=C; s=s->slink) {
|
||||
n--;
|
||||
if(n == 0)
|
||||
break;
|
||||
}
|
||||
n = nc/2;
|
||||
sb = s->slink;
|
||||
s->slink = C;
|
||||
|
||||
p1 = gbranch(AJMP, T); // goto midcmp
|
||||
p2 = pc; // low half of switch
|
||||
swconst(sa, n, n1, tmp);
|
||||
|
||||
p3 = gbranch(AJMP, T); // goto end
|
||||
patch(p1, pc);
|
||||
|
||||
setlineno(s->scase);
|
||||
memset(n1, 0, sizeof(*n1));
|
||||
n1->op = OLE;
|
||||
n1->left = tmp;
|
||||
n1->right = s->scase;
|
||||
walktype(n1, Erv);
|
||||
bgen(n1, 1, p2);
|
||||
|
||||
swconst(sb, nc-n, n1, tmp); // high half of switch
|
||||
patch(p3, pc);
|
||||
}
|
||||
|
||||
void
|
||||
swgen(Node *n)
|
||||
{
|
||||
Node *c1, *c2;
|
||||
Node n1, tmp;
|
||||
Case *s0, *se, *s;
|
||||
Case *s0, *se, *s, *sa;
|
||||
Prog *p1, *dflt;
|
||||
int32 lno;
|
||||
int any;
|
||||
int any, nc, w;
|
||||
Iter save1, save2;
|
||||
|
||||
// botch - put most of this code in
|
||||
@ -404,7 +547,7 @@ swgen(Node *n)
|
||||
patch(gbranch(AJMP, T), breakpc);
|
||||
any = 1;
|
||||
|
||||
// over case expressions
|
||||
// loop over case expressions
|
||||
c2 = listfirst(&save2, &c1->left);
|
||||
if(c2 == N)
|
||||
dflt = pc;
|
||||
@ -439,7 +582,28 @@ swgen(Node *n)
|
||||
tempname(&tmp, n->ntest->type);
|
||||
cgen(n->ntest, &tmp);
|
||||
|
||||
sa = C; // base of constant cases
|
||||
nc = 0;
|
||||
for(s=s0; s!=C; s=s->slink) {
|
||||
switch(whatis(s->scase)) {
|
||||
case Wlitfloat:
|
||||
case Wlitint:
|
||||
case Wlitstr:
|
||||
// case Wlitbool:
|
||||
// case Wlitnil:
|
||||
nc++;
|
||||
if(sa == C)
|
||||
sa = s;
|
||||
se = s;
|
||||
continue;
|
||||
}
|
||||
if(sa != C) {
|
||||
se->slink = C;
|
||||
sa = csort(sa, casecmp);
|
||||
swconst(sa, nc, &n1, &tmp);
|
||||
nc = 0;
|
||||
sa = C;
|
||||
}
|
||||
setlineno(s->scase);
|
||||
memset(&n1, 0, sizeof(n1));
|
||||
n1.op = OEQ;
|
||||
@ -448,6 +612,11 @@ swgen(Node *n)
|
||||
walktype(&n1, Erv);
|
||||
bgen(&n1, 1, s->sprog);
|
||||
}
|
||||
if(sa != C) {
|
||||
se->slink = C;
|
||||
sa = csort(sa, casecmp);
|
||||
swconst(sa, nc, &n1, &tmp);
|
||||
}
|
||||
if(dflt != P) {
|
||||
patch(gbranch(AJMP, T), dflt);
|
||||
goto ret;
|
||||
|
@ -1094,8 +1094,7 @@ loop:
|
||||
goto ret;
|
||||
|
||||
nottop:
|
||||
dump("bad top", n);
|
||||
fatal("walktype: top=%d %O", top, n->op);
|
||||
yyerror("didn't expect %O here", n->op);
|
||||
goto ret;
|
||||
|
||||
badt:
|
||||
@ -2360,8 +2359,7 @@ shape:
|
||||
return N;
|
||||
|
||||
nottop:
|
||||
dump("bad top", n);
|
||||
fatal("mapop: top=%d %O", top, n->op);
|
||||
yyerror("didn't expect %O here", n->op);
|
||||
return N;
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ hash_init (struct hash *h,
|
||||
|
||||
if(datasize < sizeof (void *))
|
||||
datasize = sizeof (void *);
|
||||
datasize = rnd(datasize, 8);
|
||||
datasize = rnd(datasize, sizeof (void *));
|
||||
init_sizes (hint, &init_power, &max_power);
|
||||
h->datasize = datasize;
|
||||
h->max_power = max_power;
|
||||
|
Loading…
Reference in New Issue
Block a user