diff options
Diffstat (limited to 'src/cmd/internal/gc/plive.go')
-rw-r--r-- | src/cmd/internal/gc/plive.go | 388 |
1 files changed, 138 insertions, 250 deletions
diff --git a/src/cmd/internal/gc/plive.go b/src/cmd/internal/gc/plive.go index 73f6086c94..99654c5079 100644 --- a/src/cmd/internal/gc/plive.go +++ b/src/cmd/internal/gc/plive.go @@ -61,9 +61,7 @@ type Liveness struct { } func xmalloc(size uint32) interface{} { - var result interface{} - - result = make([]byte, size) + result := (interface{})(make([]byte, size)) if result == nil { Fatal("malloc failed") } @@ -72,12 +70,10 @@ func xmalloc(size uint32) interface{} { // Constructs a new basic block containing a single instruction. func newblock(prog *obj.Prog) *BasicBlock { - var result *BasicBlock - if prog == nil { Fatal("newblock: prog cannot be nil") } - result = new(BasicBlock) + result := new(BasicBlock) result.rpo = -1 result.mark = UNVISITED result.first = prog @@ -111,9 +107,6 @@ func addedge(from *BasicBlock, to *BasicBlock) { // stream. Any control flow, such as branches or fall throughs, that target the // existing instruction are adjusted to target the new instruction. func splicebefore(lv *Liveness, bb *BasicBlock, prev *obj.Prog, curr *obj.Prog) { - var next *obj.Prog - var tmp obj.Prog - // There may be other instructions pointing at curr, // and we want them to now point at prev. Instead of // trying to find all such instructions, swap the contents @@ -121,14 +114,14 @@ func splicebefore(lv *Liveness, bb *BasicBlock, prev *obj.Prog, curr *obj.Prog) // The "opt" field is the backward link in the linked list. // Overwrite curr's data with prev, but keep the list links. - tmp = *curr + tmp := *curr *curr = *prev curr.Opt = tmp.Opt curr.Link = tmp.Link // Overwrite prev (now next) with curr's old data. - next = prev + next := prev *next = tmp next.Opt = nil @@ -151,27 +144,25 @@ func splicebefore(lv *Liveness, bb *BasicBlock, prev *obj.Prog, curr *obj.Prog) // A pretty printer for basic blocks. func printblock(bb *BasicBlock) { var pred *BasicBlock - var succ *BasicBlock - var prog *obj.Prog - var i int fmt.Printf("basic block %d\n", bb.rpo) fmt.Printf("\tpred:") - for i = 0; i < len(bb.pred); i++ { + for i := 0; i < len(bb.pred); i++ { pred = bb.pred[i] fmt.Printf(" %d", pred.rpo) } fmt.Printf("\n") fmt.Printf("\tsucc:") - for i = 0; i < len(bb.succ); i++ { + var succ *BasicBlock + for i := 0; i < len(bb.succ); i++ { succ = bb.succ[i] fmt.Printf(" %d", succ.rpo) } fmt.Printf("\n") fmt.Printf("\tprog:\n") - for prog = bb.first; ; prog = prog.Link { + for prog := bb.first; ; prog = prog.Link { fmt.Printf("\t\t%v\n", prog) if prog == bb.last { break @@ -195,11 +186,8 @@ func blockany(bb *BasicBlock, f func(*obj.Prog) bool) bool { // Collects and returns and array of Node*s for functions arguments and local // variables. func getvariables(fn *Node) []*Node { - var result []*Node - var ll *NodeList - - result = make([]*Node, 0, 0) - for ll = fn.Dcl; ll != nil; ll = ll.Next { + result := make([]*Node, 0, 0) + for ll := fn.Dcl; ll != nil; ll = ll.Next { if ll.N.Op == ONAME { // In order for GODEBUG=gcdead=1 to work, each bitmap needs // to contain information about all variables covered by the bitmap. @@ -244,9 +232,8 @@ func getvariables(fn *Node) []*Node { // A pretty printer for control flow graphs. Takes an array of BasicBlock*s. func printcfg(cfg []*BasicBlock) { var bb *BasicBlock - var i int32 - for i = 0; i < int32(len(cfg)); i++ { + for i := int32(0); i < int32(len(cfg)); i++ { bb = cfg[i] printblock(bb) } @@ -256,10 +243,9 @@ func printcfg(cfg []*BasicBlock) { // standard algorithm. Unconnected blocks will not be affected. func reversepostorder(root *BasicBlock, rpo *int32) { var bb *BasicBlock - var i int root.mark = VISITED - for i = 0; i < len(root.succ); i++ { + for i := 0; i < len(root.succ); i++ { bb = root.succ[i] if bb.mark == UNVISITED { reversepostorder(bb, rpo) @@ -299,8 +285,6 @@ func iscall(prog *obj.Prog, name *obj.LSym) bool { var isselectcommcasecall_names [5]*obj.LSym func isselectcommcasecall(prog *obj.Prog) bool { - var i int32 - if isselectcommcasecall_names[0] == nil { isselectcommcasecall_names[0] = Linksym(Pkglookup("selectsend", Runtimepkg)) isselectcommcasecall_names[1] = Linksym(Pkglookup("selectrecv", Runtimepkg)) @@ -308,7 +292,7 @@ func isselectcommcasecall(prog *obj.Prog) bool { isselectcommcasecall_names[3] = Linksym(Pkglookup("selectdefault", Runtimepkg)) } - for i = 0; isselectcommcasecall_names[i] != nil; i++ { + for i := int32(0); isselectcommcasecall_names[i] != nil; i++ { if iscall(prog, isselectcommcasecall_names[i]) { return true } @@ -352,10 +336,9 @@ func isdeferreturn(prog *obj.Prog) bool { // are implicit successors of the runtime·selectgo call node. The goal of this // analysis is to add these missing edges to complete the control flow graph. func addselectgosucc(selectgo *BasicBlock) { - var pred *BasicBlock var succ *BasicBlock - pred = selectgo + pred := selectgo for { if len(pred.pred) == 0 { Fatal("selectgo does not have a newselect") @@ -392,9 +375,8 @@ func addselectgosucc(selectgo *BasicBlock) { // array of BasicBlock*s containing selectgo calls. func fixselectgo(selectgo []*BasicBlock) { var bb *BasicBlock - var i int32 - for i = 0; i < int32(len(selectgo)); i++ { + for i := int32(0); i < int32(len(selectgo)); i++ { bb = selectgo[i] addselectgosucc(bb) } @@ -406,33 +388,25 @@ func fixselectgo(selectgo []*BasicBlock) { // array of BasicBlock*s in control flow graph form (basic blocks ordered by // their RPO number). func newcfg(firstp *obj.Prog) []*BasicBlock { - var p *obj.Prog - var prev *obj.Prog - var bb *BasicBlock - var cfg []*BasicBlock - var selectgo []*BasicBlock - var i int32 - var rpo int32 - // Reset the opt field of each prog to nil. In the first and second // passes, instructions that are labels temporarily use the opt field to // point to their basic block. In the third pass, the opt field reset // to point to the predecessor of an instruction in its basic block. - for p = firstp; p != nil; p = p.Link { + for p := firstp; p != nil; p = p.Link { p.Opt = nil } // Allocate an array to remember where we have seen selectgo calls. // These blocks will be revisited to add successor control flow edges. - selectgo = make([]*BasicBlock, 0, 0) + selectgo := make([]*BasicBlock, 0, 0) // Loop through all instructions identifying branch targets // and fall-throughs and allocate basic blocks. - cfg = make([]*BasicBlock, 0, 0) + cfg := make([]*BasicBlock, 0, 0) - bb = newblock(firstp) + bb := newblock(firstp) cfg = append(cfg, bb) - for p = firstp; p != nil; p = p.Link { + for p := firstp; p != nil; p = p.Link { if p.To.Type == obj.TYPE_BRANCH { if p.To.U.Branch == nil { Fatal("prog branch to nil") @@ -458,7 +432,8 @@ func newcfg(firstp *obj.Prog) []*BasicBlock { // Loop through all basic blocks maximally growing the list of // contained instructions until a label is reached. Add edges // for branches and fall-through instructions. - for i = 0; i < int32(len(cfg)); i++ { + var p *obj.Prog + for i := int32(0); i < int32(len(cfg)); i++ { bb = cfg[i] for p = bb.last; p != nil; p = p.Link { if p.Opt != nil && p != bb.last { @@ -492,7 +467,8 @@ func newcfg(firstp *obj.Prog) []*BasicBlock { // Add back links so the instructions in a basic block can be traversed // backward. This is the final state of the instruction opt field. - for i = 0; i < int32(len(cfg)); i++ { + var prev *obj.Prog + for i := int32(0); i < int32(len(cfg)); i++ { bb = cfg[i] p = bb.first prev = nil @@ -513,13 +489,13 @@ func newcfg(firstp *obj.Prog) []*BasicBlock { // Find a depth-first order and assign a depth-first number to // all basic blocks. - for i = 0; i < int32(len(cfg)); i++ { + for i := int32(0); i < int32(len(cfg)); i++ { bb = cfg[i] bb.mark = UNVISITED } bb = cfg[0] - rpo = int32(len(cfg)) + rpo := int32(len(cfg)) reversepostorder(bb, &rpo) // Sort the basic blocks by their depth first number. The @@ -544,20 +520,15 @@ func newcfg(firstp *obj.Prog) []*BasicBlock { // Frees a control flow graph (an array of BasicBlock*s) and all of its leaf // data structures. func freecfg(cfg []*BasicBlock) { - var bb *BasicBlock - var bb0 *BasicBlock - var p *obj.Prog - var i int32 - var n int32 - - n = int32(len(cfg)) + n := int32(len(cfg)) if n > 0 { - bb0 = cfg[0] - for p = bb0.first; p != nil; p = p.Link { + bb0 := cfg[0] + for p := bb0.first; p != nil; p = p.Link { p.Opt = nil } - for i = 0; i < n; i++ { + var bb *BasicBlock + for i := int32(0); i < n; i++ { bb = cfg[i] freeblock(bb) } @@ -586,10 +557,6 @@ func isfunny(n *Node) bool { // initialization. func progeffects(prog *obj.Prog, vars []*Node, uevar *Bvec, varkill *Bvec, avarinit *Bvec) { var info ProgInfo - var from *obj.Addr - var to *obj.Addr - var node *Node - var i int32 bvresetall(uevar) bvresetall(varkill) @@ -607,7 +574,8 @@ func progeffects(prog *obj.Prog, vars []*Node, uevar *Bvec, varkill *Bvec, avari // all the parameters for correctness, and similarly it must not // read the out arguments - they won't be set until the new // function runs. - for i = 0; i < int32(len(vars)); i++ { + var node *Node + for i := int32(0); i < int32(len(vars)); i++ { node = vars[i] switch node.Class &^ PHEAP { case PPARAM: @@ -634,7 +602,8 @@ func progeffects(prog *obj.Prog, vars []*Node, uevar *Bvec, varkill *Bvec, avari if prog.As == obj.ATEXT { // A text instruction marks the entry point to a function and // the definition point of all in arguments. - for i = 0; i < int32(len(vars)); i++ { + var node *Node + for i := int32(0); i < int32(len(vars)); i++ { node = vars[i] switch node.Class &^ PHEAP { case PPARAM: @@ -649,7 +618,7 @@ func progeffects(prog *obj.Prog, vars []*Node, uevar *Bvec, varkill *Bvec, avari } if info.Flags&(LeftRead|LeftWrite|LeftAddr) != 0 { - from = &prog.From + from := &prog.From if from.Node != nil && from.Sym != nil && ((from.Node).(*Node)).Curfn == Curfn { switch ((from.Node).(*Node)).Class &^ PHEAP { case PAUTO, @@ -680,7 +649,7 @@ func progeffects(prog *obj.Prog, vars []*Node, uevar *Bvec, varkill *Bvec, avari Next: if info.Flags&(RightRead|RightWrite|RightAddr) != 0 { - to = &prog.To + to := &prog.To if to.Node != nil && to.Sym != nil && ((to.Node).(*Node)).Curfn == Curfn { switch ((to.Node).(*Node)).Class &^ PHEAP { case PAUTO, @@ -729,18 +698,13 @@ Next1: // liveness computation. The cfg argument is an array of BasicBlock*s and the // vars argument is an array of Node*s. func newliveness(fn *Node, ptxt *obj.Prog, cfg []*BasicBlock, vars []*Node) *Liveness { - var result *Liveness - var i int32 - var nblocks int32 - var nvars int32 - - result = new(Liveness) + result := new(Liveness) result.fn = fn result.ptxt = ptxt result.cfg = cfg result.vars = vars - nblocks = int32(len(cfg)) + nblocks := int32(len(cfg)) result.uevar = make([]*Bvec, nblocks) result.varkill = make([]*Bvec, nblocks) result.livein = make([]*Bvec, nblocks) @@ -749,8 +713,8 @@ func newliveness(fn *Node, ptxt *obj.Prog, cfg []*BasicBlock, vars []*Node) *Liv result.avarinitany = make([]*Bvec, nblocks) result.avarinitall = make([]*Bvec, nblocks) - nvars = int32(len(vars)) - for i = 0; i < nblocks; i++ { + nvars := int32(len(vars)) + for i := int32(0); i < nblocks; i++ { result.uevar[i] = bvalloc(nvars) result.varkill[i] = bvalloc(nvars) result.livein[i] = bvalloc(nvars) @@ -767,19 +731,17 @@ func newliveness(fn *Node, ptxt *obj.Prog, cfg []*BasicBlock, vars []*Node) *Liv // Frees the liveness structure and all of its leaf data structures. func freeliveness(lv *Liveness) { - var i int32 - if lv == nil { Fatal("freeliveness: cannot free nil") } - for i = 0; i < int32(len(lv.livepointers)); i++ { + for i := int32(0); i < int32(len(lv.livepointers)); i++ { } - for i = 0; i < int32(len(lv.argslivepointers)); i++ { + for i := int32(0); i < int32(len(lv.argslivepointers)); i++ { } - for i = 0; i < int32(len(lv.cfg)); i++ { + for i := int32(0); i < int32(len(lv.cfg)); i++ { } } @@ -798,14 +760,11 @@ func printeffects(p *obj.Prog, uevar *Bvec, varkill *Bvec, avarinit *Bvec) { // addresses to avoid confusing the C like conventions used in the node variable // names. func printnode(node *Node) { - var p string - var a string - - p = "" + p := "" if haspointers(node.Type) { p = "^" } - a = "" + a := "" if node.Addrtaken != 0 { a = "@" } @@ -814,10 +773,8 @@ func printnode(node *Node) { // Pretty print a list of variables. The vars argument is an array of Node*s. func printvars(name string, bv *Bvec, vars []*Node) { - var i int32 - fmt.Printf("%s:", name) - for i = 0; i < int32(len(vars)); i++ { + for i := int32(0); i < int32(len(vars)); i++ { if bvget(bv, i) != 0 { printnode(vars[i]) } @@ -829,16 +786,11 @@ func printvars(name string, bv *Bvec, vars []*Node) { // analysis. func livenessprintblock(lv *Liveness, bb *BasicBlock) { var pred *BasicBlock - var succ *BasicBlock - var prog *obj.Prog - var live *Bvec - var i int - var pos int32 fmt.Printf("basic block %d\n", bb.rpo) fmt.Printf("\tpred:") - for i = 0; i < len(bb.pred); i++ { + for i := 0; i < len(bb.pred); i++ { pred = bb.pred[i] fmt.Printf(" %d", pred.rpo) } @@ -846,7 +798,8 @@ func livenessprintblock(lv *Liveness, bb *BasicBlock) { fmt.Printf("\n") fmt.Printf("\tsucc:") - for i = 0; i < len(bb.succ); i++ { + var succ *BasicBlock + for i := 0; i < len(bb.succ); i++ { succ = bb.succ[i] fmt.Printf(" %d", succ.rpo) } @@ -862,7 +815,9 @@ func livenessprintblock(lv *Liveness, bb *BasicBlock) { printvars("\tavarinitall", lv.avarinitall[bb.rpo], []*Node(lv.vars)) fmt.Printf("\tprog:\n") - for prog = bb.first; ; prog = prog.Link { + var live *Bvec + var pos int32 + for prog := bb.first; ; prog = prog.Link { fmt.Printf("\t\t%v", prog) if prog.As == obj.APCDATA && prog.From.Offset == obj.PCDATA_StackMapIndex { pos = int32(prog.To.Offset) @@ -882,18 +837,15 @@ func livenessprintblock(lv *Liveness, bb *BasicBlock) { // liveness analysis. func livenessprintcfg(lv *Liveness) { var bb *BasicBlock - var i int32 - for i = 0; i < int32(len(lv.cfg)); i++ { + for i := int32(0); i < int32(len(lv.cfg)); i++ { bb = lv.cfg[i] livenessprintblock(lv, bb) } } func checkauto(fn *Node, p *obj.Prog, n *Node) { - var l *NodeList - - for l = fn.Dcl; l != nil; l = l.Next { + for l := fn.Dcl; l != nil; l = l.Next { if l.N.Op == ONAME && l.N.Class == PAUTO && l.N == n { return } @@ -905,21 +857,19 @@ func checkauto(fn *Node, p *obj.Prog, n *Node) { } fmt.Printf("checkauto %v: %v (%p; class=%d) not found in %v\n", Nconv(Curfn, 0), Nconv(n, 0), n, n.Class, p) - for l = fn.Dcl; l != nil; l = l.Next { + for l := fn.Dcl; l != nil; l = l.Next { fmt.Printf("\t%v (%p; class=%d)\n", Nconv(l.N, 0), l.N, l.N.Class) } Yyerror("checkauto: invariant lost") } func checkparam(fn *Node, p *obj.Prog, n *Node) { - var l *NodeList - var a *Node - var class int - if isfunny(n) { return } - for l = fn.Dcl; l != nil; l = l.Next { + var a *Node + var class int + for l := fn.Dcl; l != nil; l = l.Next { a = l.N class = int(a.Class) &^ PHEAP if a.Op == ONAME && (class == PPARAM || class == PPARAMOUT) && a == n { @@ -928,7 +878,7 @@ func checkparam(fn *Node, p *obj.Prog, n *Node) { } fmt.Printf("checkparam %v: %v (%p; class=%d) not found in %v\n", Nconv(Curfn, 0), Nconv(n, 0), n, n.Class, p) - for l = fn.Dcl; l != nil; l = l.Next { + for l := fn.Dcl; l != nil; l = l.Next { fmt.Printf("\t%v (%p; class=%d)\n", Nconv(l.N, 0), l.N, l.N.Class) } Yyerror("checkparam: invariant lost") @@ -955,13 +905,11 @@ func checkprog(fn *Node, p *obj.Prog) { // nodes and there are special cases to skip over that stuff. The analysis will // fail if this invariant blindly changes. func checkptxt(fn *Node, firstp *obj.Prog) { - var p *obj.Prog - if debuglive == 0 { return } - for p = firstp; p != nil; p = p.Link { + for p := firstp; p != nil; p = p.Link { if false { fmt.Printf("analyzing '%v'\n", p) } @@ -976,11 +924,6 @@ func checkptxt(fn *Node, firstp *obj.Prog) { // the same type t. On https://rsc.googlecode.com/hg/testdata/slow.go, twobitwalktype1 // accounts for 40% of the 6g execution time. func twobitwalktype1(t *Type, xoffset *int64, bv *Bvec) { - var fieldoffset int64 - var i int64 - var o int64 - var t1 *Type - if t.Align > 0 && *xoffset&int64(t.Align-1) != 0 { Fatal("twobitwalktype1: invalid initial alignment, %v", Tconv(t, 0)) } @@ -1002,7 +945,7 @@ func twobitwalktype1(t *Type, xoffset *int64, bv *Bvec) { TFLOAT64, TCOMPLEX64, TCOMPLEX128: - for i = 0; i < t.Width; i++ { + for i := int64(0); i < t.Width; i++ { bvset(bv, int32(((*xoffset+i)/int64(Widthptr))*obj.BitsPerPointer)) // 1 = live scalar (BitsScalar) } @@ -1053,14 +996,15 @@ func twobitwalktype1(t *Type, xoffset *int64, bv *Bvec) { bvset(bv, int32((*xoffset/int64(Widthptr))*obj.BitsPerPointer+1)) // 2 = live ptr in first slot (BitsPointer) *xoffset += t.Width } else { - for i = 0; i < t.Bound; i++ { + for i := int64(0); i < t.Bound; i++ { twobitwalktype1(t.Type, xoffset, bv) } } case TSTRUCT: - o = 0 - for t1 = t.Type; t1 != nil; t1 = t1.Down { + o := int64(0) + var fieldoffset int64 + for t1 := t.Type; t1 != nil; t1 = t1.Down { fieldoffset = t1.Width *xoffset += fieldoffset - o twobitwalktype1(t1.Type, xoffset, bv) @@ -1089,12 +1033,9 @@ func argswords() int32 { // argument is an array of Node*s. func twobitlivepointermap(lv *Liveness, liveout *Bvec, vars []*Node, args *Bvec, locals *Bvec) { var node *Node - var thisargtype *Type - var inargtype *Type var xoffset int64 - var i int32 - for i = 0; ; i++ { + for i := int32(0); ; i++ { i = int32(bvnext(liveout, i)) if i < 0 { break @@ -1116,14 +1057,14 @@ func twobitlivepointermap(lv *Liveness, liveout *Bvec, vars []*Node, args *Bvec, // If the receiver or arguments are unnamed, they will be omitted // from the list above. Preserve those values - even though they are unused - // in order to keep their addresses live for use in stack traces. - thisargtype = getthisx(lv.fn.Type) + thisargtype := getthisx(lv.fn.Type) if thisargtype != nil { xoffset = 0 twobitwalktype1(thisargtype, &xoffset, args) } - inargtype = getinargx(lv.fn.Type) + inargtype := getinargx(lv.fn.Type) if inargtype != nil { xoffset = 0 twobitwalktype1(inargtype, &xoffset, args) @@ -1132,9 +1073,7 @@ func twobitlivepointermap(lv *Liveness, liveout *Bvec, vars []*Node, args *Bvec, // Construct a disembodied instruction. func unlinkedprog(as int) *obj.Prog { - var p *obj.Prog - - p = Ctxt.NewProg() + p := Ctxt.NewProg() Clearp(p) p.As = int16(as) return p @@ -1145,11 +1084,10 @@ func unlinkedprog(as int) *obj.Prog { func newpcdataprog(prog *obj.Prog, index int32) *obj.Prog { var from Node var to Node - var pcdata *obj.Prog Nodconst(&from, Types[TINT32], obj.PCDATA_StackMapIndex) Nodconst(&to, Types[TINT32], int64(index)) - pcdata = unlinkedprog(obj.APCDATA) + pcdata := unlinkedprog(obj.APCDATA) pcdata.Lineno = prog.Lineno Naddr(&from, &pcdata.From, 0) Naddr(&to, &pcdata.To, 0) @@ -1167,18 +1105,13 @@ func issafepoint(prog *obj.Prog) bool { // block func livenessprologue(lv *Liveness) { var bb *BasicBlock - var uevar *Bvec - var varkill *Bvec - var avarinit *Bvec var p *obj.Prog - var i int32 - var nvars int32 - nvars = int32(len(lv.vars)) - uevar = bvalloc(nvars) - varkill = bvalloc(nvars) - avarinit = bvalloc(nvars) - for i = 0; i < int32(len(lv.cfg)); i++ { + nvars := int32(len(lv.vars)) + uevar := bvalloc(nvars) + varkill := bvalloc(nvars) + avarinit := bvalloc(nvars) + for i := int32(0); i < int32(len(lv.cfg)); i++ { bb = lv.cfg[i] // Walk the block instructions backward and update the block @@ -1214,29 +1147,20 @@ func livenessprologue(lv *Liveness) { // Solve the liveness dataflow equations. func livenesssolve(lv *Liveness) { var bb *BasicBlock - var succ *BasicBlock - var pred *BasicBlock - var newlivein *Bvec - var newliveout *Bvec - var any *Bvec - var all *Bvec var rpo int32 - var i int32 - var j int32 - var change int32 // These temporary bitvectors exist to avoid successive allocations and // frees within the loop. - newlivein = bvalloc(int32(len(lv.vars))) + newlivein := bvalloc(int32(len(lv.vars))) - newliveout = bvalloc(int32(len(lv.vars))) - any = bvalloc(int32(len(lv.vars))) - all = bvalloc(int32(len(lv.vars))) + newliveout := bvalloc(int32(len(lv.vars))) + any := bvalloc(int32(len(lv.vars))) + all := bvalloc(int32(len(lv.vars))) // Push avarinitall, avarinitany forward. // avarinitall says the addressed var is initialized along all paths reaching the block exit. // avarinitany says the addressed var is initialized along some path reaching the block exit. - for i = 0; i < int32(len(lv.cfg)); i++ { + for i := int32(0); i < int32(len(lv.cfg)); i++ { bb = lv.cfg[i] rpo = int32(bb.rpo) if i == 0 { @@ -1249,7 +1173,10 @@ func livenesssolve(lv *Liveness) { bvcopy(lv.avarinitany[rpo], lv.avarinit[rpo]) } - change = 1 + change := int32(1) + var j int32 + var i int32 + var pred *BasicBlock for change != 0 { change = 0 for i = 0; i < int32(len(lv.cfg)); i++ { @@ -1289,6 +1216,7 @@ func livenesssolve(lv *Liveness) { // so low that it hardly seems to be worth the complexity. change = 1 + var succ *BasicBlock for change != 0 { change = 0 @@ -1328,19 +1256,17 @@ func livenesssolve(lv *Liveness) { // This function is slow but it is only used for generating debug prints. // Check whether n is marked live in args/locals. func islive(n *Node, args *Bvec, locals *Bvec) bool { - var i int - switch n.Class { case PPARAM, PPARAMOUT: - for i = 0; int64(i) < n.Type.Width/int64(Widthptr)*obj.BitsPerPointer; i++ { + for i := 0; int64(i) < n.Type.Width/int64(Widthptr)*obj.BitsPerPointer; i++ { if bvget(args, int32(n.Xoffset/int64(Widthptr)*obj.BitsPerPointer+int64(i))) != 0 { return true } } case PAUTO: - for i = 0; int64(i) < n.Type.Width/int64(Widthptr)*obj.BitsPerPointer; i++ { + for i := 0; int64(i) < n.Type.Width/int64(Widthptr)*obj.BitsPerPointer; i++ { if bvget(locals, int32((n.Xoffset+stkptrsize)/int64(Widthptr)*obj.BitsPerPointer+int64(i))) != 0 { return true } @@ -1355,44 +1281,28 @@ func islive(n *Node, args *Bvec, locals *Bvec) bool { func livenessepilogue(lv *Liveness) { var bb *BasicBlock var pred *BasicBlock - var ambig *Bvec - var livein *Bvec - var liveout *Bvec - var uevar *Bvec - var varkill *Bvec var args *Bvec var locals *Bvec - var avarinit *Bvec - var any *Bvec - var all *Bvec var n *Node var p *obj.Prog - var next *obj.Prog - var i int32 var j int32 - var numlive int32 - var startmsg int32 - var nmsg int32 - var nvars int32 var pos int32 var xoffset int64 - var msg []string - var fmt_ string - nvars = int32(len(lv.vars)) - livein = bvalloc(nvars) - liveout = bvalloc(nvars) - uevar = bvalloc(nvars) - varkill = bvalloc(nvars) - avarinit = bvalloc(nvars) - any = bvalloc(nvars) - all = bvalloc(nvars) - ambig = bvalloc(localswords() * obj.BitsPerPointer) - msg = nil - nmsg = 0 - startmsg = 0 - - for i = 0; i < int32(len(lv.cfg)); i++ { + nvars := int32(len(lv.vars)) + livein := bvalloc(nvars) + liveout := bvalloc(nvars) + uevar := bvalloc(nvars) + varkill := bvalloc(nvars) + avarinit := bvalloc(nvars) + any := bvalloc(nvars) + all := bvalloc(nvars) + ambig := bvalloc(localswords() * obj.BitsPerPointer) + msg := []string(nil) + nmsg := int32(0) + startmsg := int32(0) + + for i := int32(0); i < int32(len(lv.cfg)); i++ { bb = lv.cfg[i] // Compute avarinitany and avarinitall for entry to block. @@ -1481,7 +1391,10 @@ func livenessepilogue(lv *Liveness) { bb.lastbitmapindex = len(lv.livepointers) - 1 } - for i = 0; i < int32(len(lv.cfg)); i++ { + var fmt_ string + var next *obj.Prog + var numlive int32 + for i := int32(0); i < int32(len(lv.cfg)); i++ { bb = lv.cfg[i] if debuglive >= 1 && Curfn.Nname.Sym.Name != "init" && Curfn.Nname.Sym.Name[0] != '.' { @@ -1627,12 +1540,10 @@ const ( ) func hashbitmap(h uint32, bv *Bvec) uint32 { - var i int - var n int var w uint32 - n = int((bv.n + 31) / 32) - for i = 0; i < n; i++ { + n := int((bv.n + 31) / 32) + for i := 0; i < n; i++ { w = bv.b[i] h = (h * Hp) ^ (w & 0xff) h = (h * Hp) ^ ((w >> 8) & 0xff) @@ -1658,45 +1569,37 @@ func hashbitmap(h uint32, bv *Bvec) uint32 { // PCDATA tables cost about 100k. So for now we keep using a single index for // both bitmap lists. func livenesscompact(lv *Liveness) { - var table []int - var remap []int - var i int - var j int - var n int - var tablesize int - var uniq int - var h uint32 - var local *Bvec - var arg *Bvec - var jlocal *Bvec - var jarg *Bvec - var p *obj.Prog - // Linear probing hash table of bitmaps seen so far. // The hash table has 4n entries to keep the linear // scan short. An entry of -1 indicates an empty slot. - n = len(lv.livepointers) + n := len(lv.livepointers) - tablesize = 4 * n - table = make([]int, tablesize) + tablesize := 4 * n + table := make([]int, tablesize) for i := range table { table[i] = -1 } // remap[i] = the new index of the old bit vector #i. - remap = make([]int, n) + remap := make([]int, n) for i := range remap { remap[i] = -1 } - uniq = 0 // unique tables found so far + uniq := 0 // unique tables found so far // Consider bit vectors in turn. // If new, assign next number using uniq, // record in remap, record in lv->livepointers and lv->argslivepointers // under the new index, and add entry to hash table. // If already seen, record earlier index in remap and free bitmaps. - for i = 0; i < n; i++ { + var jarg *Bvec + var j int + var h uint32 + var arg *Bvec + var jlocal *Bvec + var local *Bvec + for i := 0; i < n; i++ { local = lv.livepointers[i] arg = lv.argslivepointers[i] h = hashbitmap(hashbitmap(H0, local), arg) % uint32(tablesize) @@ -1732,13 +1635,14 @@ func livenesscompact(lv *Liveness) { // we don't need anymore. Clear the pointers later in the // array so that we can tell where the coalesced bitmaps stop // and so that we don't double-free when cleaning up. - for j = uniq; j < n; j++ { + for j := uniq; j < n; j++ { lv.livepointers[j] = nil lv.argslivepointers[j] = nil } // Rewrite PCDATA instructions to use new numbering. - for p = lv.ptxt; p != nil; p = p.Link { + var i int + for p := lv.ptxt; p != nil; p = p.Link { if p.As == obj.APCDATA && p.From.Offset == obj.PCDATA_StackMapIndex { i = int(p.To.Offset) if i >= 0 { @@ -1749,12 +1653,10 @@ func livenesscompact(lv *Liveness) { } func printbitset(printed int, name string, vars []*Node, bits *Bvec) int { - var i int - var started int var n *Node - started = 0 - for i = 0; i < len(vars); i++ { + started := 0 + for i := 0; i < len(vars); i++ { if bvget(bits, int32(i)) == 0 { continue } @@ -1782,27 +1684,22 @@ func printbitset(printed int, name string, vars []*Node, bits *Bvec) int { // This format synthesizes the information used during the multiple passes // into a single presentation. func livenessprintdebug(lv *Liveness) { - var i int var j int - var pcdata int var printed int var bb *BasicBlock var p *obj.Prog - var uevar *Bvec - var varkill *Bvec - var avarinit *Bvec var args *Bvec var locals *Bvec var n *Node fmt.Printf("liveness: %s\n", Curfn.Nname.Sym.Name) - uevar = bvalloc(int32(len(lv.vars))) - varkill = bvalloc(int32(len(lv.vars))) - avarinit = bvalloc(int32(len(lv.vars))) + uevar := bvalloc(int32(len(lv.vars))) + varkill := bvalloc(int32(len(lv.vars))) + avarinit := bvalloc(int32(len(lv.vars))) - pcdata = 0 - for i = 0; i < len(lv.cfg); i++ { + pcdata := 0 + for i := 0; i < len(lv.cfg); i++ { if i > 0 { fmt.Printf("\n") } @@ -1898,17 +1795,14 @@ func livenessprintdebug(lv *Liveness) { // words that are followed are the raw bitmap words. The arr argument is an // array of Node*s. func twobitwritesymbol(arr []*Bvec, sym *Sym) { - var bv *Bvec - var off int var i int var j int - var n int var word uint32 - n = len(arr) - off = 0 + n := len(arr) + off := 0 off += 4 // number of bitmaps, to fill in later - bv = arr[0] + bv := arr[0] off = duint32(sym, off, uint32(bv.n)) // number of bits in each bitmap for i = 0; i < n; i++ { // bitmap words @@ -1944,14 +1838,8 @@ func printprog(p *obj.Prog) { // the liveness of pointer variables in the function, and emits a runtime data // structure read by the garbage collector. func liveness(fn *Node, firstp *obj.Prog, argssym *Sym, livesym *Sym) { - var cfg []*BasicBlock - var vars []*Node - var lv *Liveness - var debugdelta int - var l *NodeList - // Change name to dump debugging information only for a specific function. - debugdelta = 0 + debugdelta := 0 if Curfn.Nname.Sym.Name == "!" { debugdelta = 2 @@ -1966,13 +1854,13 @@ func liveness(fn *Node, firstp *obj.Prog, argssym *Sym, livesym *Sym) { checkptxt(fn, firstp) // Construct the global liveness state. - cfg = newcfg(firstp) + cfg := newcfg(firstp) if debuglive >= 3 { printcfg([]*BasicBlock(cfg)) } - vars = getvariables(fn) - lv = newliveness(fn, firstp, cfg, vars) + vars := getvariables(fn) + lv := newliveness(fn, firstp, cfg, vars) // Run the dataflow framework. livenessprologue(lv) @@ -2000,7 +1888,7 @@ func liveness(fn *Node, firstp *obj.Prog, argssym *Sym, livesym *Sym) { twobitwritesymbol(lv.argslivepointers, argssym) // Free everything. - for l = fn.Dcl; l != nil; l = l.Next { + for l := fn.Dcl; l != nil; l = l.Next { if l.N != nil { l.N.Opt = nil } |