From 77f467cd982edceff865feee017b8074db387f42 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Sun, 27 Sep 2026 11:28:28 +0200 Subject: [PATCH] Implemented copy removal --- src/config/Build.go | 1 + src/config/Optimize.go | 1 + src/core/errors_test.go | 2 +- src/core/optimize.go | 5 +++++ src/optimizer/RemoveCopies.go | 36 +++++++++++++++++++++++++++++++++++ src/ssa/IR.go | 4 ++++ 6 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/optimizer/RemoveCopies.go diff --git a/src/config/Build.go b/src/config/Build.go index 52d1c34..3c06763 100644 --- a/src/config/Build.go +++ b/src/config/Build.go @@ -7,6 +7,7 @@ type Build struct { OS OS Dry bool Fold bool + RemoveCopies bool Reorder bool LintAssertionDensity bool LintBinaryOps bool diff --git a/src/config/Optimize.go b/src/config/Optimize.go index 690a563..f0a2aab 100644 --- a/src/config/Optimize.go +++ b/src/config/Optimize.go @@ -3,5 +3,6 @@ package config // Optimize enables or disables the optimizer. func (build *Build) Optimize(enabled bool) { build.Fold = enabled + build.RemoveCopies = enabled build.Reorder = enabled } \ No newline at end of file diff --git a/src/core/errors_test.go b/src/core/errors_test.go index 329c8e8..f3db859 100644 --- a/src/core/errors_test.go +++ b/src/core/errors_test.go @@ -117,7 +117,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: "x"}}, + {"UnusedValue6.q", &core.UnusedValue{Value: "0"}}, {"UnusedValue7.q", &core.UnusedValue{Value: "1"}}, {"UnusedValue8.q", &core.UnusedValue{Value: "1 + 1"}}, {"VariableAlreadyExists.q", &core.VariableAlreadyExists{Name: "x"}}, diff --git a/src/core/optimize.go b/src/core/optimize.go index c560396..a8dc2af 100644 --- a/src/core/optimize.go +++ b/src/core/optimize.go @@ -45,6 +45,11 @@ func (f *Function) optimize() error { folded = optimizer.Fold(f.IR) } + // Replace copies with their actual values. + if f.Env.Build.RemoveCopies { + optimizer.RemoveCopies(&f.IR) + } + // After cleaning up some of the instructions we can proceed // to calculate the list of users. f.ComputeUsers() diff --git a/src/optimizer/RemoveCopies.go b/src/optimizer/RemoveCopies.go new file mode 100644 index 0000000..7b7fd30 --- /dev/null +++ b/src/optimizer/RemoveCopies.go @@ -0,0 +1,36 @@ +package optimizer + +import ( + "git.urbach.dev/cli/q/src/ssa" + "git.urbach.dev/cli/q/src/types" +) + +// RemoveCopies replaces copies with their actual values. +func RemoveCopies(ir *ssa.IR) { + for _, block := range ir.Blocks { + for i, value := range block.Instructions { + copy, isCopy := value.(*ssa.Copy) + + if !isCopy { + continue + } + + typ := copy.Value.Type() + + if copy.Typ != typ { + continue + } + + _, isResource := typ.(*types.Resource) + + if isResource { + continue + } + + ir.ReplaceAll(copy, copy.Value) + block.RemoveAt(i) + } + + block.RemoveNilValues() + } +} \ No newline at end of file diff --git a/src/ssa/IR.go b/src/ssa/IR.go index f8a6188..fc470d9 100644 --- a/src/ssa/IR.go +++ b/src/ssa/IR.go @@ -79,6 +79,10 @@ func (ir *IR) IsIdentified(value Value) bool { func (ir *IR) ReplaceAll(old Value, new Value) { for _, block := range ir.Blocks { for _, value := range block.Instructions { + if value == nil { + continue + } + value.Replace(old, new) } } -- 2.51.2