From ff642e290f8e8ced8be26324838febda2ae3c534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Oudompheng?= Date: Tue, 11 Sep 2012 08:08:40 +0200 Subject: [PATCH] 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 --- src/cmd/6g/cgen.c | 28 +++++++++++----------------- src/cmd/8g/cgen.c | 22 ++++++++-------------- 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c index 05e7ac7a26..1839040f20 100644 --- a/src/cmd/6g/cgen.c +++ b/src/cmd/6g/cgen.c @@ -978,41 +978,35 @@ bgen(Node *n, int true, int likely, Prog *to) nl = nr; nr = r; } - + 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; diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c index 3ef75712c0..fc9c183beb 100644 --- a/src/cmd/8g/cgen.c +++ b/src/cmd/8g/cgen.c @@ -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;