Commit fdb030d8 authored by Russ Cox's avatar Russ Cox

6g etc: groundwork for eliminating redundant bounds checks.

	drop check in range over array.
	drop check in [256]array indexed by byte.

R=ken2
https://golang.org/cl/163088
parent dc7355a9
...@@ -547,7 +547,7 @@ agen(Node *n, Node *res) ...@@ -547,7 +547,7 @@ agen(Node *n, Node *res)
v = mpgetfix(nr->val.u.xval); v = mpgetfix(nr->val.u.xval);
if(isslice(nl->type)) { if(isslice(nl->type)) {
if(!debug['B']) { if(!debug['B'] && !n->etype) {
n1 = n3; n1 = n3;
n1.op = OINDREG; n1.op = OINDREG;
n1.type = types[tptr]; n1.type = types[tptr];
...@@ -599,7 +599,7 @@ agen(Node *n, Node *res) ...@@ -599,7 +599,7 @@ agen(Node *n, Node *res)
gmove(&n1, &n2); gmove(&n1, &n2);
regfree(&n1); regfree(&n1);
if(!debug['B']) { if(!debug['B'] && !n->etype) {
// check bounds // check bounds
regalloc(&n4, types[TUINT32], N); regalloc(&n4, types[TUINT32], N);
if(isslice(nl->type)) { if(isslice(nl->type)) {
......
...@@ -1767,7 +1767,7 @@ oindex_const: ...@@ -1767,7 +1767,7 @@ oindex_const:
v = mpgetfix(r->val.u.xval); v = mpgetfix(r->val.u.xval);
if(o & ODynam) { if(o & ODynam) {
if(!debug['B']) { if(!debug['B'] && !n->etype) {
n1 = *reg; n1 = *reg;
n1.op = OINDREG; n1.op = OINDREG;
n1.type = types[tptr]; n1.type = types[tptr];
......
...@@ -504,7 +504,7 @@ agen(Node *n, Node *res) ...@@ -504,7 +504,7 @@ agen(Node *n, Node *res)
v = mpgetfix(nr->val.u.xval); v = mpgetfix(nr->val.u.xval);
if(isslice(nl->type)) { if(isslice(nl->type)) {
if(!debug['B']) { if(!debug['B'] && !n->etype) {
n1 = n3; n1 = n3;
n1.op = OINDREG; n1.op = OINDREG;
n1.type = types[tptr]; n1.type = types[tptr];
...@@ -547,7 +547,7 @@ agen(Node *n, Node *res) ...@@ -547,7 +547,7 @@ agen(Node *n, Node *res)
gmove(&n1, &n2); gmove(&n1, &n2);
regfree(&n1); regfree(&n1);
if(!debug['B']) { if(!debug['B'] && !n->etype) {
// check bounds // check bounds
if(isslice(nl->type)) { if(isslice(nl->type)) {
n1 = n3; n1 = n3;
......
...@@ -1827,23 +1827,24 @@ oindex: ...@@ -1827,23 +1827,24 @@ oindex:
agen(l, reg); agen(l, reg);
} }
if(!(o & ODynam) && l->type->width >= unmappedzero && l->op == OIND) {
// cannot rely on page protections to
// catch array ptr == 0, so dereference.
n2 = *reg;
n2.op = OINDREG;
n2.type = types[TUINT8];
n2.xoffset = 0;
gins(ATESTB, nodintconst(0), &n2);
}
// check bounds // check bounds
if(!debug['B']) { if(!debug['B'] && !n->etype) {
if(o & ODynam) { if(o & ODynam) {
n2 = *reg; n2 = *reg;
n2.op = OINDREG; n2.op = OINDREG;
n2.type = types[tptr]; n2.type = types[tptr];
n2.xoffset = Array_nel; n2.xoffset = Array_nel;
} else { } else {
if(l->type->width >= unmappedzero && l->op == OIND) {
// cannot rely on page protections to
// catch array ptr == 0, so dereference.
n2 = *reg;
n2.op = OINDREG;
n2.type = types[TUINT8];
n2.xoffset = 0;
gins(ATESTB, nodintconst(0), &n2);
}
nodconst(&n2, types[TUINT64], l->type->bound); nodconst(&n2, types[TUINT64], l->type->bound);
} }
gins(optoas(OCMP, types[TUINT32]), reg1, &n2); gins(optoas(OCMP, types[TUINT32]), reg1, &n2);
...@@ -1879,7 +1880,7 @@ oindex_const: ...@@ -1879,7 +1880,7 @@ oindex_const:
v = mpgetfix(r->val.u.xval); v = mpgetfix(r->val.u.xval);
if(o & ODynam) { if(o & ODynam) {
if(!debug['B']) { if(!debug['B'] && !n->etype) {
n1 = *reg; n1 = *reg;
n1.op = OINDREG; n1.op = OINDREG;
n1.type = types[tptr]; n1.type = types[tptr];
......
...@@ -540,7 +540,7 @@ agen(Node *n, Node *res) ...@@ -540,7 +540,7 @@ agen(Node *n, Node *res)
v = mpgetfix(nr->val.u.xval); v = mpgetfix(nr->val.u.xval);
if(isslice(nl->type)) { if(isslice(nl->type)) {
if(!debug['B']) { if(!debug['B'] && !n->etype) {
n1 = n3; n1 = n3;
n1.op = OINDREG; n1.op = OINDREG;
n1.type = types[tptr]; n1.type = types[tptr];
...@@ -558,7 +558,7 @@ agen(Node *n, Node *res) ...@@ -558,7 +558,7 @@ agen(Node *n, Node *res)
n1.xoffset = Array_array; n1.xoffset = Array_array;
gmove(&n1, &n3); gmove(&n1, &n3);
} else } else
if(!debug['B']) { if(!debug['B'] && !n->etype) {
if(v < 0) if(v < 0)
yyerror("out of bounds on array"); yyerror("out of bounds on array");
else else
...@@ -583,7 +583,7 @@ agen(Node *n, Node *res) ...@@ -583,7 +583,7 @@ agen(Node *n, Node *res)
gmove(&n1, &n2); gmove(&n1, &n2);
regfree(&n1); regfree(&n1);
if(!debug['B']) { if(!debug['B'] && !n->etype) {
// check bounds // check bounds
if(isslice(nl->type)) { if(isslice(nl->type)) {
n1 = n3; n1 = n3;
......
...@@ -91,7 +91,7 @@ walkrange(Node *n) ...@@ -91,7 +91,7 @@ walkrange(Node *n)
Node *ohv1, *hv1, *hv2; // hidden (old) val 1, 2 Node *ohv1, *hv1, *hv2; // hidden (old) val 1, 2
Node *ha, *hit; // hidden aggregate, iterator Node *ha, *hit; // hidden aggregate, iterator
Node *a, *v1, *v2; // not hidden aggregate, val 1, 2 Node *a, *v1, *v2; // not hidden aggregate, val 1, 2
Node *fn; Node *fn, *tmp;
NodeList *body, *init; NodeList *body, *init;
Type *th, *t; Type *th, *t;
...@@ -128,8 +128,11 @@ walkrange(Node *n) ...@@ -128,8 +128,11 @@ walkrange(Node *n)
n->nincr = nod(OASOP, hv1, nodintconst(1)); n->nincr = nod(OASOP, hv1, nodintconst(1));
n->nincr->etype = OADD; n->nincr->etype = OADD;
body = list1(nod(OAS, v1, hv1)); body = list1(nod(OAS, v1, hv1));
if(v2) if(v2) {
body = list(body, nod(OAS, v2, nod(OINDEX, ha, hv1))); tmp = nod(OINDEX, ha, hv1);
tmp->etype = 1; // no bounds check
body = list(body, nod(OAS, v2, tmp));
}
break; break;
case TMAP: case TMAP:
......
...@@ -787,6 +787,14 @@ walkexpr(Node **np, NodeList **init) ...@@ -787,6 +787,14 @@ walkexpr(Node **np, NodeList **init)
case OINDEX: case OINDEX:
walkexpr(&n->left, init); walkexpr(&n->left, init);
walkexpr(&n->right, init); walkexpr(&n->right, init);
// if range of type cannot exceed static array bound,
// disable bounds check
if(!isslice(n->left->type))
if(n->right->type->width < 4)
if((1<<(8*n->right->type->width)) <= n->left->type->bound)
n->etype = 1;
goto ret; goto ret;
case OINDEXMAP: case OINDEXMAP:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment