Reduced usage of temporary registers
This commit is contained in:
parent
4386392844
commit
d3436b13a5
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user