]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: optimize unsafe.Slice generated code
authorKeith Randall <khr@golang.org>
Wed, 27 Jul 2022 16:56:38 +0000 (09:56 -0700)
committerKeith Randall <khr@golang.org>
Mon, 8 Aug 2022 17:36:47 +0000 (17:36 +0000)
We don't need a multiply when the element type is size 0 or 1.

The panic functions don't return, so we don't need any post-call
code (register restores, etc.).

Change-Id: I0dcea5df56d29d7be26554ddca966b3903c672e5
Reviewed-on: https://go-review.googlesource.com/c/go/+/419754
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go
src/cmd/compile/internal/ssagen/ssa.go
test/codegen/slices.go

index d5cc107fab7b5bae5a9f65e39102cd8b1394186a..744cc839f424b447e20611415936d61e4073ed1b 100644 (file)
 
 // Convert x * 1 to x.
 (Mul(8|16|32|64)  (Const(8|16|32|64)  [1]) x) => x
+(Select0 (Mul(32|64)uover (Const(32|64) [1]) x)) => x
+(Select1 (Mul(32|64)uover (Const(32|64) [1]) x)) => (ConstBool [false])
 
 // Convert x * -1 to -x.
 (Mul(8|16|32|64)  (Const(8|16|32|64)  [-1]) x) => (Neg(8|16|32|64)  x)
 (Add(64|32|16|8) (Const(64|32|16|8) [0]) x) => x
 (Sub(64|32|16|8) x x) => (Const(64|32|16|8) [0])
 (Mul(64|32|16|8) (Const(64|32|16|8) [0]) _) => (Const(64|32|16|8) [0])
+(Select0 (Mul(64|32)uover (Const(64|32) [0]) x)) => (Const(64|32) [0])
+(Select1 (Mul(64|32)uover (Const(64|32) [0]) x)) => (ConstBool [false])
 
 (Com(64|32|16|8) (Com(64|32|16|8)  x)) => x
 (Com(64|32|16|8) (Const(64|32|16|8) [c])) => (Const(64|32|16|8) [^c])
index f61b6ca3ececa76c777c7015e0221b9d495f5ed9..99346edd4b2cdffa721505672b523c2201893a71 100644 (file)
@@ -21260,6 +21260,82 @@ func rewriteValuegeneric_OpSelect0(v *Value) bool {
                v.AddArg2(lo, y)
                return true
        }
