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