mirror of
https://github.com/golang/go
synced 2024-11-22 06:44:40 -07:00
gc: generalize dst = append(src,...) inlining to arbitrary src and dst arguments.
R=rsc CC=golang-dev https://golang.org/cl/4517057
This commit is contained in:
parent
ba006e6b6a
commit
36cec789cd
@ -22,7 +22,6 @@ char *runtimeimport =
|
|||||||
"func \"\".printsp ()\n"
|
"func \"\".printsp ()\n"
|
||||||
"func \"\".goprintf ()\n"
|
"func \"\".goprintf ()\n"
|
||||||
"func \"\".concatstring ()\n"
|
"func \"\".concatstring ()\n"
|
||||||
"func \"\".append ()\n"
|
|
||||||
"func \"\".appendslice (typ *uint8, x any, y []any) any\n"
|
"func \"\".appendslice (typ *uint8, x any, y []any) any\n"
|
||||||
"func \"\".cmpstring (? string, ? string) int\n"
|
"func \"\".cmpstring (? string, ? string) int\n"
|
||||||
"func \"\".slicestring (? string, ? int, ? int) string\n"
|
"func \"\".slicestring (? string, ? int, ? int) string\n"
|
||||||
|
@ -20,7 +20,6 @@ static NodeList* reorder3(NodeList*);
|
|||||||
static Node* addstr(Node*, NodeList**);
|
static Node* addstr(Node*, NodeList**);
|
||||||
static Node* appendslice(Node*, NodeList**);
|
static Node* appendslice(Node*, NodeList**);
|
||||||
static Node* append(Node*, NodeList**);
|
static Node* append(Node*, NodeList**);
|
||||||
static int oasappend(Node**, NodeList**);
|
|
||||||
|
|
||||||
static NodeList* walkdefstack;
|
static NodeList* walkdefstack;
|
||||||
|
|
||||||
@ -811,9 +810,6 @@ walkexpr(Node **np, NodeList **init)
|
|||||||
if(oaslit(n, init))
|
if(oaslit(n, init))
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
if (oasappend(&n, init))
|
|
||||||
goto ret;
|
|
||||||
|
|
||||||
walkexpr(&n->right, init);
|
walkexpr(&n->right, init);
|
||||||
if(n->left != N && n->right != N) {
|
if(n->left != N && n->right != N) {
|
||||||
r = convas(nod(OAS, n->left, n->right), init);
|
r = convas(nod(OAS, n->left, n->right), init);
|
||||||
@ -2381,41 +2377,10 @@ appendslice(Node *n, NodeList **init)
|
|||||||
return mkcall1(f, n->type, init, typename(n->type), n->list->n, n->list->next->n);
|
return mkcall1(f, n->type, init, typename(n->type), n->list->n, n->list->next->n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Node*
|
// expand append(src, a [, b]* ) to
|
||||||
append(Node *n, NodeList **init)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
Node *f, *r;
|
|
||||||
NodeList *in, *args;
|
|
||||||
|
|
||||||
j = count(n->list) - 1;
|
|
||||||
f = syslook("append", 1);
|
|
||||||
f->type = T;
|
|
||||||
f->ntype = nod(OTFUNC, N, N);
|
|
||||||
in = list1(nod(ODCLFIELD, N, typenod(ptrto(types[TUINT8])))); // type
|
|
||||||
in = list(in, nod(ODCLFIELD, N, typenod(types[TINT]))); // count
|
|
||||||
in = list(in, nod(ODCLFIELD, N, typenod(n->type))); // slice
|
|
||||||
for(i=0; i<j; i++)
|
|
||||||
in = list(in, nod(ODCLFIELD, N, typenod(n->type->type)));
|
|
||||||
f->ntype->list = in;
|
|
||||||
f->ntype->rlist = list1(nod(ODCLFIELD, N, typenod(n->type)));
|
|
||||||
|
|
||||||
args = list1(typename(n->type));
|
|
||||||
args = list(args, nodintconst(j));
|
|
||||||
args = concat(args, n->list);
|
|
||||||
|
|
||||||
r = nod(OCALL, f, N);
|
|
||||||
r->list = args;
|
|
||||||
typecheck(&r, Erv);
|
|
||||||
walkexpr(&r, init);
|
|
||||||
r->type = n->type;
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// expand s = append(s, a [, b]* ) to
|
|
||||||
//
|
//
|
||||||
|
// init {
|
||||||
|
// s := src
|
||||||
// const argc = len(args) - 1
|
// const argc = len(args) - 1
|
||||||
// if cap(s) - len(s) < argc {
|
// if cap(s) - len(s) < argc {
|
||||||
// s = growslice(s, argc)
|
// s = growslice(s, argc)
|
||||||
@ -2425,33 +2390,31 @@ append(Node *n, NodeList **init)
|
|||||||
// s[n] = a
|
// s[n] = a
|
||||||
// s[n+1] = b
|
// s[n+1] = b
|
||||||
// ...
|
// ...
|
||||||
//
|
// }
|
||||||
static int
|
// s
|
||||||
oasappend(Node **np, NodeList **init)
|
static Node*
|
||||||
|
append(Node *n, NodeList **init)
|
||||||
{
|
{
|
||||||
NodeList *l, *a;
|
NodeList *l, *a;
|
||||||
Node *n, *ns, *nn, *na, *nx, *fn;
|
Node *nsrc, *ns, *nn, *na, *nx, *fn;
|
||||||
int argc;
|
int argc;
|
||||||
|
|
||||||
n = *np;
|
walkexprlistsafe(n->list, init);
|
||||||
|
|
||||||
// Check that it's an assignment of the form s = append(s, elem), where s is ONAME.
|
nsrc = n->list->n;
|
||||||
if (n->right == N || n->right->op != OAPPEND || n->right->isddd ||
|
argc = count(n->list) - 1;
|
||||||
n->left == N || n->left->op != ONAME || n->left != n->right->list->n)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ns = cheapexpr(n->left, init);
|
|
||||||
walkexprlistsafe(n->right->list, init);
|
|
||||||
argc = count(n->right->list) - 1;
|
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
n->op = OEMPTY;
|
return nsrc;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
na = nodintconst(argc); // const argc
|
l = nil;
|
||||||
|
|
||||||
|
ns = nod(OXXX, N, N); // var s
|
||||||
|
tempname(ns, nsrc->type);
|
||||||
|
l = list(l, nod(OAS, ns, nsrc)); // s = src
|
||||||
|
|
||||||
|
na = nodintconst(argc); // const argc
|
||||||
nx = nod(OIF, N, N); // if cap(s) - len(s) < argc
|
nx = nod(OIF, N, N); // if cap(s) - len(s) < argc
|
||||||
nx->lineno = n->lineno;
|
|
||||||
nx->ntest = nod(OLT, nod(OSUB, nod(OCAP, ns, N), nod(OLEN, ns, N)), na);
|
nx->ntest = nod(OLT, nod(OSUB, nod(OCAP, ns, N), nod(OLEN, ns, N)), na);
|
||||||
|
|
||||||
fn = syslook("growslice", 1); // growslice(<type>, old []T, n int64) (ret []T)
|
fn = syslook("growslice", 1); // growslice(<type>, old []T, n int64) (ret []T)
|
||||||
@ -2462,7 +2425,7 @@ oasappend(Node **np, NodeList **init)
|
|||||||
typename(ns->type),
|
typename(ns->type),
|
||||||
ns,
|
ns,
|
||||||
conv(na, types[TINT64]))));
|
conv(na, types[TINT64]))));
|
||||||
l = list1(nx);
|
l = list(l, nx);
|
||||||
|
|
||||||
nn = nod(OXXX, N, N); // var n
|
nn = nod(OXXX, N, N); // var n
|
||||||
tempname(nn, types[TINT]);
|
tempname(nn, types[TINT]);
|
||||||
@ -2472,7 +2435,7 @@ oasappend(Node **np, NodeList **init)
|
|||||||
nx->etype = 1; // disable bounds check
|
nx->etype = 1; // disable bounds check
|
||||||
l = list(l, nod(OAS, ns, nx)); // s = s[:n+argc]
|
l = list(l, nod(OAS, ns, nx)); // s = s[:n+argc]
|
||||||
|
|
||||||
for (a = n->right->list->next; a != nil; a = a->next) {
|
for (a = n->list->next; a != nil; a = a->next) {
|
||||||
nx = nod(OINDEX, ns, nn); // s[n] ...
|
nx = nod(OINDEX, ns, nn); // s[n] ...
|
||||||
nx->etype = 1; // disable bounds check
|
nx->etype = 1; // disable bounds check
|
||||||
l = list(l, nod(OAS, nx, a->n)); // s[n] = arg
|
l = list(l, nod(OAS, nx, a->n)); // s[n] = arg
|
||||||
@ -2481,8 +2444,7 @@ oasappend(Node **np, NodeList **init)
|
|||||||
}
|
}
|
||||||
|
|
||||||
typechecklist(l, Etop);
|
typechecklist(l, Etop);
|
||||||
*np = liststmt(l);
|
walkstmtlist(l);
|
||||||
|
*init = concat(*init, l);
|
||||||
walkstmt(np);
|
return ns;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
@ -48,20 +48,6 @@ makeslice1(SliceType *t, int32 len, int32 cap, Slice *ret)
|
|||||||
ret->array = runtime·mal(size);
|
ret->array = runtime·mal(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// append(type *Type, n int, old []T, ...,) []T
|
|
||||||
#pragma textflag 7
|
|
||||||
void
|
|
||||||
runtime·append(SliceType *t, int32 n, Slice old, ...)
|
|
||||||
{
|
|
||||||
Slice sl;
|
|
||||||
Slice *ret;
|
|
||||||
|
|
||||||
sl.len = n;
|
|
||||||
sl.array = (byte*)(&old+1);
|
|
||||||
ret = (Slice*)(sl.array + ((t->elem->size*n+sizeof(uintptr)-1) & ~(sizeof(uintptr)-1)));
|
|
||||||
appendslice1(t, old, sl, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
// appendslice(type *Type, x, y, []T) []T
|
// appendslice(type *Type, x, y, []T) []T
|
||||||
void
|
void
|
||||||
runtime·appendslice(SliceType *t, Slice x, Slice y, Slice ret)
|
runtime·appendslice(SliceType *t, Slice x, Slice y, Slice ret)
|
||||||
|
Loading…
Reference in New Issue
Block a user