]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: implement OCAP
authorBrad Fitzpatrick <bradfitz@golang.org>
Fri, 10 Jul 2015 16:47:28 +0000 (10:47 -0600)
committerBrad Fitzpatrick <bradfitz@golang.org>
Sun, 12 Jul 2015 04:14:58 +0000 (04:14 +0000)
And dependent fixes and misc cleanup.

Co-hacking with josharian at Gophercon.

Change-Id: Ib85dc13b303929017eb0a4d2fc2f603485f7479b
Reviewed-on: https://go-review.googlesource.com/12027
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>

src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/type.go
src/cmd/compile/internal/ssa/config.go

index 0aa0e289ec44e188806058b47ea3d8b1e2bbe682..fabe325c38baab9ece67d76803e0f51de79cb16f 100644 (file)
@@ -199,7 +199,7 @@ type Type struct {
        Note  *string // literal string annotation
 
        // TARRAY
-       Bound int64 // negative is dynamic array
+       Bound int64 // negative is slice
 
        // TMAP
        Bucket *Type // internal type representing a hash bucket
index ab16a3351005ee04188a883770f1c214ad054952..90c1e0a25e6fb39d304a46b2eea23180f054bb12 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "fmt"
+       "strings"
 
        "cmd/compile/internal/ssa"
        "cmd/internal/obj"
@@ -18,7 +19,7 @@ import (
 // it will never return nil, and the bool can be removed.
 func buildssa(fn *Node) (ssafn *ssa.Func, usessa bool) {
        name := fn.Func.Nname.Sym.Name
-       usessa = len(name) > 4 && name[len(name)-4:] == "_ssa"
+       usessa = strings.HasSuffix(name, "_ssa")
 
        if usessa {
                dumplist("buildssa-enter", fn.Func.Enter)
@@ -293,6 +294,8 @@ func (s *state) stmt(n *Node) {
        case OBLOCK:
                s.stmtList(n.List)
 
+       case OEMPTY:
+
        case ODCL:
                if n.Left.Class&PHEAP == 0 {
                        return
@@ -527,14 +530,18 @@ func (s *state) expr(n *Node) *ssa.Value {
                        return s.newValue2(ssa.OpLoad, n.Left.Type.Type, p, s.mem())
                }
 
-       case OLEN:
+       case OLEN, OCAP:
                switch {
-               case n.Left.Type.Bound < 0: // slice
-                       return s.newValue1(ssa.OpSliceLen, s.config.Uintptr, s.expr(n.Left))
-               case n.Left.Type.IsString(): // string
-                       return s.newValue1(ssa.OpStringLen, s.config.Uintptr, s.expr(n.Left))
+               case n.Left.Type.IsSlice():
+                       op := ssa.OpSliceLen
+                       if n.Op == OCAP {
+                               op = ssa.OpSliceCap
+                       }
+                       return s.newValue1(op, s.config.Int, s.expr(n.Left))
+               case n.Left.Type.IsString(): // string; not reachable for OCAP
+                       return s.newValue1(ssa.OpStringLen, s.config.Int, s.expr(n.Left))
                default: // array
-                       return s.constInt(s.config.Uintptr, n.Left.Type.Bound)
+                       return s.constInt(s.config.Int, n.Left.Type.Bound)
                }
 
        case OCALLFUNC:
@@ -645,19 +652,19 @@ func (s *state) addr(n *Node) *ssa.Value {
                // used for storing/loading arguments/returns to/from callees
                return s.entryNewValue1I(ssa.OpOffPtr, Ptrto(n.Type), n.Xoffset, s.sp)
        case OINDEX:
-               if n.Left.Type.Bound >= 0 { // array
-                       a := s.addr(n.Left)
-                       i := s.expr(n.Right)
-                       len := s.constInt(s.config.Uintptr, n.Left.Type.Bound)
-                       s.boundsCheck(i, len)
-                       return s.newValue2(ssa.OpPtrIndex, Ptrto(n.Left.Type.Type), a, i)
-               } else { // slice
+               if n.Left.Type.IsSlice() {
                        a := s.expr(n.Left)
                        i := s.expr(n.Right)
                        len := s.newValue1(ssa.OpSliceLen, s.config.Uintptr, a)
                        s.boundsCheck(i, len)
                        p := s.newValue1(ssa.OpSlicePtr, Ptrto(n.Left.Type.Type), a)
                        return s.newValue2(ssa.OpPtrIndex, Ptrto(n.Left.Type.Type), p, i)
+               } else { // array
+                       a := s.addr(n.Left)
+                       i := s.expr(n.Right)
+                       len := s.constInt(s.config.Uintptr, n.Left.Type.Bound)
+                       s.boundsCheck(i, len)
+                       return s.newValue2(ssa.OpPtrIndex, Ptrto(n.Left.Type.Type), a, i)
                }
        default:
                s.Unimplementedf("addr: bad op %v", Oconv(int(n.Op), 0))
index 11635d8929f33ddacd66c0677e2a4c6a55eaa664..7f7b6635e00ec98080742b4b1e2260a1492c42cb 100644 (file)
@@ -64,6 +64,10 @@ func (t *Type) IsString() bool {
        return t.Etype == TSTRING
 }
 
+func (t *Type) IsSlice() bool {
+       return t.Etype == TARRAY && t.Bound < 0
+}
+
 func (t *Type) Elem() ssa.Type {
        return t.Type
 }
index 53eb5e8eb5a87c3aabaddbea6a928b1b368c8833..c6c7bf36e9f4b3028902470cc7fa3b6be94635f6 100644 (file)
@@ -5,9 +5,10 @@
 package ssa
 
 type Config struct {
-       arch       string                     // "amd64", etc.
-       ptrSize    int64                      // 4 or 8
-       Uintptr    Type                       // pointer arithmetic type
+       arch       string // "amd64", etc.
+       ptrSize    int64  // 4 or 8
+       Uintptr    Type   // pointer arithmetic type
+       Int        Type
        lowerBlock func(*Block) bool          // lowering function
        lowerValue func(*Value, *Config) bool // lowering function
        fe         Frontend                   // callbacks into compiler frontend
@@ -48,10 +49,12 @@ func NewConfig(arch string, fe Frontend) *Config {
                fe.Unimplementedf("arch %s not implemented", arch)
        }
 
-       // cache the intptr type in the config
+       // cache the frequently-used types in the config
        c.Uintptr = TypeUInt32
+       c.Int = TypeInt32
        if c.ptrSize == 8 {
                c.Uintptr = TypeUInt64
+               c.Int = TypeInt64
        }
 
        return c