Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Commit 8f35ae0

Browse files
committed
Store instruction data in interface, instead of directly
1 parent 55e8e65 commit 8f35ae0

7 files changed

Lines changed: 75 additions & 63 deletions

File tree

go/src/enjarify-go/jvm/consts.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ func AllocateRequiredConstants(pool cpool.Pool, long_irs []*IRWriter) {
3232
for i := range irw.Instructions {
3333
instr := &irw.Instructions[i]
3434
if instr.Tag == ir.PRIMCONSTANT {
35-
key := instr.PrimConstant.Pair
35+
key := instr.PrimConstant().Pair
3636
alt_lens[key] = len(instr.Bytecode)
37-
if instr.PrimConstant.T.Wide() {
37+
if instr.PrimConstant().T.Wide() {
3838
if len(instr.Bytecode) > 3 {
3939
wide_pairs[key] += 1
4040
}

go/src/enjarify-go/jvm/ir/ir.go

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,24 @@ type Instruction struct {
4646
HasBC bool
4747

4848
Tag insTag
49-
Label
50-
RegAccess
51-
PrimConstant
52-
Goto
53-
If
54-
Switch
49+
sub interface{}
5550
}
5651

52+
func (self *Instruction) Label() Label {
53+
lbl, ok := self.sub.(*Label)
54+
if !ok {
55+
return Label{}
56+
} else {
57+
return *lbl
58+
}
59+
}
60+
61+
func (self *Instruction) RegAccess() *RegAccess { return self.sub.(*RegAccess) }
62+
func (self *Instruction) PrimConstant() *PrimConstant { return self.sub.(*PrimConstant) }
63+
func (self *Instruction) Goto() *Goto { return self.sub.(*Goto) }
64+
func (self *Instruction) If() *If { return self.sub.(*If) }
65+
func (self *Instruction) Switch() *Switch { return self.sub.(*Switch) }
66+
5767
func (self *Instruction) Fallsthrough() bool {
5868
switch self.Tag {
5969
case GOTO_TAG, SWITCH:
@@ -71,11 +81,12 @@ func (self *Instruction) Fallsthrough() bool {
7181
func (self *Instruction) Targets() []uint32 {
7282
switch self.Tag {
7383
case GOTO_TAG:
74-
return []uint32{self.Goto.Target}
84+
return []uint32{self.Goto().Target}
7585
case IF:
76-
return []uint32{self.If.Target}
86+
return []uint32{self.If().Target}
7787
case SWITCH:
7888
{
89+
self := self.Switch()
7990
result := make([]uint32, 0, 1+len(self.Jumps))
8091
for _, v := range self.Jumps {
8192
result = append(result, v)
@@ -97,19 +108,19 @@ func (self *Instruction) IsConstant() bool {
97108
func (self *Instruction) MinLen(pos uint32) uint32 {
98109
switch self.Tag {
99110
case GOTO_TAG:
100-
if self.Goto.Wide {
111+
if self.Goto().Wide {
101112
return 5
102113
} else {
103114
return 3
104115
}
105116
case IF:
106-
if self.If.Wide {
117+
if self.If().Wide {
107118
return 8
108119
} else {
109120
return 3
110121
}
111122
case SWITCH:
112-
return ((^pos) % 4) + self.NoPadSize
123+
return ((^pos) % 4) + self.Switch().NoPadSize
113124
default:
114125
return uint32(len(self.Bytecode))
115126
}
@@ -125,7 +136,7 @@ func (self *Instruction) UpperBound() int {
125136
case IF:
126137
return 8
127138
case SWITCH:
128-
return 3 + int(self.NoPadSize)
139+
return 3 + int(self.Switch().NoPadSize)
129140
}
130141
panic(util.Unreachable)
131142
}
@@ -149,7 +160,7 @@ type Label struct {
149160
}
150161

151162
func NewLabel(tag lblTag, pos uint32) Instruction {
152-
return Instruction{HasBC: true, Tag: LABEL, Label: Label{tag, pos}}
163+
return Instruction{HasBC: true, Tag: LABEL, sub: &Label{tag, pos}}
153164
}
154165

155166
type RegKey struct {
@@ -184,12 +195,12 @@ func (self *RegAccess) CalcBytecode(local uint16) string {
184195
}
185196

186197
func NewRegAccess(dreg uint16, st scalars.T, store bool) Instruction {
187-
return Instruction{Tag: REGACCESS, RegAccess: RegAccess{RegKey{dreg, st}, store}}
198+
return Instruction{Tag: REGACCESS, sub: &RegAccess{RegKey{dreg, st}, store}}
188199
}
189200

190201
func RawRegAccess(local uint16, st scalars.T, store bool) Instruction {
191202
data := RegAccess{RegKey{0, st}, store}
192-
return Instruction{Bytecode: data.CalcBytecode(local), HasBC: true, Tag: REGACCESS, RegAccess: data}
203+
return Instruction{Bytecode: data.CalcBytecode(local), HasBC: true, Tag: REGACCESS, sub: &data}
193204
}
194205

195206
type PrimConstant struct {
@@ -260,7 +271,7 @@ func NewPrimConstant(st scalars.T, val uint64, pool cpool.Pool) Instruction {
260271
} else {
261272
bytecode = constants.Calc(st, val)
262273
}
263-
return Instruction{Bytecode: bytecode, HasBC: true, Tag: PRIMCONSTANT, PrimConstant: PrimConstant{st, key}}
274+
return Instruction{Bytecode: bytecode, HasBC: true, Tag: PRIMCONSTANT, sub: &PrimConstant{st, key}}
264275
}
265276

266277
func NewOtherConstant(bc string) Instruction {
@@ -273,7 +284,7 @@ type Goto struct {
273284
}
274285

275286
func NewGoto(target uint32) Instruction {
276-
return Instruction{Tag: GOTO_TAG, Goto: Goto{target, false}}
287+
return Instruction{Tag: GOTO_TAG, sub: &Goto{target, false}}
277288
}
278289

279290
type If struct {
@@ -283,7 +294,7 @@ type If struct {
283294
}
284295

285296
func NewIf(op uint8, target uint32) Instruction {
286-
return Instruction{Tag: IF, If: If{target, false, op}}
297+
return Instruction{Tag: IF, sub: &If{target, false, op}}
287298
}
288299

289300
type Switch struct {
@@ -317,7 +328,7 @@ func NewSwitch(def uint32, jumps map[int32]uint32) Instruction {
317328
best = jumpSize
318329
}
319330

320-
return Instruction{Tag: SWITCH, Switch: Switch{
331+
return Instruction{Tag: SWITCH, sub: &Switch{
321332
Default: def,
322333
Jumps: jumps,
323334
Low: int32(low),

go/src/enjarify-go/jvm/irwriter.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,11 @@ func (self *IRWriter) calcInitialArgs(nregs uint16, scalar_ptypes []scalars.T) {
8282

8383
func (self *IRWriter) addExceptionRedirect(target uint32) ir.Label {
8484
if val, ok := self.exception_redirects[target]; ok {
85-
return val.Label
85+
return val.Label()
8686
}
87-
self.exception_redirects[target] = ir.NewLabel(ir.EHANDLER, target)
88-
return self.exception_redirects[target].Label
87+
temp := ir.NewLabel(ir.EHANDLER, target)
88+
self.exception_redirects[target] = temp
89+
return temp.Label()
8990
}
9091

9192
func (self *IRWriter) createBlock(pos uint32) *irBlock {

go/src/enjarify-go/jvm/jumps.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func widenIfNecessary(ins *ir.Instruction, pos uint32, info PosInfo) bool {
4242
switch ins.Tag {
4343
case ir.GOTO_TAG:
4444
{
45-
data := &ins.Goto
45+
data := ins.Goto()
4646
if data.Wide {
4747
return false
4848
}
@@ -52,7 +52,7 @@ func widenIfNecessary(ins *ir.Instruction, pos uint32, info PosInfo) bool {
5252
}
5353
case ir.IF:
5454
{
55-
data := &ins.If
55+
data := ins.If()
5656
if data.Wide {
5757
return false
5858
}
@@ -77,7 +77,7 @@ func optimizeJumps(irdata *IRWriter) {
7777
for i := range instrs {
7878
ins := &instrs[i]
7979
if ins.Tag == ir.LABEL {
80-
lblToVind[ins.Label] = i
80+
lblToVind[ins.Label()] = i
8181
}
8282
}
8383

@@ -110,7 +110,7 @@ func createBytecode(irdata *IRWriter) (string, []string) {
110110
for i := range instrs {
111111
ins := &instrs[i]
112112
if ins.Tag == ir.LABEL {
113-
lblToVind[ins.Label] = i
113+
lblToVind[ins.Label()] = i
114114
}
115115
}
116116

@@ -125,7 +125,7 @@ func createBytecode(irdata *IRWriter) (string, []string) {
125125
switch ins.Tag {
126126
case ir.GOTO_TAG:
127127
{
128-
data := ins.Goto
128+
data := ins.Goto()
129129
offset := info.offset(pos, data.Target)
130130
if data.Wide {
131131
stream.WriteString(byteio.Bi(GOTO_W, offset))
@@ -135,7 +135,7 @@ func createBytecode(irdata *IRWriter) (string, []string) {
135135
}
136136
case ir.IF:
137137
{
138-
data := ins.If
138+
data := ins.If()
139139
offset := info.offset(pos, data.Target)
140140
if data.Wide {
141141
// Unlike with goto, if instructions are limited to a 16 bit jump offset.
@@ -157,7 +157,7 @@ func createBytecode(irdata *IRWriter) (string, []string) {
157157
}
158158
case ir.SWITCH:
159159
{
160-
data := ins.Switch
160+
data := ins.Switch()
161161
offset := info.offset(pos, data.Default)
162162
pad := (^pos) % 4
163163

@@ -206,12 +206,12 @@ func createBytecode(irdata *IRWriter) (string, []string) {
206206
// therefore we include the previous (IR) instruction too
207207
// Note that this cannot cause an overlap because in that case the previous
208208
// instruction would just be a label and hence not change anything
209-
sind := lblToVind[item.start.Label]
209+
sind := lblToVind[item.start.Label()]
210210
if sind > 0 {
211211
sind--
212212
}
213213
soff := positions[sind]
214-
excepts = append(excepts, byteio.HHHH(uint16(soff), uint16(info.getlbl(item.end.Label)), uint16(info.getlbl(item.target)), item.ctype))
214+
excepts = append(excepts, byteio.HHHH(uint16(soff), uint16(info.getlbl(item.end.Label())), uint16(info.getlbl(item.target)), item.ctype))
215215
}
216216

217217
return stream.String(), excepts

go/src/enjarify-go/jvm/registers.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -118,23 +118,23 @@ func CopyPropagation(irdata *IRWriter) {
118118
for i := range instrs {
119119
instr := &instrs[i]
120120
// reset all info when control flow is merged
121-
if irdata.IsTarget(instr.Label) {
121+
if irdata.IsTarget(instr.Label()) {
122122
// try to use info if this was a single predecessor forward jump
123-
if i > 0 && !prev.Fallsthrough() && irdata.target_pred_counts[instr.Label] == 1 {
124-
current = single_pred_infos[instr.Label]
123+
if i > 0 && !prev.Fallsthrough() && irdata.target_pred_counts[instr.Label()] == 1 {
124+
current = single_pred_infos[instr.Label()]
125125
if current == nil {
126126
current = newCopySetsMap()
127127
}
128128
} else {
129129
current = newCopySetsMap()
130130
}
131131
} else if instr.Tag == ir.REGACCESS {
132-
ins := instr.RegAccess
132+
ins := instr.RegAccess()
133133
key := ins.RegKey
134134
if ins.Store {
135135
// check if previous instr was a load
136-
if prev.Tag == ir.REGACCESS && !prev.RegAccess.Store {
137-
if !current.move(key, prev.RegKey) {
136+
if prev.Tag == ir.REGACCESS && !prev.RegAccess().Store {
137+
if !current.move(key, prev.RegAccess().RegKey) {
138138
replace[i-1] = nil
139139
replace[i] = nil
140140
}
@@ -172,8 +172,8 @@ func RemoveUnusedRegisters(irdata *IRWriter) {
172172
used := make(map[ir.RegKey]bool)
173173
for i := range instrs {
174174
instr := &instrs[i]
175-
if instr.Tag == ir.REGACCESS && !instr.RegAccess.Store {
176-
used[instr.RegKey] = true
175+
if instr.Tag == ir.REGACCESS && !instr.RegAccess().Store {
176+
used[instr.RegAccess().RegKey] = true
177177
}
178178
}
179179

@@ -182,22 +182,22 @@ func RemoveUnusedRegisters(irdata *IRWriter) {
182182
for i := range instrs {
183183
instr := &instrs[i]
184184
if instr.Tag == ir.REGACCESS {
185-
if !used[instr.RegAccess.RegKey] {
186-
util.Assert(instr.RegAccess.Store)
185+
if !used[instr.RegAccess().RegKey] {
186+
util.Assert(instr.RegAccess().Store)
187187
// if prev instruction is load or const, just remove it and the store
188188
// otherwise, replace the store with a pop
189189
if prev_was_replaceable {
190190
replace[i-1] = nil
191191
replace[i] = nil
192192
} else {
193-
if instr.RegAccess.T.Wide() {
193+
if instr.RegAccess().T.Wide() {
194194
replace[i] = []ir.Instruction{ir.NewOther(byteio.B(POP2))}
195195
} else {
196196
replace[i] = []ir.Instruction{ir.NewOther(byteio.B(POP))}
197197
}
198198
}
199199
}
200-
prev_was_replaceable = !instr.RegAccess.Store
200+
prev_was_replaceable = !instr.RegAccess().Store
201201
} else {
202202
prev_was_replaceable = instr.IsConstant()
203203
}
@@ -218,16 +218,16 @@ func SimpleAllocateRegisters(irdata *IRWriter) {
218218
for i := range instrs {
219219
instr := &instrs[i]
220220
if instr.Tag == ir.REGACCESS {
221-
if _, ok := regmap[instr.RegKey]; !ok {
222-
regmap[instr.RegKey] = next
221+
if _, ok := regmap[instr.RegAccess().RegKey]; !ok {
222+
regmap[instr.RegAccess().RegKey] = next
223223
next++
224-
if instr.RegAccess.T.Wide() {
224+
if instr.RegAccess().T.Wide() {
225225
next++
226226
}
227227
}
228-
_, ok := regmap[instr.RegKey]
228+
_, ok := regmap[instr.RegAccess().RegKey]
229229
util.Assert(ok)
230-
instrs[i].Bytecode = instr.CalcBytecode(uint16(regmap[instr.RegKey]))
230+
instrs[i].Bytecode = instr.RegAccess().CalcBytecode(uint16(regmap[instr.RegAccess().RegKey]))
231231
instrs[i].HasBC = true
232232
}
233233
}
@@ -264,7 +264,7 @@ func SortAllocateRegisters(irdata *IRWriter) {
264264
for i := range instrs {
265265
instr := &instrs[i]
266266
if instr.Tag == ir.REGACCESS {
267-
use_counts[instr.RegKey] += 1
267+
use_counts[instr.RegAccess().RegKey] += 1
268268
}
269269
}
270270

@@ -343,7 +343,7 @@ func SortAllocateRegisters(irdata *IRWriter) {
343343
for i := range instrs {
344344
instr := &instrs[i]
345345
if instr.Tag == ir.REGACCESS && !instr.HasBC {
346-
instr.Bytecode = instr.RegAccess.CalcBytecode(uint16(regmap[instr.RegKey]))
346+
instr.Bytecode = instr.RegAccess().CalcBytecode(uint16(regmap[instr.RegAccess().RegKey]))
347347
instr.HasBC = true
348348
}
349349
}

0 commit comments

Comments
 (0)