1
0
mirror of https://github.com/golang/go synced 2024-11-19 02:44:44 -07:00

5g, 6g, 8g: generate code for string index

instead of calling function.

R=ken2
CC=golang-dev
https://golang.org/cl/2762041
This commit is contained in:
Russ Cox 2010-10-26 21:11:17 -07:00
parent 705c0382e8
commit e48c0fb562
14 changed files with 117 additions and 69 deletions

View File

@ -558,9 +558,11 @@ agen(Node *n, Node *res)
p2 = nil; // to be patched to panicindex.
w = n->type->width;
if(nr->addable) {
if(!isconst(nr, CTINT))
tempname(&tmp, types[TINT32]);
if(!isconst(nl, CTSTR))
agenr(nl, &n3, res);
if(!isconst(nr, CTINT)) {
tempname(&tmp, types[TINT32]);
p2 = cgenindex(nr, &tmp);
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
@ -572,12 +574,15 @@ agen(Node *n, Node *res)
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
if(!isconst(nl, CTSTR)) {
regalloc(&n3, types[tptr], res);
agen(nl, &n3);
}
} else {
tempname(&tmp, types[TINT32]);
p2 = cgenindex(nr, &tmp);
nr = &tmp;
if(!isconst(nl, CTSTR))
agenr(nl, &n3, res);
regalloc(&n1, tmp.type, N);
gins(optoas(OAS, tmp.type), &tmp, &n1);
@ -592,9 +597,10 @@ agen(Node *n, Node *res)
// constant index
if(isconst(nr, CTINT)) {
if(isconst(nl, CTSTR))
fatal("constant string constant index");
v = mpgetfix(nr->val.u.xval);
if(isslice(nl->type)) {
if(isslice(nl->type) || nl->type->etype == TSTRING) {
if(!debug['B'] && !n->etype) {
n1 = n3;
n1.op = OINDREG;
@ -638,7 +644,10 @@ agen(Node *n, Node *res)
if(!debug['B'] && !n->etype) {
// check bounds
regalloc(&n4, types[TUINT32], N);
if(isslice(nl->type)) {
if(isconst(nl, CTSTR)) {
nodconst(&n1, types[TUINT32], nl->val.u.sval->len);
gmove(&n1, &n4);
} else if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
@ -657,7 +666,12 @@ agen(Node *n, Node *res)
patch(p1, pc);
}
if(isslice(nl->type)) {
if(isconst(nl, CTSTR)) {
regalloc(&n3, types[tptr], res);
p1 = gins(AMOVW, N, &n3);
datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
p1->from.type = D_CONST;
} else if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
@ -795,12 +809,8 @@ igen(Node *n, Node *a, Node *res)
void
agenr(Node *n, Node *a, Node *res)
{
Node n1;
tempname(&n1, types[tptr]);
agen(n, &n1);
regalloc(a, types[tptr], res);
gmove(&n1, a);
agen(n, a);
}
/*

View File

@ -1678,6 +1678,8 @@ sudoaddable(int as, Node *n, Addr *a, int *w)
goto odot;
case OINDEX:
if(n->left->type->etype == TSTRING)
return 0;
cleani += 2;
reg = &clean[cleani-1];
reg1 = &clean[cleani-2];

View File

@ -477,8 +477,10 @@ agen(Node *n, Node *res)
regalloc(&n1, nr->type, N);
cgen(nr, &n1);
}
if(!isconst(nl, CTSTR)) {
regalloc(&n3, types[tptr], res);
agen(nl, &n3);
}
goto index;
}
tempname(&tmp, nr->type);
@ -486,8 +488,10 @@ agen(Node *n, Node *res)
nr = &tmp;
irad:
if(!isconst(nl, CTSTR)) {
regalloc(&n3, types[tptr], res);
agen(nl, &n3);
}
if(!isconst(nr, CTINT)) {
regalloc(&n1, nr->type, N);
cgen(nr, &n1);
@ -501,7 +505,7 @@ agen(Node *n, Node *res)
// explicit check for nil if array is large enough
// that we might derive too big a pointer.
if(!isslice(nl->type) && nl->type->width >= unmappedzero) {
if(isfixedarray(nl->type) && nl->type->width >= unmappedzero) {
regalloc(&n4, types[tptr], &n3);
gmove(&n3, &n4);
n4.op = OINDREG;
@ -516,8 +520,10 @@ agen(Node *n, Node *res)
// constant index
if(isconst(nr, CTINT)) {
if(isconst(nl, CTSTR))
fatal("constant string constant index"); // front end should handle
v = mpgetfix(nr->val.u.xval);
if(isslice(nl->type)) {
if(isslice(nl->type) || nl->type->etype == TSTRING) {
if(!debug['B'] && !n->etype) {
n1 = n3;
n1.op = OINDREG;
@ -556,20 +562,21 @@ agen(Node *n, Node *res)
// check bounds
n5.op = OXXX;
t = types[TUINT32];
if(isslice(nl->type)) {
if(is64(nr->type))
t = types[TUINT64];
if(isconst(nl, CTSTR)) {
nodconst(&n1, t, nl->val.u.sval->len);
} else if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[TUINT32];
n1.xoffset = Array_nel;
if(is64(nr->type)) {
t = types[TUINT64];
regalloc(&n5, t, N);
gmove(&n1, &n5);
n1 = n5;
}
} else {
if(is64(nr->type))
t = types[TUINT64];
nodconst(&n1, t, nl->type->bound);
}
gins(optoas(OCMP, t), &n2, &n1);
@ -580,7 +587,16 @@ agen(Node *n, Node *res)
patch(p1, pc);
}
if(isslice(nl->type)) {
if(isconst(nl, CTSTR)) {
regalloc(&n3, types[tptr], res);
p1 = gins(ALEAQ, N, &n3);
datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
p1->from.scale = 1;
p1->from.index = n2.val.u.reg;
goto indexdone;
}
if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
@ -599,6 +615,7 @@ agen(Node *n, Node *res)
gmove(&n3, res);
}
indexdone:
gmove(&n3, res);
regfree(&n2);
regfree(&n3);

View File

@ -1784,6 +1784,8 @@ sudoaddable(int as, Node *n, Addr *a)
goto odot;
case OINDEX:
if(n->left->type->etype == TSTRING)
return 0;
goto oindex;
}
return 0;

View File

@ -230,8 +230,8 @@ cgen(Node *n, Node *res)
cgen(nl, res);
break;
}
mgen(nl, &n1, res);
tempname(&n2, n->type);
mgen(nl, &n1, res);
gmove(&n1, &n2);
gmove(&n2, res);
mfree(&n1);
@ -518,9 +518,11 @@ agen(Node *n, Node *res)
p2 = nil; // to be patched to panicindex.
w = n->type->width;
if(nr->addable) {
if(!isconst(nr, CTINT))
tempname(&tmp, types[TINT32]);
if(!isconst(nl, CTSTR))
agenr(nl, &n3, res);
if(!isconst(nr, CTINT)) {
tempname(&tmp, types[TINT32]);
p2 = cgenindex(nr, &tmp);
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
@ -532,12 +534,15 @@ agen(Node *n, Node *res)
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
if(!isconst(nl, CTSTR)) {
regalloc(&n3, types[tptr], res);
agen(nl, &n3);
}
} else {
tempname(&tmp, types[TINT32]);
p2 = cgenindex(nr, &tmp);
nr = &tmp;
if(!isconst(nl, CTSTR))
agenr(nl, &n3, res);
regalloc(&n1, tmp.type, N);
gins(optoas(OAS, tmp.type), &tmp, &n1);
@ -549,7 +554,7 @@ agen(Node *n, Node *res)
// explicit check for nil if array is large enough
// that we might derive too big a pointer.
if(!isslice(nl->type) && nl->type->width >= unmappedzero) {
if(isfixedarray(nl->type) && nl->type->width >= unmappedzero) {
regalloc(&n4, types[tptr], &n3);
gmove(&n3, &n4);
n4.op = OINDREG;
@ -564,9 +569,10 @@ agen(Node *n, Node *res)
// constant index
if(isconst(nr, CTINT)) {
if(isconst(nl, CTSTR))
fatal("constant string constant index");
v = mpgetfix(nr->val.u.xval);
if(isslice(nl->type)) {
if(isslice(nl->type) || nl->type->etype == TSTRING) {
if(!debug['B'] && !n->etype) {
n1 = n3;
n1.op = OINDREG;
@ -600,7 +606,9 @@ agen(Node *n, Node *res)
if(!debug['B'] && !n->etype) {
// check bounds
if(isslice(nl->type)) {
if(isconst(nl, CTSTR))
nodconst(&n1, types[TUINT32], nl->val.u.sval->len);
else if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
@ -615,7 +623,16 @@ agen(Node *n, Node *res)
patch(p1, pc);
}
if(isslice(nl->type)) {
if(isconst(nl, CTSTR)) {
regalloc(&n3, types[tptr], res);
p1 = gins(ALEAL, N, &n3);
datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
p1->from.scale = 1;
p1->from.index = n2.val.u.reg;
goto indexdone;
}
if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
@ -635,6 +652,7 @@ agen(Node *n, Node *res)
gmove(&n3, res);
}
indexdone:
gmove(&n3, res);
regfree(&n2);
regfree(&n3);
@ -710,8 +728,14 @@ igen(Node *n, Node *a, Node *res)
{
Node n1;
// release register for now, to avoid
// confusing tempname.
if(res != N && res->op == OREGISTER)
reg[res->val.u.reg]--;
tempname(&n1, types[tptr]);
agen(n, &n1);
if(res != N && res->op == OREGISTER)
reg[res->val.u.reg]++;
regalloc(a, types[tptr], res);
gmove(&n1, a);
a->op = OINDREG;

View File

@ -789,6 +789,8 @@ mkvar(Reg *r, Adr *a)
// if they overlaps, disable both
if(overlap(v->offset, v->width, o, w)) {
if(debug['R'])
print("disable %s\n", v->sym->name);
v->addr = 1;
flag = 1;
}
@ -821,7 +823,7 @@ mkvar(Reg *r, Adr *a)
v->addr = flag; // funny punning
if(debug['R'])
print("bit=%2d et=%2d w=%d %S %D\n", i, et, w, s, a);
print("bit=%2d et=%2d w=%d %S %D flag=%d\n", i, et, w, s, a, v->addr);
ostats.nvar++;
bit = blsh(i);

View File

@ -24,7 +24,6 @@ char *runtimeimport =
"func \"\".cmpstring (? string, ? string) int\n"
"func \"\".slicestring (? string, ? int, ? int) string\n"
"func \"\".slicestring1 (? string, ? int) string\n"
"func \"\".indexstring (? string, ? int) uint8\n"
"func \"\".intstring (? int64) string\n"
"func \"\".slicebytetostring (? []uint8) string\n"
"func \"\".sliceinttostring (? []int) string\n"

View File

@ -652,7 +652,6 @@ tempname(Node *n, Type *t)
snprint(namebuf, sizeof(namebuf), "autotmp_%.4d", statuniqgen);
statuniqgen++;
s = lookup(namebuf);
memset(n, 0, sizeof(*n));
n->op = ONAME;
n->sym = s;

View File

@ -369,7 +369,7 @@ enum
ODOTTYPE2,
OEQ, ONE, OLT, OLE, OGE, OGT,
OIND,
OINDEX, OINDEXSTR, OINDEXMAP,
OINDEX, OINDEXMAP,
OKEY, OPARAM,
OLEN,
OMAKE, OMAKECHAN, OMAKEMAP, OMAKESLICE,

View File

@ -59,6 +59,9 @@ exprfmt(Fmt *f, Node *n, int prec)
case OPRINT:
case OPRINTN:
case OCALL:
case OCALLMETH:
case OCALLINTER:
case OCALLFUNC:
case OCONV:
case OCONVNOP:
case OMAKESLICE:
@ -72,6 +75,8 @@ exprfmt(Fmt *f, Node *n, int prec)
case ORECV:
case OCONVIFACE:
case OTPAREN:
case OINDEX:
case OINDEXMAP:
nprec = 7;
break;
@ -328,7 +333,6 @@ exprfmt(Fmt *f, Node *n, int prec)
case OINDEX:
case OINDEXMAP:
case OINDEXSTR:
exprfmt(f, n->left, 7);
fmtprint(f, "[");
exprfmt(f, n->right, 0);

View File

@ -39,7 +39,6 @@ func concatstring()
func cmpstring(string, string) int
func slicestring(string, int, int) string
func slicestring1(string, int) string
func indexstring(string, int) byte
func intstring(int64) string
func slicebytetostring([]byte) string
func sliceinttostring([]int) string

View File

@ -614,7 +614,6 @@ reswitch:
if(n->right->type != T && !isint[n->right->type->etype])
yyerror("non-integer string index %#N", n->right);
n->type = types[TUINT8];
n->op = OINDEXSTR;
break;
}
goto ret;
@ -2052,6 +2051,8 @@ islvalue(Node *n)
case OINDEX:
if(isfixedarray(n->left->type))
return islvalue(n->left);
if(n->left->type != T && n->left->type->etype == TSTRING)
return 0;
// fall through
case OIND:
case ODOTPTR:

View File

@ -1033,22 +1033,35 @@ walkexpr(Node **np, NodeList **init)
// if range of type cannot exceed static array bound,
// disable bounds check
if(!isslice(n->left->type))
if(isfixedarray(n->left->type))
if(n->right->type->width < 4)
if((1<<(8*n->right->type->width)) <= n->left->type->bound)
n->etype = 1;
if(isconst(n->left, CTSTR))
if(n->right->type->width < 4)
if((1<<(8*n->right->type->width)) <= n->left->val.u.sval->len)
n->etype = 1;
// check for static out of bounds
if(isconst(n->right, CTINT) && !n->etype) {
v = mpgetfix(n->right->val.u.xval);
len = 1LL<<60;
t = n->left->type;
if(isconst(n->left, CTSTR))
len = n->left->val.u.sval->len;
if(t != T && isptr[t->etype])
t = t->type;
if(isfixedarray(t))
len = t->bound;
if(v < 0 || v >= (1LL<<31) || v >= len)
yyerror("index out of bounds");
else if(isconst(n->left, CTSTR)) {
// replace "abc"[2] with 'b'.
// delayed until now because "abc"[2] is not
// an ideal constant.
nodconst(n, n->type, n->left->val.u.sval->s[v]);
}
}
goto ret;
@ -1252,14 +1265,6 @@ walkexpr(Node **np, NodeList **init)
}
goto ret;
case OINDEXSTR:
// TODO(rsc): should be done in back end
// sys_indexstring(s, i)
n = mkcall("indexstring", n->type, init,
conv(n->left, types[TSTRING]),
conv(n->right, types[TINT]));
goto ret;
case OCOPY:
if(n->right->type->etype == TSTRING)
fn = syslook("slicestringcopy", 1);

View File

@ -200,10 +200,6 @@ func slicestring(si String, lindex int32, hindex int32) (so String) {
l = hindex-lindex;
so.str = si.str + lindex;
so.len = l;
// alternate to create a new string
// so = gostringsize(l);
// mcpy(so.str, si.str+lindex, l);
}
func slicestring1(si String, lindex int32) (so String) {
@ -216,18 +212,6 @@ func slicestring1(si String, lindex int32) (so String) {
l = si.len-lindex;
so.str = si.str + lindex;
so.len = l;
// alternate to create a new string
// so = gostringsize(l);
// mcpy(so.str, si.str+lindex, l);
}
func indexstring(s String, i int32) (b byte) {
if(i < 0 || i >= s.len) {
·panicindex();
}
b = s.str[i];
}
func intstring(v int64) (s String) {