mirror of
https://github.com/golang/go
synced 2024-11-25 14:57:57 -07:00
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
This commit is contained in:
parent
dc7355a974
commit
fdb030d86f
@ -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)
|
|||||||
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:
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,15 +1827,7 @@ oindex:
|
|||||||
agen(l, reg);
|
agen(l, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check bounds
|
if(!(o & ODynam) && l->type->width >= unmappedzero && l->op == OIND) {
|
||||||
if(!debug['B']) {
|
|
||||||
if(o & ODynam) {
|
|
||||||
n2 = *reg;
|
|
||||||
n2.op = OINDREG;
|
|
||||||
n2.type = types[tptr];
|
|
||||||
n2.xoffset = Array_nel;
|
|
||||||
} else {
|
|
||||||
if(l->type->width >= unmappedzero && l->op == OIND) {
|
|
||||||
// cannot rely on page protections to
|
// cannot rely on page protections to
|
||||||
// catch array ptr == 0, so dereference.
|
// catch array ptr == 0, so dereference.
|
||||||
n2 = *reg;
|
n2 = *reg;
|
||||||
@ -1844,6 +1836,15 @@ oindex:
|
|||||||
n2.xoffset = 0;
|
n2.xoffset = 0;
|
||||||
gins(ATESTB, nodintconst(0), &n2);
|
gins(ATESTB, nodintconst(0), &n2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check bounds
|
||||||
|
if(!debug['B'] && !n->etype) {
|
||||||
|
if(o & ODynam) {
|
||||||
|
n2 = *reg;
|
||||||
|
n2.op = OINDREG;
|
||||||
|
n2.type = types[tptr];
|
||||||
|
n2.xoffset = Array_nel;
|
||||||
|
} else {
|
||||||
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:
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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:
|
||||||
|
Loading…
Reference in New Issue
Block a user