mirror of
https://github.com/golang/go
synced 2024-11-24 18:20:02 -07:00
[dev.ssa] cmd/compile: small improvements
Found looking at mapaccess1_faststr. runtime.throw never returns. Do x+y+c with an LEA. Change-Id: I27ea6669324242a6302397cbdc73230891d97591 Reviewed-on: https://go-review.googlesource.com/19911 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
a5325761cd
commit
fb54e0305f
@ -544,8 +544,9 @@ func (s *state) stmt(n *Node) {
|
|||||||
// Expression statements
|
// Expression statements
|
||||||
case OCALLFUNC, OCALLMETH, OCALLINTER:
|
case OCALLFUNC, OCALLMETH, OCALLINTER:
|
||||||
s.call(n, callNormal)
|
s.call(n, callNormal)
|
||||||
if n.Op == OCALLFUNC && n.Left.Op == ONAME && n.Left.Class == PFUNC && n.Left.Sym.Pkg == Runtimepkg &&
|
if n.Op == OCALLFUNC && n.Left.Op == ONAME && n.Left.Class == PFUNC &&
|
||||||
(n.Left.Sym.Name == "gopanic" || n.Left.Sym.Name == "selectgo") {
|
(compiling_runtime != 0 && n.Left.Sym.Name == "throw" ||
|
||||||
|
n.Left.Sym.Pkg == Runtimepkg && (n.Left.Sym.Name == "gopanic" || n.Left.Sym.Name == "selectgo")) {
|
||||||
m := s.mem()
|
m := s.mem()
|
||||||
b := s.endBlock()
|
b := s.endBlock()
|
||||||
b.Kind = ssa.BlockExit
|
b.Kind = ssa.BlockExit
|
||||||
|
@ -34,6 +34,14 @@ Optimizations (better compiled code)
|
|||||||
flag regeneration.
|
flag regeneration.
|
||||||
- In forms like if ... { call } else { no call }, mark the call branch as unlikely.
|
- In forms like if ... { call } else { no call }, mark the call branch as unlikely.
|
||||||
- Non-constant rotate detection.
|
- Non-constant rotate detection.
|
||||||
|
- Do 0 <= x && x < n with one unsigned compare
|
||||||
|
- nil-check removal in indexed load/store case:
|
||||||
|
lea (%rdx,%rax,1),%rcx
|
||||||
|
test %al,(%rcx) // nil check
|
||||||
|
mov (%rdx,%rax,1),%cl // load to same address
|
||||||
|
- any pointer generated by unsafe arithmetic must be non-nil?
|
||||||
|
(Of course that may not be true in general, but it is for all uses
|
||||||
|
in the runtime, and we can play games with unsafe.)
|
||||||
|
|
||||||
Optimizations (better compiler)
|
Optimizations (better compiler)
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
@ -558,6 +558,11 @@
|
|||||||
(ADDQ x (ADDQ x y)) -> (LEAQ2 y x)
|
(ADDQ x (ADDQ x y)) -> (LEAQ2 y x)
|
||||||
(ADDQ x (ADDQ y x)) -> (LEAQ2 y x)
|
(ADDQ x (ADDQ y x)) -> (LEAQ2 y x)
|
||||||
|
|
||||||
|
// combine ADDQ/ADDQconst into LEAQ1
|
||||||
|
(ADDQconst [c] (ADDQ x y)) -> (LEAQ1 [c] x y)
|
||||||
|
(ADDQ (ADDQconst [c] x) y) -> (LEAQ1 [c] x y)
|
||||||
|
(ADDQ x (ADDQconst [c] y)) -> (LEAQ1 [c] x y)
|
||||||
|
|
||||||
// fold ADDQ into LEAQ
|
// fold ADDQ into LEAQ
|
||||||
(ADDQconst [c] (LEAQ [d] {s} x)) -> (LEAQ [c+d] {s} x)
|
(ADDQconst [c] (LEAQ [d] {s} x)) -> (LEAQ [c+d] {s} x)
|
||||||
(LEAQ [c] {s} (ADDQconst [d] x)) -> (LEAQ [c+d] {s} x)
|
(LEAQ [c] {s} (ADDQconst [d] x)) -> (LEAQ [c+d] {s} x)
|
||||||
@ -818,7 +823,6 @@
|
|||||||
(LEAQ [off1] {sym1} (LEAQ8 [off2] {sym2} x y)) && canMergeSym(sym1, sym2) ->
|
(LEAQ [off1] {sym1} (LEAQ8 [off2] {sym2} x y)) && canMergeSym(sym1, sym2) ->
|
||||||
(LEAQ8 [addOff(off1,off2)] {mergeSym(sym1,sym2)} x y)
|
(LEAQ8 [addOff(off1,off2)] {mergeSym(sym1,sym2)} x y)
|
||||||
|
|
||||||
|
|
||||||
// lower Zero instructions with word sizes
|
// lower Zero instructions with word sizes
|
||||||
(Zero [0] _ mem) -> mem
|
(Zero [0] _ mem) -> mem
|
||||||
(Zero [1] destptr mem) -> (MOVBstoreconst [0] destptr mem)
|
(Zero [1] destptr mem) -> (MOVBstoreconst [0] destptr mem)
|
||||||
|
@ -1075,6 +1075,38 @@ func rewriteValueAMD64_OpAMD64ADDQ(v *Value, config *Config) bool {
|
|||||||
v.AddArg(x)
|
v.AddArg(x)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
// match: (ADDQ (ADDQconst [c] x) y)
|
||||||
|
// cond:
|
||||||
|
// result: (LEAQ1 [c] x y)
|
||||||
|
for {
|
||||||
|
if v.Args[0].Op != OpAMD64ADDQconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v.Args[0].AuxInt
|
||||||
|
x := v.Args[0].Args[0]
|
||||||
|
y := v.Args[1]
|
||||||
|
v.reset(OpAMD64LEAQ1)
|
||||||
|
v.AuxInt = c
|
||||||
|
v.AddArg(x)
|
||||||
|
v.AddArg(y)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (ADDQ x (ADDQconst [c] y))
|
||||||
|
// cond:
|
||||||
|
// result: (LEAQ1 [c] x y)
|
||||||
|
for {
|
||||||
|
x := v.Args[0]
|
||||||
|
if v.Args[1].Op != OpAMD64ADDQconst {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v.Args[1].AuxInt
|
||||||
|
y := v.Args[1].Args[0]
|
||||||
|
v.reset(OpAMD64LEAQ1)
|
||||||
|
v.AuxInt = c
|
||||||
|
v.AddArg(x)
|
||||||
|
v.AddArg(y)
|
||||||
|
return true
|
||||||
|
}
|
||||||
// match: (ADDQ x (LEAQ [c] {s} y))
|
// match: (ADDQ x (LEAQ [c] {s} y))
|
||||||
// cond: x.Op != OpSB && y.Op != OpSB
|
// cond: x.Op != OpSB && y.Op != OpSB
|
||||||
// result: (LEAQ1 [c] {s} x y)
|
// result: (LEAQ1 [c] {s} x y)
|
||||||
@ -1136,6 +1168,22 @@ func rewriteValueAMD64_OpAMD64ADDQ(v *Value, config *Config) bool {
|
|||||||
func rewriteValueAMD64_OpAMD64ADDQconst(v *Value, config *Config) bool {
|
func rewriteValueAMD64_OpAMD64ADDQconst(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
_ = b
|
_ = b
|
||||||
|
// match: (ADDQconst [c] (ADDQ x y))
|
||||||
|
// cond:
|
||||||
|
// result: (LEAQ1 [c] x y)
|
||||||
|
for {
|
||||||
|
c := v.AuxInt
|
||||||
|
if v.Args[0].Op != OpAMD64ADDQ {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
x := v.Args[0].Args[0]
|
||||||
|
y := v.Args[0].Args[1]
|
||||||
|
v.reset(OpAMD64LEAQ1)
|
||||||
|
v.AuxInt = c
|
||||||
|
v.AddArg(x)
|
||||||
|
v.AddArg(y)
|
||||||
|
return true
|
||||||
|
}
|
||||||
// match: (ADDQconst [c] (LEAQ [d] {s} x))
|
// match: (ADDQconst [c] (LEAQ [d] {s} x))
|
||||||
// cond:
|
// cond:
|
||||||
// result: (LEAQ [c+d] {s} x)
|
// result: (LEAQ [c+d] {s} x)
|
||||||
|
Loading…
Reference in New Issue
Block a user