From 65a7a1e426ec502df5079c0fb8d7fcd3f4f7fdf4 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Thu, 27 Aug 2026 19:55:58 +0200 Subject: [PATCH] Removed unused loads during dead code removal --- src/ssa/Block.go | 7 ++++--- src/ssa/Load.go | 7 ++++--- tests/dead-value-load.q | 21 +++++++++++++++++++++ tests/{switch-dead-value.q => dead-value.q} | 0 tests/tests_test.go | 3 ++- 5 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 tests/dead-value-load.q rename tests/{switch-dead-value.q => dead-value.q} (100%) diff --git a/src/ssa/Block.go b/src/ssa/Block.go index f0e03d8..e2f1dac 100644 --- a/src/ssa/Block.go +++ b/src/ssa/Block.go @@ -60,10 +60,11 @@ func (b *Block) FindExisting(instr Value) Value { return existing } - // If we encounter a call, we can't be sure that the value is still the same. - // TODO: This is a bit too conservative. We could check if the call affects the value. + // If we encounter an instruction with side effects, + // we can't be sure that the value is still the same. + // TODO: This is a bit too conservative. We could check if the instruction affects the value. switch existing.(type) { - case *Call, *CallExtern: + case *Call, *CallExtern, *CallPointer, *Store, *Syscall, *Cas: return nil } } diff --git a/src/ssa/Load.go b/src/ssa/Load.go index 240ba69..62f77e5 100644 --- a/src/ssa/Load.go +++ b/src/ssa/Load.go @@ -24,10 +24,11 @@ func (a *Load) Equals(v Value) bool { return a.Memory == b.Memory } -// IsPure returns false because loads read from memory -// and two equal loads may yield different values. +// IsPure returns true because loads have no side effects. +// Dead loads can be removed and two equal loads only deduplicate if +// nothing between them modifies the memory. func (l *Load) IsPure() bool { - return false + return true } // Inputs returns the memory address of the load. diff --git a/tests/dead-value-load.q b/tests/dead-value-load.q new file mode 100644 index 0000000..e8eff98 --- /dev/null +++ b/tests/dead-value-load.q @@ -0,0 +1,21 @@ +main() { + v := 4 + a := new(int, 4) + a[0] = -39 + a[1] = 28 + a[2] = 22 + a[3] = -31 + sum := 0 + sum += a[0] + sum += a[1] + sum += a[2] + sum += a[3] + sel := 0 + + switch { + v > 2 { sel = 7 } + _ { sel = -3 } + } + + assert sel == 7 +} \ No newline at end of file diff --git a/tests/switch-dead-value.q b/tests/dead-value.q similarity index 100% rename from tests/switch-dead-value.q rename to tests/dead-value.q diff --git a/tests/tests_test.go b/tests/tests_test.go index 1714954..b17b38c 100644 --- a/tests/tests_test.go +++ b/tests/tests_test.go @@ -50,7 +50,6 @@ var tests = []run{ {"jump-near", nil, "", "", 0}, {"switch", nil, "", "", 0}, {"switch-expression", nil, "", "", 0}, - {"switch-dead-value", nil, "", "", 0}, {"phi", nil, "", "", 0}, {"phi-simple", nil, "", "", 0}, {"phi-advanced", nil, "", "", 0}, @@ -193,6 +192,8 @@ var tests = []run{ {"zero-alloc", nil, "", "", 0}, {"spill-call", nil, "", "", 0}, {"spill-call-binary", nil, "", "", 0}, + {"dead-value", nil, "", "", 0}, + {"dead-value-load", nil, "", "", 0}, } func TestTests(t *testing.T) { -- 2.51.2