all: move bootstrapping IR to Go runtime

This has the benefit of not requiring a 'runtime' IR file, so that
complete relocatable files can be built without requiring input IR.
This makes the compiler a lot easier to use without the Makefile.

Code size is not affected.
This commit is contained in:
Ayke van Laethem
2018-09-04 20:39:22 +02:00
parent 0746d61639
commit 83ad0b6137
7 changed files with 70 additions and 49 deletions
+33
View File
@@ -6,6 +6,39 @@ import (
const Compiler = "tgo"
// The compiler will fill this with calls to the initialization function of each
// package.
func initAll()
// These signatures are used to call the correct main function: with scheduling
// or without scheduling.
func main_main()
func main_mainAsync(parent *coroutine) *coroutine
// The compiler will change this to true if there are 'go' statements in the
// compiled program and turn it into a const.
var hasScheduler bool
// Entry point for Go. Initialize all packages and call main.main().
//go:export main
func main() int {
// Run initializers of all packages.
initAll()
// This branch must be optimized away. Only one of the targets must remain,
// or there will be link errors.
if hasScheduler {
// Initialize main and run the scheduler.
coro := main_mainAsync(nil)
scheduler(coro)
return 0
} else {
// No scheduler is necessary. Call main directly.
main_main()
return 0
}
}
func Sleep(d Duration) {
// This function is treated specially by the compiler: when goroutines are
// used, it is transformed into a llvm.coro.suspend() call.
+1 -25
View File
@@ -1,27 +1,3 @@
source_filename = "runtime/runtime.ll"
declare void @runtime.initAll()
declare void @main.main()
declare i8* @main.main$async(i8*)
declare void @runtime.scheduler(i8*)
; Will be changed to true if there are 'go' statements in the compiled program.
@has_scheduler = private unnamed_addr constant i1 false
define i32 @main() {
call void @runtime.initAll()
%has_scheduler = load i1, i1* @has_scheduler
; This branch will be optimized away. Only one of the targets will remain.
br i1 %has_scheduler, label %with_scheduler, label %without_scheduler
with_scheduler:
; Initialize main and run the scheduler.
%main = call i8* @main.main$async(i8* null)
call void @runtime.scheduler(i8* %main)
ret i32 0
without_scheduler:
; No scheduler is necessary. Call main directly.
call void @main.main()
ret i32 0
}
; dummy file
-4
View File
@@ -29,10 +29,6 @@ void RTC0_IRQHandler() {
rtc_wakeup = true;
}
void _start() {
main();
}
__attribute__((weak))
void __aeabi_unwind_cpp_pr0() {
// dummy, not actually used
+5
View File
@@ -11,6 +11,11 @@ func _Cfunc_rtc_sleep(ticks uint32)
const Microsecond = 1
//go:export _start
func _start() {
main()
}
func init() {
initUART()
initLFCLK()