1 // Copyright 2013 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 // Garbage collector liveness bitmap generation. 6 7 // The command line flag -live causes this code to print debug information. 8 // The levels are: 9 // 10 // -live (aka -live=1): print liveness lists as code warnings at safe points 11 // -live=2: print an assembly listing with liveness annotations 12 // -live=3: print information during each computation phase (much chattier) 13 // 14 // Each level includes the earlier output as well. 15 16 package gc 17 18 import ( 19 "cmd/internal/obj" 20 "fmt" 21 "sort" 22 ) 23 24 const ( 25 UNVISITED = 0 26 VISITED = 1 27 ) 28 29 // An ordinary basic block. 30 // 31 // Instructions are threaded together in a doubly-linked list. To iterate in 32 // program order follow the link pointer from the first node and stop after the 33 // last node has been visited 34 // 35 // for(p = bb->first;; p = p->link) { 36 // ... 37 // if(p == bb->last) 38 // break; 39 // } 40 // 41 // To iterate in reverse program order by following the opt pointer from the 42 // last node 43 // 44 // for(p = bb->last; p != nil; p = p->opt) { 45 // ... 46 // } 47 type BasicBlock struct { 48 pred []*BasicBlock // predecessors; if none, probably start of CFG 49 succ []*BasicBlock // successors; if none, probably ends in return statement 50 first *obj.Prog // first instruction in block 51 last *obj.Prog // last instruction in block 52 rpo int // reverse post-order number (also index in cfg) 53 mark int // mark bit for traversals 54 lastbitmapindex int // for livenessepilogue 55 56 // Summary sets of block effects. 57 58 // Computed during livenessprologue using only the content of 59 // individual blocks: 60 // 61 // uevar: upward exposed variables (used before set in block) 62 // varkill: killed variables (set in block) 63 // avarinit: addrtaken variables set or used (proof of initialization) 64 uevar Bvec 65 varkill Bvec 66 avarinit Bvec 67 68 // Computed during livenesssolve using control flow information: 69 // 70 // livein: variables live at block entry 71 // liveout: variables live at block exit 72 // avarinitany: addrtaken variables possibly initialized at block exit 73 // (initialized in block or at exit from any predecessor block) 74 // avarinitall: addrtaken variables certainly initialized at block exit 75 // (initialized in block or at exit from all predecessor blocks) 76 livein Bvec 77 liveout Bvec 78 avarinitany Bvec 79 avarinitall Bvec 80 } 81 82 // A collection of global state used by liveness analysis. 83 type Liveness struct { 84 fn *Node 85 ptxt *obj.Prog 86 vars []*Node 87 cfg []*BasicBlock 88 89 // An array with a bit vector for each safe point tracking live pointers 90 // in the arguments and locals area, indexed by bb.rpo. 91 argslivepointers []Bvec 92 livepointers []Bvec 93 } 94 95 func xmalloc(size uint32) interface{} { 96 result := (interface{})(make([]byte, size)) 97 if result == nil { 98 Fatal("malloc failed") 99 } 100 return result 101 } 102 103 // Constructs a new basic block containing a single instruction. 104 func newblock(prog *obj.Prog) *BasicBlock { 105 if prog == nil { 106 Fatal("newblock: prog cannot be nil") 107 } 108 result := new(BasicBlock) 109 result.rpo = -1 110 result.mark = UNVISITED 111 result.first = prog 112 result.last = prog 113 result.pred = make([]*BasicBlock, 0, 2) 114 result.succ = make([]*BasicBlock, 0, 2) 115 return result 116 } 117 118 // Frees a basic block and all of its leaf data structures. 119 func freeblock(bb *BasicBlock) { 120 if bb == nil { 121 Fatal("freeblock: cannot free nil") 122 } 123 } 124 125 // Adds an edge between two basic blocks by making from a predecessor of to and 126 // to a successor of from. 127 func addedge(from *BasicBlock, to *BasicBlock) { 128 if from == nil { 129 Fatal("addedge: from is nil") 130 } 131 if to == nil { 132 Fatal("addedge: to is nil") 133 } 134 from.succ = append(from.succ, to) 135 to.pred = append(to.pred, from) 136 } 137 138 // Inserts prev before curr in the instruction 139 // stream. Any control flow, such as branches or fall throughs, that target the 140 // existing instruction are adjusted to target the new instruction. 141 func splicebefore(lv *Liveness, bb *BasicBlock, prev *obj.Prog, curr *obj.Prog) { 142 // There may be other instructions pointing at curr, 143 // and we want them to now point at prev. Instead of 144 // trying to find all such instructions, swap the contents 145 // so that the problem becomes inserting next after curr. 146 // The "opt" field is the backward link in the linked list. 147 148 // Overwrite curr's data with prev, but keep the list links. 149 tmp := *curr 150 151 *curr = *prev 152 curr.Opt = tmp.Opt 153 curr.Link = tmp.Link 154 155 // Overwrite prev (now next) with curr's old data. 156 next := prev 157 158 *next = tmp 159 next.Opt = nil 160 next.Link = nil 161 162 // Now insert next after curr. 163 next.Link = curr.Link 164 165 next.Opt = curr 166 curr.Link = next 167 if next.Link != nil && next.Link.Opt == curr { 168 next.Link.Opt = next 169 } 170 171 if bb.last == curr { 172 bb.last = next 173 } 174 } 175 176 // A pretty printer for basic blocks. 177 func printblock(bb *BasicBlock) { 178 fmt.Printf("basic block %d\n", bb.rpo) 179 fmt.Printf("\tpred:") 180 for _, pred := range bb.pred { 181 fmt.Printf(" %d", pred.rpo) 182 } 183 fmt.Printf("\n") 184 fmt.Printf("\tsucc:") 185 for _, succ := range bb.succ { 186 fmt.Printf(" %d", succ.rpo) 187 } 188 fmt.Printf("\n") 189 fmt.Printf("\tprog:\n") 190 for prog := bb.first; ; prog = prog.Link { 191 fmt.Printf("\t\t%v\n", prog) 192 if prog == bb.last { 193 break 194 } 195 } 196 } 197 198 // Iterates over a basic block applying a callback to each instruction. There 199 // are two criteria for termination. If the end of basic block is reached a 200 // value of zero is returned. If the callback returns a non-zero value, the 201 // iteration is stopped and the value of the callback is returned. 202 func blockany(bb *BasicBlock, f func(*obj.Prog) bool) bool { 203 for p := bb.last; p != nil; p = p.Opt.(*obj.Prog) { 204 if f(p) { 205 return true 206 } 207 } 208 return false 209 } 210 211 // Collects and returns and array of Node*s for functions arguments and local 212 // variables. 213 func getvariables(fn *Node) []*Node { 214 result := make([]*Node, 0, 0) 215 for ll := fn.Func.Dcl; ll != nil; ll = ll.Next { 216 if ll.N.Op == ONAME { 217 // In order for GODEBUG=gcdead=1 to work, each bitmap needs 218 // to contain information about all variables covered by the bitmap. 219 // For local variables, the bitmap only covers the stkptrsize 220 // bytes in the frame where variables containing pointers live. 221 // For arguments and results, the bitmap covers all variables, 222 // so we must include all the variables, even the ones without 223 // pointers. 224 // 225 // The Node.opt field is available for use by optimization passes. 226 // We use it to hold the index of the node in the variables array, plus 1 227 // (so that 0 means the Node is not in the variables array). 228 // Each pass should clear opt when done, but you never know, 229 // so clear them all ourselves too. 230 // The Node.curfn field is supposed to be set to the current function 231 // already, but for some compiler-introduced names it seems not to be, 232 // so fix that here. 233 // Later, when we want to find the index of a node in the variables list, 234 // we will check that n->curfn == curfn and n->opt > 0. Then n->opt - 1 235 // is the index in the variables list. 236 ll.N.SetOpt(nil) 237 238 // The compiler doesn't emit initializations for zero-width parameters or results. 239 if ll.N.Type.Width == 0 { 240 continue 241 } 242 243 ll.N.Name.Curfn = Curfn 244 switch ll.N.Class { 245 case PAUTO: 246 if haspointers(ll.N.Type) { 247 ll.N.SetOpt(int32(len(result))) 248 result = append(result, ll.N) 249 } 250 251 case PPARAM, PPARAMOUT: 252 ll.N.SetOpt(int32(len(result))) 253 result = append(result, ll.N) 254 } 255 } 256 } 257 258 return result 259 } 260 261 // A pretty printer for control flow graphs. Takes an array of BasicBlock*s. 262 func printcfg(cfg []*BasicBlock) { 263 for _, bb := range cfg { 264 printblock(bb) 265 } 266 } 267 268 // Assigns a reverse post order number to each connected basic block using the 269 // standard algorithm. Unconnected blocks will not be affected. 270 func reversepostorder(root *BasicBlock, rpo *int32) { 271 root.mark = VISITED 272 for _, bb := range root.succ { 273 if bb.mark == UNVISITED { 274 reversepostorder(bb, rpo) 275 } 276 } 277 *rpo -= 1 278 root.rpo = int(*rpo) 279 } 280 281 // Comparison predicate used for sorting basic blocks by their rpo in ascending 282 // order. 283 type blockrpocmp []*BasicBlock 284 285 func (x blockrpocmp) Len() int { return len(x) } 286 func (x blockrpocmp) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 287 func (x blockrpocmp) Less(i, j int) bool { return x[i].rpo < x[j].rpo } 288 289 // A pattern matcher for call instructions. Returns true when the instruction 290 // is a call to a specific package qualified function name. 291 func iscall(prog *obj.Prog, name *obj.LSym) bool { 292 if prog == nil { 293 Fatal("iscall: prog is nil") 294 } 295 if name == nil { 296 Fatal("iscall: function name is nil") 297 } 298 if prog.As != obj.ACALL { 299 return false 300 } 301 return name == prog.To.Sym 302 } 303 304 // Returns true for instructions that call a runtime function implementing a 305 // select communication clause. 306 307 var selectNames [4]*obj.LSym 308 309 func isselectcommcasecall(prog *obj.Prog) bool { 310 if selectNames[0] == nil { 311 selectNames[0] = Linksym(Pkglookup("selectsend", Runtimepkg)) 312 selectNames[1] = Linksym(Pkglookup("selectrecv", Runtimepkg)) 313 selectNames[2] = Linksym(Pkglookup("selectrecv2", Runtimepkg)) 314 selectNames[3] = Linksym(Pkglookup("selectdefault", Runtimepkg)) 315 } 316 317 for _, name := range selectNames { 318 if iscall(prog, name) { 319 return true 320 } 321 } 322 return false 323 } 324 325 // Returns true for call instructions that target runtimenewselect. 326 327 var isnewselect_sym *obj.LSym 328 329 func isnewselect(prog *obj.Prog) bool { 330 if isnewselect_sym == nil { 331 isnewselect_sym = Linksym(Pkglookup("newselect", Runtimepkg)) 332 } 333 return iscall(prog, isnewselect_sym) 334 } 335 336 // Returns true for call instructions that target runtimeselectgo. 337 338 var isselectgocall_sym *obj.LSym 339 340 func isselectgocall(prog *obj.Prog) bool { 341 if isselectgocall_sym == nil { 342 isselectgocall_sym = Linksym(Pkglookup("selectgo", Runtimepkg)) 343 } 344 return iscall(prog, isselectgocall_sym) 345 } 346 347 var isdeferreturn_sym *obj.LSym 348 349 func isdeferreturn(prog *obj.Prog) bool { 350 if isdeferreturn_sym == nil { 351 isdeferreturn_sym = Linksym(Pkglookup("deferreturn", Runtimepkg)) 352 } 353 return iscall(prog, isdeferreturn_sym) 354 } 355 356 // Walk backwards from a runtimeselectgo call up to its immediately dominating 357 // runtimenewselect call. Any successor nodes of communication clause nodes 358 // are implicit successors of the runtimeselectgo call node. The goal of this 359 // analysis is to add these missing edges to complete the control flow graph. 360 func addselectgosucc(selectgo *BasicBlock) { 361 var succ *BasicBlock 362 363 pred := selectgo 364 for { 365 if len(pred.pred) == 0 { 366 Fatal("selectgo does not have a newselect") 367 } 368 pred = pred.pred[0] 369 if blockany(pred, isselectcommcasecall) { 370 // A select comm case block should have exactly one 371 // successor. 372 if len(pred.succ) != 1 { 373 Fatal("select comm case has too many successors") 374 } 375 succ = pred.succ[0] 376 377 // Its successor should have exactly two successors. 378 // The drop through should flow to the selectgo block 379 // and the branch should lead to the select case 380 // statements block. 381 if len(succ.succ) != 2 { 382 Fatal("select comm case successor has too many successors") 383 } 384 385 // Add the block as a successor of the selectgo block. 386 addedge(selectgo, succ) 387 } 388 389 if blockany(pred, isnewselect) { 390 // Reached the matching newselect. 391 break 392 } 393 } 394 } 395 396 // The entry point for the missing selectgo control flow algorithm. Takes an 397 // array of BasicBlock*s containing selectgo calls. 398 func fixselectgo(selectgo []*BasicBlock) { 399 for _, bb := range selectgo { 400 addselectgosucc(bb) 401 } 402 } 403 404 // Constructs a control flow graph from a sequence of instructions. This 405 // procedure is complicated by various sources of implicit control flow that are 406 // not accounted for using the standard cfg construction algorithm. Returns an 407 // array of BasicBlock*s in control flow graph form (basic blocks ordered by 408 // their RPO number). 409 func newcfg(firstp *obj.Prog) []*BasicBlock { 410 // Reset the opt field of each prog to nil. In the first and second 411 // passes, instructions that are labels temporarily use the opt field to 412 // point to their basic block. In the third pass, the opt field reset 413 // to point to the predecessor of an instruction in its basic block. 414 for p := firstp; p != nil; p = p.Link { 415 p.Opt = nil 416 } 417 418 // Allocate an array to remember where we have seen selectgo calls. 419 // These blocks will be revisited to add successor control flow edges. 420 selectgo := make([]*BasicBlock, 0, 0) 421 422 // Loop through all instructions identifying branch targets 423 // and fall-throughs and allocate basic blocks. 424 cfg := make([]*BasicBlock, 0, 0) 425 426 bb := newblock(firstp) 427 cfg = append(cfg, bb) 428 for p := firstp; p != nil; p = p.Link { 429 Thearch.Proginfo(p) 430 if p.To.Type == obj.TYPE_BRANCH { 431 if p.To.Val == nil { 432 Fatal("prog branch to nil") 433 } 434 if p.To.Val.(*obj.Prog).Opt == nil { 435 p.To.Val.(*obj.Prog).Opt = newblock(p.To.Val.(*obj.Prog)) 436 cfg = append(cfg, p.To.Val.(*obj.Prog).Opt.(*BasicBlock)) 437 } 438 439 if p.As != obj.AJMP && p.Link != nil && p.Link.Opt == nil { 440 p.Link.Opt = newblock(p.Link) 441 cfg = append(cfg, p.Link.Opt.(*BasicBlock)) 442 } 443 } else if isselectcommcasecall(p) || isselectgocall(p) { 444 // Accommodate implicit selectgo control flow. 445 if p.Link.Opt == nil { 446 p.Link.Opt = newblock(p.Link) 447 cfg = append(cfg, p.Link.Opt.(*BasicBlock)) 448 } 449 } 450 } 451 452 // Loop through all basic blocks maximally growing the list of 453 // contained instructions until a label is reached. Add edges 454 // for branches and fall-through instructions. 455 for _, bb := range cfg { 456 for p := bb.last; p != nil; p = p.Link { 457 if p.Opt != nil && p != bb.last { 458 break 459 } 460 bb.last = p 461 462 // Stop before an unreachable RET, to avoid creating 463 // unreachable control flow nodes. 464 if p.Link != nil && p.Link.As == obj.ARET && p.Link.Mode == 1 { 465 break 466 } 467 468 // Collect basic blocks with selectgo calls. 469 if isselectgocall(p) { 470 selectgo = append(selectgo, bb) 471 } 472 } 473 474 if bb.last.To.Type == obj.TYPE_BRANCH { 475 addedge(bb, bb.last.To.Val.(*obj.Prog).Opt.(*BasicBlock)) 476 } 477 if bb.last.Link != nil { 478 // Add a fall-through when the instruction is 479 // not an unconditional control transfer. 480 if bb.last.As != obj.AJMP && bb.last.As != obj.ARET && bb.last.As != obj.AUNDEF { 481 addedge(bb, bb.last.Link.Opt.(*BasicBlock)) 482 } 483 } 484 } 485 486 // Add back links so the instructions in a basic block can be traversed 487 // backward. This is the final state of the instruction opt field. 488 for _, bb := range cfg { 489 p := bb.first 490 var prev *obj.Prog 491 for { 492 p.Opt = prev 493 if p == bb.last { 494 break 495 } 496 prev = p 497 p = p.Link 498 } 499 } 500 501 // Add missing successor edges to the selectgo blocks. 502 if len(selectgo) != 0 { 503 fixselectgo([]*BasicBlock(selectgo)) 504 } 505 506 // Find a depth-first order and assign a depth-first number to 507 // all basic blocks. 508 for _, bb := range cfg { 509 bb.mark = UNVISITED 510 } 511 bb = cfg[0] 512 rpo := int32(len(cfg)) 513 reversepostorder(bb, &rpo) 514 515 // Sort the basic blocks by their depth first number. The 516 // array is now a depth-first spanning tree with the first 517 // node being the root. 518 sort.Sort(blockrpocmp(cfg)) 519 520 // Unreachable control flow nodes are indicated by a -1 in the rpo 521 // field. If we see these nodes something must have gone wrong in an 522 // upstream compilation phase. 523 bb = cfg[0] 524 if bb.rpo == -1 { 525 fmt.Printf("newcfg: unreachable basic block for %v\n", bb.last) 526 printcfg(cfg) 527 Fatal("newcfg: invalid control flow graph") 528 } 529 530 return cfg 531 } 532 533 // Frees a control flow graph (an array of BasicBlock*s) and all of its leaf 534 // data structures. 535 func freecfg(cfg []*BasicBlock) { 536 if len(cfg) > 0 { 537 bb0 := cfg[0] 538 for p := bb0.first; p != nil; p = p.Link { 539 p.Opt = nil 540 } 541 } 542 } 543 544 // Returns true if the node names a variable that is otherwise uninteresting to 545 // the liveness computation. 546 func isfunny(n *Node) bool { 547 return n.Sym != nil && (n.Sym.Name == ".fp" || n.Sym.Name == ".args") 548 } 549 550 // Computes the effects of an instruction on a set of 551 // variables. The vars argument is an array of Node*s. 552 // 553 // The output vectors give bits for variables: 554 // uevar - used by this instruction 555 // varkill - killed by this instruction 556 // for variables without address taken, means variable was set 557 // for variables with address taken, means variable was marked dead 558 // avarinit - initialized or referred to by this instruction, 559 // only for variables with address taken but not escaping to heap 560 // 561 // The avarinit output serves as a signal that the data has been 562 // initialized, because any use of a variable must come after its 563 // initialization. 564 func progeffects(prog *obj.Prog, vars []*Node, uevar Bvec, varkill Bvec, avarinit Bvec) { 565 bvresetall(uevar) 566 bvresetall(varkill) 567 bvresetall(avarinit) 568 569 if prog.As == obj.ARET { 570 // Return instructions implicitly read all the arguments. For 571 // the sake of correctness, out arguments must be read. For the 572 // sake of backtrace quality, we read in arguments as well. 573 // 574 // A return instruction with a p->to is a tail return, which brings 575 // the stack pointer back up (if it ever went down) and then jumps 576 // to a new function entirely. That form of instruction must read 577 // all the parameters for correctness, and similarly it must not 578 // read the out arguments - they won't be set until the new 579 // function runs. 580 for i, node := range vars { 581 switch node.Class &^ PHEAP { 582 case PPARAM: 583 bvset(uevar, int32(i)) 584 585 // If the result had its address taken, it is being tracked 586 // by the avarinit code, which does not use uevar. 587 // If we added it to uevar too, we'd not see any kill 588 // and decide that the variable was live entry, which it is not. 589 // So only use uevar in the non-addrtaken case. 590 // The p->to.type == thearch.D_NONE limits the bvset to 591 // non-tail-call return instructions; see note above 592 // the for loop for details. 593 case PPARAMOUT: 594 if !node.Addrtaken && prog.To.Type == obj.TYPE_NONE { 595 bvset(uevar, int32(i)) 596 } 597 } 598 } 599 600 return 601 } 602 603 if prog.As == obj.ATEXT { 604 // A text instruction marks the entry point to a function and 605 // the definition point of all in arguments. 606 for i, node := range vars { 607 switch node.Class &^ PHEAP { 608 case PPARAM: 609 if node.Addrtaken { 610 bvset(avarinit, int32(i)) 611 } 612 bvset(varkill, int32(i)) 613 } 614 } 615 616 return 617 } 618 619 if prog.Info.Flags&(LeftRead|LeftWrite|LeftAddr) != 0 { 620 from := &prog.From 621 if from.Node != nil && from.Sym != nil && ((from.Node).(*Node)).Name.Curfn == Curfn { 622 switch ((from.Node).(*Node)).Class &^ PHEAP { 623 case PAUTO, PPARAM, PPARAMOUT: 624 pos, ok := from.Node.(*Node).Opt().(int32) // index in vars 625 if !ok { 626 goto Next 627 } 628 if pos >= int32(len(vars)) || vars[pos] != from.Node { 629 Fatal("bad bookkeeping in liveness %v %d", Nconv(from.Node.(*Node), 0), pos) 630 } 631 if ((from.Node).(*Node)).Addrtaken { 632 bvset(avarinit, pos) 633 } else { 634 if prog.Info.Flags&(LeftRead|LeftAddr) != 0 { 635 bvset(uevar, pos) 636 } 637 if prog.Info.Flags&LeftWrite != 0 { 638 if from.Node != nil && !Isfat(((from.Node).(*Node)).Type) { 639 bvset(varkill, pos) 640 } 641 } 642 } 643 } 644 } 645 } 646 647 Next: 648 if prog.Info.Flags&(RightRead|RightWrite|RightAddr) != 0 { 649 to := &prog.To 650 if to.Node != nil && to.Sym != nil && ((to.Node).(*Node)).Name.Curfn == Curfn { 651 switch ((to.Node).(*Node)).Class &^ PHEAP { 652 case PAUTO, PPARAM, PPARAMOUT: 653 pos, ok := to.Node.(*Node).Opt().(int32) // index in vars 654 if !ok { 655 return 656 } 657 if pos >= int32(len(vars)) || vars[pos] != to.Node { 658 Fatal("bad bookkeeping in liveness %v %d", Nconv(to.Node.(*Node), 0), pos) 659 } 660 if ((to.Node).(*Node)).Addrtaken { 661 if prog.As != obj.AVARKILL { 662 bvset(avarinit, pos) 663 } 664 if prog.As == obj.AVARDEF || prog.As == obj.AVARKILL { 665 bvset(varkill, pos) 666 } 667 } else { 668 // RightRead is a read, obviously. 669 // RightAddr by itself is also implicitly a read. 670 // 671 // RightAddr|RightWrite means that the address is being taken 672 // but only so that the instruction can write to the value. 673 // It is not a read. It is equivalent to RightWrite except that 674 // having the RightAddr bit set keeps the registerizer from 675 // trying to substitute a register for the memory location. 676 if (prog.Info.Flags&RightRead != 0) || prog.Info.Flags&(RightAddr|RightWrite) == RightAddr { 677 bvset(uevar, pos) 678 } 679 if prog.Info.Flags&RightWrite != 0 { 680 if to.Node != nil && (!Isfat(((to.Node).(*Node)).Type) || prog.As == obj.AVARDEF) { 681 bvset(varkill, pos) 682 } 683 } 684 } 685 } 686 } 687 } 688 } 689 690 // Constructs a new liveness structure used to hold the global state of the 691 // liveness computation. The cfg argument is an array of BasicBlock*s and the 692 // vars argument is an array of Node*s. 693 func newliveness(fn *Node, ptxt *obj.Prog, cfg []*BasicBlock, vars []*Node) *Liveness { 694 result := new(Liveness) 695 result.fn = fn 696 result.ptxt = ptxt 697 result.cfg = cfg 698 result.vars = vars 699 700 nblocks := int32(len(cfg)) 701 nvars := int32(len(vars)) 702 bulk := bvbulkalloc(nvars, nblocks*7) 703 for _, bb := range cfg { 704 bb.uevar = bulk.next() 705 bb.varkill = bulk.next() 706 bb.livein = bulk.next() 707 bb.liveout = bulk.next() 708 bb.avarinit = bulk.next() 709 bb.avarinitany = bulk.next() 710 bb.avarinitall = bulk.next() 711 } 712 713 result.livepointers = make([]Bvec, 0, 0) 714 result.argslivepointers = make([]Bvec, 0, 0) 715 return result 716 } 717 718 // Frees the liveness structure and all of its leaf data structures. 719 func freeliveness(lv *Liveness) { 720 if lv == nil { 721 Fatal("freeliveness: cannot free nil") 722 } 723 } 724 725 func printeffects(p *obj.Prog, uevar Bvec, varkill Bvec, avarinit Bvec) { 726 fmt.Printf("effects of %v", p) 727 fmt.Printf("\nuevar: ") 728 bvprint(uevar) 729 fmt.Printf("\nvarkill: ") 730 bvprint(varkill) 731 fmt.Printf("\navarinit: ") 732 bvprint(avarinit) 733 fmt.Printf("\n") 734 } 735 736 // Pretty print a variable node. Uses Pascal like conventions for pointers and 737 // addresses to avoid confusing the C like conventions used in the node variable 738 // names. 739 func printnode(node *Node) { 740 p := "" 741 if haspointers(node.Type) { 742 p = "^" 743 } 744 a := "" 745 if node.Addrtaken { 746 a = "@" 747 } 748 fmt.Printf(" %v%s%s", node, p, a) 749 } 750 751 // Pretty print a list of variables. The vars argument is an array of Node*s. 752 func printvars(name string, bv Bvec, vars []*Node) { 753 fmt.Printf("%s:", name) 754 for i, node := range vars { 755 if bvget(bv, int32(i)) != 0 { 756 printnode(node) 757 } 758 } 759 fmt.Printf("\n") 760 } 761 762 // Prints a basic block annotated with the information computed by liveness 763 // analysis. 764 func livenessprintblock(lv *Liveness, bb *BasicBlock) { 765 fmt.Printf("basic block %d\n", bb.rpo) 766 767 fmt.Printf("\tpred:") 768 for _, pred := range bb.pred { 769 fmt.Printf(" %d", pred.rpo) 770 } 771 fmt.Printf("\n") 772 773 fmt.Printf("\tsucc:") 774 for _, succ := range bb.succ { 775 fmt.Printf(" %d", succ.rpo) 776 } 777 fmt.Printf("\n") 778 779 printvars("\tuevar", bb.uevar, []*Node(lv.vars)) 780 printvars("\tvarkill", bb.varkill, []*Node(lv.vars)) 781 printvars("\tlivein", bb.livein, []*Node(lv.vars)) 782 printvars("\tliveout", bb.liveout, []*Node(lv.vars)) 783 printvars("\tavarinit", bb.avarinit, []*Node(lv.vars)) 784 printvars("\tavarinitany", bb.avarinitany, []*Node(lv.vars)) 785 printvars("\tavarinitall", bb.avarinitall, []*Node(lv.vars)) 786 787 fmt.Printf("\tprog:\n") 788 for prog := bb.first; ; prog = prog.Link { 789 fmt.Printf("\t\t%v", prog) 790 if prog.As == obj.APCDATA && prog.From.Offset == obj.PCDATA_StackMapIndex { 791 pos := int32(prog.To.Offset) 792 live := lv.livepointers[pos] 793 fmt.Printf(" ") 794 bvprint(live) 795 } 796 797 fmt.Printf("\n") 798 if prog == bb.last { 799 break 800 } 801 } 802 } 803 804 // Prints a control flow graph annotated with any information computed by 805 // liveness analysis. 806 func livenessprintcfg(lv *Liveness) { 807 for _, bb := range lv.cfg { 808 livenessprintblock(lv, bb) 809 } 810 } 811 812 func checkauto(fn *Node, p *obj.Prog, n *Node) { 813 for l := fn.Func.Dcl; l != nil; l = l.Next { 814 if l.N.Op == ONAME && l.N.Class == PAUTO && l.N == n { 815 return 816 } 817 } 818 819 if n == nil { 820 fmt.Printf("%v: checkauto %v: nil node in %v\n", p.Line(), Curfn, p) 821 return 822 } 823 824 fmt.Printf("checkauto %v: %v (%p; class=%d) not found in %v\n", Curfn, n, n, n.Class, p) 825 for l := fn.Func.Dcl; l != nil; l = l.Next { 826 fmt.Printf("\t%v (%p; class=%d)\n", l.N, l.N, l.N.Class) 827 } 828 Yyerror("checkauto: invariant lost") 829 } 830 831 func checkparam(fn *Node, p *obj.Prog, n *Node) { 832 if isfunny(n) { 833 return 834 } 835 var a *Node 836 var class uint8 837 for l := fn.Func.Dcl; l != nil; l = l.Next { 838 a = l.N 839 class = a.Class &^ PHEAP 840 if a.Op == ONAME && (class == PPARAM || class == PPARAMOUT) && a == n { 841 return 842 } 843 } 844 845 fmt.Printf("checkparam %v: %v (%p; class=%d) not found in %v\n", Curfn, n, n, n.Class, p) 846 for l := fn.Func.Dcl; l != nil; l = l.Next { 847 fmt.Printf("\t%v (%p; class=%d)\n", l.N, l.N, l.N.Class) 848 } 849 Yyerror("checkparam: invariant lost") 850 } 851 852 func checkprog(fn *Node, p *obj.Prog) { 853 if p.From.Name == obj.NAME_AUTO { 854 checkauto(fn, p, p.From.Node.(*Node)) 855 } 856 if p.From.Name == obj.NAME_PARAM { 857 checkparam(fn, p, p.From.Node.(*Node)) 858 } 859 if p.To.Name == obj.NAME_AUTO { 860 checkauto(fn, p, p.To.Node.(*Node)) 861 } 862 if p.To.Name == obj.NAME_PARAM { 863 checkparam(fn, p, p.To.Node.(*Node)) 864 } 865 } 866 867 // Check instruction invariants. We assume that the nodes corresponding to the 868 // sources and destinations of memory operations will be declared in the 869 // function. This is not strictly true, as is the case for the so-called funny 870 // nodes and there are special cases to skip over that stuff. The analysis will 871 // fail if this invariant blindly changes. 872 func checkptxt(fn *Node, firstp *obj.Prog) { 873 if debuglive == 0 { 874 return 875 } 876 877 for p := firstp; p != nil; p = p.Link { 878 if false { 879 fmt.Printf("analyzing '%v'\n", p) 880 } 881 if p.As != obj.ADATA && p.As != obj.AGLOBL && p.As != obj.ATYPE { 882 checkprog(fn, p) 883 } 884 } 885 } 886 887 // NOTE: The bitmap for a specific type t should be cached in t after the first run 888 // and then simply copied into bv at the correct offset on future calls with 889 // the same type t. On https://rsc.googlecode.com/hg/testdata/slow.go, onebitwalktype1 890 // accounts for 40% of the 6g execution time. 891 func onebitwalktype1(t *Type, xoffset *int64, bv Bvec) { 892 if t.Align > 0 && *xoffset&int64(t.Align-1) != 0 { 893 Fatal("onebitwalktype1: invalid initial alignment, %v", t) 894 } 895 896 switch t.Etype { 897 case TINT8, 898 TUINT8, 899 TINT16, 900 TUINT16, 901 TINT32, 902 TUINT32, 903 TINT64, 904 TUINT64, 905 TINT, 906 TUINT, 907 TUINTPTR, 908 TBOOL, 909 TFLOAT32, 910 TFLOAT64, 911 TCOMPLEX64, 912 TCOMPLEX128: 913 *xoffset += t.Width 914 915 case TPTR32, 916 TPTR64, 917 TUNSAFEPTR, 918 TFUNC, 919 TCHAN, 920 TMAP: 921 if *xoffset&int64(Widthptr-1) != 0 { 922 Fatal("onebitwalktype1: invalid alignment, %v", t) 923 } 924 bvset(bv, int32(*xoffset/int64(Widthptr))) // pointer 925 *xoffset += t.Width 926 927 case TSTRING: 928 // struct { byte *str; intgo len; } 929 if *xoffset&int64(Widthptr-1) != 0 { 930 Fatal("onebitwalktype1: invalid alignment, %v", t) 931 } 932 bvset(bv, int32(*xoffset/int64(Widthptr))) //pointer in first slot 933 *xoffset += t.Width 934 935 case TINTER: 936 // struct { Itab *tab; void *data; } 937 // or, when isnilinter(t)==true: 938 // struct { Type *type; void *data; } 939 if *xoffset&int64(Widthptr-1) != 0 { 940 Fatal("onebitwalktype1: invalid alignment, %v", t) 941 } 942 bvset(bv, int32(*xoffset/int64(Widthptr))) // pointer in first slot 943 bvset(bv, int32(*xoffset/int64(Widthptr)+1)) // pointer in second slot 944 *xoffset += t.Width 945 946 case TARRAY: 947 // The value of t->bound is -1 for slices types and >=0 for 948 // for fixed array types. All other values are invalid. 949 if t.Bound < -1 { 950 Fatal("onebitwalktype1: invalid bound, %v", t) 951 } 952 if Isslice(t) { 953 // struct { byte *array; uintgo len; uintgo cap; } 954 if *xoffset&int64(Widthptr-1) != 0 { 955 Fatal("onebitwalktype1: invalid TARRAY alignment, %v", t) 956 } 957 bvset(bv, int32(*xoffset/int64(Widthptr))) // pointer in first slot (BitsPointer) 958 *xoffset += t.Width 959 } else { 960 for i := int64(0); i < t.Bound; i++ { 961 onebitwalktype1(t.Type, xoffset, bv) 962 } 963 } 964 965 case TSTRUCT: 966 o := int64(0) 967 var fieldoffset int64 968 for t1 := t.Type; t1 != nil; t1 = t1.Down { 969 fieldoffset = t1.Width 970 *xoffset += fieldoffset - o 971 onebitwalktype1(t1.Type, xoffset, bv) 972 o = fieldoffset + t1.Type.Width 973 } 974 975 *xoffset += t.Width - o 976 977 default: 978 Fatal("onebitwalktype1: unexpected type, %v", t) 979 } 980 } 981 982 // Returns the number of words of local variables. 983 func localswords() int32 { 984 return int32(stkptrsize / int64(Widthptr)) 985 } 986 987 // Returns the number of words of in and out arguments. 988 func argswords() int32 { 989 return int32(Curfn.Type.Argwid / int64(Widthptr)) 990 } 991 992 // Generates live pointer value maps for arguments and local variables. The 993 // this argument and the in arguments are always assumed live. The vars 994 // argument is an array of Node*s. 995 func onebitlivepointermap(lv *Liveness, liveout Bvec, vars []*Node, args Bvec, locals Bvec) { 996 var node *Node 997 var xoffset int64 998 999 for i := int32(0); ; i++ { 1000 i = int32(bvnext(liveout, i)) 1001 if i < 0 { 1002 break 1003 } 1004 node = vars[i] 1005 switch node.Class { 1006 case PAUTO: 1007 xoffset = node.Xoffset + stkptrsize 1008 onebitwalktype1(node.Type, &xoffset, locals) 1009 1010 case PPARAM, PPARAMOUT: 1011 xoffset = node.Xoffset 1012 onebitwalktype1(node.Type, &xoffset, args) 1013 } 1014 } 1015 1016 // The node list only contains declared names. 1017 // If the receiver or arguments are unnamed, they will be omitted 1018 // from the list above. Preserve those values - even though they are unused - 1019 // in order to keep their addresses live for use in stack traces. 1020 thisargtype := getthisx(lv.fn.Type) 1021 1022 if thisargtype != nil { 1023 xoffset = 0 1024 onebitwalktype1(thisargtype, &xoffset, args) 1025 } 1026 1027 inargtype := getinargx(lv.fn.Type) 1028 if inargtype != nil { 1029 xoffset = 0 1030 onebitwalktype1(inargtype, &xoffset, args) 1031 } 1032 } 1033 1034 // Construct a disembodied instruction. 1035 func unlinkedprog(as int) *obj.Prog { 1036 p := Ctxt.NewProg() 1037 Clearp(p) 1038 p.As = int16(as) 1039 return p 1040 } 1041 1042 // Construct a new PCDATA instruction associated with and for the purposes of 1043 // covering an existing instruction. 1044 func newpcdataprog(prog *obj.Prog, index int32) *obj.Prog { 1045 var from Node 1046 var to Node 1047 1048 Nodconst(&from, Types[TINT32], obj.PCDATA_StackMapIndex) 1049 Nodconst(&to, Types[TINT32], int64(index)) 1050 pcdata := unlinkedprog(obj.APCDATA) 1051 pcdata.Lineno = prog.Lineno 1052 Naddr(&pcdata.From, &from) 1053 Naddr(&pcdata.To, &to) 1054 return pcdata 1055 } 1056 1057 // Returns true for instructions that are safe points that must be annotated 1058 // with liveness information. 1059 func issafepoint(prog *obj.Prog) bool { 1060 return prog.As == obj.ATEXT || prog.As == obj.ACALL 1061 } 1062 1063 // Initializes the sets for solving the live variables. Visits all the 1064 // instructions in each basic block to summarizes the information at each basic 1065 // block 1066 func livenessprologue(lv *Liveness) { 1067 nvars := int32(len(lv.vars)) 1068 uevar := bvalloc(nvars) 1069 varkill := bvalloc(nvars) 1070 avarinit := bvalloc(nvars) 1071 for _, bb := range lv.cfg { 1072 // Walk the block instructions backward and update the block 1073 // effects with the each prog effects. 1074 for p := bb.last; p != nil; p = p.Opt.(*obj.Prog) { 1075 progeffects(p, []*Node(lv.vars), uevar, varkill, avarinit) 1076 if debuglive >= 3 { 1077 printeffects(p, uevar, varkill, avarinit) 1078 } 1079 bvor(bb.varkill, bb.varkill, varkill) 1080 bvandnot(bb.uevar, bb.uevar, varkill) 1081 bvor(bb.uevar, bb.uevar, uevar) 1082 } 1083 1084 // Walk the block instructions forward to update avarinit bits. 1085 // avarinit describes the effect at the end of the block, not the beginning. 1086 bvresetall(varkill) 1087 1088 for p := bb.first; ; p = p.Link { 1089 progeffects(p, []*Node(lv.vars), uevar, varkill, avarinit) 1090 if debuglive >= 3 { 1091 printeffects(p, uevar, varkill, avarinit) 1092 } 1093 bvandnot(bb.avarinit, bb.avarinit, varkill) 1094 bvor(bb.avarinit, bb.avarinit, avarinit) 1095 if p == bb.last { 1096 break 1097 } 1098 } 1099 } 1100 } 1101 1102 // Solve the liveness dataflow equations. 1103 func livenesssolve(lv *Liveness) { 1104 // These temporary bitvectors exist to avoid successive allocations and 1105 // frees within the loop. 1106 newlivein := bvalloc(int32(len(lv.vars))) 1107 1108 newliveout := bvalloc(int32(len(lv.vars))) 1109 any := bvalloc(int32(len(lv.vars))) 1110 all := bvalloc(int32(len(lv.vars))) 1111 1112 // Push avarinitall, avarinitany forward. 1113 // avarinitall says the addressed var is initialized along all paths reaching the block exit. 1114 // avarinitany says the addressed var is initialized along some path reaching the block exit. 1115 for i, bb := range lv.cfg { 1116 if i == 0 { 1117 bvcopy(bb.avarinitall, bb.avarinit) 1118 } else { 1119 bvresetall(bb.avarinitall) 1120 bvnot(bb.avarinitall) 1121 } 1122 bvcopy(bb.avarinitany, bb.avarinit) 1123 } 1124 1125 change := int32(1) 1126 for change != 0 { 1127 change = 0 1128 for _, bb := range lv.cfg { 1129 bvresetall(any) 1130 bvresetall(all) 1131 for j, pred := range bb.pred { 1132 if j == 0 { 1133 bvcopy(any, pred.avarinitany) 1134 bvcopy(all, pred.avarinitall) 1135 } else { 1136 bvor(any, any, pred.avarinitany) 1137 bvand(all, all, pred.avarinitall) 1138 } 1139 } 1140 1141 bvandnot(any, any, bb.varkill) 1142 bvandnot(all, all, bb.varkill) 1143 bvor(any, any, bb.avarinit) 1144 bvor(all, all, bb.avarinit) 1145 if bvcmp(any, bb.avarinitany) != 0 { 1146 change = 1 1147 bvcopy(bb.avarinitany, any) 1148 } 1149 1150 if bvcmp(all, bb.avarinitall) != 0 { 1151 change = 1 1152 bvcopy(bb.avarinitall, all) 1153 } 1154 } 1155 } 1156 1157 // Iterate through the blocks in reverse round-robin fashion. A work 1158 // queue might be slightly faster. As is, the number of iterations is 1159 // so low that it hardly seems to be worth the complexity. 1160 change = 1 1161 1162 for change != 0 { 1163 change = 0 1164 1165 // Walk blocks in the general direction of propagation. This 1166 // improves convergence. 1167 for i := len(lv.cfg) - 1; i >= 0; i-- { 1168 bb := lv.cfg[i] 1169 1170 // A variable is live on output from this block 1171 // if it is live on input to some successor. 1172 // 1173 // out[b] = \bigcup_{s \in succ[b]} in[s] 1174 bvresetall(newliveout) 1175 for _, succ := range bb.succ { 1176 bvor(newliveout, newliveout, succ.livein) 1177 } 1178 1179 if bvcmp(bb.liveout, newliveout) != 0 { 1180 change = 1 1181 bvcopy(bb.liveout, newliveout) 1182 } 1183 1184 // A variable is live on input to this block 1185 // if it is live on output from this block and 1186 // not set by the code in this block. 1187 // 1188 // in[b] = uevar[b] \cup (out[b] \setminus varkill[b]) 1189 bvandnot(newlivein, bb.liveout, bb.varkill) 1190 1191 bvor(bb.livein, newlivein, bb.uevar) 1192 } 1193 } 1194 } 1195 1196 // This function is slow but it is only used for generating debug prints. 1197 // Check whether n is marked live in args/locals. 1198 func islive(n *Node, args Bvec, locals Bvec) bool { 1199 switch n.Class { 1200 case PPARAM, PPARAMOUT: 1201 for i := 0; int64(i) < n.Type.Width/int64(Widthptr); i++ { 1202 if bvget(args, int32(n.Xoffset/int64(Widthptr)+int64(i))) != 0 { 1203 return true 1204 } 1205 } 1206 1207 case PAUTO: 1208 for i := 0; int64(i) < n.Type.Width/int64(Widthptr); i++ { 1209 if bvget(locals, int32((n.Xoffset+stkptrsize)/int64(Widthptr)+int64(i))) != 0 { 1210 return true 1211 } 1212 } 1213 } 1214 1215 return false 1216 } 1217 1218 // Visits all instructions in a basic block and computes a bit vector of live 1219 // variables at each safe point locations. 1220 func livenessepilogue(lv *Liveness) { 1221 var pred *BasicBlock 1222 var args Bvec 1223 var locals Bvec 1224 var n *Node 1225 var p *obj.Prog 1226 var j int32 1227 var pos int32 1228 var xoffset int64 1229 1230 nvars := int32(len(lv.vars)) 1231 livein := bvalloc(nvars) 1232 liveout := bvalloc(nvars) 1233 uevar := bvalloc(nvars) 1234 varkill := bvalloc(nvars) 1235 avarinit := bvalloc(nvars) 1236 any := bvalloc(nvars) 1237 all := bvalloc(nvars) 1238 ambig := bvalloc(localswords()) 1239 nmsg := int32(0) 1240 startmsg := int32(0) 1241 1242 for _, bb := range lv.cfg { 1243 // Compute avarinitany and avarinitall for entry to block. 1244 // This duplicates information known during livenesssolve 1245 // but avoids storing two more vectors for each block. 1246 bvresetall(any) 1247 1248 bvresetall(all) 1249 for j = 0; j < int32(len(bb.pred)); j++ { 1250 pred = bb.pred[j] 1251 if j == 0 { 1252 bvcopy(any, pred.avarinitany) 1253 bvcopy(all, pred.avarinitall) 1254 } else { 1255 bvor(any, any, pred.avarinitany) 1256 bvand(all, all, pred.avarinitall) 1257 } 1258 } 1259 1260 // Walk forward through the basic block instructions and 1261 // allocate liveness maps for those instructions that need them. 1262 // Seed the maps with information about the addrtaken variables. 1263 for p = bb.first; ; p = p.Link { 1264 progeffects(p, []*Node(lv.vars), uevar, varkill, avarinit) 1265 bvandnot(any, any, varkill) 1266 bvandnot(all, all, varkill) 1267 bvor(any, any, avarinit) 1268 bvor(all, all, avarinit) 1269 1270 if issafepoint(p) { 1271 // Annotate ambiguously live variables so that they can 1272 // be zeroed at function entry. 1273 // livein and liveout are dead here and used as temporaries. 1274 bvresetall(livein) 1275 1276 bvandnot(liveout, any, all) 1277 if !bvisempty(liveout) { 1278 for pos = 0; pos < liveout.n; pos++ { 1279 if bvget(liveout, pos) == 0 { 1280 continue 1281 } 1282 bvset(all, pos) // silence future warnings in this block 1283 n = lv.vars[pos] 1284 if !n.Name.Needzero { 1285 n.Name.Needzero = true 1286 if debuglive >= 1 { 1287 Warnl(int(p.Lineno), "%v: %v is ambiguously live", Curfn.Func.Nname, Nconv(n, obj.FmtLong)) 1288 } 1289 1290 // Record in 'ambiguous' bitmap. 1291 xoffset = n.Xoffset + stkptrsize 1292 1293 onebitwalktype1(n.Type, &xoffset, ambig) 1294 } 1295 } 1296 } 1297 1298 // Allocate a bit vector for each class and facet of 1299 // value we are tracking. 1300 1301 // Live stuff first. 1302 args = bvalloc(argswords()) 1303 1304 lv.argslivepointers = append(lv.argslivepointers, args) 1305 locals = bvalloc(localswords()) 1306 lv.livepointers = append(lv.livepointers, locals) 1307 1308 if debuglive >= 3 { 1309 fmt.Printf("%v\n", p) 1310 printvars("avarinitany", any, lv.vars) 1311 } 1312 1313 // Record any values with an "address taken" reaching 1314 // this code position as live. Must do now instead of below 1315 // because the any/all calculation requires walking forward 1316 // over the block (as this loop does), while the liveout 1317 // requires walking backward (as the next loop does). 1318 onebitlivepointermap(lv, any, lv.vars, args, locals) 1319 } 1320 1321 if p == bb.last { 1322 break 1323 } 1324 } 1325 1326 bb.lastbitmapindex = len(lv.livepointers) - 1 1327 } 1328 1329 var fmt_ string 1330 var next *obj.Prog 1331 var numlive int32 1332 var msg []string 1333 for _, bb := range lv.cfg { 1334 if debuglive >= 1 && Curfn.Func.Nname.Sym.Name != "init" && Curfn.Func.Nname.Sym.Name[0] != '.' { 1335 nmsg = int32(len(lv.livepointers)) 1336 startmsg = nmsg 1337 msg = make([]string, nmsg) 1338 for j = 0; j < nmsg; j++ { 1339 msg[j] = "" 1340 } 1341 } 1342 1343 // walk backward, emit pcdata and populate the maps 1344 pos = int32(bb.lastbitmapindex) 1345 1346 if pos < 0 { 1347 // the first block we encounter should have the ATEXT so 1348 // at no point should pos ever be less than zero. 1349 Fatal("livenessepilogue") 1350 } 1351 1352 bvcopy(livein, bb.liveout) 1353 for p = bb.last; p != nil; p = next { 1354 next = p.Opt.(*obj.Prog) // splicebefore modifies p->opt 1355 1356 // Propagate liveness information 1357 progeffects(p, lv.vars, uevar, varkill, avarinit) 1358 1359 bvcopy(liveout, livein) 1360 bvandnot(livein, liveout, varkill) 1361 bvor(livein, livein, uevar) 1362 if debuglive >= 3 && issafepoint(p) { 1363 fmt.Printf("%v\n", p) 1364 printvars("uevar", uevar, lv.vars) 1365 printvars("varkill", varkill, lv.vars) 1366 printvars("livein", livein, lv.vars) 1367 printvars("liveout", liveout, lv.vars) 1368 } 1369 1370 if issafepoint(p) { 1371 // Found an interesting instruction, record the 1372 // corresponding liveness information. 1373 1374 // Useful sanity check: on entry to the function, 1375 // the only things that can possibly be live are the 1376 // input parameters. 1377 if p.As == obj.ATEXT { 1378 for j = 0; j < liveout.n; j++ { 1379 if bvget(liveout, j) == 0 { 1380 continue 1381 } 1382 n = lv.vars[j] 1383 if n.Class != PPARAM { 1384 yyerrorl(int(p.Lineno), "internal error: %v %v recorded as live on entry", Curfn.Func.Nname, Nconv(n, obj.FmtLong)) 1385 } 1386 } 1387 } 1388 1389 // Record live pointers. 1390 args = lv.argslivepointers[pos] 1391 1392 locals = lv.livepointers[pos] 1393 onebitlivepointermap(lv, liveout, lv.vars, args, locals) 1394 1395 // Ambiguously live variables are zeroed immediately after 1396 // function entry. Mark them live for all the non-entry bitmaps 1397 // so that GODEBUG=gcdead=1 mode does not poison them. 1398 if p.As == obj.ACALL { 1399 bvor(locals, locals, ambig) 1400 } 1401 1402 // Show live pointer bitmaps. 1403 // We're interpreting the args and locals bitmap instead of liveout so that we 1404 // include the bits added by the avarinit logic in the 1405 // previous loop. 1406 if msg != nil { 1407 fmt_ = "" 1408 fmt_ += fmt.Sprintf("%v: live at ", p.Line()) 1409 if p.As == obj.ACALL && p.To.Node != nil { 1410 fmt_ += fmt.Sprintf("call to %s:", ((p.To.Node).(*Node)).Sym.Name) 1411 } else if p.As == obj.ACALL { 1412 fmt_ += "indirect call:" 1413 } else { 1414 fmt_ += fmt.Sprintf("entry to %s:", ((p.From.Node).(*Node)).Sym.Name) 1415 } 1416 numlive = 0 1417 for j = 0; j < int32(len(lv.vars)); j++ { 1418 n = lv.vars[j] 1419 if islive(n, args, locals) { 1420 fmt_ += fmt.Sprintf(" %v", n) 1421 numlive++ 1422 } 1423 } 1424 1425 fmt_ += "\n" 1426 if numlive == 0 { // squelch message 1427 1428 } else { 1429 startmsg-- 1430 msg[startmsg] = fmt_ 1431 } 1432 } 1433 1434 // Only CALL instructions need a PCDATA annotation. 1435 // The TEXT instruction annotation is implicit. 1436 if p.As == obj.ACALL { 1437 if isdeferreturn(p) { 1438 // runtime.deferreturn modifies its return address to return 1439 // back to the CALL, not to the subsequent instruction. 1440 // Because the return comes back one instruction early, 1441 // the PCDATA must begin one instruction early too. 1442 // The instruction before a call to deferreturn is always a 1443 // no-op, to keep PC-specific data unambiguous. 1444 splicebefore(lv, bb, newpcdataprog(p.Opt.(*obj.Prog), pos), p.Opt.(*obj.Prog)) 1445 } else { 1446 splicebefore(lv, bb, newpcdataprog(p, pos), p) 1447 } 1448 } 1449 1450 pos-- 1451 } 1452 } 1453 1454 if msg != nil { 1455 for j = startmsg; j < nmsg; j++ { 1456 if msg[j] != "" { 1457 fmt.Printf("%s", msg[j]) 1458 } 1459 } 1460 1461 msg = nil 1462 nmsg = 0 1463 startmsg = 0 1464 } 1465 } 1466 1467 Flusherrors() 1468 } 1469 1470 // FNV-1 hash function constants. 1471 const ( 1472 H0 = 2166136261 1473 Hp = 16777619 1474 ) 1475 1476 func hashbitmap(h uint32, bv Bvec) uint32 { 1477 var w uint32 1478 1479 n := int((bv.n + 31) / 32) 1480 for i := 0; i < n; i++ { 1481 w = bv.b[i] 1482 h = (h * Hp) ^ (w & 0xff) 1483 h = (h * Hp) ^ ((w >> 8) & 0xff) 1484 h = (h * Hp) ^ ((w >> 16) & 0xff) 1485 h = (h * Hp) ^ ((w >> 24) & 0xff) 1486 } 1487 1488 return h 1489 } 1490 1491 // Compact liveness information by coalescing identical per-call-site bitmaps. 1492 // The merging only happens for a single function, not across the entire binary. 1493 // 1494 // There are actually two lists of bitmaps, one list for the local variables and one 1495 // list for the function arguments. Both lists are indexed by the same PCDATA 1496 // index, so the corresponding pairs must be considered together when 1497 // merging duplicates. The argument bitmaps change much less often during 1498 // function execution than the local variable bitmaps, so it is possible that 1499 // we could introduce a separate PCDATA index for arguments vs locals and 1500 // then compact the set of argument bitmaps separately from the set of 1501 // local variable bitmaps. As of 2014-04-02, doing this to the godoc binary 1502 // is actually a net loss: we save about 50k of argument bitmaps but the new 1503 // PCDATA tables cost about 100k. So for now we keep using a single index for 1504 // both bitmap lists. 1505 func livenesscompact(lv *Liveness) { 1506 // Linear probing hash table of bitmaps seen so far. 1507 // The hash table has 4n entries to keep the linear 1508 // scan short. An entry of -1 indicates an empty slot. 1509 n := len(lv.livepointers) 1510 1511 tablesize := 4 * n 1512 table := make([]int, tablesize) 1513 for i := range table { 1514 table[i] = -1 1515 } 1516 1517 // remap[i] = the new index of the old bit vector #i. 1518 remap := make([]int, n) 1519 1520 for i := range remap { 1521 remap[i] = -1 1522 } 1523 uniq := 0 // unique tables found so far 1524 1525 // Consider bit vectors in turn. 1526 // If new, assign next number using uniq, 1527 // record in remap, record in lv->livepointers and lv->argslivepointers 1528 // under the new index, and add entry to hash table. 1529 // If already seen, record earlier index in remap and free bitmaps. 1530 var jarg Bvec 1531 var j int 1532 var h uint32 1533 var arg Bvec 1534 var jlocal Bvec 1535 var local Bvec 1536 for i := 0; i < n; i++ { 1537 local = lv.livepointers[i] 1538 arg = lv.argslivepointers[i] 1539 h = hashbitmap(hashbitmap(H0, local), arg) % uint32(tablesize) 1540 1541 for { 1542 j = table[h] 1543 if j < 0 { 1544 break 1545 } 1546 jlocal = lv.livepointers[j] 1547 jarg = lv.argslivepointers[j] 1548 if bvcmp(local, jlocal) == 0 && bvcmp(arg, jarg) == 0 { 1549 remap[i] = j 1550 goto Next 1551 } 1552 1553 h++ 1554 if h == uint32(tablesize) { 1555 h = 0 1556 } 1557 } 1558 1559 table[h] = uniq 1560 remap[i] = uniq 1561 lv.livepointers[uniq] = local 1562 lv.argslivepointers[uniq] = arg 1563 uniq++ 1564 Next: 1565 } 1566 1567 // We've already reordered lv->livepointers[0:uniq] 1568 // and lv->argslivepointers[0:uniq] and freed the bitmaps 1569 // we don't need anymore. Clear the pointers later in the 1570 // array so that we can tell where the coalesced bitmaps stop 1571 // and so that we don't double-free when cleaning up. 1572 for j := uniq; j < n; j++ { 1573 lv.livepointers[j] = Bvec{} 1574 lv.argslivepointers[j] = Bvec{} 1575 } 1576 1577 // Rewrite PCDATA instructions to use new numbering. 1578 var i int 1579 for p := lv.ptxt; p != nil; p = p.Link { 1580 if p.As == obj.APCDATA && p.From.Offset == obj.PCDATA_StackMapIndex { 1581 i = int(p.To.Offset) 1582 if i >= 0 { 1583 p.To.Offset = int64(remap[i]) 1584 } 1585 } 1586 } 1587 } 1588 1589 func printbitset(printed int, name string, vars []*Node, bits Bvec) int { 1590 started := 0 1591 for i, n := range vars { 1592 if bvget(bits, int32(i)) == 0 { 1593 continue 1594 } 1595 if started == 0 { 1596 if printed == 0 { 1597 fmt.Printf("\t") 1598 } else { 1599 fmt.Printf(" ") 1600 } 1601 started = 1 1602 printed = 1 1603 fmt.Printf("%s=", name) 1604 } else { 1605 fmt.Printf(",") 1606 } 1607 1608 fmt.Printf("%s", n.Sym.Name) 1609 } 1610 1611 return printed 1612 } 1613 1614 // Prints the computed liveness information and inputs, for debugging. 1615 // This format synthesizes the information used during the multiple passes 1616 // into a single presentation. 1617 func livenessprintdebug(lv *Liveness) { 1618 var j int 1619 var printed int 1620 var p *obj.Prog 1621 var args Bvec 1622 var locals Bvec 1623 var n *Node 1624 1625 fmt.Printf("liveness: %s\n", Curfn.Func.Nname.Sym.Name) 1626 1627 uevar := bvalloc(int32(len(lv.vars))) 1628 varkill := bvalloc(int32(len(lv.vars))) 1629 avarinit := bvalloc(int32(len(lv.vars))) 1630 1631 pcdata := 0 1632 for i, bb := range lv.cfg { 1633 if i > 0 { 1634 fmt.Printf("\n") 1635 } 1636 1637 // bb#0 pred=1,2 succ=3,4 1638 fmt.Printf("bb#%d pred=", i) 1639 1640 for j = 0; j < len(bb.pred); j++ { 1641 if j > 0 { 1642 fmt.Printf(",") 1643 } 1644 fmt.Printf("%d", (bb.pred[j]).rpo) 1645 } 1646 1647 fmt.Printf(" succ=") 1648 for j = 0; j < len(bb.succ); j++ { 1649 if j > 0 { 1650 fmt.Printf(",") 1651 } 1652 fmt.Printf("%d", (bb.succ[j]).rpo) 1653 } 1654 1655 fmt.Printf("\n") 1656 1657 // initial settings 1658 printed = 0 1659 1660 printed = printbitset(printed, "uevar", lv.vars, bb.uevar) 1661 printed = printbitset(printed, "livein", lv.vars, bb.livein) 1662 if printed != 0 { 1663 fmt.Printf("\n") 1664 } 1665 1666 // program listing, with individual effects listed 1667 for p = bb.first; ; p = p.Link { 1668 fmt.Printf("%v\n", p) 1669 if p.As == obj.APCDATA && p.From.Offset == obj.PCDATA_StackMapIndex { 1670 pcdata = int(p.To.Offset) 1671 } 1672 progeffects(p, lv.vars, uevar, varkill, avarinit) 1673 printed = 0 1674 printed = printbitset(printed, "uevar", lv.vars, uevar) 1675 printed = printbitset(printed, "varkill", lv.vars, varkill) 1676 printed = printbitset(printed, "avarinit", lv.vars, avarinit) 1677 if printed != 0 { 1678 fmt.Printf("\n") 1679 } 1680 if issafepoint(p) { 1681 args = lv.argslivepointers[pcdata] 1682 locals = lv.livepointers[pcdata] 1683 fmt.Printf("\tlive=") 1684 printed = 0 1685 for j = 0; j < len(lv.vars); j++ { 1686 n = lv.vars[j] 1687 if islive(n, args, locals) { 1688 tmp9 := printed 1689 printed++ 1690 if tmp9 != 0 { 1691 fmt.Printf(",") 1692 } 1693 fmt.Printf("%v", n) 1694 } 1695 } 1696 1697 fmt.Printf("\n") 1698 } 1699 1700 if p == bb.last { 1701 break 1702 } 1703 } 1704 1705 // bb bitsets 1706 fmt.Printf("end\n") 1707 1708 printed = printbitset(printed, "varkill", lv.vars, bb.varkill) 1709 printed = printbitset(printed, "liveout", lv.vars, bb.liveout) 1710 printed = printbitset(printed, "avarinit", lv.vars, bb.avarinit) 1711 printed = printbitset(printed, "avarinitany", lv.vars, bb.avarinitany) 1712 printed = printbitset(printed, "avarinitall", lv.vars, bb.avarinitall) 1713 if printed != 0 { 1714 fmt.Printf("\n") 1715 } 1716 } 1717 1718 fmt.Printf("\n") 1719 } 1720 1721 // Dumps an array of bitmaps to a symbol as a sequence of uint32 values. The 1722 // first word dumped is the total number of bitmaps. The second word is the 1723 // length of the bitmaps. All bitmaps are assumed to be of equal length. The 1724 // words that are followed are the raw bitmap words. The arr argument is an 1725 // array of Node*s. 1726 func onebitwritesymbol(arr []Bvec, sym *Sym) { 1727 var i int 1728 var j int 1729 var word uint32 1730 1731 n := len(arr) 1732 off := 0 1733 off += 4 // number of bitmaps, to fill in later 1734 bv := arr[0] 1735 off = duint32(sym, off, uint32(bv.n)) // number of bits in each bitmap 1736 for i = 0; i < n; i++ { 1737 // bitmap words 1738 bv = arr[i] 1739 1740 if bv.b == nil { 1741 break 1742 } 1743 for j = 0; int32(j) < bv.n; j += 32 { 1744 word = bv.b[j/32] 1745 1746 // Runtime reads the bitmaps as byte arrays. Oblige. 1747 off = duint8(sym, off, uint8(word)) 1748 1749 off = duint8(sym, off, uint8(word>>8)) 1750 off = duint8(sym, off, uint8(word>>16)) 1751 off = duint8(sym, off, uint8(word>>24)) 1752 } 1753 } 1754 1755 duint32(sym, 0, uint32(i)) // number of bitmaps 1756 ggloblsym(sym, int32(off), obj.RODATA) 1757 } 1758 1759 func printprog(p *obj.Prog) { 1760 for p != nil { 1761 fmt.Printf("%v\n", p) 1762 p = p.Link 1763 } 1764 } 1765 1766 // Entry pointer for liveness analysis. Constructs a complete CFG, solves for 1767 // the liveness of pointer variables in the function, and emits a runtime data 1768 // structure read by the garbage collector. 1769 func liveness(fn *Node, firstp *obj.Prog, argssym *Sym, livesym *Sym) { 1770 // Change name to dump debugging information only for a specific function. 1771 debugdelta := 0 1772 1773 if Curfn.Func.Nname.Sym.Name == "!" { 1774 debugdelta = 2 1775 } 1776 1777 debuglive += debugdelta 1778 if debuglive >= 3 { 1779 fmt.Printf("liveness: %s\n", Curfn.Func.Nname.Sym.Name) 1780 printprog(firstp) 1781 } 1782 1783 checkptxt(fn, firstp) 1784 1785 // Construct the global liveness state. 1786 cfg := newcfg(firstp) 1787 1788 if debuglive >= 3 { 1789 printcfg([]*BasicBlock(cfg)) 1790 } 1791 vars := getvariables(fn) 1792 lv := newliveness(fn, firstp, cfg, vars) 1793 1794 // Run the dataflow framework. 1795 livenessprologue(lv) 1796 1797 if debuglive >= 3 { 1798 livenessprintcfg(lv) 1799 } 1800 livenesssolve(lv) 1801 if debuglive >= 3 { 1802 livenessprintcfg(lv) 1803 } 1804 livenessepilogue(lv) 1805 if debuglive >= 3 { 1806 livenessprintcfg(lv) 1807 } 1808 livenesscompact(lv) 1809 1810 if debuglive >= 2 { 1811 livenessprintdebug(lv) 1812 } 1813 1814 // Emit the live pointer map data structures 1815 onebitwritesymbol(lv.livepointers, livesym) 1816 1817 onebitwritesymbol(lv.argslivepointers, argssym) 1818 1819 // Free everything. 1820 for l := fn.Func.Dcl; l != nil; l = l.Next { 1821 if l.N != nil { 1822 l.N.SetOpt(nil) 1823 } 1824 } 1825 freeliveness(lv) 1826 1827 freecfg([]*BasicBlock(cfg)) 1828 1829 debuglive -= debugdelta 1830 } 1831