github.com/yanyiwu/go@v0.0.0-20150106053140-03d6637dbb7f/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 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 // 442 // Ordermapassign also inserts these temporaries if needed for 443 // calling writebarrierfat with a pointer to n->right. 444 static void 445 ordermapassign(Node *n, Order *order) 446 { 447 Node *m, *a; 448 NodeList *l; 449 NodeList *post; 450 451 switch(n->op) { 452 default: 453 fatal("ordermapassign %O", n->op); 454 455 case OAS: 456 order->out = list(order->out, n); 457 // We call writebarrierfat only for values > 4 pointers long. See walk.c. 458 if((n->left->op == OINDEXMAP || (needwritebarrier(n->left, n->right) && n->left->type->width > 4*widthptr)) && !isaddrokay(n->right)) { 459 m = n->left; 460 n->left = ordertemp(m->type, order, 0); 461 a = nod(OAS, m, n->left); 462 typecheck(&a, Etop); 463 order->out = list(order->out, a); 464 } 465 break; 466 467 case OAS2: 468 case OAS2DOTTYPE: 469 case OAS2MAPR: 470 case OAS2FUNC: 471 post = nil; 472 for(l=n->list; l != nil; l=l->next) { 473 if(l->n->op == OINDEXMAP) { 474 m = l->n; 475 if(!istemp(m->left)) 476 m->left = ordercopyexpr(m->left, m->left->type, order, 0); 477 if(!istemp(m->right)) 478 m->right = ordercopyexpr(m->right, m->right->type, order, 0); 479 l->n = ordertemp(m->type, order, 0); 480 a = nod(OAS, m, l->n); 481 typecheck(&a, Etop); 482 post = list(post, a); 483 } 484 } 485 order->out = list(order->out, n); 486 order->out = concat(order->out, post); 487 break; 488 } 489 } 490 491 // Orderstmt orders the statement n, appending to order->out. 492 // Temporaries created during the statement are cleaned 493 // up using VARKILL instructions as possible. 494 static void 495 orderstmt(Node *n, Order *order) 496 { 497 int lno; 498 NodeList *l, *t, *t1; 499 Node *r, *tmp1, *tmp2, **np; 500 Type *ch, *typ; 501 502 if(n == N) 503 return; 504 505 lno = setlineno(n); 506 507 orderinit(n, order); 508 509 switch(n->op) { 510 default: 511 fatal("orderstmt %O", n->op); 512 513 case OVARKILL: 514 order->out = list(order->out, n); 515 break; 516 517 case OAS: 518 case OAS2: 519 case OCLOSE: 520 case OCOPY: 521 case OPRINT: 522 case OPRINTN: 523 case ORECOVER: 524 case ORECV: 525 t = marktemp(order); 526 orderexpr(&n->left, order); 527 orderexpr(&n->right, order); 528 orderexprlist(n->list, order); 529 orderexprlist(n->rlist, order); 530 switch(n->op) { 531 case OAS: 532 case OAS2: 533 case OAS2DOTTYPE: 534 ordermapassign(n, order); 535 break; 536 default: 537 order->out = list(order->out, n); 538 break; 539 } 540 cleantemp(t, order); 541 break; 542 543 case OASOP: 544 // Special: rewrite l op= r into l = l op r. 545 // This simplies quite a few operations; 546 // most important is that it lets us separate 547 // out map read from map write when l is 548 // a map index expression. 549 t = marktemp(order); 550 orderexpr(&n->left, order); 551 n->left = ordersafeexpr(n->left, order); 552 tmp1 = treecopy(n->left); 553 if(tmp1->op == OINDEXMAP) 554 tmp1->etype = 0; // now an rvalue not an lvalue 555 tmp1 = ordercopyexpr(tmp1, n->left->type, order, 0); 556 n->right = nod(n->etype, tmp1, n->right); 557 typecheck(&n->right, Erv); 558 orderexpr(&n->right, order); 559 n->etype = 0; 560 n->op = OAS; 561 ordermapassign(n, order); 562 cleantemp(t, order); 563 break; 564 565 case OAS2MAPR: 566 // Special: make sure key is addressable, 567 // and make sure OINDEXMAP is not copied out. 568 t = marktemp(order); 569 orderexprlist(n->list, order); 570 r = n->rlist->n; 571 orderexpr(&r->left, order); 572 orderexpr(&r->right, order); 573 // See case OINDEXMAP below. 574 if(r->right->op == OARRAYBYTESTR) 575 r->right->op = OARRAYBYTESTRTMP; 576 orderaddrtemp(&r->right, order); 577 ordermapassign(n, order); 578 cleantemp(t, order); 579 break; 580 581 case OAS2FUNC: 582 // Special: avoid copy of func call n->rlist->n. 583 t = marktemp(order); 584 orderexprlist(n->list, order); 585 ordercall(n->rlist->n, order); 586 ordermapassign(n, order); 587 cleantemp(t, order); 588 break; 589 590 case OAS2DOTTYPE: 591 // Special: use temporary variables to hold result, 592 // so that assertI2Tetc can take address of temporary. 593 // No temporary for blank assignment. 594 t = marktemp(order); 595 orderexprlist(n->list, order); 596 orderexpr(&n->rlist->n->left, order); // i in i.(T) 597 if(isblank(n->list->n)) 598 order->out = list(order->out, n); 599 else { 600 typ = n->rlist->n->type; 601 tmp1 = ordertemp(typ, order, haspointers(typ)); 602 order->out = list(order->out, n); 603 r = nod(OAS, n->list->n, tmp1); 604 typecheck(&r, Etop); 605 ordermapassign(r, order); 606 n->list = list(list1(tmp1), n->list->next->n); 607 } 608 cleantemp(t, order); 609 break; 610 611 case OAS2RECV: 612 // Special: use temporary variables to hold result, 613 // so that chanrecv can take address of temporary. 614 t = marktemp(order); 615 orderexprlist(n->list, order); 616 orderexpr(&n->rlist->n->left, order); // arg to recv 617 ch = n->rlist->n->left->type; 618 tmp1 = ordertemp(ch->type, order, haspointers(ch->type)); 619 if(!isblank(n->list->next->n)) 620 tmp2 = ordertemp(n->list->next->n->type, order, 0); 621 else 622 tmp2 = ordertemp(types[TBOOL], order, 0); 623 order->out = list(order->out, n); 624 r = nod(OAS, n->list->n, tmp1); 625 typecheck(&r, Etop); 626 ordermapassign(r, order); 627 r = nod(OAS, n->list->next->n, tmp2); 628 typecheck(&r, Etop); 629 ordermapassign(r, order); 630 n->list = list(list1(tmp1), tmp2); 631 cleantemp(t, order); 632 break; 633 634 case OBLOCK: 635 case OEMPTY: 636 // Special: does not save n onto out. 637 orderstmtlist(n->list, order); 638 break; 639 640 case OBREAK: 641 case OCONTINUE: 642 case ODCL: 643 case ODCLCONST: 644 case ODCLTYPE: 645 case OFALL: 646 case OXFALL: 647 case OGOTO: 648 case OLABEL: 649 case ORETJMP: 650 // Special: n->left is not an expression; save as is. 651 order->out = list(order->out, n); 652 break; 653 654 case OCALLFUNC: 655 case OCALLINTER: 656 case OCALLMETH: 657 // Special: handle call arguments. 658 t = marktemp(order); 659 ordercall(n, order); 660 order->out = list(order->out, n); 661 cleantemp(t, order); 662 break; 663 664 case ODEFER: 665 case OPROC: 666 // Special: order arguments to inner call but not call itself. 667 t = marktemp(order); 668 switch(n->left->op) { 669 case ODELETE: 670 // Delete will take the address of the key. 671 // Copy key into new temp and do not clean it 672 // (it persists beyond the statement). 673 orderexprlist(n->left->list, order); 674 t1 = marktemp(order); 675 np = &n->left->list->next->n; // map key 676 *np = ordercopyexpr(*np, (*np)->type, order, 0); 677 poptemp(t1, order); 678 break; 679 default: 680 ordercall(n->left, order); 681 break; 682 } 683 order->out = list(order->out, n); 684 cleantemp(t, order); 685 break; 686 687 case ODELETE: 688 t = marktemp(order); 689 orderexpr(&n->list->n, order); 690 orderexpr(&n->list->next->n, order); 691 orderaddrtemp(&n->list->next->n, order); // map key 692 order->out = list(order->out, n); 693 cleantemp(t, order); 694 break; 695 696 case OFOR: 697 // Clean temporaries from condition evaluation at 698 // beginning of loop body and after for statement. 699 t = marktemp(order); 700 orderexprinplace(&n->ntest, order); 701 l = nil; 702 cleantempnopop(t, order, &l); 703 n->nbody = concat(l, n->nbody); 704 orderblock(&n->nbody); 705 orderstmtinplace(&n->nincr); 706 order->out = list(order->out, n); 707 cleantemp(t, order); 708 break; 709 710 case OIF: 711 // Clean temporaries from condition at 712 // beginning of both branches. 713 t = marktemp(order); 714 orderexprinplace(&n->ntest, order); 715 l = nil; 716 cleantempnopop(t, order, &l); 717 n->nbody = concat(l, n->nbody); 718 l = nil; 719 cleantempnopop(t, order, &l); 720 n->nelse = concat(l, n->nelse); 721 poptemp(t, order); 722 orderblock(&n->nbody); 723 orderblock(&n->nelse); 724 order->out = list(order->out, n); 725 break; 726 727 case OPANIC: 728 // Special: argument will be converted to interface using convT2E 729 // so make sure it is an addressable temporary. 730 t = marktemp(order); 731 orderexpr(&n->left, order); 732 if(!isinter(n->left->type)) 733 orderaddrtemp(&n->left, order); 734 order->out = list(order->out, n); 735 cleantemp(t, order); 736 break; 737 738 case ORANGE: 739 // n->right is the expression being ranged over. 740 // order it, and then make a copy if we need one. 741 // We almost always do, to ensure that we don't 742 // see any value changes made during the loop. 743 // Usually the copy is cheap (e.g., array pointer, chan, slice, string are all tiny). 744 // The exception is ranging over an array value (not a slice, not a pointer to array), 745 // which must make a copy to avoid seeing updates made during 746 // the range body. Ranging over an array value is uncommon though. 747 t = marktemp(order); 748 orderexpr(&n->right, order); 749 switch(n->type->etype) { 750 default: 751 fatal("orderstmt range %T", n->type); 752 case TARRAY: 753 if(count(n->list) < 2 || isblank(n->list->next->n)) { 754 // for i := range x will only use x once, to compute len(x). 755 // No need to copy it. 756 break; 757 } 758 // fall through 759 case TCHAN: 760 case TSTRING: 761 // chan, string, slice, array ranges use value multiple times. 762 // make copy. 763 r = n->right; 764 if(r->type->etype == TSTRING && r->type != types[TSTRING]) { 765 r = nod(OCONV, r, N); 766 r->type = types[TSTRING]; 767 typecheck(&r, Erv); 768 } 769 n->right = ordercopyexpr(r, r->type, order, 0); 770 break; 771 case TMAP: 772 // copy the map value in case it is a map literal. 773 // TODO(rsc): Make tmp = literal expressions reuse tmp. 774 // For maps tmp is just one word so it hardly matters. 775 r = n->right; 776 n->right = ordercopyexpr(r, r->type, order, 0); 777 // n->alloc is the temp for the iterator. 778 n->alloc = ordertemp(types[TUINT8], order, 1); 779 break; 780 } 781 for(l=n->list; l; l=l->next) 782 orderexprinplace(&l->n, order); 783 orderblock(&n->nbody); 784 order->out = list(order->out, n); 785 cleantemp(t, order); 786 break; 787 788 case ORETURN: 789 ordercallargs(&n->list, order); 790 order->out = list(order->out, n); 791 break; 792 793 case OSELECT: 794 // Special: clean case temporaries in each block entry. 795 // Select must enter one of its blocks, so there is no 796 // need for a cleaning at the end. 797 // Doubly special: evaluation order for select is stricter 798 // than ordinary expressions. Even something like p.c 799 // has to be hoisted into a temporary, so that it cannot be 800 // reordered after the channel evaluation for a different 801 // case (if p were nil, then the timing of the fault would 802 // give this away). 803 t = marktemp(order); 804 for(l=n->list; l; l=l->next) { 805 if(l->n->op != OXCASE) 806 fatal("order select case %O", l->n->op); 807 r = l->n->left; 808 setlineno(l->n); 809 // Append any new body prologue to ninit. 810 // The next loop will insert ninit into nbody. 811 if(l->n->ninit != nil) 812 fatal("order select ninit"); 813 if(r != nil) { 814 switch(r->op) { 815 default: 816 yyerror("unknown op in select %O", r->op); 817 dump("select case", r); 818 break; 819 820 case OSELRECV: 821 case OSELRECV2: 822 // If this is case x := <-ch or case x, y := <-ch, the case has 823 // the ODCL nodes to declare x and y. We want to delay that 824 // declaration (and possible allocation) until inside the case body. 825 // Delete the ODCL nodes here and recreate them inside the body below. 826 if(r->colas) { 827 t = r->ninit; 828 if(t != nil && t->n->op == ODCL && t->n->left == r->left) 829 t = t->next; 830 if(t != nil && t->n->op == ODCL && t->n->left == r->ntest) 831 t = t->next; 832 if(t == nil) 833 r->ninit = nil; 834 } 835 if(r->ninit != nil) { 836 yyerror("ninit on select recv"); 837 dumplist("ninit", r->ninit); 838 } 839 // case x = <-c 840 // case x, ok = <-c 841 // r->left is x, r->ntest is ok, r->right is ORECV, r->right->left is c. 842 // r->left == N means 'case <-c'. 843 // c is always evaluated; x and ok are only evaluated when assigned. 844 orderexpr(&r->right->left, order); 845 if(r->right->left->op != ONAME) 846 r->right->left = ordercopyexpr(r->right->left, r->right->left->type, order, 0); 847 848 // Introduce temporary for receive and move actual copy into case body. 849 // avoids problems with target being addressed, as usual. 850 // NOTE: If we wanted to be clever, we could arrange for just one 851 // temporary per distinct type, sharing the temp among all receives 852 // with that temp. Similarly one ok bool could be shared among all 853 // the x,ok receives. Not worth doing until there's a clear need. 854 if(r->left != N && isblank(r->left)) 855 r->left = N; 856 if(r->left != N) { 857 // use channel element type for temporary to avoid conversions, 858 // such as in case interfacevalue = <-intchan. 859 // the conversion happens in the OAS instead. 860 tmp1 = r->left; 861 if(r->colas) { 862 tmp2 = nod(ODCL, tmp1, N); 863 typecheck(&tmp2, Etop); 864 l->n->ninit = list(l->n->ninit, tmp2); 865 } 866 r->left = ordertemp(r->right->left->type->type, order, haspointers(r->right->left->type->type)); 867 tmp2 = nod(OAS, tmp1, r->left); 868 typecheck(&tmp2, Etop); 869 l->n->ninit = list(l->n->ninit, tmp2); 870 } 871 if(r->ntest != N && isblank(r->ntest)) 872 r->ntest = N; 873 if(r->ntest != N) { 874 tmp1 = r->ntest; 875 if(r->colas) { 876 tmp2 = nod(ODCL, tmp1, N); 877 typecheck(&tmp2, Etop); 878 l->n->ninit = list(l->n->ninit, tmp2); 879 } 880 r->ntest = ordertemp(tmp1->type, order, 0); 881 tmp2 = nod(OAS, tmp1, r->ntest); 882 typecheck(&tmp2, Etop); 883 l->n->ninit = list(l->n->ninit, tmp2); 884 } 885 orderblock(&l->n->ninit); 886 break; 887 888 case OSEND: 889 if(r->ninit != nil) { 890 yyerror("ninit on select send"); 891 dumplist("ninit", r->ninit); 892 } 893 // case c <- x 894 // r->left is c, r->right is x, both are always evaluated. 895 orderexpr(&r->left, order); 896 if(!istemp(r->left)) 897 r->left = ordercopyexpr(r->left, r->left->type, order, 0); 898 orderexpr(&r->right, order); 899 if(!istemp(r->right)) 900 r->right = ordercopyexpr(r->right, r->right->type, order, 0); 901 break; 902 } 903 } 904 orderblock(&l->n->nbody); 905 } 906 // Now that we have accumulated all the temporaries, clean them. 907 // Also insert any ninit queued during the previous loop. 908 // (The temporary cleaning must follow that ninit work.) 909 for(l=n->list; l; l=l->next) { 910 cleantempnopop(t, order, &l->n->ninit); 911 l->n->nbody = concat(l->n->ninit, l->n->nbody); 912 l->n->ninit = nil; 913 } 914 order->out = list(order->out, n); 915 poptemp(t, order); 916 break; 917 918 case OSEND: 919 // Special: value being sent is passed as a pointer; make it addressable. 920 t = marktemp(order); 921 orderexpr(&n->left, order); 922 orderexpr(&n->right, order); 923 orderaddrtemp(&n->right, order); 924 order->out = list(order->out, n); 925 cleantemp(t, order); 926 break; 927 928 case OSWITCH: 929 // TODO(rsc): Clean temporaries more aggressively. 930 // Note that because walkswitch will rewrite some of the 931 // switch into a binary search, this is not as easy as it looks. 932 // (If we ran that code here we could invoke orderstmt on 933 // the if-else chain instead.) 934 // For now just clean all the temporaries at the end. 935 // In practice that's fine. 936 t = marktemp(order); 937 orderexpr(&n->ntest, order); 938 for(l=n->list; l; l=l->next) { 939 if(l->n->op != OXCASE) 940 fatal("order switch case %O", l->n->op); 941 orderexprlistinplace(l->n->list, order); 942 orderblock(&l->n->nbody); 943 } 944 order->out = list(order->out, n); 945 cleantemp(t, order); 946 break; 947 } 948 949 lineno = lno; 950 } 951 952 // Orderexprlist orders the expression list l into order. 953 static void 954 orderexprlist(NodeList *l, Order *order) 955 { 956 for(; l; l=l->next) 957 orderexpr(&l->n, order); 958 } 959 960 // Orderexprlist orders the expression list l but saves 961 // the side effects on the individual expression ninit lists. 962 static void 963 orderexprlistinplace(NodeList *l, Order *order) 964 { 965 for(; l; l=l->next) 966 orderexprinplace(&l->n, order); 967 } 968 969 // Orderexpr orders a single expression, appending side 970 // effects to order->out as needed. 971 static void 972 orderexpr(Node **np, Order *order) 973 { 974 Node *n; 975 NodeList *mark, *l; 976 Type *t; 977 int lno; 978 979 n = *np; 980 if(n == N) 981 return; 982 983 lno = setlineno(n); 984 orderinit(n, order); 985 986 switch(n->op) { 987 default: 988 orderexpr(&n->left, order); 989 orderexpr(&n->right, order); 990 orderexprlist(n->list, order); 991 orderexprlist(n->rlist, order); 992 break; 993 994 case OADDSTR: 995 // Addition of strings turns into a function call. 996 // Allocate a temporary to hold the strings. 997 // Fewer than 5 strings use direct runtime helpers. 998 orderexprlist(n->list, order); 999 if(count(n->list) > 5) { 1000 t = typ(TARRAY); 1001 t->bound = count(n->list); 1002 t->type = types[TSTRING]; 1003 n->alloc = ordertemp(t, order, 0); 1004 } 1005 break; 1006 1007 case OINDEXMAP: 1008 // key must be addressable 1009 orderexpr(&n->left, order); 1010 orderexpr(&n->right, order); 1011 1012 // For x = m[string(k)] where k is []byte, the allocation of 1013 // backing bytes for the string can be avoided by reusing 1014 // the []byte backing array. This is a special case that it 1015 // would be nice to handle more generally, but because 1016 // there are no []byte-keyed maps, this specific case comes 1017 // up in important cases in practice. See issue 3512. 1018 // Nothing can change the []byte we are not copying before 1019 // the map index, because the map access is going to 1020 // be forced to happen immediately following this 1021 // conversion (by the ordercopyexpr a few lines below). 1022 if(n->etype == 0 && n->right->op == OARRAYBYTESTR) 1023 n->right->op = OARRAYBYTESTRTMP; 1024 1025 orderaddrtemp(&n->right, order); 1026 if(n->etype == 0) { 1027 // use of value (not being assigned); 1028 // make copy in temporary. 1029 n = ordercopyexpr(n, n->type, order, 0); 1030 } 1031 break; 1032 1033 case OCONVIFACE: 1034 // concrete type (not interface) argument must be addressable 1035 // temporary to pass to runtime. 1036 orderexpr(&n->left, order); 1037 if(!isinter(n->left->type)) 1038 orderaddrtemp(&n->left, order); 1039 break; 1040 1041 case OANDAND: 1042 case OOROR: 1043 mark = marktemp(order); 1044 orderexpr(&n->left, order); 1045 // Clean temporaries from first branch at beginning of second. 1046 // Leave them on the stack so that they can be killed in the outer 1047 // context in case the short circuit is taken. 1048 l = nil; 1049 cleantempnopop(mark, order, &l); 1050 n->right->ninit = concat(l, n->right->ninit); 1051 orderexprinplace(&n->right, order); 1052 break; 1053 1054 case OAPPEND: 1055 case OCALLFUNC: 1056 case OCALLINTER: 1057 case OCALLMETH: 1058 case OCAP: 1059 case OCOMPLEX: 1060 case OCOPY: 1061 case OIMAG: 1062 case OLEN: 1063 case OMAKECHAN: 1064 case OMAKEMAP: 1065 case OMAKESLICE: 1066 case ONEW: 1067 case OREAL: 1068 case ORECOVER: 1069 ordercall(n, order); 1070 n = ordercopyexpr(n, n->type, order, 0); 1071 break; 1072 1073 case OCLOSURE: 1074 if(n->noescape && n->cvars != nil) 1075 n->alloc = ordertemp(types[TUINT8], order, 0); // walk will fill in correct type 1076 break; 1077 1078 case OARRAYLIT: 1079 case OCALLPART: 1080 orderexpr(&n->left, order); 1081 orderexpr(&n->right, order); 1082 orderexprlist(n->list, order); 1083 orderexprlist(n->rlist, order); 1084 if(n->noescape) 1085 n->alloc = ordertemp(types[TUINT8], order, 0); // walk will fill in correct type 1086 break; 1087 1088 case ODDDARG: 1089 if(n->noescape) { 1090 // The ddd argument does not live beyond the call it is created for. 1091 // Allocate a temporary that will be cleaned up when this statement 1092 // completes. We could be more aggressive and try to arrange for it 1093 // to be cleaned up when the call completes. 1094 n->alloc = ordertemp(n->type->type, order, 0); 1095 } 1096 break; 1097 1098 case ORECV: 1099 case ODOTTYPE: 1100 orderexpr(&n->left, order); 1101 n = ordercopyexpr(n, n->type, order, 1); 1102 break; 1103 1104 case OEQ: 1105 case ONE: 1106 orderexpr(&n->left, order); 1107 orderexpr(&n->right, order); 1108 t = n->left->type; 1109 if(t->etype == TSTRUCT || isfixedarray(t)) { 1110 // for complex comparisons, we need both args to be 1111 // addressable so we can pass them to the runtime. 1112 orderaddrtemp(&n->left, order); 1113 orderaddrtemp(&n->right, order); 1114 } 1115 break; 1116 } 1117 1118 lineno = lno; 1119 1120 *np = n; 1121 }