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:
parent
ff642e290f
commit
b45b6fd1c7
@ -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:
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user