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