]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/6g, cmd/8g: do not LEA[LQ] interfaces when calling methods.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Tue, 11 Sep 2012 06:45:23 +0000 (08:45 +0200)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Tue, 11 Sep 2012 06:45:23 +0000 (08:45 +0200)
It is enough to load directly the data word and the itab word
from memory, so we save a LEA instruction for each method call,
and allow elimination of some extra temporaries.

Update #1914.

R=daniel.morsing, rsc
CC=golang-dev, remy
https://golang.org/cl/6501110

src/cmd/6g/ggen.c
src/cmd/8g/ggen.c

index 73577a7f3de3e1ecfb7ea7783b5c0749a7618033..193cb08ffbafe8603f9b732e032af9930cb0bab6 100644 (file)
@@ -105,7 +105,7 @@ void
 cgen_callinter(Node *n, Node *res, int proc)
 {
        Node *i, *f;
-       Node tmpi, nodo, nodr, nodsp;
+       Node tmpi, nodi, nodo, nodr, nodsp;
 
        i = n->left;
        if(i->op != ODOTINTER)
@@ -125,19 +125,25 @@ cgen_callinter(Node *n, Node *res, int proc)
 
        genlist(n->list);               // assign the args
 
-       regalloc(&nodr, types[tptr], res);
-       regalloc(&nodo, types[tptr], &nodr);
-       nodo.op = OINDREG;
-
-       agen(i, &nodr);         // REG = &inter
+       // i is now addable, prepare an indirected
+       // register to hold its address.
+       igen(i, &nodi, res);            // REG = &inter
 
        nodindreg(&nodsp, types[tptr], D_SP);
-       nodo.xoffset += widthptr;
-       cgen(&nodo, &nodsp);    // 0(SP) = 8(REG) -- i.data
-
-       nodo.xoffset -= widthptr;
-       cgen(&nodo, &nodr);     // REG = 0(REG) -- i.tab
-
+       nodi.type = types[tptr];
+       nodi.xoffset += widthptr;
+       cgen(&nodi, &nodsp);    // 0(SP) = 8(REG) -- i.data
+
+       regalloc(&nodo, types[tptr], res);
+       nodi.type = types[tptr];
+       nodi.xoffset -= widthptr;
+       cgen(&nodi, &nodo);     // REG = 0(REG) -- i.tab
+       regfree(&nodi);
+
+       regalloc(&nodr, types[tptr], &nodo);
+       if(n->left->xoffset == BADWIDTH)
+               fatal("cgen_callinter: badwidth");
+       nodo.op = OINDREG;
        nodo.xoffset = n->left->xoffset + 3*widthptr + 8;
        cgen(&nodo, &nodr);     // REG = 32+offset(REG) -- i.tab->fun[f]
 
@@ -185,7 +191,7 @@ cgen_call(Node *n, int proc)
                nod.type = t;
                ginscall(&nod, proc);
                regfree(&nod);
-               goto ret;
+               return;
        }
 
        // call pointer
@@ -195,16 +201,12 @@ cgen_call(Node *n, int proc)
                nod.type = t;
                ginscall(&nod, proc);
                regfree(&nod);
-               goto ret;
+               return;
        }
 
        // call direct
        n->left->method = 1;
        ginscall(n->left, proc);
-
-
-ret:
-       ;
 }
 
 /*
index a31f660740c9dcfb101235801d25836fd57ad5f1..fde94fc15642f2a894287a0d4bd077a32d35c7c8 100644 (file)
@@ -146,7 +146,7 @@ void
 cgen_callinter(Node *n, Node *res, int proc)
 {
        Node *i, *f;
-       Node tmpi, nodo, nodr, nodsp;
+       Node tmpi, nodi, nodo, nodr, nodsp;
 
        i = n->left;
        if(i->op != ODOTINTER)
@@ -166,23 +166,25 @@ cgen_callinter(Node *n, Node *res, int proc)
 
        genlist(n->list);               // assign the args
 
-       // Can regalloc now; i is known to be addable,
-       // so the agen will be easy.
-       regalloc(&nodr, types[tptr], res);
-       regalloc(&nodo, types[tptr], &nodr);
-       nodo.op = OINDREG;
-
-       agen(i, &nodr);         // REG = &inter
+       // i is now addable, prepare an indirected
+       // register to hold its address.
+       igen(i, &nodi, res);            // REG = &inter
 
        nodindreg(&nodsp, types[tptr], D_SP);
-       nodo.xoffset += widthptr;
-       cgen(&nodo, &nodsp);    // 0(SP) = 4(REG) -- i.data
+       nodi.type = types[tptr];
+       nodi.xoffset += widthptr;
+       cgen(&nodi, &nodsp);    // 0(SP) = 4(REG) -- i.data
 
-       nodo.xoffset -= widthptr;
-       cgen(&nodo, &nodr);     // REG = 0(REG) -- i.tab
+       regalloc(&nodo, types[tptr], res);
+       nodi.type = types[tptr];
+       nodi.xoffset -= widthptr;
+       cgen(&nodi, &nodo);     // REG = 0(REG) -- i.tab
+       regfree(&nodi);
 
+       regalloc(&nodr, types[tptr], &nodo);
        if(n->left->xoffset == BADWIDTH)
                fatal("cgen_callinter: badwidth");
+       nodo.op = OINDREG;
        nodo.xoffset = n->left->xoffset + 3*widthptr + 8;
        cgen(&nodo, &nodr);     // REG = 20+offset(REG) -- i.tab->fun[f]