github.com/slayercat/go@v0.0.0-20170428012452-c51559813f61/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 // 13 // Each level includes the earlier output as well. 14 15 package gc 16 17 import ( 18 "cmd/compile/internal/ssa" 19 "cmd/compile/internal/types" 20 "cmd/internal/obj" 21 "cmd/internal/objabi" 22 "cmd/internal/src" 23 "crypto/md5" 24 "crypto/sha1" 25 "fmt" 26 "os" 27 "strings" 28 ) 29 30 // TODO(mdempsky): Update to reference OpVar{Def,Kill,Live} instead. 31 32 // VARDEF is an annotation for the liveness analysis, marking a place 33 // where a complete initialization (definition) of a variable begins. 34 // Since the liveness analysis can see initialization of single-word 35 // variables quite easy, gvardef is usually only called for multi-word 36 // or 'fat' variables, those satisfying isfat(n->type). 37 // However, gvardef is also called when a non-fat variable is initialized 38 // via a block move; the only time this happens is when you have 39 // return f() 40 // for a function with multiple return values exactly matching the return 41 // types of the current function. 42 // 43 // A 'VARDEF x' annotation in the instruction stream tells the liveness 44 // analysis to behave as though the variable x is being initialized at that 45 // point in the instruction stream. The VARDEF must appear before the 46 // actual (multi-instruction) initialization, and it must also appear after 47 // any uses of the previous value, if any. For example, if compiling: 48 // 49 // x = x[1:] 50 // 51 // it is important to generate code like: 52 // 53 // base, len, cap = pieces of x[1:] 54 // VARDEF x 55 // x = {base, len, cap} 56 // 57 // If instead the generated code looked like: 58 // 59 // VARDEF x 60 // base, len, cap = pieces of x[1:] 61 // x = {base, len, cap} 62 // 63 // then the liveness analysis would decide the previous value of x was 64 // unnecessary even though it is about to be used by the x[1:] computation. 65 // Similarly, if the generated code looked like: 66 // 67 // base, len, cap = pieces of x[1:] 68 // x = {base, len, cap} 69 // VARDEF x 70 // 71 // then the liveness analysis will not preserve the new value of x, because 72 // the VARDEF appears to have "overwritten" it. 73 // 74 // VARDEF is a bit of a kludge to work around the fact that the instruction 75 // stream is working on single-word values but the liveness analysis 76 // wants to work on individual variables, which might be multi-word 77 // aggregates. It might make sense at some point to look into letting 78 // the liveness analysis work on single-word values as well, although 79 // there are complications around interface values, slices, and strings, 80 // all of which cannot be treated as individual words. 81 // 82 // VARKILL is the opposite of VARDEF: it marks a value as no longer needed, 83 // even if its address has been taken. That is, a VARKILL annotation asserts 84 // that its argument is certainly dead, for use when the liveness analysis 85 // would not otherwise be able to deduce that fact. 86 87 // BlockEffects summarizes the liveness effects on an SSA block. 88 type BlockEffects struct { 89 lastbitmapindex int // for livenessepilogue 90 91 // Computed during livenessprologue using only the content of 92 // individual blocks: 93 // 94 // uevar: upward exposed variables (used before set in block) 95 // varkill: killed variables (set in block) 96 // avarinit: addrtaken variables set or used (proof of initialization) 97 uevar bvec 98 varkill bvec 99 avarinit bvec 100 101 // Computed during livenesssolve using control flow information: 102 // 103 // livein: variables live at block entry 104 // liveout: variables live at block exit 105 // avarinitany: addrtaken variables possibly initialized at block exit 106 // (initialized in block or at exit from any predecessor block) 107 // avarinitall: addrtaken variables certainly initialized at block exit 108 // (initialized in block or at exit from all predecessor blocks) 109 livein bvec 110 liveout bvec 111 avarinitany bvec 112 avarinitall bvec 113 } 114 115 // A collection of global state used by liveness analysis. 116 type Liveness struct { 117 fn *Node 118 f *ssa.Func 119 vars []*Node 120 stkptrsize int64 121 122 be []BlockEffects 123 124 // stackMapIndex maps from safe points (i.e., CALLs) to their 125 // index within the stack maps. 126 stackMapIndex map[*ssa.Value]int 127 128 // An array with a bit vector for each safe point tracking live variables. 129 livevars []bvec 130 131 cache progeffectscache 132 } 133 134 type progeffectscache struct { 135 textavarinit []int32 136 retuevar []int32 137 tailuevar []int32 138 initialized bool 139 } 140 141 // livenessShouldTrack reports whether the liveness analysis 142 // should track the variable n. 143 // We don't care about variables that have no pointers, 144 // nor do we care about non-local variables, 145 // nor do we care about empty structs (handled by the pointer check), 146 // nor do we care about the fake PAUTOHEAP variables. 147 func livenessShouldTrack(n *Node) bool { 148 return n.Op == ONAME && (n.Class() == PAUTO || n.Class() == PPARAM || n.Class() == PPARAMOUT) && types.Haspointers(n.Type) 149 } 150 151 // getvariables returns the list of on-stack variables that we need to track. 152 func getvariables(fn *Node) []*Node { 153 var vars []*Node 154 for _, n := range fn.Func.Dcl { 155 if n.Op == ONAME { 156 // The Node.opt field is available for use by optimization passes. 157 // We use it to hold the index of the node in the variables array 158 // (nil means the Node is not in the variables array). 159 // The Node.curfn field is supposed to be set to the current function 160 // already, but for some compiler-introduced names it seems not to be, 161 // so fix that here. 162 // Later, when we want to find the index of a node in the variables list, 163 // we will check that n.Curfn == lv.fn and n.Opt() != nil. Then n.Opt().(int32) 164 // is the index in the variables list. 165 n.SetOpt(nil) 166 n.Name.Curfn = fn 167 } 168 169 if livenessShouldTrack(n) { 170 n.SetOpt(int32(len(vars))) 171 vars = append(vars, n) 172 } 173 } 174 175 return vars 176 } 177 178 func (lv *Liveness) initcache() { 179 if lv.cache.initialized { 180 Fatalf("liveness cache initialized twice") 181 return 182 } 183 lv.cache.initialized = true 184 185 for i, node := range lv.vars { 186 switch node.Class() { 187 case PPARAM: 188 // A return instruction with a p.to is a tail return, which brings 189 // the stack pointer back up (if it ever went down) and then jumps 190 // to a new function entirely. That form of instruction must read 191 // all the parameters for correctness, and similarly it must not 192 // read the out arguments - they won't be set until the new 193 // function runs. 194 195 lv.cache.tailuevar = append(lv.cache.tailuevar, int32(i)) 196 197 if node.Addrtaken() { 198 lv.cache.textavarinit = append(lv.cache.textavarinit, int32(i)) 199 } 200 201 case PPARAMOUT: 202 // If the result had its address taken, it is being tracked 203 // by the avarinit code, which does not use uevar. 204 // If we added it to uevar too, we'd not see any kill 205 // and decide that the variable was live entry, which it is not. 206 // So only use uevar in the non-addrtaken case. 207 // The p.to.type == obj.TYPE_NONE limits the bvset to 208 // non-tail-call return instructions; see note below for details. 209 if !node.Addrtaken() { 210 lv.cache.retuevar = append(lv.cache.retuevar, int32(i)) 211 } 212 } 213 } 214 } 215 216 // A liveEffect is a set of flags that describe an instruction's 217 // liveness effects on a variable. 218 // 219 // The possible flags are: 220 // uevar - used by the instruction 221 // varkill - killed by the instruction 222 // for variables without address taken, means variable was set 223 // for variables with address taken, means variable was marked dead 224 // avarinit - initialized or referred to by the instruction, 225 // only for variables with address taken but not escaping to heap 226 // 227 // The avarinit output serves as a signal that the data has been 228 // initialized, because any use of a variable must come after its 229 // initialization. 230 type liveEffect int 231 232 const ( 233 uevar liveEffect = 1 << iota 234 varkill 235 avarinit 236 ) 237 238 // valueEffects returns the index of a variable in lv.vars and the 239 // liveness effects v has on that variable. 240 // If v does not affect any tracked variables, it returns -1, 0. 241 func (lv *Liveness) valueEffects(v *ssa.Value) (pos int32, effect liveEffect) { 242 n, e := affectedNode(v) 243 if e == 0 { 244 return -1, 0 245 } 246 247 // AllocFrame has dropped unused variables from 248 // lv.fn.Func.Dcl, but they might still be referenced by 249 // OpVarFoo pseudo-ops. Ignore them to prevent "lost track of 250 // variable" ICEs (issue 19632). 251 switch v.Op { 252 case ssa.OpVarDef, ssa.OpVarKill, ssa.OpVarLive, ssa.OpKeepAlive: 253 if !n.Name.Used() { 254 return -1, 0 255 } 256 } 257 258 pos = lv.liveIndex(n) 259 if pos < 0 { 260 return -1, 0 261 } 262 263 if n.Addrtaken() { 264 if v.Op != ssa.OpVarKill { 265 effect |= avarinit 266 } 267 if v.Op == ssa.OpVarDef || v.Op == ssa.OpVarKill { 268 effect |= varkill 269 } 270 } else { 271 // Read is a read, obviously. 272 // Addr by itself is also implicitly a read. 273 // 274 // Addr|Write means that the address is being taken 275 // but only so that the instruction can write to the value. 276 // It is not a read. 277 278 if e&ssa.SymRead != 0 || e&(ssa.SymAddr|ssa.SymWrite) == ssa.SymAddr { 279 effect |= uevar 280 } 281 if e&ssa.SymWrite != 0 && (!isfat(n.Type) || v.Op == ssa.OpVarDef) { 282 effect |= varkill 283 } 284 } 285 286 return 287 } 288 289 // affectedNode returns the *Node affected by v 290 func affectedNode(v *ssa.Value) (*Node, ssa.SymEffect) { 291 // Special cases. 292 switch v.Op { 293 case ssa.OpLoadReg: 294 n, _ := AutoVar(v.Args[0]) 295 return n, ssa.SymRead 296 case ssa.OpStoreReg: 297 n, _ := AutoVar(v) 298 return n, ssa.SymWrite 299 300 case ssa.OpVarLive: 301 return v.Aux.(*Node), ssa.SymRead 302 case ssa.OpVarDef, ssa.OpVarKill: 303 return v.Aux.(*Node), ssa.SymWrite 304 case ssa.OpKeepAlive: 305 n, _ := AutoVar(v.Args[0]) 306 return n, ssa.SymRead 307 } 308 309 e := v.Op.SymEffect() 310 if e == 0 { 311 return nil, 0 312 } 313 314 var n *Node 315 switch a := v.Aux.(type) { 316 case nil, *ssa.ExternSymbol: 317 // ok, but no node 318 case *ssa.ArgSymbol: 319 n = a.Node.(*Node) 320 case *ssa.AutoSymbol: 321 n = a.Node.(*Node) 322 default: 323 Fatalf("weird aux: %s", v.LongString()) 324 } 325 326 return n, e 327 } 328 329 // liveIndex returns the index of n in the set of tracked vars. 330 // If n is not a tracked var, liveIndex returns -1. 331 // If n is not a tracked var but should be tracked, liveIndex crashes. 332 func (lv *Liveness) liveIndex(n *Node) int32 { 333 if n == nil || n.Name.Curfn != lv.fn || !livenessShouldTrack(n) { 334 return -1 335 } 336 337 pos, ok := n.Opt().(int32) // index in vars 338 if !ok { 339 Fatalf("lost track of variable in liveness: %v (%p, %p)", n, n, n.Orig) 340 } 341 if pos >= int32(len(lv.vars)) || lv.vars[pos] != n { 342 Fatalf("bad bookkeeping in liveness: %v (%p, %p)", n, n, n.Orig) 343 } 344 return pos 345 } 346 347 // Constructs a new liveness structure used to hold the global state of the 348 // liveness computation. The cfg argument is a slice of *BasicBlocks and the 349 // vars argument is a slice of *Nodes. 350 func newliveness(fn *Node, f *ssa.Func, vars []*Node, stkptrsize int64) *Liveness { 351 lv := &Liveness{ 352 fn: fn, 353 f: f, 354 vars: vars, 355 stkptrsize: stkptrsize, 356 be: make([]BlockEffects, f.NumBlocks()), 357 } 358 359 nblocks := int32(len(f.Blocks)) 360 nvars := int32(len(vars)) 361 bulk := bvbulkalloc(nvars, nblocks*7) 362 for _, b := range f.Blocks { 363 be := lv.blockEffects(b) 364 365 be.uevar = bulk.next() 366 be.varkill = bulk.next() 367 be.livein = bulk.next() 368 be.liveout = bulk.next() 369 be.avarinit = bulk.next() 370 be.avarinitany = bulk.next() 371 be.avarinitall = bulk.next() 372 } 373 return lv 374 } 375 376 func (lv *Liveness) blockEffects(b *ssa.Block) *BlockEffects { 377 return &lv.be[b.ID] 378 } 379 380 // NOTE: The bitmap for a specific type t should be cached in t after the first run 381 // and then simply copied into bv at the correct offset on future calls with 382 // the same type t. On https://rsc.googlecode.com/hg/testdata/slow.go, onebitwalktype1 383 // accounts for 40% of the 6g execution time. 384 func onebitwalktype1(t *types.Type, xoffset *int64, bv bvec) { 385 if t.Align > 0 && *xoffset&int64(t.Align-1) != 0 { 386 Fatalf("onebitwalktype1: invalid initial alignment, %v", t) 387 } 388 389 switch t.Etype { 390 case TINT8, 391 TUINT8, 392 TINT16, 393 TUINT16, 394 TINT32, 395 TUINT32, 396 TINT64, 397 TUINT64, 398 TINT, 399 TUINT, 400 TUINTPTR, 401 TBOOL, 402 TFLOAT32, 403 TFLOAT64, 404 TCOMPLEX64, 405 TCOMPLEX128: 406 *xoffset += t.Width 407 408 case TPTR32, 409 TPTR64, 410 TUNSAFEPTR, 411 TFUNC, 412 TCHAN, 413 TMAP: 414 if *xoffset&int64(Widthptr-1) != 0 { 415 Fatalf("onebitwalktype1: invalid alignment, %v", t) 416 } 417 bv.Set(int32(*xoffset / int64(Widthptr))) // pointer 418 *xoffset += t.Width 419 420 case TSTRING: 421 // struct { byte *str; intgo len; } 422 if *xoffset&int64(Widthptr-1) != 0 { 423 Fatalf("onebitwalktype1: invalid alignment, %v", t) 424 } 425 bv.Set(int32(*xoffset / int64(Widthptr))) //pointer in first slot 426 *xoffset += t.Width 427 428 case TINTER: 429 // struct { Itab *tab; void *data; } 430 // or, when isnilinter(t)==true: 431 // struct { Type *type; void *data; } 432 if *xoffset&int64(Widthptr-1) != 0 { 433 Fatalf("onebitwalktype1: invalid alignment, %v", t) 434 } 435 bv.Set(int32(*xoffset / int64(Widthptr))) // pointer in first slot 436 bv.Set(int32(*xoffset/int64(Widthptr) + 1)) // pointer in second slot 437 *xoffset += t.Width 438 439 case TSLICE: 440 // struct { byte *array; uintgo len; uintgo cap; } 441 if *xoffset&int64(Widthptr-1) != 0 { 442 Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t) 443 } 444 bv.Set(int32(*xoffset / int64(Widthptr))) // pointer in first slot (BitsPointer) 445 *xoffset += t.Width 446 447 case TARRAY: 448 for i := int64(0); i < t.NumElem(); i++ { 449 onebitwalktype1(t.Elem(), xoffset, bv) 450 } 451 452 case TSTRUCT: 453 var o int64 454 for _, t1 := range t.Fields().Slice() { 455 fieldoffset := t1.Offset 456 *xoffset += fieldoffset - o 457 onebitwalktype1(t1.Type, xoffset, bv) 458 o = fieldoffset + t1.Type.Width 459 } 460 461 *xoffset += t.Width - o 462 463 default: 464 Fatalf("onebitwalktype1: unexpected type, %v", t) 465 } 466 } 467 468 // Returns the number of words of local variables. 469 func localswords(lv *Liveness) int32 { 470 return int32(lv.stkptrsize / int64(Widthptr)) 471 } 472 473 // Returns the number of words of in and out arguments. 474 func argswords(lv *Liveness) int32 { 475 return int32(lv.fn.Type.ArgWidth() / int64(Widthptr)) 476 } 477 478 // Generates live pointer value maps for arguments and local variables. The 479 // this argument and the in arguments are always assumed live. The vars 480 // argument is a slice of *Nodes. 481 func onebitlivepointermap(lv *Liveness, liveout bvec, vars []*Node, args bvec, locals bvec) { 482 var xoffset int64 483 484 for i := int32(0); ; i++ { 485 i = liveout.Next(i) 486 if i < 0 { 487 break 488 } 489 node := vars[i] 490 switch node.Class() { 491 case PAUTO: 492 xoffset = node.Xoffset + lv.stkptrsize 493 onebitwalktype1(node.Type, &xoffset, locals) 494 495 case PPARAM, PPARAMOUT: 496 xoffset = node.Xoffset 497 onebitwalktype1(node.Type, &xoffset, args) 498 } 499 } 500 } 501 502 // Returns true for instructions that are safe points that must be annotated 503 // with liveness information. 504 func issafepoint(v *ssa.Value) bool { 505 return v.Op.IsCall() 506 } 507 508 // Initializes the sets for solving the live variables. Visits all the 509 // instructions in each basic block to summarizes the information at each basic 510 // block 511 func livenessprologue(lv *Liveness) { 512 lv.initcache() 513 514 for _, b := range lv.f.Blocks { 515 be := lv.blockEffects(b) 516 517 // Walk the block instructions backward and update the block 518 // effects with the each prog effects. 519 for j := len(b.Values) - 1; j >= 0; j-- { 520 pos, e := lv.valueEffects(b.Values[j]) 521 if e&varkill != 0 { 522 be.varkill.Set(pos) 523 be.uevar.Unset(pos) 524 } 525 if e&uevar != 0 { 526 be.uevar.Set(pos) 527 } 528 } 529 530 // Walk the block instructions forward to update avarinit bits. 531 // avarinit describes the effect at the end of the block, not the beginning. 532 for j := 0; j < len(b.Values); j++ { 533 pos, e := lv.valueEffects(b.Values[j]) 534 if e&varkill != 0 { 535 be.avarinit.Unset(pos) 536 } 537 if e&avarinit != 0 { 538 be.avarinit.Set(pos) 539 } 540 } 541 } 542 } 543 544 // Solve the liveness dataflow equations. 545 func livenesssolve(lv *Liveness) { 546 // These temporary bitvectors exist to avoid successive allocations and 547 // frees within the loop. 548 newlivein := bvalloc(int32(len(lv.vars))) 549 newliveout := bvalloc(int32(len(lv.vars))) 550 any := bvalloc(int32(len(lv.vars))) 551 all := bvalloc(int32(len(lv.vars))) 552 553 // Push avarinitall, avarinitany forward. 554 // avarinitall says the addressed var is initialized along all paths reaching the block exit. 555 // avarinitany says the addressed var is initialized along some path reaching the block exit. 556 for _, b := range lv.f.Blocks { 557 be := lv.blockEffects(b) 558 if b == lv.f.Entry { 559 be.avarinitall.Copy(be.avarinit) 560 } else { 561 be.avarinitall.Clear() 562 be.avarinitall.Not() 563 } 564 be.avarinitany.Copy(be.avarinit) 565 } 566 567 // Walk blocks in the general direction of propagation (RPO 568 // for avarinit{any,all}, and PO for live{in,out}). This 569 // improves convergence. 570 po := lv.f.Postorder() 571 572 for change := true; change; { 573 change = false 574 for i := len(po) - 1; i >= 0; i-- { 575 b := po[i] 576 be := lv.blockEffects(b) 577 lv.avarinitanyall(b, any, all) 578 579 any.AndNot(any, be.varkill) 580 all.AndNot(all, be.varkill) 581 any.Or(any, be.avarinit) 582 all.Or(all, be.avarinit) 583 if !any.Eq(be.avarinitany) { 584 change = true 585 be.avarinitany.Copy(any) 586 } 587 588 if !all.Eq(be.avarinitall) { 589 change = true 590 be.avarinitall.Copy(all) 591 } 592 } 593 } 594 595 // Iterate through the blocks in reverse round-robin fashion. A work 596 // queue might be slightly faster. As is, the number of iterations is 597 // so low that it hardly seems to be worth the complexity. 598 599 for change := true; change; { 600 change = false 601 for _, b := range po { 602 be := lv.blockEffects(b) 603 604 newliveout.Clear() 605 switch b.Kind { 606 case ssa.BlockRet: 607 for _, pos := range lv.cache.retuevar { 608 newliveout.Set(pos) 609 } 610 case ssa.BlockRetJmp: 611 for _, pos := range lv.cache.tailuevar { 612 newliveout.Set(pos) 613 } 614 case ssa.BlockExit: 615 // nothing to do 616 default: 617 // A variable is live on output from this block 618 // if it is live on input to some successor. 619 // 620 // out[b] = \bigcup_{s \in succ[b]} in[s] 621 newliveout.Copy(lv.blockEffects(b.Succs[0].Block()).livein) 622 for _, succ := range b.Succs[1:] { 623 newliveout.Or(newliveout, lv.blockEffects(succ.Block()).livein) 624 } 625 } 626 627 if !be.liveout.Eq(newliveout) { 628 change = true 629 be.liveout.Copy(newliveout) 630 } 631 632 // A variable is live on input to this block 633 // if it is live on output from this block and 634 // not set by the code in this block. 635 // 636 // in[b] = uevar[b] \cup (out[b] \setminus varkill[b]) 637 newlivein.AndNot(be.liveout, be.varkill) 638 be.livein.Or(newlivein, be.uevar) 639 } 640 } 641 } 642 643 // Visits all instructions in a basic block and computes a bit vector of live 644 // variables at each safe point locations. 645 func livenessepilogue(lv *Liveness) { 646 nvars := int32(len(lv.vars)) 647 liveout := bvalloc(nvars) 648 any := bvalloc(nvars) 649 all := bvalloc(nvars) 650 livedefer := bvalloc(nvars) // always-live variables 651 652 // If there is a defer (that could recover), then all output 653 // parameters are live all the time. In addition, any locals 654 // that are pointers to heap-allocated output parameters are 655 // also always live (post-deferreturn code needs these 656 // pointers to copy values back to the stack). 657 // TODO: if the output parameter is heap-allocated, then we 658 // don't need to keep the stack copy live? 659 if lv.fn.Func.HasDefer() { 660 for i, n := range lv.vars { 661 if n.Class() == PPARAMOUT { 662 if n.IsOutputParamHeapAddr() { 663 // Just to be paranoid. Heap addresses are PAUTOs. 664 Fatalf("variable %v both output param and heap output param", n) 665 } 666 if n.Name.Param.Heapaddr != nil { 667 // If this variable moved to the heap, then 668 // its stack copy is not live. 669 continue 670 } 671 // Note: zeroing is handled by zeroResults in walk.go. 672 livedefer.Set(int32(i)) 673 } 674 if n.IsOutputParamHeapAddr() { 675 n.Name.SetNeedzero(true) 676 livedefer.Set(int32(i)) 677 } 678 } 679 } 680 681 { 682 // Reserve an entry for function entry. 683 live := bvalloc(nvars) 684 for _, pos := range lv.cache.textavarinit { 685 live.Set(pos) 686 } 687 lv.livevars = append(lv.livevars, live) 688 } 689 690 for _, b := range lv.f.Blocks { 691 be := lv.blockEffects(b) 692 693 // Compute avarinitany and avarinitall for entry to block. 694 // This duplicates information known during livenesssolve 695 // but avoids storing two more vectors for each block. 696 lv.avarinitanyall(b, any, all) 697 698 // Walk forward through the basic block instructions and 699 // allocate liveness maps for those instructions that need them. 700 // Seed the maps with information about the addrtaken variables. 701 for _, v := range b.Values { 702 pos, e := lv.valueEffects(v) 703 if e&varkill != 0 { 704 any.Unset(pos) 705 all.Unset(pos) 706 } 707 if e&avarinit != 0 { 708 any.Set(pos) 709 all.Set(pos) 710 } 711 712 if !issafepoint(v) { 713 continue 714 } 715 716 // Annotate ambiguously live variables so that they can 717 // be zeroed at function entry and at VARKILL points. 718 // liveout is dead here and used as a temporary. 719 liveout.AndNot(any, all) 720 if !liveout.IsEmpty() { 721 for pos := int32(0); pos < liveout.n; pos++ { 722 if !liveout.Get(pos) { 723 continue 724 } 725 all.Set(pos) // silence future warnings in this block 726 n := lv.vars[pos] 727 if !n.Name.Needzero() { 728 n.Name.SetNeedzero(true) 729 if debuglive >= 1 { 730 Warnl(v.Pos, "%v: %L is ambiguously live", lv.fn.Func.Nname, n) 731 } 732 } 733 } 734 } 735 736 // Live stuff first. 737 live := bvalloc(nvars) 738 live.Copy(any) 739 lv.livevars = append(lv.livevars, live) 740 } 741 742 be.lastbitmapindex = len(lv.livevars) - 1 743 } 744 745 for _, b := range lv.f.Blocks { 746 be := lv.blockEffects(b) 747 748 // walk backward, emit pcdata and populate the maps 749 index := int32(be.lastbitmapindex) 750 if index < 0 { 751 // the first block we encounter should have the ATEXT so 752 // at no point should pos ever be less than zero. 753 Fatalf("livenessepilogue") 754 } 755 756 liveout.Copy(be.liveout) 757 for i := len(b.Values) - 1; i >= 0; i-- { 758 v := b.Values[i] 759 760 if issafepoint(v) { 761 // Found an interesting instruction, record the 762 // corresponding liveness information. 763 764 live := lv.livevars[index] 765 live.Or(live, liveout) 766 live.Or(live, livedefer) // only for non-entry safe points 767 index-- 768 } 769 770 // Update liveness information. 771 pos, e := lv.valueEffects(v) 772 if e&varkill != 0 { 773 liveout.Unset(pos) 774 } 775 if e&uevar != 0 { 776 liveout.Set(pos) 777 } 778 } 779 780 if b == lv.f.Entry { 781 if index != 0 { 782 Fatalf("bad index for entry point: %v", index) 783 } 784 785 // Record live variables. 786 live := lv.livevars[index] 787 live.Or(live, liveout) 788 } 789 } 790 791 // Useful sanity check: on entry to the function, 792 // the only things that can possibly be live are the 793 // input parameters. 794 for j, n := range lv.vars { 795 if n.Class() != PPARAM && lv.livevars[0].Get(int32(j)) { 796 Fatalf("internal error: %v %L recorded as live on entry", lv.fn.Func.Nname, n) 797 } 798 } 799 } 800 801 func (lv *Liveness) clobber() { 802 // The clobberdead experiment inserts code to clobber all the dead variables (locals and args) 803 // before and after every safepoint. This experiment is useful for debugging the generation 804 // of live pointer bitmaps. 805 if objabi.Clobberdead_enabled == 0 { 806 return 807 } 808 var varSize int64 809 for _, n := range lv.vars { 810 varSize += n.Type.Size() 811 } 812 if len(lv.livevars) > 1000 || varSize > 10000 { 813 // Be careful to avoid doing too much work. 814 // Bail if >1000 safepoints or >10000 bytes of variables. 815 // Otherwise, giant functions make this experiment generate too much code. 816 return 817 } 818 if h := os.Getenv("GOCLOBBERDEADHASH"); h != "" { 819 // Clobber only functions where the hash of the function name matches a pattern. 820 // Useful for binary searching for a miscompiled function. 821 hstr := "" 822 for _, b := range sha1.Sum([]byte(lv.fn.funcname())) { 823 hstr += fmt.Sprintf("%08b", b) 824 } 825 if !strings.HasSuffix(hstr, h) { 826 return 827 } 828 fmt.Printf("\t\t\tCLOBBERDEAD %s\n", lv.fn.funcname()) 829 } 830 if lv.f.Name == "forkAndExecInChild" { 831 // forkAndExecInChild calls vfork (on linux/amd64, anyway). 832 // The code we add here clobbers parts of the stack in the child. 833 // When the parent resumes, it is using the same stack frame. But the 834 // child has clobbered stack variables that the parent needs. Boom! 835 // In particular, the sys argument gets clobbered. 836 // Note to self: GOCLOBBERDEADHASH=011100101110 837 return 838 } 839 840 var oldSched []*ssa.Value 841 for _, b := range lv.f.Blocks { 842 // Copy block's values to a temporary. 843 oldSched = append(oldSched[:0], b.Values...) 844 b.Values = b.Values[:0] 845 846 // Clobber all dead variables at entry. 847 if b == lv.f.Entry { 848 for len(oldSched) > 0 && len(oldSched[0].Args) == 0 { 849 // Skip argless ops. We need to skip at least 850 // the lowered ClosurePtr op, because it 851 // really wants to be first. This will also 852 // skip ops like InitMem and SP, which are ok. 853 b.Values = append(b.Values, oldSched[0]) 854 oldSched = oldSched[1:] 855 } 856 clobber(lv, b, lv.livevars[0]) 857 } 858 859 // Copy values into schedule, adding clobbering around safepoints. 860 for _, v := range oldSched { 861 if !issafepoint(v) { 862 b.Values = append(b.Values, v) 863 continue 864 } 865 before := true 866 if v.Op.IsCall() && v.Aux != nil && v.Aux.(*obj.LSym) == typedmemmove { 867 // Can't put clobber code before the call to typedmemmove. 868 // The variable to-be-copied is marked as dead 869 // at the callsite. That is ok, though, as typedmemmove 870 // is marked as nosplit, and the first thing it does 871 // is to call memmove (also nosplit), after which 872 // the source value is dead. 873 // See issue 16026. 874 before = false 875 } 876 if before { 877 clobber(lv, b, lv.livevars[lv.stackMapIndex[v]]) 878 } 879 b.Values = append(b.Values, v) 880 clobber(lv, b, lv.livevars[lv.stackMapIndex[v]]) 881 } 882 } 883 } 884 885 // clobber generates code to clobber all dead variables (those not marked in live). 886 // Clobbering instructions are added to the end of b.Values. 887 func clobber(lv *Liveness, b *ssa.Block, live bvec) { 888 for i, n := range lv.vars { 889 if !live.Get(int32(i)) { 890 clobberVar(b, n) 891 } 892 } 893 } 894 895 // clobberVar generates code to trash the pointers in v. 896 // Clobbering instructions are added to the end of b.Values. 897 func clobberVar(b *ssa.Block, v *Node) { 898 clobberWalk(b, v, 0, v.Type) 899 } 900 901 // b = block to which we append instructions 902 // v = variable 903 // offset = offset of (sub-portion of) variable to clobber (in bytes) 904 // t = type of sub-portion of v. 905 func clobberWalk(b *ssa.Block, v *Node, offset int64, t *types.Type) { 906 if !types.Haspointers(t) { 907 return 908 } 909 switch t.Etype { 910 case TPTR32, 911 TPTR64, 912 TUNSAFEPTR, 913 TFUNC, 914 TCHAN, 915 TMAP: 916 clobberPtr(b, v, offset) 917 918 case TSTRING: 919 // struct { byte *str; int len; } 920 clobberPtr(b, v, offset) 921 922 case TINTER: 923 // struct { Itab *tab; void *data; } 924 // or, when isnilinter(t)==true: 925 // struct { Type *type; void *data; } 926 clobberPtr(b, v, offset) 927 clobberPtr(b, v, offset+int64(Widthptr)) 928 929 case TSLICE: 930 // struct { byte *array; int len; int cap; } 931 clobberPtr(b, v, offset) 932 933 case TARRAY: 934 for i := int64(0); i < t.NumElem(); i++ { 935 clobberWalk(b, v, offset+i*t.Elem().Size(), t.Elem()) 936 } 937 938 case TSTRUCT: 939 for _, t1 := range t.Fields().Slice() { 940 clobberWalk(b, v, offset+t1.Offset, t1.Type) 941 } 942 943 default: 944 Fatalf("clobberWalk: unexpected type, %v", t) 945 } 946 } 947 948 // clobberPtr generates a clobber of the pointer at offset offset in v. 949 // The clobber instruction is added at the end of b. 950 func clobberPtr(b *ssa.Block, v *Node, offset int64) { 951 var aux interface{} 952 if v.Class() == PAUTO { 953 aux = &ssa.AutoSymbol{Node: v} 954 } else { 955 aux = &ssa.ArgSymbol{Node: v} 956 } 957 b.NewValue0IA(src.NoXPos, ssa.OpClobber, ssa.TypeVoid, offset, aux) 958 } 959 960 func (lv *Liveness) avarinitanyall(b *ssa.Block, any, all bvec) { 961 if len(b.Preds) == 0 { 962 any.Clear() 963 all.Clear() 964 for _, pos := range lv.cache.textavarinit { 965 any.Set(pos) 966 all.Set(pos) 967 } 968 return 969 } 970 971 be := lv.blockEffects(b.Preds[0].Block()) 972 any.Copy(be.avarinitany) 973 all.Copy(be.avarinitall) 974 975 for _, pred := range b.Preds[1:] { 976 be := lv.blockEffects(pred.Block()) 977 any.Or(any, be.avarinitany) 978 all.And(all, be.avarinitall) 979 } 980 } 981 982 // FNV-1 hash function constants. 983 const ( 984 H0 = 2166136261 985 Hp = 16777619 986 ) 987 988 func hashbitmap(h uint32, bv bvec) uint32 { 989 n := int((bv.n + 31) / 32) 990 for i := 0; i < n; i++ { 991 w := bv.b[i] 992 h = (h * Hp) ^ (w & 0xff) 993 h = (h * Hp) ^ ((w >> 8) & 0xff) 994 h = (h * Hp) ^ ((w >> 16) & 0xff) 995 h = (h * Hp) ^ ((w >> 24) & 0xff) 996 } 997 998 return h 999 } 1000 1001 // Compact liveness information by coalescing identical per-call-site bitmaps. 1002 // The merging only happens for a single function, not across the entire binary. 1003 // 1004 // There are actually two lists of bitmaps, one list for the local variables and one 1005 // list for the function arguments. Both lists are indexed by the same PCDATA 1006 // index, so the corresponding pairs must be considered together when 1007 // merging duplicates. The argument bitmaps change much less often during 1008 // function execution than the local variable bitmaps, so it is possible that 1009 // we could introduce a separate PCDATA index for arguments vs locals and 1010 // then compact the set of argument bitmaps separately from the set of 1011 // local variable bitmaps. As of 2014-04-02, doing this to the godoc binary 1012 // is actually a net loss: we save about 50k of argument bitmaps but the new 1013 // PCDATA tables cost about 100k. So for now we keep using a single index for 1014 // both bitmap lists. 1015 func livenesscompact(lv *Liveness) { 1016 // Linear probing hash table of bitmaps seen so far. 1017 // The hash table has 4n entries to keep the linear 1018 // scan short. An entry of -1 indicates an empty slot. 1019 n := len(lv.livevars) 1020 1021 tablesize := 4 * n 1022 table := make([]int, tablesize) 1023 for i := range table { 1024 table[i] = -1 1025 } 1026 1027 // remap[i] = the new index of the old bit vector #i. 1028 remap := make([]int, n) 1029 for i := range remap { 1030 remap[i] = -1 1031 } 1032 uniq := 0 // unique tables found so far 1033 1034 // Consider bit vectors in turn. 1035 // If new, assign next number using uniq, 1036 // record in remap, record in lv.livevars 1037 // under the new index, and add entry to hash table. 1038 // If already seen, record earlier index in remap. 1039 Outer: 1040 for i, live := range lv.livevars { 1041 h := hashbitmap(H0, live) % uint32(tablesize) 1042 1043 for { 1044 j := table[h] 1045 if j < 0 { 1046 break 1047 } 1048 jlive := lv.livevars[j] 1049 if live.Eq(jlive) { 1050 remap[i] = j 1051 continue Outer 1052 } 1053 1054 h++ 1055 if h == uint32(tablesize) { 1056 h = 0 1057 } 1058 } 1059 1060 table[h] = uniq 1061 remap[i] = uniq 1062 lv.livevars[uniq] = live 1063 uniq++ 1064 } 1065 1066 // We've already reordered lv.livevars[0:uniq]. Clear the 1067 // pointers later in the array so they can be GC'd. 1068 tail := lv.livevars[uniq:] 1069 for i := range tail { // memclr loop pattern 1070 tail[i] = bvec{} 1071 } 1072 lv.livevars = lv.livevars[:uniq] 1073 1074 // Rewrite PCDATA instructions to use new numbering. 1075 lv.showlive(nil, lv.livevars[0]) 1076 pos := 1 1077 lv.stackMapIndex = make(map[*ssa.Value]int) 1078 for _, b := range lv.f.Blocks { 1079 for _, v := range b.Values { 1080 if issafepoint(v) { 1081 lv.showlive(v, lv.livevars[remap[pos]]) 1082 lv.stackMapIndex[v] = int(remap[pos]) 1083 pos++ 1084 } 1085 } 1086 } 1087 } 1088 1089 func (lv *Liveness) showlive(v *ssa.Value, live bvec) { 1090 if debuglive == 0 || lv.fn.funcname() == "init" || strings.HasPrefix(lv.fn.funcname(), ".") { 1091 return 1092 } 1093 if live.IsEmpty() { 1094 return 1095 } 1096 1097 pos := lv.fn.Func.Nname.Pos 1098 if v != nil { 1099 pos = v.Pos 1100 } 1101 1102 s := "live at " 1103 if v == nil { 1104 s += fmt.Sprintf("entry to %s:", lv.fn.funcname()) 1105 } else if sym, ok := v.Aux.(*obj.LSym); ok { 1106 fn := sym.Name 1107 if pos := strings.Index(fn, "."); pos >= 0 { 1108 fn = fn[pos+1:] 1109 } 1110 s += fmt.Sprintf("call to %s:", fn) 1111 } else { 1112 s += "indirect call:" 1113 } 1114 1115 for j, n := range lv.vars { 1116 if live.Get(int32(j)) { 1117 s += fmt.Sprintf(" %v", n) 1118 } 1119 } 1120 1121 Warnl(pos, s) 1122 } 1123 1124 func (lv *Liveness) printbvec(printed bool, name string, live bvec) bool { 1125 started := false 1126 for i, n := range lv.vars { 1127 if !live.Get(int32(i)) { 1128 continue 1129 } 1130 if !started { 1131 if !printed { 1132 fmt.Printf("\t") 1133 } else { 1134 fmt.Printf(" ") 1135 } 1136 started = true 1137 printed = true 1138 fmt.Printf("%s=", name) 1139 } else { 1140 fmt.Printf(",") 1141 } 1142 1143 fmt.Printf("%s", n.Sym.Name) 1144 } 1145 return printed 1146 } 1147 1148 // printeffect is like printbvec, but for a single variable. 1149 func (lv *Liveness) printeffect(printed bool, name string, pos int32, x bool) bool { 1150 if !x { 1151 return printed 1152 } 1153 if !printed { 1154 fmt.Printf("\t") 1155 } else { 1156 fmt.Printf(" ") 1157 } 1158 fmt.Printf("%s=%s", name, lv.vars[pos].Sym.Name) 1159 return true 1160 } 1161 1162 // Prints the computed liveness information and inputs, for debugging. 1163 // This format synthesizes the information used during the multiple passes 1164 // into a single presentation. 1165 func livenessprintdebug(lv *Liveness) { 1166 fmt.Printf("liveness: %s\n", lv.fn.funcname()) 1167 1168 pcdata := 0 1169 for i, b := range lv.f.Blocks { 1170 if i > 0 { 1171 fmt.Printf("\n") 1172 } 1173 1174 // bb#0 pred=1,2 succ=3,4 1175 fmt.Printf("bb#%d pred=", b.ID) 1176 for j, pred := range b.Preds { 1177 if j > 0 { 1178 fmt.Printf(",") 1179 } 1180 fmt.Printf("%d", pred.Block().ID) 1181 } 1182 fmt.Printf(" succ=") 1183 for j, succ := range b.Succs { 1184 if j > 0 { 1185 fmt.Printf(",") 1186 } 1187 fmt.Printf("%d", succ.Block().ID) 1188 } 1189 fmt.Printf("\n") 1190 1191 be := lv.blockEffects(b) 1192 1193 // initial settings 1194 printed := false 1195 printed = lv.printbvec(printed, "uevar", be.uevar) 1196 printed = lv.printbvec(printed, "livein", be.livein) 1197 if printed { 1198 fmt.Printf("\n") 1199 } 1200 1201 // program listing, with individual effects listed 1202 1203 if b == lv.f.Entry { 1204 live := lv.livevars[pcdata] 1205 fmt.Printf("(%s) function entry\n", linestr(lv.fn.Func.Nname.Pos)) 1206 fmt.Printf("\tlive=") 1207 printed = false 1208 for j, n := range lv.vars { 1209 if !live.Get(int32(j)) { 1210 continue 1211 } 1212 if printed { 1213 fmt.Printf(",") 1214 } 1215 fmt.Printf("%v", n) 1216 printed = true 1217 } 1218 fmt.Printf("\n") 1219 } 1220 1221 for _, v := range b.Values { 1222 fmt.Printf("(%s) %v\n", linestr(v.Pos), v.LongString()) 1223 1224 if pos, ok := lv.stackMapIndex[v]; ok { 1225 pcdata = pos 1226 } 1227 1228 pos, effect := lv.valueEffects(v) 1229 printed = false 1230 printed = lv.printeffect(printed, "uevar", pos, effect&uevar != 0) 1231 printed = lv.printeffect(printed, "varkill", pos, effect&varkill != 0) 1232 printed = lv.printeffect(printed, "avarinit", pos, effect&avarinit != 0) 1233 if printed { 1234 fmt.Printf("\n") 1235 } 1236 1237 if !issafepoint(v) { 1238 continue 1239 } 1240 1241 live := lv.livevars[pcdata] 1242 fmt.Printf("\tlive=") 1243 printed = false 1244 for j, n := range lv.vars { 1245 if !live.Get(int32(j)) { 1246 continue 1247 } 1248 if printed { 1249 fmt.Printf(",") 1250 } 1251 fmt.Printf("%v", n) 1252 printed = true 1253 } 1254 fmt.Printf("\n") 1255 } 1256 1257 // bb bitsets 1258 fmt.Printf("end\n") 1259 printed = false 1260 printed = lv.printbvec(printed, "varkill", be.varkill) 1261 printed = lv.printbvec(printed, "liveout", be.liveout) 1262 printed = lv.printbvec(printed, "avarinit", be.avarinit) 1263 printed = lv.printbvec(printed, "avarinitany", be.avarinitany) 1264 printed = lv.printbvec(printed, "avarinitall", be.avarinitall) 1265 if printed { 1266 fmt.Printf("\n") 1267 } 1268 } 1269 1270 fmt.Printf("\n") 1271 } 1272 1273 // Dumps a slice of bitmaps to a symbol as a sequence of uint32 values. The 1274 // first word dumped is the total number of bitmaps. The second word is the 1275 // length of the bitmaps. All bitmaps are assumed to be of equal length. The 1276 // remaining bytes are the raw bitmaps. 1277 func livenessemit(lv *Liveness, argssym, livesym *obj.LSym) { 1278 args := bvalloc(argswords(lv)) 1279 aoff := duint32(argssym, 0, uint32(len(lv.livevars))) // number of bitmaps 1280 aoff = duint32(argssym, aoff, uint32(args.n)) // number of bits in each bitmap 1281 1282 locals := bvalloc(localswords(lv)) 1283 loff := duint32(livesym, 0, uint32(len(lv.livevars))) // number of bitmaps 1284 loff = duint32(livesym, loff, uint32(locals.n)) // number of bits in each bitmap 1285 1286 for _, live := range lv.livevars { 1287 args.Clear() 1288 locals.Clear() 1289 1290 onebitlivepointermap(lv, live, lv.vars, args, locals) 1291 1292 aoff = dbvec(argssym, aoff, args) 1293 loff = dbvec(livesym, loff, locals) 1294 } 1295 1296 // Give these LSyms content-addressable names, 1297 // so that they can be de-duplicated. 1298 // This provides significant binary size savings. 1299 // It is safe to rename these LSyms because 1300 // they are tracked separately from ctxt.hash. 1301 argssym.Name = fmt.Sprintf("gclocals·%x", md5.Sum(argssym.P)) 1302 livesym.Name = fmt.Sprintf("gclocals·%x", md5.Sum(livesym.P)) 1303 } 1304 1305 // Entry pointer for liveness analysis. Solves for the liveness of 1306 // pointer variables in the function and emits a runtime data 1307 // structure read by the garbage collector. 1308 // Returns a map from GC safe points to their corresponding stack map index. 1309 func liveness(e *ssafn, f *ssa.Func) map[*ssa.Value]int { 1310 // Construct the global liveness state. 1311 vars := getvariables(e.curfn) 1312 lv := newliveness(e.curfn, f, vars, e.stkptrsize) 1313 1314 // Run the dataflow framework. 1315 livenessprologue(lv) 1316 livenesssolve(lv) 1317 livenessepilogue(lv) 1318 livenesscompact(lv) 1319 lv.clobber() 1320 if debuglive >= 2 { 1321 livenessprintdebug(lv) 1322 } 1323 1324 // Emit the live pointer map data structures 1325 if ls := e.curfn.Func.lsym; ls != nil { 1326 livenessemit(lv, &ls.Func.GCArgs, &ls.Func.GCLocals) 1327 } 1328 return lv.stackMapIndex 1329 }