From a083d0806b2d809b57e1e860962f2125bd3f0099 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Mon, 1 Sep 2025 20:30:13 +0200 Subject: [PATCH] Fixed loop replacements for undefined phi values --- src/core/compileLoop.go | 8 +++++++- src/core/errors_test.go | 1 + src/core/testdata/UnusedValue6.q | 13 +++++++++++++ src/ssa/Copy.go | 2 +- src/verbose/SSA.go | 13 +++++++------ 5 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 src/core/testdata/UnusedValue6.q diff --git a/src/core/compileLoop.go b/src/core/compileLoop.go index f803e15..39f4109 100644 --- a/src/core/compileLoop.go +++ b/src/core/compileLoop.go @@ -118,12 +118,18 @@ func (f *Function) compileLoop(loop *ast.Loop) error { block.Loop = loopHead for phi := range loopHead.Phis { + oldValue := phi.Arguments[0] + + if oldValue == ssa.Undefined { + continue + } + for _, instr := range block.Instructions { if instr == phi { continue } - instr.Replace(phi.Arguments[0], phi) + instr.Replace(oldValue, phi) } } } diff --git a/src/core/errors_test.go b/src/core/errors_test.go index 710cd95..ef2bc69 100644 --- a/src/core/errors_test.go +++ b/src/core/errors_test.go @@ -64,6 +64,7 @@ var errs = []struct { {"UnusedValue3.q", &core.UnusedValue{Value: "\"not used\""}}, {"UnusedValue4.q", &core.UnusedValue{Value: "1"}}, {"UnusedValue5.q", &core.UnusedValue{Value: "x + 1"}}, + {"UnusedValue6.q", &core.UnusedValue{Value: "x2"}}, {"VariableAlreadyExists.q", &core.VariableAlreadyExists{Name: "x"}}, {"VariableAlreadyExists2.q", &core.VariableAlreadyExists{Name: "x"}}, } diff --git a/src/core/testdata/UnusedValue6.q b/src/core/testdata/UnusedValue6.q new file mode 100644 index 0000000..4f8e9b1 --- /dev/null +++ b/src/core/testdata/UnusedValue6.q @@ -0,0 +1,13 @@ +main() { + x := 0 + y := 0 + + loop { + if true { + return + } + + x2 := x + y2 := y + } +} \ No newline at end of file diff --git a/src/ssa/Copy.go b/src/ssa/Copy.go index 0613e13..59f2c07 100644 --- a/src/ssa/Copy.go +++ b/src/ssa/Copy.go @@ -31,7 +31,7 @@ func (c *Copy) Inputs() []Value { // IsConst returns false because a copy is a new value. func (c *Copy) IsConst() bool { - return false + return true } // Replace replaces the value to be copied if it matches. diff --git a/src/verbose/SSA.go b/src/verbose/SSA.go index ebd2722..c784764 100644 --- a/src/verbose/SSA.go +++ b/src/verbose/SSA.go @@ -23,14 +23,15 @@ func SSA(root *core.Function) { return } - pointerToIndex := make(map[string]int, len(f.Steps)) + tmpColor := ansi.Green + tmpPrefix := "α" + pointerToName := make(map[string]string, len(f.Steps)) + pointerToName[fmt.Sprintf("%p", ssa.Undefined)] = "?" for _, step := range f.Steps { - pointerToIndex[fmt.Sprintf("%p", step.Value)] = step.Index + pointerToName[fmt.Sprintf("%p", step.Value)] = fmt.Sprintf("%s%d", tmpPrefix, step.Index) } - tmpColor := ansi.Green - tmpPrefix := "α" ansi.Yellow.Println(f.FullName + ":") for _, step := range f.Steps { @@ -73,9 +74,9 @@ func SSA(root *core.Function) { end = len(value) - pos - 2 } - index := pointerToIndex[value[pos:pos+2+end]] + name := pointerToName[value[pos:pos+2+end]] fmt.Print(value[:pos]) - tmpColor.Printf("%s%d", tmpPrefix, index) + tmpColor.Printf("%s", name) value = value[pos+2+end:] pos = strings.Index(value, "0x") } -- 2.51.2