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