]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: flatten dependency graph [generated]
authorMatthew Dempsky <mdempsky@google.com>
Sun, 27 Dec 2020 07:46:36 +0000 (23:46 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Mon, 28 Dec 2020 08:06:26 +0000 (08:06 +0000)
This CL shuffles a couple functions around to help flatten the package
dependency graph somewhat:

1. ssa.LosesStmtMark is only ever used in associated with an
objw.Prog, so we might as well move it to that package. This removes a
dependency from objw (a relatively low-level utility package that
wraps cmd/internal/obj) on ssa (a large and relatively high-level
package).

2. Moves liveness.SetTypeBits into a new package typebits. A
single-function package is a bit on the silly side, but reflectdata
shouldn't need to depend on liveness (nor vice versa).

[git-generate]
cd src/cmd/compile/internal/ssa
rf '
mv LosesStmtMark prog.go
mv prog.go cmd/compile/internal/objw
'

cd ../liveness
rf '
mv SetTypeBits Set
mv Set typebits.go
rm typebits.go:/Copyright/+4,/^package/-0
mv typebits.go cmd/compile/internal/typebits
'

Change-Id: Ic9a983f0ad6c0cf1a537f99889699a8444699e6e
Reviewed-on: https://go-review.googlesource.com/c/go/+/280447
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
src/cmd/compile/internal/liveness/plive.go
src/cmd/compile/internal/objw/prog.go
src/cmd/compile/internal/reflectdata/reflect.go
src/cmd/compile/internal/ssa/numberlines.go
src/cmd/compile/internal/ssagen/ssa.go
src/cmd/compile/internal/typebits/typebits.go [new file with mode: 0644]

index cf4debb7959668e8a9b8eaf70fae0c61e70cfef5..89c70df65a4900104957709c6cfede1b74d1ed3a 100644 (file)
@@ -24,6 +24,7 @@ import (
        "cmd/compile/internal/ir"
        "cmd/compile/internal/objw"
        "cmd/compile/internal/ssa"
+       "cmd/compile/internal/typebits"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/objabi"
@@ -375,82 +376,6 @@ func (lv *liveness) blockEffects(b *ssa.Block) *blockEffects {
        return &lv.be[b.ID]
 }
 
-// NOTE: The bitmap for a specific type t could be cached in t after
-// the first run and then simply copied into bv at the correct offset
-// on future calls with the same type t.
-func SetTypeBits(t *types.Type, off int64, bv bitvec.BitVec) {
-       if t.Align > 0 && off&int64(t.Align-1) != 0 {
-               base.Fatalf("onebitwalktype1: invalid initial alignment: type %v has alignment %d, but offset is %v", t, t.Align, off)
-       }
-       if !t.HasPointers() {
-               // Note: this case ensures that pointers to go:notinheap types
-               // are not considered pointers by garbage collection and stack copying.
-               return
-       }
-
-       switch t.Kind() {
-       case types.TPTR, types.TUNSAFEPTR, types.TFUNC, types.TCHAN, types.TMAP:
-               if off&int64(types.PtrSize-1) != 0 {
-                       base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
-               }
-               bv.Set(int32(off / int64(types.PtrSize))) // pointer
-
-       case types.TSTRING:
-               // struct { byte *str; intgo len; }
-               if off&int64(types.PtrSize-1) != 0 {
-                       base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
-               }
-               bv.Set(int32(off / int64(types.PtrSize))) //pointer in first slot
-
-       case types.TINTER:
-               // struct { Itab *tab;  void *data; }
-               // or, when isnilinter(t)==true:
-               // struct { Type *type; void *data; }
-               if off&int64(types.PtrSize-1) != 0 {
-                       base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
-               }
-               // The first word of an interface is a pointer, but we don't
-               // treat it as such.
-               // 1. If it is a non-empty interface, the pointer points to an itab
-               //    which is always in persistentalloc space.
-               // 2. If it is an empty interface, the pointer points to a _type.
-               //   a. If it is a compile-time-allocated type, it points into
-               //      the read-only data section.
-               //   b. If it is a reflect-allocated type, it points into the Go heap.
-               //      Reflect is responsible for keeping a reference to
-               //      the underlying type so it won't be GCd.
-               // If we ever have a moving GC, we need to change this for 2b (as
-               // well as scan itabs to update their itab._type fields).
-               bv.Set(int32(off/int64(types.PtrSize) + 1)) // pointer in second slot
-
-       case types.TSLICE:
-               // struct { byte *array; uintgo len; uintgo cap; }
-               if off&int64(types.PtrSize-1) != 0 {
-                       base.Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t)
-               }
-               bv.Set(int32(off / int64(types.PtrSize))) // pointer in first slot (BitsPointer)
-
-       case types.TARRAY:
-               elt := t.Elem()
-               if elt.Width == 0 {
-                       // Short-circuit for #20739.
-                       break
-               }
-               for i := int64(0); i < t.NumElem(); i++ {
-                       SetTypeBits(elt, off, bv)
-                       off += elt.Width
-               }
-
-       case types.TSTRUCT:
-               for _, f := range t.Fields().Slice() {
-                       SetTypeBits(f.Type, off+f.Offset, bv)
-               }
-
-       default:
-               base.Fatalf("onebitwalktype1: unexpected type, %v", t)
-       }
-}
-
 // Generates live pointer value maps for arguments and local variables. The
 // this argument and the in arguments are always assumed live. The vars
 // argument is a slice of *Nodes.
@@ -463,10 +388,10 @@ func (lv *liveness) pointerMap(liveout bitvec.BitVec, vars []*ir.Name, args, loc
                node := vars[i]
                switch node.Class_ {
                case ir.PAUTO:
-                       SetTypeBits(node.Type(), node.FrameOffset()+lv.stkptrsize, locals)
+                       typebits.Set(node.Type(), node.FrameOffset()+lv.stkptrsize, locals)
 
                case ir.PPARAM, ir.PPARAMOUT:
-                       SetTypeBits(node.Type(), node.FrameOffset(), args)
+                       typebits.Set(node.Type(), node.FrameOffset(), args)
                }
        }
 }
