]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: remove Zero and NilCheck for newobject
authorCherry Zhang <cherryyz@google.com>
Fri, 26 Aug 2016 19:41:51 +0000 (15:41 -0400)
committerCherry Zhang <cherryyz@google.com>
Tue, 30 Aug 2016 23:10:43 +0000 (23:10 +0000)
Recognize runtime.newobject and don't Zero or NilCheck it.

Fixes #15914 (?)
Updates #15390.

TBD: add test

Change-Id: Ia3bfa5c2ddbe2c27c92d9f68534a713b5ce95934
Reviewed-on: https://go-review.googlesource.com/27930
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
14 files changed:
src/cmd/compile/internal/ssa/config.go
src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/gen/rulegen.go
src/cmd/compile/internal/ssa/rewrite.go
src/cmd/compile/internal/ssa/rewrite386.go
src/cmd/compile/internal/ssa/rewriteAMD64.go
src/cmd/compile/internal/ssa/rewriteARM.go
src/cmd/compile/internal/ssa/rewriteARM64.go
src/cmd/compile/internal/ssa/rewriteMIPS64.go
src/cmd/compile/internal/ssa/rewritePPC64.go
src/cmd/compile/internal/ssa/rewritedec.go
src/cmd/compile/internal/ssa/rewritedec64.go
src/cmd/compile/internal/ssa/rewritegeneric.go
src/runtime/malloc.go

