]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: use types2.Sizes instead of compiler own implementation
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 28 Jun 2023 05:03:22 +0000 (12:03 +0700)
committerGopher Robot <gobot@golang.org>
Wed, 16 Aug 2023 21:01:11 +0000 (21:01 +0000)
With #61035 fixed, types2.Sizes matches the compiler behavior, so use its
Sizes implementation instead of rolling our own copy.

Updates #61035

Change-Id: I7b9efd27a01f729a04c79cd6b4ee5f417fe6e664
Reviewed-on: https://go-review.googlesource.com/c/go/+/506716
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
src/cmd/compile/internal/noder/irgen.go
src/cmd/compile/internal/noder/sizes.go [deleted file]

index 6019c5986c323b584baec0a91f0a014e2bccb912..f7b6d191fb85223ae7148790b96764506db2028b 100644 (file)
@@ -6,6 +6,7 @@ package noder
 
 import (
        "fmt"
+       "internal/buildcfg"
        "internal/types/errors"
        "regexp"
        "sort"
@@ -51,7 +52,7 @@ func checkFiles(m posMap, noders []*noder) (*types2.Package, *types2.Info) {
                        base.ErrorfAt(m.makeXPos(terr.Pos), terr.Code, "%s", msg)
                },
                Importer: &importer,
-               Sizes:    &gcSizes{},
+               Sizes:    types2.SizesFor("gc", buildcfg.GOARCH),
        }
        if base.Flag.ErrorURL {
                conf.ErrorURL = " [go.dev/e/%s]"
diff --git a/src/cmd/compile/internal/noder/sizes.go b/src/cmd/compile/internal/noder/sizes.go
deleted file mode 100644 (file)
index dff8d7b..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2021 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 noder
-
-import (
-       "fmt"
-
-       "cmd/compile/internal/types"
-       "cmd/compile/internal/types2"
-)
-
-// Code below based on go/types.StdSizes.
-// Intentional differences are marked with "gc:".
-
-type gcSizes struct{}
-
-func (s *gcSizes) Alignof(T types2.Type) int64 {
-       // For arrays and structs, alignment is defined in terms
-       // of alignment of the elements and fields, respectively.
-       switch t := T.Underlying().(type) {
-       case *types2.Array:
-               // spec: "For a variable x of array type: unsafe.Alignof(x)
-               // is the same as unsafe.Alignof(x[0]), but at least 1."
-               return s.Alignof(t.Elem())
-       case *types2.Struct:
-               if t.NumFields() == 0 && types2.IsSyncAtomicAlign64(T) {
-                       // Special case: sync/atomic.align64 is an
-                       // empty struct we recognize as a signal that
-                       // the struct it contains must be
-                       // 64-bit-aligned.
-                       //
-                       // This logic is equivalent to the logic in
-                       // cmd/compile/internal/types/size.go:calcStructOffset
-                       return 8
-               }
-
-               // spec: "For a variable x of struct type: unsafe.Alignof(x)
-               // is the largest of the values unsafe.Alignof(x.f) for each
-               // field f of x, but at least 1."
-               max := int64(1)
-               for i, nf := 0, t.NumFields(); i < nf; i++ {
-                       if a := s.Alignof(t.Field(i).Type()); a > max {
-                               max = a
-                       }
-               }
-               return max
-       case *types2.Slice, *types2.Interface:
-               // Multiword data structures are effectively structs
-               // in which each element has size PtrSize.
-               return int64(types.PtrSize)
-       case *types2.Basic:
-               // Strings are like slices and interfaces.
-               if t.Info()&types2.IsString != 0 {
-                       return int64(types.PtrSize)
-               }
-       }
-       a := s.Sizeof(T) // may be 0
-       // spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
-       if a < 1 {
-               return 1
-       }
-       // complex{64,128} are aligned like [2]float{32,64}.
-       if isComplex(T) {
-               a /= 2
-       }
-       if a > int64(types.RegSize) {
-               return int64(types.RegSize)
-       }
-       return a
-}
-
-func isComplex(T types2.Type) bool {
-       basic, ok := T.Underlying().(*types2.Basic)
-       return ok && basic.Info()&types2.IsComplex != 0
-}
-
-func (s *gcSizes) Offsetsof(fields []*types2.Var) []int64 {
-       offsets := make([]int64, len(fields))
-       var offs int64
-       for i, f := range fields {
-               if offs < 0 {
-                       // all remaining offsets are too large
-                       offsets[i] = -1
-                       continue
-               }
-               // offs >= 0
-               typ := f.Type()
-               a := s.Alignof(typ)
-               offs = types.RoundUp(offs, a) // possibly < 0 if align overflows
-               offsets[i] = offs
-               if d := s.Sizeof(typ); d >= 0 && offs >= 0 {
-                       offs += d // ok to overflow to < 0
-               } else {
-                       offs = -1
-               }
-       }
-       return offsets
-}
-
-func (s *gcSizes) Sizeof(T types2.Type) int64 {
-       switch t := T.Underlying().(type) {
-       case *types2.Basic:
-               k := t.Kind()
-               if int(k) < len(basicSizes) {
-                       if s := basicSizes[k]; s > 0 {
-                               return int64(s)
-                       }
-               }
-               switch k {
-               case types2.String:
-                       return int64(types.PtrSize) * 2
-               case types2.Int, types2.Uint, types2.Uintptr, types2.UnsafePointer:
-                       return int64(types.PtrSize)
-               }
-               panic(fmt.Sprintf("unimplemented basic: %v (kind %v)", T, k))
-       case *types2.Array:
-               n := t.Len()
-               if n <= 0 {
-                       return 0
-               }
-               // n > 0
-               // gc: Size includes alignment padding.
-               esize := s.Sizeof(t.Elem())
-               if esize < 0 {
-                       return -1 // array element too large
-               }
-               if esize == 0 {
-                       return 0 // 0-size element
-               }
-               // esize > 0
-               // Final size is esize * n; and size must be <= maxInt64.
-               const maxInt64 = 1<<63 - 1
-               if esize > maxInt64/n {
-                       return -1 // esize * n overflows
-               }
-               return esize * n
-       case *types2.Slice:
-               return int64(types.PtrSize) * 3
-       case *types2.Struct:
-               n := t.NumFields()
-               if n == 0 {
-                       return 0
-               }
-               fields := make([]*types2.Var, n)
-               for i := range fields {
-                       fields[i] = t.Field(i)
-               }
-               offsets := s.Offsetsof(fields)
-
-               // gc: The last field of a non-zero-sized struct is not allowed to
-               // have size 0.
-               last := s.Sizeof(fields[n-1].Type())
-               if last == 0 && offsets[n-1] > 0 {
-                       last = 1
-               }
-
-               // gc: Size includes alignment padding.
-               return types.RoundUp(offsets[n-1]+last, s.Alignof(t)) // may overflow to < 0 which is ok
-       case *types2.Interface:
-               return int64(types.PtrSize) * 2
-       case *types2.Chan, *types2.Map, *types2.Pointer, *types2.Signature:
-               return int64(types.PtrSize)
-       default:
-               panic(fmt.Sprintf("unimplemented type: %T", t))
-       }
-}
-
-var basicSizes = [...]byte{
-       types2.Invalid:    1,
-       types2.Bool:       1,
-       types2.Int8:       1,
-       types2.Int16:      2,
-       types2.Int32:      4,
-       types2.Int64:      8,
-       types2.Uint8:      1,
-       types2.Uint16:     2,
-       types2.Uint32:     4,
-       types2.Uint64:     8,
-       types2.Float32:    4,
-       types2.Float64:    8,
-       types2.Complex64:  8,
-       types2.Complex128: 16,
-}