From 59363e2ed34de96e704e820c0fb5e4d122412d6e Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Fri, 4 Jul 2025 23:46:06 +0200 Subject: [PATCH] Fixed input parameter interference --- src/compiler/showSSA.go | 11 ++++----- src/core/Compile.go | 34 ++++++++++++++++++++------ src/core/Evaluate.go | 42 +++++++++++++++++++-------------- src/ssa2asm/Compiler.go | 1 + src/ssa2asm/CreateSteps.go | 15 +++++++++++- src/ssa2asm/Exec.go | 6 ++--- src/ssa2asm/GenerateAssembly.go | 4 ++-- 7 files changed, 75 insertions(+), 38 deletions(-) diff --git a/src/compiler/showSSA.go b/src/compiler/showSSA.go index bf78313..4c188a3 100644 --- a/src/compiler/showSSA.go +++ b/src/compiler/showSSA.go @@ -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() diff --git a/src/core/Compile.go b/src/core/Compile.go index 158979d..cf793a1 100644 --- a/src/core/Compile.go +++ b/src/core/Compile.go @@ -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 { diff --git a/src/core/Evaluate.go b/src/core/Evaluate.go index d28338c..c4273d2 100644 --- a/src/core/Evaluate.go +++ b/src/core/Evaluate.go @@ -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) - } - - v := f.Append(&ssa.Field{ - Object: identifier, - Field: field, - Source: ssa.Source(expr.Source), - }) - - return v, nil + return identifier, nil } - label := fmt.Sprintf("%s.%s", leftText, rightText) - function, exists := f.All.Functions[label] + // identifier, exists := f.Identifiers[leftText] + + // if exists { + // structType := identifier.Type().(*types.Struct) + // field := structType.FieldByName(rightText) + + // 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() { diff --git a/src/ssa2asm/Compiler.go b/src/ssa2asm/Compiler.go index 17959c9..65076a1 100644 --- a/src/ssa2asm/Compiler.go +++ b/src/ssa2asm/Compiler.go @@ -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 diff --git a/src/ssa2asm/CreateSteps.go b/src/ssa2asm/CreateSteps.go index 3a9e558..8aaaa22 100644 --- a/src/ssa2asm/CreateSteps.go +++ b/src/ssa2asm/CreateSteps.go @@ -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) diff --git a/src/ssa2asm/Exec.go b/src/ssa2asm/Exec.go index 9d109ed..66f24ab 100644 --- a/src/ssa2asm/Exec.go +++ b/src/ssa2asm/Exec.go @@ -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 diff --git a/src/ssa2asm/GenerateAssembly.go b/src/ssa2asm/GenerateAssembly.go index 671d8cf..7ed8ee4 100644 --- a/src/ssa2asm/GenerateAssembly.go +++ b/src/ssa2asm/GenerateAssembly.go @@ -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) }