mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile/internal/ssa: lower builtins much later
* Move lowering into a separate pass. * SliceLen/SliceCap is now available to various intermediate passes which use useful for bounds checking. * Add a second opt pass to handle the new opportunities Decreases the code size of binaries in pkg/tool/linux_amd64 by ~45K. Updates #14564 #14606 Change-Id: I5b2bd6202181c50623a3585fbf15c0d6db6d4685 Reviewed-on: https://go-review.googlesource.com/20172 Run-TryBot: Alexandru Moșoi <alexandru@mosoi.ro> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
aa3650f019
commit
dfcb853d9d
7 changed files with 198 additions and 35 deletions
|
|
@ -182,6 +182,8 @@ var passes = [...]pass{
|
||||||
{name: "phiopt", fn: phiopt},
|
{name: "phiopt", fn: phiopt},
|
||||||
{name: "nilcheckelim", fn: nilcheckelim},
|
{name: "nilcheckelim", fn: nilcheckelim},
|
||||||
{name: "prove", fn: prove},
|
{name: "prove", fn: prove},
|
||||||
|
{name: "dec", fn: dec, required: true},
|
||||||
|
{name: "late opt", fn: opt}, // TODO: split required rules and optimizing rules
|
||||||
{name: "generic deadcode", fn: deadcode},
|
{name: "generic deadcode", fn: deadcode},
|
||||||
{name: "fuse", fn: fuse},
|
{name: "fuse", fn: fuse},
|
||||||
{name: "dse", fn: dse},
|
{name: "dse", fn: dse},
|
||||||
|
|
|
||||||
6
src/cmd/compile/internal/ssa/gen/dec.rules
Normal file
6
src/cmd/compile/internal/ssa/gen/dec.rules
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
(StringPtr (StringMake ptr _)) -> ptr
|
||||||
|
(StringLen (StringMake _ len)) -> len
|
||||||
|
|
||||||
|
(SlicePtr (SliceMake ptr _ _ )) -> ptr
|
||||||
|
(SliceLen (SliceMake _ len _)) -> len
|
||||||
|
(SliceCap (SliceMake _ _ cap)) -> cap
|
||||||
13
src/cmd/compile/internal/ssa/gen/decOps.go
Normal file
13
src/cmd/compile/internal/ssa/gen/decOps.go
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2015 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 main
|
||||||
|
|
||||||
|
var decOps = []opData{}
|
||||||
|
|
||||||
|
var decBlocks = []blockData{}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
archs = append(archs, arch{"dec", decOps, decBlocks, nil})
|
||||||
|
}
|
||||||
|
|
@ -511,8 +511,8 @@
|
||||||
(Store [8] dst real mem))
|
(Store [8] dst real mem))
|
||||||
|
|
||||||
// string ops
|
// string ops
|
||||||
(StringPtr (StringMake ptr _)) -> ptr
|
(StringPtr (StringMake (Const64 <t> [c]) _)) -> (Const64 <t> [c])
|
||||||
(StringLen (StringMake _ len)) -> len
|
(StringLen (StringMake _ (Const64 <t> [c]))) -> (Const64 <t> [c])
|
||||||
(ConstString {s}) && config.PtrSize == 4 && s.(string) == "" ->
|
(ConstString {s}) && config.PtrSize == 4 && s.(string) == "" ->
|
||||||
(StringMake (ConstNil) (Const32 <config.fe.TypeInt()> [0]))
|
(StringMake (ConstNil) (Const32 <config.fe.TypeInt()> [0]))
|
||||||
(ConstString {s}) && config.PtrSize == 8 && s.(string) == "" ->
|
(ConstString {s}) && config.PtrSize == 8 && s.(string) == "" ->
|
||||||
|
|
@ -540,9 +540,9 @@
|
||||||
(Store [config.PtrSize] dst ptr mem))
|
(Store [config.PtrSize] dst ptr mem))
|
||||||
|
|
||||||
// slice ops
|
// slice ops
|
||||||
(SlicePtr (SliceMake ptr _ _ )) -> ptr
|
(SlicePtr (SliceMake (Const64 <t> [c]) _ _)) -> (Const64 <t> [c])
|
||||||
(SliceLen (SliceMake _ len _)) -> len
|
(SliceLen (SliceMake _ (Const64 <t> [c]) _)) -> (Const64 <t> [c])
|
||||||
(SliceCap (SliceMake _ _ cap)) -> cap
|
(SliceCap (SliceMake _ _ (Const64 <t> [c]))) -> (Const64 <t> [c])
|
||||||
(ConstSlice) && config.PtrSize == 4 ->
|
(ConstSlice) && config.PtrSize == 4 ->
|
||||||
(SliceMake
|
(SliceMake
|
||||||
(ConstNil <config.fe.TypeBytePtr()>)
|
(ConstNil <config.fe.TypeBytePtr()>)
|
||||||
|
|
|
||||||
|
|
@ -8,3 +8,7 @@ package ssa
|
||||||
func opt(f *Func) {
|
func opt(f *Func) {
|
||||||
applyRewrite(f, rewriteBlockgeneric, rewriteValuegeneric)
|
applyRewrite(f, rewriteBlockgeneric, rewriteValuegeneric)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func dec(f *Func) {
|
||||||
|
applyRewrite(f, rewriteBlockdec, rewriteValuedec)
|
||||||
|
}
|
||||||
|
|
|
||||||
118
src/cmd/compile/internal/ssa/rewritedec.go
Normal file
118
src/cmd/compile/internal/ssa/rewritedec.go
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
// autogenerated from gen/dec.rules: do not edit!
|
||||||
|
// generated with: cd gen; go run *.go
|
||||||
|
|
||||||
|
package ssa
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
var _ = math.MinInt8 // in case not otherwise used
|
||||||
|
func rewriteValuedec(v *Value, config *Config) bool {
|
||||||
|
switch v.Op {
|
||||||
|
case OpSliceCap:
|
||||||
|
return rewriteValuedec_OpSliceCap(v, config)
|
||||||
|
case OpSliceLen:
|
||||||
|
return rewriteValuedec_OpSliceLen(v, config)
|
||||||
|
case OpSlicePtr:
|
||||||
|
return rewriteValuedec_OpSlicePtr(v, config)
|
||||||
|
case OpStringLen:
|
||||||
|
return rewriteValuedec_OpStringLen(v, config)
|
||||||
|
case OpStringPtr:
|
||||||
|
return rewriteValuedec_OpStringPtr(v, config)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func rewriteValuedec_OpSliceCap(v *Value, config *Config) bool {
|
||||||
|
b := v.Block
|
||||||
|
_ = b
|
||||||
|
// match: (SliceCap (SliceMake _ _ cap))
|
||||||
|
// cond:
|
||||||
|
// result: cap
|
||||||
|
for {
|
||||||
|
if v.Args[0].Op != OpSliceMake {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
cap := v.Args[0].Args[2]
|
||||||
|
v.reset(OpCopy)
|
||||||
|
v.Type = cap.Type
|
||||||
|
v.AddArg(cap)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func rewriteValuedec_OpSliceLen(v *Value, config *Config) bool {
|
||||||
|
b := v.Block
|
||||||
|
_ = b
|
||||||
|
// match: (SliceLen (SliceMake _ len _))
|
||||||
|
// cond:
|
||||||
|
// result: len
|
||||||
|
for {
|
||||||
|
if v.Args[0].Op != OpSliceMake {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
len := v.Args[0].Args[1]
|
||||||
|
v.reset(OpCopy)
|
||||||
|
v.Type = len.Type
|
||||||
|
v.AddArg(len)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func rewriteValuedec_OpSlicePtr(v *Value, config *Config) bool {
|
||||||
|
b := v.Block
|
||||||
|
_ = b
|
||||||
|
// match: (SlicePtr (SliceMake ptr _ _ ))
|
||||||
|
// cond:
|
||||||
|
// result: ptr
|
||||||
|
for {
|
||||||
|
if v.Args[0].Op != OpSliceMake {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
ptr := v.Args[0].Args[0]
|
||||||
|
v.reset(OpCopy)
|
||||||
|
v.Type = ptr.Type
|
||||||
|
v.AddArg(ptr)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func rewriteValuedec_OpStringLen(v *Value, config *Config) bool {
|
||||||
|
b := v.Block
|
||||||
|
_ = b
|
||||||
|
// match: (StringLen (StringMake _ len))
|
||||||
|
// cond:
|
||||||
|
// result: len
|
||||||
|
for {
|
||||||
|
if v.Args[0].Op != OpStringMake {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
len := v.Args[0].Args[1]
|
||||||
|
v.reset(OpCopy)
|
||||||
|
v.Type = len.Type
|
||||||
|
v.AddArg(len)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func rewriteValuedec_OpStringPtr(v *Value, config *Config) bool {
|
||||||
|
b := v.Block
|
||||||
|
_ = b
|
||||||
|
// match: (StringPtr (StringMake ptr _))
|
||||||
|
// cond:
|
||||||
|
// result: ptr
|
||||||
|
for {
|
||||||
|
if v.Args[0].Op != OpStringMake {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
ptr := v.Args[0].Args[0]
|
||||||
|
v.reset(OpCopy)
|
||||||
|
v.Type = ptr.Type
|
||||||
|
v.AddArg(ptr)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func rewriteBlockdec(b *Block) bool {
|
||||||
|
switch b.Kind {
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
@ -6564,17 +6564,21 @@ func rewriteValuegeneric_OpRsh8x8(v *Value, config *Config) bool {
|
||||||
func rewriteValuegeneric_OpSliceCap(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpSliceCap(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
_ = b
|
_ = b
|
||||||
// match: (SliceCap (SliceMake _ _ cap))
|
// match: (SliceCap (SliceMake _ _ (Const64 <t> [c])))
|
||||||
// cond:
|
// cond:
|
||||||
// result: cap
|
// result: (Const64 <t> [c])
|
||||||
for {
|
for {
|
||||||
if v.Args[0].Op != OpSliceMake {
|
if v.Args[0].Op != OpSliceMake {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
cap := v.Args[0].Args[2]
|
if v.Args[0].Args[2].Op != OpConst64 {
|
||||||
v.reset(OpCopy)
|
break
|
||||||
v.Type = cap.Type
|
}
|
||||||
v.AddArg(cap)
|
t := v.Args[0].Args[2].Type
|
||||||
|
c := v.Args[0].Args[2].AuxInt
|
||||||
|
v.reset(OpConst64)
|
||||||
|
v.Type = t
|
||||||
|
v.AuxInt = c
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
@ -6582,17 +6586,21 @@ func rewriteValuegeneric_OpSliceCap(v *Value, config *Config) bool {
|
||||||
func rewriteValuegeneric_OpSliceLen(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpSliceLen(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
_ = b
|
_ = b
|
||||||
// match: (SliceLen (SliceMake _ len _))
|
// match: (SliceLen (SliceMake _ (Const64 <t> [c]) _))
|
||||||
// cond:
|
// cond:
|
||||||
// result: len
|
// result: (Const64 <t> [c])
|
||||||
for {
|
for {
|
||||||
if v.Args[0].Op != OpSliceMake {
|
if v.Args[0].Op != OpSliceMake {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
len := v.Args[0].Args[1]
|
if v.Args[0].Args[1].Op != OpConst64 {
|
||||||
v.reset(OpCopy)
|
break
|
||||||
v.Type = len.Type
|
}
|
||||||
v.AddArg(len)
|
t := v.Args[0].Args[1].Type
|
||||||
|
c := v.Args[0].Args[1].AuxInt
|
||||||
|
v.reset(OpConst64)
|
||||||
|
v.Type = t
|
||||||
|
v.AuxInt = c
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
@ -6600,17 +6608,21 @@ func rewriteValuegeneric_OpSliceLen(v *Value, config *Config) bool {
|
||||||
func rewriteValuegeneric_OpSlicePtr(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpSlicePtr(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
_ = b
|
_ = b
|
||||||
// match: (SlicePtr (SliceMake ptr _ _ ))
|
// match: (SlicePtr (SliceMake (Const64 <t> [c]) _ _))
|
||||||
// cond:
|
// cond:
|
||||||
// result: ptr
|
// result: (Const64 <t> [c])
|
||||||
for {
|
for {
|
||||||
if v.Args[0].Op != OpSliceMake {
|
if v.Args[0].Op != OpSliceMake {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
ptr := v.Args[0].Args[0]
|
if v.Args[0].Args[0].Op != OpConst64 {
|
||||||
v.reset(OpCopy)
|
break
|
||||||
v.Type = ptr.Type
|
}
|
||||||
v.AddArg(ptr)
|
t := v.Args[0].Args[0].Type
|
||||||
|
c := v.Args[0].Args[0].AuxInt
|
||||||
|
v.reset(OpConst64)
|
||||||
|
v.Type = t
|
||||||
|
v.AuxInt = c
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
@ -6973,17 +6985,21 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
|
||||||
func rewriteValuegeneric_OpStringLen(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpStringLen(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
_ = b
|
_ = b
|
||||||
// match: (StringLen (StringMake _ len))
|
// match: (StringLen (StringMake _ (Const64 <t> [c])))
|
||||||
// cond:
|
// cond:
|
||||||
// result: len
|
// result: (Const64 <t> [c])
|
||||||
for {
|
for {
|
||||||
if v.Args[0].Op != OpStringMake {
|
if v.Args[0].Op != OpStringMake {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
len := v.Args[0].Args[1]
|
if v.Args[0].Args[1].Op != OpConst64 {
|
||||||
v.reset(OpCopy)
|
break
|
||||||
v.Type = len.Type
|
}
|
||||||
v.AddArg(len)
|
t := v.Args[0].Args[1].Type
|
||||||
|
c := v.Args[0].Args[1].AuxInt
|
||||||
|
v.reset(OpConst64)
|
||||||
|
v.Type = t
|
||||||
|
v.AuxInt = c
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
@ -6991,17 +7007,21 @@ func rewriteValuegeneric_OpStringLen(v *Value, config *Config) bool {
|
||||||
func rewriteValuegeneric_OpStringPtr(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpStringPtr(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
_ = b
|
_ = b
|
||||||
// match: (StringPtr (StringMake ptr _))
|
// match: (StringPtr (StringMake (Const64 <t> [c]) _))
|
||||||
// cond:
|
// cond:
|
||||||
// result: ptr
|
// result: (Const64 <t> [c])
|
||||||
for {
|
for {
|
||||||
if v.Args[0].Op != OpStringMake {
|
if v.Args[0].Op != OpStringMake {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
ptr := v.Args[0].Args[0]
|
if v.Args[0].Args[0].Op != OpConst64 {
|
||||||
v.reset(OpCopy)
|
break
|
||||||
v.Type = ptr.Type
|
}
|
||||||
v.AddArg(ptr)
|
t := v.Args[0].Args[0].Type
|
||||||
|
c := v.Args[0].Args[0].AuxInt
|
||||||
|
v.reset(OpConst64)
|
||||||
|
v.Type = t
|
||||||
|
v.AuxInt = c
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue