mirror of
https://github.com/golang/go
synced 2024-10-05 19:11:22 -06:00
[dev.ssa] cmd/compile: implement OGETG
Change-Id: I7ecf62cf399c710b4a617803c43e83fce09b8a7d Reviewed-on: https://go-review.googlesource.com/13585 Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
bbf8c5ce2f
commit
3d23afb913
@ -1340,6 +1340,10 @@ func (s *state) expr(n *Node) *ssa.Value {
|
|||||||
}
|
}
|
||||||
a := s.entryNewValue1I(ssa.OpOffPtr, Ptrto(fp.Type), fp.Width, s.sp)
|
a := s.entryNewValue1I(ssa.OpOffPtr, Ptrto(fp.Type), fp.Width, s.sp)
|
||||||
return s.newValue2(ssa.OpLoad, fp.Type, a, call)
|
return s.newValue2(ssa.OpLoad, fp.Type, a, call)
|
||||||
|
|
||||||
|
case OGETG:
|
||||||
|
return s.newValue0(ssa.OpGetG, n.Type)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
s.Unimplementedf("unhandled expr %s", opnames[n.Op])
|
s.Unimplementedf("unhandled expr %s", opnames[n.Op])
|
||||||
return nil
|
return nil
|
||||||
@ -2185,6 +2189,33 @@ func genValue(v *ssa.Value) {
|
|||||||
q.From.Reg = x86.REG_AX
|
q.From.Reg = x86.REG_AX
|
||||||
q.To.Type = obj.TYPE_MEM
|
q.To.Type = obj.TYPE_MEM
|
||||||
q.To.Reg = x86.REG_AX
|
q.To.Reg = x86.REG_AX
|
||||||
|
case ssa.OpAMD64LoweredGetG:
|
||||||
|
r := regnum(v)
|
||||||
|
// See the comments in cmd/internal/obj/x86/obj6.go
|
||||||
|
// near CanUse1InsnTLS for a detailed explanation of these instructions.
|
||||||
|
if x86.CanUse1InsnTLS(Ctxt) {
|
||||||
|
// MOVQ (TLS), r
|
||||||
|
p := Prog(x86.AMOVQ)
|
||||||
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Reg = x86.REG_TLS
|
||||||
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = r
|
||||||
|
} else {
|
||||||
|
// MOVQ TLS, r
|
||||||
|
// MOVQ (r)(TLS*1), r
|
||||||
|
p := Prog(x86.AMOVQ)
|
||||||
|
p.From.Type = obj.TYPE_REG
|
||||||
|
p.From.Reg = x86.REG_TLS
|
||||||
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = r
|
||||||
|
q := Prog(x86.AMOVQ)
|
||||||
|
q.From.Type = obj.TYPE_MEM
|
||||||
|
q.From.Reg = r
|
||||||
|
q.From.Index = x86.REG_TLS
|
||||||
|
q.From.Scale = 1
|
||||||
|
q.To.Type = obj.TYPE_REG
|
||||||
|
q.To.Reg = r
|
||||||
|
}
|
||||||
case ssa.OpAMD64CALLstatic:
|
case ssa.OpAMD64CALLstatic:
|
||||||
p := Prog(obj.ACALL)
|
p := Prog(obj.ACALL)
|
||||||
p.To.Type = obj.TYPE_MEM
|
p.To.Type = obj.TYPE_MEM
|
||||||
|
@ -217,6 +217,7 @@
|
|||||||
(IsInBounds idx len) -> (SETB (CMPQ <TypeFlags> idx len))
|
(IsInBounds idx len) -> (SETB (CMPQ <TypeFlags> idx len))
|
||||||
|
|
||||||
(PanicNilCheck ptr mem) -> (LoweredPanicNilCheck ptr mem)
|
(PanicNilCheck ptr mem) -> (LoweredPanicNilCheck ptr mem)
|
||||||
|
(GetG) -> (LoweredGetG)
|
||||||
|
|
||||||
(Move [size] dst src mem) -> (REPMOVSB dst src (MOVQconst <config.Frontend().TypeUInt64()> [size]) mem)
|
(Move [size] dst src mem) -> (REPMOVSB dst src (MOVQconst <config.Frontend().TypeUInt64()> [size]) mem)
|
||||||
|
|
||||||
|
@ -288,8 +288,9 @@ func init() {
|
|||||||
// InvertFlags is a pseudo-op which can't appear in assembly output.
|
// InvertFlags is a pseudo-op which can't appear in assembly output.
|
||||||
{name: "InvertFlags"}, // reverse direction of arg0
|
{name: "InvertFlags"}, // reverse direction of arg0
|
||||||
|
|
||||||
// LoweredPanicNilCheck is a pseudo-op.
|
// Pseudo-ops
|
||||||
{name: "LoweredPanicNilCheck"},
|
{name: "LoweredPanicNilCheck"},
|
||||||
|
{name: "LoweredGetG"},
|
||||||
}
|
}
|
||||||
|
|
||||||
var AMD64blocks = []blockData{
|
var AMD64blocks = []blockData{
|
||||||
|
@ -71,6 +71,8 @@
|
|||||||
(StringLen (StringMake _ len)) -> len
|
(StringLen (StringMake _ len)) -> len
|
||||||
(Store dst str mem) && str.Type.IsString() -> (Store (OffPtr <config.Frontend().TypeBytePtr()> [config.PtrSize] dst) (StringLen <config.Frontend().TypeUintptr()> str) (Store <TypeMem> dst (StringPtr <config.Frontend().TypeBytePtr()> str) mem))
|
(Store dst str mem) && str.Type.IsString() -> (Store (OffPtr <config.Frontend().TypeBytePtr()> [config.PtrSize] dst) (StringLen <config.Frontend().TypeUintptr()> str) (Store <TypeMem> dst (StringPtr <config.Frontend().TypeBytePtr()> str) mem))
|
||||||
|
|
||||||
|
(If (IsNonNil (GetG)) yes no) -> (Plain nil yes)
|
||||||
|
|
||||||
(If (Not cond) yes no) -> (If cond no yes)
|
(If (Not cond) yes no) -> (If cond no yes)
|
||||||
(If (ConstBool {c}) yes no) && c.(bool) -> (Plain nil yes)
|
(If (ConstBool {c}) yes no) && c.(bool) -> (Plain nil yes)
|
||||||
(If (ConstBool {c}) yes no) && !c.(bool) -> (Plain nil no)
|
(If (ConstBool {c}) yes no) && !c.(bool) -> (Plain nil no)
|
||||||
|
@ -252,7 +252,9 @@ var genericOps = []opData{
|
|||||||
{name: "IsNonNil"}, // arg0 != nil
|
{name: "IsNonNil"}, // arg0 != nil
|
||||||
{name: "IsInBounds"}, // 0 <= arg0 < arg1
|
{name: "IsInBounds"}, // 0 <= arg0 < arg1
|
||||||
|
|
||||||
|
// Pseudo-ops
|
||||||
{name: "PanicNilCheck"}, // trigger a dereference fault; arg0=nil ptr, arg1=mem
|
{name: "PanicNilCheck"}, // trigger a dereference fault; arg0=nil ptr, arg1=mem
|
||||||
|
{name: "GetG"}, // runtime.getg() (read g pointer)
|
||||||
|
|
||||||
// Indexing operations
|
// Indexing operations
|
||||||
{name: "ArrayIndex"}, // arg0=array, arg1=index. Returns a[i]
|
{name: "ArrayIndex"}, // arg0=array, arg1=index. Returns a[i]
|
||||||
|
@ -195,6 +195,7 @@ const (
|
|||||||
OpAMD64REPMOVSB
|
OpAMD64REPMOVSB
|
||||||
OpAMD64InvertFlags
|
OpAMD64InvertFlags
|
||||||
OpAMD64LoweredPanicNilCheck
|
OpAMD64LoweredPanicNilCheck
|
||||||
|
OpAMD64LoweredGetG
|
||||||
|
|
||||||
OpAdd8
|
OpAdd8
|
||||||
OpAdd16
|
OpAdd16
|
||||||
@ -369,6 +370,7 @@ const (
|
|||||||
OpIsNonNil
|
OpIsNonNil
|
||||||
OpIsInBounds
|
OpIsInBounds
|
||||||
OpPanicNilCheck
|
OpPanicNilCheck
|
||||||
|
OpGetG
|
||||||
OpArrayIndex
|
OpArrayIndex
|
||||||
OpPtrIndex
|
OpPtrIndex
|
||||||
OpOffPtr
|
OpOffPtr
|
||||||
@ -2119,6 +2121,10 @@ var opcodeTable = [...]opInfo{
|
|||||||
name: "LoweredPanicNilCheck",
|
name: "LoweredPanicNilCheck",
|
||||||
reg: regInfo{},
|
reg: regInfo{},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "LoweredGetG",
|
||||||
|
reg: regInfo{},
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: "Add8",
|
name: "Add8",
|
||||||
@ -2812,6 +2818,10 @@ var opcodeTable = [...]opInfo{
|
|||||||
name: "PanicNilCheck",
|
name: "PanicNilCheck",
|
||||||
generic: true,
|
generic: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "GetG",
|
||||||
|
generic: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "ArrayIndex",
|
name: "ArrayIndex",
|
||||||
generic: true,
|
generic: true,
|
||||||
|
@ -1893,6 +1893,20 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
|
|||||||
goto endd30ee67afc0284c419cef70261f61452
|
goto endd30ee67afc0284c419cef70261f61452
|
||||||
endd30ee67afc0284c419cef70261f61452:
|
endd30ee67afc0284c419cef70261f61452:
|
||||||
;
|
;
|
||||||
|
case OpGetG:
|
||||||
|
// match: (GetG)
|
||||||
|
// cond:
|
||||||
|
// result: (LoweredGetG)
|
||||||
|
{
|
||||||
|
v.Op = OpAMD64LoweredGetG
|
||||||
|
v.AuxInt = 0
|
||||||
|
v.Aux = nil
|
||||||
|
v.resetArgs()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
goto endb17140e71dd641aa4d89e14479160260
|
||||||
|
endb17140e71dd641aa4d89e14479160260:
|
||||||
|
;
|
||||||
case OpGreater16:
|
case OpGreater16:
|
||||||
// match: (Greater16 x y)
|
// match: (Greater16 x y)
|
||||||
// cond:
|
// cond:
|
||||||
|
@ -782,6 +782,30 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
|||||||
func rewriteBlockgeneric(b *Block) bool {
|
func rewriteBlockgeneric(b *Block) bool {
|
||||||
switch b.Kind {
|
switch b.Kind {
|
||||||
case BlockIf:
|
case BlockIf:
|
||||||
|
// match: (If (IsNonNil (GetG)) yes no)
|
||||||
|
// cond:
|
||||||
|
// result: (Plain nil yes)
|
||||||
|
{
|
||||||
|
v := b.Control
|
||||||
|
if v.Op != OpIsNonNil {
|
||||||
|
goto end0f2bb0111a86be0436b44210dbd83a90
|
||||||
|
}
|
||||||
|
if v.Args[0].Op != OpGetG {
|
||||||
|
goto end0f2bb0111a86be0436b44210dbd83a90
|
||||||
|
}
|
||||||
|
yes := b.Succs[0]
|
||||||
|
no := b.Succs[1]
|
||||||
|
b.Func.removePredecessor(b, no)
|
||||||
|
b.Kind = BlockPlain
|
||||||
|
b.Control = nil
|
||||||
|
b.Succs = b.Succs[:1]
|
||||||
|
b.Succs[0] = yes
|
||||||
|
b.Likely = BranchUnknown
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
goto end0f2bb0111a86be0436b44210dbd83a90
|
||||||
|
end0f2bb0111a86be0436b44210dbd83a90:
|
||||||
|
;
|
||||||
// match: (If (Not cond) yes no)
|
// match: (If (Not cond) yes no)
|
||||||
// cond:
|
// cond:
|
||||||
// result: (If cond no yes)
|
// result: (If cond no yes)
|
||||||
|
@ -38,7 +38,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
func canuse1insntls(ctxt *obj.Link) bool {
|
func CanUse1InsnTLS(ctxt *obj.Link) bool {
|
||||||
if ctxt.Arch.Regsize == 4 {
|
if ctxt.Arch.Regsize == 4 {
|
||||||
switch ctxt.Headtype {
|
switch ctxt.Headtype {
|
||||||
case obj.Hlinux,
|
case obj.Hlinux,
|
||||||
@ -120,7 +120,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
|||||||
// rewriting the instructions more comprehensively, and it only does because
|
// rewriting the instructions more comprehensively, and it only does because
|
||||||
// we only support a single TLS variable (g).
|
// we only support a single TLS variable (g).
|
||||||
|
|
||||||
if canuse1insntls(ctxt) {
|
if CanUse1InsnTLS(ctxt) {
|
||||||
// Reduce 2-instruction sequence to 1-instruction sequence.
|
// Reduce 2-instruction sequence to 1-instruction sequence.
|
||||||
// Sequences like
|
// Sequences like
|
||||||
// MOVQ TLS, BX
|
// MOVQ TLS, BX
|
||||||
|
Loading…
Reference in New Issue
Block a user