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