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 package core
import ( import (
"fmt"
"git.akyoto.dev/cli/q/src/build/ast" "git.akyoto.dev/cli/q/src/build/ast"
"git.akyoto.dev/cli/q/src/build/config" "git.akyoto.dev/cli/q/src/build/config"
"git.akyoto.dev/cli/q/src/build/errors" "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) { func (f *Function) AddVariable(variable *Variable) {
if config.Comments { 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 f.variables[variable.Name] = variable
@ -60,7 +58,7 @@ func (f *Function) useVariable(variable *Variable) {
if variable.Alive == 0 { if variable.Alive == 0 {
if config.Comments { 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) f.cpu.Free(variable.Register)

View File

@ -3,6 +3,7 @@ package core
import ( import (
"git.akyoto.dev/cli/q/src/build/asm" "git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/ast" "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/cpu"
"git.akyoto.dev/cli/q/src/build/errors" "git.akyoto.dev/cli/q/src/build/errors"
"git.akyoto.dev/cli/q/src/build/expression" "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) { if f.UsesRegister(right, register) {
register = f.cpu.MustFindFree(f.cpu.General) register = f.cpu.MustFindFree(f.cpu.General)
if config.Comments {
f.Comment("temporary register %s", register)
}
} }
f.cpu.Reserve(register) f.cpu.Reserve(register)

View File

@ -1,8 +1,6 @@
package core package core
import ( import (
"fmt"
"git.akyoto.dev/cli/q/src/build/arch/x64" "git.akyoto.dev/cli/q/src/build/arch/x64"
"git.akyoto.dev/cli/q/src/build/asm" "git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/ast" "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. // String returns the function name.
func (f *Function) String() string { func (f *Function) String() string {
return f.Name return f.Name

View File

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

View File

@ -1,8 +1,6 @@
package core package core
import ( import (
"fmt"
"git.akyoto.dev/cli/q/src/build/asm" "git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/config" "git.akyoto.dev/cli/q/src/build/config"
"git.akyoto.dev/cli/q/src/build/cpu" "git.akyoto.dev/cli/q/src/build/cpu"
@ -37,10 +35,9 @@ func (f *Function) SaveRegister(register cpu.Register) {
f.cpu.Reserve(newRegister) f.cpu.Reserve(newRegister)
if config.Comments { 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.RegisterRegister(asm.MOVE, newRegister, register)
f.cpu.Free(register)
variable.Register = newRegister variable.Register = newRegister
} }

View File

@ -4,21 +4,14 @@ import (
"git.akyoto.dev/cli/q/src/build/ast" "git.akyoto.dev/cli/q/src/build/ast"
"git.akyoto.dev/cli/q/src/build/cpu" "git.akyoto.dev/cli/q/src/build/cpu"
"git.akyoto.dev/cli/q/src/build/expression" "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. // 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 { func (f *Function) UsesRegister(expr *expression.Expression, register cpu.Register) bool {
if expr.IsLeaf() { if expr.IsLeaf() {
if expr.Token.Kind == token.Number {
return false return false
} }
name := expr.Token.Text()
variable := f.variables[name]
return register == variable.Register
}
if ast.IsFunctionCall(expr) { if ast.IsFunctionCall(expr) {
if register == f.cpu.Output[0] { if register == f.cpu.Output[0] {
return true return true