Implemented liveness analysis
All checks were successful
/ test (push) Successful in 15s

This commit is contained in:
Eduard Urbach 2025-07-04 19:06:47 +02:00
parent f357285045
commit 0ece1b092e
Signed by: akyoto
GPG key ID: 49226B848C78F6C8
23 changed files with 274 additions and 113 deletions

View file

@ -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)

View file

@ -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
}
}