1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
8 #include "../ld/textflag.h"
9 #include "../../runtime/mgc0.h"
11 static Node* walkprint(Node*, NodeList**);
12 static Node* writebarrierfn(char*, Type*, Type*);
13 static Node* applywritebarrier(Node*, NodeList**);
14 static Node* mapfn(char*, Type*);
15 static Node* mapfndel(char*, Type*);
16 static Node* ascompatee1(int, Node*, Node*, NodeList**);
17 static NodeList* ascompatee(int, NodeList*, NodeList*, NodeList**);
18 static NodeList* ascompatet(int, NodeList*, Type**, int, NodeList**);
19 static NodeList* ascompatte(int, Node*, int, Type**, NodeList*, int, NodeList**);
20 static Node* convas(Node*, NodeList**);
21 static void heapmoves(void);
22 static NodeList* paramstoheap(Type **argin, int out);
23 static NodeList* reorder1(NodeList*);
24 static NodeList* reorder3(NodeList*);
25 static Node* addstr(Node*, NodeList**);
26 static Node* appendslice(Node*, NodeList**);
27 static Node* append(Node*, NodeList**);
28 static Node* copyany(Node*, NodeList**, int);
29 static Node* sliceany(Node*, NodeList**);
30 static void walkcompare(Node**, NodeList**);
31 static void walkrotate(Node**);
32 static void walkmul(Node**, NodeList**);
33 static void walkdiv(Node**, NodeList**);
34 static int bounded(Node*, int64);
36 static void walkprintfunc(Node**, NodeList**);
48 snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym);
49 dumplist(s, curfn->nbody);
54 // Final typecheck for any unused variables.
55 // It's hard to be on the heap when not-used, but best to be consistent about &~PHEAP here and below.
56 for(l=fn->dcl; l; l=l->next)
57 if(l->n->op == ONAME && (l->n->class&~PHEAP) == PAUTO)
58 typecheck(&l->n, Erv | Easgn);
60 // Propagate the used flag for typeswitch variables up to the NONAME in it's definition.
61 for(l=fn->dcl; l; l=l->next)
62 if(l->n->op == ONAME && (l->n->class&~PHEAP) == PAUTO && l->n->defn && l->n->defn->op == OTYPESW && l->n->used)
63 l->n->defn->left->used++;
65 for(l=fn->dcl; l; l=l->next) {
66 if(l->n->op != ONAME || (l->n->class&~PHEAP) != PAUTO || l->n->sym->name[0] == '&' || l->n->used)
68 if(l->n->defn && l->n->defn->op == OTYPESW) {
69 if(l->n->defn->left->used)
71 lineno = l->n->defn->left->lineno;
72 yyerror("%S declared and not used", l->n->sym);
73 l->n->defn->left->used = 1; // suppress repeats
75 lineno = l->n->lineno;
76 yyerror("%S declared and not used", l->n->sym);
83 walkstmtlist(curfn->nbody);
85 snprint(s, sizeof(s), "after walk %S", curfn->nname->sym);
86 dumplist(s, curfn->nbody);
89 if(debug['W'] && curfn->enter != nil) {
90 snprint(s, sizeof(s), "enter %S", curfn->nname->sym);
91 dumplist(s, curfn->enter);
97 walkstmtlist(NodeList *l)
104 samelist(NodeList *a, NodeList *b)
106 for(; a && b; a=a->next, b=b->next)
113 paramoutheap(Node *fn)
117 for(l=fn->dcl; l; l=l->next) {
118 switch(l->n->class) {
120 case PPARAMOUT|PHEAP:
121 return l->n->addrtaken;
124 // stop early - parameters are over
142 if(n->dodata == 2) // don't walk, generated by anylit.
147 walkstmtlist(n->ninit);
152 yyerror("%S is not a top level statement", n->sym);
154 yyerror("%O is not a top level statement", n->op);
178 if(n->typecheck == 0)
179 fatal("missing typecheck: %+N", n);
184 if((*np)->op == OCOPY && n->op == OCONVNOP)
185 n->op = OEMPTY; // don't leave plain values as statements.
189 // special case for a receive where we throw away
190 // the value received.
191 if(n->typecheck == 0)
192 fatal("missing typecheck: %+N", n);
196 walkexpr(&n->left, &init);
197 n = mkcall1(chanfn("chanrecv1", 2, n->left->type), T, &init, typename(n->left->type), n->left, nodnil());
216 walkstmtlist(n->list);
220 yyerror("case statement out of place");
228 switch(n->left->op) {
231 walkprintfunc(&n->left, &n->ninit);
234 n->left = copyany(n->left, &n->ninit, 1);
237 walkexpr(&n->left, &n->ninit);
244 walkstmtlist(n->ntest->ninit);
245 init = n->ntest->ninit;
246 n->ntest->ninit = nil;
247 walkexpr(&n->ntest, &init);
248 addinit(&n->ntest, init);
251 walkstmtlist(n->nbody);
255 walkexpr(&n->ntest, &n->ninit);
256 walkstmtlist(n->nbody);
257 walkstmtlist(n->nelse);
261 switch(n->left->op) {
264 walkprintfunc(&n->left, &n->ninit);
267 n->left = copyany(n->left, &n->ninit, 1);
270 walkexpr(&n->left, &n->ninit);
276 walkexprlist(n->list, &n->ninit);
279 if((curfn->type->outnamed && count(n->list) > 1) || paramoutheap(curfn)) {
280 // assign to the function out parameters,
281 // so that reorder3 can fix up conflicts
283 for(ll=curfn->dcl; ll != nil; ll=ll->next) {
284 cl = ll->n->class & ~PHEAP;
288 rl = list(rl, ll->n);
290 if(samelist(rl, n->list)) {
291 // special return in disguise
295 if(count(n->list) == 1 && count(rl) > 1) {
296 // OAS2FUNC in disguise
298 if(f->op != OCALLFUNC && f->op != OCALLMETH && f->op != OCALLINTER)
299 fatal("expected return of call, have %N", f);
300 n->list = concat(list1(f), ascompatet(n->op, rl, &f->type, 0, &n->ninit));
304 // move function calls out, to make reorder3's job easier.
305 walkexprlistsafe(n->list, &n->ninit);
306 ll = ascompatee(n->op, rl, n->list, &n->ninit);
307 n->list = reorder3(ll);
310 ll = ascompatte(n->op, nil, 0, getoutarg(curfn->type), n->list, 1, &n->ninit);
330 yyerror("fallthrough statement out of place");
336 fatal("walkstmt ended up with name: %+N", n);
343 * walk the whole tree of the body of an
344 * expression or simple statement.
345 * the types expressions are calculated.
346 * compile-time constants are evaluated.
347 * complex side effects like statements are appended to init
351 walkexprlist(NodeList *l, NodeList **init)
354 walkexpr(&l->n, init);
358 walkexprlistsafe(NodeList *l, NodeList **init)
360 for(; l; l=l->next) {
361 l->n = safeexpr(l->n, init);
362 walkexpr(&l->n, init);
367 walkexprlistcheap(NodeList *l, NodeList **init)
369 for(; l; l=l->next) {
370 l->n = cheapexpr(l->n, init);
371 walkexpr(&l->n, init);
376 walkexpr(Node **np, NodeList **init)
378 Node *r, *l, *var, *a;
382 int et, old_safemode;
385 Node *n, *fn, *n1, *n2;
394 if(init == &n->ninit) {
395 // not okay to use n->ninit when walking n,
396 // because we might replace n with some other node
397 // and would lose the init list.
398 fatal("walkexpr init == &n->ninit");
401 if(n->ninit != nil) {
402 walkstmtlist(n->ninit);
403 *init = concat(*init, n->ninit);
407 // annoying case - not typechecked
409 walkexpr(&n->left, init);
410 walkexpr(&n->right, init);
417 dump("walk-before", n);
419 if(n->typecheck != 1)
420 fatal("missed typecheck: %+N\n", n);
425 fatal("walkexpr: switch 1 unknown op %+hN", n);
442 walkexpr(&n->left, init);
446 walkexpr(&n->left, init);
451 walkexpr(&n->left, init);
456 if(n->op == ODOTPTR && n->left->type->type->width == 0) {
457 // No actual copy will be generated, so emit an explicit nil check.
458 n->left = cheapexpr(n->left, init);
459 checknil(n->left, init);
461 walkexpr(&n->left, init);
465 walkexpr(&n->left, init);
466 walkexpr(&n->right, init);
471 walkexpr(&n->left, init);
476 walkexpr(&n->left, init);
478 // replace len(*[10]int) with 10.
479 // delayed until now to preserve side effects.
483 if(isfixedarray(t)) {
484 safeexpr(n->left, init);
485 nodconst(n, n->type, t->bound);
492 walkexpr(&n->left, init);
493 walkexpr(&n->right, init);
495 n->bounded = bounded(n->right, 8*t->width);
496 if(debug['m'] && n->etype && !isconst(n->right, CTINT))
497 warn("shift bounds check elided");
510 // Use results from call expression as arguments for complex.
511 if(n->op == OCOMPLEX && n->left == N && n->right == N) {
512 n->left = n->list->n;
513 n->right = n->list->next->n;
515 walkexpr(&n->left, init);
516 walkexpr(&n->right, init);
521 walkexpr(&n->left, init);
522 walkexpr(&n->right, init);
528 walkexpr(&n->left, init);
529 walkexpr(&n->right, init);
530 // Disable safemode while compiling this code: the code we
531 // generate internally can refer to unsafe.Pointer.
532 // In this case it can happen if we need to generate an ==
533 // for a struct containing a reflect.Value, which itself has
534 // an unexported field of type unsafe.Pointer.
535 old_safemode = safemode;
537 walkcompare(&n, init);
538 safemode = old_safemode;
543 walkexpr(&n->left, init);
544 // cannot put side effects from n->right on init,
545 // because they cannot run before n->left is checked.
546 // save elsewhere and store on the eventual n->right.
548 walkexpr(&n->right, &ll);
549 addinit(&n->right, ll);
554 walkexprlist(n->list, init);
555 n = walkprint(n, init);
559 n = mkcall("gopanic", T, init, n->left);
563 n = mkcall("gorecover", n->type, init, nod(OADDR, nodfp, N));
576 if(!(n->class & PHEAP) && n->class != PPARAMREF)
582 if(n->list && n->list->n->op == OAS)
584 walkexpr(&n->left, init);
585 walkexprlist(n->list, init);
586 ll = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init);
587 n->list = reorder1(ll);
592 if(n->list && n->list->n->op == OAS)
595 walkexpr(&n->left, init);
596 walkexprlist(n->list, init);
598 ll = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init);
599 n->list = reorder1(ll);
604 if(n->list && n->list->n->op == OAS)
606 walkexpr(&n->left, init);
607 walkexprlist(n->list, init);
608 ll = ascompatte(n->op, n, 0, getthis(t), list1(n->left->left), 0, init);
609 lr = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init);
613 n->list = reorder1(ll);
617 *init = concat(*init, n->ninit);
620 walkexpr(&n->left, init);
621 n->left = safeexpr(n->left, init);
626 if(n->right == N || iszero(n->right) && !flag_race)
629 switch(n->right->op) {
631 walkexpr(&n->right, init);
635 // x = <-c; n->left is x, n->right->left is c.
636 // orderstmt made sure x is addressable.
637 walkexpr(&n->right->left, init);
638 n1 = nod(OADDR, n->left, N);
639 r = n->right->left; // the channel
640 n = mkcall1(chanfn("chanrecv1", 2, r->type), T, init, typename(r->type), r, n1);
645 if(n->left != N && n->right != N) {
646 r = convas(nod(OAS, n->left, n->right), init);
647 r->dodata = n->dodata;
649 n = applywritebarrier(n, init);
655 *init = concat(*init, n->ninit);
657 walkexprlistsafe(n->list, init);
658 walkexprlistsafe(n->rlist, init);
659 ll = ascompatee(OAS, n->list, n->rlist, init);
661 for(lr = ll; lr != nil; lr = lr->next)
662 lr->n = applywritebarrier(lr->n, init);
668 *init = concat(*init, n->ninit);
671 walkexprlistsafe(n->list, init);
674 ll = ascompatet(n->op, n->list, &r->type, 0, init);
675 for(lr = ll; lr != nil; lr = lr->next)
676 lr->n = applywritebarrier(lr->n, init);
677 n = liststmt(concat(list1(r), ll));
682 // orderstmt made sure x is addressable.
683 *init = concat(*init, n->ninit);
686 walkexprlistsafe(n->list, init);
687 walkexpr(&r->left, init);
688 if(isblank(n->list->n))
691 n1 = nod(OADDR, n->list->n, N);
692 n1->etype = 1; // addr does not escape
693 fn = chanfn("chanrecv2", 2, r->left->type);
694 r = mkcall1(fn, n->list->next->n->type, init, typename(r->left->type), r->left, n1);
695 n = nod(OAS, n->list->next->n, r);
701 *init = concat(*init, n->ninit);
704 walkexprlistsafe(n->list, init);
705 walkexpr(&r->left, init);
706 walkexpr(&r->right, init);
709 if(t->type->width <= 128) { // Check ../../runtime/hashmap.c:MAXVALUESIZE before changing.
710 switch(simsimtype(t->down)) {
713 p = "mapaccess2_fast32";
717 p = "mapaccess2_fast64";
720 p = "mapaccess2_faststr";
725 // fast versions take key by value
728 // standard version takes key by reference
729 // orderexpr made sure key is addressable.
730 key = nod(OADDR, r->right, N);
737 // var,b = mapaccess2*(t, m, i)
740 var = temp(ptrto(t->type));
743 r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, key);
745 // mapaccess2* returns a typed bool, but due to spec changes,
746 // the boolean result of i.(T) is now untyped so we make it the
747 // same type as the variable on the lhs.
748 if(!isblank(n->list->next->n))
749 r->type->type->down->type = n->list->next->n->type;
754 *init = list(*init, n);
755 n = nod(OAS, a, nod(OIND, var, N));
758 // mapaccess needs a zero value to be at least this big.
759 if(zerosize < t->type->width)
760 zerosize = t->type->width;
761 // TODO: ptr is always non-nil, so disable nil check for this OIND op.
765 *init = concat(*init, n->ninit);
768 key = n->list->next->n;
769 walkexpr(&map, init);
770 walkexpr(&key, init);
771 // orderstmt made sure key is addressable.
772 key = nod(OADDR, key, N);
774 n = mkcall1(mapfndel("mapdelete", t), T, init, typename(t), map, key);
779 *init = concat(*init, n->ninit);
782 walkexprlistsafe(n->list, init);
783 if(isblank(n->list->n) && !isinter(r->type)) {
784 strcpy(buf, "assert");
786 if(isnilinter(r->left->type))
796 fn = syslook(buf, 1);
798 // runtime.assert(E|I)2TOK returns a typed bool, but due
799 // to spec changes, the boolean result of i.(T) is now untyped
800 // so we make it the same type as the variable on the lhs.
801 if(!isblank(n->list->next->n))
802 fn->type->type->down->type->type = n->list->next->n->type;
803 ll = list1(typename(r->type));
804 ll = list(ll, r->left);
805 argtype(fn, r->left->type);
806 n1 = nod(OCALL, fn, N);
808 n = nod(OAS, n->list->next->n, n1);
816 ll = ascompatet(n->op, n->list, &r->type, 0, init);
817 n = liststmt(concat(list1(r), ll));
822 // Build name of function: assertI2E2 etc.
823 strcpy(buf, "assert");
825 if(isnilinter(n->left->type))
830 if(isnilinter(n->type))
832 else if(isinter(n->type))
836 if(n->op == ODOTTYPE2)
840 fn = syslook(buf, 1);
841 ll = list1(typename(n->type));
842 ll = list(ll, n->left);
843 argtype(fn, n->left->type);
844 argtype(fn, n->type);
845 n = nod(OCALL, fn, N);
847 typecheck(&n, Erv | Efnstruct);
852 walkexpr(&n->left, init);
854 // Optimize convT2E as a two-word copy when T is uintptr-shaped.
855 if(isnilinter(n->type) && isdirectiface(n->left->type) && n->left->type->width == widthptr && isint[simsimtype(n->left->type)]) {
856 l = nod(OEFACE, typename(n->left->type), n->left);
858 l->typecheck = n->typecheck;
863 // Build name of function: convI2E etc.
864 // Not all names are possible
865 // (e.g., we'll never generate convE2E or convE2I).
868 if(isnilinter(n->left->type))
870 else if(isinter(n->left->type))
875 if(isnilinter(n->type))
881 fn = syslook(buf, 1);
883 if(!isinter(n->left->type))
884 ll = list(ll, typename(n->left->type));
885 if(!isnilinter(n->type))
886 ll = list(ll, typename(n->type));
887 if(!isinter(n->left->type) && !isnilinter(n->type)){
888 sym = pkglookup(smprint("%-T.%-T", n->left->type, n->type), itabpkg);
890 l = nod(ONAME, N, N);
892 l->type = ptrto(types[TUINT8]);
897 ggloblsym(sym, widthptr, DUPOK|NOPTR);
899 l = nod(OADDR, sym->def, N);
903 if(isdirectiface(n->left->type) && n->left->type->width == widthptr && isint[simsimtype(n->left->type)]) {
904 /* For pointer types, we can make a special form of optimization
906 * These statements are put onto the expression init list:
907 * Itab *tab = atomicloadtype(&cache);
909 * tab = typ2Itab(type, itype, &cache);
911 * The CONVIFACE expression is replaced with this:
914 l = temp(ptrto(types[TUINT8]));
916 n1 = nod(OAS, l, sym->def);
917 typecheck(&n1, Etop);
918 *init = list(*init, n1);
920 fn = syslook("typ2Itab", 1);
921 n1 = nod(OCALL, fn, N);
927 n2->ntest = nod(OEQ, l, nodnil());
928 n2->nbody = list1(nod(OAS, l, n1));
930 typecheck(&n2, Etop);
931 *init = list(*init, n2);
933 l = nod(OEFACE, l, n->left);
934 l->typecheck = n->typecheck;
940 if(isinter(n->left->type)) {
941 ll = list(ll, n->left);
943 // regular types are passed by reference to avoid C vararg calls
944 // orderexpr arranged for n->left to be a temporary for all
945 // the conversions it could see. comparison of an interface
946 // with a non-interface, especially in a switch on interface value
947 // with non-interface cases, is not visible to orderstmt, so we
948 // have to fall back on allocating a temp here.
949 if(islvalue(n->left))
950 ll = list(ll, nod(OADDR, n->left, N));
952 ll = list(ll, nod(OADDR, copyexpr(n->left, n->left->type, init), N));
954 argtype(fn, n->left->type);
955 argtype(fn, n->type);
957 n = nod(OCALL, fn, N);
966 if(isfloat[n->left->type->etype]) {
967 if(n->type->etype == TINT64) {
968 n = mkcall("float64toint64", n->type, init, conv(n->left, types[TFLOAT64]));
971 if(n->type->etype == TUINT64) {
972 n = mkcall("float64touint64", n->type, init, conv(n->left, types[TFLOAT64]));
976 if(isfloat[n->type->etype]) {
977 if(n->left->type->etype == TINT64) {
978 n = mkcall("int64tofloat64", n->type, init, conv(n->left, types[TINT64]));
981 if(n->left->type->etype == TUINT64) {
982 n = mkcall("uint64tofloat64", n->type, init, conv(n->left, types[TUINT64]));
987 walkexpr(&n->left, init);
991 walkexpr(&n->left, init);
993 n->right = nod(OCOM, n->right, N);
994 typecheck(&n->right, Erv);
995 walkexpr(&n->right, init);
999 walkexpr(&n->left, init);
1000 walkexpr(&n->right, init);
1006 walkexpr(&n->left, init);
1007 walkexpr(&n->right, init);
1009 * rewrite complex div into function call.
1011 et = n->left->type->etype;
1012 if(iscomplex[et] && n->op == ODIV) {
1014 n = mkcall("complex128div", types[TCOMPLEX128], init,
1015 conv(n->left, types[TCOMPLEX128]),
1016 conv(n->right, types[TCOMPLEX128]));
1020 // Nothing to do for float divisions.
1024 // Try rewriting as shifts or magic multiplies.
1028 * rewrite 64-bit div and mod into function calls
1029 * on 32-bit architectures.
1034 if(widthreg >= 8 || (et != TUINT64 && et != TINT64))
1037 strcpy(namebuf, "int64");
1039 strcpy(namebuf, "uint64");
1041 strcat(namebuf, "div");
1043 strcat(namebuf, "mod");
1044 n = mkcall(namebuf, n->type, init,
1045 conv(n->left, types[et]), conv(n->right, types[et]));
1053 walkexpr(&n->left, init);
1054 // save the original node for bounds checking elision.
1055 // If it was a ODIV/OMOD walk might rewrite it.
1057 walkexpr(&n->right, init);
1059 // if range of type cannot exceed static array bound,
1060 // disable bounds check.
1064 if(t != T && isptr[t->etype])
1066 if(isfixedarray(t)) {
1067 n->bounded = bounded(r, t->bound);
1068 if(debug['m'] && n->bounded && !isconst(n->right, CTINT))
1069 warn("index bounds check elided");
1070 if(smallintconst(n->right) && !n->bounded)
1071 yyerror("index out of bounds");
1072 } else if(isconst(n->left, CTSTR)) {
1073 n->bounded = bounded(r, n->left->val.u.sval->len);
1074 if(debug['m'] && n->bounded && !isconst(n->right, CTINT))
1075 warn("index bounds check elided");
1076 if(smallintconst(n->right)) {
1078 yyerror("index out of bounds");
1080 // replace "abc"[1] with 'b'.
1081 // delayed until now because "abc"[1] is not
1082 // an ideal constant.
1083 v = mpgetfix(n->right->val.u.xval);
1084 nodconst(n, n->type, n->left->val.u.sval->s[v]);
1090 if(isconst(n->right, CTINT))
1091 if(mpcmpfixfix(n->right->val.u.xval, &mpzero) < 0 ||
1092 mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0)
1093 yyerror("index out of bounds");
1099 walkexpr(&n->left, init);
1100 walkexpr(&n->right, init);
1104 if(t->type->width <= 128) { // Check ../../runtime/hashmap.c:MAXVALUESIZE before changing.
1105 switch(simsimtype(t->down)) {
1108 p = "mapaccess1_fast32";
1112 p = "mapaccess1_fast64";
1115 p = "mapaccess1_faststr";
1120 // fast versions take key by value
1123 // standard version takes key by reference.
1124 // orderexpr made sure key is addressable.
1125 key = nod(OADDR, n->right, N);
1128 n = mkcall1(mapfn(p, t), ptrto(t->type), init, typename(t), n->left, key);
1129 n = nod(OIND, n, N);
1132 // mapaccess needs a zero value to be at least this big.
1133 if(zerosize < t->type->width)
1134 zerosize = t->type->width;
1138 fatal("walkexpr ORECV"); // should see inside OAS only
1141 if(n->right != N && n->right->left == N && n->right->right == N) { // noop
1142 walkexpr(&n->left, init);
1149 if(n->right == N) // already processed
1152 walkexpr(&n->left, init);
1153 // cgen_slice can't handle string literals as source
1154 // TODO the OINDEX case is a bug elsewhere that needs to be traced. it causes a crash on ([2][]int{ ... })[1][lo:hi]
1155 if((n->op == OSLICESTR && n->left->op == OLITERAL) || (n->left->op == OINDEX))
1156 n->left = copyexpr(n->left, n->left->type, init);
1158 n->left = safeexpr(n->left, init);
1159 walkexpr(&n->right->left, init);
1160 n->right->left = safeexpr(n->right->left, init);
1161 walkexpr(&n->right->right, init);
1162 n->right->right = safeexpr(n->right->right, init);
1163 n = sliceany(n, init); // chops n->right, sets n->list
1168 if(n->right == N) // already processed
1171 walkexpr(&n->left, init);
1172 // TODO the OINDEX case is a bug elsewhere that needs to be traced. it causes a crash on ([2][]int{ ... })[1][lo:hi]
1173 // TODO the comment on the previous line was copied from case OSLICE. it might not even be true.
1174 if(n->left->op == OINDEX)
1175 n->left = copyexpr(n->left, n->left->type, init);
1177 n->left = safeexpr(n->left, init);
1178 walkexpr(&n->right->left, init);
1179 n->right->left = safeexpr(n->right->left, init);
1180 walkexpr(&n->right->right->left, init);
1181 n->right->right->left = safeexpr(n->right->right->left, init);
1182 walkexpr(&n->right->right->right, init);
1183 n->right->right->right = safeexpr(n->right->right->right, init);
1184 n = sliceany(n, init); // chops n->right, sets n->list
1188 walkexpr(&n->left, init);
1192 if(n->esc == EscNone && n->type->type->width < (1<<16)) {
1193 r = temp(n->type->type);
1194 r = nod(OAS, r, N); // zero temp
1195 typecheck(&r, Etop);
1196 *init = list(*init, r);
1197 r = nod(OADDR, r->left, N);
1201 n = callnew(n->type->type);
1206 // If one argument to the comparison is an empty string,
1207 // comparing the lengths instead will yield the same result
1208 // without the function call.
1209 if((isconst(n->left, CTSTR) && n->left->val.u.sval->len == 0) ||
1210 (isconst(n->right, CTSTR) && n->right->val.u.sval->len == 0)) {
1211 r = nod(n->etype, nod(OLEN, n->left, N), nod(OLEN, n->right, N));
1219 // s + "badgerbadgerbadger" == "badgerbadgerbadger"
1220 if((n->etype == OEQ || n->etype == ONE) &&
1221 isconst(n->right, CTSTR) &&
1222 n->left->op == OADDSTR && count(n->left->list) == 2 &&
1223 isconst(n->left->list->next->n, CTSTR) &&
1224 cmpslit(n->right, n->left->list->next->n) == 0) {
1225 r = nod(n->etype, nod(OLEN, n->left->list->n, N), nodintconst(0));
1233 if(n->etype == OEQ || n->etype == ONE) {
1234 // prepare for rewrite below
1235 n->left = cheapexpr(n->left, init);
1236 n->right = cheapexpr(n->right, init);
1238 r = mkcall("eqstring", types[TBOOL], init,
1239 conv(n->left, types[TSTRING]),
1240 conv(n->right, types[TSTRING]));
1242 // quick check of len before full compare for == or !=
1243 if(n->etype == OEQ) {
1244 // len(left) == len(right) && eqstring(left, right)
1245 r = nod(OANDAND, nod(OEQ, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
1247 // len(left) != len(right) || !eqstring(left, right)
1248 r = nod(ONOT, r, N);
1249 r = nod(OOROR, nod(ONE, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
1254 // sys_cmpstring(s1, s2) :: 0
1255 r = mkcall("cmpstring", types[TINT], init,
1256 conv(n->left, types[TSTRING]),
1257 conv(n->right, types[TSTRING]));
1258 r = nod(n->etype, r, nodintconst(0));
1262 if(n->type->etype != TBOOL) fatal("cmp %T", n->type);
1268 n = addstr(n, init);
1273 n = appendslice(n, init); // also works for append(slice, string).
1275 n = append(n, init);
1279 n = copyany(n, init, flag_race);
1283 // cannot use chanfn - closechan takes any, not chan any
1284 fn = syslook("closechan", 1);
1285 argtype(fn, n->left->type);
1286 n = mkcall1(fn, T, init, n->left);
1290 n = mkcall1(chanfn("makechan", 1, n->type), n->type, init,
1292 conv(n->left, types[TINT64]));
1298 fn = syslook("makemap", 1);
1299 argtype(fn, t->down); // any-1
1300 argtype(fn, t->type); // any-2
1302 n = mkcall1(fn, n->type, init,
1304 conv(n->left, types[TINT64]));
1311 l = r = safeexpr(l, init);
1313 if(n->esc == EscNone
1314 && smallintconst(l) && smallintconst(r)
1315 && (t->type->width == 0 || mpgetfix(r->val.u.xval) < (1ULL<<16) / t->type->width)) {
1318 t = aindex(r, t->type); // [r]T
1320 a = nod(OAS, var, N); // zero temp
1321 typecheck(&a, Etop);
1322 *init = list(*init, a);
1323 r = nod(OSLICE, var, nod(OKEY, N, l)); // arr[:l]
1324 r = conv(r, n->type); // in case n->type is named.
1329 // makeslice(t *Type, nel int64, max int64) (ary []any)
1330 fn = syslook("makeslice", 1);
1331 argtype(fn, t->type); // any-1
1332 n = mkcall1(fn, n->type, init,
1334 conv(l, types[TINT64]),
1335 conv(r, types[TINT64]));
1341 n = mkcall("intstring", n->type, init,
1342 conv(n->left, types[TINT64]));
1346 // slicebytetostring([]byte) string;
1347 n = mkcall("slicebytetostring", n->type, init, n->left);
1350 case OARRAYBYTESTRTMP:
1351 // slicebytetostringtmp([]byte) string;
1352 n = mkcall("slicebytetostringtmp", n->type, init, n->left);
1356 // slicerunetostring([]rune) string;
1357 n = mkcall("slicerunetostring", n->type, init, n->left);
1361 // stringtoslicebyte(string) []byte;
1362 n = mkcall("stringtoslicebyte", n->type, init, conv(n->left, types[TSTRING]));
1366 // stringtoslicerune(string) []rune
1367 n = mkcall("stringtoslicerune", n->type, init, n->left);
1371 // ifaceeq(i1 any-1, i2 any-2) (ret bool);
1372 if(!eqtype(n->left->type, n->right->type))
1373 fatal("ifaceeq %O %T %T", n->op, n->left->type, n->right->type);
1374 if(isnilinter(n->left->type))
1375 fn = syslook("efaceeq", 1);
1377 fn = syslook("ifaceeq", 1);
1379 n->right = cheapexpr(n->right, init);
1380 n->left = cheapexpr(n->left, init);
1381 argtype(fn, n->right->type);
1382 argtype(fn, n->left->type);
1383 r = mkcall1(fn, n->type, init, n->left, n->right);
1385 r = nod(ONOT, r, N);
1387 // check itable/type before full compare.
1389 r = nod(OANDAND, nod(OEQ, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r);
1391 r = nod(OOROR, nod(ONE, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r);
1402 var = temp(n->type);
1403 anylit(0, n, var, init);
1409 n1 = assignconv(n1, n->left->type->type, "chan send");
1410 walkexpr(&n1, init);
1411 n1 = nod(OADDR, n1, N);
1412 n = mkcall1(chanfn("chansend1", 2, n->left->type), T, init, typename(n->left->type), n->left, n1);
1416 n = walkclosure(n, init);
1420 n = walkpartialcall(n, init);
1423 fatal("missing switch %O", n->op);
1426 // Expressions that are constant at run time but not
1427 // considered const by the language spec are not turned into
1428 // constants until walk. For example, if n is y%1 == 0, the
1429 // walk of y%1 may have replaced it by 0.
1430 // Check whether n with its updated args is itself now a constant.
1434 if(n->op == OLITERAL)
1439 if(debug['w'] && n != N)
1447 ascompatee1(int op, Node *l, Node *r, NodeList **init)
1452 // convas will turn map assigns into function calls,
1453 // making it impossible for reorder3 to work.
1455 if(l->op == OINDEXMAP)
1458 return convas(n, init);
1462 ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init)
1464 NodeList *ll, *lr, *nn;
1467 * check assign expression list to
1468 * a expression list. called in
1469 * expr-list = expr-list
1472 // ensure order of evaluation for function calls
1473 for(ll=nl; ll; ll=ll->next)
1474 ll->n = safeexpr(ll->n, init);
1475 for(lr=nr; lr; lr=lr->next)
1476 lr->n = safeexpr(lr->n, init);
1479 for(ll=nl, lr=nr; ll && lr; ll=ll->next, lr=lr->next) {
1480 // Do not generate 'x = x' during return. See issue 4014.
1481 if(op == ORETURN && ll->n == lr->n)
1483 nn = list(nn, ascompatee1(op, ll->n, lr->n, init));
1486 // cannot happen: caller checked that lists had same length
1488 yyerror("error in shape across %+H %O %+H / %d %d [%s]", nl, op, nr, count(nl), count(nr), curfn->nname->sym->name);
1493 * l is an lv and rt is the type of an rv
1494 * return 1 if this implies a function call
1495 * evaluating the lv or a function call
1496 * in the conversion of the types
1499 fncall(Node *l, Type *rt)
1503 if(l->ullman >= UINF || l->op == OINDEXMAP)
1505 memset(&r, 0, sizeof r);
1506 if(needwritebarrier(l, &r))
1508 if(eqtype(l->type, rt))
1514 ascompatet(int op, NodeList *nl, Type **nr, int fp, NodeList **init)
1526 * check assign type list to
1527 * a expression list. called in
1528 * expr-list = func()
1530 r = structfirst(&saver, nr);
1534 for(ll=nl; ll; ll=ll->next) {
1539 r = structnext(&saver);
1543 // any lv that causes a fn call must be
1544 // deferred until all the return arguments
1545 // have been pulled from the output arguments
1546 if(fncall(l, r->type)) {
1547 tmp = temp(r->type);
1548 typecheck(&tmp, Erv);
1549 a = nod(OAS, l, tmp);
1550 a = convas(a, init);
1555 a = nod(OAS, l, nodarg(r, fp));
1556 a = convas(a, init);
1558 if(a->ullman >= UINF) {
1559 dump("ascompatet ucount", a);
1563 r = structnext(&saver);
1566 if(ll != nil || r != T)
1567 yyerror("ascompatet: assignment count mismatch: %d = %d",
1568 count(nl), structcount(*nr));
1571 fatal("ascompatet: too many function calls evaluating parameters");
1572 return concat(nn, mm);
1576 * package all the arguments that match a ... T parameter into a []T.
1579 mkdotargslice(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init, Node *ddd)
1589 tslice = typ(TARRAY);
1590 tslice->type = l->type->type;
1593 if(count(lr0) == 0) {
1597 n = nod(OCOMPLIT, N, typenod(tslice));
1599 n->alloc = ddd->alloc; // temporary to use
1604 fatal("mkdotargslice: typecheck failed");
1608 a = nod(OAS, nodarg(l, fp), n);
1609 nn = list(nn, convas(a, init));
1614 * helpers for shape errors
1617 dumptypes(Type **nl, char *what)
1625 fmtprint(&fmt, "\t");
1627 for(l = structfirst(&savel, nl); l != T; l = structnext(&savel)) {
1631 fmtprint(&fmt, ", ");
1632 fmtprint(&fmt, "%T", l);
1635 fmtprint(&fmt, "[no arguments %s]", what);
1636 return fmtstrflush(&fmt);
1640 dumpnodetypes(NodeList *l, char *what)
1647 fmtprint(&fmt, "\t");
1649 for(; l; l=l->next) {
1654 fmtprint(&fmt, ", ");
1655 fmtprint(&fmt, "%T", r->type);
1658 fmtprint(&fmt, "[no arguments %s]", what);
1659 return fmtstrflush(&fmt);
1663 * check assign expression list to
1664 * a type list. called in
1669 ascompatte(int op, Node *call, int isddd, Type **nl, NodeList *lr, int fp, NodeList **init)
1673 NodeList *nn, *lr0, *alist;
1678 l = structfirst(&savel, nl);
1684 // f(g()) where g has multiple return values
1685 if(r != N && lr->next == nil && r->type->etype == TSTRUCT && r->type->funarg) {
1686 // optimization - can do block copy
1687 if(eqtypenoname(r->type, *nl)) {
1688 a = nodarg(*nl, fp);
1689 r = nod(OCONVNOP, r, N);
1691 nn = list1(convas(nod(OAS, a, r), init));
1695 // conversions involved.
1696 // copy into temporaries.
1698 for(l=structfirst(&savel, &r->type); l; l=structnext(&savel)) {
1700 alist = list(alist, a);
1702 a = nod(OAS2, N, N);
1705 typecheck(&a, Etop);
1707 *init = list(*init, a);
1710 l = structfirst(&savel, nl);
1714 if(l != T && l->isddd) {
1715 // the ddd parameter must be last
1716 ll = structnext(&savel);
1718 yyerror("... must be last argument");
1721 // only if we are assigning a single ddd
1722 // argument to a ddd parameter then it is
1723 // passed thru unencapsulated
1724 if(r != N && lr->next == nil && isddd && eqtype(l->type, r->type)) {
1725 a = nod(OAS, nodarg(l, fp), r);
1726 a = convas(a, init);
1731 // normal case -- make a slice of all
1732 // remaining arguments and pass it to
1733 // the ddd parameter.
1734 nn = mkdotargslice(lr, nn, l, fp, init, call->right);
1738 if(l == T || r == N) {
1739 if(l != T || r != N) {
1740 l1 = dumptypes(nl, "expected");
1741 l2 = dumpnodetypes(lr0, "given");
1743 yyerror("not enough arguments to %O\n%s\n%s", op, l1, l2);
1745 yyerror("too many arguments to %O\n%s\n%s", op, l1, l2);
1750 a = nod(OAS, nodarg(l, fp), r);
1751 a = convas(a, init);
1754 l = structnext(&savel);
1762 for(lr=nn; lr; lr=lr->next)
1763 lr->n->typecheck = 1;
1767 // generate code for print
1769 walkprint(Node *nn, NodeList **init)
1776 int notfirst, et, op;
1784 // Hoist all the argument evaluation up before the lock.
1785 walkexprlistcheap(all, init);
1787 calls = list(calls, mkcall("printlock", T, init));
1789 for(l=all; l; l=l->next) {
1791 calls = list(calls, mkcall("printsp", T, init));
1793 notfirst = op == OPRINTN;
1796 if(n->op == OLITERAL) {
1797 switch(n->val.ctype) {
1799 defaultlit(&n, runetype);
1802 defaultlit(&n, types[TINT64]);
1805 defaultlit(&n, types[TFLOAT64]);
1809 if(n->op != OLITERAL && n->type && n->type->etype == TIDEAL)
1810 defaultlit(&n, types[TINT64]);
1811 defaultlit(&n, nil);
1813 if(n->type == T || n->type->etype == TFORW)
1817 et = n->type->etype;
1818 if(isinter(n->type)) {
1819 if(isnilinter(n->type))
1820 on = syslook("printeface", 1);
1822 on = syslook("printiface", 1);
1823 argtype(on, n->type); // any-1
1824 } else if(isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR) {
1825 on = syslook("printpointer", 1);
1826 argtype(on, n->type); // any-1
1827 } else if(isslice(n->type)) {
1828 on = syslook("printslice", 1);
1829 argtype(on, n->type); // any-1
1830 } else if(isint[et]) {
1832 if((t->sym->pkg == runtimepkg || compiling_runtime) && strcmp(t->sym->name, "hex") == 0)
1833 on = syslook("printhex", 0);
1835 on = syslook("printuint", 0);
1837 on = syslook("printint", 0);
1838 } else if(isfloat[et]) {
1839 on = syslook("printfloat", 0);
1840 } else if(iscomplex[et]) {
1841 on = syslook("printcomplex", 0);
1842 } else if(et == TBOOL) {
1843 on = syslook("printbool", 0);
1844 } else if(et == TSTRING) {
1845 on = syslook("printstring", 0);
1847 badtype(OPRINT, n->type, T);
1851 t = *getinarg(on->type);
1857 if(!eqtype(t, n->type)) {
1858 n = nod(OCONV, n, N);
1862 r = nod(OCALL, on, N);
1864 calls = list(calls, r);
1868 calls = list(calls, mkcall("printnl", T, nil));
1870 calls = list(calls, mkcall("printunlock", T, init));
1872 typechecklist(calls, Etop);
1873 walkexprlist(calls, init);
1875 r = nod(OEMPTY, N, N);
1876 typecheck(&r, Etop);
1888 fn = syslook("newobject", 1);
1890 return mkcall1(fn, ptrto(t), nil, typename(t));
1896 while(n->op == ODOT || n->op == OPAREN || n->op == OCONVNOP || n->op == OINDEX && isfixedarray(n->left->type))
1901 // OINDREG only ends up in walk if it's indirect of SP.
1920 while(n->op == ODOT || n->op == OPAREN || n->op == OCONVNOP || n->op == OINDEX && isfixedarray(n->left->type))
1935 // Do we need a write barrier for the assignment l = r?
1937 needwritebarrier(Node *l, Node *r)
1939 if(!use_writebarrier)
1942 if(l == N || isblank(l))
1945 // No write barrier for write of non-pointers.
1947 if(!haspointers(l->type))
1950 // No write barrier for write to stack.
1954 // No write barrier for implicit or explicit zeroing.
1955 if(r == N || iszero(r))
1958 // No write barrier for initialization to constant.
1959 if(r->op == OLITERAL)
1962 // No write barrier for storing static (read-only) data.
1963 if(r->op == ONAME && strncmp(r->sym->name, "statictmp_", 10) == 0)
1966 // No write barrier for storing address of stack values,
1967 // which are guaranteed only to be written to the stack.
1968 if(r->op == OADDR && isstack(r->left))
1971 // No write barrier for storing address of global, which
1972 // is live no matter what.
1973 if(r->op == OADDR && isglobal(r->left))
1976 // No write barrier for reslice: x = x[0:y] or x = append(x, ...).
1977 // Both are compiled to modify x directly.
1978 // In the case of append, a write barrier may still be needed
1979 // if the underlying array grows, but the append code can
1980 // generate the write barrier directly in that case.
1981 // (It does not yet, but the cost of the write barrier will be
1982 // small compared to the cost of the allocation.)
1991 dump("bad reslice-l", l);
1992 dump("bad reslice-r", r);
1998 // Otherwise, be conservative and use write barrier.
2002 // TODO(rsc): Perhaps componentgen should run before this.
2004 applywritebarrier(Node *n, NodeList **init)
2012 if(n->left && n->right && needwritebarrier(n->left, n->right)) {
2014 l = nod(OADDR, n->left, N);
2015 l->etype = 1; // addr does not escape
2016 if(t->width == widthptr) {
2017 n = mkcall1(writebarrierfn("writebarrierptr", t, n->right->type), T, init,
2019 } else if(t->etype == TSTRING) {
2020 n = mkcall1(writebarrierfn("writebarrierstring", t, n->right->type), T, init,
2022 } else if(isslice(t)) {
2023 n = mkcall1(writebarrierfn("writebarrierslice", t, n->right->type), T, init,
2025 } else if(isinter(t)) {
2026 n = mkcall1(writebarrierfn("writebarrieriface", t, n->right->type), T, init,
2028 } else if(t->width <= 4*widthptr) {
2031 bv = bvalloc(BitsPerPointer*4);
2033 twobitwalktype1(t, &x, bv);
2034 // The bvgets are looking for BitsPointer in successive slots.
2038 if(BitsPointer != (1<<PtrBit))
2039 fatal("wrong PtrBit");
2040 switch(t->width/widthptr) {
2042 fatal("found writebarrierfat for %d-byte object of type %T", (int)t->width, t);
2044 snprint(name, sizeof name, "writebarrierfat%d%d",
2045 bvget(bv, PtrBit), bvget(bv, BitsPerPointer+PtrBit));
2048 snprint(name, sizeof name, "writebarrierfat%d%d%d",
2049 bvget(bv, PtrBit), bvget(bv, BitsPerPointer+PtrBit), bvget(bv, 2*BitsPerPointer+PtrBit));
2052 snprint(name, sizeof name, "writebarrierfat%d%d%d%d",
2053 bvget(bv, PtrBit), bvget(bv, BitsPerPointer+PtrBit), bvget(bv, 2*BitsPerPointer+PtrBit), bvget(bv, 3*BitsPerPointer+PtrBit));
2056 n = mkcall1(writebarrierfn(name, t, n->right->type), T, init,
2057 l, nodnil(), n->right);
2060 while(r->op == OCONVNOP)
2062 r = nod(OADDR, r, N);
2063 r->etype = 1; // addr does not escape
2064 //warnl(n->lineno, "writebarrierfat %T %N", t, r);
2065 n = mkcall1(writebarrierfn("writebarrierfat", t, r->left->type), T, init,
2073 convas(Node *n, NodeList **init)
2076 Node *map, *key, *val;
2079 fatal("convas: not OAS %O", n->op);
2083 if(n->left == N || n->right == N)
2087 rt = n->right->type;
2088 if(lt == T || rt == T)
2091 if(isblank(n->left)) {
2092 defaultlit(&n->right, T);
2096 if(n->left->op == OINDEXMAP) {
2097 map = n->left->left;
2098 key = n->left->right;
2100 walkexpr(&map, init);
2101 walkexpr(&key, init);
2102 walkexpr(&val, init);
2103 // orderexpr made sure key and val are addressable.
2104 key = nod(OADDR, key, N);
2105 val = nod(OADDR, val, N);
2106 n = mkcall1(mapfn("mapassign1", map->type), T, init,
2107 typename(map->type), map, key, val);
2111 if(!eqtype(lt, rt)) {
2112 n->right = assignconv(n->right, lt, "assignment");
2113 walkexpr(&n->right, init);
2123 * evaluating actual function arguments.
2125 * if there is exactly one function expr,
2126 * then it is done first. otherwise must
2127 * make temp variables
2130 reorder1(NodeList *all)
2133 NodeList *l, *r, *g;
2136 c = 0; // function calls
2137 t = 0; // total parameters
2139 for(l=all; l; l=l->next) {
2143 if(n->ullman >= UINF)
2146 if(c == 0 || t == 1)
2149 g = nil; // fncalls assigned to tempnames
2150 f = N; // last fncall assigned to stack
2151 r = nil; // non fncalls and tempnames assigned to stack
2153 for(l=all; l; l=l->next) {
2155 if(n->ullman < UINF) {
2165 // make assignment of fncall to tempname
2166 a = temp(n->right->type);
2167 a = nod(OAS, a, n->right);
2170 // put normal arg assignment on list
2171 // with fncall replaced by tempname
2178 return concat(g, r);
2181 static void reorder3save(Node**, NodeList*, NodeList*, NodeList**);
2182 static int aliased(Node*, NodeList*, NodeList*);
2187 * simultaneous assignment. there cannot
2188 * be later use of an earlier lvalue.
2190 * function calls have been removed.
2193 reorder3(NodeList *all)
2195 NodeList *list, *early, *mapinit;
2198 // If a needed expression may be affected by an
2199 // earlier assignment, make an early copy of that
2200 // expression and use the copy instead.
2203 for(list=all; list; list=list->next) {
2206 // Save subexpressions needed on left side.
2207 // Drill through non-dereferences.
2209 if(l->op == ODOT || l->op == OPAREN) {
2213 if(l->op == OINDEX && isfixedarray(l->left->type)) {
2214 reorder3save(&l->right, all, list, &early);
2222 fatal("reorder3 unexpected lvalue %#O", l->op);
2227 reorder3save(&l->left, all, list, &early);
2228 reorder3save(&l->right, all, list, &early);
2229 if(l->op == OINDEXMAP)
2230 list->n = convas(list->n, &mapinit);
2234 reorder3save(&l->left, all, list, &early);
2237 // Save expression on right side.
2238 reorder3save(&list->n->right, all, list, &early);
2241 early = concat(mapinit, early);
2242 return concat(early, all);
2245 static int vmatch2(Node*, Node*);
2246 static int varexpr(Node*);
2249 * if the evaluation of *np would be affected by the
2250 * assignments in all up to but not including stop,
2251 * copy into a temporary during *early and
2252 * replace *np with that temp.
2255 reorder3save(Node **np, NodeList *all, NodeList *stop, NodeList **early)
2260 if(!aliased(n, all, stop))
2265 typecheck(&q, Etop);
2266 *early = list(*early, q);
2271 * what's the outer value that a write to n affects?
2272 * outer value means containing struct or array.
2278 if(n->op == ODOT || n->op == OPAREN) {
2282 if(n->op == OINDEX && isfixedarray(n->left->type)) {
2292 * Is it possible that the computation of n might be
2293 * affected by writes in as up to but not including stop?
2296 aliased(Node *n, NodeList *all, NodeList *stop)
2298 int memwrite, varwrite;
2305 // Look for obvious aliasing: a variable being assigned
2306 // during the all list and appearing in n.
2307 // Also record whether there are any writes to main memory.
2308 // Also record whether there are any writes to variables
2309 // whose addresses have been taken.
2312 for(l=all; l!=stop; l=l->next) {
2313 a = outervalue(l->n->left);
2314 if(a->op != ONAME) {
2336 // The variables being written do not appear in n.
2337 // However, n might refer to computed addresses
2338 // that are being written.
2340 // If no computed addresses are affected by the writes, no aliasing.
2341 if(!memwrite && !varwrite)
2344 // If n does not refer to computed addresses
2345 // (that is, if n only refers to variables whose addresses
2346 // have not been taken), no aliasing.
2350 // Otherwise, both the writes and n refer to computed memory addresses.
2351 // Assume that they might conflict.
2356 * does the evaluation of n only refer to variables
2357 * whose addresses have not been taken?
2358 * (and no other memory)
2396 case ODOT: // but not ODOTPTR
2401 return varexpr(n->left) && varexpr(n->right);
2409 * is the name l mentioned in r?
2412 vmatch2(Node *l, Node *r)
2420 // match each right given left
2425 if(vmatch2(l, r->left))
2427 if(vmatch2(l, r->right))
2429 for(ll=r->list; ll; ll=ll->next)
2430 if(vmatch2(l, ll->n))
2436 * is any name mentioned in l also mentioned in r?
2440 vmatch1(Node *l, Node *r)
2445 * isolate all left sides
2447 if(l == N || r == N)
2457 // assignment to non-stack variable
2458 // must be delayed if right has function calls.
2459 if(r->ullman >= UINF)
2463 return vmatch2(l, r);
2467 if(vmatch1(l->left, r))
2469 if(vmatch1(l->right, r))
2471 for(ll=l->list; ll; ll=ll->next)
2472 if(vmatch1(ll->n, r))
2478 * walk through argin parameters.
2479 * generate and return code to allocate
2480 * copies of escaped parameters to the heap.
2483 paramstoheap(Type **argin, int out)
2491 for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) {
2493 if(v && v->sym && v->sym->name[0] == '~' && v->sym->name[1] == 'r') // unnamed result
2495 // In precisestack mode, the garbage collector assumes results
2496 // are always live, so zero them always.
2497 if(out && (precisestack_enabled || (v == N && hasdefer))) {
2498 // Defer might stop a panic and show the
2499 // return values as they exist at the time of panic.
2500 // Make sure to zero them on entry to the function.
2501 nn = list(nn, nod(OAS, nodarg(t, 1), N));
2503 if(v == N || !(v->class & PHEAP))
2506 // generate allocation & copying code
2507 if(compiling_runtime)
2508 yyerror("%N escapes to heap, not allowed in runtime.", v);
2510 v->alloc = callnew(v->type);
2511 nn = list(nn, nod(OAS, v->heapaddr, v->alloc));
2512 if((v->class & ~PHEAP) != PPARAMOUT)
2513 nn = list(nn, nod(OAS, v, v->stackparam));
2519 * walk through argout parameters copying back to stack
2522 returnsfromheap(Type **argin)
2530 for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) {
2532 if(v == N || v->class != (PHEAP|PPARAMOUT))
2534 nn = list(nn, nod(OAS, v->stackparam, v));
2540 * take care of migrating any function in/out args
2541 * between the stack and the heap. adds code to
2542 * curfn's before and after lists.
2551 lineno = curfn->lineno;
2552 nn = paramstoheap(getthis(curfn->type), 0);
2553 nn = concat(nn, paramstoheap(getinarg(curfn->type), 0));
2554 nn = concat(nn, paramstoheap(getoutarg(curfn->type), 1));
2555 curfn->enter = concat(curfn->enter, nn);
2556 lineno = curfn->endlineno;
2557 curfn->exit = returnsfromheap(getoutarg(curfn->type));
2562 vmkcall(Node *fn, Type *t, NodeList **init, va_list va)
2568 if(fn->type == T || fn->type->etype != TFUNC)
2569 fatal("mkcall %N %T", fn, fn->type);
2572 n = fn->type->intuple;
2574 args = list(args, va_arg(va, Node*));
2576 r = nod(OCALL, fn, N);
2578 if(fn->type->outtuple > 0)
2579 typecheck(&r, Erv | Efnstruct);
2581 typecheck(&r, Etop);
2588 mkcall(char *name, Type *t, NodeList **init, ...)
2594 r = vmkcall(syslook(name, 0), t, init, va);
2600 mkcall1(Node *fn, Type *t, NodeList **init, ...)
2606 r = vmkcall(fn, t, init, va);
2612 conv(Node *n, Type *t)
2614 if(eqtype(n->type, t))
2616 n = nod(OCONV, n, N);
2623 chanfn(char *name, int n, Type *t)
2628 if(t->etype != TCHAN)
2629 fatal("chanfn %T", t);
2630 fn = syslook(name, 1);
2632 argtype(fn, t->type);
2637 mapfn(char *name, Type *t)
2641 if(t->etype != TMAP)
2642 fatal("mapfn %T", t);
2643 fn = syslook(name, 1);
2644 argtype(fn, t->down);
2645 argtype(fn, t->type);
2646 argtype(fn, t->down);
2647 argtype(fn, t->type);
2652 mapfndel(char *name, Type *t)
2656 if(t->etype != TMAP)
2657 fatal("mapfn %T", t);
2658 fn = syslook(name, 1);
2659 argtype(fn, t->down);
2660 argtype(fn, t->type);
2661 argtype(fn, t->down);
2666 writebarrierfn(char *name, Type *l, Type *r)
2670 fn = syslook(name, 1);
2677 addstr(Node *n, NodeList **init)
2679 Node *r, *cat, *slice;
2684 // orderexpr rewrote OADDSTR to have a list of strings.
2687 yyerror("addstr count %d too small", c);
2689 // build list of string arguments
2691 for(l=n->list; l != nil; l=l->next)
2692 args = list(args, conv(l->n, types[TSTRING]));
2695 // small numbers of strings use direct runtime helpers.
2696 // note: orderexpr knows this cutoff too.
2697 snprint(namebuf, sizeof(namebuf), "concatstring%d", c);
2699 // large numbers of strings are passed to the runtime as a slice.
2700 strcpy(namebuf, "concatstrings");
2702 t->type = types[TSTRING];
2704 slice = nod(OCOMPLIT, N, typenod(t));
2705 slice->alloc = n->alloc;
2707 slice->esc = EscNone;
2708 args = list1(slice);
2710 cat = syslook(namebuf, 1);
2711 r = nod(OCALL, cat, N);
2720 // expand append(l1, l2...) to
2723 // if n := len(l1) + len(l2) - cap(s); n > 0 {
2724 // s = growslice(s, n)
2726 // s = s[:len(l1)+len(l2)]
2727 // memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
2731 // l2 is allowed to be a string.
2733 appendslice(Node *n, NodeList **init)
2736 Node *l1, *l2, *nt, *nif, *fn;
2737 Node *nptr1, *nptr2, *nwid;
2740 walkexprlistsafe(n->list, init);
2742 // walkexprlistsafe will leave OINDEX (s[n]) alone if both s
2743 // and n are name or literal, but those may index the slice we're
2744 // modifying here. Fix explicitly.
2745 for(l=n->list; l; l=l->next)
2746 l->n = cheapexpr(l->n, init);
2749 l2 = n->list->next->n;
2751 s = temp(l1->type); // var s []T
2753 l = list(l, nod(OAS, s, l1)); // s = l1
2755 nt = temp(types[TINT]);
2756 nif = nod(OIF, N, N);
2757 // n := len(s) + len(l2) - cap(s)
2758 nif->ninit = list1(nod(OAS, nt,
2759 nod(OSUB, nod(OADD, nod(OLEN, s, N), nod(OLEN, l2, N)), nod(OCAP, s, N))));
2760 nif->ntest = nod(OGT, nt, nodintconst(0));
2761 // instantiate growslice(Type*, []any, int64) []any
2762 fn = syslook("growslice", 1);
2763 argtype(fn, s->type->type);
2764 argtype(fn, s->type->type);
2766 // s = growslice(T, s, n)
2767 nif->nbody = list1(nod(OAS, s, mkcall1(fn, s->type, &nif->ninit,
2770 conv(nt, types[TINT64]))));
2775 // rely on runtime to instrument copy.
2776 // copy(s[len(l1):len(l1)+len(l2)], l2)
2777 nptr1 = nod(OSLICE, s, nod(OKEY,
2779 nod(OADD, nod(OLEN, l1, N), nod(OLEN, l2, N))));
2782 if(l2->type->etype == TSTRING)
2783 fn = syslook("slicestringcopy", 1);
2785 fn = syslook("slicecopy", 1);
2786 argtype(fn, l1->type);
2787 argtype(fn, l2->type);
2788 nt = mkcall1(fn, types[TINT], &l,
2790 nodintconst(s->type->type->width));
2793 // memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
2794 nptr1 = nod(OINDEX, s, nod(OLEN, l1, N));
2796 nptr1 = nod(OADDR, nptr1, N);
2798 nptr2 = nod(OSPTR, l2, N);
2800 fn = syslook("memmove", 1);
2801 argtype(fn, s->type->type); // 1 old []any
2802 argtype(fn, s->type->type); // 2 ret []any
2804 nwid = cheapexpr(conv(nod(OLEN, l2, N), types[TUINTPTR]), &l);
2805 nwid = nod(OMUL, nwid, nodintconst(s->type->type->width));
2806 nt = mkcall1(fn, T, &l, nptr1, nptr2, nwid);
2810 // s = s[:len(l1)+len(l2)]
2811 nt = nod(OADD, nod(OLEN, l1, N), nod(OLEN, l2, N));
2812 nt = nod(OSLICE, s, nod(OKEY, N, nt));
2814 l = list(l, nod(OAS, s, nt));
2816 typechecklist(l, Etop);
2818 *init = concat(*init, l);
2822 // expand append(src, a [, b]* ) to
2826 // const argc = len(args) - 1
2827 // if cap(s) - len(s) < argc {
2828 // s = growslice(s, argc)
2838 append(Node *n, NodeList **init)
2841 Node *nsrc, *ns, *nn, *na, *nx, *fn;
2844 walkexprlistsafe(n->list, init);
2846 // walkexprlistsafe will leave OINDEX (s[n]) alone if both s
2847 // and n are name or literal, but those may index the slice we're
2848 // modifying here. Fix explicitly.
2849 for(l=n->list; l; l=l->next)
2850 l->n = cheapexpr(l->n, init);
2854 // Resolve slice type of multi-valued return.
2855 if(istype(nsrc->type, TSTRUCT))
2856 nsrc->type = nsrc->type->type->type;
2857 argc = count(n->list) - 1;
2864 ns = temp(nsrc->type);
2865 l = list(l, nod(OAS, ns, nsrc)); // s = src
2867 na = nodintconst(argc); // const argc
2868 nx = nod(OIF, N, N); // if cap(s) - len(s) < argc
2869 nx->ntest = nod(OLT, nod(OSUB, nod(OCAP, ns, N), nod(OLEN, ns, N)), na);
2871 fn = syslook("growslice", 1); // growslice(<type>, old []T, n int64) (ret []T)
2872 argtype(fn, ns->type->type); // 1 old []any
2873 argtype(fn, ns->type->type); // 2 ret []any
2875 nx->nbody = list1(nod(OAS, ns, mkcall1(fn, ns->type, &nx->ninit,
2878 conv(na, types[TINT64]))));
2881 nn = temp(types[TINT]);
2882 l = list(l, nod(OAS, nn, nod(OLEN, ns, N))); // n = len(s)
2884 nx = nod(OSLICE, ns, nod(OKEY, N, nod(OADD, nn, na))); // ...s[:n+argc]
2886 l = list(l, nod(OAS, ns, nx)); // s = s[:n+argc]
2888 for (a = n->list->next; a != nil; a = a->next) {
2889 nx = nod(OINDEX, ns, nn); // s[n] ...
2891 l = list(l, nod(OAS, nx, a->n)); // s[n] = arg
2893 l = list(l, nod(OAS, nn, nod(OADD, nn, nodintconst(1)))); // n = n + 1
2896 typechecklist(l, Etop);
2898 *init = concat(*init, l);
2902 // Lower copy(a, b) to a memmove call or a runtime call.
2906 // if n > len(b) { n = len(b) }
2907 // memmove(a.ptr, b.ptr, n*sizeof(elem(a)))
2911 // Also works if b is a string.
2914 copyany(Node *n, NodeList **init, int runtimecall)
2916 Node *nl, *nr, *nfrm, *nto, *nif, *nlen, *nwid, *fn;
2919 if(haspointers(n->left->type->type)) {
2920 fn = writebarrierfn("writebarriercopy", n->left->type, n->right->type);
2921 return mkcall1(fn, n->type, init, typename(n->left->type->type), n->left, n->right);
2925 if(n->right->type->etype == TSTRING)
2926 fn = syslook("slicestringcopy", 1);
2928 fn = syslook("slicecopy", 1);
2929 argtype(fn, n->left->type);
2930 argtype(fn, n->right->type);
2931 return mkcall1(fn, n->type, init,
2933 nodintconst(n->left->type->type->width));
2935 walkexpr(&n->left, init);
2936 walkexpr(&n->right, init);
2937 nl = temp(n->left->type);
2938 nr = temp(n->right->type);
2940 l = list(l, nod(OAS, nl, n->left));
2941 l = list(l, nod(OAS, nr, n->right));
2943 nfrm = nod(OSPTR, nr, N);
2944 nto = nod(OSPTR, nl, N);
2946 nlen = temp(types[TINT]);
2948 l = list(l, nod(OAS, nlen, nod(OLEN, nl, N)));
2949 // if n > len(frm) { n = len(frm) }
2950 nif = nod(OIF, N, N);
2951 nif->ntest = nod(OGT, nlen, nod(OLEN, nr, N));
2952 nif->nbody = list(nif->nbody,
2953 nod(OAS, nlen, nod(OLEN, nr, N)));
2957 fn = syslook("memmove", 1);
2958 argtype(fn, nl->type->type);
2959 argtype(fn, nl->type->type);
2960 nwid = temp(types[TUINTPTR]);
2961 l = list(l, nod(OAS, nwid, conv(nlen, types[TUINTPTR])));
2962 nwid = nod(OMUL, nwid, nodintconst(nl->type->type->width));
2963 l = list(l, mkcall1(fn, T, init, nto, nfrm, nwid));
2965 typechecklist(l, Etop);
2967 *init = concat(*init, l);
2971 // Generate frontend part for OSLICE[3][ARR|STR]
2974 sliceany(Node* n, NodeList **init)
2976 int bounded, slice3;
2977 Node *src, *lb, *hb, *cb, *bound, *chk, *chk0, *chk1, *chk2;
2978 int64 lbv, hbv, cbv, bv, w;
2981 // print("before sliceany: %+N\n", n);
2984 lb = n->right->left;
2985 slice3 = n->op == OSLICE3 || n->op == OSLICE3ARR;
2987 hb = n->right->right->left;
2988 cb = n->right->right->right;
2990 hb = n->right->right;
2996 if(n->op == OSLICESTR)
2997 bound = nod(OLEN, src, N);
2999 bound = nod(OCAP, src, N);
3001 typecheck(&bound, Erv);
3002 walkexpr(&bound, init); // if src is an array, bound will be a const now.
3004 // static checks if possible
3006 if(isconst(bound, CTINT)) {
3007 if(!smallintconst(bound))
3008 yyerror("array len too large");
3010 bv = mpgetfix(bound->val.u.xval);
3013 if(isconst(cb, CTINT)) {
3014 cbv = mpgetfix(cb->val.u.xval);
3015 if(cbv < 0 || cbv > bv)
3016 yyerror("slice index out of bounds");
3018 if(isconst(hb, CTINT)) {
3019 hbv = mpgetfix(hb->val.u.xval);
3020 if(hbv < 0 || hbv > bv)
3021 yyerror("slice index out of bounds");
3023 if(isconst(lb, CTINT)) {
3024 lbv = mpgetfix(lb->val.u.xval);
3025 if(lbv < 0 || lbv > bv) {
3026 yyerror("slice index out of bounds");
3033 // Checking src[lb:hb:cb] or src[lb:hb].
3034 // if chk0 || chk1 || chk2 { panicslice() }
3036 chk0 = N; // cap(src) < cb
3037 chk1 = N; // cb < hb for src[lb:hb:cb]; cap(src) < hb for src[lb:hb]
3038 chk2 = N; // hb < lb
3040 // All comparisons are unsigned to avoid testing < 0.
3041 bt = types[simtype[TUINT]];
3042 if(cb != N && cb->type->width > 4)
3043 bt = types[TUINT64];
3044 if(hb != N && hb->type->width > 4)
3045 bt = types[TUINT64];
3046 if(lb != N && lb->type->width > 4)
3047 bt = types[TUINT64];
3049 bound = cheapexpr(conv(bound, bt), init);
3052 cb = cheapexpr(conv(cb, bt), init);
3054 chk0 = nod(OLT, bound, cb);
3056 // When we figure out what this means, implement it.
3057 fatal("slice3 with cb == N"); // rejected by parser
3061 hb = cheapexpr(conv(hb, bt), init);
3064 chk1 = nod(OLT, cb, hb);
3066 chk1 = nod(OLT, bound, hb);
3069 // When we figure out what this means, implement it.
3070 fatal("slice3 with hb == N"); // rejected by parser
3071 } else if(n->op == OSLICEARR) {
3074 hb = nod(OLEN, src, N);
3075 typecheck(&hb, Erv);
3076 walkexpr(&hb, init);
3077 hb = cheapexpr(conv(hb, bt), init);
3081 lb = cheapexpr(conv(lb, bt), init);
3083 chk2 = nod(OLT, hb, lb);
3086 if(chk0 != N || chk1 != N || chk2 != N) {
3087 chk = nod(OIF, N, N);
3088 chk->nbody = list1(mkcall("panicslice", T, init));
3096 chk->ntest = nod(OOROR, chk->ntest, chk1);
3102 chk->ntest = nod(OOROR, chk->ntest, chk2);
3104 typecheck(&chk, Etop);
3106 *init = concat(*init, chk->ninit);
3108 *init = list(*init, chk);
3111 // prepare new cap, len and offs for backend cgen_slice
3112 // cap = bound [ - lo ]
3118 bound = conv(cb, types[simtype[TUINT]]);
3120 bound = nod(OSUB, conv(cb, types[simtype[TUINT]]), conv(lb, types[simtype[TUINT]]));
3121 typecheck(&bound, Erv);
3122 walkexpr(&bound, init);
3123 n->list = list(n->list, bound);
3127 hb = conv(hb, types[simtype[TUINT]]);
3129 hb = nod(OSUB, conv(hb, types[simtype[TUINT]]), conv(lb, types[simtype[TUINT]]));
3130 typecheck(&hb, Erv);
3131 walkexpr(&hb, init);
3132 n->list = list(n->list, hb);
3134 // offs = [width *] lo, but omit if zero
3136 if(n->op == OSLICESTR)
3139 w = n->type->type->width;
3140 lb = conv(lb, types[TUINTPTR]);
3142 lb = nod(OMUL, nodintconst(w), lb);
3143 typecheck(&lb, Erv);
3144 walkexpr(&lb, init);
3145 n->list = list(n->list, lb);
3148 // print("after sliceany: %+N\n", n);
3161 // Should only arrive here with large memory or
3162 // a struct/array containing a non-memory field/element.
3163 // Small memory is handled inline, and single non-memory
3164 // is handled during type check (OCMPSTR etc).
3165 a = algtype1(t, nil);
3166 if(a != AMEM && a != -1)
3167 fatal("eqfor %T", t);
3170 n = syslook("memequal", 1);
3176 sym = typesymprefix(".eq", t);
3179 ntype = nod(OTFUNC, N, N);
3180 ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
3181 ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
3182 ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
3183 ntype->rlist = list(ntype->rlist, nod(ODCLFIELD, N, typenod(types[TBOOL])));
3184 typecheck(&ntype, Etype);
3185 n->type = ntype->type;
3196 for(t1=t->type; t1!=T; t1=t1->down)
3202 walkcompare(Node **np, NodeList **init)
3204 Node *n, *l, *r, *call, *a, *li, *ri, *expr, *cmpl, *cmpr;
3210 // Must be comparison of array or struct.
3211 // Otherwise back end handles it.
3225 while(cmpl != N && cmpl->op == OCONVNOP)
3228 while(cmpr != N && cmpr->op == OCONVNOP)
3231 if(!islvalue(cmpl) || !islvalue(cmpr)) {
3232 fatal("arguments of comparison must be lvalues - %N %N", cmpl, cmpr);
3236 a = nod(OAS, l, nod(OADDR, cmpl, N));
3237 a->right->etype = 1; // addr does not escape
3238 typecheck(&a, Etop);
3239 *init = list(*init, a);
3242 a = nod(OAS, r, nod(OADDR, cmpr, N));
3243 a->right->etype = 1; // addr does not escape
3244 typecheck(&a, Etop);
3245 *init = list(*init, a);
3252 if(t->etype == TARRAY &&
3254 issimple[t->type->etype]) {
3255 // Four or fewer elements of a basic type.
3256 // Unroll comparisons.
3257 for(i=0; i<t->bound; i++) {
3258 li = nod(OINDEX, l, nodintconst(i));
3259 ri = nod(OINDEX, r, nodintconst(i));
3260 a = nod(n->op, li, ri);
3264 expr = nod(andor, expr, a);
3267 expr = nodbool(n->op == OEQ);
3272 if(t->etype == TSTRUCT && countfield(t) <= 4) {
3273 // Struct of four or fewer fields.
3274 // Inline comparisons.
3275 for(t1=t->type; t1; t1=t1->down) {
3276 if(isblanksym(t1->sym))
3278 li = nod(OXDOT, l, newname(t1->sym));
3279 ri = nod(OXDOT, r, newname(t1->sym));
3280 a = nod(n->op, li, ri);
3284 expr = nod(andor, expr, a);
3287 expr = nodbool(n->op == OEQ);
3292 // Chose not to inline. Call equality function directly.
3293 call = nod(OCALL, eqfor(t), N);
3294 call->list = list(call->list, l);
3295 call->list = list(call->list, r);
3296 call->list = list(call->list, nodintconst(t->width));
3299 r = nod(ONOT, r, N);
3305 if(r->type != n->type) {
3306 r = nod(OCONVNOP, r, N);
3315 samecheap(Node *a, Node *b)
3318 while(a != N && b != N && a->op == b->op) {
3328 if(ar->op != ONAME || br->op != ONAME || ar->sym != br->sym)
3334 if(!isconst(ar, CTINT) || !isconst(br, CTINT) || mpcmpfixfix(ar->val.u.xval, br->val.u.xval) != 0)
3345 walkrotate(Node **np)
3356 // Want << | >> or >> | << or << ^ >> or >> ^ << on unsigned value.
3359 if((n->op != OOR && n->op != OXOR) ||
3360 (l->op != OLSH && l->op != ORSH) ||
3361 (r->op != OLSH && r->op != ORSH) ||
3362 n->type == T || issigned[n->type->etype] ||
3367 // Want same, side effect-free expression on lhs of both shifts.
3368 if(!samecheap(l->left, r->left))
3371 // Constants adding to width?
3372 w = l->type->width * 8;
3373 if(smallintconst(l->right) && smallintconst(r->right)) {
3374 if((sl=mpgetfix(l->right->val.u.xval)) >= 0 && (sr=mpgetfix(r->right->val.u.xval)) >= 0 && sl+sr == w)
3379 // TODO: Could allow s and 32-s if s is bounded (maybe s&31 and 32-s&31).
3383 // Rewrite left shift half to left rotate.
3390 // Remove rotate 0 and rotate w.
3391 s = mpgetfix(n->right->val.u.xval);
3392 if(s == 0 || s == w)
3400 * walkmul rewrites integer multiplication by powers of two as shifts.
3403 walkmul(Node **np, NodeList **init)
3409 if(!isint[n->type->etype])
3412 if(n->right->op == OLITERAL) {
3415 } else if(n->left->op == OLITERAL) {
3423 // x*0 is 0 (and side effects of x).
3424 if(mpgetfix(nr->val.u.xval) == 0) {
3425 cheapexpr(nl, init);
3426 nodconst(n, n->type, 0);
3430 // nr is a constant.
3435 // negative power of 2, like -16
3440 w = nl->type->width*8;
3441 if(pow+1 >= w)// too big, shouldn't happen
3444 nl = cheapexpr(nl, init);
3452 n = nod(OLSH, nl, nodintconst(pow));
3456 n = nod(OMINUS, n, N);
3464 * walkdiv rewrites division by a constant as less expensive
3468 walkdiv(Node **np, NodeList **init)
3470 Node *n, *nl, *nr, *nc;
3471 Node *n1, *n2, *n3, *n4;
3472 int pow; // if >= 0, nr is 1<<pow
3473 int s; // 1 if nr is negative.
3483 if(n->right->op != OLITERAL)
3485 // nr is a constant.
3486 nl = cheapexpr(n->left, init);
3489 // special cases of mod/div
3491 w = nl->type->width*8;
3495 // negative power of 2
3501 // divisor too large.
3512 nodconst(n, n->type, 0);
3523 if(issigned[n->type->etype]) {
3525 // signed modulo 2^pow is like ANDing
3526 // with the last pow bits, but if nl < 0,
3527 // nl & (2^pow-1) is (nl+1)%2^pow - 1.
3528 nc = nod(OXXX, N, N);
3529 nodconst(nc, types[simtype[TUINT]], w-1);
3530 n1 = nod(ORSH, nl, nc); // n1 = -1 iff nl < 0.
3532 typecheck(&n1, Erv);
3533 n1 = cheapexpr(n1, init);
3534 // n = (nl+ε)&1 -ε where ε=1 iff nl<0.
3535 n2 = nod(OSUB, nl, n1);
3536 nc = nod(OXXX, N, N);
3537 nodconst(nc, nl->type, 1);
3538 n3 = nod(OAND, n2, nc);
3539 n = nod(OADD, n3, n1);
3541 // n = (nl+ε)&(nr-1) - ε where ε=2^pow-1 iff nl<0.
3542 nc = nod(OXXX, N, N);
3543 nodconst(nc, nl->type, (1LL<<pow)-1);
3544 n2 = nod(OAND, n1, nc); // n2 = 2^pow-1 iff nl<0.
3545 typecheck(&n2, Erv);
3546 n2 = cheapexpr(n2, init);
3548 n3 = nod(OADD, nl, n2);
3549 n4 = nod(OAND, n3, nc);
3550 n = nod(OSUB, n4, n2);
3554 // arithmetic right shift does not give the correct rounding.
3555 // if nl >= 0, nl >> n == nl / nr
3556 // if nl < 0, we want to add 2^n-1 first.
3557 nc = nod(OXXX, N, N);
3558 nodconst(nc, types[simtype[TUINT]], w-1);
3559 n1 = nod(ORSH, nl, nc); // n1 = -1 iff nl < 0.
3562 n->left = nod(OSUB, nl, n1);
3564 // Do a logical right right on -1 to keep pow bits.
3565 nc = nod(OXXX, N, N);
3566 nodconst(nc, types[simtype[TUINT]], w-pow);
3567 n2 = nod(ORSH, conv(n1, tounsigned(nl->type)), nc);
3568 n->left = nod(OADD, nl, conv(n2, nl->type));
3570 // n = (nl + 2^pow-1) >> pow
3572 nc = nod(OXXX, N, N);
3573 nodconst(nc, types[simtype[TUINT]], pow);
3578 n = nod(OMINUS, n, N);
3581 nc = nod(OXXX, N, N);
3585 nodconst(nc, nl->type, mpgetfix(nr->val.u.xval)-1);
3589 nodconst(nc, types[simtype[TUINT]], pow);
3598 // try to do division by multiply by (2^w)/d
3599 // see hacker's delight chapter 10
3600 // TODO: support 64-bit magic multiply here.
3602 if(issigned[nl->type->etype]) {
3603 m.sd = mpgetfix(nr->val.u.xval);
3606 m.ud = mpgetfix(nr->val.u.xval);
3612 // We have a quick division method so use it
3617 switch(simtype[nl->type->etype]) {
3624 // n1 = nl * magic >> w (HMUL)
3625 nc = nod(OXXX, N, N);
3626 nodconst(nc, nl->type, m.um);
3627 n1 = nod(OMUL, nl, nc);
3628 typecheck(&n1, Erv);
3631 // Select a Go type with (at least) twice the width.
3632 switch(simtype[nl->type->etype]) {
3637 twide = types[TUINT32];
3640 twide = types[TUINT64];
3644 twide = types[TINT32];
3647 twide = types[TINT64];
3651 // add numerator (might overflow).
3653 n2 = nod(OADD, conv(n1, twide), conv(nl, twide));
3656 nc = nod(OXXX, N, N);
3657 nodconst(nc, types[TUINT], m.s);
3658 n = conv(nod(ORSH, n2, nc), nl->type);
3661 nc = nod(OXXX, N, N);
3662 nodconst(nc, types[TUINT], m.s);
3663 n = nod(ORSH, n1, nc);
3670 // n1 = nl * magic >> w
3671 nc = nod(OXXX, N, N);
3672 nodconst(nc, nl->type, m.sm);
3673 n1 = nod(OMUL, nl, nc);
3674 typecheck(&n1, Erv);
3677 // add the numerator.
3678 n1 = nod(OADD, n1, nl);
3681 nc = nod(OXXX, N, N);
3682 nodconst(nc, types[TUINT], m.s);
3683 n2 = conv(nod(ORSH, n1, nc), nl->type);
3684 // add 1 iff n1 is negative.
3685 nc = nod(OXXX, N, N);
3686 nodconst(nc, types[TUINT], w-1);
3687 n3 = nod(ORSH, nl, nc); // n4 = -1 iff n1 is negative.
3688 n = nod(OSUB, n2, n3);
3691 n = nod(OMINUS, n, N);
3697 // rewrite as A%B = A - (A/B*B).
3698 n1 = nod(ODIV, nl, nr);
3699 n2 = nod(OMUL, n1, nr);
3700 n = nod(OSUB, nl, n2);
3709 // return 1 if integer n must be in range [0, max), 0 otherwise
3711 bounded(Node *n, int64 max)
3717 if(n->type == T || !isint[n->type->etype])
3720 sign = issigned[n->type->etype];
3721 bits = 8*n->type->width;
3723 if(smallintconst(n)) {
3724 v = mpgetfix(n->val.u.xval);
3725 return 0 <= v && v < max;
3731 if(smallintconst(n->left)) {
3732 v = mpgetfix(n->left->val.u.xval);
3733 } else if(smallintconst(n->right)) {
3734 v = mpgetfix(n->right->val.u.xval);
3736 if(0 <= v && v < max)
3741 if(!sign && smallintconst(n->right)) {
3742 v = mpgetfix(n->right->val.u.xval);
3743 if(0 <= v && v <= max)
3749 if(!sign && smallintconst(n->right)) {
3750 v = mpgetfix(n->right->val.u.xval);
3751 while(bits > 0 && v >= 2) {
3759 if(!sign && smallintconst(n->right)) {
3760 v = mpgetfix(n->right->val.u.xval);
3768 if(!sign && bits <= 62 && (1LL<<bits) <= max)
3779 if(!fieldtrack_enabled)
3784 fatal("usefield %O", n->op);
3790 field = n->paramfld;
3792 fatal("usefield %T %S without paramfld", n->left->type, n->right->sym);
3793 if(field->note == nil || strstr(field->note->s, "go:\"track\"") == nil)
3797 if(field->lastfn == curfn)
3799 field->lastfn = curfn;
3800 field->outer = n->left->type;
3801 if(isptr[field->outer->etype])
3802 field->outer = field->outer->type;
3803 if(field->outer->sym == S)
3804 yyerror("tracked field must be in named struct type");
3805 if(!exportname(field->sym->name))
3806 yyerror("tracked field must be exported (upper case)");
3810 l->down = curfn->paramfld;
3811 curfn->paramfld = l;
3815 candiscardlist(NodeList *l)
3818 if(!candiscard(l->n))
3885 // Discardable as long as the subpieces are.
3890 // Discardable as long as we know it's not division by zero.
3891 if(isconst(n->right, CTINT) && mpcmpfixc(n->right->val.u.xval, 0) != 0)
3893 if(isconst(n->right, CTFLT) && mpcmpfltc(n->right->val.u.fval, 0) != 0)
3899 // Discardable as long as we know it won't fail because of a bad size.
3900 if(isconst(n->left, CTINT) && mpcmpfixc(n->left->val.u.xval, 0) == 0)
3905 // Difficult to tell what sizes are okay.
3909 if(!candiscard(n->left) ||
3910 !candiscard(n->right) ||
3911 !candiscard(n->ntest) ||
3912 !candiscard(n->nincr) ||
3913 !candiscardlist(n->ninit) ||
3914 !candiscardlist(n->nbody) ||
3915 !candiscardlist(n->nelse) ||
3916 !candiscardlist(n->list) ||
3917 !candiscardlist(n->rlist)) {
3927 // func(a1, a2, a3) {
3928 // print(a1, a2, a3)
3930 // and same for println.
3932 walkprintfunc(Node **np, NodeList **init)
3935 Node *a, *fn, *t, *oldfn;
3936 NodeList *l, *printargs;
3943 if(n->ninit != nil) {
3944 walkstmtlist(n->ninit);
3945 *init = concat(*init, n->ninit);
3949 t = nod(OTFUNC, N, N);
3952 for(l=n->list; l != nil; l=l->next) {
3953 snprint(buf, sizeof buf, "a%d", num++);
3954 a = nod(ODCLFIELD, newname(lookup(buf)), typenod(l->n->type));
3955 t->list = list(t->list, a);
3956 printargs = list(printargs, a->left);
3959 fn = nod(ODCLFUNC, N, N);
3960 snprint(buf, sizeof buf, "print·%d", ++prgen);
3961 fn->nname = newname(lookup(buf));
3962 fn->nname->defn = fn;
3963 fn->nname->ntype = t;
3964 declare(fn->nname, PFUNC);
3970 a = nod(n->op, N, N);
3971 a->list = printargs;
3972 typecheck(&a, Etop);
3975 fn->nbody = list1(a);
3979 typecheck(&fn, Etop);
3980 typechecklist(fn->nbody, Etop);
3981 xtop = list(xtop, fn);
3984 a = nod(OCALL, N, N);
3985 a->left = fn->nname;
3987 typecheck(&a, Etop);