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