func (c *Compiler) LowerGoroutines() error {
	needsScheduler, err := c.markAsyncFunctions()
	if err != nil {
		return err
	}

	uses := getUses(c.mod.NamedFunction("runtime.callMain"))
	if len(uses) != 1 || uses[0].IsACallInst().IsNil() {
		panic("expected exactly 1 call of runtime.callMain, check the entry point")
	}
	mainCall := uses[0]

	// Replace call of runtime.callMain() with a real call to main.main(),
	// optionally followed by a call to runtime.scheduler().
	c.builder.SetInsertPointBefore(mainCall)
	realMain := c.mod.NamedFunction(c.ir.MainPkg().Pkg.Path() + ".main")
	c.builder.CreateCall(realMain, []llvm.Value{llvm.Undef(c.i8ptrType), llvm.ConstPointerNull(c.i8ptrType)}, "")
	if needsScheduler {
		c.createRuntimeCall("scheduler", nil, "")
	}
	mainCall.EraseFromParentAsInstruction()

	if !needsScheduler {
		go_scheduler := c.mod.NamedFunction("go_scheduler")
		if !go_scheduler.IsNil() {
			// This is the WebAssembly backend.
			// There is no need to export the go_scheduler function, but it is
			// still exported. Make sure it is optimized away.
			go_scheduler.SetLinkage(llvm.InternalLinkage)
		}
	}

	// main.main was set to external linkage during IR construction. Set it to
	// internal linkage to enable interprocedural optimizations.
	realMain.SetLinkage(llvm.InternalLinkage)
	c.mod.NamedFunction("runtime.alloc").SetLinkage(llvm.InternalLinkage)
	c.mod.NamedFunction("runtime.free").SetLinkage(llvm.InternalLinkage)
	c.mod.NamedFunction("runtime.sleepTask").SetLinkage(llvm.InternalLinkage)
	c.mod.NamedFunction("runtime.setTaskPromisePtr").SetLinkage(llvm.InternalLinkage)
	c.mod.NamedFunction("runtime.getTaskPromisePtr").SetLinkage(llvm.InternalLinkage)
	c.mod.NamedFunction("runtime.scheduler").SetLinkage(llvm.InternalLinkage)

	return nil
}
// LowerGoroutines is a pass called during optimization that transforms the IR
// into one where all blocking functions are turned into goroutines and blocking
// calls into await calls.
LowerGoroutines is a pass called during optimization that transforms the IR
into one where all blocking functions are turned into goroutines and blocking
calls into await calls.
// LowerGoroutines is a pass called during optimization that transforms the IR // into one where all blocking functions are turned into goroutines and blocking // calls into await calls .
func (c *Compiler) LowerGoroutines() error {
	needsScheduler, err := c.markAsyncFunctions()
	if err != nil {
		return err
	}
	uses := getUses(c.mod.NamedFunction("runtime.callMain"))
	if len(uses) != 1 || uses[0].IsACallInst().IsNil() {
		panic("expected exactly 1 call of runtime.callMain, check the entry point")
	}
	mainCall := uses[0]
	c.builder.SetInsertPointBefore(mainCall)
	realMain := c.mod.NamedFunction(c.ir.MainPkg().Pkg.Path() + ".main")
	c.builder.CreateCall(realMain, []llvm.Value{llvm.Undef(c.i8ptrType), llvm.ConstPointerNull(c.i8ptrType)}, "")
	if needsScheduler {
		c.createRuntimeCall("scheduler", nil, "")
	}
	mainCall.EraseFromParentAsInstruction()
	if !needsScheduler {
		go_scheduler := c.mod.NamedFunction("go_scheduler")
		if !go_scheduler.IsNil() {
			go_scheduler.SetLinkage(llvm.InternalLinkage)
		}
	}
	realMain.SetLinkage(llvm.InternalLinkage)
	c.mod.NamedFunction("runtime.alloc").SetLinkage(llvm.InternalLinkage)
	c.mod.NamedFunction("runtime.free").SetLinkage(llvm.InternalLinkage)
	c.mod.NamedFunction("runtime.sleepTask").SetLinkage(llvm.InternalLinkage)
	c.mod.NamedFunction("runtime.setTaskPromisePtr").SetLinkage(llvm.InternalLinkage)
	c.mod.NamedFunction("runtime.getTaskPromisePtr").SetLinkage(llvm.InternalLinkage)
	c.mod.NamedFunction("runtime.scheduler").SetLinkage(llvm.InternalLinkage)
	return nil
}
func ( c * Compiler ) LowerGoroutines ( ) error { needsScheduler , err := c . markAsyncFunctions ( ) if err != nil { return err } uses := getUses ( c . mod . NamedFunction ( " " ) ) if len ( uses ) != 1 || uses [ 0 ] . IsACallInst ( ) . IsNil ( ) { panic ( " " ) } mainCall := uses [ 0 ] c . builder . SetInsertPointBefore ( mainCall ) realMain := c . mod . NamedFunction ( c . ir . MainPkg ( ) . Pkg . Path ( ) + " " ) c . builder . CreateCall ( realMain , [ ] llvm . Value { llvm . Undef ( c . i8ptrType ) , llvm . ConstPointerNull ( c . i8ptrType ) } , " " ) if needsScheduler { c . createRuntimeCall ( " " , nil , " " ) } mainCall . EraseFromParentAsInstruction ( ) if ! needsScheduler { go_scheduler := c . mod . NamedFunction ( " " ) if ! go_scheduler . IsNil ( ) { go_scheduler . SetLinkage ( llvm . InternalLinkage ) } } realMain . SetLinkage ( llvm . InternalLinkage ) c . mod . NamedFunction ( " " ) . SetLinkage ( llvm . InternalLinkage ) c . mod . NamedFunction ( " " ) . SetLinkage ( llvm . InternalLinkage ) c . mod . NamedFunction ( " " ) . SetLinkage ( llvm . InternalLinkage ) c . mod . NamedFunction ( " " ) . SetLinkage ( llvm . InternalLinkage ) c . mod . NamedFunction ( " " ) . SetLinkage ( llvm . InternalLinkage ) c . mod . NamedFunction ( " " ) . SetLinkage ( llvm . InternalLinkage ) return nil }
LowerGoroutines is a pass called during optimization that transforms the IR
into one where all blocking functions are turned into goroutines and blocking
calls into await calls.
LowerGoroutines is a pass called during optimization that transforms the IR into one where all blocking functions are turned into goroutines and blocking calls into await calls .
// Replace call of runtime.callMain() with a real call to main.main(), // optionally followed by a call to runtime.scheduler(). // This is the WebAssembly backend. // There is no need to export the go_scheduler function, but it is // still exported. Make sure it is optimized away. // main.main was set to external linkage during IR construction. Set it to // internal linkage to enable interprocedural optimizations.