+       // match: (Select0 (Mul32uover (Const32 [1]) x))
+       // result: x
+       for {
+               if v_0.Op != OpMul32uover {
+                       break
+               }
+               _ = v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+                       if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 1 {
+                               continue
+                       }
+                       x := v_0_1
+                       v.copyOf(x)
+                       return true
+               }
+               break
+       }
+       // match: (Select0 (Mul64uover (Const64 [1]) x))
+       // result: x
+       for {
+               if v_0.Op != OpMul64uover {
+                       break
+               }
+               _ = v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+                       if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 1 {
+                               continue
+                       }
+                       x := v_0_1
+                       v.copyOf(x)
+                       return true
+               }
+               break
+       }
+       // match: (Select0 (Mul64uover (Const64 [0]) x))
+       // result: (Const64 [0])
+       for {
+               if v_0.Op != OpMul64uover {
+                       break
+               }
+               _ = v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+                       if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
+                               continue
+                       }
+                       v.reset(OpConst64)
+                       v.AuxInt = int64ToAuxInt(0)
+                       return true
+               }
+               break
+       }
+       // match: (Select0 (Mul32uover (Const32 [0]) x))
+       // result: (Const32 [0])
+       for {
+               if v_0.Op != OpMul32uover {
+                       break
+               }
+               _ = v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+                       if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 0 {
+                               continue
+                       }
+                       v.reset(OpConst32)
+                       v.AuxInt = int32ToAuxInt(0)
+                       return true
+               }
+               break
+       }
        return false
 }
 func rewriteValuegeneric_OpSelect1(v *Value) bool {
@@ -21280,6 +21356,82 @@ func rewriteValuegeneric_OpSelect1(v *Value) bool {
                v.AddArg2(lo, y)
                return true
        }
+       // match: (Select1 (Mul32uover (Const32 [1]) x))
+       // result: (ConstBool [false])
+       for {
+               if v_0.Op != OpMul32uover {
+                       break
+               }
+               _ = v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+                       if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 1 {
+                               continue
+                       }
+                       v.reset(OpConstBool)
+                       v.AuxInt = boolToAuxInt(false)
+                       return true
+               }
+               break
+       }
+       // match: (Select1 (Mul64uover (Const64 [1]) x))
+       // result: (ConstBool [false])
+       for {
+               if v_0.Op != OpMul64uover {
+                       break
+               }
+               _ = v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+                       if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 1 {
+                               continue
+                       }
+                       v.reset(OpConstBool)
+                       v.AuxInt = boolToAuxInt(false)
+                       return true
+               }
+               break
+       }
+       // match: (Select1 (Mul64uover (Const64 [0]) x))
+       // result: (ConstBool [false])
+       for {
+               if v_0.Op != OpMul64uover {
+                       break
+               }
+               _ = v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+                       if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
+                               continue
+                       }
+                       v.reset(OpConstBool)
+                       v.AuxInt = boolToAuxInt(false)
+                       return true
+               }
+               break
+       }
+       // match: (Select1 (Mul32uover (Const32 [0]) x))
+       // result: (ConstBool [false])
+       for {
+               if v_0.Op != OpMul32uover {
+                       break
+               }
+               _ = v_0.Args[1]
+               v_0_0 := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+                       if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 0 {
+                               continue
+                       }
+                       v.reset(OpConstBool)
+                       v.AuxInt = boolToAuxInt(false)
+                       return true
+               }
+               break
+       }
        return false
 }
 func rewriteValuegeneric_OpSelectN(v *Value) bool {
index 86b5358e3cc2daef6ecc58dcdc9b6f645dddd51d..805b47ce7d30c6eae65c8bd064351c308bcaa281 100644 (file)
@@ -1421,7 +1421,7 @@ func (s *state) stmt(n ir.Node) {
                s.callResult(n, callNormal)
                if n.Op() == ir.OCALLFUNC && n.X.Op() == ir.ONAME && n.X.(*ir.Name).Class == ir.PFUNC {
                        if fn := n.X.Sym().Name; base.Flag.CompilingRuntime && fn == "throw" ||
-                               n.X.Sym().Pkg == ir.Pkgs.Runtime && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap") {
+                               n.X.Sym().Pkg == ir.Pkgs.Runtime && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap" || fn == "panicunsafeslicelen" || fn == "panicunsafeslicenilptr") {
                                m := s.mem()
                                b := s.endBlock()
                                b.Kind = ssa.BlockExit
index d20aa9eddfa4447192610f2d54a08eea7776741d..99bdd50e5234e4b46e68b5481944bca1cd38e31a 100644 (file)
@@ -6,6 +6,8 @@
 
 package codegen
 
+import "unsafe"
+
 // This file contains code generation tests related to the handling of
 // slice types.
 
@@ -368,3 +370,16 @@ func SliceWithSubtractBound(a []int, b int) []int {
        // ppc64:"SUBC",-"NEG"
        return a[(3 - b):]
 }
+
+// --------------------------------------- //
+//   Code generation for unsafe.Slice      //
+// --------------------------------------- //
+
+func Slice1(p *byte, i int) []byte {
+       // amd64:-"MULQ"
+       return unsafe.Slice(p, i)
+}
+func Slice0(p *struct{}, i int) []struct{} {
+       // amd64:-"MULQ"
+       return unsafe.Slice(p, i)
+}