Fixed input parameter interference
All checks were successful
/ test (push) Successful in 20s

This commit is contained in:
Eduard Urbach 2025-07-04 23:46:06 +02:00
parent 0ece1b092e
commit 59363e2ed3
Signed by: akyoto
GPG key ID: 49226B848C78F6C8
7 changed files with 75 additions and 38 deletions

View file

@ -12,13 +12,10 @@ func showSSA(root *core.Function) {
root.EachDependency(make(map[*core.Function]bool), func(f *core.Function) {
ansi.Yellow.Println(f.UniqueName + ":")
for _, block := range f.Blocks {
for i, instr := range block.Instructions {
ansi.Dim.Printf("%%%-1d = ", i)
fmt.Printf("%-30s ", instr.String())
ansi.Dim.Printf(" %-30s", instr.Type().Name())
fmt.Println()
}
for i, step := range f.Steps {
ansi.Dim.Printf("%%%d = ", i)
fmt.Print(step.Value.String())
ansi.Dim.Printf(" %s %s %s\n", step.Value.Type().Name(), step.Register, step.Live)
}
fmt.Println()

View file

@ -1,6 +1,11 @@
package core
import "git.urbach.dev/cli/q/src/types"
import (
"fmt"
"git.urbach.dev/cli/q/src/ssa"
"git.urbach.dev/cli/q/src/types"
)
// Compile turns a function into machine code.
func (f *Function) Compile() {
@ -11,14 +16,29 @@ func (f *Function) Compile() {
continue
}
input.Index = uint8(offset + i)
f.Append(input)
f.Identifiers[input.Name] = input
structure, isStruct := input.Typ.(*types.Struct)
structType, isStructType := input.Typ.(*types.Struct)
if isStruct {
offset += len(structure.Fields) - 1
if isStructType {
for _, field := range structType.Fields {
param := &ssa.Parameter{
Index: uint8(offset + i),
Name: fmt.Sprintf("%s.%s", input.Name, field.Name),
Typ: field.Type,
Source: input.Source,
}
f.Identifiers[param.Name] = param
f.Append(param)
offset++
}
offset--
continue
}
input.Index = uint8(offset + i)
f.Identifiers[input.Name] = input
f.Append(input)
}
for instr := range f.Body.Instructions {

View file

@ -169,27 +169,33 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) {
right := expr.Children[1]
leftText := left.String(f.File.Bytes)
rightText := right.String(f.File.Bytes)
identifier, exists := f.Identifiers[leftText]
fullName := fmt.Sprintf("%s.%s", leftText, rightText)
identifier, exists := f.Identifiers[fullName]
if exists {
structure := identifier.Type().(*types.Struct)
field := structure.FieldByName(rightText)
if field == nil {
return nil, errors.New(&UnknownStructField{StructName: structure.Name(), FieldName: rightText}, f.File, right.Token.Position)
return identifier, nil
}
v := f.Append(&ssa.Field{
Object: identifier,
Field: field,
Source: ssa.Source(expr.Source),
})
// identifier, exists := f.Identifiers[leftText]
return v, nil
}
// if exists {
// structType := identifier.Type().(*types.Struct)
// field := structType.FieldByName(rightText)
label := fmt.Sprintf("%s.%s", leftText, rightText)
function, exists := f.All.Functions[label]
// if field == nil {
// return nil, errors.New(&UnknownStructField{StructName: structType.Name(), FieldName: rightText}, f.File, right.Token.Position)
// }
// v := f.Append(&ssa.Field{
// Object: identifier,
// Field: field,
// Source: ssa.Source(expr.Source),
// })
// return v, nil
// }
function, exists := f.All.Functions[fullName]
if exists {
if function.IsExtern() {
@ -208,7 +214,7 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) {
return v, nil
}
return nil, errors.New(&UnknownIdentifier{Name: label}, f.File, left.Token.Position)
return nil, errors.New(&UnknownIdentifier{Name: fullName}, f.File, left.Token.Position)
default:
if expr.Token.IsOperator() {

View file

@ -9,6 +9,7 @@ import (
type Compiler struct {
UniqueName string
Assembler asm.Assembler
Steps []Step
ValueToStep map[ssa.Value]*Step
CPU *cpu.CPU
Count Count

View file

@ -65,6 +65,12 @@ func (f *Compiler) CreateSteps(ir ssa.IR) []Step {
}
liveStart := i
_, isParam := instr.(*ssa.Parameter)
if isParam {
liveStart = 0
}
liveEnd := f.ValueToStep[users[len(users)-1]].Index
instrStep := f.ValueToStep[instr]
@ -79,12 +85,19 @@ func (f *Compiler) CreateSteps(ir ssa.IR) []Step {
continue
}
oldRegister := cpu.Register(-1)
liveParam, isParam := live.Value.(*ssa.Parameter)
if isParam {
oldRegister = f.CPU.Call[liveParam.Index]
}
for _, existing := range step.Live[:liveIndex] {
if existing.Register == -1 {
continue
}
if existing.Register == live.Register {
if existing.Register == live.Register || existing.Register == oldRegister {
a := existing.Index
b := live.Index
freeRegister := cpu.Register(15)

View file

@ -114,9 +114,9 @@ func (f *Compiler) Exec(step *Step) {
})
case *ssa.Field:
parameter := instr.Object.(*ssa.Parameter)
field := instr.Field
source := f.CPU.Call[parameter.Index+field.Index]
structure := instr.Object.(*ssa.Struct)
field := structure.Arguments[instr.Field.Index]
source := f.ValueToStep[field].Register
if step.Register == -1 || step.Register == source {
return

View file

@ -13,9 +13,9 @@ func (f *Compiler) GenerateAssembly(ir ssa.IR, isLeaf bool) {
f.Assembler.Append(&asm.FunctionStart{})
}
steps := f.CreateSteps(ir)
f.Steps = f.CreateSteps(ir)
for _, step := range steps {
for _, step := range f.Steps {
f.Exec(&step)
}