Commit 3dd4f74e authored by Keith Randall's avatar Keith Randall

cmd/compile: merge shifts into LEAs

Change-Id: I5a43c354f36184ae64a52268023c3222da3026d8
Reviewed-on: https://go-review.googlesource.com/20880
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarTodd Neal <todd@tneal.org>
parent 377eaa74
......@@ -571,7 +571,7 @@
(ADDQ x (LEAQ [c] {s} y)) && x.Op != OpSB && y.Op != OpSB -> (LEAQ1 [c] {s} x y)
(ADDQ (LEAQ [c] {s} x) y) && x.Op != OpSB && y.Op != OpSB -> (LEAQ1 [c] {s} x y)
// fold ADDQconst into leaqX
// fold ADDQconst into LEAQx
(ADDQconst [c] (LEAQ1 [d] {s} x y)) -> (LEAQ1 [c+d] {s} x y)
(ADDQconst [c] (LEAQ2 [d] {s} x y)) -> (LEAQ2 [c+d] {s} x y)
(ADDQconst [c] (LEAQ4 [d] {s} x y)) -> (LEAQ4 [c+d] {s} x y)
......@@ -585,6 +585,18 @@
(LEAQ8 [c] {s} (ADDQconst [d] x) y) && x.Op != OpSB -> (LEAQ8 [c+d] {s} x y)
(LEAQ8 [c] {s} x (ADDQconst [d] y)) && y.Op != OpSB -> (LEAQ8 [c+8*d] {s} x y)
// fold shifts into LEAQx
(LEAQ1 [c] {s} x (SHLQconst [1] y)) -> (LEAQ2 [c] {s} x y)
(LEAQ1 [c] {s} (SHLQconst [1] x) y) -> (LEAQ2 [c] {s} y x)
(LEAQ1 [c] {s} x (SHLQconst [2] y)) -> (LEAQ4 [c] {s} x y)
(LEAQ1 [c] {s} (SHLQconst [2] x) y) -> (LEAQ4 [c] {s} y x)
(LEAQ1 [c] {s} x (SHLQconst [3] y)) -> (LEAQ8 [c] {s} x y)
(LEAQ1 [c] {s} (SHLQconst [3] x) y) -> (LEAQ8 [c] {s} y x)
(LEAQ2 [c] {s} x (SHLQconst [1] y)) -> (LEAQ4 [c] {s} x y)
(LEAQ2 [c] {s} x (SHLQconst [2] y)) -> (LEAQ8 [c] {s} x y)
(LEAQ4 [c] {s} x (SHLQconst [1] y)) -> (LEAQ8 [c] {s} x y)
// reverse ordering of compare instruction
(SETL (InvertFlags x)) -> (SETG x)
(SETG (InvertFlags x)) -> (SETL x)
......
......@@ -4195,6 +4195,132 @@ func rewriteValueAMD64_OpAMD64LEAQ1(v *Value, config *Config) bool {
v.AddArg(y)
return true
}
// match: (LEAQ1 [c] {s} x (SHLQconst [1] y))
// cond:
// result: (LEAQ2 [c] {s} x y)
for {
c := v.AuxInt
s := v.Aux
x := v.Args[0]
if v.Args[1].Op != OpAMD64SHLQconst {
break
}
if v.Args[1].AuxInt != 1 {
break
}
y := v.Args[1].Args[0]
v.reset(OpAMD64LEAQ2)
v.AuxInt = c
v.Aux = s
v.AddArg(x)
v.AddArg(y)
return true
}
// match: (LEAQ1 [c] {s} (SHLQconst [1] x) y)
// cond:
// result: (LEAQ2 [c] {s} y x)
for {
c := v.AuxInt
s := v.Aux
if v.Args[0].Op != OpAMD64SHLQconst {
break
}
if v.Args[0].AuxInt != 1 {
break
}
x := v.Args[0].Args[0]
y := v.Args[1]
v.reset(OpAMD64LEAQ2)
v.AuxInt = c
v.Aux = s
v.AddArg(y)
v.AddArg(x)
return true
}
// match: (LEAQ1 [c] {s} x (SHLQconst [2] y))
// cond:
// result: (LEAQ4 [c] {s} x y)
for {
c := v.AuxInt
s := v.Aux
x := v.Args[0]
if v.Args[1].Op != OpAMD64SHLQconst {
break
}
if v.Args[1].AuxInt != 2 {
break
}
y := v.Args[1].Args[0]
v.reset(OpAMD64LEAQ4)
v.AuxInt = c
v.Aux = s
v.AddArg(x)
v.AddArg(y)
return true
}
// match: (LEAQ1 [c] {s} (SHLQconst [2] x) y)
// cond:
// result: (LEAQ4 [c] {s} y x)
for {
c := v.AuxInt
s := v.Aux
if v.Args[0].Op != OpAMD64SHLQconst {
break
}
if v.Args[0].AuxInt != 2 {
break
}
x := v.Args[0].Args[0]
y := v.Args[1]
v.reset(OpAMD64LEAQ4)
v.AuxInt = c
v.Aux = s
v.AddArg(y)
v.AddArg(x)
return true
}
// match: (LEAQ1 [c] {s} x (SHLQconst [3] y))
// cond:
// result: (LEAQ8 [c] {s} x y)
for {
c := v.AuxInt
s := v.Aux
x := v.Args[0]
if v.Args[1].Op != OpAMD64SHLQconst {
break
}
if v.Args[1].AuxInt != 3 {
break
}
y := v.Args[1].Args[0]
v.reset(OpAMD64LEAQ8)
v.AuxInt = c
v.Aux = s
v.AddArg(x)
v.AddArg(y)
return true
}
// match: (LEAQ1 [c] {s} (SHLQconst [3] x) y)
// cond:
// result: (LEAQ8 [c] {s} y x)
for {
c := v.AuxInt
s := v.Aux
if v.Args[0].Op != OpAMD64SHLQconst {
break
}
if v.Args[0].AuxInt != 3 {
break
}
x := v.Args[0].Args[0]
y := v.Args[1]
v.reset(OpAMD64LEAQ8)
v.AuxInt = c
v.Aux = s
v.AddArg(y)
v.AddArg(x)
return true
}
// match: (LEAQ1 [off1] {sym1} (LEAQ [off2] {sym2} x) y)
// cond: canMergeSym(sym1, sym2) && x.Op != OpSB
// result: (LEAQ1 [addOff(off1,off2)] {mergeSym(sym1,sym2)} x y)
......@@ -4290,6 +4416,48 @@ func rewriteValueAMD64_OpAMD64LEAQ2(v *Value, config *Config) bool {
v.AddArg(y)
return true
}
// match: (LEAQ2 [c] {s} x (SHLQconst [1] y))
// cond:
// result: (LEAQ4 [c] {s} x y)
for {
c := v.AuxInt
s := v.Aux
x := v.Args[0]
if v.Args[1].Op != OpAMD64SHLQconst {
break
}
if v.Args[1].AuxInt != 1 {
break
}
y := v.Args[1].Args[0]
v.reset(OpAMD64LEAQ4)
v.AuxInt = c
v.Aux = s
v.AddArg(x)
v.AddArg(y)
return true
}
// match: (LEAQ2 [c] {s} x (SHLQconst [2] y))
// cond:
// result: (LEAQ8 [c] {s} x y)
for {
c := v.AuxInt
s := v.Aux
x := v.Args[0]
if v.Args[1].Op != OpAMD64SHLQconst {
break
}
if v.Args[1].AuxInt != 2 {
break
}
y := v.Args[1].Args[0]
v.reset(OpAMD64LEAQ8)
v.AuxInt = c
v.Aux = s
v.AddArg(x)
v.AddArg(y)
return true
}
// match: (LEAQ2 [off1] {sym1} (LEAQ [off2] {sym2} x) y)
// cond: canMergeSym(sym1, sym2) && x.Op != OpSB
// result: (LEAQ2 [addOff(off1,off2)] {mergeSym(sym1,sym2)} x y)
......@@ -4362,6 +4530,27 @@ func rewriteValueAMD64_OpAMD64LEAQ4(v *Value, config *Config) bool {
v.AddArg(y)
return true
}
// match: (LEAQ4 [c] {s} x (SHLQconst [1] y))
// cond:
// result: (LEAQ8 [c] {s} x y)
for {
c := v.AuxInt
s := v.Aux
x := v.Args[0]
if v.Args[1].Op != OpAMD64SHLQconst {
break
}
if v.Args[1].AuxInt != 1 {
break
}
y := v.Args[1].Args[0]
v.reset(OpAMD64LEAQ8)
v.AuxInt = c
v.Aux = s
v.AddArg(x)
v.AddArg(y)
return true
}
// match: (LEAQ4 [off1] {sym1} (LEAQ [off2] {sym2} x) y)
// cond: canMergeSym(sym1, sym2) && x.Op != OpSB
// result: (LEAQ4 [addOff(off1,off2)] {mergeSym(sym1,sym2)} x y)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment