Skip to content

Commit 8247da3

Browse files
committed
cmd/compile,cmd/asm: simplify recording of branch targets
We currently use two fields to store the targets of branches. Some phases use p.To.Val, some use p.Pcond. Rewrite so that every branch instruction uses p.To.Val. p.From.Val is also used in rare instances. Introduce a Pool link for use by arm/arm64, instead of repurposing Pcond. This is a cleanup CL in preparation for some stack frame CLs. Change-Id: I9055bf0a1d986aff421e47951a1dedc301c846f8 Reviewed-on: https://go-review.googlesource.com/c/go/+/243318 Run-TryBot: Keith Randall <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Cherry Zhang <[email protected]>
1 parent 5c2c6d3 commit 8247da3

21 files changed

Lines changed: 142 additions & 134 deletions

File tree

src/cmd/compile/internal/amd64/ssa.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
319319
// TODO(khr): issue only the -1 fixup code we need.
320320
// For instance, if only the quotient is used, no point in zeroing the remainder.
321321

322-
j1.To.Val = n1
323-
j2.To.Val = s.Pc()
322+
j1.To.SetTarget(n1)
323+
j2.To.SetTarget(s.Pc())
324324
}
325325

326326
case ssa.OpAMD64HMULQ, ssa.OpAMD64HMULL, ssa.OpAMD64HMULQU, ssa.OpAMD64HMULLU:

src/cmd/compile/internal/gc/gsubr.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,6 @@ func Patch(p *obj.Prog, to *obj.Prog) {
342342
if p.To.Type != obj.TYPE_BRANCH {
343343
Fatalf("patch: not a branch")
344344
}
345-
p.To.Val = to
345+
p.To.SetTarget(to)
346346
p.To.Offset = to.Pc
347347
}

src/cmd/compile/internal/gc/ssa.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6182,7 +6182,7 @@ func genssa(f *ssa.Func, pp *Progs) {
61826182

61836183
// Resolve branches, and relax DefaultStmt into NotStmt
61846184
for _, br := range s.Branches {
6185-
br.P.To.Val = s.bstart[br.B.ID]
6185+
br.P.To.SetTarget(s.bstart[br.B.ID])
61866186
if br.P.Pos.IsStmt() != src.PosIsStmt {
61876187
br.P.Pos = br.P.Pos.WithNotStmt()
61886188
} else if v0 := br.B.FirstPossibleStmtValue(); v0 != nil && v0.Pos.Line() == br.P.Pos.Line() && v0.Pos.IsStmt() == src.PosIsStmt {

src/cmd/compile/internal/s390x/ssa.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
338338
n.To.Reg = dividend
339339
}
340340

341-
j.To.Val = n
342-
j2.To.Val = s.Pc()
341+
j.To.SetTarget(n)
342+
j2.To.SetTarget(s.Pc())
343343
}
344344
case ssa.OpS390XADDconst, ssa.OpS390XADDWconst:
345345
opregregimm(s, v.Op.Asm(), v.Reg(), v.Args[0].Reg(), v.AuxInt)

src/cmd/compile/internal/x86/ssa.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
261261
n.To.Reg = x86.REG_DX
262262
}
263263

264-
j.To.Val = n
265-
j2.To.Val = s.Pc()
264+
j.To.SetTarget(n)
265+
j2.To.SetTarget(s.Pc())
266266
}
267267

268268
case ssa.Op386HMULL, ssa.Op386HMULLU:

