Example #1
0
func runMainFunction(m *llgo.Module) (output []string, err error) {
	runtimeModule, err := getRuntimeModuleFile()
	if err != nil {
		return
	}

	err = llvm.VerifyModule(m.Module, llvm.ReturnStatusAction)
	if err != nil {
		return nil, fmt.Errorf("Verification failed: %v", err)
	}

	bcpath := filepath.Join(tempdir, "test.bc")
	bcfile, err := os.Create(bcpath)
	if err != nil {
		return nil, err
	}
	llvm.WriteBitcodeToFile(m.Module, bcfile)
	bcfile.Close()

	cmd := exec.Command("llvm-link", "-o", bcpath, bcpath, runtimeModule)
	data, err := cmd.CombinedOutput()
	if err != nil {
		output = strings.Split(strings.TrimSpace(string(data)), "\n")
		return output, fmt.Errorf("llvm-link failed: %v", err)
	}

	exepath := filepath.Join(tempdir, "test")
	args := []string{"-pthread", "-o", exepath, bcpath}
	if runtime.GOOS != "darwin" {
		// TODO(q): -g breaks badly on my system at the moment, so is not enabled on darwin for now
		args = append([]string{"-g"}, args...)
	}

	cmd = exec.Command("clang++", args...)
	data, err = cmd.CombinedOutput()
	if err != nil {
		output = strings.Split(strings.TrimSpace(string(data)), "\n")
		return output, fmt.Errorf("clang++ failed: %v", err)
	}

	cmd = exec.Command(exepath)
	data, err = cmd.CombinedOutput()
	output = strings.Split(strings.TrimSpace(string(data)), "\n")
	return output, err
}
Example #2
0
File: llgo.go Project: pcc/llgo
func writeObjectFile(m *llgo.Module) error {
	var outfile *os.File
	switch *outputFile {
	case "-":
		outfile = os.Stdout
	default:
		var err error
		outfile, err = os.Create(*outputFile)
		if err != nil {
			return err
		}
	}
	err := llvm.VerifyModule(m.Module, llvm.ReturnStatusAction)
	if err != nil {
		return fmt.Errorf("Verification failed: %v", err)
	}
	return llvm.WriteBitcodeToFile(m.Module, outfile)
}
Example #3
0
func runMainFunction(m *llgo.Module) (output []string, err error) {
	runtimeModule, err := getRuntimeModuleFile()
	if err != nil {
		return
	}

	err = llvm.VerifyModule(m.Module, llvm.ReturnStatusAction)
	if err != nil {
		err = fmt.Errorf("Verification failed: %v", err)
		return
	}

	bcpath := filepath.Join(tempdir, "test.bc")
	bcfile, err := os.Create(bcpath)
	if err != nil {
		return nil, err
	}
	llvm.WriteBitcodeToFile(m.Module, bcfile)
	bcfile.Close()

	cmd := exec.Command("llvm-link", "-o", bcpath, bcpath, runtimeModule)
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err != nil {
		return
	}

	exepath := filepath.Join(tempdir, "test")
	cmd = exec.Command("clang++", "-pthread", "-g", "-o", exepath, bcpath)
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err != nil {
		return
	}

	cmd = exec.Command(exepath)
	data, err := cmd.Output()
	if err != nil {
		return
	}
	output = strings.Split(strings.TrimSpace(string(data)), "\n")
	return
}
Example #4
0
func runFunction(m *llgo.Module, name string) (output []string, err error) {
	addExterns(m)
	err = addRuntime(m)
	if err != nil {
		return
	}

	err = llvm.VerifyModule(m.Module, llvm.ReturnStatusAction)
	if err != nil {
		return
	}

	engine, err := llvm.NewJITCompiler(m.Module, 0)
	if err != nil {
		return
	}
	defer engine.Dispose()

	fn := engine.FindFunction(name)
	if fn.IsNil() {
		err = fmt.Errorf("Couldn't find function '%s'", name)
		return
	}

	// Redirect stdout to a pipe.
	pipe_fds := make([]int, 2)
	err = syscall.Pipe(pipe_fds)
	if err != nil {
		return
	}
	defer syscall.Close(pipe_fds[0])
	defer syscall.Close(pipe_fds[1])
	old_stdout, err := syscall.Dup(syscall.Stdout)
	if err != nil {
		return
	}
	defer syscall.Close(old_stdout)
	err = syscall.Dup2(pipe_fds[1], syscall.Stdout)
	if err != nil {
		return
	}
	defer syscall.Dup2(old_stdout, syscall.Stdout)

	c := make(chan string)
	go readPipe(pipe_fds[0], c)

	exec_args := []llvm.GenericValue{}
	engine.RunStaticConstructors()
	engine.RunFunction(fn, exec_args)
	defer engine.RunStaticDestructors()

	// Call fflush to flush stdio (printf), then sync and close the write
	// end of the pipe.
	fflush := engine.FindFunction("fflush")
	ptr0 := unsafe.Pointer(uintptr(0))
	exec_args = []llvm.GenericValue{llvm.NewGenericValueFromPointer(ptr0)}
	engine.RunFunction(fflush, exec_args)
	syscall.Fsync(pipe_fds[1])
	syscall.Close(pipe_fds[1])
	syscall.Close(syscall.Stdout)

	output_str := <-c
	output = strings.Split(strings.TrimSpace(output_str), "\n")
	return
}
Example #5
0
func runMainFunction(m *llgo.Module) (output []string, err error) {
	addExterns(m)
	err = addRuntime(m)
	if err != nil {
		return
	}

	err = llvm.VerifyModule(m.Module, llvm.ReturnStatusAction)
	if err != nil {
		err = fmt.Errorf("Verification failed: %v", err)
		return
	}

	engine, err := llvm.NewExecutionEngine(m.Module)
	if err != nil {
		return
	}
	defer engine.Dispose()

	fn := engine.FindFunction("main")
	if fn.IsNil() {
		err = fmt.Errorf("Couldn't find function 'main'")
		return
	}

	// Redirect stdout to a pipe.
	pipe_fds := make([]int, 2)
	err = syscall.Pipe(pipe_fds)
	if err != nil {
		return
	}
	defer syscall.Close(pipe_fds[0])
	defer syscall.Close(pipe_fds[1])
	old_stdout, err := syscall.Dup(syscall.Stdout)
	if err != nil {
		return
	}
	defer syscall.Close(old_stdout)
	err = syscall.Dup2(pipe_fds[1], syscall.Stdout)
	if err != nil {
		return
	}
	defer syscall.Dup2(old_stdout, syscall.Stdout)

	c := make(chan string)
	go readPipe(pipe_fds[0], c)

	// FIXME implement and use RunFunctionAsMain
	argv0 := []byte("llgo-test\000")
	var envs [1]*byte
	argv0ptr := &argv0
	exec_args := []llvm.GenericValue{
		llvm.NewGenericValueFromInt(llvm.Int32Type(), 1, true),
		llvm.NewGenericValueFromPointer(unsafe.Pointer(&argv0ptr)),
		llvm.NewGenericValueFromPointer(unsafe.Pointer(&envs)),
	}
	engine.RunStaticConstructors()
	engine.RunFunction(fn, exec_args)
	defer engine.RunStaticDestructors()

	// Call fflush to flush stdio (printf), then sync and close the write
	// end of the pipe.
	fflush := engine.FindFunction("fflush")
	ptr0 := unsafe.Pointer(uintptr(0))
	exec_args = []llvm.GenericValue{llvm.NewGenericValueFromPointer(ptr0)}
	engine.RunFunction(fflush, exec_args)
	syscall.Fsync(pipe_fds[1])
	syscall.Close(pipe_fds[1])
	syscall.Close(syscall.Stdout)

	output_str := <-c
	output = strings.Split(strings.TrimSpace(output_str), "\n")
	return
}
Example #6
0
func test() {
	llvm.LinkInJIT()
	llvm.InitializeNativeTarget()

	mod := llvm.NewModule("fac_module")

	// don't do that, because ExecutionEngine takes ownership over module
	//defer mod.Dispose()

	fac_args := []llvm.Type{llvm.Int32Type()}
	fac_type := llvm.FunctionType(llvm.Int32Type(), fac_args, false)
	fac := llvm.AddFunction(mod, "fac", fac_type)
	fac.SetFunctionCallConv(llvm.CCallConv)
	n := fac.Param(0)

	entry := llvm.AddBasicBlock(fac, "entry")
	iftrue := llvm.AddBasicBlock(fac, "iftrue")
	iffalse := llvm.AddBasicBlock(fac, "iffalse")
	end := llvm.AddBasicBlock(fac, "end")

	builder := llvm.NewBuilder()
	defer builder.Dispose()

	builder.SetInsertPointAtEnd(entry)
	If := builder.CreateICmp(llvm.IntEQ, n, llvm.ConstInt(llvm.Int32Type(), 0, false), "cmptmp")
	builder.CreateCondBr(If, iftrue, iffalse)

	builder.SetInsertPointAtEnd(iftrue)
	res_iftrue := llvm.ConstInt(llvm.Int32Type(), 1, false)
	builder.CreateBr(end)

	builder.SetInsertPointAtEnd(iffalse)
	n_minus := builder.CreateSub(n, llvm.ConstInt(llvm.Int32Type(), 1, false), "subtmp")
	call_fac_args := []llvm.Value{n_minus}
	call_fac := builder.CreateCall(fac, call_fac_args, "calltmp")
	res_iffalse := builder.CreateMul(n, call_fac, "multmp")
	builder.CreateBr(end)

	builder.SetInsertPointAtEnd(end)
	res := builder.CreatePHI(llvm.Int32Type(), "result")
	phi_vals := []llvm.Value{res_iftrue, res_iffalse}
	phi_blocks := []llvm.BasicBlock{iftrue, iffalse}
	res.AddIncoming(phi_vals, phi_blocks)
	builder.CreateRet(res)

	err := llvm.VerifyModule(mod, llvm.ReturnStatusAction)
	if err != nil {
		fmt.Println(err)
		return
	}

	engine, err := llvm.NewJITCompiler(mod, 2)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer engine.Dispose()

	pass := llvm.NewPassManager()
	defer pass.Dispose()

	pass.Add(engine.TargetData())
	pass.AddConstantPropagationPass()
	pass.AddInstructionCombiningPass()
	pass.AddPromoteMemoryToRegisterPass()
	pass.AddGVNPass()
	pass.AddCFGSimplificationPass()
	pass.Run(mod)

	mod.Dump()

	exec_args := []llvm.GenericValue{llvm.NewGenericValueFromInt(llvm.Int32Type(), 10, false)}
	exec_res := engine.RunFunction(fac, exec_args)
	fmt.Println("-----------------------------------------")
	fmt.Println("Running fac(10) with JIT...")
	fmt.Printf("Result: %d\n", exec_res.Int(false))
}