mirror of
https://github.com/golang/go
synced 2024-11-13 17:00:22 -07:00
cmd/compile: make vet happy with ssa code
Fixes #15488 Change-Id: I054eb1e1c859de315e3cdbdef5428682bce693fd Reviewed-on: https://go-review.googlesource.com/22609 Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
56b5491262
commit
cd956576ae
@ -141,7 +141,6 @@ func moveByType(t ssa.Type) obj.As {
|
|||||||
panic(fmt.Sprintf("bad int register width %d:%s", t.Size(), t))
|
panic(fmt.Sprintf("bad int register width %d:%s", t.Size(), t))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic("bad register type")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// opregreg emits instructions for
|
// opregreg emits instructions for
|
||||||
@ -966,12 +965,12 @@ var blockJump = [...]struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var eqfJumps = [2][2]gc.FloatingEQNEJump{
|
var eqfJumps = [2][2]gc.FloatingEQNEJump{
|
||||||
{{x86.AJNE, 1}, {x86.AJPS, 1}}, // next == b.Succs[0]
|
{{Jump: x86.AJNE, Index: 1}, {Jump: x86.AJPS, Index: 1}}, // next == b.Succs[0]
|
||||||
{{x86.AJNE, 1}, {x86.AJPC, 0}}, // next == b.Succs[1]
|
{{Jump: x86.AJNE, Index: 1}, {Jump: x86.AJPC, Index: 0}}, // next == b.Succs[1]
|
||||||
}
|
}
|
||||||
var nefJumps = [2][2]gc.FloatingEQNEJump{
|
var nefJumps = [2][2]gc.FloatingEQNEJump{
|
||||||
{{x86.AJNE, 0}, {x86.AJPC, 1}}, // next == b.Succs[0]
|
{{Jump: x86.AJNE, Index: 0}, {Jump: x86.AJPC, Index: 1}}, // next == b.Succs[0]
|
||||||
{{x86.AJNE, 0}, {x86.AJPS, 0}}, // next == b.Succs[1]
|
{{Jump: x86.AJNE, Index: 0}, {Jump: x86.AJPS, Index: 0}}, // next == b.Succs[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
||||||
@ -982,7 +981,7 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
|||||||
if b.Succs[0] != next {
|
if b.Succs[0] != next {
|
||||||
p := gc.Prog(obj.AJMP)
|
p := gc.Prog(obj.AJMP)
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
s.Branches = append(s.Branches, gc.Branch{p, b.Succs[0]})
|
s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0]})
|
||||||
}
|
}
|
||||||
case ssa.BlockDefer:
|
case ssa.BlockDefer:
|
||||||
// defer returns in rax:
|
// defer returns in rax:
|
||||||
@ -995,11 +994,11 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
|||||||
p.To.Reg = x86.REG_AX
|
p.To.Reg = x86.REG_AX
|
||||||
p = gc.Prog(x86.AJNE)
|
p = gc.Prog(x86.AJNE)
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
s.Branches = append(s.Branches, gc.Branch{p, b.Succs[1]})
|
s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1]})
|
||||||
if b.Succs[0] != next {
|
if b.Succs[0] != next {
|
||||||
p := gc.Prog(obj.AJMP)
|
p := gc.Prog(obj.AJMP)
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
s.Branches = append(s.Branches, gc.Branch{p, b.Succs[0]})
|
s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0]})
|
||||||
}
|
}
|
||||||
case ssa.BlockExit:
|
case ssa.BlockExit:
|
||||||
gc.Prog(obj.AUNDEF) // tell plive.go that we never reach here
|
gc.Prog(obj.AUNDEF) // tell plive.go that we never reach here
|
||||||
@ -1030,18 +1029,18 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
|||||||
p = gc.Prog(jmp.invasm)
|
p = gc.Prog(jmp.invasm)
|
||||||
likely *= -1
|
likely *= -1
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
s.Branches = append(s.Branches, gc.Branch{p, b.Succs[1]})
|
s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1]})
|
||||||
case b.Succs[1]:
|
case b.Succs[1]:
|
||||||
p = gc.Prog(jmp.asm)
|
p = gc.Prog(jmp.asm)
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
s.Branches = append(s.Branches, gc.Branch{p, b.Succs[0]})
|
s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0]})
|
||||||
default:
|
default:
|
||||||
p = gc.Prog(jmp.asm)
|
p = gc.Prog(jmp.asm)
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
s.Branches = append(s.Branches, gc.Branch{p, b.Succs[0]})
|
s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0]})
|
||||||
q := gc.Prog(obj.AJMP)
|
q := gc.Prog(obj.AJMP)
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
s.Branches = append(s.Branches, gc.Branch{q, b.Succs[1]})
|
s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1]})
|
||||||
}
|
}
|
||||||
|
|
||||||
// liblink reorders the instruction stream as it sees fit.
|
// liblink reorders the instruction stream as it sees fit.
|
||||||
|
@ -139,16 +139,16 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
|||||||
if b.Succs[0] != next {
|
if b.Succs[0] != next {
|
||||||
p := gc.Prog(obj.AJMP)
|
p := gc.Prog(obj.AJMP)
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
s.Branches = append(s.Branches, gc.Branch{p, b.Succs[0]})
|
s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0]})
|
||||||
}
|
}
|
||||||
case ssa.BlockRet:
|
case ssa.BlockRet:
|
||||||
gc.Prog(obj.ARET)
|
gc.Prog(obj.ARET)
|
||||||
case ssa.BlockARMLT:
|
case ssa.BlockARMLT:
|
||||||
p := gc.Prog(arm.ABLT)
|
p := gc.Prog(arm.ABLT)
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
s.Branches = append(s.Branches, gc.Branch{p, b.Succs[0]})
|
s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0]})
|
||||||
p = gc.Prog(obj.AJMP)
|
p = gc.Prog(obj.AJMP)
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
s.Branches = append(s.Branches, gc.Branch{p, b.Succs[1]})
|
s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1]})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1693,7 +1693,7 @@ func onebitwritesymbol(arr []bvec, sym *Sym) {
|
|||||||
ls := Linksym(sym)
|
ls := Linksym(sym)
|
||||||
ls.Name = fmt.Sprintf("gclocals·%x", md5.Sum(ls.P))
|
ls.Name = fmt.Sprintf("gclocals·%x", md5.Sum(ls.P))
|
||||||
ls.Dupok = true
|
ls.Dupok = true
|
||||||
sv := obj.SymVer{ls.Name, 0}
|
sv := obj.SymVer{Name: ls.Name, Version: 0}
|
||||||
ls2, ok := Ctxt.Hash[sv]
|
ls2, ok := Ctxt.Hash[sv]
|
||||||
if ok {
|
if ok {
|
||||||
sym.Lsym = ls2
|
sym.Lsym = ls2
|
||||||
|
@ -1424,7 +1424,7 @@ func (s *state) expr(n *Node) *ssa.Value {
|
|||||||
s.stmtList(n.Ninit)
|
s.stmtList(n.Ninit)
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case OCFUNC:
|
case OCFUNC:
|
||||||
aux := s.lookupSymbol(n, &ssa.ExternSymbol{n.Type, n.Left.Sym})
|
aux := s.lookupSymbol(n, &ssa.ExternSymbol{Typ: n.Type, Sym: n.Left.Sym})
|
||||||
return s.entryNewValue1A(ssa.OpAddr, n.Type, aux, s.sb)
|
return s.entryNewValue1A(ssa.OpAddr, n.Type, aux, s.sb)
|
||||||
case OPARAM:
|
case OPARAM:
|
||||||
addr := s.addr(n, false)
|
addr := s.addr(n, false)
|
||||||
@ -1433,7 +1433,7 @@ func (s *state) expr(n *Node) *ssa.Value {
|
|||||||
if n.Class == PFUNC {
|
if n.Class == PFUNC {
|
||||||
// "value" of a function is the address of the function's closure
|
// "value" of a function is the address of the function's closure
|
||||||
sym := funcsym(n.Sym)
|
sym := funcsym(n.Sym)
|
||||||
aux := &ssa.ExternSymbol{n.Type, sym}
|
aux := &ssa.ExternSymbol{Typ: n.Type, Sym: sym}
|
||||||
return s.entryNewValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sb)
|
return s.entryNewValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sb)
|
||||||
}
|
}
|
||||||
if s.canSSA(n) {
|
if s.canSSA(n) {
|
||||||
@ -2163,7 +2163,7 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
|
|||||||
|
|
||||||
// Call growslice
|
// Call growslice
|
||||||
s.startBlock(grow)
|
s.startBlock(grow)
|
||||||
taddr := s.newValue1A(ssa.OpAddr, Types[TUINTPTR], &ssa.ExternSymbol{Types[TUINTPTR], typenamesym(n.Type.Elem())}, s.sb)
|
taddr := s.newValue1A(ssa.OpAddr, Types[TUINTPTR], &ssa.ExternSymbol{Typ: Types[TUINTPTR], Sym: typenamesym(n.Type.Elem())}, s.sb)
|
||||||
|
|
||||||
r := s.rtcall(growslice, true, []*Type{pt, Types[TINT], Types[TINT]}, taddr, p, l, c, nl)
|
r := s.rtcall(growslice, true, []*Type{pt, Types[TINT], Types[TINT]}, taddr, p, l, c, nl)
|
||||||
|
|
||||||
@ -2691,7 +2691,7 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value {
|
|||||||
switch n.Class {
|
switch n.Class {
|
||||||
case PEXTERN:
|
case PEXTERN:
|
||||||
// global variable
|
// global variable
|
||||||
aux := s.lookupSymbol(n, &ssa.ExternSymbol{n.Type, n.Sym})
|
aux := s.lookupSymbol(n, &ssa.ExternSymbol{Typ: n.Type, Sym: n.Sym})
|
||||||
v := s.entryNewValue1A(ssa.OpAddr, t, aux, s.sb)
|
v := s.entryNewValue1A(ssa.OpAddr, t, aux, s.sb)
|
||||||
// TODO: Make OpAddr use AuxInt as well as Aux.
|
// TODO: Make OpAddr use AuxInt as well as Aux.
|
||||||
if n.Xoffset != 0 {
|
if n.Xoffset != 0 {
|
||||||
@ -3024,7 +3024,7 @@ func (s *state) insertWBmove(t *Type, left, right *ssa.Value, line int32) {
|
|||||||
bElse := s.f.NewBlock(ssa.BlockPlain)
|
bElse := s.f.NewBlock(ssa.BlockPlain)
|
||||||
bEnd := s.f.NewBlock(ssa.BlockPlain)
|
bEnd := s.f.NewBlock(ssa.BlockPlain)
|
||||||
|
|
||||||
aux := &ssa.ExternSymbol{Types[TBOOL], syslook("writeBarrier").Sym}
|
aux := &ssa.ExternSymbol{Typ: Types[TBOOL], Sym: syslook("writeBarrier").Sym}
|
||||||
flagaddr := s.newValue1A(ssa.OpAddr, Ptrto(Types[TUINT32]), aux, s.sb)
|
flagaddr := s.newValue1A(ssa.OpAddr, Ptrto(Types[TUINT32]), aux, s.sb)
|
||||||
// TODO: select the .enabled field. It is currently first, so not needed for now.
|
// TODO: select the .enabled field. It is currently first, so not needed for now.
|
||||||
// Load word, test byte, avoiding partial register write from load byte.
|
// Load word, test byte, avoiding partial register write from load byte.
|
||||||
@ -3038,7 +3038,7 @@ func (s *state) insertWBmove(t *Type, left, right *ssa.Value, line int32) {
|
|||||||
b.AddEdgeTo(bElse)
|
b.AddEdgeTo(bElse)
|
||||||
|
|
||||||
s.startBlock(bThen)
|
s.startBlock(bThen)
|
||||||
taddr := s.newValue1A(ssa.OpAddr, Types[TUINTPTR], &ssa.ExternSymbol{Types[TUINTPTR], typenamesym(t)}, s.sb)
|
taddr := s.newValue1A(ssa.OpAddr, Types[TUINTPTR], &ssa.ExternSymbol{Typ: Types[TUINTPTR], Sym: typenamesym(t)}, s.sb)
|
||||||
s.rtcall(typedmemmove, true, nil, taddr, left, right)
|
s.rtcall(typedmemmove, true, nil, taddr, left, right)
|
||||||
s.endBlock().AddEdgeTo(bEnd)
|
s.endBlock().AddEdgeTo(bEnd)
|
||||||
|
|
||||||
@ -3075,7 +3075,7 @@ func (s *state) insertWBstore(t *Type, left, right *ssa.Value, line int32, skip
|
|||||||
bElse := s.f.NewBlock(ssa.BlockPlain)
|
bElse := s.f.NewBlock(ssa.BlockPlain)
|
||||||
bEnd := s.f.NewBlock(ssa.BlockPlain)
|
bEnd := s.f.NewBlock(ssa.BlockPlain)
|
||||||
|
|
||||||
aux := &ssa.ExternSymbol{Types[TBOOL], syslook("writeBarrier").Sym}
|
aux := &ssa.ExternSymbol{Typ: Types[TBOOL], Sym: syslook("writeBarrier").Sym}
|
||||||
flagaddr := s.newValue1A(ssa.OpAddr, Ptrto(Types[TUINT32]), aux, s.sb)
|
flagaddr := s.newValue1A(ssa.OpAddr, Ptrto(Types[TUINT32]), aux, s.sb)
|
||||||
// TODO: select the .enabled field. It is currently first, so not needed for now.
|
// TODO: select the .enabled field. It is currently first, so not needed for now.
|
||||||
// Load word, test byte, avoiding partial register write from load byte.
|
// Load word, test byte, avoiding partial register write from load byte.
|
||||||
@ -3629,7 +3629,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
|
|||||||
if !commaok {
|
if !commaok {
|
||||||
// on failure, panic by calling panicdottype
|
// on failure, panic by calling panicdottype
|
||||||
s.startBlock(bFail)
|
s.startBlock(bFail)
|
||||||
taddr := s.newValue1A(ssa.OpAddr, byteptr, &ssa.ExternSymbol{byteptr, typenamesym(n.Left.Type)}, s.sb)
|
taddr := s.newValue1A(ssa.OpAddr, byteptr, &ssa.ExternSymbol{Typ: byteptr, Sym: typenamesym(n.Left.Type)}, s.sb)
|
||||||
s.rtcall(panicdottype, false, nil, typ, target, taddr)
|
s.rtcall(panicdottype, false, nil, typ, target, taddr)
|
||||||
|
|
||||||
// on success, return idata field
|
// on success, return idata field
|
||||||
@ -3995,7 +3995,7 @@ func genssa(f *ssa.Func, ptxt *obj.Prog, gcargs, gclocals *Sym) {
|
|||||||
if f.StaticData != nil {
|
if f.StaticData != nil {
|
||||||
for _, n := range f.StaticData.([]*Node) {
|
for _, n := range f.StaticData.([]*Node) {
|
||||||
if !gen_as_init(n, false) {
|
if !gen_as_init(n, false) {
|
||||||
Fatalf("non-static data marked as static: %v\n\n", n, f)
|
Fatalf("non-static data marked as static: %v\n\n", n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4084,7 +4084,7 @@ func AddAux(a *obj.Addr, v *ssa.Value) {
|
|||||||
}
|
}
|
||||||
func AddAux2(a *obj.Addr, v *ssa.Value, offset int64) {
|
func AddAux2(a *obj.Addr, v *ssa.Value, offset int64) {
|
||||||
if a.Type != obj.TYPE_MEM {
|
if a.Type != obj.TYPE_MEM {
|
||||||
v.Fatalf("bad AddAux addr %s", a)
|
v.Fatalf("bad AddAux addr %v", a)
|
||||||
}
|
}
|
||||||
// add integer offset
|
// add integer offset
|
||||||
a.Offset += offset
|
a.Offset += offset
|
||||||
@ -4263,10 +4263,10 @@ func (e *ssaExport) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlo
|
|||||||
// Split this string up into two separate variables.
|
// Split this string up into two separate variables.
|
||||||
p := e.namedAuto(n.Sym.Name+".ptr", ptrType)
|
p := e.namedAuto(n.Sym.Name+".ptr", ptrType)
|
||||||
l := e.namedAuto(n.Sym.Name+".len", lenType)
|
l := e.namedAuto(n.Sym.Name+".len", lenType)
|
||||||
return ssa.LocalSlot{p, ptrType, 0}, ssa.LocalSlot{l, lenType, 0}
|
return ssa.LocalSlot{N: p, Type: ptrType, Off: 0}, ssa.LocalSlot{N: l, Type: lenType, Off: 0}
|
||||||
}
|
}
|
||||||
// Return the two parts of the larger variable.
|
// Return the two parts of the larger variable.
|
||||||
return ssa.LocalSlot{n, ptrType, name.Off}, ssa.LocalSlot{n, lenType, name.Off + int64(Widthptr)}
|
return ssa.LocalSlot{N: n, Type: ptrType, Off: name.Off}, ssa.LocalSlot{N: n, Type: lenType, Off: name.Off + int64(Widthptr)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ssaExport) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
|
func (e *ssaExport) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
|
||||||
@ -4280,10 +4280,10 @@ func (e *ssaExport) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.Local
|
|||||||
}
|
}
|
||||||
c := e.namedAuto(n.Sym.Name+f, t)
|
c := e.namedAuto(n.Sym.Name+f, t)
|
||||||
d := e.namedAuto(n.Sym.Name+".data", t)
|
d := e.namedAuto(n.Sym.Name+".data", t)
|
||||||
return ssa.LocalSlot{c, t, 0}, ssa.LocalSlot{d, t, 0}
|
return ssa.LocalSlot{N: c, Type: t, Off: 0}, ssa.LocalSlot{N: d, Type: t, Off: 0}
|
||||||
}
|
}
|
||||||
// Return the two parts of the larger variable.
|
// Return the two parts of the larger variable.
|
||||||
return ssa.LocalSlot{n, t, name.Off}, ssa.LocalSlot{n, t, name.Off + int64(Widthptr)}
|
return ssa.LocalSlot{N: n, Type: t, Off: name.Off}, ssa.LocalSlot{N: n, Type: t, Off: name.Off + int64(Widthptr)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ssaExport) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot, ssa.LocalSlot) {
|
func (e *ssaExport) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot, ssa.LocalSlot) {
|
||||||
@ -4295,12 +4295,12 @@ func (e *ssaExport) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot
|
|||||||
p := e.namedAuto(n.Sym.Name+".ptr", ptrType)
|
p := e.namedAuto(n.Sym.Name+".ptr", ptrType)
|
||||||
l := e.namedAuto(n.Sym.Name+".len", lenType)
|
l := e.namedAuto(n.Sym.Name+".len", lenType)
|
||||||
c := e.namedAuto(n.Sym.Name+".cap", lenType)
|
c := e.namedAuto(n.Sym.Name+".cap", lenType)
|
||||||
return ssa.LocalSlot{p, ptrType, 0}, ssa.LocalSlot{l, lenType, 0}, ssa.LocalSlot{c, lenType, 0}
|
return ssa.LocalSlot{N: p, Type: ptrType, Off: 0}, ssa.LocalSlot{N: l, Type: lenType, Off: 0}, ssa.LocalSlot{N: c, Type: lenType, Off: 0}
|
||||||
}
|
}
|
||||||
// Return the three parts of the larger variable.
|
// Return the three parts of the larger variable.
|
||||||
return ssa.LocalSlot{n, ptrType, name.Off},
|
return ssa.LocalSlot{N: n, Type: ptrType, Off: name.Off},
|
||||||
ssa.LocalSlot{n, lenType, name.Off + int64(Widthptr)},
|
ssa.LocalSlot{N: n, Type: lenType, Off: name.Off + int64(Widthptr)},
|
||||||
ssa.LocalSlot{n, lenType, name.Off + int64(2*Widthptr)}
|
ssa.LocalSlot{N: n, Type: lenType, Off: name.Off + int64(2*Widthptr)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ssaExport) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
|
func (e *ssaExport) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
|
||||||
@ -4316,10 +4316,10 @@ func (e *ssaExport) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSl
|
|||||||
// Split this complex up into two separate variables.
|
// Split this complex up into two separate variables.
|
||||||
c := e.namedAuto(n.Sym.Name+".real", t)
|
c := e.namedAuto(n.Sym.Name+".real", t)
|
||||||
d := e.namedAuto(n.Sym.Name+".imag", t)
|
d := e.namedAuto(n.Sym.Name+".imag", t)
|
||||||
return ssa.LocalSlot{c, t, 0}, ssa.LocalSlot{d, t, 0}
|
return ssa.LocalSlot{N: c, Type: t, Off: 0}, ssa.LocalSlot{N: d, Type: t, Off: 0}
|
||||||
}
|
}
|
||||||
// Return the two parts of the larger variable.
|
// Return the two parts of the larger variable.
|
||||||
return ssa.LocalSlot{n, t, name.Off}, ssa.LocalSlot{n, t, name.Off + s}
|
return ssa.LocalSlot{N: n, Type: t, Off: name.Off}, ssa.LocalSlot{N: n, Type: t, Off: name.Off + s}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ssaExport) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot {
|
func (e *ssaExport) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot {
|
||||||
@ -4331,9 +4331,9 @@ func (e *ssaExport) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot {
|
|||||||
// have no fear, identically-named but distinct Autos are
|
// have no fear, identically-named but distinct Autos are
|
||||||
// ok, albeit maybe confusing for a debugger.
|
// ok, albeit maybe confusing for a debugger.
|
||||||
x := e.namedAuto(n.Sym.Name+"."+st.FieldName(i), ft)
|
x := e.namedAuto(n.Sym.Name+"."+st.FieldName(i), ft)
|
||||||
return ssa.LocalSlot{x, ft, 0}
|
return ssa.LocalSlot{N: x, Type: ft, Off: 0}
|
||||||
}
|
}
|
||||||
return ssa.LocalSlot{n, ft, name.Off + st.FieldOff(i)}
|
return ssa.LocalSlot{N: n, Type: ft, Off: name.Off + st.FieldOff(i)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// namedAuto returns a new AUTO variable with the given name and type.
|
// namedAuto returns a new AUTO variable with the given name and type.
|
||||||
|
@ -67,7 +67,7 @@ func checkFunc(f *Func) {
|
|||||||
f.Fatalf("ret block %s has successors", b)
|
f.Fatalf("ret block %s has successors", b)
|
||||||
}
|
}
|
||||||
if b.Control == nil {
|
if b.Control == nil {
|
||||||
f.Fatalf("ret block %s has nil control %s", b)
|
f.Fatalf("ret block %s has nil control", b)
|
||||||
}
|
}
|
||||||
if !b.Control.Type.IsMemory() {
|
if !b.Control.Type.IsMemory() {
|
||||||
f.Fatalf("ret block %s has non-memory control value %s", b, b.Control.LongString())
|
f.Fatalf("ret block %s has non-memory control value %s", b, b.Control.LongString())
|
||||||
@ -77,7 +77,7 @@ func checkFunc(f *Func) {
|
|||||||
f.Fatalf("retjmp block %s len(Succs)==%d, want 0", b, len(b.Succs))
|
f.Fatalf("retjmp block %s len(Succs)==%d, want 0", b, len(b.Succs))
|
||||||
}
|
}
|
||||||
if b.Control == nil {
|
if b.Control == nil {
|
||||||
f.Fatalf("retjmp block %s has nil control %s", b)
|
f.Fatalf("retjmp block %s has nil control", b)
|
||||||
}
|
}
|
||||||
if !b.Control.Type.IsMemory() {
|
if !b.Control.Type.IsMemory() {
|
||||||
f.Fatalf("retjmp block %s has non-memory control value %s", b, b.Control.LongString())
|
f.Fatalf("retjmp block %s has non-memory control value %s", b, b.Control.LongString())
|
||||||
@ -141,7 +141,7 @@ func checkFunc(f *Func) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(b.Succs) > 2 && b.Likely != BranchUnknown {
|
if len(b.Succs) > 2 && b.Likely != BranchUnknown {
|
||||||
f.Fatalf("likeliness prediction %d for block %s with %d successors: %s", b.Likely, b, len(b.Succs))
|
f.Fatalf("likeliness prediction %d for block %s with %d successors", b.Likely, b, len(b.Succs))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range b.Values {
|
for _, v := range b.Values {
|
||||||
|
@ -1196,9 +1196,7 @@
|
|||||||
(ADDQconst [c] (ADDQconst [d] x)) && is32Bit(c+d) -> (ADDQconst [c+d] x)
|
(ADDQconst [c] (ADDQconst [d] x)) && is32Bit(c+d) -> (ADDQconst [c+d] x)
|
||||||
(ADDLconst [c] (ADDLconst [d] x)) -> (ADDLconst [int64(int32(c+d))] x)
|
(ADDLconst [c] (ADDLconst [d] x)) -> (ADDLconst [int64(int32(c+d))] x)
|
||||||
(SUBQconst (MOVQconst [d]) [c]) -> (MOVQconst [d-c])
|
(SUBQconst (MOVQconst [d]) [c]) -> (MOVQconst [d-c])
|
||||||
(SUBLconst (MOVLconst [d]) [c]) -> (MOVLconst [int64(int32(d-c))])
|
|
||||||
(SUBQconst (SUBQconst x [d]) [c]) && is32Bit(-c-d) -> (ADDQconst [-c-d] x)
|
(SUBQconst (SUBQconst x [d]) [c]) && is32Bit(-c-d) -> (ADDQconst [-c-d] x)
|
||||||
(SUBLconst (SUBLconst x [d]) [c]) -> (ADDLconst [int64(int32(-c-d))] x)
|
|
||||||
(SARQconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
|
(SARQconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
|
||||||
(SARLconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
|
(SARLconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
|
||||||
(SARWconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
|
(SARWconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
|
||||||
|
@ -173,17 +173,25 @@ func genRules(arch arch) {
|
|||||||
fmt.Fprintf(w, "func rewriteValue%s_%s(v *Value, config *Config) bool {\n", arch.name, opName(op, arch))
|
fmt.Fprintf(w, "func rewriteValue%s_%s(v *Value, config *Config) bool {\n", arch.name, opName(op, arch))
|
||||||
fmt.Fprintln(w, "b := v.Block")
|
fmt.Fprintln(w, "b := v.Block")
|
||||||
fmt.Fprintln(w, "_ = b")
|
fmt.Fprintln(w, "_ = b")
|
||||||
for _, rule := range oprules[op] {
|
var canFail bool
|
||||||
|
for i, rule := range oprules[op] {
|
||||||
match, cond, result := rule.parse()
|
match, cond, result := rule.parse()
|
||||||
fmt.Fprintf(w, "// match: %s\n", match)
|
fmt.Fprintf(w, "// match: %s\n", match)
|
||||||
fmt.Fprintf(w, "// cond: %s\n", cond)
|
fmt.Fprintf(w, "// cond: %s\n", cond)
|
||||||
fmt.Fprintf(w, "// result: %s\n", result)
|
fmt.Fprintf(w, "// result: %s\n", result)
|
||||||
|
|
||||||
|
canFail = false
|
||||||
fmt.Fprintf(w, "for {\n")
|
fmt.Fprintf(w, "for {\n")
|
||||||
genMatch(w, arch, match, rule.loc)
|
if genMatch(w, arch, match, rule.loc) {
|
||||||
|
canFail = true
|
||||||
|
}
|
||||||
|
|
||||||
if cond != "" {
|
if cond != "" {
|
||||||
fmt.Fprintf(w, "if !(%s) {\nbreak\n}\n", cond)
|
fmt.Fprintf(w, "if !(%s) {\nbreak\n}\n", cond)
|
||||||
|
canFail = true
|
||||||
|
}
|
||||||
|
if !canFail && i != len(oprules[op])-1 {
|
||||||
|
log.Fatalf("unconditional rule %s is followed by other rules", match)
|
||||||
}
|
}
|
||||||
|
|
||||||
genResult(w, arch, result, rule.loc)
|
genResult(w, arch, result, rule.loc)
|
||||||
@ -194,7 +202,9 @@ func genRules(arch arch) {
|
|||||||
|
|
||||||
fmt.Fprintf(w, "}\n")
|
fmt.Fprintf(w, "}\n")
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, "return false\n")
|
if canFail {
|
||||||
|
fmt.Fprintf(w, "return false\n")
|
||||||
|
}
|
||||||
fmt.Fprintf(w, "}\n")
|
fmt.Fprintf(w, "}\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,14 +331,16 @@ func genRules(arch arch) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func genMatch(w io.Writer, arch arch, match string, loc string) {
|
// genMatch returns true if the match can fail.
|
||||||
genMatch0(w, arch, match, "v", map[string]struct{}{}, true, loc)
|
func genMatch(w io.Writer, arch arch, match string, loc string) bool {
|
||||||
|
return genMatch0(w, arch, match, "v", map[string]struct{}{}, true, loc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func genMatch0(w io.Writer, arch arch, match, v string, m map[string]struct{}, top bool, loc string) {
|
func genMatch0(w io.Writer, arch arch, match, v string, m map[string]struct{}, top bool, loc string) bool {
|
||||||
if match[0] != '(' || match[len(match)-1] != ')' {
|
if match[0] != '(' || match[len(match)-1] != ')' {
|
||||||
panic("non-compound expr in genMatch0: " + match)
|
panic("non-compound expr in genMatch0: " + match)
|
||||||
}
|
}
|
||||||
|
canFail := false
|
||||||
|
|
||||||
// split body up into regions. Split by spaces/tabs, except those
|
// split body up into regions. Split by spaces/tabs, except those
|
||||||
// contained in () or {}.
|
// contained in () or {}.
|
||||||
@ -355,6 +367,7 @@ func genMatch0(w io.Writer, arch arch, match, v string, m map[string]struct{}, t
|
|||||||
// check op
|
// check op
|
||||||
if !top {
|
if !top {
|
||||||
fmt.Fprintf(w, "if %s.Op != %s {\nbreak\n}\n", v, opName(s[0], arch))
|
fmt.Fprintf(w, "if %s.Op != %s {\nbreak\n}\n", v, opName(s[0], arch))
|
||||||
|
canFail = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// check type/aux/args
|
// check type/aux/args
|
||||||
@ -366,11 +379,13 @@ func genMatch0(w io.Writer, arch arch, match, v string, m map[string]struct{}, t
|
|||||||
if !isVariable(t) {
|
if !isVariable(t) {
|
||||||
// code. We must match the results of this code.
|
// code. We must match the results of this code.
|
||||||
fmt.Fprintf(w, "if %s.Type != %s {\nbreak\n}\n", v, t)
|
fmt.Fprintf(w, "if %s.Type != %s {\nbreak\n}\n", v, t)
|
||||||
|
canFail = true
|
||||||
} else {
|
} else {
|
||||||
// variable
|
// variable
|
||||||
if _, ok := m[t]; ok {
|
if _, ok := m[t]; ok {
|
||||||
// must match previous variable
|
// must match previous variable
|
||||||
fmt.Fprintf(w, "if %s.Type != %s {\nbreak\n}\n", v, t)
|
fmt.Fprintf(w, "if %s.Type != %s {\nbreak\n}\n", v, t)
|
||||||
|
canFail = true
|
||||||
} else {
|
} else {
|
||||||
m[t] = struct{}{}
|
m[t] = struct{}{}
|
||||||
fmt.Fprintf(w, "%s := %s.Type\n", t, v)
|
fmt.Fprintf(w, "%s := %s.Type\n", t, v)
|
||||||
@ -387,10 +402,12 @@ func genMatch0(w io.Writer, arch arch, match, v string, m map[string]struct{}, t
|
|||||||
if !isVariable(x) {
|
if !isVariable(x) {
|
||||||
// code
|
// code
|
||||||
fmt.Fprintf(w, "if %s.AuxInt != %s {\nbreak\n}\n", v, x)
|
fmt.Fprintf(w, "if %s.AuxInt != %s {\nbreak\n}\n", v, x)
|
||||||
|
canFail = true
|
||||||
} else {
|
} else {
|
||||||
// variable
|
// variable
|
||||||
if _, ok := m[x]; ok {
|
if _, ok := m[x]; ok {
|
||||||
fmt.Fprintf(w, "if %s.AuxInt != %s {\nbreak\n}\n", v, x)
|
fmt.Fprintf(w, "if %s.AuxInt != %s {\nbreak\n}\n", v, x)
|
||||||
|
canFail = true
|
||||||
} else {
|
} else {
|
||||||
m[x] = struct{}{}
|
m[x] = struct{}{}
|
||||||
fmt.Fprintf(w, "%s := %s.AuxInt\n", x, v)
|
fmt.Fprintf(w, "%s := %s.AuxInt\n", x, v)
|
||||||
@ -407,10 +424,12 @@ func genMatch0(w io.Writer, arch arch, match, v string, m map[string]struct{}, t
|
|||||||
if !isVariable(x) {
|
if !isVariable(x) {
|
||||||
// code
|
// code
|
||||||
fmt.Fprintf(w, "if %s.Aux != %s {\nbreak\n}\n", v, x)
|
fmt.Fprintf(w, "if %s.Aux != %s {\nbreak\n}\n", v, x)
|
||||||
|
canFail = true
|
||||||
} else {
|
} else {
|
||||||
// variable
|
// variable
|
||||||
if _, ok := m[x]; ok {
|
if _, ok := m[x]; ok {
|
||||||
fmt.Fprintf(w, "if %s.Aux != %s {\nbreak\n}\n", v, x)
|
fmt.Fprintf(w, "if %s.Aux != %s {\nbreak\n}\n", v, x)
|
||||||
|
canFail = true
|
||||||
} else {
|
} else {
|
||||||
m[x] = struct{}{}
|
m[x] = struct{}{}
|
||||||
fmt.Fprintf(w, "%s := %s.Aux\n", x, v)
|
fmt.Fprintf(w, "%s := %s.Aux\n", x, v)
|
||||||
@ -426,6 +445,7 @@ func genMatch0(w io.Writer, arch arch, match, v string, m map[string]struct{}, t
|
|||||||
// For example, (add x x). Equality is just pointer equality
|
// For example, (add x x). Equality is just pointer equality
|
||||||
// on Values (so cse is important to do before lowering).
|
// on Values (so cse is important to do before lowering).
|
||||||
fmt.Fprintf(w, "if %s != %s.Args[%d] {\nbreak\n}\n", a, v, argnum)
|
fmt.Fprintf(w, "if %s != %s.Args[%d] {\nbreak\n}\n", a, v, argnum)
|
||||||
|
canFail = true
|
||||||
} else {
|
} else {
|
||||||
// remember that this variable references the given value
|
// remember that this variable references the given value
|
||||||
m[a] = struct{}{}
|
m[a] = struct{}{}
|
||||||
@ -446,15 +466,19 @@ func genMatch0(w io.Writer, arch arch, match, v string, m map[string]struct{}, t
|
|||||||
argname = fmt.Sprintf("%s_%d", v, argnum)
|
argname = fmt.Sprintf("%s_%d", v, argnum)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, "%s := %s.Args[%d]\n", argname, v, argnum)
|
fmt.Fprintf(w, "%s := %s.Args[%d]\n", argname, v, argnum)
|
||||||
genMatch0(w, arch, a, argname, m, false, loc)
|
if genMatch0(w, arch, a, argname, m, false, loc) {
|
||||||
|
canFail = true
|
||||||
|
}
|
||||||
argnum++
|
argnum++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if op.argLength == -1 {
|
if op.argLength == -1 {
|
||||||
fmt.Fprintf(w, "if len(%s.Args) != %d {\nbreak\n}\n", v, argnum)
|
fmt.Fprintf(w, "if len(%s.Args) != %d {\nbreak\n}\n", v, argnum)
|
||||||
|
canFail = true
|
||||||
} else if int(op.argLength) != argnum {
|
} else if int(op.argLength) != argnum {
|
||||||
log.Fatalf("%s: op %s should have %d args, has %d", loc, op.name, op.argLength, argnum)
|
log.Fatalf("%s: op %s should have %d args, has %d", loc, op.name, op.argLength, argnum)
|
||||||
}
|
}
|
||||||
|
return canFail
|
||||||
}
|
}
|
||||||
|
|
||||||
func genResult(w io.Writer, arch arch, result string, loc string) {
|
func genResult(w io.Writer, arch arch, result string, loc string) {
|
||||||
|
@ -142,7 +142,6 @@ func mergeSym(x, y interface{}) interface{} {
|
|||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
panic(fmt.Sprintf("mergeSym with two non-nil syms %s %s", x, y))
|
panic(fmt.Sprintf("mergeSym with two non-nil syms %s %s", x, y))
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
func canMergeSym(x, y interface{}) bool {
|
func canMergeSym(x, y interface{}) bool {
|
||||||
return x == nil || y == nil
|
return x == nil || y == nil
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -82,7 +82,6 @@ func rewriteValueARM_OpAdd32(v *Value, config *Config) bool {
|
|||||||
v.AddArg(y)
|
v.AddArg(y)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func rewriteValueARM_OpAddr(v *Value, config *Config) bool {
|
func rewriteValueARM_OpAddr(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
@ -98,7 +97,6 @@ func rewriteValueARM_OpAddr(v *Value, config *Config) bool {
|
|||||||
v.AddArg(base)
|
v.AddArg(base)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func rewriteValueARM_OpConst32(v *Value, config *Config) bool {
|
func rewriteValueARM_OpConst32(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
@ -112,7 +110,6 @@ func rewriteValueARM_OpConst32(v *Value, config *Config) bool {
|
|||||||
v.AuxInt = val
|
v.AuxInt = val
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func rewriteValueARM_OpLess32(v *Value, config *Config) bool {
|
func rewriteValueARM_OpLess32(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
@ -130,7 +127,6 @@ func rewriteValueARM_OpLess32(v *Value, config *Config) bool {
|
|||||||
v.AddArg(v0)
|
v.AddArg(v0)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func rewriteValueARM_OpLoad(v *Value, config *Config) bool {
|
func rewriteValueARM_OpLoad(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
@ -228,7 +224,6 @@ func rewriteValueARM_OpOffPtr(v *Value, config *Config) bool {
|
|||||||
v.AddArg(ptr)
|
v.AddArg(ptr)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func rewriteValueARM_OpStaticCall(v *Value, config *Config) bool {
|
func rewriteValueARM_OpStaticCall(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
@ -246,7 +241,6 @@ func rewriteValueARM_OpStaticCall(v *Value, config *Config) bool {
|
|||||||
v.AddArg(mem)
|
v.AddArg(mem)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func rewriteValueARM_OpStore(v *Value, config *Config) bool {
|
func rewriteValueARM_OpStore(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
|
@ -1620,7 +1620,6 @@ func rewriteValuegeneric_OpConstInterface(v *Value, config *Config) bool {
|
|||||||
v.AddArg(v1)
|
v.AddArg(v1)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func rewriteValuegeneric_OpConstSlice(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpConstSlice(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
@ -2497,7 +2496,6 @@ func rewriteValuegeneric_OpEqInter(v *Value, config *Config) bool {
|
|||||||
v.AddArg(v1)
|
v.AddArg(v1)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func rewriteValuegeneric_OpEqPtr(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpEqPtr(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
@ -2552,7 +2550,6 @@ func rewriteValuegeneric_OpEqSlice(v *Value, config *Config) bool {
|
|||||||
v.AddArg(v1)
|
v.AddArg(v1)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func rewriteValuegeneric_OpGeq16(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpGeq16(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
@ -5780,7 +5777,6 @@ func rewriteValuegeneric_OpNeqInter(v *Value, config *Config) bool {
|
|||||||
v.AddArg(v1)
|
v.AddArg(v1)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func rewriteValuegeneric_OpNeqPtr(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpNeqPtr(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
@ -5831,7 +5827,6 @@ func rewriteValuegeneric_OpNeqSlice(v *Value, config *Config) bool {
|
|||||||
v.AddArg(v1)
|
v.AddArg(v1)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func rewriteValuegeneric_OpOffPtr(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpOffPtr(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
|
Loading…
Reference in New Issue
Block a user