src/cmd/internal/obj/arm/asm5.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ func (c *ctxt5) flushpool(p *obj.Prog, skip int, force int) bool {
644644
q := c.newprog()
645645
q.As = AB
646646
q.To.Type = obj.TYPE_BRANCH
647-
q.Pcond = p.Link
647+
q.To.SetTarget(p.Link)
648648
q.Link = c.blitrl
649649
q.Pos = p.Pos
650650
c.blitrl = q
@@ -705,7 +705,7 @@ func (c *ctxt5) addpool(p *obj.Prog, a *obj.Addr) {
705705
if t.Rel == nil {
706706
for q := c.blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */
707707
if q.Rel == nil && q.To == t.To {
708-
p.Pcond = q
708+
p.Pool = q
709709
return
710710
}
711711
}
@@ -724,8 +724,8 @@ func (c *ctxt5) addpool(p *obj.Prog, a *obj.Addr) {
724724
c.elitrl = q
725725
c.pool.size += 4
726726

727-
// Store the link to the pool entry in Pcond.
728-
p.Pcond = q
727+
// Store the link to the pool entry in Pool.
728+
p.Pool = q
729729
}
730730

731731
func (c *ctxt5) regoff(a *obj.Addr) int32 {
@@ -1584,8 +1584,8 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
15841584
break
15851585
}
15861586

1587-
if p.Pcond != nil {
1588-
v = int32((p.Pcond.Pc - c.pc) - 8)
1587+
if p.To.Target() != nil {
1588+
v = int32((p.To.Target().Pc - c.pc) - 8)
15891589
}
15901590
o1 |= (uint32(v) >> 2) & 0xffffff
15911591

@@ -3023,7 +3023,7 @@ func (c *ctxt5) omvr(p *obj.Prog, a *obj.Addr, dr int) uint32 {
30233023

30243024
func (c *ctxt5) omvl(p *obj.Prog, a *obj.Addr, dr int) uint32 {
30253025
var o1 uint32
3026-
if p.Pcond == nil {
3026+
if p.Pool == nil {
30273027
c.aclass(a)
30283028
v := immrot(^uint32(c.instoffset))
30293029
if v == 0 {
@@ -3035,7 +3035,7 @@ func (c *ctxt5) omvl(p *obj.Prog, a *obj.Addr, dr int) uint32 {
30353035
o1 |= uint32(v)
30363036
o1 |= (uint32(dr) & 15) << 12
30373037
} else {
3038-
v := int32(p.Pcond.Pc - p.Pc - 8)
3038+
v := int32(p.Pool.Pc - p.Pc - 8)
30393039
o1 = c.olr(v, REGPC, dr, int(p.Scond)&C_SCOND)
30403040
}
30413041

src/cmd/internal/obj/arm/obj5.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
406406
mov.To.Reg = REG_R2
407407

408408
// B.NE branch target is MOVW above
409-
bne.Pcond = mov
409+
bne.To.SetTarget(mov)
410410

411411
// ADD $(autosize+4), R13, R3
412412
p = obj.Appendp(mov, newprog)
@@ -428,7 +428,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
428428
p = obj.Appendp(p, newprog)
429429
p.As = ABNE
430430
p.To.Type = obj.TYPE_BRANCH
431-
p.Pcond = end
431+
p.To.SetTarget(end)
432432

433433
// ADD $4, R13, R4
434434
p = obj.Appendp(p, newprog)
@@ -452,7 +452,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
452452
p = obj.Appendp(p, newprog)
453453
p.As = AB
454454
p.To.Type = obj.TYPE_BRANCH
455-
p.Pcond = end
455+
p.To.SetTarget(end)
456456

457457
// reset for subsequent passes
458458
p = end
@@ -741,7 +741,7 @@ func (c *ctxt5) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
741741
movw.To.Type = obj.TYPE_REG
742742
movw.To.Reg = REG_R3
743743

744-
bls.Pcond = movw
744+
bls.To.SetTarget(movw)
745745

746746
// BL runtime.morestack
747747
call := obj.Appendp(movw, c.newprog)
@@ -762,7 +762,7 @@ func (c *ctxt5) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
762762
b := obj.Appendp(pcdata, c.newprog)
763763
b.As = obj.AJMP
764764
b.To.Type = obj.TYPE_BRANCH
765-
b.Pcond = c.cursym.Func.Text.Link
765+
b.To.SetTarget(c.cursym.Func.Text.Link)
766766
b.Spadj = +framesize
767767

768768
return end

src/cmd/internal/obj/arm64/asm7.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -977,8 +977,8 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
977977
o = c.oplook(p)
978978

979979
/* very large branches */
980-
if (o.type_ == 7 || o.type_ == 39 || o.type_ == 40) && p.Pcond != nil { // 7: BEQ and like, 39: CBZ and like, 40: TBZ and like
981-
otxt := p.Pcond.Pc - pc
980+
if (o.type_ == 7 || o.type_ == 39 || o.type_ == 40) && p.To.Target() != nil { // 7: BEQ and like, 39: CBZ and like, 40: TBZ and like
981+
otxt := p.To.Target().Pc - pc
982982
var toofar bool
983983
switch o.type_ {
984984
case 7, 39: // branch instruction encodes 19 bits
@@ -992,14 +992,14 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
992992
p.Link = q
993993
q.As = AB
994994
q.To.Type = obj.TYPE_BRANCH
995-
q.Pcond = p.Pcond
996-
p.Pcond = q
995+
q.To.SetTarget(p.To.Target())
996+
p.To.SetTarget(q)
997997
q = c.newprog()
998998
q.Link = p.Link
999999
p.Link = q
10001000
q.As = AB
10011001
q.To.Type = obj.TYPE_BRANCH
1002-
q.Pcond = q.Link.Link
1002+
q.To.SetTarget(q.Link.Link)
10031003
bflag = 1
10041004
}
10051005
}
@@ -1123,7 +1123,7 @@ func (c *ctxt7) flushpool(p *obj.Prog, skip int) {
11231123
q := c.newprog()
11241124
q.As = AB
11251125
q.To.Type = obj.TYPE_BRANCH
1126-
q.Pcond = p.Link
1126+
q.To.SetTarget(p.Link)
11271127
q.Link = c.blitrl
11281128
q.Pos = p.Pos
11291129
c.blitrl = q
@@ -1249,7 +1249,7 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) {
12491249

12501250
for q := c.blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */
12511251
if q.To == t.To {
1252-
p.Pcond = q
1252+
p.Pool = q
12531253
return
12541254
}
12551255
}
@@ -1266,7 +1266,7 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) {
12661266
c.elitrl = q
12671267
c.pool.size = -c.pool.size & (funcAlign - 1)
12681268
c.pool.size += uint32(sz)
1269-
p.Pcond = q
1269+
p.Pool = q
12701270
}
12711271

12721272
func (c *ctxt7) regoff(a *obj.Addr) uint32 {
@@ -6042,15 +6042,15 @@ func (c *ctxt7) opimm(p *obj.Prog, a obj.As) uint32 {
60426042
func (c *ctxt7) brdist(p *obj.Prog, preshift int, flen int, shift int) int64 {
60436043
v := int64(0)
60446044
t := int64(0)
6045-
if p.Pcond != nil {
6046-
v = (p.Pcond.Pc >> uint(preshift)) - (c.pc >> uint(preshift))
6045+
if p.To.Target() != nil {
6046+
v = (p.To.Target().Pc >> uint(preshift)) - (c.pc >> uint(preshift))
60476047
if (v & ((1 << uint(shift)) - 1)) != 0 {
60486048
c.ctxt.Diag("misaligned label\n%v", p)
60496049
}
60506050
v >>= uint(shift)
60516051
t = int64(1) << uint(flen-1)
60526052
if v < -t || v >= t {
6053-
c.ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, c.blitrl, p, p.Pcond)
6053+
c.ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, c.blitrl, p, p.To.Target())
60546054
panic("branch too far")
60556055
}
60566056
}
@@ -6526,7 +6526,7 @@ func (c *ctxt7) oaddi(p *obj.Prog, o1 int32, v int32, r int, rt int) uint32 {
65266526
*/
65276527
func (c *ctxt7) omovlit(as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 {
65286528
var o1 int32
6529-
if p.Pcond == nil { /* not in literal pool */
6529+
if p.Pool == nil { /* not in literal pool */
65306530
c.aclass(a)
65316531
c.ctxt.Logf("omovlit add %d (%#x)\n", c.instoffset, uint64(c.instoffset))
65326532

@@ -6552,11 +6552,11 @@ func (c *ctxt7) omovlit(as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 {
65526552
w = 1 /* 64-bit SIMD/FP */
65536553

65546554
case AMOVD:
6555-
if p.Pcond.As == ADWORD {
6555+
if p.Pool.As == ADWORD {
65566556
w = 1 /* 64-bit */
6557-
} else if p.Pcond.To.Offset < 0 {
6557+
} else if p.Pool.To.Offset < 0 {
65586558
w = 2 /* 32-bit, sign-extended to 64-bit */
6559-
} else if p.Pcond.To.Offset >= 0 {
6559+
} else if p.Pool.To.Offset >= 0 {
65606560
w = 0 /* 32-bit, zero-extended to 64-bit */
65616561
} else {
65626562
c.ctxt.Diag("invalid operand %v in %v", a, p)

src/cmd/internal/obj/arm64/obj7.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,9 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
187187
movlr.To.Type = obj.TYPE_REG
188188
movlr.To.Reg = REG_R3
189189
if q != nil {
190-
q.Pcond = movlr
190+
q.To.SetTarget(movlr)
191191
}
192-
bls.Pcond = movlr
192+
bls.To.SetTarget(movlr)
193193

194194
debug := movlr
195195
if false {
@@ -220,7 +220,7 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
220220
jmp := obj.Appendp(pcdata, c.newprog)
221221
jmp.As = AB
222222
jmp.To.Type = obj.TYPE_BRANCH
223-
jmp.Pcond = c.cursym.Func.Text.Link
223+
jmp.To.SetTarget(c.cursym.Func.Text.Link)
224224
jmp.Spadj = +framesize
225225

226226
return end
@@ -697,7 +697,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
697697
mov.To.Reg = REG_R2
698698

699699
// CBNZ branches to the MOV above
700-
cbnz.Pcond = mov
700+
cbnz.To.SetTarget(mov)
701701

702702
// ADD $(autosize+8), SP, R3
703703
q = obj.Appendp(mov, c.newprog)
@@ -719,7 +719,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
719719
q = obj.Appendp(q, c.newprog)
720720
q.As = ABNE
721721
q.To.Type = obj.TYPE_BRANCH
722-
q.Pcond = end
722+
q.To.SetTarget(end)
723723

724724
// ADD $8, SP, R4
725725
q = obj.Appendp(q, c.newprog)
@@ -743,7 +743,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
743743
q = obj.Appendp(q, c.newprog)
744744
q.As = AB
745745
q.To.Type = obj.TYPE_BRANCH
746-
q.Pcond = end
746+
q.To.SetTarget(end)
747747
}
748748

749749
case obj.ARET:
@@ -913,7 +913,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
913913
q5.Reg = REGSP
914914
q5.To.Type = obj.TYPE_REG
915915
q5.To.Reg = REGFP
916-
q1.Pcond = q5
916+
q1.From.SetTarget(q5)
917917
p = q5
918918
}
919919

@@ -966,7 +966,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
966966
q5.Reg = REGSP
967967
q5.To.Type = obj.TYPE_REG
968968
q5.To.Reg = REGFP
969-
q1.Pcond = q5
969+
q1.From.SetTarget(q5)
970970
p = q5
971971
}
972972
}

src/cmd/internal/obj/link.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,19 @@ const (
237237
TYPE_REGLIST
238238
)
239239

240+
func (a *Addr) Target() *Prog {
241+
if a.Type == TYPE_BRANCH && a.Val != nil {
242+
return a.Val.(*Prog)
243+
}
244+
return nil
245+
}
246+
func (a *Addr) SetTarget(t *Prog) {
247+
if a.Type != TYPE_BRANCH {
248+
panic("setting branch target when type is not TYPE_BRANCH")
249+
}
250+
a.Val = t
251+
}
252+
240253
// Prog describes a single machine instruction.
241254
//
242255
// The general instruction form is:
@@ -255,7 +268,7 @@ const (
255268
// to avoid too much changes in a single swing.
256269
// (1) scheme is enough to express any kind of operand combination.
257270
//
258-
// Jump instructions use the Pcond field to point to the target instruction,
271+
// Jump instructions use the To.Val field to point to the target *Prog,
259272
// which must be in the same linked list as the jump instruction.
260273
//
261274
// The Progs for a given function are arranged in a list linked through the Link field.
@@ -274,7 +287,7 @@ type Prog struct {
274287
From Addr // first source operand
275288
RestArgs []Addr // can pack any operands that not fit into {Prog.From, Prog.To}
276289
To Addr // destination operand (second is RegTo2 below)
277-
Pcond *Prog // target of conditional jump
290+
Pool *Prog // constant pool entry, for arm,arm64 back ends
278291
Forwd *Prog // for x86 back end
279292
Rel *Prog // for x86, arm back ends
280293
Pc int64 // for back ends or assembler: virtual or actual program counter, depending on phase

0 commit comments

Comments
 (0)