5g, 6g, 8g: generate code for string index
instead of calling function.
R=ken2
CC=golang-dev
https://golang.org/cl/2762041
diff --git a/src/cmd/gc/builtin.c.boot b/src/cmd/gc/builtin.c.boot
index bb1a5f5..10559a9 100644
--- a/src/cmd/gc/builtin.c.boot
+++ b/src/cmd/gc/builtin.c.boot
@@ -24,7 +24,6 @@
"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"
diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c
index d2396aa..65861c7 100644
--- a/src/cmd/gc/gen.c
+++ b/src/cmd/gc/gen.c
@@ -652,7 +652,6 @@
snprint(namebuf, sizeof(namebuf), "autotmp_%.4d", statuniqgen);
statuniqgen++;
s = lookup(namebuf);
-
memset(n, 0, sizeof(*n));
n->op = ONAME;
n->sym = s;
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index 78472d2..91a1562 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -369,7 +369,7 @@
ODOTTYPE2,
OEQ, ONE, OLT, OLE, OGE, OGT,
OIND,
- OINDEX, OINDEXSTR, OINDEXMAP,
+ OINDEX, OINDEXMAP,
OKEY, OPARAM,
OLEN,
OMAKE, OMAKECHAN, OMAKEMAP, OMAKESLICE,
diff --git a/src/cmd/gc/print.c b/src/cmd/gc/print.c
index 32e8b7d..478aa84 100644
--- a/src/cmd/gc/print.c
+++ b/src/cmd/gc/print.c
@@ -59,6 +59,9 @@
case OPRINT:
case OPRINTN:
case OCALL:
+ case OCALLMETH:
+ case OCALLINTER:
+ case OCALLFUNC:
case OCONV:
case OCONVNOP:
case OMAKESLICE:
@@ -72,6 +75,8 @@
case ORECV:
case OCONVIFACE:
case OTPAREN:
+ case OINDEX:
+ case OINDEXMAP:
nprec = 7;
break;
@@ -328,7 +333,6 @@
case OINDEX:
case OINDEXMAP:
- case OINDEXSTR:
exprfmt(f, n->left, 7);
fmtprint(f, "[");
exprfmt(f, n->right, 0);
diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go
index 2279384..1be706f 100644
--- a/src/cmd/gc/runtime.go
+++ b/src/cmd/gc/runtime.go
@@ -39,7 +39,6 @@
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
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
index 6148337..c4f0826 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -614,7 +614,6 @@
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 @@
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:
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index bf20102..757b6d9 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -1033,22 +1033,35 @@
// 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 @@
}
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);