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  }