]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: implement OGETG
authorJosh Bleecher Snyder <josharian@gmail.com>
Wed, 12 Aug 2015 18:22:16 +0000 (11:22 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Wed, 12 Aug 2015 22:05:42 +0000 (22:05 +0000)
Change-Id: I7ecf62cf399c710b4a617803c43e83fce09b8a7d
Reviewed-on: https://go-review.googlesource.com/13585
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/ssa/gen/AMD64.rules
src/cmd/compile/internal/ssa/gen/AMD64Ops.go
src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/gen/genericOps.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteAMD64.go
src/cmd/compile/internal/ssa/rewritegeneric.go
src/cmd/internal/obj/x86/obj6.go

index 0086feceabf590f48e9e955e2be6896267504452..c8ec01f5b6e04b0bb732cf0ed35a2c94c89bdefe 100644 (file)
@@ -1340,6 +1340,10 @@ func (s *state) expr(n *Node) *ssa.Value {
                }
                a := s.entryNewValue1I(ssa.OpOffPtr, Ptrto(fp.Type), fp.Width, s.sp)
                return s.newValue2(ssa.OpLoad, fp.Type, a, call)
+
+       case OGETG:
+               return s.newValue0(ssa.OpGetG, n.Type)
+
        default:
                s.Unimplementedf("unhandled expr %s", opnames[n.Op])
                return nil
@@ -2185,6 +2189,33 @@ func genValue(v *ssa.Value) {
                q.From.Reg = x86.REG_AX
                q.To.Type = obj.TYPE_MEM
                q.To.Reg = x86.REG_AX
+       case ssa.OpAMD64LoweredGetG:
+               r := regnum(v)
+               // See the comments in cmd/internal/obj/x86/obj6.go
+               // near CanUse1InsnTLS for a detailed explanation of these instructions.
+               if x86.CanUse1InsnTLS(Ctxt) {
+                       // MOVQ (TLS), r
+                       p := Prog(x86.AMOVQ)
+                       p.From.Type = obj.TYPE_MEM
+                       p.From.Reg = x86.REG_TLS
+                       p.To.Type = obj.TYPE_REG
+                       p.To.Reg = r
+               } else {
+                       // MOVQ TLS, r
+                       // MOVQ (r)(TLS*1), r
+                       p := Prog(x86.AMOVQ)
+                       p.From.Type = obj.TYPE_REG
+                       p.From.Reg = x86.REG_TLS
+                       p.To.Type = obj.TYPE_REG
+                       p.To.Reg = r
+                       q := Prog(x86.AMOVQ)
+                       q.From.Type = obj.TYPE_MEM
+                       q.From.Reg = r
+                       q.From.Index = x86.REG_TLS
+                       q.From.Scale = 1
+                       q.To.Type = obj.TYPE_REG
+                       q.To.Reg = r
+               }
        case ssa.OpAMD64CALLstatic:
                p := Prog(obj.ACALL)
                p.To.Type = obj.TYPE_MEM
index 29f60d9a6b54fbe36795745a3145992b69b5ab08..ab8e44a4442d4911bc5115a0b2f3e9b0748012a4 100644 (file)
 (IsInBounds idx len) -> (SETB (CMPQ <TypeFlags> idx len))
 
 (PanicNilCheck ptr mem) -> (LoweredPanicNilCheck ptr mem)
+(GetG) -> (LoweredGetG)
 
 (Move [size] dst src mem) -> (REPMOVSB dst src (MOVQconst <config.Frontend().TypeUInt64()> [size]) mem)
 
index 9808745e35f0e475c8ce1203b2f7d202be65dfcd..903eea3057f9e629842885cc576230cffb2d7f30 100644 (file)
@@ -288,8 +288,9 @@ func init() {
                // InvertFlags is a pseudo-op which can't appear in assembly output.
                {name: "InvertFlags"}, // reverse direction of arg0
 
-               // LoweredPanicNilCheck is a pseudo-op.
+               // Pseudo-ops
                {name: "LoweredPanicNilCheck"},
+               {name: "LoweredGetG"},
        }
 
        var AMD64blocks = []blockData{
index 8656b7cc4f3f6c41ae460ca5eb3b0e3edeae741b..f4f49acb8620c7312552ea3ebb9a43833cbf13f7 100644 (file)
@@ -71,6 +71,8 @@
 (StringLen (StringMake _ len)) -> len
 (Store dst str mem) && str.Type.IsString() -> (Store (OffPtr <config.Frontend().TypeBytePtr()> [config.PtrSize] dst) (StringLen <config.Frontend().TypeUintptr()> str) (Store <TypeMem> dst (StringPtr <config.Frontend().TypeBytePtr()> str) mem))
 
+(If (IsNonNil (GetG)) yes no) -> (Plain nil yes)
+
 (If (Not cond) yes no) -> (If cond no yes)
 (If (ConstBool {c}) yes no) && c.(bool) -> (Plain nil yes)
 (If (ConstBool {c}) yes no) && !c.(bool) -> (Plain nil no)
index 6ff5d1ea1a678eb126da9b4583d75c74195fdc58..ec4f038f43ac2b251257f365a4413510da8711a0 100644 (file)
@@ -252,7 +252,9 @@ var genericOps = []opData{
        {name: "IsNonNil"},   // arg0 != nil
        {name: "IsInBounds"}, // 0 <= arg0 < arg1
 
+       // Pseudo-ops
        {name: "PanicNilCheck"}, // trigger a dereference fault; arg0=nil ptr, arg1=mem
+       {name: "GetG"},          // runtime.getg() (read g pointer)
 
        // Indexing operations
        {name: "ArrayIndex"},   // arg0=array, arg1=index.  Returns a[i]
index d56a8ba81b0d29bd64cced5e21ec41cf1eb5ddd4..425c7e468c2cc138bc4d3a36adbe9289832f7adc 100644 (file)
@@ -195,6 +195,7 @@ const (
        OpAMD64REPMOVSB
        OpAMD64InvertFlags
        OpAMD64LoweredPanicNilCheck
+       OpAMD64LoweredGetG
 
        OpAdd8
        OpAdd16
@@ -369,6 +370,7 @@ const (
        OpIsNonNil
        OpIsInBounds
        OpPanicNilCheck
+       OpGetG
        OpArrayIndex
        OpPtrIndex
        OpOffPtr
@@ -2119,6 +2121,10 @@ var opcodeTable = [...]opInfo{
                name: "LoweredPanicNilCheck",
                reg:  regInfo{},
        },
+       {
+               name: "LoweredGetG",
+               reg:  regInfo{},
+       },
 
        {
                name:    "Add8",
@@ -2812,6 +2818,10 @@ var opcodeTable = [...]opInfo{
                name:    "PanicNilCheck",
                generic: true,
        },
+       {
+               name:    "GetG",
+               generic: true,
+       },
        {
                name:    "ArrayIndex",
                generic: true,
index 2668d570d189514626f35c9424a78aafd3b49644..a18097f91e1ffc1ac70296eed61ad8816b168760 100644 (file)
@@ -1893,6 +1893,20 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
                goto endd30ee67afc0284c419cef70261f61452
        endd30ee67afc0284c419cef70261f61452:
                ;
+       case OpGetG:
+               // match: (GetG)
+               // cond:
+               // result: (LoweredGetG)
+               {
+                       v.Op = OpAMD64LoweredGetG
+                       v.AuxInt = 0
+                       v.Aux = nil
+                       v.resetArgs()
+                       return true
+               }
+               goto endb17140e71dd641aa4d89e14479160260
+       endb17140e71dd641aa4d89e14479160260:
+               ;
        case OpGreater16:
                // match: (Greater16 x y)
                // cond:
index 6371ac2b38dbe9287214beeb19ec1cdac75d7dff..e39305461d308c227005dd77fc661824ceab4d77 100644 (file)
@@ -782,6 +782,30 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
 func rewriteBlockgeneric(b *Block) bool {
        switch b.Kind {
        case BlockIf:
+               // match: (If (IsNonNil (GetG)) yes no)
+               // cond:
+               // result: (Plain nil yes)
+               {
+                       v := b.Control
+                       if v.Op != OpIsNonNil {
+                               goto end0f2bb0111a86be0436b44210dbd83a90
+                       }
+                       if v.Args[0].Op != OpGetG {
+                               goto end0f2bb0111a86be0436b44210dbd83a90
+                       }
+                       yes := b.Succs[0]
+                       no := b.Succs[1]
+                       b.Func.removePredecessor(b, no)
+                       b.Kind = BlockPlain
+                       b.Control = nil
+                       b.Succs = b.Succs[:1]
+                       b.Succs[0] = yes
+                       b.Likely = BranchUnknown
+                       return true
+               }
+               goto end0f2bb0111a86be0436b44210dbd83a90
+       end0f2bb0111a86be0436b44210dbd83a90:
+               ;
                // match: (If (Not cond) yes no)
                // cond:
                // result: (If cond no yes)
index fa9c474adb344f8f66089330bcd408e7a4b07ff8..5249ca9581d0b87886aa901344b8c147b923cdb4 100644 (file)
@@ -38,7 +38,7 @@ import (
        "math"
 )
 
-func canuse1insntls(ctxt *obj.Link) bool {
+func CanUse1InsnTLS(ctxt *obj.Link) bool {
        if ctxt.Arch.Regsize == 4 {
                switch ctxt.Headtype {
                case obj.Hlinux,
@@ -120,7 +120,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
        // rewriting the instructions more comprehensively, and it only does because
        // we only support a single TLS variable (g).
 
-       if canuse1insntls(ctxt) {
+       if CanUse1InsnTLS(ctxt) {
                // Reduce 2-instruction sequence to 1-instruction sequence.
                // Sequences like
                //      MOVQ TLS, BX