This commit is contained in:
parent
0ece1b092e
commit
59363e2ed3
7 changed files with 75 additions and 38 deletions
|
@ -12,13 +12,10 @@ func showSSA(root *core.Function) {
|
||||||
root.EachDependency(make(map[*core.Function]bool), func(f *core.Function) {
|
root.EachDependency(make(map[*core.Function]bool), func(f *core.Function) {
|
||||||
ansi.Yellow.Println(f.UniqueName + ":")
|
ansi.Yellow.Println(f.UniqueName + ":")
|
||||||
|
|
||||||
for _, block := range f.Blocks {
|
for i, step := range f.Steps {
|
||||||
for i, instr := range block.Instructions {
|
ansi.Dim.Printf("%%%d = ", i)
|
||||||
ansi.Dim.Printf("%%%-1d = ", i)
|
fmt.Print(step.Value.String())
|
||||||
fmt.Printf("%-30s ", instr.String())
|
ansi.Dim.Printf(" %s %s %s\n", step.Value.Type().Name(), step.Register, step.Live)
|
||||||
ansi.Dim.Printf(" %-30s", instr.Type().Name())
|
|
||||||
fmt.Println()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
package core
|
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.
|
// Compile turns a function into machine code.
|
||||||
func (f *Function) Compile() {
|
func (f *Function) Compile() {
|
||||||
|
@ -11,14 +16,29 @@ func (f *Function) Compile() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
input.Index = uint8(offset + i)
|
structType, isStructType := input.Typ.(*types.Struct)
|
||||||
f.Append(input)
|
|
||||||
f.Identifiers[input.Name] = input
|
|
||||||
structure, isStruct := input.Typ.(*types.Struct)
|
|
||||||
|
|
||||||
if isStruct {
|
if isStructType {
|
||||||
offset += len(structure.Fields) - 1
|
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 {
|
for instr := range f.Body.Instructions {
|
||||||
|
|
|
@ -169,27 +169,33 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) {
|
||||||
right := expr.Children[1]
|
right := expr.Children[1]
|
||||||
leftText := left.String(f.File.Bytes)
|
leftText := left.String(f.File.Bytes)
|
||||||
rightText := right.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 {
|
if exists {
|
||||||
structure := identifier.Type().(*types.Struct)
|
return identifier, nil
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
label := fmt.Sprintf("%s.%s", leftText, rightText)
|
// identifier, exists := f.Identifiers[leftText]
|
||||||
function, exists := f.All.Functions[label]
|
|
||||||
|
// 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 exists {
|
||||||
if function.IsExtern() {
|
if function.IsExtern() {
|
||||||
|
@ -208,7 +214,7 @@ func (f *Function) Evaluate(expr *expression.Expression) (ssa.Value, error) {
|
||||||
return v, nil
|
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:
|
default:
|
||||||
if expr.Token.IsOperator() {
|
if expr.Token.IsOperator() {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
type Compiler struct {
|
type Compiler struct {
|
||||||
UniqueName string
|
UniqueName string
|
||||||
Assembler asm.Assembler
|
Assembler asm.Assembler
|
||||||
|
Steps []Step
|
||||||
ValueToStep map[ssa.Value]*Step
|
ValueToStep map[ssa.Value]*Step
|
||||||
CPU *cpu.CPU
|
CPU *cpu.CPU
|
||||||
Count Count
|
Count Count
|
||||||
|
|
|
@ -65,6 +65,12 @@ func (f *Compiler) CreateSteps(ir ssa.IR) []Step {
|
||||||
}
|
}
|
||||||
|
|
||||||
liveStart := i
|
liveStart := i
|
||||||
|
_, isParam := instr.(*ssa.Parameter)
|
||||||
|
|
||||||
|
if isParam {
|
||||||
|
liveStart = 0
|
||||||
|
}
|
||||||
|
|
||||||
liveEnd := f.ValueToStep[users[len(users)-1]].Index
|
liveEnd := f.ValueToStep[users[len(users)-1]].Index
|
||||||
instrStep := f.ValueToStep[instr]
|
instrStep := f.ValueToStep[instr]
|
||||||
|
|
||||||
|
@ -79,12 +85,19 @@ func (f *Compiler) CreateSteps(ir ssa.IR) []Step {
|
||||||
continue
|
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] {
|
for _, existing := range step.Live[:liveIndex] {
|
||||||
if existing.Register == -1 {
|
if existing.Register == -1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if existing.Register == live.Register {
|
if existing.Register == live.Register || existing.Register == oldRegister {
|
||||||
a := existing.Index
|
a := existing.Index
|
||||||
b := live.Index
|
b := live.Index
|
||||||
freeRegister := cpu.Register(15)
|
freeRegister := cpu.Register(15)
|
||||||
|
|
|
@ -114,9 +114,9 @@ func (f *Compiler) Exec(step *Step) {
|
||||||
})
|
})
|
||||||
|
|
||||||
case *ssa.Field:
|
case *ssa.Field:
|
||||||
parameter := instr.Object.(*ssa.Parameter)
|
structure := instr.Object.(*ssa.Struct)
|
||||||
field := instr.Field
|
field := structure.Arguments[instr.Field.Index]
|
||||||
source := f.CPU.Call[parameter.Index+field.Index]
|
source := f.ValueToStep[field].Register
|
||||||
|
|
||||||
if step.Register == -1 || step.Register == source {
|
if step.Register == -1 || step.Register == source {
|
||||||
return
|
return
|
||||||
|
|
|
@ -13,9 +13,9 @@ func (f *Compiler) GenerateAssembly(ir ssa.IR, isLeaf bool) {
|
||||||
f.Assembler.Append(&asm.FunctionStart{})
|
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)
|
f.Exec(&step)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue