1
0
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:
Josh Bleecher Snyder 2015-08-12 11:22:16 -07:00
parent bbf8c5ce2f
commit 3d23afb913
9 changed files with 88 additions and 3 deletions

View File

@ -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

View File

@ -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)

View File

@ -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{

View File

@ -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)

View File

@ -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]

View File

@ -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,

View File

@ -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:

View File

@ -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)

View File

@ -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