From c9ae72a10535383f91a8afb1ff9bf633d32592dd Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Mon, 24 Sep 2018 16:17:42 +0200 Subject: [PATCH] all: allow -O0 optimization level --- compiler/compiler.go | 20 ++++++++------------ src/runtime/runtime.go | 37 +++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/compiler/compiler.go b/compiler/compiler.go index 48cfe0f8..e176523d 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -361,22 +361,18 @@ func (c *Compiler) Compile(mainPath string) error { } c.builder.CreateRetVoid() - // Adjust main function. + mainWrapper := c.mod.NamedFunction("runtime.mainWrapper") + block = c.ctx.AddBasicBlock(mainWrapper, "entry") + c.builder.SetInsertPointAtEnd(block) realMain := c.mod.NamedFunction(c.ir.MainPkg().Pkg.Path() + ".main") if c.ir.NeedsScheduler() { - c.mod.NamedFunction("runtime.main_mainAsync").ReplaceAllUsesWith(realMain) + coroutine := c.builder.CreateCall(realMain, []llvm.Value{llvm.ConstPointerNull(c.i8ptrType)}, "") + scheduler := c.mod.NamedFunction("runtime.scheduler") + c.builder.CreateCall(scheduler, []llvm.Value{coroutine}, "") } else { - c.mod.NamedFunction("runtime.main_main").ReplaceAllUsesWith(realMain) - } - - // Only use a scheduler when necessary. - if c.ir.NeedsScheduler() { - // Enable the scheduler. - hasScheduler := c.mod.NamedGlobal("runtime.hasScheduler") - hasScheduler.SetInitializer(llvm.ConstInt(llvm.Int1Type(), 1, false)) - hasScheduler.SetGlobalConstant(true) - hasScheduler.SetUnnamedAddr(true) + c.builder.CreateCall(realMain, nil, "") } + c.builder.CreateRetVoid() // Initialize runtime type information, for interfaces. // See src/runtime/interface.go for more details. diff --git a/src/runtime/runtime.go b/src/runtime/runtime.go index 5ac66633..25da2143 100644 --- a/src/runtime/runtime.go +++ b/src/runtime/runtime.go @@ -10,14 +10,18 @@ const Compiler = "tgo" // 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 +// The compiler will insert the call to main.main() here, depending on whether +// the scheduler is necessary. +// +// Without scheduler: +// +// main.main() +// +// With scheduler: +// +// coroutine := main.main(nil) +// scheduler(coroutine) +func mainWrapper() // Entry point for Go. Initialize all packages and call main.main(). //go:export main @@ -31,18 +35,11 @@ func main() int { // Enable interrupts etc. postinit() - // 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 - } + // Compiler-generated wrapper to main.main(). + mainWrapper() + + // For libc compatibility. + return 0 } func GOMAXPROCS(n int) int {