github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/cmd/gc/order.c (about) 1 // Copyright 2012 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 // Rewrite tree to use separate statements to enforce 6 // order of evaluation. Makes walk easier, because it 7 // can (after this runs) reorder at will within an expression. 8 // 9 // Rewrite x op= y into x = x op y. 10 // 11 // Introduce temporaries as needed by runtime routines. 12 // For example, the map runtime routines take the map key 13 // by reference, so make sure all map keys are addressable 14 // by copying them to temporaries as needed. 15 // The same is true for channel operations. 16 // 17 // Arrange that map index expressions only appear in direct 18 // assignments x = m[k] or m[k] = x, never in larger expressions. 19 // 20 // Arrange that receive expressions only appear in direct assignments 21 // x = <-c or as standalone statements <-c, never in larger expressions. 22 23 // TODO(rsc): The temporary introduction during multiple assignments 24 // should be moved into this file, so that the temporaries can be cleaned 25 // and so that conversions implicit in the OAS2FUNC and OAS2RECV 26 // nodes can be made explicit and then have their temporaries cleaned. 27 28 // TODO(rsc): Goto and multilevel break/continue can jump over 29 // inserted VARKILL annotations. Work out a way to handle these. 30 // The current implementation is safe, in that it will execute correctly. 31 // But it won't reuse temporaries as aggressively as it might, and 32 // it can result in unnecessary zeroing of those variables in the function 33 // prologue. 34 35 #include <u.h> 36 #include <libc.h> 37 #include "go.h" 38 39 // Order holds state during the ordering process. 40 typedef struct Order Order; 41 struct Order 42 { 43 NodeList *out; // list of generated statements 44 NodeList *temp; // head of stack of temporary variables 45 NodeList *free; // free list of NodeList* structs (for use in temp) 46 }; 47 48 static void orderstmt(Node*, Order*); 49 static void orderstmtlist(NodeList*, Order*); 50 static void orderblock(NodeList **l); 51 static void orderexpr(Node**, Order*); 52 static void orderexprinplace(Node**, Order*); 53 static void orderexprlist(NodeList*, Order*); 54 static void orderexprlistinplace(NodeList*, Order*); 55 56 // Order rewrites fn->nbody to apply the ordering constraints 57 // described in the comment at the top of the file. 58 void 59 order(Node *fn) 60 { 61 orderblock(&fn->nbody); 62 } 63 64 // Ordertemp allocates a new temporary with the given type, 65 // pushes it onto the temp stack, and returns it. 66 // If clear is true, ordertemp emits code to zero the temporary. 67 static Node* 68 ordertemp(Type *t, Order *order, int clear) 69 { 70 Node *var, *a; 71 NodeList *l; 72 73 var = temp(t); 74 if(clear) { 75 a = nod(OAS, var, N); 76 typecheck(&a, Etop); 77 order->out = list(order->out, a); 78 } 79 if((l = order->free) == nil) 80 l = mal(sizeof *l); 81 order->free = l->next; 82 l->next = order->temp; 83 l->n = var; 84 order->temp = l; 85 return var; 86 } 87 88 // Ordercopyexpr behaves like ordertemp but also emits 89 // code to initialize the temporary to the value n. 90 // 91 // The clear argument is provided for use when the evaluation 92 // of tmp = n turns into a function call that is passed a pointer 93 // to the temporary as the output space. If the call blocks before 94 // tmp has been written, the garbage collector will still treat the 95 // temporary as live, so we must zero it before entering that call. 96 // Today, this only happens for channel receive operations. 97 // (The other candidate would be map access, but map access 98 // returns a pointer to the result data instead of taking a pointer 99 // to be filled in.) 100 static Node* 101 ordercopyexpr(Node *n, Type *t, Order *order, int clear) 102 { 103 Node *a, *var; 104 105 var = ordertemp(t, order, clear); 106 a = nod(OAS, var, n); 107 typecheck(&a, Etop); 108 order->out = list(order->out, a); 109 return var; 110 } 111 112 // Ordercheapexpr returns a cheap version of n. 113 // The definition of cheap is that n is a variable or constant. 114 // If not, ordercheapexpr allocates a new tmp, emits tmp = n, 115 // and then returns tmp. 116 static Node* 117 ordercheapexpr(Node *n, Order *order) 118 { 119 switch(n->op) { 120 case ONAME: 121 case OLITERAL: 122 return n; 123 } 124 return ordercopyexpr(n, n->type, order, 0); 125 } 126 127 // Ordersafeexpr returns a safe version of n. 128 // The definition of safe is that n can appear multiple times 129 // without violating the semantics of the original program, 130 // and that assigning to the safe version has the same effect 131 // as assigning to the original n. 132 // 133 // The intended use is to apply to x when rewriting x += y into x = x + y. 134 static Node* 135 ordersafeexpr(Node *n, Order *order) 136 { 137 Node *l, *r, *a; 138 139 switch(n->op) { 140 default: 141 fatal("ordersafeexpr %O", n->op); 142 143 case ONAME: 144 case OLITERAL: 145 return n; 146 147 case ODOT: 148 l = ordersafeexpr(n->left, order); 149 if(l == n->left) 150 return n; 151 a = nod(OXXX, N, N); 152 *a = *n; 153 a->orig = a; 154 a->left = l; 155 typecheck(&a, Erv); 156 return a; 157 158 case ODOTPTR: 159 case OIND: 160 l = ordercheapexpr(n->left, order); 161 if(l == n->left) 162 return n; 163 a = nod(OXXX, N, N); 164 *a = *n; 165 a->orig = a; 166 a->left = l; 167 typecheck(&a, Erv); 168 return a; 169 170 case OINDEX: 171 case OINDEXMAP: 172 if(isfixedarray(n->left->type)) 173 l = ordersafeexpr(n->left, order); 174 else 175 l = ordercheapexpr(n->left, order); 176 r = ordercheapexpr(n->right, order); 177 if(l == n->left && r == n->right) 178 return n; 179 a = nod(OXXX, N, N); 180 *a = *n; 181 a->orig = a; 182 a->left = l; 183 a->right = r; 184 typecheck(&a, Erv); 185 return a; 186 } 187 } 188 189 // Istemp reports whether n is a temporary variable. 190 static int 191 istemp(Node *n) 192 { 193 if(n->op != ONAME) 194 return 0; 195 return strncmp(n->sym->name, "autotmp_", 8) == 0; 196 } 197 198 // Isaddrokay reports whether it is okay to pass n's address to runtime routines. 199 // Taking the address of a variable makes the liveness and optimization analyses 200 // lose track of where the variable's lifetime ends. To avoid hurting the analyses 201 // of ordinary stack variables, those are not 'isaddrokay'. Temporaries are okay, 202 // because we emit explicit VARKILL instructions marking the end of those 203 // temporaries' lifetimes. 204 static int 205 isaddrokay(Node *n) 206 { 207 return islvalue(n) && (n->op != ONAME || n->class == PEXTERN || istemp(n)); 208 } 209 210 // Orderaddrtemp ensures that *np is okay to pass by address to runtime routines. 211 // If the original argument *np is not okay, orderaddrtemp creates a tmp, emits 212 // tmp = *np, and then sets *np to the tmp variable. 213 static void 214 orderaddrtemp(Node **np, Order *order) 215 { 216 Node *n; 217 218 n = *np; 219 if(isaddrokay(n)) 220 return; 221 *np = ordercopyexpr(n, n->type, order, 0); 222 } 223 224 // Marktemp returns the top of the temporary variable stack. 225 static NodeList* 226 marktemp(Order *order) 227 { 228 return order->temp; 229 } 230 231 // Poptemp pops temporaries off the stack until reaching the mark, 232 // which must have been returned by marktemp. 233 static void 234 poptemp(NodeList *mark, Order *order) 235 { 236 NodeList *l; 237 238 while((l = order->temp) != mark) { 239 order->temp = l->next; 240 l->next = order->free; 241 order->free = l; 242 } 243 } 244 245 // Cleantempnopop emits to *out VARKILL instructions for each temporary 246 // above the mark on the temporary stack, but it does not pop them 247 // from the stack. 248 static void 249 cleantempnopop(NodeList *mark, Order *order, NodeList **out) 250 { 251 NodeList *l; 252 Node *kill; 253 254 for(l=order->temp; l != mark; l=l->next) { 255 kill = nod(OVARKILL, l->n, N); 256 typecheck(&kill, Etop); 257 *out = list(*out, kill); 258 } 259 } 260 261 // Cleantemp emits VARKILL instructions for each temporary above the 262 // mark on the temporary stack and removes them from the stack. 263 static void 264 cleantemp(NodeList *top, Order *order) 265 { 266 cleantempnopop(top, order, &order->out); 267 poptemp(top, order); 268 } 269 270 // Orderstmtlist orders each of the statements in the list. 271 static void 272 orderstmtlist(NodeList *l, Order *order) 273 { 274 for(; l; l=l->next) 275 orderstmt(l->n, order); 276 } 277 278 // Orderblock orders the block of statements *l onto a new list, 279 // and then replaces *l with that list. 280 static void 281 orderblock(NodeList **l) 282 { 283 Order order; 284 NodeList *mark; 285 286 memset(&order, 0, sizeof order); 287 mark = marktemp(&order); 288 orderstmtlist(*l, &order); 289 cleantemp(mark, &order); 290 *l = order.out; 291 } 292 293 // Orderexprinplace orders the side effects in *np and 294 // leaves them as the init list of the final *np. 295 static void 296 orderexprinplace(Node **np, Order *outer) 297 { 298 Node *n; 299 NodeList **lp; 300 Order order; 301 302 n = *np; 303 memset(&order, 0, sizeof order); 304 orderexpr(&n, &order); 305 addinit(&n, order.out); 306 307 // insert new temporaries from order 308 // at head of outer list. 309 lp = &order.temp; 310 while(*lp != nil) 311 lp = &(*lp)->next; 312 *lp = outer->temp; 313 outer->temp = order.temp; 314 315 *np = n; 316 } 317 318 // Orderstmtinplace orders the side effects of the single statement *np 319 // and replaces it with the resulting statement list. 320 static void 321 orderstmtinplace(Node **np) 322 { 323 Node *n; 324 Order order; 325 NodeList *mark; 326 327 n = *np; 328 memset(&order, 0, sizeof order); 329 mark = marktemp(&order); 330 orderstmt(n, &order); 331 cleantemp(mark, &order); 332 *np = liststmt(order.out); 333 } 334 335 // Orderinit moves n's init list to order->out. 336 static void 337 orderinit(Node *n, Order *order) 338 { 339 orderstmtlist(n->ninit, order); 340 n->ninit = nil; 341 } 342 343 // Ismulticall reports whether the list l is f() for a multi-value function. 344 // Such an f() could appear as the lone argument to a multi-arg function. 345 static int 346 ismulticall(NodeList *l) 347 { 348 Node *n; 349 350 // one arg only 351 if(l == nil || l->next != nil) 352 return 0; 353 n = l->n; 354 355 // must be call 356 switch(n->op) { 357 default: 358 return 0; 359 case OCALLFUNC: 360 case OCALLMETH: 361 case OCALLINTER: 362 break; 363 } 364 365 // call must return multiple values 366 return n->left->type->outtuple > 1; 367 } 368 369 // Copyret emits t1, t2, ... = n, where n is a function call, 370 // and then returns the list t1, t2, .... 371 static NodeList* 372 copyret(Node *n, Order *order) 373 { 374 Type *t; 375 Node *tmp, *as; 376 NodeList *l1, *l2; 377 Iter tl; 378 379 if(n->type->etype != TSTRUCT || !n->type->funarg) 380 fatal("copyret %T %d", n->type, n->left->type->outtuple); 381 382 l1 = nil; 383 l2 = nil; 384 for(t=structfirst(&tl, &n->type); t; t=structnext(&tl)) { 385 tmp = temp(t->type); 386 l1 = list(l1, tmp); 387 l2 = list(l2, tmp); 388 } 389 390 as = nod(OAS2, N, N); 391 as->list = l1; 392 as->rlist = list1(n); 393 typecheck(&as, Etop); 394 orderstmt(as, order); 395 396 return l2; 397 } 398 399 // Ordercallargs orders the list of call arguments *l. 400 static void 401 ordercallargs(NodeList **l, Order *order) 402 { 403 if(ismulticall(*l)) { 404 // return f() where f() is multiple values. 405 *l = copyret((*l)->n, order); 406 } else { 407 orderexprlist(*l, order); 408 } 409 } 410 411 // Ordercall orders the call expression n. 412 // n->op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY. 413 static void 414 ordercall(Node *n, Order *order) 415 { 416 orderexpr(&n->left, order); 417 orderexpr(&n->right, order); // ODDDARG temp 418 ordercallargs(&n->list, order); 419 } 420 421 // Ordermapassign appends n to order->out, introducing temporaries 422 // to make sure that all map assignments have the form m[k] = x, 423 // where x is adressable. 424 // (Orderexpr has already been called on n, so we know k is addressable.) 425 // 426 // If n is m[k] = x where x is not addressable, the rewrite is: 427 // tmp = x 428 // m[k] = tmp 429 // 430 // If n is the multiple assignment form ..., m[k], ... = ..., the rewrite is 431 // t1 = m 432 // t2 = k 433 // ...., t3, ... = x 434 // t1[t2] = t3 435 // 436 // The temporaries t1, t2 are needed in case the ... being assigned 437 // contain m or k. They are usually unnecessary, but in the unnecessary 438 // cases they are also typically registerizable, so not much harm done. 439 // And this only applies to the multiple-assignment form. 440 // We could do a more precise analysis if needed, like in walk.c. 441 static void 442 ordermapassign(Node *n, Order *order) 443 { 444 Node *m, *a; 445 NodeList *l; 446 NodeList *post; 447 448 switch(n->op) { 449 default: 450 fatal("ordermapassign %O", n->op); 451 452 case OAS: 453 order->out = list(order->out, n); 454 if(n->left->op == OINDEXMAP && !isaddrokay(n->right)) { 455 m = n->left; 456 n->left = ordertemp(m->type, order, 0); 457 a = nod(OAS, m, n->left); 458 typecheck(&a, Etop); 459 order->out = list(order->out, a); 460 } 461 break; 462 463 case OAS2: 464 case OAS2DOTTYPE: 465 case OAS2MAPR: 466 case OAS2FUNC: 467 post = nil; 468 for(l=n->list; l != nil; l=l->next) { 469 if(l->n->op == OINDEXMAP) { 470 m = l->n; 471 if(!istemp(m->left)) 472 m->left = ordercopyexpr(m->left, m->left->type, order, 0); 473 if(!istemp(m->right)) 474 m->right = ordercopyexpr(m->right, m->right->type, order, 0); 475 l->n = ordertemp(m->type, order, 0); 476 a = nod(OAS, m, l->n); 477 typecheck(&a, Etop); 478 post = list(post, a); 479 } 480 } 481 order->out = list(order->out, n); 482 order->out = concat(order->out, post); 483 break; 484 } 485 } 486 487 // Orderstmt orders the statement n, appending to order->out. 488 // Temporaries created during the statement are cleaned 489 // up using VARKILL instructions as possible. 490 static void 491 orderstmt(Node *n, Order *order) 492 { 493 int lno; 494 NodeList *l, *t, *t1; 495 Node *r, *tmp1, *tmp2, **np; 496 Type *ch; 497 498 if(n == N) 499 return; 500 501 lno = setlineno(n); 502 503 orderinit(n, order); 504 505 switch(n->op) { 506 default: 507 fatal("orderstmt %O", n->op); 508 509 case OVARKILL: 510 order->out = list(order->out, n); 511 break; 512 513 case OAS: 514 case OAS2: 515 case OAS2DOTTYPE: 516 case OCLOSE: 517 case OCOPY: 518 case OPRINT: 519 case OPRINTN: 520 case ORECOVER: 521 case ORECV: 522 t = marktemp(order); 523 orderexpr(&n->left, order); 524 orderexpr(&n->right, order); 525 orderexprlist(n->list, order); 526 orderexprlist(n->rlist, order); 527 switch(n->op) { 528 case OAS: 529 case OAS2: 530 case OAS2DOTTYPE: 531 ordermapassign(n, order); 532 break; 533 default: 534 order->out = list(order->out, n); 535 break; 536 } 537 cleantemp(t, order); 538 break; 539 540 case OASOP: 541 // Special: rewrite l op= r into l = l op r. 542 // This simplies quite a few operations; 543 // most important is that it lets us separate 544 // out map read from map write when l is 545 // a map index expression. 546 t = marktemp(order); 547 orderexpr(&n->left, order); 548 n->left = ordersafeexpr(n->left, order); 549 tmp1 = treecopy(n->left); 550 if(tmp1->op == OINDEXMAP) 551 tmp1->etype = 0; // now an rvalue not an lvalue 552 tmp1 = ordercopyexpr(tmp1, n->left->type, order, 0); 553 n->right = nod(n->etype, tmp1, n->right); 554 typecheck(&n->right, Erv); 555 orderexpr(&n->right, order); 556 n->etype = 0; 557 n->op = OAS; 558 ordermapassign(n, order); 559 cleantemp(t, order); 560 break; 561 562 case OAS2MAPR: 563 // Special: make sure key is addressable, 564 // and make sure OINDEXMAP is not copied out. 565 t = marktemp(order); 566 orderexprlist(n->list, order); 567 r = n->rlist->n; 568 orderexpr(&r->left, order); 569 orderexpr(&r->right, order); 570 // See case OINDEXMAP below. 571 if(r->right->op == OARRAYBYTESTR) 572 r->right->op = OARRAYBYTESTRTMP; 573 orderaddrtemp(&r->right, order); 574 ordermapassign(n, order); 575 cleantemp(t, order); 576 break; 577 578 case OAS2FUNC: 579 // Special: avoid copy of func call n->rlist->n. 580 t = marktemp(order); 581 orderexprlist(n->list, order); 582 ordercall(n->rlist->n, order); 583 ordermapassign(n, order); 584 cleantemp(t, order); 585 break; 586 587 case OAS2RECV: 588 // Special: avoid copy of receive. 589 // Use temporary variables to hold result, 590 // so that chanrecv can take address of temporary. 591 t = marktemp(order); 592 orderexprlist(n->list, order); 593 orderexpr(&n->rlist->n->left, order); // arg to recv 594 ch = n->rlist->n->left->type; 595 tmp1 = ordertemp(ch->type, order, haspointers(ch->type)); 596 tmp2 = ordertemp(types[TBOOL], order, 0); 597 order->out = list(order->out, n); 598 r = nod(OAS, n->list->n, tmp1); 599 typecheck(&r, Etop); 600 ordermapassign(r, order); 601 r = nod(OAS, n->list->next->n, tmp2); 602 typecheck(&r, Etop); 603 ordermapassign(r, order); 604 n->list = list(list1(tmp1), tmp2); 605 cleantemp(t, order); 606 break; 607 608 case OBLOCK: 609 case OEMPTY: 610 // Special: does not save n onto out. 611 orderstmtlist(n->list, order); 612 break; 613 614 case OBREAK: 615 case OCONTINUE: 616 case ODCL: 617 case ODCLCONST: 618 case ODCLTYPE: 619 case OFALL: 620 case OXFALL: 621 case OGOTO: 622 case OLABEL: 623 case ORETJMP: 624 // Special: n->left is not an expression; save as is. 625 order->out = list(order->out, n); 626 break; 627 628 case OCALLFUNC: 629 case OCALLINTER: 630 case OCALLMETH: 631 // Special: handle call arguments. 632 t = marktemp(order); 633 ordercall(n, order); 634 order->out = list(order->out, n); 635 cleantemp(t, order); 636 break; 637 638 case ODEFER: 639 case OPROC: 640 // Special: order arguments to inner call but not call itself. 641 t = marktemp(order); 642 switch(n->left->op) { 643 case ODELETE: 644 // Delete will take the address of the key. 645 // Copy key into new temp and do not clean it 646 // (it persists beyond the statement). 647 orderexprlist(n->left->list, order); 648 t1 = marktemp(order); 649 np = &n->left->list->next->n; // map key 650 *np = ordercopyexpr(*np, (*np)->type, order, 0); 651 poptemp(t1, order); 652 break; 653 default: 654 ordercall(n->left, order); 655 break; 656 } 657 order->out = list(order->out, n); 658 cleantemp(t, order); 659 break; 660 661 case ODELETE: 662 t = marktemp(order); 663 orderexpr(&n->list->n, order); 664 orderexpr(&n->list->next->n, order); 665 orderaddrtemp(&n->list->next->n, order); // map key 666 order->out = list(order->out, n); 667 cleantemp(t, order); 668 break; 669 670 case OFOR: 671 // Clean temporaries from condition evaluation at 672 // beginning of loop body and after for statement. 673 t = marktemp(order); 674 orderexprinplace(&n->ntest, order); 675 l = nil; 676 cleantempnopop(t, order, &l); 677 n->nbody = concat(l, n->nbody); 678 orderblock(&n->nbody); 679 orderstmtinplace(&n->nincr); 680 order->out = list(order->out, n); 681 cleantemp(t, order); 682 break; 683 684 case OIF: 685 // Clean temporaries from condition at 686 // beginning of both branches. 687 t = marktemp(order); 688 orderexprinplace(&n->ntest, order); 689 l = nil; 690 cleantempnopop(t, order, &l); 691 n->nbody = concat(l, n->nbody); 692 l = nil; 693 cleantempnopop(t, order, &l); 694 n->nelse = concat(l, n->nelse); 695 poptemp(t, order); 696 orderblock(&n->nbody); 697 orderblock(&n->nelse); 698 order->out = list(order->out, n); 699 break; 700 701 case OPANIC: 702 // Special: argument will be converted to interface using convT2E 703 // so make sure it is an addressable temporary. 704 t = marktemp(order); 705 orderexpr(&n->left, order); 706 if(!isinter(n->left->type)) 707 orderaddrtemp(&n->left, order); 708 order->out = list(order->out, n); 709 cleantemp(t, order); 710 break; 711 712 case ORANGE: 713 // n->right is the expression being ranged over. 714 // order it, and then make a copy if we need one. 715 // We almost always do, to ensure that we don't 716 // see any value changes made during the loop. 717 // Usually the copy is cheap (e.g., array pointer, chan, slice, string are all tiny). 718 // The exception is ranging over an array value (not a slice, not a pointer to array), 719 // which must make a copy to avoid seeing updates made during 720 // the range body. Ranging over an array value is uncommon though. 721 t = marktemp(order); 722 orderexpr(&n->right, order); 723 switch(n->type->etype) { 724 default: 725 fatal("orderstmt range %T", n->type); 726 case TARRAY: 727 if(count(n->list) < 2 || isblank(n->list->next->n)) { 728 // for i := range x will only use x once, to compute len(x). 729 // No need to copy it. 730 break; 731 } 732 // fall through 733 case TCHAN: 734 case TSTRING: 735 // chan, string, slice, array ranges use value multiple times. 736 // make copy. 737 r = n->right; 738 if(r->type->etype == TSTRING && r->type != types[TSTRING]) { 739 r = nod(OCONV, r, N); 740 r->type = types[TSTRING]; 741 typecheck(&r, Erv); 742 } 743 n->right = ordercopyexpr(r, r->type, order, 0); 744 break; 745 case TMAP: 746 // copy the map value in case it is a map literal. 747 // TODO(rsc): Make tmp = literal expressions reuse tmp. 748 // For maps tmp is just one word so it hardly matters. 749 r = n->right; 750 n->right = ordercopyexpr(r, r->type, order, 0); 751 // n->alloc is the temp for the iterator. 752 n->alloc = ordertemp(types[TUINT8], order, 1); 753 break; 754 } 755 for(l=n->list; l; l=l->next) 756 orderexprinplace(&l->n, order); 757 orderblock(&n->nbody); 758 order->out = list(order->out, n); 759 cleantemp(t, order); 760 break; 761 762 case ORETURN: 763 ordercallargs(&n->list, order); 764 order->out = list(order->out, n); 765 break; 766 767 case OSELECT: 768 // Special: clean case temporaries in each block entry. 769 // Select must enter one of its blocks, so there is no 770 // need for a cleaning at the end. 771 t = marktemp(order); 772 for(l=n->list; l; l=l->next) { 773 if(l->n->op != OXCASE) 774 fatal("order select case %O", l->n->op); 775 r = l->n->left; 776 setlineno(l->n); 777 // Append any new body prologue to ninit. 778 // The next loop will insert ninit into nbody. 779 if(l->n->ninit != nil) 780 fatal("order select ninit"); 781 if(r != nil) { 782 switch(r->op) { 783 default: 784 yyerror("unknown op in select %O", r->op); 785 dump("select case", r); 786 break; 787 788 case OSELRECV: 789 case OSELRECV2: 790 // If this is case x := <-ch or case x, y := <-ch, the case has 791 // the ODCL nodes to declare x and y. We want to delay that 792 // declaration (and possible allocation) until inside the case body. 793 // Delete the ODCL nodes here and recreate them inside the body below. 794 if(r->colas) { 795 t = r->ninit; 796 if(t != nil && t->n->op == ODCL && t->n->left == r->left) 797 t = t->next; 798 if(t != nil && t->n->op == ODCL && t->n->left == r->ntest) 799 t = t->next; 800 if(t == nil) 801 r->ninit = nil; 802 } 803 if(r->ninit != nil) { 804 yyerror("ninit on select recv"); 805 dumplist("ninit", r->ninit); 806 } 807 // case x = <-c 808 // case x, ok = <-c 809 // r->left is x, r->ntest is ok, r->right is ORECV, r->right->left is c. 810 // r->left == N means 'case <-c'. 811 // c is always evaluated; x and ok are only evaluated when assigned. 812 orderexpr(&r->right->left, order); 813 814 // Introduce temporary for receive and move actual copy into case body. 815 // avoids problems with target being addressed, as usual. 816 // NOTE: If we wanted to be clever, we could arrange for just one 817 // temporary per distinct type, sharing the temp among all receives 818 // with that temp. Similarly one ok bool could be shared among all 819 // the x,ok receives. Not worth doing until there's a clear need. 820 if(r->left != N && isblank(r->left)) 821 r->left = N; 822 if(r->left != N) { 823 // use channel element type for temporary to avoid conversions, 824 // such as in case interfacevalue = <-intchan. 825 // the conversion happens in the OAS instead. 826 tmp1 = r->left; 827 if(r->colas) { 828 tmp2 = nod(ODCL, tmp1, N); 829 typecheck(&tmp2, Etop); 830 l->n->ninit = list(l->n->ninit, tmp2); 831 } 832 r->left = ordertemp(r->right->left->type->type, order, haspointers(r->right->left->type->type)); 833 tmp2 = nod(OAS, tmp1, r->left); 834 typecheck(&tmp2, Etop); 835 l->n->ninit = list(l->n->ninit, tmp2); 836 } 837 if(r->ntest != N && isblank(r->ntest)) 838 r->ntest = N; 839 if(r->ntest != N) { 840 tmp1 = r->ntest; 841 if(r->colas) { 842 tmp2 = nod(ODCL, tmp1, N); 843 typecheck(&tmp2, Etop); 844 l->n->ninit = list(l->n->ninit, tmp2); 845 } 846 r->ntest = ordertemp(tmp1->type, order, 0); 847 tmp2 = nod(OAS, tmp1, r->ntest); 848 typecheck(&tmp2, Etop); 849 l->n->ninit = list(l->n->ninit, tmp2); 850 } 851 orderblock(&l->n->ninit); 852 break; 853 854 case OSEND: 855 if(r->ninit != nil) { 856 yyerror("ninit on select send"); 857 dumplist("ninit", r->ninit); 858 } 859 // case c <- x 860 // r->left is c, r->right is x, both are always evaluated. 861 orderexpr(&r->left, order); 862 if(!istemp(r->left)) 863 r->left = ordercopyexpr(r->left, r->left->type, order, 0); 864 orderexpr(&r->right, order); 865 if(!istemp(r->right)) 866 r->right = ordercopyexpr(r->right, r->right->type, order, 0); 867 break; 868 } 869 } 870 orderblock(&l->n->nbody); 871 } 872 // Now that we have accumulated all the temporaries, clean them. 873 // Also insert any ninit queued during the previous loop. 874 // (The temporary cleaning must follow that ninit work.) 875 for(l=n->list; l; l=l->next) { 876 cleantempnopop(t, order, &l->n->ninit); 877 l->n->nbody = concat(l->n->ninit, l->n->nbody); 878 l->n->ninit = nil; 879 } 880 order->out = list(order->out, n); 881 poptemp(t, order); 882 break; 883 884 case OSEND: 885 // Special: value being sent is passed as a pointer; make it addressable. 886 t = marktemp(order); 887 orderexpr(&n->left, order); 888 orderexpr(&n->right, order); 889 orderaddrtemp(&n->right, order); 890 order->out = list(order->out, n); 891 cleantemp(t, order); 892 break; 893 894 case OSWITCH: 895 // TODO(rsc): Clean temporaries more aggressively. 896 // Note that because walkswitch will rewrite some of the 897 // switch into a binary search, this is not as easy as it looks. 898 // (If we ran that code here we could invoke orderstmt on 899 // the if-else chain instead.) 900 // For now just clean all the temporaries at the end. 901 // In practice that's fine. 902 t = marktemp(order); 903 orderexpr(&n->ntest, order); 904 for(l=n->list; l; l=l->next) { 905 if(l->n->op != OXCASE) 906 fatal("order switch case %O", l->n->op); 907 orderexprlistinplace(l->n->list, order); 908 orderblock(&l->n->nbody); 909 } 910 order->out = list(order->out, n); 911 cleantemp(t, order); 912 break; 913 } 914 915 lineno = lno; 916 } 917 918 // Orderexprlist orders the expression list l into order. 919 static void 920 orderexprlist(NodeList *l, Order *order) 921 { 922 for(; l; l=l->next) 923 orderexpr(&l->n, order); 924 } 925 926 // Orderexprlist orders the expression list l but saves 927 // the side effects on the individual expression ninit lists. 928 static void 929 orderexprlistinplace(NodeList *l, Order *order) 930 { 931 for(; l; l=l->next) 932 orderexprinplace(&l->n, order); 933 } 934 935 // Orderexpr orders a single expression, appending side 936 // effects to order->out as needed. 937 static void 938 orderexpr(Node **np, Order *order) 939 { 940 Node *n; 941 NodeList *mark, *l; 942 Type *t; 943 int lno; 944 945 n = *np; 946 if(n == N) 947 return; 948 949 lno = setlineno(n); 950 orderinit(n, order); 951 952 switch(n->op) { 953 default: 954 orderexpr(&n->left, order); 955 orderexpr(&n->right, order); 956 orderexprlist(n->list, order); 957 orderexprlist(n->rlist, order); 958 break; 959 960 case OADDSTR: 961 // Addition of strings turns into a function call. 962 // Allocate a temporary to hold the strings. 963 // Fewer than 5 strings use direct runtime helpers. 964 orderexprlist(n->list, order); 965 if(count(n->list) > 5) { 966 t = typ(TARRAY); 967 t->bound = count(n->list); 968 t->type = types[TSTRING]; 969 n->alloc = ordertemp(t, order, 0); 970 } 971 break; 972 973 case OINDEXMAP: 974 // key must be addressable 975 orderexpr(&n->left, order); 976 orderexpr(&n->right, order); 977 978 // For x = m[string(k)] where k is []byte, the allocation of 979 // backing bytes for the string can be avoided by reusing 980 // the []byte backing array. This is a special case that it 981 // would be nice to handle more generally, but because 982 // there are no []byte-keyed maps, this specific case comes 983 // up in important cases in practice. See issue 3512. 984 // Nothing can change the []byte we are not copying before 985 // the map index, because the map access is going to 986 // be forced to happen immediately following this 987 // conversion (by the ordercopyexpr a few lines below). 988 if(n->etype == 0 && n->right->op == OARRAYBYTESTR) 989 n->right->op = OARRAYBYTESTRTMP; 990 991 orderaddrtemp(&n->right, order); 992 if(n->etype == 0) { 993 // use of value (not being assigned); 994 // make copy in temporary. 995 n = ordercopyexpr(n, n->type, order, 0); 996 } 997 break; 998 999 case OCONVIFACE: 1000 // concrete type (not interface) argument must be addressable 1001 // temporary to pass to runtime. 1002 orderexpr(&n->left, order); 1003 if(!isinter(n->left->type)) 1004 orderaddrtemp(&n->left, order); 1005 break; 1006 1007 case OANDAND: 1008 case OOROR: 1009 mark = marktemp(order); 1010 orderexpr(&n->left, order); 1011 // Clean temporaries from first branch at beginning of second. 1012 // Leave them on the stack so that they can be killed in the outer 1013 // context in case the short circuit is taken. 1014 l = nil; 1015 cleantempnopop(mark, order, &l); 1016 n->right->ninit = concat(l, n->right->ninit); 1017 orderexprinplace(&n->right, order); 1018 break; 1019 1020 case OCALLFUNC: 1021 case OCALLMETH: 1022 case OCALLINTER: 1023 case OAPPEND: 1024 case OCOMPLEX: 1025 ordercall(n, order); 1026 n = ordercopyexpr(n, n->type, order, 0); 1027 break; 1028 1029 case OCLOSURE: 1030 if(n->noescape && n->cvars != nil) 1031 n->alloc = ordertemp(types[TUINT8], order, 0); // walk will fill in correct type 1032 break; 1033 1034 case OARRAYLIT: 1035 case OCALLPART: 1036 orderexpr(&n->left, order); 1037 orderexpr(&n->right, order); 1038 orderexprlist(n->list, order); 1039 orderexprlist(n->rlist, order); 1040 if(n->noescape) 1041 n->alloc = ordertemp(types[TUINT8], order, 0); // walk will fill in correct type 1042 break; 1043 1044 case ODDDARG: 1045 if(n->noescape) { 1046 // The ddd argument does not live beyond the call it is created for. 1047 // Allocate a temporary that will be cleaned up when this statement 1048 // completes. We could be more aggressive and try to arrange for it 1049 // to be cleaned up when the call completes. 1050 n->alloc = ordertemp(n->type->type, order, 0); 1051 } 1052 break; 1053 1054 case ORECV: 1055 orderexpr(&n->left, order); 1056 n = ordercopyexpr(n, n->type, order, 1); 1057 break; 1058 } 1059 1060 lineno = lno; 1061 1062 *np = n; 1063 }