LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include <u.h> | 5 #include <u.h> |
6 #include <libc.h> | 6 #include <libc.h> |
7 #include "go.h" | 7 #include "go.h" |
8 | 8 |
9 static Node* walkprint(Node*, NodeList**, int); | 9 static Node* walkprint(Node*, NodeList**, int); |
10 static Node* mapfn(char*, Type*); | 10 static Node* mapfn(char*, Type*); |
11 static Node* mapfndel(char*, Type*); | 11 static Node* mapfndel(char*, Type*); |
12 static Node* ascompatee1(int, Node*, Node*, NodeList**); | 12 static Node* ascompatee1(int, Node*, Node*, NodeList**); |
13 static NodeList* ascompatee(int, NodeList*, NodeList*, NodeList**); | 13 static NodeList* ascompatee(int, NodeList*, NodeList*, NodeList**); |
14 static NodeList* ascompatet(int, NodeList*, Type**, int, NodeList**); | 14 static NodeList* ascompatet(int, NodeList*, Type**, int, NodeList**); |
15 static NodeList* ascompatte(int, Node*, int, Type**, NodeList*, int, Node
List**); | 15 static NodeList* ascompatte(int, Node*, int, Type**, NodeList*, int, Node
List**); |
16 static Node* convas(Node*, NodeList**); | 16 static Node* convas(Node*, NodeList**); |
17 static void heapmoves(void); | 17 static void heapmoves(void); |
18 static NodeList* paramstoheap(Type **argin, int out); | 18 static NodeList* paramstoheap(Type **argin, int out); |
19 static NodeList* reorder1(NodeList*); | 19 static NodeList* reorder1(NodeList*); |
20 static NodeList* reorder3(NodeList*); | 20 static NodeList* reorder3(NodeList*); |
21 static Node* addstr(Node*, NodeList**); | 21 static Node* addstr(Node*, NodeList**); |
22 static Node* appendslice(Node*, NodeList**); | 22 static Node* appendslice(Node*, NodeList**); |
23 static» Node*» append(Node*, NodeList**); | 23 static» Node*» append(Node*, Node*, NodeList**); |
24 static Node* sliceany(Node*, NodeList**); | 24 static Node* sliceany(Node*, NodeList**); |
25 static void walkcompare(Node**, NodeList**); | 25 static void walkcompare(Node**, NodeList**); |
26 static void walkrotate(Node**); | 26 static void walkrotate(Node**); |
27 static void walkmul(Node**, NodeList**); | 27 static void walkmul(Node**, NodeList**); |
28 static void walkdiv(Node**, NodeList**); | 28 static void walkdiv(Node**, NodeList**); |
29 static int bounded(Node*, int64); | 29 static int bounded(Node*, int64); |
30 static Mpint mpzero; | 30 static Mpint mpzero; |
31 | 31 |
32 void | 32 void |
33 walk(Node *fn) | 33 walk(Node *fn) |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 | 563 |
564 case OAS: | 564 case OAS: |
565 *init = concat(*init, n->ninit); | 565 *init = concat(*init, n->ninit); |
566 n->ninit = nil; | 566 n->ninit = nil; |
567 walkexpr(&n->left, init); | 567 walkexpr(&n->left, init); |
568 n->left = safeexpr(n->left, init); | 568 n->left = safeexpr(n->left, init); |
569 | 569 |
570 if(oaslit(n, init)) | 570 if(oaslit(n, init)) |
571 goto ret; | 571 goto ret; |
572 | 572 |
| 573 // optimization of the common pattern x = append(x, y) |
| 574 // We provide x as temporary storage for the inlined append. |
| 575 if(n->left->op != OINDEXMAP && !isblank(n->left)) |
| 576 if(n->right != N && n->right->op == OAPPEND && !n->right
->isddd) { |
| 577 append(n->right, n->left, init); |
| 578 n = nod(OEMPTY, N, N); |
| 579 goto ret; |
| 580 } |
573 walkexpr(&n->right, init); | 581 walkexpr(&n->right, init); |
574 if(n->left != N && n->right != N) { | 582 if(n->left != N && n->right != N) { |
575 r = convas(nod(OAS, n->left, n->right), init); | 583 r = convas(nod(OAS, n->left, n->right), init); |
576 r->dodata = n->dodata; | 584 r->dodata = n->dodata; |
577 n = r; | 585 n = r; |
578 } | 586 } |
579 | 587 |
580 goto ret; | 588 goto ret; |
581 | 589 |
582 case OAS2: | 590 case OAS2: |
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1198 goto ret; | 1206 goto ret; |
1199 ········ | 1207 ········ |
1200 case OAPPEND: | 1208 case OAPPEND: |
1201 if(n->isddd) { | 1209 if(n->isddd) { |
1202 if(istype(n->type->type, TUINT8) && istype(n->list->next
->n->type, TSTRING)) | 1210 if(istype(n->type->type, TUINT8) && istype(n->list->next
->n->type, TSTRING)) |
1203 n = mkcall("appendstr", n->type, init, typename(
n->type), n->list->n, n->list->next->n); | 1211 n = mkcall("appendstr", n->type, init, typename(
n->type), n->list->n, n->list->next->n); |
1204 else | 1212 else |
1205 n = appendslice(n, init); | 1213 n = appendslice(n, init); |
1206 } | 1214 } |
1207 else | 1215 else |
1208 » » » n = append(n, init); | 1216 » » » n = append(n, N, init); |
1209 goto ret; | 1217 goto ret; |
1210 | 1218 |
1211 case OCOPY: | 1219 case OCOPY: |
1212 if(n->right->type->etype == TSTRING) | 1220 if(n->right->type->etype == TSTRING) |
1213 fn = syslook("slicestringcopy", 1); | 1221 fn = syslook("slicestringcopy", 1); |
1214 else | 1222 else |
1215 fn = syslook("copy", 1); | 1223 fn = syslook("copy", 1); |
1216 argtype(fn, n->left->type); | 1224 argtype(fn, n->left->type); |
1217 argtype(fn, n->right->type); | 1225 argtype(fn, n->right->type); |
1218 n = mkcall1(fn, n->type, init, | 1226 n = mkcall1(fn, n->type, init, |
(...skipping 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2486 // if cap(s) - len(s) < argc { | 2494 // if cap(s) - len(s) < argc { |
2487 // s = growslice(s, argc) | 2495 // s = growslice(s, argc) |
2488 // } | 2496 // } |
2489 // n := len(s) | 2497 // n := len(s) |
2490 // s = s[:n+argc] | 2498 // s = s[:n+argc] |
2491 // s[n] = a | 2499 // s[n] = a |
2492 // s[n+1] = b | 2500 // s[n+1] = b |
2493 // ... | 2501 // ... |
2494 // } | 2502 // } |
2495 // s | 2503 // s |
| 2504 // |
| 2505 // The s variable above may be predeclared by the caller |
| 2506 // and provided as the ns argument. |
2496 static Node* | 2507 static Node* |
2497 append(Node *n, NodeList **init) | 2508 append(Node *n, Node *ns, NodeList **init) |
2498 { | 2509 { |
2499 NodeList *l, *a; | 2510 NodeList *l, *a; |
2500 » Node *nsrc, *ns, *nn, *na, *nx, *fn; | 2511 » Node *nsrc, *nn, *na, *nx, *fn; |
2501 int argc; | 2512 int argc; |
2502 | 2513 |
2503 walkexprlistsafe(n->list, init); | 2514 walkexprlistsafe(n->list, init); |
2504 | 2515 |
2505 // walkexprlistsafe will leave OINDEX (s[n]) alone if both s | 2516 // walkexprlistsafe will leave OINDEX (s[n]) alone if both s |
2506 // and n are name or literal, but those may index the slice we're | 2517 // and n are name or literal, but those may index the slice we're |
2507 // modifying here. Fix explicitly. | 2518 // modifying here. Fix explicitly. |
2508 for(l=n->list; l; l=l->next) | 2519 for(l=n->list; l; l=l->next) |
2509 l->n = cheapexpr(l->n, init); | 2520 l->n = cheapexpr(l->n, init); |
2510 | 2521 |
2511 nsrc = n->list->n; | 2522 nsrc = n->list->n; |
2512 argc = count(n->list) - 1; | 2523 argc = count(n->list) - 1; |
2513 if (argc < 1) { | 2524 if (argc < 1) { |
2514 return nsrc; | 2525 return nsrc; |
2515 } | 2526 } |
2516 | 2527 |
2517 l = nil; | 2528 l = nil; |
2518 | 2529 |
2519 » ns = temp(nsrc->type); | 2530 » if(ns == N) |
| 2531 » » ns = temp(nsrc->type); |
2520 l = list(l, nod(OAS, ns, nsrc)); // s = src | 2532 l = list(l, nod(OAS, ns, nsrc)); // s = src |
2521 | 2533 |
2522 na = nodintconst(argc); // const argc | 2534 na = nodintconst(argc); // const argc |
2523 nx = nod(OIF, N, N); // if cap(s) - len(s) < argc | 2535 nx = nod(OIF, N, N); // if cap(s) - len(s) < argc |
2524 nx->ntest = nod(OLT, nod(OSUB, nod(OCAP, ns, N), nod(OLEN, ns, N)), na); | 2536 nx->ntest = nod(OLT, nod(OSUB, nod(OCAP, ns, N), nod(OLEN, ns, N)), na); |
2525 | 2537 |
2526 fn = syslook("growslice", 1); // growslice(<type>, old []T, n int64)
(ret []T) | 2538 fn = syslook("growslice", 1); // growslice(<type>, old []T, n int64)
(ret []T) |
2527 argtype(fn, ns->type->type); // 1 old []any | 2539 argtype(fn, ns->type->type); // 1 old []any |
2528 argtype(fn, ns->type->type); // 2 ret []any | 2540 argtype(fn, ns->type->type); // 2 ret []any |
2529 | 2541 |
(...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3489 !candiscardlist(n->ninit) || | 3501 !candiscardlist(n->ninit) || |
3490 !candiscardlist(n->nbody) || | 3502 !candiscardlist(n->nbody) || |
3491 !candiscardlist(n->nelse) || | 3503 !candiscardlist(n->nelse) || |
3492 !candiscardlist(n->list) || | 3504 !candiscardlist(n->list) || |
3493 !candiscardlist(n->rlist)) { | 3505 !candiscardlist(n->rlist)) { |
3494 return 0; | 3506 return 0; |
3495 } | 3507 } |
3496 ········ | 3508 ········ |
3497 return 1; | 3509 return 1; |
3498 } | 3510 } |
LEFT | RIGHT |