1
0
mirror of https://github.com/golang/go synced 2024-11-21 23:44:39 -07:00

cmd/6g, cmd/8g: do not LEA[LQ] interfaces when calling methods.

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
This commit is contained in:
Rémy Oudompheng 2012-09-11 08:45:23 +02:00
parent ff642e290f
commit b45b6fd1c7
2 changed files with 32 additions and 28 deletions

View 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
nodi.type = types[tptr];
nodi.xoffset += widthptr;
cgen(&nodi, &nodsp); // 0(SP) = 8(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 = 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:
;
}
/*

View 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]