index 6fc30a3847a49da5095928ef3bca69a9f2e67018..37c2945988bbff798ef6a78248e641905c63f220 100644 (file)
@@ -17,7 +17,7 @@ type Config struct {
        arch            string                     // "amd64", etc.
        IntSize         int64                      // 4 or 8
        PtrSize         int64                      // 4 or 8
-       lowerBlock      func(*Block) bool          // lowering function
+       lowerBlock      func(*Block, *Config) bool // lowering function
        lowerValue      func(*Value, *Config) bool // lowering function
        registers       []Register                 // machine registers
        gpRegMask       regMask                    // general purpose integer register mask
index 33d361e6d3ba9f3e236cd5dab4043b28a79dcee9..23cda160f72058f1571a7437e3ea61dbe2107ce7 100644 (file)
 (Div64F x (Const64F [f2i(-1)])) -> (Neg32F x)
 
 (Sqrt (Const64F [c])) -> (Const64F [f2i(math.Sqrt(i2f(c)))])
+
+// recognize runtime.newobject and don't Zero/Nilcheck it
+(Zero (Load (OffPtr [c] (SP)) mem:(StaticCall {sym} _)) mem2)
+       && c == config.ctxt.FixedFrameSize() + config.PtrSize // offset of return value
+       && mem2 == mem
+       && isSameSym(sym, "runtime.newobject")
+       -> mem
+(Check (NilCheck (Load (OffPtr [c] (SP)) mem:(StaticCall {sym} _)) _) succ)
+       && c == config.ctxt.FixedFrameSize() + config.PtrSize // offset of return value
+       && isSameSym(sym, "runtime.newobject")
+       -> (Plain nil succ)
+(Check (NilCheck (OffPtr (Load (OffPtr [c] (SP)) mem:(StaticCall {sym} _))) _) succ)
+       && c == config.ctxt.FixedFrameSize() + config.PtrSize // offset of return value
+       && isSameSym(sym, "runtime.newobject")
+       -> (Plain nil succ)
index 8841c4d018824ced072a37e5a7b798760445fa80..60187730e2bb43b54b6349190a2c00c322c8a2a1 100644 (file)
@@ -209,7 +209,7 @@ func genRules(arch arch) {
 
        // Generate block rewrite function. There are only a few block types
        // so we can make this one function with a switch.
-       fmt.Fprintf(w, "func rewriteBlock%s(b *Block) bool {\n", arch.name)
+       fmt.Fprintf(w, "func rewriteBlock%s(b *Block, config *Config) bool {\n", arch.name)
        fmt.Fprintf(w, "switch b.Kind {\n")
        ops = nil
        for op := range blockrules {
index 8290d9cc55a5c3d60d6edd5b72b9436842285ebf..a7dea1afcf12295f4efaffdef42588a1dd1ad727 100644 (file)
@@ -11,7 +11,7 @@ import (
        "path/filepath"
 )
 
-func applyRewrite(f *Func, rb func(*Block) bool, rv func(*Value, *Config) bool) {
+func applyRewrite(f *Func, rb func(*Block, *Config) bool, rv func(*Value, *Config) bool) {
        // repeat rewrites until we find no more rewrites
        var curb *Block
        var curv *Value
@@ -34,7 +34,7 @@ func applyRewrite(f *Func, rb func(*Block) bool, rv func(*Value, *Config) bool)
                                }
                        }
                        curb = b
-                       if rb(b) {
+                       if rb(b, config) {
                                change = true
                        }
                        curb = nil
@@ -161,6 +161,12 @@ func isAuto(s interface{}) bool {
        return ok
 }
 
+// isSameSym returns whether sym is the same as the given named symbol
+func isSameSym(sym interface{}, name string) bool {
+       s, ok := sym.(fmt.Stringer)
+       return ok && s.String() == name
+}
+
 // nlz returns the number of leading zeros.
 func nlz(x int64) int64 {
        // log2(0) == 1, so nlz(0) == 64
index 8100b9ef7c182d1aa277fbcd532bc703ed75b72d..04932be887fc7534c03d873fc4cdeab9e54b72e0 100644 (file)
@@ -13162,7 +13162,7 @@ func rewriteValue386_OpZeromask(v *Value, config *Config) bool {
                return true
        }
 }
-func rewriteBlock386(b *Block) bool {
+func rewriteBlock386(b *Block, config *Config) bool {
        switch b.Kind {
        case Block386EQ:
                // match: (EQ (InvertFlags cmp) yes no)
index 3e481ca7252a51bc01fbc58fcceab8f66f9e0647..2b685618f9f54b6a2bcd5e87b9dcc8a8f406ed5c 100644 (file)
@@ -18803,7 +18803,7 @@ func rewriteValueAMD64_OpZeroExt8to64(v *Value, config *Config) bool {
                return true
        }
 }
-func rewriteBlockAMD64(b *Block) bool {
+func rewriteBlockAMD64(b *Block, config *Config) bool {
        switch b.Kind {
        case BlockAMD64EQ:
                // match: (EQ (InvertFlags cmp) yes no)
index 9b4d1ed0991808659b3afde77fa05fe0031a9b61..543e3bdc9d57b41a2a7cda10e951c59e6645bb35 100644 (file)
@@ -16824,7 +16824,7 @@ func rewriteValueARM_OpZeromask(v *Value, config *Config) bool {
                return true
        }
 }
-func rewriteBlockARM(b *Block) bool {
+func rewriteBlockARM(b *Block, config *Config) bool {
        switch b.Kind {
        case BlockARMEQ:
                // match: (EQ (FlagEQ) yes no)
index ca1dd805cdfe240c22c5002619ae92ff6f0a26f1..db3ad730d8dea050b97820cb30b92eedb695717e 100644 (file)
@@ -14719,7 +14719,7 @@ func rewriteValueARM64_OpZeroExt8to64(v *Value, config *Config) bool {
                return true
        }
 }
-func rewriteBlockARM64(b *Block) bool {
+func rewriteBlockARM64(b *Block, config *Config) bool {
        switch b.Kind {
        case BlockARM64EQ:
                // match: (EQ (FlagEQ) yes no)
index 2bda6a79aa59c64f694ed09e5d0e4b6da5813eb0..a3e8b4039392d714ded02cbefaf094c09860bca1 100644 (file)
@@ -9710,7 +9710,7 @@ func rewriteValueMIPS64_OpZeroExt8to64(v *Value, config *Config) bool {
                return true
        }
 }
-func rewriteBlockMIPS64(b *Block) bool {
+func rewriteBlockMIPS64(b *Block, config *Config) bool {
        switch b.Kind {
        case BlockMIPS64EQ:
                // match: (EQ (FPFlagTrue cmp) yes no)
index 4be68fda2bd2790676458a2fd80061818d6ad8d6..35441c91253d19f26479798f493068a01b895e1a 100644 (file)
@@ -7159,7 +7159,7 @@ func rewriteValuePPC64_OpZeroExt8to64(v *Value, config *Config) bool {
                return true
        }
 }
-func rewriteBlockPPC64(b *Block) bool {
+func rewriteBlockPPC64(b *Block, config *Config) bool {
        switch b.Kind {
        case BlockPPC64EQ:
                // match: (EQ (FlagEQ) yes no)
index c32d54e1f5b8515eae7e6e3641a72d53742e4be9..fd527518908096570b51e4aed1c6f57757c4742a 100644 (file)
@@ -500,7 +500,7 @@ func rewriteValuedec_OpStringPtr(v *Value, config *Config) bool {
        }
        return false
 }
-func rewriteBlockdec(b *Block) bool {
+func rewriteBlockdec(b *Block, config *Config) bool {
        switch b.Kind {
        }
        return false
index 91103f8475d3ec6cc72827679d571547a8cf8b0c..4a8175accb375c9926421f828fdce55f048e4ce0 100644 (file)
@@ -2527,7 +2527,7 @@ func rewriteValuedec64_OpZeroExt8to64(v *Value, config *Config) bool {
                return true
        }
 }
-func rewriteBlockdec64(b *Block) bool {
+func rewriteBlockdec64(b *Block, config *Config) bool {
        switch b.Kind {
        }
        return false
index 81537036ab18981dbeb5cf529a9c2871ab04306d..d041afd9beccee29157062097901f7408257f160 100644 (file)
@@ -358,6 +358,8 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
                return rewriteValuegeneric_OpXor64(v, config)
        case OpXor8:
                return rewriteValuegeneric_OpXor8(v, config)
+       case OpZero:
+               return rewriteValuegeneric_OpZero(v, config)
        }
        return false
 }
@@ -10969,7 +10971,43 @@ func rewriteValuegeneric_OpXor8(v *Value, config *Config) bool {
        }
        return false
 }
-func rewriteBlockgeneric(b *Block) bool {
+func rewriteValuegeneric_OpZero(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Zero (Load (OffPtr [c] (SP)) mem:(StaticCall {sym} _)) mem2)
+       // cond: c == config.ctxt.FixedFrameSize() + config.PtrSize     && mem2 == mem  && isSameSym(sym, "runtime.newobject")
+       // result: mem
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpLoad {
+                       break
+               }
+               v_0_0 := v_0.Args[0]
+               if v_0_0.Op != OpOffPtr {
+                       break
+               }
+               c := v_0_0.AuxInt
+               v_0_0_0 := v_0_0.Args[0]
+               if v_0_0_0.Op != OpSP {
+                       break
+               }
+               mem := v_0.Args[1]
+               if mem.Op != OpStaticCall {
+                       break
+               }
+               sym := mem.Aux
+               mem2 := v.Args[1]
+               if !(c == config.ctxt.FixedFrameSize()+config.PtrSize && mem2 == mem && isSameSym(sym, "runtime.newobject")) {
+                       break
+               }
+               v.reset(OpCopy)
+               v.Type = mem.Type
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteBlockgeneric(b *Block, config *Config) bool {
        switch b.Kind {
        case BlockCheck:
                // match: (Check (NilCheck (GetG _) _) next)
@@ -10990,6 +11028,80 @@ func rewriteBlockgeneric(b *Block) bool {
                        _ = next
                        return true
                }
+               // match: (Check (NilCheck (Load (OffPtr [c] (SP)) mem:(StaticCall {sym} _)) _) succ)
+               // cond: c == config.ctxt.FixedFrameSize() + config.PtrSize     && isSameSym(sym, "runtime.newobject")
+               // result: (Plain nil succ)
+               for {
+                       v := b.Control
+                       if v.Op != OpNilCheck {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpLoad {
+                               break
+                       }
+                       v_0_0 := v_0.Args[0]
+                       if v_0_0.Op != OpOffPtr {
+                               break
+                       }
+                       c := v_0_0.AuxInt
+                       v_0_0_0 := v_0_0.Args[0]
+                       if v_0_0_0.Op != OpSP {
+                               break
+                       }
+                       mem := v_0.Args[1]
+                       if mem.Op != OpStaticCall {
+                               break
+                       }
+                       sym := mem.Aux
+                       succ := b.Succs[0]
+                       if !(c == config.ctxt.FixedFrameSize()+config.PtrSize && isSameSym(sym, "runtime.newobject")) {
+                               break
+                       }
+                       b.Kind = BlockPlain
+                       b.SetControl(nil)
+                       _ = succ
+                       return true
+               }
+               // match: (Check (NilCheck (OffPtr (Load (OffPtr [c] (SP)) mem:(StaticCall {sym} _))) _) succ)
+               // cond: c == config.ctxt.FixedFrameSize() + config.PtrSize     && isSameSym(sym, "runtime.newobject")
+               // result: (Plain nil succ)
+               for {
+                       v := b.Control
+                       if v.Op != OpNilCheck {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpOffPtr {
+                               break
+                       }
+                       v_0_0 := v_0.Args[0]
+                       if v_0_0.Op != OpLoad {
+                               break
+                       }
+                       v_0_0_0 := v_0_0.Args[0]
+                       if v_0_0_0.Op != OpOffPtr {
+                               break
+                       }
+                       c := v_0_0_0.AuxInt
+                       v_0_0_0_0 := v_0_0_0.Args[0]
+                       if v_0_0_0_0.Op != OpSP {
+                               break
+                       }
+                       mem := v_0_0.Args[1]
+                       if mem.Op != OpStaticCall {
+                               break
+                       }
+                       sym := mem.Aux
+                       succ := b.Succs[0]
+                       if !(c == config.ctxt.FixedFrameSize()+config.PtrSize && isSameSym(sym, "runtime.newobject")) {
+                               break
+                       }
+                       b.Kind = BlockPlain
+                       b.SetControl(nil)
+                       _ = succ
+                       return true
+               }
        case BlockIf:
                // match: (If (Not cond) yes no)
                // cond:
index 38c7a3b8474fa1bfc9657d95451800e0612908cc..7d7f9e11d380a19cf4c64762ad65e97fdec25a08 100644 (file)
@@ -781,6 +781,8 @@ func largeAlloc(size uintptr, needzero bool) *mspan {
 }
 
 // implementation of new builtin
+// compiler (both frontend and SSA backend) knows the signature
+// of this function
 func newobject(typ *_type) unsafe.Pointer {
        return mallocgc(typ.size, typ, true)
 }