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