Commit ff642e29 authored by Rémy Oudompheng's avatar Rémy Oudompheng

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