@@ -1309,15 +1234,15 @@ func WriteFuncMap(fn *ir.Func) {
        off = objw.Uint32(lsym, off, uint32(bv.N))
 
        if ir.IsMethod(fn) {
-               SetTypeBits(fn.Type().Recvs(), 0, bv)
+               typebits.Set(fn.Type().Recvs(), 0, bv)
        }
        if fn.Type().NumParams() > 0 {
-               SetTypeBits(fn.Type().Params(), 0, bv)
+               typebits.Set(fn.Type().Params(), 0, bv)
        }
        off = objw.BitVec(lsym, off, bv)
 
        if fn.Type().NumResults() > 0 {
-               SetTypeBits(fn.Type().Results(), 0, bv)
+               typebits.Set(fn.Type().Results(), 0, bv)
                off = objw.BitVec(lsym, off, bv)
        }
 
index 54028e47fd23ca80f95ca163e3db26630390642c..8d24f94aa56602eb0d27d7bda97412b8500b646c 100644 (file)
@@ -33,7 +33,6 @@ package objw
 import (
        "cmd/compile/internal/base"
        "cmd/compile/internal/ir"
-       "cmd/compile/internal/ssa"
        "cmd/internal/obj"
        "cmd/internal/objabi"
        "cmd/internal/src"
@@ -173,7 +172,7 @@ func (pp *Progs) Prog(as obj.As) *obj.Prog {
        p.Pos = pp.Pos
        if pp.Pos.IsStmt() == src.PosIsStmt {
                // Clear IsStmt for later Progs at this pos provided that as can be marked as a stmt
-               if ssa.LosesStmtMark(as) {
+               if LosesStmtMark(as) {
                        return p
                }
                pp.Pos = pp.Pos.WithNotStmt()
@@ -216,3 +215,12 @@ func (pp *Progs) SetText(fn *ir.Func) {
        ptxt.From.Name = obj.NAME_EXTERN
        ptxt.From.Sym = fn.LSym
 }
+
+// LosesStmtMark reports whether a prog with op as loses its statement mark on the way to DWARF.
+// The attributes from some opcodes are lost in translation.
+// TODO: this is an artifact of how funcpctab combines information for instructions at a single PC.
+// Should try to fix it there.
+func LosesStmtMark(as obj.As) bool {
+       // is_stmt does not work for these; it DOES for ANOP even though that generates no code.
+       return as == obj.APCDATA || as == obj.AFUNCDATA
+}
index 7c424218962b66fcea07e5ad7f0fabcb43260a3e..df80380fc1311d4b3aaa05057ddadd02f419858a 100644 (file)
@@ -16,8 +16,8 @@ import (
        "cmd/compile/internal/escape"
        "cmd/compile/internal/inline"
        "cmd/compile/internal/ir"
-       "cmd/compile/internal/liveness"
        "cmd/compile/internal/objw"
+       "cmd/compile/internal/typebits"
        "cmd/compile/internal/typecheck"
        "cmd/compile/internal/types"
        "cmd/internal/gcprog"
@@ -1552,7 +1552,7 @@ func fillptrmask(t *types.Type, ptrmask []byte) {
        }
 
        vec := bitvec.New(8 * int32(len(ptrmask)))
-       liveness.SetTypeBits(t, 0, vec)
+       typebits.Set(t, 0, vec)
 
        nptr := types.PtrDataSize(t) / int64(types.PtrSize)
        for i := int64(0); i < nptr; i++ {
index f4e62b88c4f6b64ab6665914c570973222e12182..2a9c8e4f326fce9bf99fde33acb731f00b83fada 100644 (file)
@@ -5,7 +5,6 @@
 package ssa
 
 import (
-       "cmd/internal/obj"
        "cmd/internal/src"
        "fmt"
        "sort"
@@ -23,15 +22,6 @@ func isPoorStatementOp(op Op) bool {
        return false
 }
 
-// LosesStmtMark reports whether a prog with op as loses its statement mark on the way to DWARF.
-// The attributes from some opcodes are lost in translation.
-// TODO: this is an artifact of how funcpctab combines information for instructions at a single PC.
-// Should try to fix it there.
-func LosesStmtMark(as obj.As) bool {
-       // is_stmt does not work for these; it DOES for ANOP even though that generates no code.
-       return as == obj.APCDATA || as == obj.AFUNCDATA
-}
-
 // nextGoodStatementIndex returns an index at i or later that is believed
 // to be a good place to start the statement for b.  This decision is
 // based on v's Op, the possibility of a better later operation, and
index 082cb7c3210ae99905bb6a65d529341fff9726a0..0da6ab3272aec645e45e42ae8f4f7658b2e9e607 100644 (file)
@@ -6277,7 +6277,7 @@ type State struct {
 // Prog appends a new Prog.
 func (s *State) Prog(as obj.As) *obj.Prog {
        p := s.pp.Prog(as)
-       if ssa.LosesStmtMark(as) {
+       if objw.LosesStmtMark(as) {
                return p
        }
        // Float a statement start to the beginning of any same-line run.
diff --git a/src/cmd/compile/internal/typebits/typebits.go b/src/cmd/compile/internal/typebits/typebits.go
new file mode 100644 (file)
index 0000000..63a2bb3
--- /dev/null
@@ -0,0 +1,87 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typebits
+
+import (
+       "cmd/compile/internal/base"
+       "cmd/compile/internal/bitvec"
+       "cmd/compile/internal/types"
+)
+
+// NOTE: The bitmap for a specific type t could be cached in t after
+// the first run and then simply copied into bv at the correct offset
+// on future calls with the same type t.
+func Set(t *types.Type, off int64, bv bitvec.BitVec) {
+       if t.Align > 0 && off&int64(t.Align-1) != 0 {
+               base.Fatalf("onebitwalktype1: invalid initial alignment: type %v has alignment %d, but offset is %v", t, t.Align, off)
+       }
+       if !t.HasPointers() {
+               // Note: this case ensures that pointers to go:notinheap types
+               // are not considered pointers by garbage collection and stack copying.
+               return
+       }
+
+       switch t.Kind() {
+       case types.TPTR, types.TUNSAFEPTR, types.TFUNC, types.TCHAN, types.TMAP:
+               if off&int64(types.PtrSize-1) != 0 {
+                       base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
+               }
+               bv.Set(int32(off / int64(types.PtrSize))) // pointer
+
+       case types.TSTRING:
+               // struct { byte *str; intgo len; }
+               if off&int64(types.PtrSize-1) != 0 {
+                       base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
+               }
+               bv.Set(int32(off / int64(types.PtrSize))) //pointer in first slot
+
+       case types.TINTER:
+               // struct { Itab *tab;  void *data; }
+               // or, when isnilinter(t)==true:
+               // struct { Type *type; void *data; }
+               if off&int64(types.PtrSize-1) != 0 {
+                       base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
+               }
+               // The first word of an interface is a pointer, but we don't
+               // treat it as such.
+               // 1. If it is a non-empty interface, the pointer points to an itab
+               //    which is always in persistentalloc space.
+               // 2. If it is an empty interface, the pointer points to a _type.
+               //   a. If it is a compile-time-allocated type, it points into
+               //      the read-only data section.
+               //   b. If it is a reflect-allocated type, it points into the Go heap.
+               //      Reflect is responsible for keeping a reference to
+               //      the underlying type so it won't be GCd.
+               // If we ever have a moving GC, we need to change this for 2b (as
+               // well as scan itabs to update their itab._type fields).
+               bv.Set(int32(off/int64(types.PtrSize) + 1)) // pointer in second slot
+
+       case types.TSLICE:
+               // struct { byte *array; uintgo len; uintgo cap; }
+               if off&int64(types.PtrSize-1) != 0 {
+                       base.Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t)
+               }
+               bv.Set(int32(off / int64(types.PtrSize))) // pointer in first slot (BitsPointer)
+
+       case types.TARRAY:
+               elt := t.Elem()
+               if elt.Width == 0 {
+                       // Short-circuit for #20739.
+                       break
+               }
+               for i := int64(0); i < t.NumElem(); i++ {
+                       Set(elt, off, bv)
+                       off += elt.Width
+               }
+
+       case types.TSTRUCT:
+               for _, f := range t.Fields().Slice() {
+                       Set(f.Type, off+f.Offset, bv)
+               }
+
+       default:
+               base.Fatalf("onebitwalktype1: unexpected type, %v", t)
+       }
+}