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