aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile30
-rw-r--r--src/runtime/runtime.c21
-rw-r--r--src/runtime/runtime.ll10
-rw-r--r--tgo.go38
4 files changed, 53 insertions, 46 deletions
diff --git a/Makefile b/Makefile
index 7fa1c332b..1120719c5 100644
--- a/Makefile
+++ b/Makefile
@@ -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
+}
diff --git a/tgo.go b/tgo.go
index 8891c1243..3cdfb2925 100644
--- a/tgo.go
+++ b/tgo.go
@@ -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 {