]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/6c: Optimize rotate expressions to use rotate instructions.
authorMatthew Dempsky <mdempsky@google.com>
Fri, 18 Jan 2013 22:29:53 +0000 (17:29 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 18 Jan 2013 22:29:53 +0000 (17:29 -0500)
For simplicity, only recognizes expressions of the exact form
"(x << a) | (x >> b)" where x is a variable and a and b are
integer constant expressions that add to x's bit width.

Fixes #4629.

$ cat rotate.c
unsigned int
rotate(unsigned int x)
{
        x = (x << 3) | (x >> (sizeof(x) * 8 - 3));
        return x;
}

## BEFORE
$ go tool 6c -S rotate.c
(rotate.c:2) TEXT rotate+0(SB),$0-8
(rotate.c:2) MOVL x+0(FP),!!DX
(rotate.c:4) MOVL DX,!!AX
(rotate.c:4) SALL $3,!!AX
(rotate.c:4) MOVL DX,!!CX
(rotate.c:4) SHRL $29,!!CX
(rotate.c:4) ORL CX,!!AX
(rotate.c:5) RET ,!!
(rotate.c:5) RET ,!!
(rotate.c:5) END ,!!

## AFTER
$ go tool 6c -S rotate.c
(rotate.c:2) TEXT rotate+0(SB),$0-8
(rotate.c:4) MOVL x+0(FP),!!AX
(rotate.c:4) ROLL $3,!!AX
(rotate.c:5) RET ,!!
(rotate.c:5) RET ,!!
(rotate.c:5) END ,!!

R=rsc, minux.ma
CC=golang-dev
https://golang.org/cl/7069056

src/cmd/6c/cgen.c
src/cmd/6c/txt.c
src/cmd/8c/cgen.c
src/cmd/8c/txt.c
src/cmd/cc/cc.h
src/cmd/cc/sub.c

index 1fe0156c64b59a46d8a27b2adcc8f5c98826d4c2..95400c445357e317892b1d6e84fb1836b1ad607d 100644 (file)
@@ -265,6 +265,18 @@ cgen(Node *n, Node *nn)
                                break;
                        }
                }
+               if(n->op == OOR && l->op == OASHL && r->op == OLSHR
+               && l->right->op == OCONST && r->right->op == OCONST
+               && l->left->op == ONAME && r->left->op == ONAME
+               && l->left->sym == r->left->sym
+               && l->right->vconst + r->right->vconst == 8 * l->left->type->width) {
+                       regalloc(&nod, l->left, nn);
+                       cgen(l->left, &nod);
+                       gopcode(OROTL, n->type, l->right, &nod);
+                       gmove(&nod, nn);
+                       regfree(&nod);
+                       break;
+               }
                if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
                && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
                        c = l->right->vconst;
index fcc97ee6ecc091f4712a1e382e630ad918be4bfc..364b189f271e30a254b465d31fdbb841a768c145 100644 (file)
@@ -1360,6 +1360,16 @@ gopcode(int o, Type *ty, Node *f, Node *t)
                        a = ASALQ;
                break;
 
+       case OROTL:
+               a = AROLL;
+               if(et == TCHAR || et == TUCHAR)
+                       a = AROLB;
+               if(et == TSHORT || et == TUSHORT)
+                       a = AROLW;
+               if(et == TVLONG || et == TUVLONG || et == TIND)
+                       a = AROLQ;
+               break;
+
        case OFUNC:
                a = ACALL;
                break;
index 7a49b671ca3a7729f3b69497086fb479d169b838..78eb7ecedb3b7f6f4b71d8d748bf9a0c519f576c 100644 (file)
@@ -277,6 +277,18 @@ cgen(Node *n, Node *nn)
                                break;
                        }
                }
+               if(n->op == OOR && l->op == OASHL && r->op == OLSHR
+               && l->right->op == OCONST && r->right->op == OCONST
+               && l->left->op == ONAME && r->left->op == ONAME
+               && l->left->sym == r->left->sym
+               && l->right->vconst + r->right->vconst == 8 * l->left->type->width) {
+                       regalloc(&nod, l->left, nn);
+                       cgen(l->left, &nod);
+                       gopcode(OROTL, n->type, l->right, &nod);
+                       gmove(&nod, nn);
+                       regfree(&nod);
+                       break;
+               }
                if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
                && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
                        c = l->right->vconst;
index d229462da34eef6f9cf335af69902b62b490607f..d7873e385536b38c64dca0d35db57a2bf8f91c73 100644 (file)
@@ -1253,6 +1253,14 @@ gopcode(int o, Type *ty, Node *f, Node *t)
                        a = ASALW;
                break;
 
+       case OROTL:
+               a = AROLL;
+               if(et == TCHAR || et == TUCHAR)
+                       a = AROLB;
+               if(et == TSHORT || et == TUSHORT)
+                       a = AROLW;
+               break;
+
        case OFUNC:
                a = ACALL;
                break;
index 6153bf9f75a9427719aa100a6869b94f62b45114..f9e1546ca3148ecc02b22d2ea9490db284d3f6dc 100644 (file)
@@ -325,6 +325,7 @@ enum
        OINDEX,
        OFAS,
        OREGPAIR,
+       OROTL,
 
        OEND
 };
index 9f124cb8206f56e1be4805a1a0e378ea1e1a5348..3a55763859a8d75d6f2f47d0acdb5a83ff0036f9 100644 (file)
@@ -1515,6 +1515,7 @@ Init      onamesinit[] =
        OINDEX,         0,      "INDEX",
        OFAS,           0,      "FAS",
        OREGPAIR,       0,      "REGPAIR",
+       OROTL,          0,      "ROTL",
        OEND,           0,      "END",
        -1,             0,      0,
 };