Commit b45b6fd1 authored by Rémy Oudompheng's avatar Rémy Oudompheng

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
parent ff642e29
...@@ -105,7 +105,7 @@ void ...@@ -105,7 +105,7 @@ void
cgen_callinter(Node *n, Node *res, int proc) cgen_callinter(Node *n, Node *res, int proc)
{ {
Node *i, *f; Node *i, *f;
Node tmpi, nodo, nodr, nodsp; Node tmpi, nodi, nodo, nodr, nodsp;
i = n->left; i = n->left;
if(i->op != ODOTINTER) if(i->op != ODOTINTER)
...@@ -125,19 +125,25 @@ cgen_callinter(Node *n, Node *res, int proc) ...@@ -125,19 +125,25 @@ cgen_callinter(Node *n, Node *res, int proc)
genlist(n->list); // assign the args genlist(n->list); // assign the args
regalloc(&nodr, types[tptr], res); // i is now addable, prepare an indirected
regalloc(&nodo, types[tptr], &nodr); // register to hold its address.
nodo.op = OINDREG; igen(i, &nodi, res); // REG = &inter
agen(i, &nodr); // REG = &inter
nodindreg(&nodsp, types[tptr], D_SP); nodindreg(&nodsp, types[tptr], D_SP);
nodo.xoffset += widthptr; nodi.type = types[tptr];
cgen(&nodo, &nodsp); // 0(SP) = 8(REG) -- i.data 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; nodo.xoffset = n->left->xoffset + 3*widthptr + 8;
cgen(&nodo, &nodr); // REG = 32+offset(REG) -- i.tab->fun[f] cgen(&nodo, &nodr); // REG = 32+offset(REG) -- i.tab->fun[f]
...@@ -185,7 +191,7 @@ cgen_call(Node *n, int proc) ...@@ -185,7 +191,7 @@ cgen_call(Node *n, int proc)
nod.type = t; nod.type = t;
ginscall(&nod, proc); ginscall(&nod, proc);
regfree(&nod); regfree(&nod);
goto ret; return;
} }
// call pointer // call pointer
...@@ -195,16 +201,12 @@ cgen_call(Node *n, int proc) ...@@ -195,16 +201,12 @@ cgen_call(Node *n, int proc)
nod.type = t; nod.type = t;
ginscall(&nod, proc); ginscall(&nod, proc);
regfree(&nod); regfree(&nod);
goto ret; return;
} }
// call direct // call direct
n->left->method = 1; n->left->method = 1;
ginscall(n->left, proc); ginscall(n->left, proc);
ret:
;
} }
/* /*
......
...@@ -146,7 +146,7 @@ void ...@@ -146,7 +146,7 @@ void
cgen_callinter(Node *n, Node *res, int proc) cgen_callinter(Node *n, Node *res, int proc)
{ {
Node *i, *f; Node *i, *f;
Node tmpi, nodo, nodr, nodsp; Node tmpi, nodi, nodo, nodr, nodsp;
i = n->left; i = n->left;
if(i->op != ODOTINTER) if(i->op != ODOTINTER)
...@@ -166,23 +166,25 @@ cgen_callinter(Node *n, Node *res, int proc) ...@@ -166,23 +166,25 @@ cgen_callinter(Node *n, Node *res, int proc)
genlist(n->list); // assign the args genlist(n->list); // assign the args
// Can regalloc now; i is known to be addable, // i is now addable, prepare an indirected
// so the agen will be easy. // register to hold its address.
regalloc(&nodr, types[tptr], res); igen(i, &nodi, res); // REG = &inter
regalloc(&nodo, types[tptr], &nodr);
nodo.op = OINDREG;
agen(i, &nodr); // REG = &inter
nodindreg(&nodsp, types[tptr], D_SP); nodindreg(&nodsp, types[tptr], D_SP);
nodo.xoffset += widthptr; nodi.type = types[tptr];
cgen(&nodo, &nodsp); // 0(SP) = 4(REG) -- i.data nodi.xoffset += widthptr;
cgen(&nodi, &nodsp); // 0(SP) = 4(REG) -- i.data
nodo.xoffset -= widthptr; regalloc(&nodo, types[tptr], res);
cgen(&nodo, &nodr); // REG = 0(REG) -- i.tab 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) if(n->left->xoffset == BADWIDTH)
fatal("cgen_callinter: badwidth"); fatal("cgen_callinter: badwidth");
nodo.op = OINDREG;
nodo.xoffset = n->left->xoffset + 3*widthptr + 8; nodo.xoffset = n->left->xoffset + 3*widthptr + 8;
cgen(&nodo, &nodr); // REG = 20+offset(REG) -- i.tab->fun[f] cgen(&nodo, &nodr); // REG = 20+offset(REG) -- i.tab->fun[f]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment