This commit is contained in:
parent
f357285045
commit
0ece1b092e
23 changed files with 274 additions and 113 deletions
|
@ -7,7 +7,7 @@ import (
|
|||
)
|
||||
|
||||
type Field struct {
|
||||
Struct Value
|
||||
Object Value
|
||||
Field *types.Field
|
||||
Liveness
|
||||
Source
|
||||
|
@ -15,8 +15,8 @@ type Field struct {
|
|||
|
||||
func (v *Field) IsConst() bool { return true }
|
||||
func (v *Field) Type() types.Type { return v.Field.Type }
|
||||
func (v *Field) String() string { return fmt.Sprintf("%s.%s", v.Struct, v.Field) }
|
||||
func (v *Field) Inputs() []Value { return []Value{v.Struct} }
|
||||
func (v *Field) String() string { return fmt.Sprintf("%s.%s", v.Object, v.Field) }
|
||||
func (v *Field) Inputs() []Value { return []Value{v.Object} }
|
||||
|
||||
func (a *Field) Equals(v Value) bool {
|
||||
b, sameType := v.(*Field)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ssa
|
||||
|
||||
import "slices"
|
||||
|
||||
// IR is a list of basic blocks.
|
||||
type IR struct {
|
||||
Blocks []*Block
|
||||
|
@ -30,13 +32,24 @@ func (f *IR) Append(instr Value) Value {
|
|||
return f.Blocks[len(f.Blocks)-1].Append(instr)
|
||||
}
|
||||
|
||||
// CountValues returns the total number of values.
|
||||
func (f *IR) CountValues() int {
|
||||
count := 0
|
||||
|
||||
for _, block := range f.Blocks {
|
||||
count += len(block.Instructions)
|
||||
}
|
||||
|
||||
return count
|
||||
}
|
||||
|
||||
// FindExisting returns an equal instruction that's already appended or `nil` if none could be found.
|
||||
func (f *IR) FindExisting(instr Value) Value {
|
||||
if !instr.IsConst() {
|
||||
return nil
|
||||
}
|
||||
|
||||
for existing := range f.Values {
|
||||
for _, existing := range f.Values {
|
||||
if existing.IsConst() && instr.Equals(existing) {
|
||||
return existing
|
||||
}
|
||||
|
@ -46,10 +59,29 @@ func (f *IR) FindExisting(instr Value) Value {
|
|||
}
|
||||
|
||||
// Values yields on each value.
|
||||
func (f *IR) Values(yield func(Value) bool) {
|
||||
func (f *IR) Values(yield func(int, Value) bool) {
|
||||
index := 0
|
||||
|
||||
for _, block := range f.Blocks {
|
||||
for _, instr := range block.Instructions {
|
||||
if !yield(instr) {
|
||||
if !yield(index, instr) {
|
||||
return
|
||||
}
|
||||
|
||||
index++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ValuesBackward yields on each value from the end towards the start.
|
||||
func (f *IR) ValuesBackward(yield func(int, Value) bool) {
|
||||
index := f.CountValues()
|
||||
|
||||
for _, block := range slices.Backward(f.Blocks) {
|
||||
for _, instr := range slices.Backward(block.Instructions) {
|
||||
index--
|
||||
|
||||
if !yield(index, instr) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue