From 9e3240218f4ff59258eeb24649108f5d93a2b427 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Sat, 2 Aug 2025 17:35:38 +0200 Subject: [PATCH] Improved phi construction in branches --- src/core/compileIf.go | 10 +++++----- src/core/compileSwitch.go | 9 +++------ src/ssa/Block.go | 5 +++++ src/ssa/Branch.go | 2 +- tests/phi-advanced.q | 19 +++++++++++++++++++ tests/{else.q => phi-simple.q} | 4 ++-- tests/phi.q | 8 ++++---- tests/tests_test.go | 5 +++-- 8 files changed, 42 insertions(+), 20 deletions(-) create mode 100644 tests/phi-advanced.q rename tests/{else.q => phi-simple.q} (72%) diff --git a/src/core/compileIf.go b/src/core/compileIf.go index 000f9a6..7409c59 100644 --- a/src/core/compileIf.go +++ b/src/core/compileIf.go @@ -14,9 +14,9 @@ func (f *Function) compileIf(branch *ast.If) error { endBlock := ssa.NewBlock(endLabel) beforeIf := f.Block() beforeIf.AddSuccessor(thenBlock) - thenBlock.AddSuccessor(endBlock) if branch.Else == nil { + beforeIf.AddSuccessor(endBlock) err := f.compileCondition(branch.Condition, thenBlock, endBlock) if err != nil { @@ -31,20 +31,18 @@ func (f *Function) compileIf(branch *ast.If) error { return err } + f.Block().AddSuccessor(endBlock) f.Append(&ssa.Jump{To: endBlock}) - beforeIf.AddSuccessor(endBlock) } else { elseLabel := f.CreateLabel("if.else", f.Count.Branch) elseBlock := ssa.NewBlock(elseLabel) + beforeIf.AddSuccessor(elseBlock) err := f.compileCondition(branch.Condition, thenBlock, elseBlock) if err != nil { return err } - beforeIf.AddSuccessor(elseBlock) - elseBlock.AddSuccessor(endBlock) - // Append the if.then block f.AddBlock(thenBlock) err = f.compileAST(branch.Body) @@ -53,6 +51,7 @@ func (f *Function) compileIf(branch *ast.If) error { return err } + f.Block().AddSuccessor(endBlock) f.Append(&ssa.Jump{To: endBlock}) // Append the if.else block @@ -63,6 +62,7 @@ func (f *Function) compileIf(branch *ast.If) error { return err } + f.Block().AddSuccessor(endBlock) f.Append(&ssa.Jump{To: endBlock}) } diff --git a/src/core/compileSwitch.go b/src/core/compileSwitch.go index 9f120c4..96e1830 100644 --- a/src/core/compileSwitch.go +++ b/src/core/compileSwitch.go @@ -19,8 +19,7 @@ func (f *Function) compileSwitch(s *ast.Switch) error { return err } - defaultBlock := f.Block() - defaultBlock.AddSuccessor(exitBlock) + f.Block().AddSuccessor(exitBlock) f.Append(&ssa.Jump{To: exitBlock}) f.AddBlock(exitBlock) break @@ -41,7 +40,6 @@ func (f *Function) compileSwitch(s *ast.Switch) error { caseBlock := f.Block() caseBlock.AddSuccessor(thenBlock) caseBlock.AddSuccessor(elseBlock) - err := f.compileCondition(branch.Condition, thenBlock, elseBlock) if err != nil { @@ -55,9 +53,8 @@ func (f *Function) compileSwitch(s *ast.Switch) error { return err } - thenBlock.Append(&ssa.Jump{To: exitBlock}) - thenBlock.AddSuccessor(exitBlock) - + f.Block().Append(&ssa.Jump{To: exitBlock}) + f.Block().AddSuccessor(exitBlock) f.AddBlock(elseBlock) } diff --git a/src/ssa/Block.go b/src/ssa/Block.go index 473c579..58da555 100644 --- a/src/ssa/Block.go +++ b/src/ssa/Block.go @@ -180,4 +180,9 @@ func (block *Block) ReplaceAll(old Value, new Value) { for _, instr := range block.Instructions { instr.Replace(old, new) } +} + +// String returns the block label. +func (block *Block) String() string { + return block.Label } \ No newline at end of file diff --git a/src/ssa/Branch.go b/src/ssa/Branch.go index 1949106..4213410 100644 --- a/src/ssa/Branch.go +++ b/src/ssa/Branch.go @@ -32,5 +32,5 @@ func (v *Branch) Replace(old Value, new Value) { } func (v *Branch) String() string { - return fmt.Sprintf("branch(%s, %s, %s)", v.Condition.String(), v.Then.Label, v.Else.Label) + return fmt.Sprintf("branch(%p, %s, %s)", v.Condition, v.Then.Label, v.Else.Label) } \ No newline at end of file diff --git a/tests/phi-advanced.q b/tests/phi-advanced.q new file mode 100644 index 0000000..e434cbe --- /dev/null +++ b/tests/phi-advanced.q @@ -0,0 +1,19 @@ +main() { + x := 0 + + if x == 1 { + if x == 0 { + x = 2 + } else { + x = 3 + } + } else { + if x == 0 { + x = 4 + } else { + x = 5 + } + } + + assert x == 4 +} \ No newline at end of file diff --git a/tests/else.q b/tests/phi-simple.q similarity index 72% rename from tests/else.q rename to tests/phi-simple.q index a51edba..829fed8 100644 --- a/tests/else.q +++ b/tests/phi-simple.q @@ -1,7 +1,7 @@ main() { - x := 1 + x := 0 - if x == 0 { + if x == 1 { x = 2 } else { x = 3 diff --git a/tests/phi.q b/tests/phi.q index 1e5eaf6..029b339 100644 --- a/tests/phi.q +++ b/tests/phi.q @@ -1,9 +1,9 @@ main() { - x := 1 + x := 0 - if x == 1 { - x = 0 + if x == 0 { + x = 1 } - assert x == 0 + assert x == 1 } \ No newline at end of file diff --git a/tests/tests_test.go b/tests/tests_test.go index bf36b3f..41fab35 100644 --- a/tests/tests_test.go +++ b/tests/tests_test.go @@ -37,9 +37,10 @@ var tests = []run{ {"branch-or", "", "", 0}, {"branch-both", "", "", 0}, {"jump-near", "", "", 0}, - {"phi", "", "", 0}, - {"else", "", "", 0}, {"switch", "", "", 0}, + {"phi", "", "", 0}, + {"phi-simple", "", "", 0}, + {"phi-advanced", "", "", 0}, {"loop", "", "..........", 0}, {"loop-lifetime", "", "", 0}, {"for", "", "", 0}, -- 2.51.2