github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/gc/walk.c (about) 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. 4 5 #include <u.h> 6 #include <libc.h> 7 #include "go.h" 8 9 static Node* walkprint(Node*, NodeList**, int); 10 static Node* mapfn(char*, Type*); 11 static Node* mapfndel(char*, Type*); 12 static Node* ascompatee1(int, Node*, Node*, NodeList**); 13 static NodeList* ascompatee(int, NodeList*, NodeList*, NodeList**); 14 static NodeList* ascompatet(int, NodeList*, Type**, int, NodeList**); 15 static NodeList* ascompatte(int, Node*, int, Type**, NodeList*, int, NodeList**); 16 static Node* convas(Node*, NodeList**); 17 static void heapmoves(void); 18 static NodeList* paramstoheap(Type **argin, int out); 19 static NodeList* reorder1(NodeList*); 20 static NodeList* reorder3(NodeList*); 21 static Node* addstr(Node*, NodeList**); 22 static Node* appendslice(Node*, NodeList**); 23 static Node* append(Node*, NodeList**); 24 static Node* sliceany(Node*, NodeList**); 25 static void walkcompare(Node**, NodeList**); 26 static void walkrotate(Node**); 27 static void walkmul(Node**, NodeList**); 28 static void walkdiv(Node**, NodeList**); 29 static int bounded(Node*, int64); 30 static Mpint mpzero; 31 32 void 33 walk(Node *fn) 34 { 35 char s[50]; 36 NodeList *l; 37 int lno; 38 39 curfn = fn; 40 41 if(debug['W']) { 42 snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym); 43 dumplist(s, curfn->nbody); 44 } 45 46 lno = lineno; 47 48 // Final typecheck for any unused variables. 49 // It's hard to be on the heap when not-used, but best to be consistent about &~PHEAP here and below. 50 for(l=fn->dcl; l; l=l->next) 51 if(l->n->op == ONAME && (l->n->class&~PHEAP) == PAUTO) 52 typecheck(&l->n, Erv | Easgn); 53 54 // Propagate the used flag for typeswitch variables up to the NONAME in it's definition. 55 for(l=fn->dcl; l; l=l->next) 56 if(l->n->op == ONAME && (l->n->class&~PHEAP) == PAUTO && l->n->defn && l->n->defn->op == OTYPESW && l->n->used) 57 l->n->defn->left->used++; 58 59 for(l=fn->dcl; l; l=l->next) { 60 if(l->n->op != ONAME || (l->n->class&~PHEAP) != PAUTO || l->n->sym->name[0] == '&' || l->n->used) 61 continue; 62 if(l->n->defn && l->n->defn->op == OTYPESW) { 63 if(l->n->defn->left->used) 64 continue; 65 lineno = l->n->defn->left->lineno; 66 yyerror("%S declared and not used", l->n->sym); 67 l->n->defn->left->used = 1; // suppress repeats 68 } else { 69 lineno = l->n->lineno; 70 yyerror("%S declared and not used", l->n->sym); 71 } 72 } 73 74 lineno = lno; 75 if(nerrors != 0) 76 return; 77 walkstmtlist(curfn->nbody); 78 if(debug['W']) { 79 snprint(s, sizeof(s), "after walk %S", curfn->nname->sym); 80 dumplist(s, curfn->nbody); 81 } 82 heapmoves(); 83 if(debug['W'] && curfn->enter != nil) { 84 snprint(s, sizeof(s), "enter %S", curfn->nname->sym); 85 dumplist(s, curfn->enter); 86 } 87 } 88 89 90 void 91 walkstmtlist(NodeList *l) 92 { 93 for(; l; l=l->next) 94 walkstmt(&l->n); 95 } 96 97 static int 98 samelist(NodeList *a, NodeList *b) 99 { 100 for(; a && b; a=a->next, b=b->next) 101 if(a->n != b->n) 102 return 0; 103 return a == b; 104 } 105 106 static int 107 paramoutheap(Node *fn) 108 { 109 NodeList *l; 110 111 for(l=fn->dcl; l; l=l->next) { 112 switch(l->n->class) { 113 case PPARAMOUT: 114 case PPARAMOUT|PHEAP: 115 return l->n->addrtaken; 116 case PAUTO: 117 case PAUTO|PHEAP: 118 // stop early - parameters are over 119 return 0; 120 } 121 } 122 return 0; 123 } 124 125 void 126 walkstmt(Node **np) 127 { 128 NodeList *init; 129 NodeList *ll, *rl; 130 int cl; 131 Node *n, *f; 132 133 n = *np; 134 if(n == N) 135 return; 136 137 setlineno(n); 138 139 walkstmtlist(n->ninit); 140 141 switch(n->op) { 142 default: 143 if(n->op == ONAME) 144 yyerror("%S is not a top level statement", n->sym); 145 else 146 yyerror("%O is not a top level statement", n->op); 147 dump("nottop", n); 148 break; 149 150 case OAS: 151 case OASOP: 152 case OAS2: 153 case OAS2DOTTYPE: 154 case OAS2RECV: 155 case OAS2FUNC: 156 case OAS2MAPR: 157 case OCLOSE: 158 case OCOPY: 159 case OCALLMETH: 160 case OCALLINTER: 161 case OCALL: 162 case OCALLFUNC: 163 case ODELETE: 164 case OSEND: 165 case ORECV: 166 case OPRINT: 167 case OPRINTN: 168 case OPANIC: 169 case OEMPTY: 170 case ORECOVER: 171 if(n->typecheck == 0) 172 fatal("missing typecheck: %+N", n); 173 init = n->ninit; 174 n->ninit = nil; 175 walkexpr(&n, &init); 176 addinit(&n, init); 177 break; 178 179 case OBREAK: 180 case ODCL: 181 case OCONTINUE: 182 case OFALL: 183 case OGOTO: 184 case OLABEL: 185 case ODCLCONST: 186 case ODCLTYPE: 187 case OCHECKNOTNIL: 188 break; 189 190 case OBLOCK: 191 walkstmtlist(n->list); 192 break; 193 194 case OXCASE: 195 yyerror("case statement out of place"); 196 n->op = OCASE; 197 case OCASE: 198 walkstmt(&n->right); 199 break; 200 201 case ODEFER: 202 hasdefer = 1; 203 switch(n->left->op) { 204 case OPRINT: 205 case OPRINTN: 206 walkexprlist(n->left->list, &n->ninit); 207 n->left = walkprint(n->left, &n->ninit, 1); 208 break; 209 default: 210 walkexpr(&n->left, &n->ninit); 211 break; 212 } 213 break; 214 215 case OFOR: 216 if(n->ntest != N) { 217 walkstmtlist(n->ntest->ninit); 218 init = n->ntest->ninit; 219 n->ntest->ninit = nil; 220 walkexpr(&n->ntest, &init); 221 addinit(&n->ntest, init); 222 } 223 walkstmt(&n->nincr); 224 walkstmtlist(n->nbody); 225 break; 226 227 case OIF: 228 walkexpr(&n->ntest, &n->ninit); 229 walkstmtlist(n->nbody); 230 walkstmtlist(n->nelse); 231 break; 232 233 case OPROC: 234 switch(n->left->op) { 235 case OPRINT: 236 case OPRINTN: 237 walkexprlist(n->left->list, &n->ninit); 238 n->left = walkprint(n->left, &n->ninit, 1); 239 break; 240 default: 241 walkexpr(&n->left, &n->ninit); 242 break; 243 } 244 break; 245 246 case ORETURN: 247 walkexprlist(n->list, &n->ninit); 248 if(n->list == nil) 249 break; 250 if((curfn->type->outnamed && count(n->list) > 1) || paramoutheap(curfn)) { 251 // assign to the function out parameters, 252 // so that reorder3 can fix up conflicts 253 rl = nil; 254 for(ll=curfn->dcl; ll != nil; ll=ll->next) { 255 cl = ll->n->class & ~PHEAP; 256 if(cl == PAUTO) 257 break; 258 if(cl == PPARAMOUT) 259 rl = list(rl, ll->n); 260 } 261 if(samelist(rl, n->list)) { 262 // special return in disguise 263 n->list = nil; 264 break; 265 } 266 if(count(n->list) == 1 && count(rl) > 1) { 267 // OAS2FUNC in disguise 268 f = n->list->n; 269 if(f->op != OCALLFUNC && f->op != OCALLMETH && f->op != OCALLINTER) 270 fatal("expected return of call, have %N", f); 271 n->list = concat(list1(f), ascompatet(n->op, rl, &f->type, 0, &n->ninit)); 272 break; 273 } 274 275 // move function calls out, to make reorder3's job easier. 276 walkexprlistsafe(n->list, &n->ninit); 277 ll = ascompatee(n->op, rl, n->list, &n->ninit); 278 n->list = reorder3(ll); 279 break; 280 } 281 ll = ascompatte(n->op, nil, 0, getoutarg(curfn->type), n->list, 1, &n->ninit); 282 n->list = ll; 283 break; 284 285 case OSELECT: 286 walkselect(n); 287 break; 288 289 case OSWITCH: 290 walkswitch(n); 291 break; 292 293 case ORANGE: 294 walkrange(n); 295 break; 296 297 case OXFALL: 298 yyerror("fallthrough statement out of place"); 299 n->op = OFALL; 300 break; 301 } 302 303 if(n->op == ONAME) 304 fatal("walkstmt ended up with name: %+N", n); 305 306 *np = n; 307 } 308 309 310 /* 311 * walk the whole tree of the body of an 312 * expression or simple statement. 313 * the types expressions are calculated. 314 * compile-time constants are evaluated. 315 * complex side effects like statements are appended to init 316 */ 317 318 void 319 walkexprlist(NodeList *l, NodeList **init) 320 { 321 for(; l; l=l->next) 322 walkexpr(&l->n, init); 323 } 324 325 void 326 walkexprlistsafe(NodeList *l, NodeList **init) 327 { 328 for(; l; l=l->next) { 329 l->n = safeexpr(l->n, init); 330 walkexpr(&l->n, init); 331 } 332 } 333 334 void 335 walkexpr(Node **np, NodeList **init) 336 { 337 Node *r, *l, *var, *a; 338 NodeList *ll, *lr, *lpost; 339 Type *t; 340 int et; 341 int64 v; 342 int32 lno; 343 Node *n, *fn, *n1, *n2; 344 Sym *sym; 345 char buf[100], *p; 346 347 n = *np; 348 349 if(n == N) 350 return; 351 352 if(init == &n->ninit) { 353 // not okay to use n->ninit when walking n, 354 // because we might replace n with some other node 355 // and would lose the init list. 356 fatal("walkexpr init == &n->ninit"); 357 } 358 359 if(n->ninit != nil) { 360 walkstmtlist(n->ninit); 361 *init = concat(*init, n->ninit); 362 n->ninit = nil; 363 } 364 365 // annoying case - not typechecked 366 if(n->op == OKEY) { 367 walkexpr(&n->left, init); 368 walkexpr(&n->right, init); 369 return; 370 } 371 372 lno = setlineno(n); 373 374 if(debug['w'] > 1) 375 dump("walk-before", n); 376 377 if(n->typecheck != 1) 378 fatal("missed typecheck: %+N\n", n); 379 380 switch(n->op) { 381 default: 382 dump("walk", n); 383 fatal("walkexpr: switch 1 unknown op %+hN", n); 384 break; 385 386 case OTYPE: 387 case ONONAME: 388 case OINDREG: 389 case OEMPTY: 390 goto ret; 391 392 case ONOT: 393 case OMINUS: 394 case OPLUS: 395 case OCOM: 396 case OREAL: 397 case OIMAG: 398 case ODOTMETH: 399 case ODOTINTER: 400 walkexpr(&n->left, init); 401 goto ret; 402 403 case OIND: 404 if(n->left->type->type->width == 0) { 405 n->left = cheapexpr(n->left, init); 406 checknotnil(n->left, init); 407 } 408 walkexpr(&n->left, init); 409 goto ret; 410 411 case ODOT: 412 usefield(n); 413 walkexpr(&n->left, init); 414 goto ret; 415 416 case ODOTPTR: 417 usefield(n); 418 if(n->op == ODOTPTR && n->left->type->type->width == 0) { 419 n->left = cheapexpr(n->left, init); 420 checknotnil(n->left, init); 421 } 422 walkexpr(&n->left, init); 423 goto ret; 424 425 case OEFACE: 426 walkexpr(&n->left, init); 427 walkexpr(&n->right, init); 428 goto ret; 429 430 case OITAB: 431 walkexpr(&n->left, init); 432 goto ret; 433 434 case OLEN: 435 case OCAP: 436 walkexpr(&n->left, init); 437 438 // replace len(*[10]int) with 10. 439 // delayed until now to preserve side effects. 440 t = n->left->type; 441 if(isptr[t->etype]) 442 t = t->type; 443 if(isfixedarray(t)) { 444 safeexpr(n->left, init); 445 nodconst(n, n->type, t->bound); 446 n->typecheck = 1; 447 } 448 goto ret; 449 450 case OLSH: 451 case ORSH: 452 walkexpr(&n->left, init); 453 walkexpr(&n->right, init); 454 shiftwalked: 455 t = n->left->type; 456 n->bounded = bounded(n->right, 8*t->width); 457 if(debug['m'] && n->etype && !isconst(n->right, CTINT)) 458 warn("shift bounds check elided"); 459 goto ret; 460 461 case OAND: 462 case OSUB: 463 case OHMUL: 464 case OLT: 465 case OLE: 466 case OGE: 467 case OGT: 468 case OADD: 469 case OCOMPLEX: 470 case OLROT: 471 walkexpr(&n->left, init); 472 walkexpr(&n->right, init); 473 goto ret; 474 475 case OOR: 476 case OXOR: 477 walkexpr(&n->left, init); 478 walkexpr(&n->right, init); 479 walkrotate(&n); 480 goto ret; 481 482 case OEQ: 483 case ONE: 484 walkexpr(&n->left, init); 485 walkexpr(&n->right, init); 486 walkcompare(&n, init); 487 goto ret; 488 489 case OANDAND: 490 case OOROR: 491 walkexpr(&n->left, init); 492 // cannot put side effects from n->right on init, 493 // because they cannot run before n->left is checked. 494 // save elsewhere and store on the eventual n->right. 495 ll = nil; 496 walkexpr(&n->right, &ll); 497 addinit(&n->right, ll); 498 goto ret; 499 500 case OPRINT: 501 case OPRINTN: 502 walkexprlist(n->list, init); 503 n = walkprint(n, init, 0); 504 goto ret; 505 506 case OPANIC: 507 n = mkcall("panic", T, init, n->left); 508 goto ret; 509 510 case ORECOVER: 511 n = mkcall("recover", n->type, init, nod(OADDR, nodfp, N)); 512 goto ret; 513 514 case OLITERAL: 515 n->addable = 1; 516 goto ret; 517 518 case OCLOSUREVAR: 519 case OCFUNC: 520 n->addable = 1; 521 goto ret; 522 523 case ONAME: 524 if(!(n->class & PHEAP) && n->class != PPARAMREF) 525 n->addable = 1; 526 goto ret; 527 528 case OCALLINTER: 529 t = n->left->type; 530 if(n->list && n->list->n->op == OAS) 531 goto ret; 532 walkexpr(&n->left, init); 533 walkexprlist(n->list, init); 534 ll = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init); 535 n->list = reorder1(ll); 536 goto ret; 537 538 case OCALLFUNC: 539 t = n->left->type; 540 if(n->list && n->list->n->op == OAS) 541 goto ret; 542 543 walkexpr(&n->left, init); 544 walkexprlist(n->list, init); 545 546 ll = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init); 547 n->list = reorder1(ll); 548 goto ret; 549 550 case OCALLMETH: 551 t = n->left->type; 552 if(n->list && n->list->n->op == OAS) 553 goto ret; 554 walkexpr(&n->left, init); 555 walkexprlist(n->list, init); 556 ll = ascompatte(n->op, n, 0, getthis(t), list1(n->left->left), 0, init); 557 lr = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init); 558 ll = concat(ll, lr); 559 n->left->left = N; 560 ullmancalc(n->left); 561 n->list = reorder1(ll); 562 goto ret; 563 564 case OAS: 565 *init = concat(*init, n->ninit); 566 n->ninit = nil; 567 walkexpr(&n->left, init); 568 n->left = safeexpr(n->left, init); 569 570 if(oaslit(n, init)) 571 goto ret; 572 573 walkexpr(&n->right, init); 574 if(n->left != N && n->right != N) { 575 r = convas(nod(OAS, n->left, n->right), init); 576 r->dodata = n->dodata; 577 n = r; 578 } 579 580 goto ret; 581 582 case OAS2: 583 *init = concat(*init, n->ninit); 584 n->ninit = nil; 585 walkexprlistsafe(n->list, init); 586 walkexprlistsafe(n->rlist, init); 587 ll = ascompatee(OAS, n->list, n->rlist, init); 588 ll = reorder3(ll); 589 n = liststmt(ll); 590 goto ret; 591 592 case OAS2FUNC: 593 as2func: 594 // a,b,... = fn() 595 *init = concat(*init, n->ninit); 596 n->ninit = nil; 597 r = n->rlist->n; 598 walkexprlistsafe(n->list, init); 599 walkexpr(&r, init); 600 l = n->list->n; 601 602 // all the really hard stuff - explicit function calls and so on - 603 // is gone, but map assignments remain. 604 // if there are map assignments here, assign via 605 // temporaries, because ascompatet assumes 606 // the targets can be addressed without function calls 607 // and map index has an implicit one. 608 lpost = nil; 609 if(l->op == OINDEXMAP) { 610 var = temp(l->type); 611 n->list->n = var; 612 a = nod(OAS, l, var); 613 typecheck(&a, Etop); 614 lpost = list(lpost, a); 615 } 616 l = n->list->next->n; 617 if(l->op == OINDEXMAP) { 618 var = temp(l->type); 619 n->list->next->n = var; 620 a = nod(OAS, l, var); 621 typecheck(&a, Etop); 622 lpost = list(lpost, a); 623 } 624 ll = ascompatet(n->op, n->list, &r->type, 0, init); 625 walkexprlist(lpost, init); 626 n = liststmt(concat(concat(list1(r), ll), lpost)); 627 goto ret; 628 629 case OAS2RECV: 630 *init = concat(*init, n->ninit); 631 n->ninit = nil; 632 r = n->rlist->n; 633 walkexprlistsafe(n->list, init); 634 walkexpr(&r->left, init); 635 fn = chanfn("chanrecv2", 2, r->left->type); 636 r = mkcall1(fn, getoutargx(fn->type), init, typename(r->left->type), r->left); 637 n->rlist->n = r; 638 n->op = OAS2FUNC; 639 goto as2func; 640 641 case OAS2MAPR: 642 // a,b = m[i]; 643 *init = concat(*init, n->ninit); 644 n->ninit = nil; 645 r = n->rlist->n; 646 walkexprlistsafe(n->list, init); 647 walkexpr(&r->left, init); 648 t = r->left->type; 649 p = nil; 650 if(t->type->width <= 128) { // Check ../../pkg/runtime/hashmap.c:MAXVALUESIZE before changing. 651 switch(simsimtype(t->down)) { 652 case TINT32: 653 case TUINT32: 654 p = "mapaccess2_fast32"; 655 break; 656 case TINT64: 657 case TUINT64: 658 p = "mapaccess2_fast64"; 659 break; 660 case TSTRING: 661 p = "mapaccess2_faststr"; 662 break; 663 } 664 } 665 if(p != nil) { 666 // from: 667 // a,b = m[i] 668 // to: 669 // var,b = mapaccess2_fast*(t, m, i) 670 // a = *var 671 a = n->list->n; 672 var = temp(ptrto(t->type)); 673 var->typecheck = 1; 674 675 fn = mapfn(p, t); 676 r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, r->right); 677 n->rlist = list1(r); 678 n->op = OAS2FUNC; 679 n->list->n = var; 680 walkexpr(&n, init); 681 *init = list(*init, n); 682 683 n = nod(OAS, a, nod(OIND, var, N)); 684 typecheck(&n, Etop); 685 walkexpr(&n, init); 686 goto ret; 687 } 688 fn = mapfn("mapaccess2", t); 689 r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, r->right); 690 n->rlist = list1(r); 691 n->op = OAS2FUNC; 692 goto as2func; 693 694 case ODELETE: 695 *init = concat(*init, n->ninit); 696 n->ninit = nil; 697 l = n->list->n; 698 r = n->list->next->n; 699 t = l->type; 700 n = mkcall1(mapfndel("mapdelete", t), t->down, init, typename(t), l, r); 701 goto ret; 702 703 case OAS2DOTTYPE: 704 // a,b = i.(T) 705 *init = concat(*init, n->ninit); 706 n->ninit = nil; 707 r = n->rlist->n; 708 walkexprlistsafe(n->list, init); 709 if(isblank(n->list->n) && !isinter(r->type)) { 710 strcpy(buf, "assert"); 711 p = buf+strlen(buf); 712 if(isnilinter(r->left->type)) 713 *p++ = 'E'; 714 else 715 *p++ = 'I'; 716 *p++ = '2'; 717 *p++ = 'T'; 718 *p++ = 'O'; 719 *p++ = 'K'; 720 *p = '\0'; 721 722 fn = syslook(buf, 1); 723 ll = list1(typename(r->type)); 724 ll = list(ll, r->left); 725 argtype(fn, r->left->type); 726 n1 = nod(OCALL, fn, N); 727 n1->list = ll; 728 n = nod(OAS, n->list->next->n, n1); 729 typecheck(&n, Etop); 730 walkexpr(&n, init); 731 goto ret; 732 } 733 734 r->op = ODOTTYPE2; 735 walkexpr(&r, init); 736 ll = ascompatet(n->op, n->list, &r->type, 0, init); 737 n = liststmt(concat(list1(r), ll)); 738 goto ret; 739 740 case ODOTTYPE: 741 case ODOTTYPE2: 742 // Build name of function: assertI2E2 etc. 743 strcpy(buf, "assert"); 744 p = buf+strlen(buf); 745 if(isnilinter(n->left->type)) 746 *p++ = 'E'; 747 else 748 *p++ = 'I'; 749 *p++ = '2'; 750 if(isnilinter(n->type)) 751 *p++ = 'E'; 752 else if(isinter(n->type)) 753 *p++ = 'I'; 754 else 755 *p++ = 'T'; 756 if(n->op == ODOTTYPE2) 757 *p++ = '2'; 758 *p = '\0'; 759 760 fn = syslook(buf, 1); 761 ll = list1(typename(n->type)); 762 ll = list(ll, n->left); 763 argtype(fn, n->left->type); 764 argtype(fn, n->type); 765 n = nod(OCALL, fn, N); 766 n->list = ll; 767 typecheck(&n, Erv | Efnstruct); 768 walkexpr(&n, init); 769 goto ret; 770 771 case OCONVIFACE: 772 walkexpr(&n->left, init); 773 774 // Optimize convT2E as a two-word copy when T is uintptr-shaped. 775 if(!isinter(n->left->type) && isnilinter(n->type) && 776 (n->left->type->width == widthptr) && 777 isint[simsimtype(n->left->type)]) { 778 l = nod(OEFACE, typename(n->left->type), n->left); 779 l->type = n->type; 780 l->typecheck = n->typecheck; 781 n = l; 782 goto ret; 783 } 784 785 // Build name of function: convI2E etc. 786 // Not all names are possible 787 // (e.g., we'll never generate convE2E or convE2I). 788 strcpy(buf, "conv"); 789 p = buf+strlen(buf); 790 if(isnilinter(n->left->type)) 791 *p++ = 'E'; 792 else if(isinter(n->left->type)) 793 *p++ = 'I'; 794 else 795 *p++ = 'T'; 796 *p++ = '2'; 797 if(isnilinter(n->type)) 798 *p++ = 'E'; 799 else 800 *p++ = 'I'; 801 *p = '\0'; 802 803 fn = syslook(buf, 1); 804 ll = nil; 805 if(!isinter(n->left->type)) 806 ll = list(ll, typename(n->left->type)); 807 if(!isnilinter(n->type)) 808 ll = list(ll, typename(n->type)); 809 if(!isinter(n->left->type) && !isnilinter(n->type)){ 810 sym = pkglookup(smprint("%-T.%-T", n->left->type, n->type), itabpkg); 811 if(sym->def == N) { 812 l = nod(ONAME, N, N); 813 l->sym = sym; 814 l->type = ptrto(types[TUINT8]); 815 l->addable = 1; 816 l->class = PEXTERN; 817 l->xoffset = 0; 818 sym->def = l; 819 ggloblsym(sym, widthptr, 1, 0); 820 } 821 l = nod(OADDR, sym->def, N); 822 l->addable = 1; 823 ll = list(ll, l); 824 825 if(n->left->type->width == widthptr && 826 isint[simsimtype(n->left->type)]) { 827 /* For pointer types, we can make a special form of optimization 828 * 829 * These statements are put onto the expression init list: 830 * Itab *tab = atomicloadtype(&cache); 831 * if(tab == nil) 832 * tab = typ2Itab(type, itype, &cache); 833 * 834 * The CONVIFACE expression is replaced with this: 835 * OEFACE{tab, ptr}; 836 */ 837 l = temp(ptrto(types[TUINT8])); 838 839 n1 = nod(OAS, l, sym->def); 840 typecheck(&n1, Etop); 841 *init = list(*init, n1); 842 843 fn = syslook("typ2Itab", 1); 844 n1 = nod(OCALL, fn, N); 845 n1->list = ll; 846 typecheck(&n1, Erv); 847 walkexpr(&n1, init); 848 849 n2 = nod(OIF, N, N); 850 n2->ntest = nod(OEQ, l, nodnil()); 851 n2->nbody = list1(nod(OAS, l, n1)); 852 n2->likely = -1; 853 typecheck(&n2, Etop); 854 *init = list(*init, n2); 855 856 l = nod(OEFACE, l, n->left); 857 l->typecheck = n->typecheck; 858 l->type = n->type; 859 n = l; 860 goto ret; 861 } 862 } 863 ll = list(ll, n->left); 864 argtype(fn, n->left->type); 865 argtype(fn, n->type); 866 dowidth(fn->type); 867 n = nod(OCALL, fn, N); 868 n->list = ll; 869 typecheck(&n, Erv); 870 walkexpr(&n, init); 871 goto ret; 872 873 case OCONV: 874 case OCONVNOP: 875 if(thechar == '5') { 876 if(isfloat[n->left->type->etype]) { 877 if(n->type->etype == TINT64) { 878 n = mkcall("float64toint64", n->type, init, conv(n->left, types[TFLOAT64])); 879 goto ret; 880 } 881 if(n->type->etype == TUINT64) { 882 n = mkcall("float64touint64", n->type, init, conv(n->left, types[TFLOAT64])); 883 goto ret; 884 } 885 } 886 if(isfloat[n->type->etype]) { 887 if(n->left->type->etype == TINT64) { 888 n = mkcall("int64tofloat64", n->type, init, conv(n->left, types[TINT64])); 889 goto ret; 890 } 891 if(n->left->type->etype == TUINT64) { 892 n = mkcall("uint64tofloat64", n->type, init, conv(n->left, types[TUINT64])); 893 goto ret; 894 } 895 } 896 } 897 walkexpr(&n->left, init); 898 goto ret; 899 900 case OASOP: 901 if(n->etype == OANDNOT) { 902 n->etype = OAND; 903 n->right = nod(OCOM, n->right, N); 904 typecheck(&n->right, Erv); 905 } 906 n->left = safeexpr(n->left, init); 907 walkexpr(&n->left, init); 908 l = n->left; 909 walkexpr(&n->right, init); 910 911 /* 912 * on 32-bit arch, rewrite 64-bit ops into l = l op r. 913 * on 386, rewrite float ops into l = l op r. 914 * everywhere, rewrite map ops into l = l op r. 915 * everywhere, rewrite string += into l = l op r. 916 * everywhere, rewrite integer/complex /= into l = l op r. 917 * TODO(rsc): Maybe this rewrite should be done always? 918 */ 919 et = n->left->type->etype; 920 if((widthptr == 4 && (et == TUINT64 || et == TINT64)) || 921 (thechar == '8' && isfloat[et]) || 922 l->op == OINDEXMAP || 923 et == TSTRING || 924 (!isfloat[et] && n->etype == ODIV) || 925 n->etype == OMOD) { 926 l = safeexpr(n->left, init); 927 a = l; 928 if(a->op == OINDEXMAP) { 929 // map index has "lhs" bit set in a->etype. 930 // make a copy so we can clear it on the rhs. 931 a = nod(OXXX, N, N); 932 *a = *l; 933 a->etype = 0; 934 } 935 r = nod(OAS, l, nod(n->etype, a, n->right)); 936 typecheck(&r, Etop); 937 walkexpr(&r, init); 938 n = r; 939 goto ret; 940 } 941 if(n->etype == OLSH || n->etype == ORSH) 942 goto shiftwalked; 943 goto ret; 944 945 case OANDNOT: 946 walkexpr(&n->left, init); 947 n->op = OAND; 948 n->right = nod(OCOM, n->right, N); 949 typecheck(&n->right, Erv); 950 walkexpr(&n->right, init); 951 goto ret; 952 953 case OMUL: 954 walkexpr(&n->left, init); 955 walkexpr(&n->right, init); 956 walkmul(&n, init); 957 goto ret; 958 959 case ODIV: 960 case OMOD: 961 walkexpr(&n->left, init); 962 walkexpr(&n->right, init); 963 /* 964 * rewrite complex div into function call. 965 */ 966 et = n->left->type->etype; 967 if(iscomplex[et] && n->op == ODIV) { 968 t = n->type; 969 n = mkcall("complex128div", types[TCOMPLEX128], init, 970 conv(n->left, types[TCOMPLEX128]), 971 conv(n->right, types[TCOMPLEX128])); 972 n = conv(n, t); 973 goto ret; 974 } 975 // Nothing to do for float divisions. 976 if(isfloat[et]) 977 goto ret; 978 979 // Try rewriting as shifts or magic multiplies. 980 walkdiv(&n, init); 981 982 /* 983 * rewrite 64-bit div and mod into function calls 984 * on 32-bit architectures. 985 */ 986 switch(n->op) { 987 case OMOD: 988 case ODIV: 989 if(widthptr > 4 || (et != TUINT64 && et != TINT64)) 990 goto ret; 991 if(et == TINT64) 992 strcpy(namebuf, "int64"); 993 else 994 strcpy(namebuf, "uint64"); 995 if(n->op == ODIV) 996 strcat(namebuf, "div"); 997 else 998 strcat(namebuf, "mod"); 999 n = mkcall(namebuf, n->type, init, 1000 conv(n->left, types[et]), conv(n->right, types[et])); 1001 break; 1002 default: 1003 break; 1004 } 1005 goto ret; 1006 1007 case OINDEX: 1008 walkexpr(&n->left, init); 1009 // save the original node for bounds checking elision. 1010 // If it was a ODIV/OMOD walk might rewrite it. 1011 r = n->right; 1012 walkexpr(&n->right, init); 1013 1014 // if range of type cannot exceed static array bound, 1015 // disable bounds check. 1016 if(n->bounded) 1017 goto ret; 1018 t = n->left->type; 1019 if(t != T && isptr[t->etype]) 1020 t = t->type; 1021 if(isfixedarray(t)) { 1022 n->bounded = bounded(r, t->bound); 1023 if(debug['m'] && n->bounded && !isconst(n->right, CTINT)) 1024 warn("index bounds check elided"); 1025 if(smallintconst(n->right) && !n->bounded) 1026 yyerror("index out of bounds"); 1027 } else if(isconst(n->left, CTSTR)) { 1028 n->bounded = bounded(r, n->left->val.u.sval->len); 1029 if(debug['m'] && n->bounded && !isconst(n->right, CTINT)) 1030 warn("index bounds check elided"); 1031 if(smallintconst(n->right)) { 1032 if(!n->bounded) 1033 yyerror("index out of bounds"); 1034 else { 1035 // replace "abc"[2] with 'b'. 1036 // delayed until now because "abc"[2] is not 1037 // an ideal constant. 1038 v = mpgetfix(n->right->val.u.xval); 1039 nodconst(n, n->type, n->left->val.u.sval->s[v]); 1040 n->typecheck = 1; 1041 } 1042 } 1043 } 1044 1045 if(isconst(n->right, CTINT)) 1046 if(mpcmpfixfix(n->right->val.u.xval, &mpzero) < 0 || 1047 mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0) 1048 yyerror("index out of bounds"); 1049 goto ret; 1050 1051 case OINDEXMAP: 1052 if(n->etype == 1) 1053 goto ret; 1054 1055 t = n->left->type; 1056 p = nil; 1057 if(t->type->width <= 128) { // Check ../../pkg/runtime/hashmap.c:MAXVALUESIZE before changing. 1058 switch(simsimtype(t->down)) { 1059 case TINT32: 1060 case TUINT32: 1061 p = "mapaccess1_fast32"; 1062 break; 1063 case TINT64: 1064 case TUINT64: 1065 p = "mapaccess1_fast64"; 1066 break; 1067 case TSTRING: 1068 p = "mapaccess1_faststr"; 1069 break; 1070 } 1071 } 1072 if(p != nil) { 1073 // use fast version. The fast versions return a pointer to the value - we need 1074 // to dereference it to get the result. 1075 n = mkcall1(mapfn(p, t), ptrto(t->type), init, typename(t), n->left, n->right); 1076 n = nod(OIND, n, N); 1077 n->type = t->type; 1078 n->typecheck = 1; 1079 } else { 1080 // no fast version for this key 1081 n = mkcall1(mapfn("mapaccess1", t), t->type, init, typename(t), n->left, n->right); 1082 } 1083 goto ret; 1084 1085 case ORECV: 1086 walkexpr(&n->left, init); 1087 walkexpr(&n->right, init); 1088 n = mkcall1(chanfn("chanrecv1", 2, n->left->type), n->type, init, typename(n->left->type), n->left); 1089 goto ret; 1090 1091 case OSLICE: 1092 if(n->right != N && n->right->left == N && n->right->right == N) { // noop 1093 walkexpr(&n->left, init); 1094 n = n->left; 1095 goto ret; 1096 } 1097 // fallthrough 1098 case OSLICEARR: 1099 case OSLICESTR: 1100 if(n->right == N) // already processed 1101 goto ret; 1102 1103 walkexpr(&n->left, init); 1104 // cgen_slice can't handle string literals as source 1105 // TODO the OINDEX case is a bug elsewhere that needs to be traced. it causes a crash on ([2][]int{ ... })[1][lo:hi] 1106 if((n->op == OSLICESTR && n->left->op == OLITERAL) || (n->left->op == OINDEX)) 1107 n->left = copyexpr(n->left, n->left->type, init); 1108 else 1109 n->left = safeexpr(n->left, init); 1110 walkexpr(&n->right->left, init); 1111 n->right->left = safeexpr(n->right->left, init); 1112 walkexpr(&n->right->right, init); 1113 n->right->right = safeexpr(n->right->right, init); 1114 n = sliceany(n, init); // chops n->right, sets n->list 1115 goto ret; 1116 1117 case OADDR: 1118 walkexpr(&n->left, init); 1119 goto ret; 1120 1121 case ONEW: 1122 if(n->esc == EscNone && n->type->type->width < (1<<16)) { 1123 r = temp(n->type->type); 1124 r = nod(OAS, r, N); // zero temp 1125 typecheck(&r, Etop); 1126 *init = list(*init, r); 1127 r = nod(OADDR, r->left, N); 1128 typecheck(&r, Erv); 1129 n = r; 1130 } else { 1131 n = callnew(n->type->type); 1132 } 1133 goto ret; 1134 1135 case OCMPSTR: 1136 // If one argument to the comparison is an empty string, 1137 // comparing the lengths instead will yield the same result 1138 // without the function call. 1139 if((isconst(n->left, CTSTR) && n->left->val.u.sval->len == 0) || 1140 (isconst(n->right, CTSTR) && n->right->val.u.sval->len == 0)) { 1141 r = nod(n->etype, nod(OLEN, n->left, N), nod(OLEN, n->right, N)); 1142 typecheck(&r, Erv); 1143 walkexpr(&r, init); 1144 r->type = n->type; 1145 n = r; 1146 goto ret; 1147 } 1148 1149 // s + "badgerbadgerbadger" == "badgerbadgerbadger" 1150 if((n->etype == OEQ || n->etype == ONE) && 1151 isconst(n->right, CTSTR) && 1152 n->left->op == OADDSTR && isconst(n->left->right, CTSTR) && 1153 cmpslit(n->right, n->left->right) == 0) { 1154 r = nod(n->etype, nod(OLEN, n->left->left, N), nodintconst(0)); 1155 typecheck(&r, Erv); 1156 walkexpr(&r, init); 1157 r->type = n->type; 1158 n = r; 1159 goto ret; 1160 } 1161 1162 if(n->etype == OEQ || n->etype == ONE) { 1163 // prepare for rewrite below 1164 n->left = cheapexpr(n->left, init); 1165 n->right = cheapexpr(n->right, init); 1166 1167 r = mkcall("eqstring", types[TBOOL], init, 1168 conv(n->left, types[TSTRING]), 1169 conv(n->right, types[TSTRING])); 1170 1171 // quick check of len before full compare for == or != 1172 if(n->etype == OEQ) { 1173 // len(left) == len(right) && eqstring(left, right) 1174 r = nod(OANDAND, nod(OEQ, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r); 1175 } else { 1176 // len(left) != len(right) || !eqstring(left, right) 1177 r = nod(ONOT, r, N); 1178 r = nod(OOROR, nod(ONE, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r); 1179 } 1180 typecheck(&r, Erv); 1181 walkexpr(&r, nil); 1182 } else { 1183 // sys_cmpstring(s1, s2) :: 0 1184 r = mkcall("cmpstring", types[TINT], init, 1185 conv(n->left, types[TSTRING]), 1186 conv(n->right, types[TSTRING])); 1187 r = nod(n->etype, r, nodintconst(0)); 1188 } 1189 1190 typecheck(&r, Erv); 1191 if(n->type->etype != TBOOL) fatal("cmp %T", n->type); 1192 r->type = n->type; 1193 n = r; 1194 goto ret; 1195 1196 case OADDSTR: 1197 n = addstr(n, init); 1198 goto ret; 1199 1200 case OAPPEND: 1201 if(n->isddd) { 1202 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); 1204 else 1205 n = appendslice(n, init); 1206 } 1207 else 1208 n = append(n, init); 1209 goto ret; 1210 1211 case OCOPY: 1212 if(n->right->type->etype == TSTRING) 1213 fn = syslook("slicestringcopy", 1); 1214 else 1215 fn = syslook("copy", 1); 1216 argtype(fn, n->left->type); 1217 argtype(fn, n->right->type); 1218 n = mkcall1(fn, n->type, init, 1219 n->left, n->right, 1220 nodintconst(n->left->type->type->width)); 1221 goto ret; 1222 1223 case OCLOSE: 1224 // cannot use chanfn - closechan takes any, not chan any 1225 fn = syslook("closechan", 1); 1226 argtype(fn, n->left->type); 1227 n = mkcall1(fn, T, init, n->left); 1228 goto ret; 1229 1230 case OMAKECHAN: 1231 n = mkcall1(chanfn("makechan", 1, n->type), n->type, init, 1232 typename(n->type), 1233 conv(n->left, types[TINT64])); 1234 goto ret; 1235 1236 case OMAKEMAP: 1237 t = n->type; 1238 1239 fn = syslook("makemap", 1); 1240 argtype(fn, t->down); // any-1 1241 argtype(fn, t->type); // any-2 1242 1243 n = mkcall1(fn, n->type, init, 1244 typename(n->type), 1245 conv(n->left, types[TINT64])); 1246 goto ret; 1247 1248 case OMAKESLICE: 1249 // makeslice(t *Type, nel int64, max int64) (ary []any) 1250 l = n->left; 1251 r = n->right; 1252 if(r == nil) 1253 l = r = safeexpr(l, init); 1254 t = n->type; 1255 fn = syslook("makeslice", 1); 1256 argtype(fn, t->type); // any-1 1257 n = mkcall1(fn, n->type, init, 1258 typename(n->type), 1259 conv(l, types[TINT64]), 1260 conv(r, types[TINT64])); 1261 goto ret; 1262 1263 case ORUNESTR: 1264 // sys_intstring(v) 1265 n = mkcall("intstring", n->type, init, 1266 conv(n->left, types[TINT64])); 1267 goto ret; 1268 1269 case OARRAYBYTESTR: 1270 // slicebytetostring([]byte) string; 1271 n = mkcall("slicebytetostring", n->type, init, n->left); 1272 goto ret; 1273 1274 case OARRAYRUNESTR: 1275 // slicerunetostring([]rune) string; 1276 n = mkcall("slicerunetostring", n->type, init, n->left); 1277 goto ret; 1278 1279 case OSTRARRAYBYTE: 1280 // stringtoslicebyte(string) []byte; 1281 n = mkcall("stringtoslicebyte", n->type, init, conv(n->left, types[TSTRING])); 1282 goto ret; 1283 1284 case OSTRARRAYRUNE: 1285 // stringtoslicerune(string) []rune 1286 n = mkcall("stringtoslicerune", n->type, init, n->left); 1287 goto ret; 1288 1289 case OCMPIFACE: 1290 // ifaceeq(i1 any-1, i2 any-2) (ret bool); 1291 if(!eqtype(n->left->type, n->right->type)) 1292 fatal("ifaceeq %O %T %T", n->op, n->left->type, n->right->type); 1293 if(isnilinter(n->left->type)) 1294 fn = syslook("efaceeq", 1); 1295 else 1296 fn = syslook("ifaceeq", 1); 1297 1298 n->right = cheapexpr(n->right, init); 1299 n->left = cheapexpr(n->left, init); 1300 argtype(fn, n->right->type); 1301 argtype(fn, n->left->type); 1302 r = mkcall1(fn, n->type, init, n->left, n->right); 1303 if(n->etype == ONE) 1304 r = nod(ONOT, r, N); 1305 1306 // check itable/type before full compare. 1307 if(n->etype == OEQ) 1308 r = nod(OANDAND, nod(OEQ, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r); 1309 else 1310 r = nod(OOROR, nod(ONE, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r); 1311 typecheck(&r, Erv); 1312 walkexpr(&r, init); 1313 r->type = n->type; 1314 n = r; 1315 goto ret; 1316 1317 case OARRAYLIT: 1318 case OMAPLIT: 1319 case OSTRUCTLIT: 1320 case OPTRLIT: 1321 var = temp(n->type); 1322 anylit(0, n, var, init); 1323 n = var; 1324 goto ret; 1325 1326 case OSEND: 1327 n = mkcall1(chanfn("chansend1", 2, n->left->type), T, init, typename(n->left->type), n->left, n->right); 1328 goto ret; 1329 1330 case OCLOSURE: 1331 n = walkclosure(n, init); 1332 goto ret; 1333 1334 case OCALLPART: 1335 n = walkpartialcall(n, init); 1336 goto ret; 1337 } 1338 fatal("missing switch %O", n->op); 1339 1340 ret: 1341 ullmancalc(n); 1342 1343 if(debug['w'] && n != N) 1344 dump("walk", n); 1345 1346 lineno = lno; 1347 *np = n; 1348 } 1349 1350 static Node* 1351 ascompatee1(int op, Node *l, Node *r, NodeList **init) 1352 { 1353 Node *n; 1354 USED(op); 1355 1356 // convas will turn map assigns into function calls, 1357 // making it impossible for reorder3 to work. 1358 n = nod(OAS, l, r); 1359 if(l->op == OINDEXMAP) 1360 return n; 1361 1362 return convas(n, init); 1363 } 1364 1365 static NodeList* 1366 ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init) 1367 { 1368 NodeList *ll, *lr, *nn; 1369 1370 /* 1371 * check assign expression list to 1372 * a expression list. called in 1373 * expr-list = expr-list 1374 */ 1375 1376 // ensure order of evaluation for function calls 1377 for(ll=nl; ll; ll=ll->next) 1378 ll->n = safeexpr(ll->n, init); 1379 for(lr=nr; lr; lr=lr->next) 1380 lr->n = safeexpr(lr->n, init); 1381 1382 nn = nil; 1383 for(ll=nl, lr=nr; ll && lr; ll=ll->next, lr=lr->next) { 1384 // Do not generate 'x = x' during return. See issue 4014. 1385 if(op == ORETURN && ll->n == lr->n) 1386 continue; 1387 nn = list(nn, ascompatee1(op, ll->n, lr->n, init)); 1388 } 1389 1390 // cannot happen: caller checked that lists had same length 1391 if(ll || lr) 1392 yyerror("error in shape across %+H %O %+H / %d %d [%s]", nl, op, nr, count(nl), count(nr), curfn->nname->sym->name); 1393 return nn; 1394 } 1395 1396 /* 1397 * l is an lv and rt is the type of an rv 1398 * return 1 if this implies a function call 1399 * evaluating the lv or a function call 1400 * in the conversion of the types 1401 */ 1402 static int 1403 fncall(Node *l, Type *rt) 1404 { 1405 if(l->ullman >= UINF || l->op == OINDEXMAP) 1406 return 1; 1407 if(eqtype(l->type, rt)) 1408 return 0; 1409 return 1; 1410 } 1411 1412 static NodeList* 1413 ascompatet(int op, NodeList *nl, Type **nr, int fp, NodeList **init) 1414 { 1415 Node *l, *tmp, *a; 1416 NodeList *ll; 1417 Type *r; 1418 Iter saver; 1419 int ucount; 1420 NodeList *nn, *mm; 1421 1422 USED(op); 1423 1424 /* 1425 * check assign type list to 1426 * a expression list. called in 1427 * expr-list = func() 1428 */ 1429 r = structfirst(&saver, nr); 1430 nn = nil; 1431 mm = nil; 1432 ucount = 0; 1433 for(ll=nl; ll; ll=ll->next) { 1434 if(r == T) 1435 break; 1436 l = ll->n; 1437 if(isblank(l)) { 1438 r = structnext(&saver); 1439 continue; 1440 } 1441 1442 // any lv that causes a fn call must be 1443 // deferred until all the return arguments 1444 // have been pulled from the output arguments 1445 if(fncall(l, r->type)) { 1446 tmp = temp(r->type); 1447 typecheck(&tmp, Erv); 1448 a = nod(OAS, l, tmp); 1449 a = convas(a, init); 1450 mm = list(mm, a); 1451 l = tmp; 1452 } 1453 1454 a = nod(OAS, l, nodarg(r, fp)); 1455 a = convas(a, init); 1456 ullmancalc(a); 1457 if(a->ullman >= UINF) 1458 ucount++; 1459 nn = list(nn, a); 1460 r = structnext(&saver); 1461 } 1462 1463 if(ll != nil || r != T) 1464 yyerror("ascompatet: assignment count mismatch: %d = %d", 1465 count(nl), structcount(*nr)); 1466 1467 if(ucount) 1468 fatal("ascompatet: too many function calls evaluating parameters"); 1469 return concat(nn, mm); 1470 } 1471 1472 /* 1473 * package all the arguments that match a ... T parameter into a []T. 1474 */ 1475 static NodeList* 1476 mkdotargslice(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init, int esc) 1477 { 1478 Node *a, *n; 1479 Type *tslice; 1480 1481 tslice = typ(TARRAY); 1482 tslice->type = l->type->type; 1483 tslice->bound = -1; 1484 1485 if(count(lr0) == 0) { 1486 n = nodnil(); 1487 n->type = tslice; 1488 } else { 1489 n = nod(OCOMPLIT, N, typenod(tslice)); 1490 n->list = lr0; 1491 n->esc = esc; 1492 typecheck(&n, Erv); 1493 if(n->type == T) 1494 fatal("mkdotargslice: typecheck failed"); 1495 walkexpr(&n, init); 1496 } 1497 1498 a = nod(OAS, nodarg(l, fp), n); 1499 nn = list(nn, convas(a, init)); 1500 return nn; 1501 } 1502 1503 /* 1504 * helpers for shape errors 1505 */ 1506 static char* 1507 dumptypes(Type **nl, char *what) 1508 { 1509 int first; 1510 Type *l; 1511 Iter savel; 1512 Fmt fmt; 1513 1514 fmtstrinit(&fmt); 1515 fmtprint(&fmt, "\t"); 1516 first = 1; 1517 for(l = structfirst(&savel, nl); l != T; l = structnext(&savel)) { 1518 if(first) 1519 first = 0; 1520 else 1521 fmtprint(&fmt, ", "); 1522 fmtprint(&fmt, "%T", l); 1523 } 1524 if(first) 1525 fmtprint(&fmt, "[no arguments %s]", what); 1526 return fmtstrflush(&fmt); 1527 } 1528 1529 static char* 1530 dumpnodetypes(NodeList *l, char *what) 1531 { 1532 int first; 1533 Node *r; 1534 Fmt fmt; 1535 1536 fmtstrinit(&fmt); 1537 fmtprint(&fmt, "\t"); 1538 first = 1; 1539 for(; l; l=l->next) { 1540 r = l->n; 1541 if(first) 1542 first = 0; 1543 else 1544 fmtprint(&fmt, ", "); 1545 fmtprint(&fmt, "%T", r->type); 1546 } 1547 if(first) 1548 fmtprint(&fmt, "[no arguments %s]", what); 1549 return fmtstrflush(&fmt); 1550 } 1551 1552 /* 1553 * check assign expression list to 1554 * a type list. called in 1555 * return expr-list 1556 * func(expr-list) 1557 */ 1558 static NodeList* 1559 ascompatte(int op, Node *call, int isddd, Type **nl, NodeList *lr, int fp, NodeList **init) 1560 { 1561 int esc; 1562 Type *l, *ll; 1563 Node *r, *a; 1564 NodeList *nn, *lr0, *alist; 1565 Iter savel; 1566 char *l1, *l2; 1567 1568 lr0 = lr; 1569 l = structfirst(&savel, nl); 1570 r = N; 1571 if(lr) 1572 r = lr->n; 1573 nn = nil; 1574 1575 // f(g()) where g has multiple return values 1576 if(r != N && lr->next == nil && r->type->etype == TSTRUCT && r->type->funarg) { 1577 // optimization - can do block copy 1578 if(eqtypenoname(r->type, *nl)) { 1579 a = nodarg(*nl, fp); 1580 a->type = r->type; 1581 nn = list1(convas(nod(OAS, a, r), init)); 1582 goto ret; 1583 } 1584 1585 // conversions involved. 1586 // copy into temporaries. 1587 alist = nil; 1588 for(l=structfirst(&savel, &r->type); l; l=structnext(&savel)) { 1589 a = temp(l->type); 1590 alist = list(alist, a); 1591 } 1592 a = nod(OAS2, N, N); 1593 a->list = alist; 1594 a->rlist = lr; 1595 typecheck(&a, Etop); 1596 walkstmt(&a); 1597 *init = list(*init, a); 1598 lr = alist; 1599 r = lr->n; 1600 l = structfirst(&savel, nl); 1601 } 1602 1603 loop: 1604 if(l != T && l->isddd) { 1605 // the ddd parameter must be last 1606 ll = structnext(&savel); 1607 if(ll != T) 1608 yyerror("... must be last argument"); 1609 1610 // special case -- 1611 // only if we are assigning a single ddd 1612 // argument to a ddd parameter then it is 1613 // passed thru unencapsulated 1614 if(r != N && lr->next == nil && isddd && eqtype(l->type, r->type)) { 1615 a = nod(OAS, nodarg(l, fp), r); 1616 a = convas(a, init); 1617 nn = list(nn, a); 1618 goto ret; 1619 } 1620 1621 // normal case -- make a slice of all 1622 // remaining arguments and pass it to 1623 // the ddd parameter. 1624 esc = EscUnknown; 1625 if(call->right) 1626 esc = call->right->esc; 1627 nn = mkdotargslice(lr, nn, l, fp, init, esc); 1628 goto ret; 1629 } 1630 1631 if(l == T || r == N) { 1632 if(l != T || r != N) { 1633 l1 = dumptypes(nl, "expected"); 1634 l2 = dumpnodetypes(lr0, "given"); 1635 if(l != T) 1636 yyerror("not enough arguments to %O\n%s\n%s", op, l1, l2); 1637 else 1638 yyerror("too many arguments to %O\n%s\n%s", op, l1, l2); 1639 } 1640 goto ret; 1641 } 1642 1643 a = nod(OAS, nodarg(l, fp), r); 1644 a = convas(a, init); 1645 nn = list(nn, a); 1646 1647 l = structnext(&savel); 1648 r = N; 1649 lr = lr->next; 1650 if(lr != nil) 1651 r = lr->n; 1652 goto loop; 1653 1654 ret: 1655 for(lr=nn; lr; lr=lr->next) 1656 lr->n->typecheck = 1; 1657 return nn; 1658 } 1659 1660 // generate code for print 1661 static Node* 1662 walkprint(Node *nn, NodeList **init, int defer) 1663 { 1664 Node *r; 1665 Node *n; 1666 NodeList *l, *all; 1667 Node *on; 1668 Type *t; 1669 int notfirst, et, op; 1670 NodeList *calls, *intypes, *args; 1671 Fmt fmt; 1672 1673 on = nil; 1674 op = nn->op; 1675 all = nn->list; 1676 calls = nil; 1677 notfirst = 0; 1678 intypes = nil; 1679 args = nil; 1680 1681 memset(&fmt, 0, sizeof fmt); 1682 if(defer) { 1683 // defer print turns into defer printf with format string 1684 fmtstrinit(&fmt); 1685 intypes = list(intypes, nod(ODCLFIELD, N, typenod(types[TSTRING]))); 1686 args = list1(nod(OXXX, N, N)); 1687 } 1688 1689 for(l=all; l; l=l->next) { 1690 if(notfirst) { 1691 if(defer) 1692 fmtprint(&fmt, " "); 1693 else 1694 calls = list(calls, mkcall("printsp", T, init)); 1695 } 1696 notfirst = op == OPRINTN; 1697 1698 n = l->n; 1699 if(n->op == OLITERAL) { 1700 switch(n->val.ctype) { 1701 case CTRUNE: 1702 defaultlit(&n, runetype); 1703 break; 1704 case CTINT: 1705 defaultlit(&n, types[TINT64]); 1706 break; 1707 case CTFLT: 1708 defaultlit(&n, types[TFLOAT64]); 1709 break; 1710 } 1711 } 1712 if(n->op != OLITERAL && n->type && n->type->etype == TIDEAL) 1713 defaultlit(&n, types[TINT64]); 1714 defaultlit(&n, nil); 1715 l->n = n; 1716 if(n->type == T || n->type->etype == TFORW) 1717 continue; 1718 1719 t = n->type; 1720 et = n->type->etype; 1721 if(isinter(n->type)) { 1722 if(defer) { 1723 if(isnilinter(n->type)) 1724 fmtprint(&fmt, "%%e"); 1725 else 1726 fmtprint(&fmt, "%%i"); 1727 } else { 1728 if(isnilinter(n->type)) 1729 on = syslook("printeface", 1); 1730 else 1731 on = syslook("printiface", 1); 1732 argtype(on, n->type); // any-1 1733 } 1734 } else if(isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR) { 1735 if(defer) { 1736 fmtprint(&fmt, "%%p"); 1737 } else { 1738 on = syslook("printpointer", 1); 1739 argtype(on, n->type); // any-1 1740 } 1741 } else if(isslice(n->type)) { 1742 if(defer) { 1743 fmtprint(&fmt, "%%a"); 1744 } else { 1745 on = syslook("printslice", 1); 1746 argtype(on, n->type); // any-1 1747 } 1748 } else if(isint[et]) { 1749 if(defer) { 1750 if(et == TUINT64) 1751 fmtprint(&fmt, "%%U"); 1752 else { 1753 fmtprint(&fmt, "%%D"); 1754 t = types[TINT64]; 1755 } 1756 } else { 1757 if(et == TUINT64) 1758 on = syslook("printuint", 0); 1759 else 1760 on = syslook("printint", 0); 1761 } 1762 } else if(isfloat[et]) { 1763 if(defer) { 1764 fmtprint(&fmt, "%%f"); 1765 t = types[TFLOAT64]; 1766 } else 1767 on = syslook("printfloat", 0); 1768 } else if(iscomplex[et]) { 1769 if(defer) { 1770 fmtprint(&fmt, "%%C"); 1771 t = types[TCOMPLEX128]; 1772 } else 1773 on = syslook("printcomplex", 0); 1774 } else if(et == TBOOL) { 1775 if(defer) 1776 fmtprint(&fmt, "%%t"); 1777 else 1778 on = syslook("printbool", 0); 1779 } else if(et == TSTRING) { 1780 if(defer) 1781 fmtprint(&fmt, "%%S"); 1782 else 1783 on = syslook("printstring", 0); 1784 } else { 1785 badtype(OPRINT, n->type, T); 1786 continue; 1787 } 1788 1789 if(!defer) { 1790 t = *getinarg(on->type); 1791 if(t != nil) 1792 t = t->type; 1793 if(t != nil) 1794 t = t->type; 1795 } 1796 1797 if(!eqtype(t, n->type)) { 1798 n = nod(OCONV, n, N); 1799 n->type = t; 1800 } 1801 1802 if(defer) { 1803 intypes = list(intypes, nod(ODCLFIELD, N, typenod(t))); 1804 args = list(args, n); 1805 } else { 1806 r = nod(OCALL, on, N); 1807 r->list = list1(n); 1808 calls = list(calls, r); 1809 } 1810 } 1811 1812 if(defer) { 1813 if(op == OPRINTN) 1814 fmtprint(&fmt, "\n"); 1815 on = syslook("goprintf", 1); 1816 on->type = functype(nil, intypes, nil); 1817 args->n = nod(OLITERAL, N, N); 1818 args->n->val.ctype = CTSTR; 1819 args->n->val.u.sval = strlit(fmtstrflush(&fmt)); 1820 r = nod(OCALL, on, N); 1821 r->list = args; 1822 typecheck(&r, Etop); 1823 walkexpr(&r, init); 1824 } else { 1825 if(op == OPRINTN) 1826 calls = list(calls, mkcall("printnl", T, nil)); 1827 typechecklist(calls, Etop); 1828 walkexprlist(calls, init); 1829 1830 r = nod(OEMPTY, N, N); 1831 typecheck(&r, Etop); 1832 walkexpr(&r, init); 1833 r->ninit = calls; 1834 } 1835 return r; 1836 } 1837 1838 Node* 1839 callnew(Type *t) 1840 { 1841 Node *fn; 1842 1843 dowidth(t); 1844 fn = syslook("new", 1); 1845 argtype(fn, t); 1846 return mkcall1(fn, ptrto(t), nil, typename(t)); 1847 } 1848 1849 static Node* 1850 convas(Node *n, NodeList **init) 1851 { 1852 Type *lt, *rt; 1853 1854 if(n->op != OAS) 1855 fatal("convas: not OAS %O", n->op); 1856 1857 n->typecheck = 1; 1858 1859 if(n->left == N || n->right == N) 1860 goto out; 1861 1862 lt = n->left->type; 1863 rt = n->right->type; 1864 if(lt == T || rt == T) 1865 goto out; 1866 1867 if(isblank(n->left)) { 1868 defaultlit(&n->right, T); 1869 goto out; 1870 } 1871 1872 if(n->left->op == OINDEXMAP) { 1873 n = mkcall1(mapfn("mapassign1", n->left->left->type), T, init, 1874 typename(n->left->left->type), 1875 n->left->left, n->left->right, n->right); 1876 goto out; 1877 } 1878 1879 if(eqtype(lt, rt)) 1880 goto out; 1881 1882 n->right = assignconv(n->right, lt, "assignment"); 1883 walkexpr(&n->right, init); 1884 1885 out: 1886 ullmancalc(n); 1887 return n; 1888 } 1889 1890 /* 1891 * from ascompat[te] 1892 * evaluating actual function arguments. 1893 * f(a,b) 1894 * if there is exactly one function expr, 1895 * then it is done first. otherwise must 1896 * make temp variables 1897 */ 1898 static NodeList* 1899 reorder1(NodeList *all) 1900 { 1901 Node *f, *a, *n; 1902 NodeList *l, *r, *g; 1903 int c, d, t; 1904 1905 c = 0; // function calls 1906 t = 0; // total parameters 1907 1908 for(l=all; l; l=l->next) { 1909 n = l->n; 1910 t++; 1911 ullmancalc(n); 1912 if(n->ullman >= UINF) 1913 c++; 1914 } 1915 if(c == 0 || t == 1) 1916 return all; 1917 1918 g = nil; // fncalls assigned to tempnames 1919 f = N; // last fncall assigned to stack 1920 r = nil; // non fncalls and tempnames assigned to stack 1921 d = 0; 1922 for(l=all; l; l=l->next) { 1923 n = l->n; 1924 if(n->ullman < UINF) { 1925 r = list(r, n); 1926 continue; 1927 } 1928 d++; 1929 if(d == c) { 1930 f = n; 1931 continue; 1932 } 1933 1934 // make assignment of fncall to tempname 1935 a = temp(n->right->type); 1936 a = nod(OAS, a, n->right); 1937 g = list(g, a); 1938 1939 // put normal arg assignment on list 1940 // with fncall replaced by tempname 1941 n->right = a->left; 1942 r = list(r, n); 1943 } 1944 1945 if(f != N) 1946 g = list(g, f); 1947 return concat(g, r); 1948 } 1949 1950 static void reorder3save(Node**, NodeList*, NodeList*, NodeList**); 1951 static int aliased(Node*, NodeList*, NodeList*); 1952 1953 /* 1954 * from ascompat[ee] 1955 * a,b = c,d 1956 * simultaneous assignment. there cannot 1957 * be later use of an earlier lvalue. 1958 * 1959 * function calls have been removed. 1960 */ 1961 static NodeList* 1962 reorder3(NodeList *all) 1963 { 1964 NodeList *list, *early, *mapinit; 1965 Node *l; 1966 1967 // If a needed expression may be affected by an 1968 // earlier assignment, make an early copy of that 1969 // expression and use the copy instead. 1970 early = nil; 1971 mapinit = nil; 1972 for(list=all; list; list=list->next) { 1973 l = list->n->left; 1974 1975 // Save subexpressions needed on left side. 1976 // Drill through non-dereferences. 1977 for(;;) { 1978 if(l->op == ODOT || l->op == OPAREN) { 1979 l = l->left; 1980 continue; 1981 } 1982 if(l->op == OINDEX && isfixedarray(l->left->type)) { 1983 reorder3save(&l->right, all, list, &early); 1984 l = l->left; 1985 continue; 1986 } 1987 break; 1988 } 1989 switch(l->op) { 1990 default: 1991 fatal("reorder3 unexpected lvalue %#O", l->op); 1992 case ONAME: 1993 break; 1994 case OINDEX: 1995 case OINDEXMAP: 1996 reorder3save(&l->left, all, list, &early); 1997 reorder3save(&l->right, all, list, &early); 1998 if(l->op == OINDEXMAP) 1999 list->n = convas(list->n, &mapinit); 2000 break; 2001 case OIND: 2002 case ODOTPTR: 2003 reorder3save(&l->left, all, list, &early); 2004 } 2005 2006 // Save expression on right side. 2007 reorder3save(&list->n->right, all, list, &early); 2008 } 2009 2010 early = concat(mapinit, early); 2011 return concat(early, all); 2012 } 2013 2014 static int vmatch2(Node*, Node*); 2015 static int varexpr(Node*); 2016 2017 /* 2018 * if the evaluation of *np would be affected by the 2019 * assignments in all up to but not including stop, 2020 * copy into a temporary during *early and 2021 * replace *np with that temp. 2022 */ 2023 static void 2024 reorder3save(Node **np, NodeList *all, NodeList *stop, NodeList **early) 2025 { 2026 Node *n, *q; 2027 2028 n = *np; 2029 if(!aliased(n, all, stop)) 2030 return; 2031 2032 q = temp(n->type); 2033 q = nod(OAS, q, n); 2034 typecheck(&q, Etop); 2035 *early = list(*early, q); 2036 *np = q->left; 2037 } 2038 2039 /* 2040 * what's the outer value that a write to n affects? 2041 * outer value means containing struct or array. 2042 */ 2043 static Node* 2044 outervalue(Node *n) 2045 { 2046 for(;;) { 2047 if(n->op == ODOT || n->op == OPAREN) { 2048 n = n->left; 2049 continue; 2050 } 2051 if(n->op == OINDEX && isfixedarray(n->left->type)) { 2052 n = n->left; 2053 continue; 2054 } 2055 break; 2056 } 2057 return n; 2058 } 2059 2060 /* 2061 * Is it possible that the computation of n might be 2062 * affected by writes in as up to but not including stop? 2063 */ 2064 static int 2065 aliased(Node *n, NodeList *all, NodeList *stop) 2066 { 2067 int memwrite, varwrite; 2068 Node *a; 2069 NodeList *l; 2070 2071 if(n == N) 2072 return 0; 2073 2074 // Look for obvious aliasing: a variable being assigned 2075 // during the all list and appearing in n. 2076 // Also record whether there are any writes to main memory. 2077 // Also record whether there are any writes to variables 2078 // whose addresses have been taken. 2079 memwrite = 0; 2080 varwrite = 0; 2081 for(l=all; l!=stop; l=l->next) { 2082 a = outervalue(l->n->left); 2083 if(a->op != ONAME) { 2084 memwrite = 1; 2085 continue; 2086 } 2087 switch(n->class) { 2088 default: 2089 varwrite = 1; 2090 continue; 2091 case PAUTO: 2092 case PPARAM: 2093 case PPARAMOUT: 2094 if(n->addrtaken) { 2095 varwrite = 1; 2096 continue; 2097 } 2098 if(vmatch2(a, n)) { 2099 // Direct hit. 2100 return 1; 2101 } 2102 } 2103 } 2104 2105 // The variables being written do not appear in n. 2106 // However, n might refer to computed addresses 2107 // that are being written. 2108 2109 // If no computed addresses are affected by the writes, no aliasing. 2110 if(!memwrite && !varwrite) 2111 return 0; 2112 2113 // If n does not refer to computed addresses 2114 // (that is, if n only refers to variables whose addresses 2115 // have not been taken), no aliasing. 2116 if(varexpr(n)) 2117 return 0; 2118 2119 // Otherwise, both the writes and n refer to computed memory addresses. 2120 // Assume that they might conflict. 2121 return 1; 2122 } 2123 2124 /* 2125 * does the evaluation of n only refer to variables 2126 * whose addresses have not been taken? 2127 * (and no other memory) 2128 */ 2129 static int 2130 varexpr(Node *n) 2131 { 2132 if(n == N) 2133 return 1; 2134 2135 switch(n->op) { 2136 case OLITERAL: 2137 return 1; 2138 case ONAME: 2139 switch(n->class) { 2140 case PAUTO: 2141 case PPARAM: 2142 case PPARAMOUT: 2143 if(!n->addrtaken) 2144 return 1; 2145 } 2146 return 0; 2147 2148 case OADD: 2149 case OSUB: 2150 case OOR: 2151 case OXOR: 2152 case OMUL: 2153 case ODIV: 2154 case OMOD: 2155 case OLSH: 2156 case ORSH: 2157 case OAND: 2158 case OANDNOT: 2159 case OPLUS: 2160 case OMINUS: 2161 case OCOM: 2162 case OPAREN: 2163 case OANDAND: 2164 case OOROR: 2165 case ODOT: // but not ODOTPTR 2166 case OCONV: 2167 case OCONVNOP: 2168 case OCONVIFACE: 2169 case ODOTTYPE: 2170 return varexpr(n->left) && varexpr(n->right); 2171 } 2172 2173 // Be conservative. 2174 return 0; 2175 } 2176 2177 /* 2178 * is the name l mentioned in r? 2179 */ 2180 static int 2181 vmatch2(Node *l, Node *r) 2182 { 2183 NodeList *ll; 2184 2185 if(r == N) 2186 return 0; 2187 switch(r->op) { 2188 case ONAME: 2189 // match each right given left 2190 return l == r; 2191 case OLITERAL: 2192 return 0; 2193 } 2194 if(vmatch2(l, r->left)) 2195 return 1; 2196 if(vmatch2(l, r->right)) 2197 return 1; 2198 for(ll=r->list; ll; ll=ll->next) 2199 if(vmatch2(l, ll->n)) 2200 return 1; 2201 return 0; 2202 } 2203 2204 /* 2205 * is any name mentioned in l also mentioned in r? 2206 * called by sinit.c 2207 */ 2208 int 2209 vmatch1(Node *l, Node *r) 2210 { 2211 NodeList *ll; 2212 2213 /* 2214 * isolate all left sides 2215 */ 2216 if(l == N || r == N) 2217 return 0; 2218 switch(l->op) { 2219 case ONAME: 2220 switch(l->class) { 2221 case PPARAM: 2222 case PPARAMREF: 2223 case PAUTO: 2224 break; 2225 default: 2226 // assignment to non-stack variable 2227 // must be delayed if right has function calls. 2228 if(r->ullman >= UINF) 2229 return 1; 2230 break; 2231 } 2232 return vmatch2(l, r); 2233 case OLITERAL: 2234 return 0; 2235 } 2236 if(vmatch1(l->left, r)) 2237 return 1; 2238 if(vmatch1(l->right, r)) 2239 return 1; 2240 for(ll=l->list; ll; ll=ll->next) 2241 if(vmatch1(ll->n, r)) 2242 return 1; 2243 return 0; 2244 } 2245 2246 /* 2247 * walk through argin parameters. 2248 * generate and return code to allocate 2249 * copies of escaped parameters to the heap. 2250 */ 2251 static NodeList* 2252 paramstoheap(Type **argin, int out) 2253 { 2254 Type *t; 2255 Iter savet; 2256 Node *v; 2257 NodeList *nn; 2258 2259 nn = nil; 2260 for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) { 2261 v = t->nname; 2262 if(v && v->sym && v->sym->name[0] == '~') 2263 v = N; 2264 if(v == N && out && hasdefer) { 2265 // Defer might stop a panic and show the 2266 // return values as they exist at the time of panic. 2267 // Make sure to zero them on entry to the function. 2268 nn = list(nn, nod(OAS, nodarg(t, 1), N)); 2269 } 2270 if(v == N || !(v->class & PHEAP)) 2271 continue; 2272 2273 // generate allocation & copying code 2274 if(v->alloc == nil) 2275 v->alloc = callnew(v->type); 2276 nn = list(nn, nod(OAS, v->heapaddr, v->alloc)); 2277 if((v->class & ~PHEAP) != PPARAMOUT) 2278 nn = list(nn, nod(OAS, v, v->stackparam)); 2279 } 2280 return nn; 2281 } 2282 2283 /* 2284 * walk through argout parameters copying back to stack 2285 */ 2286 static NodeList* 2287 returnsfromheap(Type **argin) 2288 { 2289 Type *t; 2290 Iter savet; 2291 Node *v; 2292 NodeList *nn; 2293 2294 nn = nil; 2295 for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) { 2296 v = t->nname; 2297 if(v == N || v->class != (PHEAP|PPARAMOUT)) 2298 continue; 2299 nn = list(nn, nod(OAS, v->stackparam, v)); 2300 } 2301 return nn; 2302 } 2303 2304 /* 2305 * take care of migrating any function in/out args 2306 * between the stack and the heap. adds code to 2307 * curfn's before and after lists. 2308 */ 2309 static void 2310 heapmoves(void) 2311 { 2312 NodeList *nn; 2313 int32 lno; 2314 2315 lno = lineno; 2316 lineno = curfn->lineno; 2317 nn = paramstoheap(getthis(curfn->type), 0); 2318 nn = concat(nn, paramstoheap(getinarg(curfn->type), 0)); 2319 nn = concat(nn, paramstoheap(getoutarg(curfn->type), 1)); 2320 curfn->enter = concat(curfn->enter, nn); 2321 lineno = curfn->endlineno; 2322 curfn->exit = returnsfromheap(getoutarg(curfn->type)); 2323 lineno = lno; 2324 } 2325 2326 static Node* 2327 vmkcall(Node *fn, Type *t, NodeList **init, va_list va) 2328 { 2329 int i, n; 2330 Node *r; 2331 NodeList *args; 2332 2333 if(fn->type == T || fn->type->etype != TFUNC) 2334 fatal("mkcall %N %T", fn, fn->type); 2335 2336 args = nil; 2337 n = fn->type->intuple; 2338 for(i=0; i<n; i++) 2339 args = list(args, va_arg(va, Node*)); 2340 2341 r = nod(OCALL, fn, N); 2342 r->list = args; 2343 if(fn->type->outtuple > 0) 2344 typecheck(&r, Erv | Efnstruct); 2345 else 2346 typecheck(&r, Etop); 2347 walkexpr(&r, init); 2348 r->type = t; 2349 return r; 2350 } 2351 2352 Node* 2353 mkcall(char *name, Type *t, NodeList **init, ...) 2354 { 2355 Node *r; 2356 va_list va; 2357 2358 va_start(va, init); 2359 r = vmkcall(syslook(name, 0), t, init, va); 2360 va_end(va); 2361 return r; 2362 } 2363 2364 Node* 2365 mkcall1(Node *fn, Type *t, NodeList **init, ...) 2366 { 2367 Node *r; 2368 va_list va; 2369 2370 va_start(va, init); 2371 r = vmkcall(fn, t, init, va); 2372 va_end(va); 2373 return r; 2374 } 2375 2376 Node* 2377 conv(Node *n, Type *t) 2378 { 2379 if(eqtype(n->type, t)) 2380 return n; 2381 n = nod(OCONV, n, N); 2382 n->type = t; 2383 typecheck(&n, Erv); 2384 return n; 2385 } 2386 2387 Node* 2388 chanfn(char *name, int n, Type *t) 2389 { 2390 Node *fn; 2391 int i; 2392 2393 if(t->etype != TCHAN) 2394 fatal("chanfn %T", t); 2395 fn = syslook(name, 1); 2396 for(i=0; i<n; i++) 2397 argtype(fn, t->type); 2398 return fn; 2399 } 2400 2401 static Node* 2402 mapfn(char *name, Type *t) 2403 { 2404 Node *fn; 2405 2406 if(t->etype != TMAP) 2407 fatal("mapfn %T", t); 2408 fn = syslook(name, 1); 2409 argtype(fn, t->down); 2410 argtype(fn, t->type); 2411 argtype(fn, t->down); 2412 argtype(fn, t->type); 2413 return fn; 2414 } 2415 2416 static Node* 2417 mapfndel(char *name, Type *t) 2418 { 2419 Node *fn; 2420 2421 if(t->etype != TMAP) 2422 fatal("mapfn %T", t); 2423 fn = syslook(name, 1); 2424 argtype(fn, t->down); 2425 argtype(fn, t->type); 2426 argtype(fn, t->down); 2427 return fn; 2428 } 2429 2430 static Node* 2431 addstr(Node *n, NodeList **init) 2432 { 2433 Node *r, *cat, *typstr; 2434 NodeList *in, *args; 2435 int i, count; 2436 2437 count = 0; 2438 for(r=n; r->op == OADDSTR; r=r->left) 2439 count++; // r->right 2440 count++; // r 2441 2442 // prepare call of runtime.catstring of type int, string, string, string 2443 // with as many strings as we have. 2444 cat = syslook("concatstring", 1); 2445 cat->type = T; 2446 cat->ntype = nod(OTFUNC, N, N); 2447 in = list1(nod(ODCLFIELD, N, typenod(types[TINT]))); // count 2448 typstr = typenod(types[TSTRING]); 2449 for(i=0; i<count; i++) 2450 in = list(in, nod(ODCLFIELD, N, typstr)); 2451 cat->ntype->list = in; 2452 cat->ntype->rlist = list1(nod(ODCLFIELD, N, typstr)); 2453 2454 args = nil; 2455 for(r=n; r->op == OADDSTR; r=r->left) 2456 args = concat(list1(conv(r->right, types[TSTRING])), args); 2457 args = concat(list1(conv(r, types[TSTRING])), args); 2458 args = concat(list1(nodintconst(count)), args); 2459 2460 r = nod(OCALL, cat, N); 2461 r->list = args; 2462 typecheck(&r, Erv); 2463 walkexpr(&r, init); 2464 r->type = n->type; 2465 2466 return r; 2467 } 2468 2469 static Node* 2470 appendslice(Node *n, NodeList **init) 2471 { 2472 Node *f; 2473 2474 f = syslook("appendslice", 1); 2475 argtype(f, n->type); 2476 argtype(f, n->type->type); 2477 argtype(f, n->type); 2478 return mkcall1(f, n->type, init, typename(n->type), n->list->n, n->list->next->n); 2479 } 2480 2481 // expand append(src, a [, b]* ) to 2482 // 2483 // init { 2484 // s := src 2485 // const argc = len(args) - 1 2486 // if cap(s) - len(s) < argc { 2487 // s = growslice(s, argc) 2488 // } 2489 // n := len(s) 2490 // s = s[:n+argc] 2491 // s[n] = a 2492 // s[n+1] = b 2493 // ... 2494 // } 2495 // s 2496 static Node* 2497 append(Node *n, NodeList **init) 2498 { 2499 NodeList *l, *a; 2500 Node *nsrc, *ns, *nn, *na, *nx, *fn; 2501 int argc; 2502 2503 walkexprlistsafe(n->list, init); 2504 2505 // 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 2507 // modifying here. Fix explicitly. 2508 for(l=n->list; l; l=l->next) 2509 l->n = cheapexpr(l->n, init); 2510 2511 nsrc = n->list->n; 2512 argc = count(n->list) - 1; 2513 if (argc < 1) { 2514 return nsrc; 2515 } 2516 2517 l = nil; 2518 2519 ns = temp(nsrc->type); 2520 l = list(l, nod(OAS, ns, nsrc)); // s = src 2521 2522 na = nodintconst(argc); // const argc 2523 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); 2525 2526 fn = syslook("growslice", 1); // growslice(<type>, old []T, n int64) (ret []T) 2527 argtype(fn, ns->type->type); // 1 old []any 2528 argtype(fn, ns->type->type); // 2 ret []any 2529 2530 nx->nbody = list1(nod(OAS, ns, mkcall1(fn, ns->type, &nx->ninit, 2531 typename(ns->type), 2532 ns, 2533 conv(na, types[TINT64])))); 2534 l = list(l, nx); 2535 2536 nn = temp(types[TINT]); 2537 l = list(l, nod(OAS, nn, nod(OLEN, ns, N))); // n = len(s) 2538 2539 nx = nod(OSLICE, ns, nod(OKEY, N, nod(OADD, nn, na))); // ...s[:n+argc] 2540 nx->bounded = 1; 2541 l = list(l, nod(OAS, ns, nx)); // s = s[:n+argc] 2542 2543 for (a = n->list->next; a != nil; a = a->next) { 2544 nx = nod(OINDEX, ns, nn); // s[n] ... 2545 nx->bounded = 1; 2546 l = list(l, nod(OAS, nx, a->n)); // s[n] = arg 2547 if (a->next != nil) 2548 l = list(l, nod(OAS, nn, nod(OADD, nn, nodintconst(1)))); // n = n + 1 2549 } 2550 2551 typechecklist(l, Etop); 2552 walkstmtlist(l); 2553 *init = concat(*init, l); 2554 return ns; 2555 } 2556 2557 2558 // Generate frontend part for OSLICE[ARR|STR] 2559 // 2560 static Node* 2561 sliceany(Node* n, NodeList **init) 2562 { 2563 int bounded; 2564 Node *src, *lb, *hb, *bound, *chk, *chk1, *chk2; 2565 int64 lbv, hbv, bv, w; 2566 Type *bt; 2567 2568 // print("before sliceany: %+N\n", n); 2569 2570 src = n->left; 2571 lb = n->right->left; 2572 hb = n->right->right; 2573 2574 bounded = n->etype; 2575 2576 if(n->op == OSLICESTR) 2577 bound = nod(OLEN, src, N); 2578 else 2579 bound = nod(OCAP, src, N); 2580 2581 typecheck(&bound, Erv); 2582 walkexpr(&bound, init); // if src is an array, bound will be a const now. 2583 2584 // static checks if possible 2585 bv = 1LL<<50; 2586 if(isconst(bound, CTINT)) { 2587 if(!smallintconst(bound)) 2588 yyerror("array len too large"); 2589 else 2590 bv = mpgetfix(bound->val.u.xval); 2591 } 2592 2593 if(isconst(hb, CTINT)) { 2594 hbv = mpgetfix(hb->val.u.xval); 2595 if(hbv < 0 || hbv > bv) { 2596 yyerror("slice index out of bounds"); 2597 hbv = -1; 2598 } 2599 } 2600 if(isconst(lb, CTINT)) { 2601 lbv = mpgetfix(lb->val.u.xval); 2602 if(lbv < 0 || lbv > bv) { 2603 yyerror("slice index out of bounds"); 2604 lbv = -1; 2605 } 2606 if(lbv == 0) 2607 lb = N; 2608 } 2609 2610 // dynamic checks convert all bounds to unsigned to save us the bound < 0 comparison 2611 // generate 2612 // if hb > bound || lb > hb { panicslice() } 2613 chk = N; 2614 chk1 = N; 2615 chk2 = N; 2616 2617 bt = types[simtype[TUINT]]; 2618 if(hb != N && hb->type->width > 4) 2619 bt = types[TUINT64]; 2620 if(lb != N && lb->type->width > 4) 2621 bt = types[TUINT64]; 2622 2623 bound = cheapexpr(conv(bound, bt), init); 2624 2625 if(hb != N) { 2626 hb = cheapexpr(conv(hb, bt), init); 2627 if(!bounded) 2628 chk1 = nod(OLT, bound, hb); 2629 } else if(n->op == OSLICEARR) { 2630 hb = bound; 2631 } else { 2632 hb = nod(OLEN, src, N); 2633 typecheck(&hb, Erv); 2634 walkexpr(&hb, init); 2635 hb = cheapexpr(conv(hb, bt), init); 2636 } 2637 2638 if(lb != N) { 2639 lb = cheapexpr(conv(lb, bt), init); 2640 if(!bounded) 2641 chk2 = nod(OLT, hb, lb); 2642 } 2643 2644 if(chk1 != N || chk2 != N) { 2645 chk = nod(OIF, N, N); 2646 chk->nbody = list1(mkcall("panicslice", T, init)); 2647 if(chk1 != N) 2648 chk->ntest = chk1; 2649 if(chk2 != N) { 2650 if(chk->ntest == N) 2651 chk->ntest = chk2; 2652 else 2653 chk->ntest = nod(OOROR, chk->ntest, chk2); 2654 } 2655 typecheck(&chk, Etop); 2656 walkstmt(&chk); 2657 *init = concat(*init, chk->ninit); 2658 chk->ninit = nil; 2659 *init = list(*init, chk); 2660 } 2661 2662 // prepare new cap, len and offs for backend cgen_slice 2663 // cap = bound [ - lo ] 2664 n->right = N; 2665 n->list = nil; 2666 if(lb == N) 2667 bound = conv(bound, types[simtype[TUINT]]); 2668 else 2669 bound = nod(OSUB, conv(bound, types[simtype[TUINT]]), conv(lb, types[simtype[TUINT]])); 2670 typecheck(&bound, Erv); 2671 walkexpr(&bound, init); 2672 n->list = list(n->list, bound); 2673 2674 // len = hi [ - lo] 2675 if(lb == N) 2676 hb = conv(hb, types[simtype[TUINT]]); 2677 else 2678 hb = nod(OSUB, conv(hb, types[simtype[TUINT]]), conv(lb, types[simtype[TUINT]])); 2679 typecheck(&hb, Erv); 2680 walkexpr(&hb, init); 2681 n->list = list(n->list, hb); 2682 2683 // offs = [width *] lo, but omit if zero 2684 if(lb != N) { 2685 if(n->op == OSLICESTR) 2686 w = 1; 2687 else 2688 w = n->type->type->width; 2689 lb = conv(lb, types[TUINTPTR]); 2690 if(w > 1) 2691 lb = nod(OMUL, nodintconst(w), lb); 2692 typecheck(&lb, Erv); 2693 walkexpr(&lb, init); 2694 n->list = list(n->list, lb); 2695 } 2696 2697 // print("after sliceany: %+N\n", n); 2698 2699 return n; 2700 } 2701 2702 static Node* 2703 eqfor(Type *t) 2704 { 2705 int a; 2706 Node *n; 2707 Node *ntype; 2708 Sym *sym; 2709 2710 // Should only arrive here with large memory or 2711 // a struct/array containing a non-memory field/element. 2712 // Small memory is handled inline, and single non-memory 2713 // is handled during type check (OCMPSTR etc). 2714 a = algtype1(t, nil); 2715 if(a != AMEM && a != -1) 2716 fatal("eqfor %T", t); 2717 2718 if(a == AMEM) { 2719 n = syslook("memequal", 1); 2720 argtype(n, t); 2721 argtype(n, t); 2722 return n; 2723 } 2724 2725 sym = typesymprefix(".eq", t); 2726 n = newname(sym); 2727 n->class = PFUNC; 2728 ntype = nod(OTFUNC, N, N); 2729 ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(types[TBOOL])))); 2730 ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR]))); 2731 ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t)))); 2732 ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t)))); 2733 typecheck(&ntype, Etype); 2734 n->type = ntype->type; 2735 return n; 2736 } 2737 2738 static int 2739 countfield(Type *t) 2740 { 2741 Type *t1; 2742 int n; 2743 2744 n = 0; 2745 for(t1=t->type; t1!=T; t1=t1->down) 2746 n++; 2747 return n; 2748 } 2749 2750 static void 2751 walkcompare(Node **np, NodeList **init) 2752 { 2753 Node *n, *l, *r, *fn, *call, *a, *li, *ri, *expr; 2754 int andor, i; 2755 Type *t, *t1; 2756 static Node *tempbool; 2757 2758 n = *np; 2759 2760 // Must be comparison of array or struct. 2761 // Otherwise back end handles it. 2762 t = n->left->type; 2763 switch(t->etype) { 2764 default: 2765 return; 2766 case TARRAY: 2767 if(isslice(t)) 2768 return; 2769 break; 2770 case TSTRUCT: 2771 break; 2772 } 2773 2774 if(!islvalue(n->left) || !islvalue(n->right)) 2775 goto hard; 2776 2777 l = temp(ptrto(t)); 2778 a = nod(OAS, l, nod(OADDR, n->left, N)); 2779 a->right->etype = 1; // addr does not escape 2780 typecheck(&a, Etop); 2781 *init = list(*init, a); 2782 2783 r = temp(ptrto(t)); 2784 a = nod(OAS, r, nod(OADDR, n->right, N)); 2785 a->right->etype = 1; // addr does not escape 2786 typecheck(&a, Etop); 2787 *init = list(*init, a); 2788 2789 expr = N; 2790 andor = OANDAND; 2791 if(n->op == ONE) 2792 andor = OOROR; 2793 2794 if(t->etype == TARRAY && 2795 t->bound <= 4 && 2796 issimple[t->type->etype]) { 2797 // Four or fewer elements of a basic type. 2798 // Unroll comparisons. 2799 for(i=0; i<t->bound; i++) { 2800 li = nod(OINDEX, l, nodintconst(i)); 2801 ri = nod(OINDEX, r, nodintconst(i)); 2802 a = nod(n->op, li, ri); 2803 if(expr == N) 2804 expr = a; 2805 else 2806 expr = nod(andor, expr, a); 2807 } 2808 if(expr == N) 2809 expr = nodbool(n->op == OEQ); 2810 typecheck(&expr, Erv); 2811 walkexpr(&expr, init); 2812 expr->type = n->type; 2813 *np = expr; 2814 return; 2815 } 2816 2817 if(t->etype == TSTRUCT && countfield(t) <= 4) { 2818 // Struct of four or fewer fields. 2819 // Inline comparisons. 2820 for(t1=t->type; t1; t1=t1->down) { 2821 if(isblanksym(t1->sym)) 2822 continue; 2823 li = nod(OXDOT, l, newname(t1->sym)); 2824 ri = nod(OXDOT, r, newname(t1->sym)); 2825 a = nod(n->op, li, ri); 2826 if(expr == N) 2827 expr = a; 2828 else 2829 expr = nod(andor, expr, a); 2830 } 2831 if(expr == N) 2832 expr = nodbool(n->op == OEQ); 2833 typecheck(&expr, Erv); 2834 walkexpr(&expr, init); 2835 expr->type = n->type; 2836 *np = expr; 2837 return; 2838 } 2839 2840 // Chose not to inline, but still have addresses. 2841 // Call equality function directly. 2842 // The equality function requires a bool pointer for 2843 // storing its address, because it has to be callable 2844 // from C, and C can't access an ordinary Go return value. 2845 // To avoid creating many temporaries, cache one per function. 2846 if(tempbool == N || tempbool->curfn != curfn) 2847 tempbool = temp(types[TBOOL]); 2848 2849 call = nod(OCALL, eqfor(t), N); 2850 a = nod(OADDR, tempbool, N); 2851 a->etype = 1; // does not escape 2852 call->list = list(call->list, a); 2853 call->list = list(call->list, nodintconst(t->width)); 2854 call->list = list(call->list, l); 2855 call->list = list(call->list, r); 2856 typecheck(&call, Etop); 2857 walkstmt(&call); 2858 *init = list(*init, call); 2859 2860 // tempbool cannot be used directly as multiple comparison 2861 // expressions may exist in the same statement. Create another 2862 // temporary to hold the value (its address is not taken so it can 2863 // be optimized away). 2864 r = temp(types[TBOOL]); 2865 a = nod(OAS, r, tempbool); 2866 typecheck(&a, Etop); 2867 walkstmt(&a); 2868 *init = list(*init, a); 2869 2870 if(n->op != OEQ) 2871 r = nod(ONOT, r, N); 2872 typecheck(&r, Erv); 2873 walkexpr(&r, init); 2874 *np = r; 2875 return; 2876 2877 hard: 2878 // Cannot take address of one or both of the operands. 2879 // Instead, pass directly to runtime helper function. 2880 // Easier on the stack than passing the address 2881 // of temporary variables, because we are better at reusing 2882 // the argument space than temporary variable space. 2883 fn = syslook("equal", 1); 2884 l = n->left; 2885 r = n->right; 2886 argtype(fn, n->left->type); 2887 argtype(fn, n->left->type); 2888 r = mkcall1(fn, n->type, init, typename(n->left->type), l, r); 2889 if(n->op == ONE) { 2890 r = nod(ONOT, r, N); 2891 typecheck(&r, Erv); 2892 } 2893 *np = r; 2894 return; 2895 } 2896 2897 static int 2898 samecheap(Node *a, Node *b) 2899 { 2900 Node *ar, *br; 2901 while(a != N && b != N && a->op == b->op) { 2902 switch(a->op) { 2903 default: 2904 return 0; 2905 case ONAME: 2906 return a == b; 2907 case ODOT: 2908 case ODOTPTR: 2909 ar = a->right; 2910 br = b->right; 2911 if(ar->op != ONAME || br->op != ONAME || ar->sym != br->sym) 2912 return 0; 2913 break; 2914 case OINDEX: 2915 ar = a->right; 2916 br = b->right; 2917 if(!isconst(ar, CTINT) || !isconst(br, CTINT) || mpcmpfixfix(ar->val.u.xval, br->val.u.xval) != 0) 2918 return 0; 2919 break; 2920 } 2921 a = a->left; 2922 b = b->left; 2923 } 2924 return 0; 2925 } 2926 2927 static void 2928 walkrotate(Node **np) 2929 { 2930 int w, sl, sr, s; 2931 Node *l, *r; 2932 Node *n; 2933 2934 n = *np; 2935 2936 // Want << | >> or >> | << or << ^ >> or >> ^ << on unsigned value. 2937 l = n->left; 2938 r = n->right; 2939 if((n->op != OOR && n->op != OXOR) || 2940 (l->op != OLSH && l->op != ORSH) || 2941 (r->op != OLSH && r->op != ORSH) || 2942 n->type == T || issigned[n->type->etype] || 2943 l->op == r->op) { 2944 return; 2945 } 2946 2947 // Want same, side effect-free expression on lhs of both shifts. 2948 if(!samecheap(l->left, r->left)) 2949 return; 2950 2951 // Constants adding to width? 2952 w = l->type->width * 8; 2953 if(smallintconst(l->right) && smallintconst(r->right)) { 2954 if((sl=mpgetfix(l->right->val.u.xval)) >= 0 && (sr=mpgetfix(r->right->val.u.xval)) >= 0 && sl+sr == w) 2955 goto yes; 2956 return; 2957 } 2958 2959 // TODO: Could allow s and 32-s if s is bounded (maybe s&31 and 32-s&31). 2960 return; 2961 2962 yes: 2963 // Rewrite left shift half to left rotate. 2964 if(l->op == OLSH) 2965 n = l; 2966 else 2967 n = r; 2968 n->op = OLROT; 2969 2970 // Remove rotate 0 and rotate w. 2971 s = mpgetfix(n->right->val.u.xval); 2972 if(s == 0 || s == w) 2973 n = n->left; 2974 2975 *np = n; 2976 return; 2977 } 2978 2979 /* 2980 * walkmul rewrites integer multiplication by powers of two as shifts. 2981 */ 2982 static void 2983 walkmul(Node **np, NodeList **init) 2984 { 2985 Node *n, *nl, *nr; 2986 int pow, neg, w; 2987 2988 n = *np; 2989 if(!isint[n->type->etype]) 2990 return; 2991 2992 if(n->right->op == OLITERAL) { 2993 nl = n->left; 2994 nr = n->right; 2995 } else if(n->left->op == OLITERAL) { 2996 nl = n->right; 2997 nr = n->left; 2998 } else 2999 return; 3000 3001 neg = 0; 3002 3003 // x*0 is 0 (and side effects of x). 3004 if(mpgetfix(nr->val.u.xval) == 0) { 3005 cheapexpr(nl, init); 3006 nodconst(n, n->type, 0); 3007 goto ret; 3008 } 3009 3010 // nr is a constant. 3011 pow = powtwo(nr); 3012 if(pow < 0) 3013 return; 3014 if(pow >= 1000) { 3015 // negative power of 2, like -16 3016 neg = 1; 3017 pow -= 1000; 3018 } 3019 3020 w = nl->type->width*8; 3021 if(pow+1 >= w)// too big, shouldn't happen 3022 return; 3023 3024 nl = cheapexpr(nl, init); 3025 3026 if(pow == 0) { 3027 // x*1 is x 3028 n = nl; 3029 goto ret; 3030 } 3031 3032 n = nod(OLSH, nl, nodintconst(pow)); 3033 3034 ret: 3035 if(neg) 3036 n = nod(OMINUS, n, N); 3037 3038 typecheck(&n, Erv); 3039 walkexpr(&n, init); 3040 *np = n; 3041 } 3042 3043 /* 3044 * walkdiv rewrites division by a constant as less expensive 3045 * operations. 3046 */ 3047 static void 3048 walkdiv(Node **np, NodeList **init) 3049 { 3050 Node *n, *nl, *nr, *nc; 3051 Node *n1, *n2, *n3, *n4; 3052 int pow; // if >= 0, nr is 1<<pow 3053 int s; // 1 if nr is negative. 3054 int w; 3055 Type *twide; 3056 Magic m; 3057 3058 n = *np; 3059 if(n->right->op != OLITERAL) 3060 return; 3061 // nr is a constant. 3062 nl = cheapexpr(n->left, init); 3063 nr = n->right; 3064 3065 // special cases of mod/div 3066 // by a constant 3067 w = nl->type->width*8; 3068 s = 0; 3069 pow = powtwo(nr); 3070 if(pow >= 1000) { 3071 // negative power of 2 3072 s = 1; 3073 pow -= 1000; 3074 } 3075 3076 if(pow+1 >= w) { 3077 // divisor too large. 3078 return; 3079 } 3080 if(pow < 0) { 3081 goto divbymul; 3082 } 3083 3084 switch(pow) { 3085 case 0: 3086 if(n->op == OMOD) { 3087 // nl % 1 is zero. 3088 nodconst(n, n->type, 0); 3089 } else if(s) { 3090 // divide by -1 3091 n->op = OMINUS; 3092 n->right = N; 3093 } else { 3094 // divide by 1 3095 n = nl; 3096 } 3097 break; 3098 default: 3099 if(issigned[n->type->etype]) { 3100 if(n->op == OMOD) { 3101 // signed modulo 2^pow is like ANDing 3102 // with the last pow bits, but if nl < 0, 3103 // nl & (2^pow-1) is (nl+1)%2^pow - 1. 3104 nc = nod(OXXX, N, N); 3105 nodconst(nc, types[simtype[TUINT]], w-1); 3106 n1 = nod(ORSH, nl, nc); // n1 = -1 iff nl < 0. 3107 if(pow == 1) { 3108 typecheck(&n1, Erv); 3109 n1 = cheapexpr(n1, init); 3110 // n = (nl+ε)&1 -ε where ε=1 iff nl<0. 3111 n2 = nod(OSUB, nl, n1); 3112 nc = nod(OXXX, N, N); 3113 nodconst(nc, nl->type, 1); 3114 n3 = nod(OAND, n2, nc); 3115 n = nod(OADD, n3, n1); 3116 } else { 3117 // n = (nl+ε)&(nr-1) - ε where ε=2^pow-1 iff nl<0. 3118 nc = nod(OXXX, N, N); 3119 nodconst(nc, nl->type, (1LL<<pow)-1); 3120 n2 = nod(OAND, n1, nc); // n2 = 2^pow-1 iff nl<0. 3121 typecheck(&n2, Erv); 3122 n2 = cheapexpr(n2, init); 3123 3124 n3 = nod(OADD, nl, n2); 3125 n4 = nod(OAND, n3, nc); 3126 n = nod(OSUB, n4, n2); 3127 } 3128 break; 3129 } else { 3130 // arithmetic right shift does not give the correct rounding. 3131 // if nl >= 0, nl >> n == nl / nr 3132 // if nl < 0, we want to add 2^n-1 first. 3133 nc = nod(OXXX, N, N); 3134 nodconst(nc, types[simtype[TUINT]], w-1); 3135 n1 = nod(ORSH, nl, nc); // n1 = -1 iff nl < 0. 3136 if(pow == 1) { 3137 // nl+1 is nl-(-1) 3138 n->left = nod(OSUB, nl, n1); 3139 } else { 3140 // Do a logical right right on -1 to keep pow bits. 3141 nc = nod(OXXX, N, N); 3142 nodconst(nc, types[simtype[TUINT]], w-pow); 3143 n2 = nod(ORSH, conv(n1, tounsigned(nl->type)), nc); 3144 n->left = nod(OADD, nl, conv(n2, nl->type)); 3145 } 3146 // n = (nl + 2^pow-1) >> pow 3147 n->op = ORSH; 3148 nc = nod(OXXX, N, N); 3149 nodconst(nc, types[simtype[TUINT]], pow); 3150 n->right = nc; 3151 n->typecheck = 0; 3152 } 3153 if(s) 3154 n = nod(OMINUS, n, N); 3155 break; 3156 } 3157 nc = nod(OXXX, N, N); 3158 if(n->op == OMOD) { 3159 // n = nl & (nr-1) 3160 n->op = OAND; 3161 nodconst(nc, nl->type, mpgetfix(nr->val.u.xval)-1); 3162 } else { 3163 // n = nl >> pow 3164 n->op = ORSH; 3165 nodconst(nc, types[simtype[TUINT]], pow); 3166 } 3167 n->typecheck = 0; 3168 n->right = nc; 3169 break; 3170 } 3171 goto ret; 3172 3173 divbymul: 3174 // try to do division by multiply by (2^w)/d 3175 // see hacker's delight chapter 10 3176 // TODO: support 64-bit magic multiply here. 3177 m.w = w; 3178 if(issigned[nl->type->etype]) { 3179 m.sd = mpgetfix(nr->val.u.xval); 3180 smagic(&m); 3181 } else { 3182 m.ud = mpgetfix(nr->val.u.xval); 3183 umagic(&m); 3184 } 3185 if(m.bad) 3186 return; 3187 3188 // We have a quick division method so use it 3189 // for modulo too. 3190 if(n->op == OMOD) 3191 goto longmod; 3192 3193 switch(simtype[nl->type->etype]) { 3194 default: 3195 return; 3196 3197 case TUINT8: 3198 case TUINT16: 3199 case TUINT32: 3200 // n1 = nl * magic >> w (HMUL) 3201 nc = nod(OXXX, N, N); 3202 nodconst(nc, nl->type, m.um); 3203 n1 = nod(OMUL, nl, nc); 3204 typecheck(&n1, Erv); 3205 n1->op = OHMUL; 3206 if(m.ua) { 3207 // Select a Go type with (at least) twice the width. 3208 switch(simtype[nl->type->etype]) { 3209 default: 3210 return; 3211 case TUINT8: 3212 case TUINT16: 3213 twide = types[TUINT32]; 3214 break; 3215 case TUINT32: 3216 twide = types[TUINT64]; 3217 break; 3218 case TINT8: 3219 case TINT16: 3220 twide = types[TINT32]; 3221 break; 3222 case TINT32: 3223 twide = types[TINT64]; 3224 break; 3225 } 3226 3227 // add numerator (might overflow). 3228 // n2 = (n1 + nl) 3229 n2 = nod(OADD, conv(n1, twide), conv(nl, twide)); 3230 3231 // shift by m.s 3232 nc = nod(OXXX, N, N); 3233 nodconst(nc, types[TUINT], m.s); 3234 n = conv(nod(ORSH, n2, nc), nl->type); 3235 } else { 3236 // n = n1 >> m.s 3237 nc = nod(OXXX, N, N); 3238 nodconst(nc, types[TUINT], m.s); 3239 n = nod(ORSH, n1, nc); 3240 } 3241 break; 3242 3243 case TINT8: 3244 case TINT16: 3245 case TINT32: 3246 // n1 = nl * magic >> w 3247 nc = nod(OXXX, N, N); 3248 nodconst(nc, nl->type, m.sm); 3249 n1 = nod(OMUL, nl, nc); 3250 typecheck(&n1, Erv); 3251 n1->op = OHMUL; 3252 if(m.sm < 0) { 3253 // add the numerator. 3254 n1 = nod(OADD, n1, nl); 3255 } 3256 // shift by m.s 3257 nc = nod(OXXX, N, N); 3258 nodconst(nc, types[TUINT], m.s); 3259 n2 = conv(nod(ORSH, n1, nc), nl->type); 3260 // add 1 iff n1 is negative. 3261 nc = nod(OXXX, N, N); 3262 nodconst(nc, types[TUINT], w-1); 3263 n3 = nod(ORSH, nl, nc); // n4 = -1 iff n1 is negative. 3264 n = nod(OSUB, n2, n3); 3265 // apply sign. 3266 if(m.sd < 0) 3267 n = nod(OMINUS, n, N); 3268 break; 3269 } 3270 goto ret; 3271 3272 longmod: 3273 // rewrite as A%B = A - (A/B*B). 3274 n1 = nod(ODIV, nl, nr); 3275 n2 = nod(OMUL, n1, nr); 3276 n = nod(OSUB, nl, n2); 3277 goto ret; 3278 3279 ret: 3280 typecheck(&n, Erv); 3281 walkexpr(&n, init); 3282 *np = n; 3283 } 3284 3285 // return 1 if integer n must be in range [0, max), 0 otherwise 3286 static int 3287 bounded(Node *n, int64 max) 3288 { 3289 int64 v; 3290 int32 bits; 3291 int sign; 3292 3293 if(n->type == T || !isint[n->type->etype]) 3294 return 0; 3295 3296 sign = issigned[n->type->etype]; 3297 bits = 8*n->type->width; 3298 3299 if(smallintconst(n)) { 3300 v = mpgetfix(n->val.u.xval); 3301 return 0 <= v && v < max; 3302 } 3303 3304 switch(n->op) { 3305 case OAND: 3306 v = -1; 3307 if(smallintconst(n->left)) { 3308 v = mpgetfix(n->left->val.u.xval); 3309 } else if(smallintconst(n->right)) { 3310 v = mpgetfix(n->right->val.u.xval); 3311 } 3312 if(0 <= v && v < max) 3313 return 1; 3314 break; 3315 3316 case OMOD: 3317 if(!sign && smallintconst(n->right)) { 3318 v = mpgetfix(n->right->val.u.xval); 3319 if(0 <= v && v <= max) 3320 return 1; 3321 } 3322 break; 3323 3324 case ODIV: 3325 if(!sign && smallintconst(n->right)) { 3326 v = mpgetfix(n->right->val.u.xval); 3327 while(bits > 0 && v >= 2) { 3328 bits--; 3329 v >>= 1; 3330 } 3331 } 3332 break; 3333 3334 case ORSH: 3335 if(!sign && smallintconst(n->right)) { 3336 v = mpgetfix(n->right->val.u.xval); 3337 if(v > bits) 3338 return 1; 3339 bits -= v; 3340 } 3341 break; 3342 } 3343 3344 if(!sign && bits <= 62 && (1LL<<bits) <= max) 3345 return 1; 3346 3347 return 0; 3348 } 3349 3350 void 3351 usefield(Node *n) 3352 { 3353 Type *field, *l; 3354 3355 if(!fieldtrack_enabled) 3356 return; 3357 3358 switch(n->op) { 3359 default: 3360 fatal("usefield %O", n->op); 3361 case ODOT: 3362 case ODOTPTR: 3363 break; 3364 } 3365 3366 field = n->paramfld; 3367 if(field == T) 3368 fatal("usefield %T %S without paramfld", n->left->type, n->right->sym); 3369 if(field->note == nil || strstr(field->note->s, "go:\"track\"") == nil) 3370 return; 3371 3372 // dedup on list 3373 if(field->lastfn == curfn) 3374 return; 3375 field->lastfn = curfn; 3376 field->outer = n->left->type; 3377 if(isptr[field->outer->etype]) 3378 field->outer = field->outer->type; 3379 if(field->outer->sym == S) 3380 yyerror("tracked field must be in named struct type"); 3381 if(!exportname(field->sym->name)) 3382 yyerror("tracked field must be exported (upper case)"); 3383 3384 l = typ(0); 3385 l->type = field; 3386 l->down = curfn->paramfld; 3387 curfn->paramfld = l; 3388 } 3389 3390 static int 3391 candiscardlist(NodeList *l) 3392 { 3393 for(; l; l=l->next) 3394 if(!candiscard(l->n)) 3395 return 0; 3396 return 1; 3397 } 3398 3399 int 3400 candiscard(Node *n) 3401 { 3402 if(n == N) 3403 return 1; 3404 3405 switch(n->op) { 3406 default: 3407 return 0; 3408 3409 case ONAME: 3410 case ONONAME: 3411 case OTYPE: 3412 case OPACK: 3413 case OLITERAL: 3414 case OADD: 3415 case OSUB: 3416 case OOR: 3417 case OXOR: 3418 case OADDSTR: 3419 case OADDR: 3420 case OANDAND: 3421 case OARRAYBYTESTR: 3422 case OARRAYRUNESTR: 3423 case OSTRARRAYBYTE: 3424 case OSTRARRAYRUNE: 3425 case OCAP: 3426 case OCMPIFACE: 3427 case OCMPSTR: 3428 case OCOMPLIT: 3429 case OMAPLIT: 3430 case OSTRUCTLIT: 3431 case OARRAYLIT: 3432 case OPTRLIT: 3433 case OCONV: 3434 case OCONVIFACE: 3435 case OCONVNOP: 3436 case ODOT: 3437 case OEQ: 3438 case ONE: 3439 case OLT: 3440 case OLE: 3441 case OGT: 3442 case OGE: 3443 case OKEY: 3444 case OLEN: 3445 case OMUL: 3446 case OLSH: 3447 case ORSH: 3448 case OAND: 3449 case OANDNOT: 3450 case ONEW: 3451 case ONOT: 3452 case OCOM: 3453 case OPLUS: 3454 case OMINUS: 3455 case OOROR: 3456 case OPAREN: 3457 case ORUNESTR: 3458 case OREAL: 3459 case OIMAG: 3460 case OCOMPLEX: 3461 // Discardable as long as the subpieces are. 3462 break; 3463 3464 case ODIV: 3465 case OMOD: 3466 // Discardable as long as we know it's not division by zero. 3467 if(isconst(n->right, CTINT) && mpcmpfixc(n->right->val.u.xval, 0) != 0) 3468 break; 3469 if(isconst(n->right, CTFLT) && mpcmpfltc(n->right->val.u.fval, 0) != 0) 3470 break; 3471 return 0; 3472 3473 case OMAKECHAN: 3474 case OMAKEMAP: 3475 // Discardable as long as we know it won't fail because of a bad size. 3476 if(isconst(n->left, CTINT) && mpcmpfixc(n->left->val.u.xval, 0) == 0) 3477 break; 3478 return 0; 3479 3480 case OMAKESLICE: 3481 // Difficult to tell what sizes are okay. 3482 return 0; 3483 } 3484 3485 if(!candiscard(n->left) || 3486 !candiscard(n->right) || 3487 !candiscard(n->ntest) || 3488 !candiscard(n->nincr) || 3489 !candiscardlist(n->ninit) || 3490 !candiscardlist(n->nbody) || 3491 !candiscardlist(n->nelse) || 3492 !candiscardlist(n->list) || 3493 !candiscardlist(n->rlist)) { 3494 return 0; 3495 } 3496 3497 return 1; 3498 }