1
0
mirror of https://github.com/golang/go synced 2024-11-12 05:40:22 -07:00

cmd/6g, cmd/8g: eliminate extra agen for nil comparisons.

Removes an extra LEAL/LEAQ instructions there and usually saves
a useless temporary in the idiom
    if err := foo(); err != nil {...}

Generated code is also less involved:
    MOVQ err+n(SP), AX
    CMPQ AX, $0
(potentially CMPQ n(SP), $0) instead of
    LEAQ err+n(SP), AX
    CMPQ (AX), $0

Update #1914.

R=daniel.morsing, nigeltao, rsc
CC=golang-dev, remy
https://golang.org/cl/6493099
This commit is contained in:
Rémy Oudompheng 2012-09-11 08:08:40 +02:00
parent b19c32acce
commit ff642e290f
2 changed files with 19 additions and 31 deletions

View File

@ -980,39 +980,33 @@ bgen(Node *n, int true, int likely, Prog *to)
}
if(isslice(nl->type)) {
// only valid to cmp darray to literal nil
// front end should only leave cmp to literal nil
if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
yyerror("illegal array comparison");
yyerror("illegal slice comparison");
break;
}
a = optoas(a, types[tptr]);
regalloc(&n1, types[tptr], N);
agen(nl, &n1);
n2 = n1;
n2.op = OINDREG;
n2.xoffset = Array_array;
n2.type = types[tptr];
igen(nl, &n1, N);
n1.xoffset += Array_array;
n1.type = types[tptr];
nodconst(&tmp, types[tptr], 0);
gins(optoas(OCMP, types[tptr]), &n2, &tmp);
gins(optoas(OCMP, types[tptr]), &n1, &tmp);
patch(gbranch(a, types[tptr], likely), to);
regfree(&n1);
break;
}
if(isinter(nl->type)) {
// front end shold only leave cmp to literal nil
// front end should only leave cmp to literal nil
if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
yyerror("illegal interface comparison");
break;
}
a = optoas(a, types[tptr]);
regalloc(&n1, types[tptr], N);
agen(nl, &n1);
n2 = n1;
n2.op = OINDREG;
n2.xoffset = 0;
igen(nl, &n1, N);
n1.type = types[tptr];
nodconst(&tmp, types[tptr], 0);
gins(optoas(OCMP, types[tptr]), &n2, &tmp);
gins(optoas(OCMP, types[tptr]), &n1, &tmp);
patch(gbranch(a, types[tptr], likely), to);
regfree(&n1);
break;

View File

@ -969,18 +969,15 @@ bgen(Node *n, int true, int likely, Prog *to)
if(isslice(nl->type)) {
// front end should only leave cmp to literal nil
if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
yyerror("illegal array comparison");
yyerror("illegal slice comparison");
break;
}
a = optoas(a, types[tptr]);
regalloc(&n1, types[tptr], N);
agen(nl, &n1);
n2 = n1;
n2.op = OINDREG;
n2.xoffset = Array_array;
n2.type = types[tptr];
igen(nl, &n1, N);
n1.xoffset += Array_array;
n1.type = types[tptr];
nodconst(&tmp, types[tptr], 0);
gins(optoas(OCMP, types[tptr]), &n2, &tmp);
gins(optoas(OCMP, types[tptr]), &n1, &tmp);
patch(gbranch(a, types[tptr], likely), to);
regfree(&n1);
break;
@ -993,13 +990,10 @@ bgen(Node *n, int true, int likely, Prog *to)
break;
}
a = optoas(a, types[tptr]);
regalloc(&n1, types[tptr], N);
agen(nl, &n1);
n2 = n1;
n2.op = OINDREG;
n2.xoffset = 0;
igen(nl, &n1, N);
n1.type = types[tptr];
nodconst(&tmp, types[tptr], 0);
gins(optoas(OCMP, types[tptr]), &n2, &tmp);
gins(optoas(OCMP, types[tptr]), &n1, &tmp);
patch(gbranch(a, types[tptr], likely), to);
regfree(&n1);
break;