func (c *Compiler) lowerMakeGoroutineCalls() error {
	// The following Go code:
	//   go startedGoroutine()
	//
	// Is translated to the following during IR construction, to preserve the
	// fact that this function should be called as a new goroutine.
	//   %0 = call i8* @runtime.makeGoroutine(i8* bitcast (void (i8*, i8*)* @main.startedGoroutine to i8*), i8* undef, i8* null)
	//   %1 = bitcast i8* %0 to void (i8*, i8*)*
	//   call void %1(i8* undef, i8* undef)
	//
	// This function rewrites it to a direct call:
	//   call void @main.startedGoroutine(i8* undef, i8* null)

	makeGoroutine := c.mod.NamedFunction("runtime.makeGoroutine")
	for _, goroutine := range getUses(makeGoroutine) {
		bitcastIn := goroutine.Operand(0)
		origFunc := bitcastIn.Operand(0)
		uses := getUses(goroutine)
		if len(uses) != 1 || uses[0].IsABitCastInst().IsNil() {
			return errors.New("expected exactly 1 bitcast use of runtime.makeGoroutine")
		}
		bitcastOut := uses[0]
		uses = getUses(bitcastOut)
		if len(uses) != 1 || uses[0].IsACallInst().IsNil() {
			return errors.New("expected exactly 1 call use of runtime.makeGoroutine bitcast")
		}
		realCall := uses[0]

		// Create call instruction.
		var params []llvm.Value
		for i := 0; i < realCall.OperandsCount()-1; i++ {
			params = append(params, realCall.Operand(i))
		}
		params[len(params)-1] = llvm.ConstPointerNull(c.i8ptrType) // parent coroutine handle (must be nil)
		c.builder.SetInsertPointBefore(realCall)
		c.builder.CreateCall(origFunc, params, "")
		realCall.EraseFromParentAsInstruction()
		bitcastOut.EraseFromParentAsInstruction()
		goroutine.EraseFromParentAsInstruction()
	}

	return nil
}
// Lower runtime.makeGoroutine calls to regular call instructions. This is done
// after the regular goroutine transformations. The started goroutines are
// either non-blocking (in which case they can be called directly) or blocking,
// in which case they will ask the scheduler themselves to be rescheduled.
Lower runtime.makeGoroutine calls to regular call instructions. This is done
after the regular goroutine transformations. The started goroutines are
either non-blocking (in which case they can be called directly) or blocking,
in which case they will ask the scheduler themselves to be rescheduled.
// Lower runtime . makeGoroutine calls to regular call instructions . This is done // after the regular goroutine transformations . The started goroutines are // either non - blocking ( in which case they can be called directly ) or blocking // in which case they will ask the scheduler themselves to be rescheduled .
func (c *Compiler) lowerMakeGoroutineCalls() error {
	 Is translated to the following during IR construction, to preserve the
	 fact that this function should be called as a new goroutine.
	   %0 = call i8* @runtime.makeGoroutine(i8* bitcast (void (i8*, i8*)* @main.startedGoroutine to i8*), i8* undef, i8* null)
	   %1 = bitcast i8* %0 to void (i8*, i8*)*
	   call void %1(i8* undef, i8* undef)
	 This function rewrites it to a direct call:
	   call void @main.startedGoroutine(i8* undef, i8* null)
	makeGoroutine := c.mod.NamedFunction("runtime.makeGoroutine")
	for _, goroutine := range getUses(makeGoroutine) {
		bitcastIn := goroutine.Operand(0)
		origFunc := bitcastIn.Operand(0)
		uses := getUses(goroutine)
		if len(uses) != 1 || uses[0].IsABitCastInst().IsNil() {
			return errors.New("expected exactly 1 bitcast use of runtime.makeGoroutine")
		}
		bitcastOut := uses[0]
		uses = getUses(bitcastOut)
		if len(uses) != 1 || uses[0].IsACallInst().IsNil() {
			return errors.New("expected exactly 1 call use of runtime.makeGoroutine bitcast")
		}
		realCall := uses[0]
		 Create call instruction.
		var params []llvm.Value
		for i := 0; i < realCall.OperandsCount()-1; i++ {
			params = append(params, realCall.Operand(i))
		}
		params[len(params)-1] = llvm.ConstPointerNull(c.i8ptrType)  parent coroutine handle (must be nil)
		c.builder.SetInsertPointBefore(realCall)
		c.builder.CreateCall(origFunc, params, "")
		realCall.EraseFromParentAsInstruction()
		bitcastOut.EraseFromParentAsInstruction()
		goroutine.EraseFromParentAsInstruction()
	}
	return nil
}
func ( c * Compiler ) lowerMakeGoroutineCalls ( ) error { makeGoroutine := c . mod . NamedFunction ( " " ) for _ , goroutine := range getUses ( makeGoroutine ) { bitcastIn := goroutine . Operand ( 0 ) origFunc := bitcastIn . Operand ( 0 ) uses := getUses ( goroutine ) if len ( uses ) != 1 || uses [ 0 ] . IsABitCastInst ( ) . IsNil ( ) { return errors . New ( " " ) } bitcastOut := uses [ 0 ] uses = getUses ( bitcastOut ) if len ( uses ) != 1 || uses [ 0 ] . IsACallInst ( ) . IsNil ( ) { return errors . New ( " " ) } realCall := uses [ 0 ] var params [ ] llvm . Value for i := 0 ; i < realCall . OperandsCount ( ) - 1 ; i ++ { params = append ( params , realCall . Operand ( i ) ) } params [ len ( params ) - 1 ] = llvm . ConstPointerNull ( c . i8ptrType ) c . builder . SetInsertPointBefore ( realCall ) c . builder . CreateCall ( origFunc , params , " " ) realCall . EraseFromParentAsInstruction ( ) bitcastOut . EraseFromParentAsInstruction ( ) goroutine . EraseFromParentAsInstruction ( ) } return nil }
Lower runtime.makeGoroutine calls to regular call instructions.
Lower runtime . makeGoroutine calls to regular call instructions .
// The following Go code: //   go startedGoroutine() // // Is translated to the following during IR construction, to preserve the // fact that this function should be called as a new goroutine. //   %0 = call i8* @runtime.makeGoroutine(i8* bitcast (void (i8*, i8*)* @main.startedGoroutine to i8*), i8* undef, i8* null) //   %1 = bitcast i8* %0 to void (i8*, i8*)* //   call void %1(i8* undef, i8* undef) // // This function rewrites it to a direct call: //   call void @main.startedGoroutine(i8* undef, i8* null) // Create call instruction. // parent coroutine handle (must be nil)