mirror of https://github.com/golang/go.git
[dev.ssa] cmd/compile : replace load of store with a copy
Loads of stores from the same pointer with compatible types can be replaced with a copy. Change-Id: I514b3ed8e5b6a9c432946880eac67a51b1607932 Reviewed-on: https://go-review.googlesource.com/19743 Run-TryBot: Todd Neal <todd@tneal.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
c3db6c95b6
commit
9dc1334cc7
|
|
@ -388,6 +388,11 @@
|
|||
(EqSlice x y) -> (EqPtr (SlicePtr x) (SlicePtr y))
|
||||
(NeqSlice x y) -> (NeqPtr (SlicePtr x) (SlicePtr y))
|
||||
|
||||
|
||||
// Load of store of same address, with compatibly typed value and same size
|
||||
(Load <t1> p1 (Store [w] p2 x _)) && isSamePtr(p1,p2) && t1.Compare(x.Type)==CMPeq && w == t1.Size() -> x
|
||||
|
||||
|
||||
// indexing operations
|
||||
// Note: bounds check has already been done
|
||||
(ArrayIndex (Load ptr mem) idx) && b == v.Args[0].Block -> (Load (PtrIndex <v.Type.PtrTo()> ptr idx) mem)
|
||||
|
|
|
|||
|
|
@ -202,6 +202,15 @@ func uaddOvf(a, b int64) bool {
|
|||
return uint64(a)+uint64(b) < uint64(a)
|
||||
}
|
||||
|
||||
// isSamePtr reports whether p1 and p2 point to the same address.
|
||||
func isSamePtr(p1, p2 *Value) bool {
|
||||
// Aux isn't used in OffPtr, and AuxInt isn't currently used in
|
||||
// Addr, but this still works as the values will be null/0
|
||||
return (p1.Op == OpOffPtr || p1.Op == OpAddr) && p1.Op == p2.Op &&
|
||||
p1.Aux == p2.Aux && p1.AuxInt == p2.AuxInt &&
|
||||
p1.Args[0] == p2.Args[0]
|
||||
}
|
||||
|
||||
// DUFFZERO consists of repeated blocks of 4 MOVUPSs + ADD,
|
||||
// See runtime/mkduff.go.
|
||||
const (
|
||||
|
|
|
|||
|
|
@ -2901,6 +2901,26 @@ func rewriteValuegeneric_OpLess8U(v *Value, config *Config) bool {
|
|||
func rewriteValuegeneric_OpLoad(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (Load <t1> p1 (Store [w] p2 x _))
|
||||
// cond: isSamePtr(p1,p2) && t1.Compare(x.Type)==CMPeq && w == t1.Size()
|
||||
// result: x
|
||||
for {
|
||||
t1 := v.Type
|
||||
p1 := v.Args[0]
|
||||
if v.Args[1].Op != OpStore {
|
||||
break
|
||||
}
|
||||
w := v.Args[1].AuxInt
|
||||
p2 := v.Args[1].Args[0]
|
||||
x := v.Args[1].Args[1]
|
||||
if !(isSamePtr(p1, p2) && t1.Compare(x.Type) == CMPeq && w == t1.Size()) {
|
||||
break
|
||||
}
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (Load <t> _ _)
|
||||
// cond: t.IsStruct() && t.NumFields() == 0 && config.fe.CanSSA(t)
|
||||
// result: (StructMake0)
|
||||
|
|
|
|||
Loading…
Reference in New Issue