Commit 7a98bdf1 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/internal/obj: remove AUSEFIELD pseudo-op

Instead, cmd/compile can directly emit R_USEFIELD relocations.

Manually verified rsc.io/tmp/fieldtrack still passes.

Change-Id: Ib1fb5ab902ff0ad17ef6a862a9a5692caf7f87d1
Reviewed-on: https://go-review.googlesource.com/37871
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarJosh Bleecher Snyder <josharian@gmail.com>
parent 5d0c20ef
......@@ -27,7 +27,6 @@ var progtable = [x86.ALAST & obj.AMask]gc.ProgInfo{
obj.AFUNCDATA: {Flags: gc.Pseudo},
obj.APCDATA: {Flags: gc.Pseudo},
obj.AUNDEF: {Flags: gc.Break},
obj.AUSEFIELD: {Flags: gc.OK},
obj.AVARDEF: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARKILL: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARLIVE: {Flags: gc.Pseudo | gc.LeftRead},
......
......@@ -26,7 +26,6 @@ var progtable = [arm.ALAST & obj.AMask]gc.ProgInfo{
obj.AFUNCDATA: {Flags: gc.Pseudo},
obj.APCDATA: {Flags: gc.Pseudo},
obj.AUNDEF: {Flags: gc.Break},
obj.AUSEFIELD: {Flags: gc.OK},
obj.AVARDEF: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARKILL: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARLIVE: {Flags: gc.Pseudo | gc.LeftRead},
......
......@@ -29,7 +29,6 @@ var progtable = [arm64.ALAST & obj.AMask]gc.ProgInfo{
obj.AFUNCDATA: {Flags: gc.Pseudo},
obj.APCDATA: {Flags: gc.Pseudo},
obj.AUNDEF: {Flags: gc.Break},
obj.AUSEFIELD: {Flags: gc.OK},
obj.AVARDEF: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARKILL: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARLIVE: {Flags: gc.Pseudo | gc.LeftRead},
......
......@@ -97,13 +97,6 @@ func ggloblLSym(s *obj.LSym, width int32, flags int16) {
Ctxt.Globl(s, int64(width), int(flags))
}
func gtrack(s *Sym) {
p := Gins(obj.AUSEFIELD, nil, nil)
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_EXTERN
p.From.Sym = Linksym(s)
}
func isfat(t *Type) bool {
if t != nil {
switch t.Etype {
......@@ -289,8 +282,7 @@ func Patch(p *obj.Prog, to *obj.Prog) {
// Gins inserts instruction as. f is from, t is to.
func Gins(as obj.As, f, t *Node) *obj.Prog {
switch as {
case obj.AVARKILL, obj.AVARLIVE, obj.AVARDEF,
obj.ATEXT, obj.AFUNCDATA, obj.AUSEFIELD:
case obj.AVARKILL, obj.AVARLIVE, obj.AVARDEF, obj.ATEXT, obj.AFUNCDATA:
default:
Fatalf("unhandled gins op %v", as)
}
......
......@@ -380,6 +380,8 @@ func compile(fn *Node) {
nam = nil
}
ptxt := Gins(obj.ATEXT, nam, nil)
fnsym := ptxt.From.Sym
ptxt.From3 = new(obj.Addr)
if fn.Func.Dupok() {
ptxt.From3.Offset |= obj.DUPOK
......@@ -418,26 +420,19 @@ func compile(fn *Node) {
gcargs := makefuncdatasym("gcargs·", obj.FUNCDATA_ArgsPointerMaps)
gclocals := makefuncdatasym("gclocals·", obj.FUNCDATA_LocalsPointerMaps)
if obj.Fieldtrack_enabled != 0 && len(Curfn.Func.FieldTrack) > 0 {
trackSyms := make([]*Sym, 0, len(Curfn.Func.FieldTrack))
for sym := range Curfn.Func.FieldTrack {
trackSyms = append(trackSyms, sym)
}
sort.Sort(symByName(trackSyms))
for _, sym := range trackSyms {
gtrack(sym)
}
}
gendebug(ptxt.From.Sym, fn.Func.Dcl)
gendebug(fnsym, fn.Func.Dcl)
genssa(ssafn, ptxt, gcargs, gclocals)
ssafn.Free()
obj.Flushplist(Ctxt, plist) // convert from Prog list to machine code
ptxt = nil // nil to prevent misuse; Prog may have been freed by Flushplist
fieldtrack(fnsym, fn.Func.FieldTrack)
}
func gendebug(fn *obj.LSym, decls []*Node) {
if fn == nil {
func gendebug(fnsym *obj.LSym, decls []*Node) {
if fnsym == nil {
return
}
......@@ -466,8 +461,30 @@ func gendebug(fn *obj.LSym, decls []*Node) {
Gotype: Linksym(ngotype(n)),
}
a.Link = fn.Autom
fn.Autom = a
a.Link = fnsym.Autom
fnsym.Autom = a
}
}
// fieldtrack adds R_USEFIELD relocations to fnsym to record any
// struct fields that it used.
func fieldtrack(fnsym *obj.LSym, tracked map[*Sym]struct{}) {
if fnsym == nil {
return
}
if obj.Fieldtrack_enabled == 0 || len(tracked) == 0 {
return
}
trackSyms := make([]*Sym, 0, len(tracked))
for sym := range tracked {
trackSyms = append(trackSyms, sym)
}
sort.Sort(symByName(trackSyms))
for _, sym := range trackSyms {
r := obj.Addrel(fnsym)
r.Sym = Linksym(sym)
r.Type = obj.R_USEFIELD
}
}
......
......@@ -29,7 +29,6 @@ var progtable = [mips.ALAST & obj.AMask]gc.ProgInfo{
obj.AFUNCDATA: {Flags: gc.Pseudo},
obj.APCDATA: {Flags: gc.Pseudo},
obj.AUNDEF: {Flags: gc.Break},
obj.AUSEFIELD: {Flags: gc.OK},
obj.AVARDEF: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARKILL: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARLIVE: {Flags: gc.Pseudo | gc.LeftRead},
......
......@@ -29,7 +29,6 @@ var progtable = [mips.ALAST & obj.AMask]gc.ProgInfo{
obj.AFUNCDATA: {Flags: gc.Pseudo},
obj.APCDATA: {Flags: gc.Pseudo},
obj.AUNDEF: {Flags: gc.Break},
obj.AUSEFIELD: {Flags: gc.OK},
obj.AVARDEF: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARKILL: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARLIVE: {Flags: gc.Pseudo | gc.LeftRead},
......
......@@ -29,7 +29,6 @@ var progtable = [ppc64.ALAST & obj.AMask]gc.ProgInfo{
obj.AFUNCDATA: {Flags: gc.Pseudo},
obj.APCDATA: {Flags: gc.Pseudo},
obj.AUNDEF: {Flags: gc.Break},
obj.AUSEFIELD: {Flags: gc.OK},
obj.AVARDEF: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARKILL: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARLIVE: {Flags: gc.Pseudo | gc.LeftRead},
......
......@@ -22,7 +22,6 @@ var progtable = [s390x.ALAST & obj.AMask]gc.ProgInfo{
obj.AFUNCDATA & obj.AMask: {Flags: gc.Pseudo},
obj.APCDATA & obj.AMask: {Flags: gc.Pseudo},
obj.AUNDEF & obj.AMask: {Flags: gc.Break},
obj.AUSEFIELD & obj.AMask: {Flags: gc.OK},
obj.AVARDEF & obj.AMask: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARKILL & obj.AMask: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARLIVE & obj.AMask: {Flags: gc.Pseudo | gc.LeftRead},
......
......@@ -29,7 +29,6 @@ var progtable = [x86.ALAST & obj.AMask]gc.ProgInfo{
obj.AFUNCDATA: {Flags: gc.Pseudo},
obj.APCDATA: {Flags: gc.Pseudo},
obj.AUNDEF: {Flags: gc.Break},
obj.AUSEFIELD: {Flags: gc.OK},
obj.AVARDEF: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARKILL: {Flags: gc.Pseudo | gc.RightWrite},
obj.AVARLIVE: {Flags: gc.Pseudo | gc.LeftRead},
......
......@@ -247,7 +247,6 @@ var optab = []Optab{
{ACLZ, C_REG, C_NONE, C_REG, 97, 4, 0, 0, 0},
{AMULWT, C_REG, C_REG, C_REG, 98, 4, 0, 0, 0},
{AMULAWT, C_REG, C_REG, C_REGREG2, 99, 4, 0, 0, 0},
{obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0, 0, 0},
{obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0, 0, 0},
{obj.AFUNCDATA, C_LCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0},
{obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
......@@ -609,7 +608,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
}
}
if m == 0 && (p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != ADATABUNDLEEND && p.As != obj.ANOP && p.As != obj.AUSEFIELD) {
if m == 0 && (p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != ADATABUNDLEEND && p.As != obj.ANOP) {
ctxt.Diag("zero-width instruction\n%v", p)
continue
}
......@@ -705,7 +704,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
if m/4 > len(out) {
ctxt.Diag("instruction size too large: %d > %d", m/4, len(out))
}
if m == 0 && (p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != ADATABUNDLEEND && p.As != obj.ANOP && p.As != obj.AUSEFIELD) {
if m == 0 && (p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != ADATABUNDLEEND && p.As != obj.ANOP) {
if p.As == obj.ATEXT {
ctxt.Autosize = int32(p.To.Offset + 4)
continue
......@@ -1410,8 +1409,7 @@ func buildop(ctxt *obj.Link) {
AWORD,
AMOVM,
ARFE,
obj.ATEXT,
obj.AUSEFIELD:
obj.ATEXT:
break
case AADDF:
......
......@@ -498,7 +498,6 @@ var optab = []Optab{
{ASHA1C, C_VREG, C_REG, C_VREG, 1, 4, 0, 0, 0},
{obj.AUNDEF, C_NONE, C_NONE, C_NONE, 90, 4, 0, 0, 0},
{obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0, 0, 0},
{obj.APCDATA, C_VCON, C_NONE, C_VCON, 0, 0, 0, 0, 0},
{obj.AFUNCDATA, C_VCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0},
{obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
......@@ -555,7 +554,7 @@ func span7(ctxt *obj.Link, cursym *obj.LSym) {
o = oplook(ctxt, p)
m = int(o.size)
if m == 0 {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
ctxt.Diag("zero-width instruction\n%v", p)
}
continue
......@@ -623,7 +622,7 @@ func span7(ctxt *obj.Link, cursym *obj.LSym) {
m = int(o.size)
if m == 0 {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
ctxt.Diag("zero-width instruction\n%v", p)
}
continue
......@@ -1875,7 +1874,6 @@ func buildop(ctxt *obj.Link) {
case obj.ANOP,
obj.AUNDEF,
obj.AUSEFIELD,
obj.AFUNCDATA,
obj.APCDATA,
obj.ADUFFZERO,
......
......@@ -82,21 +82,3 @@ func linkgetlineFromPos(ctxt *Link, xpos src.XPos) (f *LSym, l int32) {
// TODO(gri) Should this use relative or absolute line number?
return Linklookup(ctxt, pos.SymFilename(), 0), int32(pos.RelLine())
}
func fieldtrack(ctxt *Link, cursym *LSym) {
p := cursym.Text
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
return
}
ctxt.Cursym = cursym
for ; p != nil; p = p.Link {
if p.As == AUSEFIELD {
r := Addrel(ctxt.Cursym)
r.Off = 0
r.Siz = 0
r.Sym = p.From.Sym
r.Type = R_USEFIELD
}
}
}
......@@ -292,7 +292,6 @@ const (
ARET
ATEXT
AUNDEF
AUSEFIELD
AVARDEF
AVARKILL
AVARLIVE
......
......@@ -359,7 +359,6 @@ var optab = []Optab{
{ABREAK, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0},
{obj.AUNDEF, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0},
{obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0, 0},
{obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0, 0},
{obj.AFUNCDATA, C_SCON, C_NONE, C_ADDR, 0, 0, 0, 0},
{obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
......@@ -396,7 +395,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym) {
o = oplook(ctxt, p)
m = int(o.size)
if m == 0 {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
ctxt.Diag("zero-width instruction\n%v", p)
}
continue
......@@ -455,7 +454,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym) {
m = int(o.size)
if m == 0 {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
ctxt.Diag("zero-width instruction\n%v", p)
}
continue
......@@ -988,7 +987,6 @@ func buildop(ctxt *obj.Link) {
obj.ANOP,
obj.ATEXT,
obj.AUNDEF,
obj.AUSEFIELD,
obj.AFUNCDATA,
obj.APCDATA,
obj.ADUFFZERO,
......
......@@ -127,7 +127,7 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
// Because p.Pos applies to p, phase == 0 (before p)
// takes care of the update.
func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 {
if p.As == ATEXT || p.As == ANOP || p.As == AUSEFIELD || p.Pos.Line() == 0 || phase == 1 {
if p.As == ATEXT || p.As == ANOP || p.Pos.Line() == 0 || phase == 1 {
return oldval
}
f, l := linkgetlineFromPos(ctxt, p.Pos)
......
......@@ -124,7 +124,6 @@ func flushplist(ctxt *Link, plist *Plist, freeProgs bool) {
linkpatch(ctxt, s)
ctxt.Arch.Preprocess(ctxt, s)
ctxt.Arch.Assemble(ctxt, s)
fieldtrack(ctxt, s)
linkpcln(ctxt, s)
if freeProgs {
s.Text = nil
......
......@@ -539,7 +539,6 @@ var optab = []Optab{
{ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
{ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0},
{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0},
{obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0},
{obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0},
{obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0},
{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0},
......@@ -576,7 +575,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
o = oplook(ctxt, p)
m = int(o.size)
if m == 0 {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
ctxt.Diag("zero-width instruction\n%v", p)
}
continue
......@@ -633,7 +632,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
m = int(o.size)
if m == 0 {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
ctxt.Diag("zero-width instruction\n%v", p)
}
continue
......@@ -1768,7 +1767,6 @@ func buildop(ctxt *obj.Link) {
obj.ANOP,
obj.ATEXT,
obj.AUNDEF,
obj.AUSEFIELD,
obj.AFUNCDATA,
obj.APCDATA,
obj.ADUFFZERO,
......
......@@ -492,7 +492,6 @@ var Anames = []string{
"RET",
"TEXT",
"UNDEF",
"USEFIELD",
"VARDEF",
"VARKILL",
"VARLIVE",
......
......@@ -1698,7 +1698,6 @@ var optab =
{AXEND, ynone, Px, [23]uint8{0x0f, 01, 0xd5}},
{AXTEST, ynone, Px, [23]uint8{0x0f, 01, 0xd6}},
{AXGETBV, ynone, Pm, [23]uint8{01, 0xd0}},
{obj.AUSEFIELD, ynop, Px, [23]uint8{0, 0}},
{obj.AFUNCDATA, yfuncdata, Px, [23]uint8{0, 0}},
{obj.APCDATA, ypcdata, Px, [23]uint8{0, 0}},
{obj.AVARDEF, nil, 0, [23]uint8{}},
......
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