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