Skip to content

Commit 601abd0

Browse files
committed
fix: back out bogus refactoring to optimizer
1 parent aa8b0ca commit 601abd0

File tree

2 files changed

+85
-94
lines changed

2 files changed

+85
-94
lines changed

bytecode/optimizer.go

Lines changed: 84 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,95 @@ func (b *ByteCode) optimize(count int) (int, error) {
7373

7474
// Is there a branch INTO this pattern? If so, then it
7575
// cannot be optimized.
76-
if branchTargetInPatter(b, idx, optimization, found) {
76+
for _, i := range b.instructions {
77+
if i.Operation > BranchInstructions {
78+
destination := data.Int(i.Operand)
79+
if destination >= idx && destination < idx+len(optimization.Pattern) {
80+
found = false
81+
82+
break
83+
}
84+
}
85+
}
86+
87+
if !found {
7788
continue
7889
}
7990

8091
// Search each instruction in the pattern to see if it matches
8192
// with the instruction stream we are positioned at.
82-
found = doesPatternMatch(optimization, b, idx, found, operandValues, registers)
93+
for sourceIdx, sourceInstruction := range optimization.Pattern {
94+
if b.nextAddress <= idx+sourceIdx {
95+
found = false
96+
97+
// This optimization can't fit because we're too near the end
98+
// so go on to the next optimization.
99+
break
100+
}
101+
102+
i := b.instructions[idx+sourceIdx]
103+
104+
// If the source instruction requires an empty operand and the operand isn't nil,
105+
// then we skip this optimization.
106+
if _, isEmpty := sourceInstruction.Operand.(empty); isEmpty && i.Operand != nil {
107+
found = false
108+
109+
// This optimization didn't match; go to next optimization
110+
break
111+
}
112+
113+
if sourceInstruction.Operation != i.Operation {
114+
found = false
115+
116+
// This optimization didn't match; go to next optimization
117+
break
118+
}
119+
120+
// Special type checks for specific operand patterns
121+
if pattern, ok := sourceInstruction.Operand.(placeholder); ok {
122+
if pattern.MustBeString {
123+
if _, ok := i.Operand.(string); !ok {
124+
found = false
125+
126+
break
127+
}
128+
}
129+
}
130+
131+
// If the operands match between the instruction and the pattern,
132+
// we're good and should keep going...
133+
if reflect.DeepEqual(sourceInstruction.Operand, i.Operand) {
134+
continue
135+
}
136+
137+
if token, ok := sourceInstruction.Operand.(placeholder); ok {
138+
value, inMap := operandValues[token.Name]
139+
if inMap {
140+
if value.Value == i.Operand {
141+
// no work to do
142+
} else if i.Operand != sourceInstruction.Operand {
143+
found = false
144+
145+
continue
146+
}
147+
} else {
148+
switch token.Operation {
149+
case OptCount:
150+
increment := 1
151+
if i.Operand != nil {
152+
increment = data.Int(i.Operand)
153+
}
154+
155+
registers[token.Register] = data.Int(registers[token.Register]) + increment
156+
157+
case optStore:
158+
registers[token.Register] = i.Operand
159+
}
160+
161+
operandValues[token.Name] = placeholder{Name: token.Name, Value: i.Operand}
162+
}
163+
}
164+
}
83165

84166
// Does this optimization match?
85167
if found {
@@ -159,97 +241,6 @@ func (b *ByteCode) optimize(count int) (int, error) {
159241
return count, nil
160242
}
161243

162-
// Determine if the current operation is the start of this optimization pattern. Compares
163-
// the operation and operands, and ensures there is enough room to fit the pattern.
164-
func doesPatternMatch(optimization optimization, b *ByteCode, idx int, found bool, operandValues map[string]placeholder, registers []interface{}) bool {
165-
for sourceIdx, sourceInstruction := range optimization.Pattern {
166-
// This optimization can't fit because we're too near the end
167-
// so go on to the next optimization.
168-
if b.nextAddress <= idx+sourceIdx {
169-
found = false
170-
171-
break
172-
}
173-
174-
i := b.instructions[idx+sourceIdx]
175-
176-
// If the source instruction requires an empty operand and the operand isn't nil,
177-
// then we skip this optimization.
178-
if _, isEmpty := sourceInstruction.Operand.(empty); isEmpty && i.Operand != nil {
179-
found = false
180-
181-
break
182-
}
183-
184-
// This optimization didn't match; go to next optimization
185-
if sourceInstruction.Operation != i.Operation {
186-
found = false
187-
188-
break
189-
}
190-
191-
// This optimization didn't match; go to next optimization
192-
if pattern, ok := sourceInstruction.Operand.(placeholder); ok {
193-
if pattern.MustBeString {
194-
if _, ok := i.Operand.(string); !ok {
195-
found = false
196-
197-
break
198-
}
199-
}
200-
}
201-
202-
if reflect.DeepEqual(sourceInstruction.Operand, i.Operand) {
203-
continue
204-
}
205-
206-
if token, ok := sourceInstruction.Operand.(placeholder); ok {
207-
value, inMap := operandValues[token.Name]
208-
if inMap {
209-
if value.Value == i.Operand {
210-
211-
} else if i.Operand != sourceInstruction.Operand {
212-
found = false
213-
214-
continue
215-
}
216-
} else {
217-
switch token.Operation {
218-
case OptCount:
219-
increment := 1
220-
if i.Operand != nil {
221-
increment = data.Int(i.Operand)
222-
}
223-
224-
registers[token.Register] = data.Int(registers[token.Register]) + increment
225-
226-
case optStore:
227-
registers[token.Register] = i.Operand
228-
}
229-
230-
operandValues[token.Name] = placeholder{Name: token.Name, Value: i.Operand}
231-
}
232-
}
233-
}
234-
235-
return found
236-
}
237-
238-
func branchTargetInPatter(b *ByteCode, idx int, optimization optimization, found bool) bool {
239-
for _, i := range b.instructions {
240-
if i.Operation > BranchInstructions {
241-
destination := data.Int(i.Operand)
242-
if destination >= idx && destination < idx+len(optimization.Pattern) {
243-
found = false
244-
245-
break
246-
}
247-
}
248-
}
249-
250-
return found
251-
}
252-
253244
func (b *ByteCode) executeFragment(start, end int) (interface{}, error) {
254245
fragment := New("code fragment")
255246

tools/buildver.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.5-1137
1+
1.5-1138

0 commit comments

Comments
 (0)