mirror of
https://github.com/golang/go
synced 2024-11-19 02:14:43 -07:00
gc: O(1) string comparison when lengths differ
R=ken2 CC=golang-dev https://golang.org/cl/2331045
This commit is contained in:
parent
30edda690f
commit
30dd191171
@ -820,6 +820,9 @@ bgen(Node *n, int true, Prog *to)
|
||||
if(n == N)
|
||||
n = nodbool(1);
|
||||
|
||||
if(n->ninit != nil)
|
||||
genlist(n->ninit);
|
||||
|
||||
nl = n->left;
|
||||
nr = n->right;
|
||||
|
||||
|
@ -699,6 +699,9 @@ bgen(Node *n, int true, Prog *to)
|
||||
if(n == N)
|
||||
n = nodbool(1);
|
||||
|
||||
if(n->ninit != nil)
|
||||
genlist(n->ninit);
|
||||
|
||||
nl = n->left;
|
||||
nr = n->right;
|
||||
|
||||
|
@ -754,6 +754,9 @@ bgen(Node *n, int true, Prog *to)
|
||||
if(n == N)
|
||||
n = nodbool(1);
|
||||
|
||||
if(n->ninit != nil)
|
||||
genlist(n->ninit);
|
||||
|
||||
nl = n->left;
|
||||
nr = n->right;
|
||||
|
||||
|
@ -248,9 +248,6 @@ gen(Node *n)
|
||||
|
||||
gen(n->nincr); // contin: incr
|
||||
patch(p1, pc); // test:
|
||||
if(n->ntest != N)
|
||||
if(n->ntest->ninit != nil)
|
||||
genlist(n->ntest->ninit);
|
||||
bgen(n->ntest, 0, breakpc); // if(!test) goto break
|
||||
genlist(n->nbody); // body
|
||||
gjmp(continpc);
|
||||
@ -263,9 +260,6 @@ gen(Node *n)
|
||||
p1 = gjmp(P); // goto test
|
||||
p2 = gjmp(P); // p2: goto else
|
||||
patch(p1, pc); // test:
|
||||
if(n->ntest != N)
|
||||
if(n->ntest->ninit != nil)
|
||||
genlist(n->ntest->ninit);
|
||||
bgen(n->ntest, 0, p2); // if(!test) goto p2
|
||||
genlist(n->nbody); // then
|
||||
p3 = gjmp(P); // goto done
|
||||
|
@ -1109,6 +1109,7 @@ Type* ptrto(Type *t);
|
||||
void* remal(void *p, int32 on, int32 n);
|
||||
Sym* restrictlookup(char *name, Pkg *pkg);
|
||||
Node* safeexpr(Node *n, NodeList **init);
|
||||
Node* cheapexpr(Node *n, NodeList **init);
|
||||
int32 setlineno(Node *n);
|
||||
void setmaxarg(Type *t);
|
||||
Type* shallow(Type *t);
|
||||
|
@ -2595,7 +2595,7 @@ brrev(int a)
|
||||
}
|
||||
|
||||
/*
|
||||
* return side effect-free appending side effects to init.
|
||||
* return side effect-free n, appending side effects to init.
|
||||
* result is assignable if n is.
|
||||
*/
|
||||
Node*
|
||||
@ -2652,6 +2652,24 @@ safeexpr(Node *n, NodeList **init)
|
||||
// make a copy; must not be used as an lvalue
|
||||
if(islvalue(n))
|
||||
fatal("missing lvalue case in safeexpr: %N", n);
|
||||
return cheapexpr(n, init);
|
||||
}
|
||||
|
||||
/*
|
||||
* return side-effect free and cheap n, appending side effects to init.
|
||||
* result may not be assignable.
|
||||
*/
|
||||
Node*
|
||||
cheapexpr(Node *n, NodeList **init)
|
||||
{
|
||||
Node *a, *l;
|
||||
|
||||
switch(n->op) {
|
||||
case ONAME:
|
||||
case OLITERAL:
|
||||
return n;
|
||||
}
|
||||
|
||||
l = nod(OXXX, N, N);
|
||||
tempname(l, n->type);
|
||||
a = nod(OAS, l, n);
|
||||
|
@ -654,8 +654,6 @@ walkexpr(Node **np, NodeList **init)
|
||||
case OAND:
|
||||
case OOR:
|
||||
case OXOR:
|
||||
case OANDAND:
|
||||
case OOROR:
|
||||
case OSUB:
|
||||
case OMUL:
|
||||
case OEQ:
|
||||
@ -669,6 +667,17 @@ walkexpr(Node **np, NodeList **init)
|
||||
walkexpr(&n->left, init);
|
||||
walkexpr(&n->right, init);
|
||||
goto ret;
|
||||
|
||||
case OANDAND:
|
||||
case OOROR:
|
||||
walkexpr(&n->left, init);
|
||||
// cannot put side effects from n->right on init,
|
||||
// because they cannot run before n->left is checked.
|
||||
// save elsewhere and store on the eventual n->right.
|
||||
ll = nil;
|
||||
walkexpr(&n->right, &ll);
|
||||
n->right->ninit = concat(n->right->ninit, ll);
|
||||
goto ret;
|
||||
|
||||
case OPRINT:
|
||||
case OPRINTN:
|
||||
@ -1196,11 +1205,27 @@ walkexpr(Node **np, NodeList **init)
|
||||
goto ret;
|
||||
}
|
||||
|
||||
// prepare for rewrite below
|
||||
if(n->etype == OEQ || n->etype == ONE) {
|
||||
n->left = cheapexpr(n->left, init);
|
||||
n->right = cheapexpr(n->right, init);
|
||||
}
|
||||
|
||||
// sys_cmpstring(s1, s2) :: 0
|
||||
r = mkcall("cmpstring", types[TINT], init,
|
||||
conv(n->left, types[TSTRING]),
|
||||
conv(n->right, types[TSTRING]));
|
||||
r = nod(n->etype, r, nodintconst(0));
|
||||
|
||||
// quick check of len before full compare for == or !=
|
||||
if(n->etype == OEQ || n->etype == ONE) {
|
||||
if(n->etype == OEQ)
|
||||
r = nod(OANDAND, nod(OEQ, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
|
||||
else
|
||||
r = nod(OOROR, nod(ONE, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
|
||||
typecheck(&r, Erv);
|
||||
walkexpr(&r, nil);
|
||||
}
|
||||
typecheck(&r, Erv);
|
||||
n = r;
|
||||
goto ret;
|
||||
|
Loading…
Reference in New Issue
Block a user