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