Reduced usage of temporary registers

This commit is contained in:
Eduard Urbach 2024-07-10 10:48:15 +02:00
parent 4386392844
commit d3436b13a5
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
6 changed files with 13 additions and 25 deletions

View File

@ -1,8 +1,6 @@
package core
import (
"fmt"
"git.akyoto.dev/cli/q/src/build/ast"
"git.akyoto.dev/cli/q/src/build/config"
"git.akyoto.dev/cli/q/src/build/errors"
@ -43,7 +41,7 @@ func (f *Function) CompileDefinition(node *ast.Define) error {
func (f *Function) AddVariable(variable *Variable) {
if config.Comments {
f.Comment(fmt.Sprintf("%s = %s (%s, %d uses)", variable.Name, variable.Value, variable.Register, variable.Alive))
f.Comment("%s = %s (%s, %d uses)", variable.Name, variable.Value, variable.Register, variable.Alive)
}
f.variables[variable.Name] = variable
@ -60,7 +58,7 @@ func (f *Function) useVariable(variable *Variable) {
if variable.Alive == 0 {
if config.Comments {
f.Comment(fmt.Sprintf("%s died (%s)", variable.Name, variable.Register))
f.Comment("%s died (%s)", variable.Name, variable.Register)
}
f.cpu.Free(variable.Register)

View File

@ -3,6 +3,7 @@ package core
import (
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/ast"
"git.akyoto.dev/cli/q/src/build/config"
"git.akyoto.dev/cli/q/src/build/cpu"
"git.akyoto.dev/cli/q/src/build/errors"
"git.akyoto.dev/cli/q/src/build/expression"
@ -34,6 +35,10 @@ func (f *Function) ExpressionToRegister(node *expression.Expression, register cp
if f.UsesRegister(right, register) {
register = f.cpu.MustFindFree(f.cpu.General)
if config.Comments {
f.Comment("temporary register %s", register)
}
}
f.cpu.Reserve(register)

View File

@ -1,8 +1,6 @@
package core
import (
"fmt"
"git.akyoto.dev/cli/q/src/build/arch/x64"
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/ast"
@ -102,11 +100,6 @@ func (f *Function) CompileASTNode(node ast.Node) error {
}
}
// Logf formats a message for verbose output.
func (f *Function) Logf(format string, data ...any) {
fmt.Printf("[%s @ %d] %s\n", f, len(f.assembler.Instructions), fmt.Sprintf(format, data...))
}
// String returns the function name.
func (f *Function) String() string {
return f.Name

View File

@ -1,6 +1,8 @@
package core
import (
"fmt"
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/config"
"git.akyoto.dev/cli/q/src/build/cpu"
@ -17,8 +19,8 @@ func (f *Function) Call(label string) {
f.postInstruction()
}
func (f *Function) Comment(comment string) {
f.assembler.Comment(comment)
func (f *Function) Comment(format string, args ...any) {
f.assembler.Comment(fmt.Sprintf(format, args...))
f.postInstruction()
}

View File

@ -1,8 +1,6 @@
package core
import (
"fmt"
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/config"
"git.akyoto.dev/cli/q/src/build/cpu"
@ -37,10 +35,9 @@ func (f *Function) SaveRegister(register cpu.Register) {
f.cpu.Reserve(newRegister)
if config.Comments {
f.Comment(fmt.Sprintf("save %s to %s", register, newRegister))
f.Comment("save %s to %s", register, newRegister)
}
f.RegisterRegister(asm.MOVE, newRegister, register)
f.cpu.Free(register)
variable.Register = newRegister
}

View File

@ -4,19 +4,12 @@ import (
"git.akyoto.dev/cli/q/src/build/ast"
"git.akyoto.dev/cli/q/src/build/cpu"
"git.akyoto.dev/cli/q/src/build/expression"
"git.akyoto.dev/cli/q/src/build/token"
)
// UsesRegister returns true if evaluating the expression would write or read the given register.
func (f *Function) UsesRegister(expr *expression.Expression, register cpu.Register) bool {
if expr.IsLeaf() {
if expr.Token.Kind == token.Number {
return false
}
name := expr.Token.Text()
variable := f.variables[name]
return register == variable.Register
return false
}
if ast.IsFunctionCall(expr) {