This commit is contained in:
parent
ec300c9a70
commit
89f375f4fc
8 changed files with 234 additions and 0 deletions
|
@ -4,11 +4,13 @@ import (
|
|||
"fmt"
|
||||
|
||||
"git.urbach.dev/cli/q/src/fs"
|
||||
"git.urbach.dev/cli/q/src/ssa"
|
||||
"git.urbach.dev/cli/q/src/token"
|
||||
)
|
||||
|
||||
// Function is the smallest unit of code.
|
||||
type Function struct {
|
||||
ssa.Function
|
||||
Name string
|
||||
UniqueName string
|
||||
File *fs.File
|
||||
|
|
11
src/ssa/Block.go
Normal file
11
src/ssa/Block.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package ssa
|
||||
|
||||
type Block struct {
|
||||
Entry []*Block
|
||||
Instructions []Instruction
|
||||
Exit []*Block
|
||||
}
|
||||
|
||||
func (b *Block) Append(instr Instruction) {
|
||||
b.Instructions = append(b.Instructions, instr)
|
||||
}
|
5
src/ssa/Function.go
Normal file
5
src/ssa/Function.go
Normal file
|
@ -0,0 +1,5 @@
|
|||
package ssa
|
||||
|
||||
type Function struct {
|
||||
Blocks []*Block
|
||||
}
|
3
src/ssa/Index.go
Normal file
3
src/ssa/Index.go
Normal file
|
@ -0,0 +1,3 @@
|
|||
package ssa
|
||||
|
||||
type Index = uint16
|
11
src/ssa/Instruction.go
Normal file
11
src/ssa/Instruction.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package ssa
|
||||
|
||||
// Instruction is a "fat struct" for performance reasons.
|
||||
// It contains all the fields necessary to represent all instruction types.
|
||||
type Instruction struct {
|
||||
Type Type
|
||||
Parameters []Index
|
||||
Int int64
|
||||
Float float64
|
||||
String string
|
||||
}
|
30
src/ssa/Type.go
Normal file
30
src/ssa/Type.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package ssa
|
||||
|
||||
type Type byte
|
||||
|
||||
const (
|
||||
None Type = iota
|
||||
|
||||
// Values
|
||||
Int
|
||||
Float
|
||||
String
|
||||
|
||||
// Binary
|
||||
Add
|
||||
Sub
|
||||
Mul
|
||||
Div
|
||||
Mod
|
||||
|
||||
// Bitwise
|
||||
And
|
||||
Or
|
||||
Xor
|
||||
Shl
|
||||
Shr
|
||||
|
||||
// Special
|
||||
Call
|
||||
Phi
|
||||
)
|
158
src/ssa/bench_test.go
Normal file
158
src/ssa/bench_test.go
Normal file
|
@ -0,0 +1,158 @@
|
|||
package ssa_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime/debug"
|
||||
"testing"
|
||||
|
||||
"git.urbach.dev/go/assert"
|
||||
)
|
||||
|
||||
const n = 100
|
||||
|
||||
type FatStruct struct {
|
||||
Type byte
|
||||
A int
|
||||
B int
|
||||
C int
|
||||
D int
|
||||
E int
|
||||
F int
|
||||
G int
|
||||
}
|
||||
|
||||
type Instruction interface{}
|
||||
|
||||
type BinaryInstruction struct {
|
||||
A int
|
||||
B int
|
||||
}
|
||||
|
||||
type OtherInstruction struct {
|
||||
C int
|
||||
D int
|
||||
E int
|
||||
F int
|
||||
G int
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
debug.SetGCPercent(-1)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func BenchmarkFatStructRaw(b *testing.B) {
|
||||
for b.Loop() {
|
||||
entries := make([]FatStruct, 0, n)
|
||||
|
||||
for i := range n {
|
||||
entries = append(entries, FatStruct{
|
||||
Type: byte(i % 2),
|
||||
A: i,
|
||||
B: i,
|
||||
})
|
||||
}
|
||||
|
||||
count := 0
|
||||
|
||||
for _, entry := range entries {
|
||||
switch entry.Type {
|
||||
case 0:
|
||||
count++
|
||||
case 1:
|
||||
}
|
||||
}
|
||||
|
||||
assert.Equal(b, count, n/2)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFatStructPtr(b *testing.B) {
|
||||
for b.Loop() {
|
||||
entries := make([]*FatStruct, 0, n)
|
||||
|
||||
for i := range n {
|
||||
entries = append(entries, &FatStruct{
|
||||
Type: byte(i % 2),
|
||||
A: i,
|
||||
B: i,
|
||||
})
|
||||
}
|
||||
|
||||
count := 0
|
||||
|
||||
for _, entry := range entries {
|
||||
switch entry.Type {
|
||||
case 0:
|
||||
count++
|
||||
case 1:
|
||||
}
|
||||
}
|
||||
|
||||
assert.Equal(b, count, n/2)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkInterfaceRaw(b *testing.B) {
|
||||
for b.Loop() {
|
||||
entries := make([]Instruction, 0, n)
|
||||
|
||||
for i := range n {
|
||||
if i%2 == 0 {
|
||||
entries = append(entries, BinaryInstruction{
|
||||
A: i,
|
||||
B: i,
|
||||
})
|
||||
} else {
|
||||
entries = append(entries, OtherInstruction{
|
||||
C: i,
|
||||
D: i,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
count := 0
|
||||
|
||||
for _, entry := range entries {
|
||||
switch entry.(type) {
|
||||
case BinaryInstruction:
|
||||
count++
|
||||
case OtherInstruction:
|
||||
}
|
||||
}
|
||||
|
||||
assert.Equal(b, count, n/2)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkInterfacePtr(b *testing.B) {
|
||||
for b.Loop() {
|
||||
entries := make([]Instruction, 0, n)
|
||||
|
||||
for i := range n {
|
||||
if i%2 == 0 {
|
||||
entries = append(entries, &BinaryInstruction{
|
||||
A: i,
|
||||
B: i,
|
||||
})
|
||||
} else {
|
||||
entries = append(entries, &OtherInstruction{
|
||||
C: i,
|
||||
D: i,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
count := 0
|
||||
|
||||
for _, entry := range entries {
|
||||
switch entry.(type) {
|
||||
case *BinaryInstruction:
|
||||
count++
|
||||
case *OtherInstruction:
|
||||
}
|
||||
}
|
||||
|
||||
assert.Equal(b, count, n/2)
|
||||
}
|
||||
}
|
14
src/ssa/ssa_test.go
Normal file
14
src/ssa/ssa_test.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
package ssa_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.urbach.dev/cli/q/src/ssa"
|
||||
)
|
||||
|
||||
func TestBlock(t *testing.T) {
|
||||
block := &ssa.Block{}
|
||||
block.Append(ssa.Instruction{Type: ssa.Int, Int: 1})
|
||||
block.Append(ssa.Instruction{Type: ssa.Int, Int: 2})
|
||||
block.Append(ssa.Instruction{Type: ssa.Add, Parameters: []ssa.Index{0, 1}})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue