Skip to content

Commit

Permalink
Merge #154
Browse files Browse the repository at this point in the history
154: compiler: zeroing of package variables r=zegl a=zegl

This updates #48

Co-authored-by: Gustav Westling <[email protected]>
  • Loading branch information
bors[bot] and zegl authored Jan 5, 2020
2 parents b731bb8 + 8e9c54c commit 1e4b1e6
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 32 deletions.
37 changes: 23 additions & 14 deletions compiler/compiler/alloc.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +25,45 @@ func (c *Compiler) compileAllocNode(v *parser.AllocNode) {
if typeNode, ok := v.Val[0].(parser.TypeNode); ok {
treType := c.parserTypeToType(typeNode)

var val llvmValue.Value
var block *ir.Block

// Package level variables
// TODO: Zeroing
if c.contextBlock == nil {
globType := treType.LLVM()
glob := c.module.NewGlobal(name.Var(v.Name[0]), globType)
glob.Init = constant.NewZeroInitializer(globType)

c.currentPackage.DefinePkgVar(v.Name[0], value.Value{
Value: glob,
Type: treType,
IsVariable: true,
})
return
}

var alloc *ir.InstAlloca
val = glob
block = c.initGlobalsFunc.Blocks[0]
} else {
alloc := c.contextBlock.NewAlloca(treType.LLVM())
alloc.SetName(name.Var(v.Name[0]))

c.setVar(v.Name[0], value.Value{
Value: alloc,
Type: treType,
IsVariable: true,
})

val = alloc
block = c.contextBlock
}

// Set to zero values
// TODO: Make slices less special
if sliceType, ok := treType.(*types.Slice); ok {
alloc = sliceType.SliceZero(c.contextBlock, c.externalFuncs.Malloc.Value.(llvmValue.Named), 2)
sliceType.SliceZero(block, c.externalFuncs.Malloc.Value.(llvmValue.Named), 2, val)
} else {
alloc = c.contextBlock.NewAlloca(treType.LLVM())
treType.Zero(c.contextBlock, alloc)
treType.Zero(block, val)
}

alloc.SetName(name.Var(v.Name[0]))

c.setVar(v.Name[0], value.Value{
Value: alloc,
Type: treType,
IsVariable: true,
})
return
}
}
Expand Down
14 changes: 14 additions & 0 deletions compiler/compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"runtime/debug"

