github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/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 581 if prog.As == obj.ATEXT { 582 // A text instruction marks the entry point to a function and 583 // the definition point of all in arguments. 584 for i, node := range vars { 585 switch node.Class { 586 case PPARAM: 587 if node.Addrtaken { 588 bvset(avarinit, int32(i)) 589 } 590 bvset(varkill, int32(i)) 591 } 592 } 593 594 return 595 } 596 597 if prog.Info.Flags&(LeftRead|LeftWrite|LeftAddr) != 0 { 598 from := &prog.From 599 if from.Node != nil && from.Sym != nil { 600 n := from.Node.(*Node) 601 if pos := liveIndex(n, vars); pos >= 0 { 602 if n.Addrtaken { 603 bvset(avarinit, pos) 604 } else { 605 if prog.Info.Flags&(LeftRead|LeftAddr) != 0 { 606 bvset(uevar, pos) 607 } 608 if prog.Info.Flags&LeftWrite != 0 { 609 if !Isfat(n.Type) { 610 bvset(varkill, pos) 611 } 612 } 613 } 614 } 615 } 616 } 617 618 if prog.Info.Flags&(RightRead|RightWrite|RightAddr) != 0 { 619 to := &prog.To 620 if to.Node != nil && to.Sym != nil { 621 n := to.Node.(*Node) 622 if pos := liveIndex(n, vars); pos >= 0 { 623 if n.Addrtaken { 624 if prog.As != obj.AVARKILL { 625 bvset(avarinit, pos) 626 } 627 if prog.As == obj.AVARDEF || prog.As == obj.AVARKILL { 628 bvset(varkill, pos) 629 } 630 } else { 631 // RightRead is a read, obviously. 632 // RightAddr by itself is also implicitly a read. 633 // 634 // RightAddr|RightWrite means that the address is being taken 635 // but only so that the instruction can write to the value. 636 // It is not a read. It is equivalent to RightWrite except that 637 // having the RightAddr bit set keeps the registerizer from 638 // trying to substitute a register for the memory location. 639 if (prog.Info.Flags&RightRead != 0) || prog.Info.Flags&(RightAddr|RightWrite) == RightAddr { 640 bvset(uevar, pos) 641 } 642 if prog.Info.Flags&RightWrite != 0 { 643 if !Isfat(n.Type) || prog.As == obj.AVARDEF { 644 bvset(varkill, pos) 645 } 646 } 647 } 648 } 649 } 650 } 651 } 652 653 // liveIndex returns the index of n in the set of tracked vars. 654 // If n is not a tracked var, liveIndex returns -1. 655 // If n is not a tracked var but should be tracked, liveIndex crashes. 656 func liveIndex(n *Node, vars []*Node) int32 { 657 if n.Name.Curfn != Curfn || !livenessShouldTrack(n) { 658 return -1 659 } 660 661 pos, ok := n.Opt().(int32) // index in vars 662 if !ok { 663 Fatalf("lost track of variable in liveness: %v (%p, %p)", n, n, n.Orig) 664 } 665 if pos >= int32(len(vars)) || vars[pos] != n { 666 Fatalf("bad bookkeeping in liveness: %v (%p, %p)", n, n, n.Orig) 667 } 668 return pos 669 } 670 671 // Constructs a new liveness structure used to hold the global state of the 672 // liveness computation. The cfg argument is a slice of *BasicBlocks and the 673 // vars argument is a slice of *Nodes. 674 func newliveness(fn *Node, ptxt *obj.Prog, cfg []*BasicBlock, vars []*Node) *Liveness { 675 result := Liveness{ 676 fn: fn, 677 ptxt: ptxt, 678 cfg: cfg, 679 vars: vars, 680 } 681 682 nblocks := int32(len(cfg)) 683 nvars := int32(len(vars)) 684 bulk := bvbulkalloc(nvars, nblocks*7) 685 for _, bb := range cfg { 686 bb.uevar = bulk.next() 687 bb.varkill = bulk.next() 688 bb.livein = bulk.next() 689 bb.liveout = bulk.next() 690 bb.avarinit = bulk.next() 691 bb.avarinitany = bulk.next() 692 bb.avarinitall = bulk.next() 693 } 694 return &result 695 } 696 697 func printeffects(p *obj.Prog, uevar bvec, varkill bvec, avarinit bvec) { 698 fmt.Printf("effects of %v", p) 699 fmt.Printf("\nuevar: ") 700 bvprint(uevar) 701 fmt.Printf("\nvarkill: ") 702 bvprint(varkill) 703 fmt.Printf("\navarinit: ") 704 bvprint(avarinit) 705 fmt.Printf("\n") 706 } 707 708 // Pretty print a variable node. Uses Pascal like conventions for pointers and 709 // addresses to avoid confusing the C like conventions used in the node variable 710 // names. 711 func printnode(node *Node) { 712 p := "" 713 if haspointers(node.Type) { 714 p = "^" 715 } 716 a := "" 717 if node.Addrtaken { 718 a = "@" 719 } 720 fmt.Printf(" %v%s%s", node, p, a) 721 } 722 723 // Pretty print a list of variables. The vars argument is a slice of *Nodes. 724 func printvars(name string, bv bvec, vars []*Node) { 725 fmt.Printf("%s:", name) 726 for i, node := range vars { 727 if bvget(bv, int32(i)) != 0 { 728 printnode(node) 729 } 730 } 731 fmt.Printf("\n") 732 } 733 734 // Prints a basic block annotated with the information computed by liveness 735 // analysis. 736 func livenessprintblock(lv *Liveness, bb *BasicBlock) { 737 fmt.Printf("basic block %d\n", bb.rpo) 738 739 fmt.Printf("\tpred:") 740 for _, pred := range bb.pred { 741 fmt.Printf(" %d", pred.rpo) 742 } 743 fmt.Printf("\n") 744 745 fmt.Printf("\tsucc:") 746 for _, succ := range bb.succ { 747 fmt.Printf(" %d", succ.rpo) 748 } 749 fmt.Printf("\n") 750 751 printvars("\tuevar", bb.uevar, lv.vars) 752 printvars("\tvarkill", bb.varkill, lv.vars) 753 printvars("\tlivein", bb.livein, lv.vars) 754 printvars("\tliveout", bb.liveout, lv.vars) 755 printvars("\tavarinit", bb.avarinit, lv.vars) 756 printvars("\tavarinitany", bb.avarinitany, lv.vars) 757 printvars("\tavarinitall", bb.avarinitall, lv.vars) 758 759 fmt.Printf("\tprog:\n") 760 for prog := bb.first; ; prog = prog.Link { 761 fmt.Printf("\t\t%v", prog) 762 if prog.As == obj.APCDATA && prog.From.Offset == obj.PCDATA_StackMapIndex { 763 pos := int32(prog.To.Offset) 764 live := lv.livepointers[pos] 765 fmt.Printf(" ") 766 bvprint(live) 767 } 768 769 fmt.Printf("\n") 770 if prog == bb.last { 771 break 772 } 773 } 774 } 775 776 // Prints a control flow graph annotated with any information computed by 777 // liveness analysis. 778 func livenessprintcfg(lv *Liveness) { 779 for _, bb := range lv.cfg { 780 livenessprintblock(lv, bb) 781 } 782 } 783 784 func checkauto(fn *Node, p *obj.Prog, n *Node) { 785 for _, ln := range fn.Func.Dcl { 786 if ln.Op == ONAME && ln.Class == PAUTO && ln == n { 787 return 788 } 789 } 790 791 if n == nil { 792 fmt.Printf("%v: checkauto %v: nil node in %v\n", p.Line(), Curfn, p) 793 return 794 } 795 796 fmt.Printf("checkauto %v: %v (%p; class=%d) not found in %p %v\n", funcSym(Curfn), n, n, n.Class, p, p) 797 for _, ln := range fn.Func.Dcl { 798 fmt.Printf("\t%v (%p; class=%d)\n", ln, ln, ln.Class) 799 } 800 Yyerror("checkauto: invariant lost") 801 } 802 803 func checkparam(fn *Node, p *obj.Prog, n *Node) { 804 if isfunny(n) { 805 return 806 } 807 for _, a := range fn.Func.Dcl { 808 if a.Op == ONAME && (a.Class == PPARAM || a.Class == PPARAMOUT) && a == n { 809 return 810 } 811 } 812 813 fmt.Printf("checkparam %v: %v (%p; class=%d) not found in %v\n", Curfn, n, n, n.Class, p) 814 for _, ln := range fn.Func.Dcl { 815 fmt.Printf("\t%v (%p; class=%d)\n", ln, ln, ln.Class) 816 } 817 Yyerror("checkparam: invariant lost") 818 } 819 820 func checkprog(fn *Node, p *obj.Prog) { 821 if p.From.Name == obj.NAME_AUTO { 822 checkauto(fn, p, p.From.Node.(*Node)) 823 } 824 if p.From.Name == obj.NAME_PARAM { 825 checkparam(fn, p, p.From.Node.(*Node)) 826 } 827 if p.To.Name == obj.NAME_AUTO { 828 checkauto(fn, p, p.To.Node.(*Node)) 829 } 830 if p.To.Name == obj.NAME_PARAM { 831 checkparam(fn, p, p.To.Node.(*Node)) 832 } 833 } 834 835 // Check instruction invariants. We assume that the nodes corresponding to the 836 // sources and destinations of memory operations will be declared in the 837 // function. This is not strictly true, as is the case for the so-called funny 838 // nodes and there are special cases to skip over that stuff. The analysis will 839 // fail if this invariant blindly changes. 840 func checkptxt(fn *Node, firstp *obj.Prog) { 841 if debuglive == 0 { 842 return 843 } 844 845 for p := firstp; p != nil; p = p.Link { 846 if false { 847 fmt.Printf("analyzing '%v'\n", p) 848 } 849 if p.As != obj.AGLOBL && p.As != obj.ATYPE { 850 checkprog(fn, p) 851 } 852 } 853 } 854 855 // NOTE: The bitmap for a specific type t should be cached in t after the first run 856 // and then simply copied into bv at the correct offset on future calls with 857 // the same type t. On https://rsc.googlecode.com/hg/testdata/slow.go, onebitwalktype1 858 // accounts for 40% of the 6g execution time. 859 func onebitwalktype1(t *Type, xoffset *int64, bv bvec) { 860 if t.Align > 0 && *xoffset&int64(t.Align-1) != 0 { 861 Fatalf("onebitwalktype1: invalid initial alignment, %v", t) 862 } 863 864 switch t.Etype { 865 case TINT8, 866 TUINT8, 867 TINT16, 868 TUINT16, 869 TINT32, 870 TUINT32, 871 TINT64, 872 TUINT64, 873 TINT, 874 TUINT, 875 TUINTPTR, 876 TBOOL, 877 TFLOAT32, 878 TFLOAT64, 879 TCOMPLEX64, 880 TCOMPLEX128: 881 *xoffset += t.Width 882 883 case TPTR32, 884 TPTR64, 885 TUNSAFEPTR, 886 TFUNC, 887 TCHAN, 888 TMAP: 889 if *xoffset&int64(Widthptr-1) != 0 { 890 Fatalf("onebitwalktype1: invalid alignment, %v", t) 891 } 892 bvset(bv, int32(*xoffset/int64(Widthptr))) // pointer 893 *xoffset += t.Width 894 895 case TSTRING: 896 // struct { byte *str; intgo len; } 897 if *xoffset&int64(Widthptr-1) != 0 { 898 Fatalf("onebitwalktype1: invalid alignment, %v", t) 899 } 900 bvset(bv, int32(*xoffset/int64(Widthptr))) //pointer in first slot 901 *xoffset += t.Width 902 903 case TINTER: 904 // struct { Itab *tab; void *data; } 905 // or, when isnilinter(t)==true: 906 // struct { Type *type; void *data; } 907 if *xoffset&int64(Widthptr-1) != 0 { 908 Fatalf("onebitwalktype1: invalid alignment, %v", t) 909 } 910 bvset(bv, int32(*xoffset/int64(Widthptr))) // pointer in first slot 911 bvset(bv, int32(*xoffset/int64(Widthptr)+1)) // pointer in second slot 912 *xoffset += t.Width 913 914 case TSLICE: 915 // struct { byte *array; uintgo len; uintgo cap; } 916 if *xoffset&int64(Widthptr-1) != 0 { 917 Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t) 918 } 919 bvset(bv, int32(*xoffset/int64(Widthptr))) // pointer in first slot (BitsPointer) 920 *xoffset += t.Width 921 922 case TARRAY: 923 for i := int64(0); i < t.NumElem(); i++ { 924 onebitwalktype1(t.Elem(), xoffset, bv) 925 } 926 927 case TSTRUCT: 928 var o int64 929 for _, t1 := range t.Fields().Slice() { 930 fieldoffset := t1.Offset 931 *xoffset += fieldoffset - o 932 onebitwalktype1(t1.Type, xoffset, bv) 933 o = fieldoffset + t1.Type.Width 934 } 935 936 *xoffset += t.Width - o 937 938 default: 939 Fatalf("onebitwalktype1: unexpected type, %v", t) 940 } 941 } 942 943 // Returns the number of words of local variables. 944 func localswords() int32 { 945 return int32(stkptrsize / int64(Widthptr)) 946 } 947 948 // Returns the number of words of in and out arguments. 949 func argswords() int32 { 950 return int32(Curfn.Type.ArgWidth() / int64(Widthptr)) 951 } 952 953 // Generates live pointer value maps for arguments and local variables. The 954 // this argument and the in arguments are always assumed live. The vars 955 // argument is a slice of *Nodes. 956 func onebitlivepointermap(lv *Liveness, liveout bvec, vars []*Node, args bvec, locals bvec) { 957 var xoffset int64 958 959 for i := int32(0); ; i++ { 960 i = bvnext(liveout, i) 961 if i < 0 { 962 break 963 } 964 node := vars[i] 965 switch node.Class { 966 case PAUTO: 967 xoffset = node.Xoffset + stkptrsize 968 onebitwalktype1(node.Type, &xoffset, locals) 969 970 case PPARAM, PPARAMOUT: 971 xoffset = node.Xoffset 972 onebitwalktype1(node.Type, &xoffset, args) 973 } 974 } 975 } 976 977 // Construct a disembodied instruction. 978 func unlinkedprog(as obj.As) *obj.Prog { 979 p := Ctxt.NewProg() 980 Clearp(p) 981 p.As = as 982 return p 983 } 984 985 // Construct a new PCDATA instruction associated with and for the purposes of 986 // covering an existing instruction. 987 func newpcdataprog(prog *obj.Prog, index int32) *obj.Prog { 988 pcdata := unlinkedprog(obj.APCDATA) 989 pcdata.Lineno = prog.Lineno 990 pcdata.From.Type = obj.TYPE_CONST 991 pcdata.From.Offset = obj.PCDATA_StackMapIndex 992 pcdata.To.Type = obj.TYPE_CONST 993 pcdata.To.Offset = int64(index) 994 return pcdata 995 } 996 997 // Returns true for instructions that are safe points that must be annotated 998 // with liveness information. 999 func issafepoint(prog *obj.Prog) bool { 1000 return prog.As == obj.ATEXT || prog.As == obj.ACALL 1001 } 1002 1003 // Initializes the sets for solving the live variables. Visits all the 1004 // instructions in each basic block to summarizes the information at each basic 1005 // block 1006 func livenessprologue(lv *Liveness) { 1007 nvars := int32(len(lv.vars)) 1008 uevar := bvalloc(nvars) 1009 varkill := bvalloc(nvars) 1010 avarinit := bvalloc(nvars) 1011 for _, bb := range lv.cfg { 1012 // Walk the block instructions backward and update the block 1013 // effects with the each prog effects. 1014 for p := bb.last; p != nil; p = p.Opt.(*obj.Prog) { 1015 progeffects(p, lv.vars, uevar, varkill, avarinit) 1016 if debuglive >= 3 { 1017 printeffects(p, uevar, varkill, avarinit) 1018 } 1019 bvor(bb.varkill, bb.varkill, varkill) 1020 bvandnot(bb.uevar, bb.uevar, varkill) 1021 bvor(bb.uevar, bb.uevar, uevar) 1022 } 1023 1024 // Walk the block instructions forward to update avarinit bits. 1025 // avarinit describes the effect at the end of the block, not the beginning. 1026 bvresetall(varkill) 1027 1028 for p := bb.first; ; p = p.Link { 1029 progeffects(p, lv.vars, uevar, varkill, avarinit) 1030 if debuglive >= 3 { 1031 printeffects(p, uevar, varkill, avarinit) 1032 } 1033 bvandnot(bb.avarinit, bb.avarinit, varkill) 1034 bvor(bb.avarinit, bb.avarinit, avarinit) 1035 if p == bb.last { 1036 break 1037 } 1038 } 1039 } 1040 } 1041 1042 // Solve the liveness dataflow equations. 1043 func livenesssolve(lv *Liveness) { 1044 // These temporary bitvectors exist to avoid successive allocations and 1045 // frees within the loop. 1046 newlivein := bvalloc(int32(len(lv.vars))) 1047 1048 newliveout := bvalloc(int32(len(lv.vars))) 1049 any := bvalloc(int32(len(lv.vars))) 1050 all := bvalloc(int32(len(lv.vars))) 1051 1052 // Push avarinitall, avarinitany forward. 1053 // avarinitall says the addressed var is initialized along all paths reaching the block exit. 1054 // avarinitany says the addressed var is initialized along some path reaching the block exit. 1055 for i, bb := range lv.cfg { 1056 if i == 0 { 1057 bvcopy(bb.avarinitall, bb.avarinit) 1058 } else { 1059 bvresetall(bb.avarinitall) 1060 bvnot(bb.avarinitall) 1061 } 1062 bvcopy(bb.avarinitany, bb.avarinit) 1063 } 1064 1065 for change := true; change; { 1066 change = false 1067 for _, bb := range lv.cfg { 1068 bvresetall(any) 1069 bvresetall(all) 1070 for j, pred := range bb.pred { 1071 if j == 0 { 1072 bvcopy(any, pred.avarinitany) 1073 bvcopy(all, pred.avarinitall) 1074 } else { 1075 bvor(any, any, pred.avarinitany) 1076 bvand(all, all, pred.avarinitall) 1077 } 1078 } 1079 1080 bvandnot(any, any, bb.varkill) 1081 bvandnot(all, all, bb.varkill) 1082 bvor(any, any, bb.avarinit) 1083 bvor(all, all, bb.avarinit) 1084 if !bveq(any, bb.avarinitany) { 1085 change = true 1086 bvcopy(bb.avarinitany, any) 1087 } 1088 1089 if !bveq(all, bb.avarinitall) { 1090 change = true 1091 bvcopy(bb.avarinitall, all) 1092 } 1093 } 1094 } 1095 1096 // Iterate through the blocks in reverse round-robin fashion. A work 1097 // queue might be slightly faster. As is, the number of iterations is 1098 // so low that it hardly seems to be worth the complexity. 1099 1100 for change := true; change; { 1101 change = false 1102 1103 // Walk blocks in the general direction of propagation. This 1104 // improves convergence. 1105 for i := len(lv.cfg) - 1; i >= 0; i-- { 1106 bb := lv.cfg[i] 1107 1108 // A variable is live on output from this block 1109 // if it is live on input to some successor. 1110 // 1111 // out[b] = \bigcup_{s \in succ[b]} in[s] 1112 bvresetall(newliveout) 1113 for _, succ := range bb.succ { 1114 bvor(newliveout, newliveout, succ.livein) 1115 } 1116 1117 if !bveq(bb.liveout, newliveout) { 1118 change = true 1119 bvcopy(bb.liveout, newliveout) 1120 } 1121 1122 // A variable is live on input to this block 1123 // if it is live on output from this block and 1124 // not set by the code in this block. 1125 // 1126 // in[b] = uevar[b] \cup (out[b] \setminus varkill[b]) 1127 bvandnot(newlivein, bb.liveout, bb.varkill) 1128 1129 bvor(bb.livein, newlivein, bb.uevar) 1130 } 1131 } 1132 } 1133 1134 // This function is slow but it is only used for generating debug prints. 1135 // Check whether n is marked live in args/locals. 1136 func islive(n *Node, args bvec, locals bvec) bool { 1137 switch n.Class { 1138 case PPARAM, PPARAMOUT: 1139 for i := 0; int64(i) < n.Type.Width/int64(Widthptr); i++ { 1140 if bvget(args, int32(n.Xoffset/int64(Widthptr)+int64(i))) != 0 { 1141 return true 1142 } 1143 } 1144 1145 case PAUTO: 1146 for i := 0; int64(i) < n.Type.Width/int64(Widthptr); i++ { 1147 if bvget(locals, int32((n.Xoffset+stkptrsize)/int64(Widthptr)+int64(i))) != 0 { 1148 return true 1149 } 1150 } 1151 } 1152 1153 return false 1154 } 1155 1156 // Visits all instructions in a basic block and computes a bit vector of live 1157 // variables at each safe point locations. 1158 func livenessepilogue(lv *Liveness) { 1159 nvars := int32(len(lv.vars)) 1160 livein := bvalloc(nvars) 1161 liveout := bvalloc(nvars) 1162 uevar := bvalloc(nvars) 1163 varkill := bvalloc(nvars) 1164 avarinit := bvalloc(nvars) 1165 any := bvalloc(nvars) 1166 all := bvalloc(nvars) 1167 ambig := bvalloc(localswords()) 1168 1169 for _, bb := range lv.cfg { 1170 // Compute avarinitany and avarinitall for entry to block. 1171 // This duplicates information known during livenesssolve 1172 // but avoids storing two more vectors for each block. 1173 bvresetall(any) 1174 1175 bvresetall(all) 1176 for j := 0; j < len(bb.pred); j++ { 1177 pred := bb.pred[j] 1178 if j == 0 { 1179 bvcopy(any, pred.avarinitany) 1180 bvcopy(all, pred.avarinitall) 1181 } else { 1182 bvor(any, any, pred.avarinitany) 1183 bvand(all, all, pred.avarinitall) 1184 } 1185 } 1186 1187 // Walk forward through the basic block instructions and 1188 // allocate liveness maps for those instructions that need them. 1189 // Seed the maps with information about the addrtaken variables. 1190 for p := bb.first; ; p = p.Link { 1191 progeffects(p, lv.vars, uevar, varkill, avarinit) 1192 bvandnot(any, any, varkill) 1193 bvandnot(all, all, varkill) 1194 bvor(any, any, avarinit) 1195 bvor(all, all, avarinit) 1196 1197 if issafepoint(p) { 1198 // Annotate ambiguously live variables so that they can 1199 // be zeroed at function entry. 1200 // livein and liveout are dead here and used as temporaries. 1201 bvresetall(livein) 1202 1203 bvandnot(liveout, any, all) 1204 if !bvisempty(liveout) { 1205 for pos := int32(0); pos < liveout.n; pos++ { 1206 if bvget(liveout, pos) == 0 { 1207 continue 1208 } 1209 bvset(all, pos) // silence future warnings in this block 1210 n := lv.vars[pos] 1211 if !n.Name.Needzero { 1212 n.Name.Needzero = true 1213 if debuglive >= 1 { 1214 Warnl(p.Lineno, "%v: %v is ambiguously live", Curfn.Func.Nname, Nconv(n, FmtLong)) 1215 } 1216 1217 // Record in 'ambiguous' bitmap. 1218 xoffset := n.Xoffset + stkptrsize 1219 1220 onebitwalktype1(n.Type, &xoffset, ambig) 1221 } 1222 } 1223 } 1224 1225 // Allocate a bit vector for each class and facet of 1226 // value we are tracking. 1227 1228 // Live stuff first. 1229 args := bvalloc(argswords()) 1230 1231 lv.argslivepointers = append(lv.argslivepointers, args) 1232 locals := bvalloc(localswords()) 1233 lv.livepointers = append(lv.livepointers, locals) 1234 1235 if debuglive >= 3 { 1236 fmt.Printf("%v\n", p) 1237 printvars("avarinitany", any, lv.vars) 1238 } 1239 1240 // Record any values with an "address taken" reaching 1241 // this code position as live. Must do now instead of below 1242 // because the any/all calculation requires walking forward 1243 // over the block (as this loop does), while the liveout 1244 // requires walking backward (as the next loop does). 1245 onebitlivepointermap(lv, any, lv.vars, args, locals) 1246 } 1247 1248 if p == bb.last { 1249 break 1250 } 1251 } 1252 1253 bb.lastbitmapindex = len(lv.livepointers) - 1 1254 } 1255 1256 var msg []string 1257 var nmsg, startmsg int 1258 for _, bb := range lv.cfg { 1259 if debuglive >= 1 && Curfn.Func.Nname.Sym.Name != "init" && Curfn.Func.Nname.Sym.Name[0] != '.' { 1260 nmsg = len(lv.livepointers) 1261 startmsg = nmsg 1262 msg = make([]string, nmsg) 1263 for j := 0; j < nmsg; j++ { 1264 msg[j] = "" 1265 } 1266 } 1267 1268 // walk backward, emit pcdata and populate the maps 1269 pos := int32(bb.lastbitmapindex) 1270 1271 if pos < 0 { 1272 // the first block we encounter should have the ATEXT so 1273 // at no point should pos ever be less than zero. 1274 Fatalf("livenessepilogue") 1275 } 1276 1277 bvcopy(livein, bb.liveout) 1278 var next *obj.Prog 1279 for p := bb.last; p != nil; p = next { 1280 next = p.Opt.(*obj.Prog) // splicebefore modifies p.opt 1281 1282 // Propagate liveness information 1283 progeffects(p, lv.vars, uevar, varkill, avarinit) 1284 1285 bvcopy(liveout, livein) 1286 bvandnot(livein, liveout, varkill) 1287 bvor(livein, livein, uevar) 1288 if debuglive >= 3 && issafepoint(p) { 1289 fmt.Printf("%v\n", p) 1290 printvars("uevar", uevar, lv.vars) 1291 printvars("varkill", varkill, lv.vars) 1292 printvars("livein", livein, lv.vars) 1293 printvars("liveout", liveout, lv.vars) 1294 } 1295 1296 if issafepoint(p) { 1297 // Found an interesting instruction, record the 1298 // corresponding liveness information. 1299 1300 // Useful sanity check: on entry to the function, 1301 // the only things that can possibly be live are the 1302 // input parameters. 1303 if p.As == obj.ATEXT { 1304 for j := int32(0); j < liveout.n; j++ { 1305 if bvget(liveout, j) == 0 { 1306 continue 1307 } 1308 n := lv.vars[j] 1309 if n.Class != PPARAM { 1310 yyerrorl(p.Lineno, "internal error: %v %v recorded as live on entry, p.Pc=%v", Curfn.Func.Nname, Nconv(n, FmtLong), p.Pc) 1311 } 1312 } 1313 } 1314 1315 // Record live pointers. 1316 args := lv.argslivepointers[pos] 1317 1318 locals := lv.livepointers[pos] 1319 onebitlivepointermap(lv, liveout, lv.vars, args, locals) 1320 1321 // Ambiguously live variables are zeroed immediately after 1322 // function entry. Mark them live for all the non-entry bitmaps 1323 // so that GODEBUG=gcdead=1 mode does not poison them. 1324 if p.As == obj.ACALL { 1325 bvor(locals, locals, ambig) 1326 } 1327 1328 // Show live pointer bitmaps. 1329 // We're interpreting the args and locals bitmap instead of liveout so that we 1330 // include the bits added by the avarinit logic in the 1331 // previous loop. 1332 if msg != nil { 1333 fmt_ := fmt.Sprintf("%v: live at ", p.Line()) 1334 if p.As == obj.ACALL && p.To.Sym != nil { 1335 name := p.To.Sym.Name 1336 i := strings.Index(name, ".") 1337 if i >= 0 { 1338 name = name[i+1:] 1339 } 1340 fmt_ += fmt.Sprintf("call to %s:", name) 1341 } else if p.As == obj.ACALL { 1342 fmt_ += "indirect call:" 1343 } else { 1344 fmt_ += fmt.Sprintf("entry to %s:", ((p.From.Node).(*Node)).Sym.Name) 1345 } 1346 numlive := 0 1347 for j := 0; j < len(lv.vars); j++ { 1348 n := lv.vars[j] 1349 if islive(n, args, locals) { 1350 fmt_ += fmt.Sprintf(" %v", n) 1351 numlive++ 1352 } 1353 } 1354 1355 fmt_ += "\n" 1356 if numlive == 0 { // squelch message 1357 1358 } else { 1359 startmsg-- 1360 msg[startmsg] = fmt_ 1361 } 1362 } 1363 1364 // Only CALL instructions need a PCDATA annotation. 1365 // The TEXT instruction annotation is implicit. 1366 if p.As == obj.ACALL { 1367 if isdeferreturn(p) { 1368 // runtime.deferreturn modifies its return address to return 1369 // back to the CALL, not to the subsequent instruction. 1370 // Because the return comes back one instruction early, 1371 // the PCDATA must begin one instruction early too. 1372 // The instruction before a call to deferreturn is always a 1373 // no-op, to keep PC-specific data unambiguous. 1374 prev := p.Opt.(*obj.Prog) 1375 if Ctxt.Arch.Family == sys.PPC64 { 1376 // On ppc64 there is an additional instruction 1377 // (another no-op or reload of toc pointer) before 1378 // the call. 1379 prev = prev.Opt.(*obj.Prog) 1380 } 1381 splicebefore(lv, bb, newpcdataprog(prev, pos), prev) 1382 } else { 1383 splicebefore(lv, bb, newpcdataprog(p, pos), p) 1384 } 1385 } 1386 1387 pos-- 1388 } 1389 } 1390 1391 if msg != nil { 1392 for j := startmsg; j < nmsg; j++ { 1393 if msg[j] != "" { 1394 fmt.Printf("%s", msg[j]) 1395 } 1396 } 1397 1398 msg = nil 1399 nmsg = 0 1400 startmsg = 0 1401 } 1402 } 1403 1404 Flusherrors() 1405 } 1406 1407 // FNV-1 hash function constants. 1408 const ( 1409 H0 = 2166136261 1410 Hp = 16777619 1411 ) 1412 1413 func hashbitmap(h uint32, bv bvec) uint32 { 1414 n := int((bv.n + 31) / 32) 1415 for i := 0; i < n; i++ { 1416 w := bv.b[i] 1417 h = (h * Hp) ^ (w & 0xff) 1418 h = (h * Hp) ^ ((w >> 8) & 0xff) 1419 h = (h * Hp) ^ ((w >> 16) & 0xff) 1420 h = (h * Hp) ^ ((w >> 24) & 0xff) 1421 } 1422 1423 return h 1424 } 1425 1426 // Compact liveness information by coalescing identical per-call-site bitmaps. 1427 // The merging only happens for a single function, not across the entire binary. 1428 // 1429 // There are actually two lists of bitmaps, one list for the local variables and one 1430 // list for the function arguments. Both lists are indexed by the same PCDATA 1431 // index, so the corresponding pairs must be considered together when 1432 // merging duplicates. The argument bitmaps change much less often during 1433 // function execution than the local variable bitmaps, so it is possible that 1434 // we could introduce a separate PCDATA index for arguments vs locals and 1435 // then compact the set of argument bitmaps separately from the set of 1436 // local variable bitmaps. As of 2014-04-02, doing this to the godoc binary 1437 // is actually a net loss: we save about 50k of argument bitmaps but the new 1438 // PCDATA tables cost about 100k. So for now we keep using a single index for 1439 // both bitmap lists. 1440 func livenesscompact(lv *Liveness) { 1441 // Linear probing hash table of bitmaps seen so far. 1442 // The hash table has 4n entries to keep the linear 1443 // scan short. An entry of -1 indicates an empty slot. 1444 n := len(lv.livepointers) 1445 1446 tablesize := 4 * n 1447 table := make([]int, tablesize) 1448 for i := range table { 1449 table[i] = -1 1450 } 1451 1452 // remap[i] = the new index of the old bit vector #i. 1453 remap := make([]int, n) 1454 1455 for i := range remap { 1456 remap[i] = -1 1457 } 1458 uniq := 0 // unique tables found so far 1459 1460 // Consider bit vectors in turn. 1461 // If new, assign next number using uniq, 1462 // record in remap, record in lv.livepointers and lv.argslivepointers 1463 // under the new index, and add entry to hash table. 1464 // If already seen, record earlier index in remap and free bitmaps. 1465 for i := 0; i < n; i++ { 1466 local := lv.livepointers[i] 1467 arg := lv.argslivepointers[i] 1468 h := hashbitmap(hashbitmap(H0, local), arg) % uint32(tablesize) 1469 1470 for { 1471 j := table[h] 1472 if j < 0 { 1473 break 1474 } 1475 jlocal := lv.livepointers[j] 1476 jarg := lv.argslivepointers[j] 1477 if bveq(local, jlocal) && bveq(arg, jarg) { 1478 remap[i] = j 1479 goto Next 1480 } 1481 1482 h++ 1483 if h == uint32(tablesize) { 1484 h = 0 1485 } 1486 } 1487 1488 table[h] = uniq 1489 remap[i] = uniq 1490 lv.livepointers[uniq] = local 1491 lv.argslivepointers[uniq] = arg 1492 uniq++ 1493 Next: 1494 } 1495 1496 // We've already reordered lv.livepointers[0:uniq] 1497 // and lv.argslivepointers[0:uniq] and freed the bitmaps 1498 // we don't need anymore. Clear the pointers later in the 1499 // array so that we can tell where the coalesced bitmaps stop 1500 // and so that we don't double-free when cleaning up. 1501 for j := uniq; j < n; j++ { 1502 lv.livepointers[j] = bvec{} 1503 lv.argslivepointers[j] = bvec{} 1504 } 1505 1506 // Rewrite PCDATA instructions to use new numbering. 1507 for p := lv.ptxt; p != nil; p = p.Link { 1508 if p.As == obj.APCDATA && p.From.Offset == obj.PCDATA_StackMapIndex { 1509 i := p.To.Offset 1510 if i >= 0 { 1511 p.To.Offset = int64(remap[i]) 1512 } 1513 } 1514 } 1515 } 1516 1517 func printbitset(printed bool, name string, vars []*Node, bits bvec) bool { 1518 started := false 1519 for i, n := range vars { 1520 if bvget(bits, int32(i)) == 0 { 1521 continue 1522 } 1523 if !started { 1524 if !printed { 1525 fmt.Printf("\t") 1526 } else { 1527 fmt.Printf(" ") 1528 } 1529 started = true 1530 printed = true 1531 fmt.Printf("%s=", name) 1532 } else { 1533 fmt.Printf(",") 1534 } 1535 1536 fmt.Printf("%s", n.Sym.Name) 1537 } 1538 1539 return printed 1540 } 1541 1542 // Prints the computed liveness information and inputs, for debugging. 1543 // This format synthesizes the information used during the multiple passes 1544 // into a single presentation. 1545 func livenessprintdebug(lv *Liveness) { 1546 fmt.Printf("liveness: %s\n", Curfn.Func.Nname.Sym.Name) 1547 1548 uevar := bvalloc(int32(len(lv.vars))) 1549 varkill := bvalloc(int32(len(lv.vars))) 1550 avarinit := bvalloc(int32(len(lv.vars))) 1551 1552 pcdata := 0 1553 for i, bb := range lv.cfg { 1554 if i > 0 { 1555 fmt.Printf("\n") 1556 } 1557 1558 // bb#0 pred=1,2 succ=3,4 1559 fmt.Printf("bb#%d pred=", i) 1560 1561 for j := 0; j < len(bb.pred); j++ { 1562 if j > 0 { 1563 fmt.Printf(",") 1564 } 1565 fmt.Printf("%d", (bb.pred[j]).rpo) 1566 } 1567 1568 fmt.Printf(" succ=") 1569 for j := 0; j < len(bb.succ); j++ { 1570 if j > 0 { 1571 fmt.Printf(",") 1572 } 1573 fmt.Printf("%d", (bb.succ[j]).rpo) 1574 } 1575 1576 fmt.Printf("\n") 1577 1578 // initial settings 1579 var printed bool 1580 1581 printed = printbitset(printed, "uevar", lv.vars, bb.uevar) 1582 printed = printbitset(printed, "livein", lv.vars, bb.livein) 1583 if printed { 1584 fmt.Printf("\n") 1585 } 1586 1587 // program listing, with individual effects listed 1588 for p := bb.first; ; p = p.Link { 1589 fmt.Printf("%v\n", p) 1590 if p.As == obj.APCDATA && p.From.Offset == obj.PCDATA_StackMapIndex { 1591 pcdata = int(p.To.Offset) 1592 } 1593 progeffects(p, lv.vars, uevar, varkill, avarinit) 1594 printed = false 1595 printed = printbitset(printed, "uevar", lv.vars, uevar) 1596 printed = printbitset(printed, "varkill", lv.vars, varkill) 1597 printed = printbitset(printed, "avarinit", lv.vars, avarinit) 1598 if printed { 1599 fmt.Printf("\n") 1600 } 1601 if issafepoint(p) { 1602 args := lv.argslivepointers[pcdata] 1603 locals := lv.livepointers[pcdata] 1604 fmt.Printf("\tlive=") 1605 printed = false 1606 for j := 0; j < len(lv.vars); j++ { 1607 n := lv.vars[j] 1608 if islive(n, args, locals) { 1609 if printed { 1610 fmt.Printf(",") 1611 } 1612 fmt.Printf("%v", n) 1613 printed = true 1614 } 1615 } 1616 fmt.Printf("\n") 1617 } 1618 1619 if p == bb.last { 1620 break 1621 } 1622 } 1623 1624 // bb bitsets 1625 fmt.Printf("end\n") 1626 1627 printed = printbitset(printed, "varkill", lv.vars, bb.varkill) 1628 printed = printbitset(printed, "liveout", lv.vars, bb.liveout) 1629 printed = printbitset(printed, "avarinit", lv.vars, bb.avarinit) 1630 printed = printbitset(printed, "avarinitany", lv.vars, bb.avarinitany) 1631 printed = printbitset(printed, "avarinitall", lv.vars, bb.avarinitall) 1632 if printed { 1633 fmt.Printf("\n") 1634 } 1635 } 1636 1637 fmt.Printf("\n") 1638 } 1639 1640 // Dumps a slice of bitmaps to a symbol as a sequence of uint32 values. The 1641 // first word dumped is the total number of bitmaps. The second word is the 1642 // length of the bitmaps. All bitmaps are assumed to be of equal length. The 1643 // words that are followed are the raw bitmap words. 1644 func onebitwritesymbol(arr []bvec, sym *Sym) { 1645 off := 4 // number of bitmaps, to fill in later 1646 off = duint32(sym, off, uint32(arr[0].n)) // number of bits in each bitmap 1647 var i int 1648 for i = 0; i < len(arr); i++ { 1649 // bitmap words 1650 bv := arr[i] 1651 1652 if bv.b == nil { 1653 break 1654 } 1655 for j := 0; int32(j) < bv.n; j += 32 { 1656 word := bv.b[j/32] 1657 1658 // Runtime reads the bitmaps as byte arrays. Oblige. 1659 off = duint8(sym, off, uint8(word)) 1660 1661 off = duint8(sym, off, uint8(word>>8)) 1662 off = duint8(sym, off, uint8(word>>16)) 1663 off = duint8(sym, off, uint8(word>>24)) 1664 } 1665 } 1666 1667 duint32(sym, 0, uint32(i)) // number of bitmaps 1668 ls := Linksym(sym) 1669 ls.Name = fmt.Sprintf("gclocals·%x", md5.Sum(ls.P)) 1670 ls.Dupok = true 1671 sv := obj.SymVer{Name: ls.Name, Version: 0} 1672 ls2, ok := Ctxt.Hash[sv] 1673 if ok { 1674 sym.Lsym = ls2 1675 } else { 1676 Ctxt.Hash[sv] = ls 1677 ggloblsym(sym, int32(off), obj.RODATA) 1678 } 1679 } 1680 1681 func printprog(p *obj.Prog) { 1682 for p != nil { 1683 fmt.Printf("%v\n", p) 1684 p = p.Link 1685 } 1686 } 1687 1688 // Entry pointer for liveness analysis. Constructs a complete CFG, solves for 1689 // the liveness of pointer variables in the function, and emits a runtime data 1690 // structure read by the garbage collector. 1691 func liveness(fn *Node, firstp *obj.Prog, argssym *Sym, livesym *Sym) { 1692 // Change name to dump debugging information only for a specific function. 1693 debugdelta := 0 1694 1695 if Curfn.Func.Nname.Sym.Name == "!" { 1696 debugdelta = 2 1697 } 1698 1699 debuglive += debugdelta 1700 if debuglive >= 3 { 1701 fmt.Printf("liveness: %s\n", Curfn.Func.Nname.Sym.Name) 1702 printprog(firstp) 1703 } 1704 1705 checkptxt(fn, firstp) 1706 1707 // Construct the global liveness state. 1708 cfg := newcfg(firstp) 1709 1710 if debuglive >= 3 { 1711 printcfg(cfg) 1712 } 1713 vars := getvariables(fn) 1714 lv := newliveness(fn, firstp, cfg, vars) 1715 1716 // Run the dataflow framework. 1717 livenessprologue(lv) 1718 1719 if debuglive >= 3 { 1720 livenessprintcfg(lv) 1721 } 1722 livenesssolve(lv) 1723 if debuglive >= 3 { 1724 livenessprintcfg(lv) 1725 } 1726 livenessepilogue(lv) 1727 if debuglive >= 3 { 1728 livenessprintcfg(lv) 1729 } 1730 livenesscompact(lv) 1731 1732 if debuglive >= 2 { 1733 livenessprintdebug(lv) 1734 } 1735 1736 // Emit the live pointer map data structures 1737 onebitwritesymbol(lv.livepointers, livesym) 1738 1739 onebitwritesymbol(lv.argslivepointers, argssym) 1740 1741 // Free everything. 1742 for _, ln := range fn.Func.Dcl { 1743 if ln != nil { 1744 ln.SetOpt(nil) 1745 } 1746 } 1747 1748 freecfg(cfg) 1749 1750 debuglive -= debugdelta 1751 }