diff options
-rw-r--r-- | Makefile | 30 | ||||
-rw-r--r-- | src/runtime/runtime.c | 21 | ||||
-rw-r--r-- | src/runtime/runtime.ll | 10 | ||||
-rw-r--r-- | tgo.go | 38 |
4 files changed, 53 insertions, 46 deletions
@@ -9,6 +9,7 @@ tgo: build/tgo LLVM := $(shell go env GOPATH)/src/llvm.org/llvm/bindings/go/llvm/workdir/llvm_build/bin/ LINK = $(LLVM)llvm-link LLC = $(LLVM)llc +LLAS = $(LLVM)llvm-as CFLAGS = -Wall -Werror -Os -g -fno-exceptions -flto -ffunction-sections -fdata-sections $(LLFLAGS) @@ -16,7 +17,14 @@ RUNTIME_PARTS = build/runtime.bc TARGET ?= unix -ifeq ($(TARGET),pca10040) +ifeq ($(TARGET),unix) +# Regular *nix system. +GCC = gcc +LD = clang +SIZE = size + +else ifeq ($(TARGET),pca10040) +# PCA10040: nRF52832 development board GCC = arm-none-eabi-gcc LD = arm-none-eabi-ld -T arm.ld --gc-sections SIZE = arm-none-eabi-size @@ -30,14 +38,12 @@ CFLAGS += -I$(CURDIR)/lib/CMSIS/CMSIS/Include CFLAGS += -DNRF52832_XXAA CFLAGS += -Wno-uninitialized RUNTIME_PARTS += build/runtime_nrf.bc -RUNTIME_PARTS += build/system_nrf52.bc -OBJ += build/startup_nrf51.o # TODO nrf52, see https://bugs.llvm.org/show_bug.cgi?id=31601 +RUNTIME_PARTS += build/nrfx_system_nrf52.bc +OBJ += build/nrfx_startup_nrf51.o # TODO nrf52, see https://bugs.llvm.org/show_bug.cgi?id=31601 + +else +$(error Unknown target) -else ifeq ($(TARGET),unix) -# Regular *nix system. -GCC = gcc -LD = clang -SIZE = size endif @@ -75,13 +81,17 @@ build/%.bc: src/runtime/%.c src/runtime/*.h @mkdir -p build clang $(CFLAGS) -c -o $@ $< +# Compile LLVM bitcode from LLVM source. +build/%.bc: src/runtime/%.ll + $(LLAS) -o $@ $< + # Compile system_* file for the nRF. -build/%.bc: lib/nrfx/mdk/%.c +build/nrfx_%.bc: lib/nrfx/mdk/%.c @mkdir -p build clang $(CFLAGS) -c -o $@ $^ # Compile startup_* file for the nRF. -build/%.o: lib/nrfx/mdk/gcc_%.S +build/nrfx_%.o: lib/nrfx/mdk/gcc_%.S @mkdir -p build clang $(CFLAGS) -c -o $@ $^ diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c deleted file mode 100644 index 1e413d9c9..000000000 --- a/src/runtime/runtime.c +++ /dev/null @@ -1,21 +0,0 @@ - -#include "runtime.h" -#include <string.h> - -void go_init() __asm__("runtime.initAll"); -void go_main() __asm__("main.main"); - -int main() { - go_init(); - go_main(); - - return 0; -} - -__attribute__((weak)) -void * memset(void *s, int c, size_t n) { - for (size_t i = 0; i < n; i++) { - ((uint8_t*)s)[i] = c; - } - return s; -} diff --git a/src/runtime/runtime.ll b/src/runtime/runtime.ll new file mode 100644 index 000000000..fa271f16c --- /dev/null +++ b/src/runtime/runtime.ll @@ -0,0 +1,10 @@ +source_filename = "runtime/runtime.ll" + +declare void @runtime.initAll() +declare void @main.main() + +define i32 @main() { + call void @runtime.initAll() + call void @main.main() + ret i32 0 +} @@ -199,8 +199,12 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error { // After all packages are imported, add a synthetic initializer function // that calls the initializer of each package. - initType := llvm.FunctionType(llvm.VoidType(), nil, false) - initFn := llvm.AddFunction(c.mod, "runtime.initAll", initType) + initFn := c.mod.NamedFunction("runtime.initAll") + if initFn.IsNil() { + initType := llvm.FunctionType(llvm.VoidType(), nil, false) + initFn = llvm.AddFunction(c.mod, "runtime.initAll", initType) + } + initFn.SetLinkage(llvm.PrivateLinkage) block := c.ctx.AddBasicBlock(initFn, "entry") c.builder.SetInsertPointAtEnd(block) for _, fn := range c.initFuncs { @@ -208,6 +212,11 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error { } c.builder.CreateRetVoid() + // Set functions referenced in runtime.ll to internal linkage, to improve + // optimization (hopefully). + main := c.mod.NamedFunction("main.main") + main.SetLinkage(llvm.PrivateLinkage) + return nil } @@ -518,6 +527,7 @@ func (c *Compiler) parseFuncDecl(f *ssa.Function) (*Frame, error) { // Special function parser for generated package initializers (which also // initializes global variables). func (c *Compiler) parseInitFunc(frame *Frame, f *ssa.Function) error { + frame.llvmFn.SetLinkage(llvm.PrivateLinkage) llvmBlock := c.ctx.AddBasicBlock(frame.llvmFn, "entry") c.builder.SetInsertPointAtEnd(llvmBlock) @@ -605,10 +615,7 @@ func (c *Compiler) parseInitFunc(frame *Frame, f *ssa.Function) error { } func (c *Compiler) parseFunc(frame *Frame, f *ssa.Function) error { - if frame.llvmFn.Name() != "main.main" { - // This function is only used from within Go. - frame.llvmFn.SetLinkage(llvm.PrivateLinkage) - } + frame.llvmFn.SetLinkage(llvm.PrivateLinkage) // Pre-create all basic blocks in the function. for _, block := range f.DomPreorder() { @@ -1341,15 +1348,7 @@ func Compile(pkgName, runtimePath, outpath, target string, printIR bool) error { return err } - parseErr := c.Parse(pkgName, buildTags) - if printIR { - fmt.Println(c.IR()) - } - if parseErr != nil { - return parseErr - } - - // Add C runtime. + // Add C/LLVM runtime. runtime, err := llvm.ParseBitcodeFile(runtimePath) if err != nil { return err @@ -1359,6 +1358,15 @@ func Compile(pkgName, runtimePath, outpath, target string, printIR bool) error { return err } + // Compile Go code to IR. + parseErr := c.Parse(pkgName, buildTags) + if printIR { + fmt.Println(c.IR()) + } + if parseErr != nil { + return parseErr + } + c.ApplyFunctionSections() // -ffunction-sections if err := c.Verify(); err != nil { |