"github.com/zegl/tre/compiler/compiler/internal"
"github.com/zegl/tre/compiler/compiler/name"
"github.com/zegl/tre/compiler/compiler/strings"
"github.com/zegl/tre/compiler/compiler/types"
"github.com/zegl/tre/compiler/compiler/value"
Expand Down Expand Up @@ -33,6 +34,9 @@ type Compiler struct {

contextFunc *types.Function

initGlobalsFunc *ir.Func
mainFunc *ir.Func

// Stack of return values pointers, is used both used if a function returns more
// than one value (arg pointers), and single stack based returns
contextFuncRetVals [][]value.Value
Expand Down Expand Up @@ -192,6 +196,16 @@ func (c *Compiler) addGlobal() {
c.packages["global"] = global

c.module.Funcs = append(c.module.Funcs, strLen)

// Initialization function
c.initGlobalsFunc = c.module.NewFunc(name.Var("global-init"), types.Void.LLVM())
b := c.initGlobalsFunc.NewBlock(name.Block())
b.NewRet(nil)

// main.main function, body will be added later
c.mainFunc = c.module.NewFunc("main", types.I32.LLVM())
mainBlock := c.mainFunc.NewBlock(name.Block())
mainBlock.NewCall(c.initGlobalsFunc)
}

func (c *Compiler) compile(instructions []parser.Node) {
Expand Down
13 changes: 8 additions & 5 deletions compiler/compiler/func.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,22 @@ func (c *Compiler) compileDefineFuncNode(v *parser.DefineFuncNode) value.Value {

funcRetType, treReturnTypes, llvmParams, treParams, isVariadicFunc, argumentReturnValuesCount := c.funcType(argTypes, retTypes)

var fn *ir.Func
var entry *ir.Block

if c.currentPackageName == "main" && v.Name == "main" {
if len(v.ReturnValues) != 0 {
panic("main func can not have a return type")
}

funcRetType = types.I32
compiledName = "main"
fn = c.mainFunc
entry = fn.Blocks[0] // use already defined block
} else {
fn = c.module.NewFunc(compiledName, funcRetType.LLVM(), llvmParams...)
entry = fn.NewBlock(name.Block())
}

fn := c.module.NewFunc(compiledName, funcRetType.LLVM(), llvmParams...)

typesFunc := &types.Function{
FuncType: fn.Type(),
LlvmReturnType: funcRetType,
Expand Down Expand Up @@ -154,8 +159,6 @@ func (c *Compiler) compileDefineFuncNode(v *parser.DefineFuncNode) value.Value {
})
}

entry := fn.NewBlock(name.Block())

prevContextFunc := c.contextFunc
prevContextBlock := c.contextBlock

Expand Down
3 changes: 2 additions & 1 deletion compiler/compiler/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,8 @@ func (c *Compiler) compileInitializeSliceWithValues(itemType types.Type, values
}

// Create slice with cap set to the requested size
allocSlice := sliceType.SliceZero(c.contextBlock, c.externalFuncs.Malloc.Value.(llvmValue.Named), len(values))
allocSlice := c.contextBlock.NewAlloca(sliceType.LLVM())
sliceType.SliceZero(c.contextBlock, c.externalFuncs.Malloc.Value.(llvmValue.Named), len(values), allocSlice)

backingArrayPtr := c.contextBlock.NewGetElementPtr(pointer.ElemType(allocSlice), allocSlice,
constant.NewInt(llvmTypes.I32, 0),
Expand Down
14 changes: 5 additions & 9 deletions compiler/compiler/types/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,22 +282,20 @@ func (Slice) Size() int64 {
return 3*4 + 8 // 3 int32s and a pointer
}

func (s Slice) SliceZero(block *ir.Block, mallocFunc llvmValue.Named, initCap int) *ir.InstAlloca {
func (s Slice) SliceZero(block *ir.Block, mallocFunc llvmValue.Named, initCap int, emptySlice llvmValue.Value) {
// The cap must always be larger than 0
// Use 2 as the default value
if initCap < 2 {
initCap = 2
}

emptySlize := block.NewAlloca(s.LLVM())

len := block.NewGetElementPtr(pointer.ElemType(emptySlize), emptySlize, constant.NewInt(types.I32, 0), constant.NewInt(types.I32, 0))
len := block.NewGetElementPtr(pointer.ElemType(emptySlice), emptySlice, constant.NewInt(types.I32, 0), constant.NewInt(types.I32, 0))
len.SetName(name.Var("len"))
cap := block.NewGetElementPtr(pointer.ElemType(emptySlize), emptySlize, constant.NewInt(types.I32, 0), constant.NewInt(types.I32, 1))
cap := block.NewGetElementPtr(pointer.ElemType(emptySlice), emptySlice, constant.NewInt(types.I32, 0), constant.NewInt(types.I32, 1))
cap.SetName(name.Var("cap"))
offset := block.NewGetElementPtr(pointer.ElemType(emptySlize), emptySlize, constant.NewInt(types.I32, 0), constant.NewInt(types.I32, 2))
offset := block.NewGetElementPtr(pointer.ElemType(emptySlice), emptySlice, constant.NewInt(types.I32, 0), constant.NewInt(types.I32, 2))
offset.SetName(name.Var("offset"))
backingArray := block.NewGetElementPtr(pointer.ElemType(emptySlize), emptySlize, constant.NewInt(types.I32, 0), constant.NewInt(types.I32, 3))
backingArray := block.NewGetElementPtr(pointer.ElemType(emptySlice), emptySlice, constant.NewInt(types.I32, 0), constant.NewInt(types.I32, 3))
backingArray.SetName(name.Var("backing"))

block.NewStore(constant.NewInt(types.I32, 0), len)
Expand All @@ -308,8 +306,6 @@ func (s Slice) SliceZero(block *ir.Block, mallocFunc llvmValue.Named, initCap in
mallocatedSpaceRaw.SetName(name.Var("slicezero"))
bitcasted := block.NewBitCast(mallocatedSpaceRaw, types.NewPointer(s.Type.LLVM()))
block.NewStore(bitcasted, backingArray)

return emptySlize
}

type Pointer struct {
Expand Down
23 changes: 20 additions & 3 deletions compiler/testdata/package-vars.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
package main

import (
"external"
)

var foo string
var num int
var sli []int

func main() {
foo = "abc\n"
print(foo) // abc
}
external.Printf("foo: '%s'\n", foo) // foo: ''
external.Printf("num: %d\n", num) // num: 0
external.Printf("sli: %d\n", len(sli)) // sli: 0

foo = "abc"
num = 3
sli = append(sli, 1)
sli = append(sli, 2)
sli = append(sli, 3)

external.Printf("foo: '%s'\n", foo) // foo: 'abc'
external.Printf("num: %d\n", num) // num: 3
external.Printf("sli: %d\n", len(sli)) // sli: 3
}

0 comments on commit 1e4b1e6

Please sign in to comment.