本文整理匯總了Golang中github.com/axw/gollvm/llvm.VoidType函數的典型用法代碼示例。如果您正苦於以下問題:Golang VoidType函數的具體用法?Golang VoidType怎麽用?Golang VoidType使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了VoidType函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: NewTypeMap
func NewTypeMap(llvmtm *LLVMTypeMap, module llvm.Module, pkgpath string, exprTypes map[ast.Expr]types.Type, c *FunctionCache, r Resolver) *TypeMap {
tm := &TypeMap{
LLVMTypeMap: llvmtm,
module: module,
pkgpath: pkgpath,
types: make(map[string]runtimeTypeInfo),
expr: exprTypes,
functions: c,
resolver: r,
}
// Load runtime/reflect types, and generate LLVM types for
// the structures we need to populate runtime type information.
pkg, err := c.compiler.parseReflect()
if err != nil {
panic(err) // FIXME return err
}
reflectLLVMType := func(name string) llvm.Type {
obj := pkg.Scope.Lookup(name)
if obj == nil {
panic(fmt.Errorf("Failed to find type: %s", name))
}
return tm.ToLLVM(obj.Type.(types.Type))
}
tm.runtimeType = reflectLLVMType("runtimeType")
tm.runtimeCommonType = reflectLLVMType("commonType")
tm.runtimeUncommonType = reflectLLVMType("uncommonType")
tm.runtimeArrayType = reflectLLVMType("arrayType")
tm.runtimeChanType = reflectLLVMType("chanType")
tm.runtimeFuncType = reflectLLVMType("funcType")
tm.runtimeMethod = reflectLLVMType("method")
tm.runtimeImethod = reflectLLVMType("imethod")
tm.runtimeInterfaceType = reflectLLVMType("interfaceType")
tm.runtimeMapType = reflectLLVMType("mapType")
tm.runtimePtrType = reflectLLVMType("ptrType")
tm.runtimeSliceType = reflectLLVMType("sliceType")
tm.runtimeStructType = reflectLLVMType("structType")
tm.commonType = pkg.Scope.Lookup("commonType").Type.(*types.Name)
// Types for algorithms. See 'runtime/runtime.h'.
uintptrType := tm.target.IntPtrType()
voidPtrType := llvm.PointerType(llvm.Int8Type(), 0)
boolType := llvm.Int1Type()
// Create runtime algorithm function types.
params := []llvm.Type{uintptrType, voidPtrType}
tm.hashAlgFunctionType = llvm.FunctionType(uintptrType, params, false)
params = []llvm.Type{uintptrType, uintptrType, uintptrType}
tm.equalAlgFunctionType = llvm.FunctionType(boolType, params, false)
params = []llvm.Type{uintptrType, voidPtrType}
tm.printAlgFunctionType = llvm.FunctionType(llvm.VoidType(), params, false)
params = []llvm.Type{uintptrType, voidPtrType, voidPtrType}
tm.copyAlgFunctionType = llvm.FunctionType(llvm.VoidType(), params, false)
return tm
}
示例2: NewTypeMap
func NewTypeMap(llvmtm *LLVMTypeMap, pkgpath string, exprTypes map[ast.Expr]types.Type, c *FunctionCache, p map[*ast.Object]string, r Resolver) *TypeMap {
tm := &TypeMap{
LLVMTypeMap: llvmtm,
pkgpath: pkgpath,
types: make(map[types.Type]llvm.Value),
expr: exprTypes,
pkgmap: p,
functions: c,
resolver: r,
}
// Load "reflect.go", and generate LLVM types for the runtime type
// structures.
pkg, err := parseReflect()
if err != nil {
panic(err) // FIXME return err
}
objToLLVMType := func(name string) llvm.Type {
obj := pkg.Scope.Lookup(name)
return tm.ToLLVM(obj.Type.(types.Type))
}
tm.runtimeType = objToLLVMType("runtimeType")
tm.runtimeCommonType = objToLLVMType("commonType")
tm.runtimeUncommonType = objToLLVMType("uncommonType")
tm.runtimeArrayType = objToLLVMType("arrayType")
tm.runtimeChanType = objToLLVMType("chanType")
tm.runtimeFuncType = objToLLVMType("funcType")
tm.runtimeMethod = objToLLVMType("method")
tm.runtimeImethod = objToLLVMType("imethod")
tm.runtimeInterfaceType = objToLLVMType("interfaceType")
tm.runtimeMapType = objToLLVMType("mapType")
tm.runtimePtrType = objToLLVMType("ptrType")
tm.runtimeSliceType = objToLLVMType("sliceType")
tm.runtimeStructType = objToLLVMType("structType")
// Types for algorithms. See 'runtime/runtime.h'.
uintptrType := tm.target.IntPtrType()
voidPtrType := llvm.PointerType(llvm.Int8Type(), 0)
boolType := llvm.Int1Type()
// Create runtime algorithm function types.
params := []llvm.Type{uintptrType, voidPtrType}
tm.hashAlgFunctionType = llvm.FunctionType(uintptrType, params, false)
params = []llvm.Type{uintptrType, uintptrType, uintptrType}
tm.equalAlgFunctionType = llvm.FunctionType(boolType, params, false)
params = []llvm.Type{uintptrType, voidPtrType}
tm.printAlgFunctionType = llvm.FunctionType(llvm.VoidType(), params, false)
params = []llvm.Type{uintptrType, voidPtrType, voidPtrType}
tm.copyAlgFunctionType = llvm.FunctionType(llvm.VoidType(), params, false)
return tm
}
示例3: getnewgoroutine
func getnewgoroutine(module llvm.Module) llvm.Value {
fn := module.NamedFunction("llgo_newgoroutine")
if fn.IsNil() {
i8Ptr := llvm.PointerType(llvm.Int8Type(), 0)
VoidFnPtr := llvm.PointerType(llvm.FunctionType(
llvm.VoidType(), []llvm.Type{i8Ptr}, false), 0)
i32 := llvm.Int32Type()
fn_type := llvm.FunctionType(
llvm.VoidType(), []llvm.Type{VoidFnPtr, i8Ptr, i32}, true)
fn = llvm.AddFunction(module, "llgo_newgoroutine", fn_type)
fn.SetFunctionCallConv(llvm.CCallConv)
}
return fn
}
示例4: defineMemcpyFunction
func (c *compiler) defineMemcpyFunction(fn llvm.Value) {
entry := llvm.AddBasicBlock(fn, "entry")
c.builder.SetInsertPointAtEnd(entry)
dst, src, size := fn.Param(0), fn.Param(1), fn.Param(2)
pint8 := llvm.PointerType(llvm.Int8Type(), 0)
dst = c.builder.CreateIntToPtr(dst, pint8, "")
src = c.builder.CreateIntToPtr(src, pint8, "")
sizeType := size.Type()
sizeBits := sizeType.IntTypeWidth()
memcpyName := "llvm.memcpy.p0i8.p0i8.i" + strconv.Itoa(sizeBits)
memcpy := c.module.NamedFunction(memcpyName)
if memcpy.IsNil() {
paramtypes := []llvm.Type{
pint8, pint8, size.Type(), llvm.Int32Type(), llvm.Int1Type()}
memcpyType := llvm.FunctionType(llvm.VoidType(), paramtypes, false)
memcpy = llvm.AddFunction(c.module.Module, memcpyName, memcpyType)
}
args := []llvm.Value{
dst, src, size,
llvm.ConstInt(llvm.Int32Type(), 1, false), // single byte alignment
llvm.ConstInt(llvm.Int1Type(), 0, false), // not volatile
}
c.builder.CreateCall(memcpy, args, "")
c.builder.CreateRetVoid()
}
示例5: funcLLVMType
func (tm *TypeMap) funcLLVMType(f *types.Func) llvm.Type {
param_types := make([]llvm.Type, 0)
// Add receiver parameter.
if f.Recv != nil {
recv_type := f.Recv.Type.(types.Type)
param_types = append(param_types, tm.ToLLVM(recv_type))
}
for _, param := range f.Params {
param_type := param.Type.(types.Type)
param_types = append(param_types, tm.ToLLVM(param_type))
}
var return_type llvm.Type
switch len(f.Results) {
case 0:
return_type = llvm.VoidType()
case 1:
return_type = tm.ToLLVM(f.Results[0].Type.(types.Type))
default:
elements := make([]llvm.Type, len(f.Results))
for i, result := range f.Results {
elements[i] = tm.ToLLVM(result.Type.(types.Type))
}
return_type = llvm.StructType(elements, false)
}
fn_type := llvm.FunctionType(return_type, param_types, false)
return llvm.PointerType(fn_type, 0)
}
示例6: NewTypeMap
func NewTypeMap(module llvm.Module, target llvm.TargetData, exprTypes map[ast.Expr]types.Type) *TypeMap {
tm := &TypeMap{module: module, target: target, expr: exprTypes}
tm.types = make(map[types.Type]llvm.Type)
tm.runtime = make(map[types.Type]llvm.Value)
// Load "reflect.go", and generate LLVM types for the runtime type
// structures.
pkg, err := parseReflect()
if err != nil {
panic(err) // FIXME return err
}
objToLLVMType := func(name string) llvm.Type {
obj := pkg.Scope.Lookup(name)
return tm.ToLLVM(obj.Type.(types.Type))
}
tm.runtimeCommonType = objToLLVMType("commonType")
tm.runtimeUncommonType = objToLLVMType("uncommonType")
tm.runtimeArrayType = objToLLVMType("arrayType")
tm.runtimeChanType = objToLLVMType("chanType")
tm.runtimeFuncType = objToLLVMType("funcType")
tm.runtimeInterfaceType = objToLLVMType("interfaceType")
tm.runtimeMapType = objToLLVMType("mapType")
tm.runtimePtrType = objToLLVMType("ptrType")
tm.runtimeSliceType = objToLLVMType("sliceType")
tm.runtimeStructType = objToLLVMType("structType")
// Types for algorithms. See 'runtime/runtime.h'.
uintptrType := tm.target.IntPtrType()
voidPtrType := llvm.PointerType(llvm.Int8Type(), 0)
boolType := llvm.Int1Type()
// Create runtime algorithm function types.
params := []llvm.Type{
llvm.PointerType(uintptrType, 0), uintptrType, voidPtrType}
tm.hashAlgFunctionType = llvm.FunctionType(llvm.VoidType(), params, false)
params = []llvm.Type{
llvm.PointerType(boolType, 0), uintptrType, voidPtrType, voidPtrType}
tm.equalAlgFunctionType = llvm.FunctionType(llvm.VoidType(), params, false)
params = []llvm.Type{uintptrType, voidPtrType}
tm.printAlgFunctionType = llvm.FunctionType(llvm.VoidType(), params, false)
params = []llvm.Type{uintptrType, voidPtrType, voidPtrType}
tm.copyAlgFunctionType = llvm.FunctionType(llvm.VoidType(), params, false)
return tm
}
示例7: funcLLVMType
func (tm *LLVMTypeMap) funcLLVMType(tstr string, f *types.Signature) llvm.Type {
typ, ok := tm.types[tstr]
if !ok {
// If there's a receiver change the receiver to an
// additional (first) parameter, and take the value of
// the resulting signature instead.
var param_types []llvm.Type
if recv := f.Recv(); recv != nil {
params := f.Params()
paramvars := make([]*types.Var, int(params.Len()+1))
paramvars[0] = recv
for i := 0; i < int(params.Len()); i++ {
paramvars[i+1] = params.At(i)
}
params = types.NewTuple(paramvars...)
f := types.NewSignature(nil, params, f.Results(), f.IsVariadic())
return tm.ToLLVM(f)
}
typ = llvm.GlobalContext().StructCreateNamed("")
tm.types[tstr] = typ
params := f.Params()
nparams := int(params.Len())
for i := 0; i < nparams; i++ {
typ := params.At(i).Type()
if f.IsVariadic() && i == nparams-1 {
typ = types.NewSlice(typ)
}
llvmtyp := tm.ToLLVM(typ)
param_types = append(param_types, llvmtyp)
}
var return_type llvm.Type
results := f.Results()
switch nresults := int(results.Len()); nresults {
case 0:
return_type = llvm.VoidType()
case 1:
return_type = tm.ToLLVM(results.At(0).Type())
default:
elements := make([]llvm.Type, nresults)
for i := range elements {
result := results.At(i)
elements[i] = tm.ToLLVM(result.Type())
}
return_type = llvm.StructType(elements, false)
}
fntyp := llvm.FunctionType(return_type, param_types, false)
fnptrtyp := llvm.PointerType(fntyp, 0)
i8ptr := llvm.PointerType(llvm.Int8Type(), 0)
elements := []llvm.Type{fnptrtyp, i8ptr} // func, closure
typ.StructSetBody(elements, false)
}
return typ
}
示例8: newAlgorithmMap
func newAlgorithmMap(m llvm.Module, runtime *runtimeInterface, target llvm.TargetData) *algorithmMap {
am := &algorithmMap{
module: m,
runtime: runtime,
}
uintptrType := target.IntPtrType()
voidPtrType := llvm.PointerType(llvm.Int8Type(), 0)
boolType := llvm.Int1Type()
params := []llvm.Type{uintptrType, voidPtrType}
am.hashAlgFunctionType = llvm.FunctionType(uintptrType, params, false)
params = []llvm.Type{uintptrType, uintptrType, uintptrType}
am.equalAlgFunctionType = llvm.FunctionType(boolType, params, false)
params = []llvm.Type{uintptrType, voidPtrType}
am.printAlgFunctionType = llvm.FunctionType(llvm.VoidType(), params, false)
params = []llvm.Type{uintptrType, voidPtrType, voidPtrType}
am.copyAlgFunctionType = llvm.FunctionType(llvm.VoidType(), params, false)
return am
}
示例9: funcLLVMType
func (tm *llvmTypeMap) funcLLVMType(f *types.Signature, name string) llvm.Type {
// If there's a receiver change the receiver to an
// additional (first) parameter, and take the value of
// the resulting signature instead.
if recv := f.Recv(); recv != nil {
params := f.Params()
paramvars := make([]*types.Var, int(params.Len()+1))
paramvars[0] = recv
for i := 0; i < int(params.Len()); i++ {
paramvars[i+1] = params.At(i)
}
params = types.NewTuple(paramvars...)
f := types.NewSignature(nil, nil, params, f.Results(), f.Variadic())
return tm.toLLVM(f, name)
}
if typ, ok := tm.types.At(f).(llvm.Type); ok {
return typ
}
typ := llvm.GlobalContext().StructCreateNamed(name)
tm.types.Set(f, typ)
params := f.Params()
param_types := make([]llvm.Type, params.Len())
for i := range param_types {
llvmtyp := tm.ToLLVM(params.At(i).Type())
param_types[i] = llvmtyp
}
var return_type llvm.Type
results := f.Results()
switch nresults := int(results.Len()); nresults {
case 0:
return_type = llvm.VoidType()
case 1:
return_type = tm.ToLLVM(results.At(0).Type())
default:
elements := make([]llvm.Type, nresults)
for i := range elements {
result := results.At(i)
elements[i] = tm.ToLLVM(result.Type())
}
return_type = llvm.StructType(elements, false)
}
fntyp := llvm.FunctionType(return_type, param_types, false)
fnptrtyp := llvm.PointerType(fntyp, 0)
i8ptr := llvm.PointerType(llvm.Int8Type(), 0)
elements := []llvm.Type{fnptrtyp, i8ptr} // func, closure
typ.StructSetBody(elements, false)
return typ
}
示例10: createMainFunction
func (c *compiler) createMainFunction() error {
// In a PNaCl program (plugin), there should not be a "main.main";
// instead, we expect a "main.CreateModule" function.
// See pkg/nacl/ppapi/ppapi.go for more details.
mainMain := c.module.NamedFunction("main.main")
if c.pnacl {
// PNaCl's libppapi_stub.a implements "main", which simply
// calls through to PpapiPluginMain. We define our own "main"
// so that we can capture argc/argv.
if !mainMain.IsNil() {
return fmt.Errorf("Found main.main")
}
pluginMain := c.NamedFunction("PpapiPluginMain", "func() int32")
// Synthesise a main which has no return value. We could cast
// PpapiPluginMain, but this is potentially unsafe as its
// calling convention is unspecified.
ftyp := llvm.FunctionType(llvm.VoidType(), nil, false)
mainMain = llvm.AddFunction(c.module.Module, "main.main", ftyp)
entry := llvm.AddBasicBlock(mainMain, "entry")
c.builder.SetInsertPointAtEnd(entry)
c.builder.CreateCall(pluginMain, nil, "")
c.builder.CreateRetVoid()
} else {
mainMain = c.module.NamedFunction("main.main")
}
if mainMain.IsNil() {
return fmt.Errorf("Could not find main.main")
}
// runtime.main is called by main, with argc, argv, argp,
// and a pointer to main.main, which must be a niladic
// function with no result.
runtimeMain := c.NamedFunction("runtime.main", "func(int32, **byte, **byte, *int8) int32")
main := c.NamedFunction("main", "func(int32, **byte, **byte) int32")
c.builder.SetCurrentDebugLocation(c.debug_info.MDNode(nil))
entry := llvm.AddBasicBlock(main, "entry")
c.builder.SetInsertPointAtEnd(entry)
mainMain = c.builder.CreateBitCast(mainMain, runtimeMain.Type().ElementType().ParamTypes()[3], "")
args := []llvm.Value{main.Param(0), main.Param(1), main.Param(2), mainMain}
result := c.builder.CreateCall(runtimeMain, args, "")
c.builder.CreateRet(result)
return nil
}
示例11: indirectFunction
// indirectFunction creates an indirect function from a
// given function, suitable for use with "defer" and "go".
func (c *compiler) indirectFunction(fn *LLVMValue, args []Value, dotdotdot bool) *LLVMValue {
nilarytyp := &types.Signature{}
if len(args) == 0 {
val := fn.LLVMValue()
ptr := c.builder.CreateExtractValue(val, 0, "")
ctx := c.builder.CreateExtractValue(val, 1, "")
fnval := llvm.Undef(c.types.ToLLVM(nilarytyp))
ptr = c.builder.CreateBitCast(ptr, fnval.Type().StructElementTypes()[0], "")
ctx = c.builder.CreateBitCast(ctx, fnval.Type().StructElementTypes()[1], "")
fnval = c.builder.CreateInsertValue(fnval, ptr, 0, "")
fnval = c.builder.CreateInsertValue(fnval, ctx, 1, "")
fn = c.NewValue(fnval, nilarytyp)
return fn
}
// TODO check if function pointer is global. I suppose
// the same can be done with the context ptr...
fnval := fn.LLVMValue()
fnptr := c.builder.CreateExtractValue(fnval, 0, "")
ctx := c.builder.CreateExtractValue(fnval, 1, "")
nctx := 1 // fnptr
if !ctx.IsNull() {
nctx++ // fnctx
}
i8ptr := llvm.PointerType(llvm.Int8Type(), 0)
llvmargs := make([]llvm.Value, len(args)+nctx)
llvmargtypes := make([]llvm.Type, len(args)+nctx)
for i, arg := range args {
llvmargs[i+nctx] = arg.LLVMValue()
llvmargtypes[i+nctx] = llvmargs[i+nctx].Type()
}
llvmargtypes[0] = fnptr.Type()
llvmargs[0] = fnptr
if nctx > 1 {
llvmargtypes[1] = ctx.Type()
llvmargs[1] = ctx
}
structtyp := llvm.StructType(llvmargtypes, false)
argstruct := c.createTypeMalloc(structtyp)
for i, llvmarg := range llvmargs {
argptr := c.builder.CreateGEP(argstruct, []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), 0, false),
llvm.ConstInt(llvm.Int32Type(), uint64(i), false)}, "")
c.builder.CreateStore(llvmarg, argptr)
}
// Create a function that will take a pointer to a structure of the type
// defined above, or no parameters if there are none to pass.
fntype := llvm.FunctionType(llvm.VoidType(), []llvm.Type{argstruct.Type()}, false)
indirectfn := llvm.AddFunction(c.module.Module, "", fntype)
i8argstruct := c.builder.CreateBitCast(argstruct, i8ptr, "")
currblock := c.builder.GetInsertBlock()
c.builder.SetInsertPointAtEnd(llvm.AddBasicBlock(indirectfn, "entry"))
argstruct = indirectfn.Param(0)
for i := range llvmargs[nctx:] {
argptr := c.builder.CreateGEP(argstruct, []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), 0, false),
llvm.ConstInt(llvm.Int32Type(), uint64(i+nctx), false)}, "")
ptrtyp := types.NewPointer(args[i].Type())
args[i] = c.NewValue(argptr, ptrtyp).makePointee()
}
// Extract the function pointer.
// TODO if function is a global, elide.
fnval = llvm.Undef(fnval.Type())
fnptrptr := c.builder.CreateGEP(argstruct, []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), 0, false),
llvm.ConstInt(llvm.Int32Type(), 0, false)}, "")
fnptr = c.builder.CreateLoad(fnptrptr, "")
fnval = c.builder.CreateInsertValue(fnval, fnptr, 0, "")
if nctx > 1 {
ctxptr := c.builder.CreateGEP(argstruct, []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), 0, false),
llvm.ConstInt(llvm.Int32Type(), 1, false)}, "")
ctx = c.builder.CreateLoad(ctxptr, "")
fnval = c.builder.CreateInsertValue(fnval, ctx, 1, "")
fn = c.NewValue(fnval, fn.Type())
}
c.createCall(fn, args, dotdotdot, false)
// Indirect function calls' return values are always ignored.
c.builder.CreateRetVoid()
c.builder.SetInsertPointAtEnd(currblock)
fnval = llvm.Undef(c.types.ToLLVM(nilarytyp))
indirectfn = c.builder.CreateBitCast(indirectfn, fnval.Type().StructElementTypes()[0], "")
fnval = c.builder.CreateInsertValue(fnval, indirectfn, 0, "")
fnval = c.builder.CreateInsertValue(fnval, i8argstruct, 1, "")
fn = c.NewValue(fnval, nilarytyp)
return fn
}
示例12: VisitGoStmt
func (c *compiler) VisitGoStmt(stmt *ast.GoStmt) {
//stmt.Call *ast.CallExpr
// TODO
var fn *LLVMValue
switch x := (stmt.Call.Fun).(type) {
case *ast.Ident:
fn = c.Resolve(x.Obj).(*LLVMValue)
if fn == nil {
panic(fmt.Sprintf(
"No function found with name '%s'", x.String()))
}
default:
fn = c.VisitExpr(stmt.Call.Fun).(*LLVMValue)
}
// Evaluate arguments, store in a structure on the stack.
var args_struct_type llvm.Type
var args_mem llvm.Value
var args_size llvm.Value
if stmt.Call.Args != nil {
param_types := make([]llvm.Type, 0)
fn_type := types.Deref(fn.Type()).(*types.Func)
for _, param := range fn_type.Params {
typ := param.Type.(types.Type)
param_types = append(param_types, c.types.ToLLVM(typ))
}
args_struct_type = llvm.StructType(param_types, false)
args_mem = c.builder.CreateAlloca(args_struct_type, "")
for i, expr := range stmt.Call.Args {
value_i := c.VisitExpr(expr)
value_i = value_i.Convert(fn_type.Params[i].Type.(types.Type))
arg_i := c.builder.CreateGEP(args_mem, []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), 0, false),
llvm.ConstInt(llvm.Int32Type(), uint64(i), false)}, "")
c.builder.CreateStore(value_i.LLVMValue(), arg_i)
}
args_size = llvm.SizeOf(args_struct_type)
args_size = llvm.ConstTrunc(args_size, llvm.Int32Type())
} else {
args_struct_type = llvm.VoidType()
args_mem = llvm.ConstNull(llvm.PointerType(args_struct_type, 0))
args_size = llvm.ConstInt(llvm.Int32Type(), 0, false)
}
// When done, return to where we were.
defer c.builder.SetInsertPointAtEnd(c.builder.GetInsertBlock())
// Create a function that will take a pointer to a structure of the type
// defined above, or no parameters if there are none to pass.
indirect_fn_type := llvm.FunctionType(
llvm.VoidType(),
[]llvm.Type{llvm.PointerType(args_struct_type, 0)}, false)
indirect_fn := llvm.AddFunction(c.module.Module, "", indirect_fn_type)
indirect_fn.SetFunctionCallConv(llvm.CCallConv)
// Call "newgoroutine" with the indirect function and stored args.
newgoroutine := getnewgoroutine(c.module.Module)
ngr_param_types := newgoroutine.Type().ElementType().ParamTypes()
fn_arg := c.builder.CreateBitCast(indirect_fn, ngr_param_types[0], "")
args_arg := c.builder.CreateBitCast(args_mem,
llvm.PointerType(llvm.Int8Type(), 0), "")
c.builder.CreateCall(newgoroutine,
[]llvm.Value{fn_arg, args_arg, args_size}, "")
entry := llvm.AddBasicBlock(indirect_fn, "entry")
c.builder.SetInsertPointAtEnd(entry)
var args []llvm.Value
if stmt.Call.Args != nil {
args_mem = indirect_fn.Param(0)
args = make([]llvm.Value, len(stmt.Call.Args))
for i := range stmt.Call.Args {
arg_i := c.builder.CreateGEP(args_mem, []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), 0, false),
llvm.ConstInt(llvm.Int32Type(), uint64(i), false)}, "")
args[i] = c.builder.CreateLoad(arg_i, "")
}
}
c.builder.CreateCall(fn.LLVMValue(), args, "")
c.builder.CreateRetVoid()
}
示例13: Compile
func (compiler *compiler) Compile(fset *token.FileSet,
pkg *ast.Package,
exprTypes map[ast.Expr]types.Type) (m *Module, err error) {
// FIXME create a compilation state, rather than storing in 'compiler'.
compiler.fileset = fset
compiler.pkg = pkg
compiler.initfuncs = make([]Value, 0)
// Create a Builder, for building LLVM instructions.
compiler.builder = llvm.GlobalContext().NewBuilder()
defer compiler.builder.Dispose()
// Create a TargetMachine from the OS & Arch.
triple := fmt.Sprintf("%s-unknown-%s",
getTripleArchName(compiler.targetArch),
compiler.targetOs)
var machine llvm.TargetMachine
for target := llvm.FirstTarget(); target.C != nil && machine.C == nil; target = target.NextTarget() {
if target.Name() == compiler.targetArch {
machine = target.CreateTargetMachine(triple, "", "",
llvm.CodeGenLevelDefault,
llvm.RelocDefault,
llvm.CodeModelDefault)
defer machine.Dispose()
}
}
if machine.C == nil {
err = fmt.Errorf("Invalid target triple: %s", triple)
return
}
// Create a Module, which contains the LLVM bitcode. Dispose it on panic,
// otherwise we'll set a finalizer at the end. The caller may invoke
// Dispose manually, which will render the finalizer a no-op.
modulename := pkg.Name
compiler.target = machine.TargetData()
compiler.module = &Module{llvm.NewModule(modulename), modulename, false}
compiler.module.SetTarget(triple)
compiler.module.SetDataLayout(compiler.target.String())
defer func() {
if e := recover(); e != nil {
compiler.module.Dispose()
panic(e)
//err = e.(error)
}
}()
compiler.types = NewTypeMap(compiler.module.Module, compiler.target, exprTypes)
// Create a mapping from objects back to packages, so we can create the
// appropriate symbol names.
compiler.pkgmap = createPackageMap(pkg)
// Compile each file in the package.
for _, file := range pkg.Files {
file.Scope.Outer = pkg.Scope
compiler.filescope = file.Scope
compiler.scope = file.Scope
compiler.fixConstDecls(file)
for _, decl := range file.Decls {
compiler.VisitDecl(decl)
}
}
// Define intrinsics for use by the runtime: malloc, free, memcpy, etc.
compiler.defineRuntimeIntrinsics()
// Create global constructors.
//
// XXX When imports are handled, we'll need to defer creating
// llvm.global_ctors until we create an executable. This is
// due to (a) imports having to be initialised before the
// importer, and (b) LLVM having no specified order of
// initialisation for ctors with the same priority.
if len(compiler.initfuncs) > 0 {
elttypes := []llvm.Type{
llvm.Int32Type(),
llvm.PointerType(
llvm.FunctionType(llvm.VoidType(), nil, false), 0)}
ctortype := llvm.StructType(elttypes, false)
ctors := make([]llvm.Value, len(compiler.initfuncs))
for i, fn := range compiler.initfuncs {
struct_values := []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), 1, false),
fn.LLVMValue()}
ctors[i] = llvm.ConstStruct(struct_values, false)
}
global_ctors_init := llvm.ConstArray(ctortype, ctors)
global_ctors_var := llvm.AddGlobal(
compiler.module.Module, global_ctors_init.Type(),
"llvm.global_ctors")
global_ctors_var.SetInitializer(global_ctors_init)
global_ctors_var.SetLinkage(llvm.AppendingLinkage)
}
// Create debug metadata.
compiler.createMetadata()
return compiler.module, nil
//.........這裏部分代碼省略.........
示例14: indirectFunction
// indirectFunction creates an indirect function from a
// given function and arguments, suitable for use with
// "defer" and "go".
func (c *compiler) indirectFunction(fn *LLVMValue, args []*LLVMValue) *LLVMValue {
nilarytyp := types.NewSignature(nil, nil, nil, nil, false)
if len(args) == 0 {
val := fn.LLVMValue()
ptr := c.builder.CreateExtractValue(val, 0, "")
ctx := c.builder.CreateExtractValue(val, 1, "")
fnval := llvm.Undef(c.types.ToLLVM(nilarytyp))
ptr = c.builder.CreateBitCast(ptr, fnval.Type().StructElementTypes()[0], "")
ctx = c.builder.CreateBitCast(ctx, fnval.Type().StructElementTypes()[1], "")
fnval = c.builder.CreateInsertValue(fnval, ptr, 0, "")
fnval = c.builder.CreateInsertValue(fnval, ctx, 1, "")
return c.NewValue(fnval, nilarytyp)
}
// Check if function pointer or context pointer is global/null.
fnval := fn.LLVMValue()
fnptr := fnval
var nctx int
var fnctx llvm.Value
var fnctxindex uint64
var globalfn bool
if fnptr.Type().TypeKind() == llvm.StructTypeKind {
fnptr = c.builder.CreateExtractValue(fnval, 0, "")
fnctx = c.builder.CreateExtractValue(fnval, 1, "")
globalfn = !fnptr.IsAFunction().IsNil()
if !globalfn {
nctx++
}
if !fnctx.IsNull() {
fnctxindex = uint64(nctx)
nctx++
}
} else {
// We've got a raw global function pointer. Convert to <ptr,ctx>.
fnval = llvm.ConstNull(c.types.ToLLVM(fn.Type()))
fnval = llvm.ConstInsertValue(fnval, fnptr, []uint32{0})
fn = c.NewValue(fnval, fn.Type())
fnctx = llvm.ConstExtractValue(fnval, []uint32{1})
globalfn = true
}
i8ptr := llvm.PointerType(llvm.Int8Type(), 0)
llvmargs := make([]llvm.Value, len(args)+nctx)
llvmargtypes := make([]llvm.Type, len(args)+nctx)
for i, arg := range args {
llvmargs[i+nctx] = arg.LLVMValue()
llvmargtypes[i+nctx] = llvmargs[i+nctx].Type()
}
if !globalfn {
llvmargtypes[0] = fnptr.Type()
llvmargs[0] = fnptr
}
if !fnctx.IsNull() {
llvmargtypes[fnctxindex] = fnctx.Type()
llvmargs[fnctxindex] = fnctx
}
// TODO(axw) investigate an option for go statements
// to allocate argument structure on the stack in the
// initiator, and block until the spawned goroutine
// has loaded the arguments from it.
structtyp := llvm.StructType(llvmargtypes, false)
argstruct := c.createTypeMalloc(structtyp)
for i, llvmarg := range llvmargs {
argptr := c.builder.CreateGEP(argstruct, []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), 0, false),
llvm.ConstInt(llvm.Int32Type(), uint64(i), false)}, "")
c.builder.CreateStore(llvmarg, argptr)
}
// Create a function that will take a pointer to a structure of the type
// defined above, or no parameters if there are none to pass.
fntype := llvm.FunctionType(llvm.VoidType(), []llvm.Type{argstruct.Type()}, false)
indirectfn := llvm.AddFunction(c.module.Module, "", fntype)
i8argstruct := c.builder.CreateBitCast(argstruct, i8ptr, "")
currblock := c.builder.GetInsertBlock()
c.builder.SetInsertPointAtEnd(llvm.AddBasicBlock(indirectfn, "entry"))
argstruct = indirectfn.Param(0)
newargs := make([]*LLVMValue, len(args))
for i := range llvmargs[nctx:] {
argptr := c.builder.CreateGEP(argstruct, []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), 0, false),
llvm.ConstInt(llvm.Int32Type(), uint64(i+nctx), false)}, "")
newargs[i] = c.NewValue(c.builder.CreateLoad(argptr, ""), args[i].Type())
}
// Unless we've got a global function, extract the
// function pointer from the context.
if !globalfn {
fnval = llvm.Undef(fnval.Type())
fnptrptr := c.builder.CreateGEP(argstruct, []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), 0, false),
llvm.ConstInt(llvm.Int32Type(), 0, false)}, "")
fnptr = c.builder.CreateLoad(fnptrptr, "")
fnval = c.builder.CreateInsertValue(fnval, fnptr, 0, "")
}
if !fnctx.IsNull() {
//.........這裏部分代碼省略.........
示例15: Compile
func (compiler *compiler) Compile(fset *token.FileSet,
pkg *ast.Package, importpath string,
exprTypes map[ast.Expr]types.Type) (m *Module, err error) {
// FIXME create a compilation state, rather than storing in 'compiler'.
compiler.fileset = fset
compiler.pkg = pkg
compiler.importpath = importpath
compiler.initfuncs = nil
compiler.varinitfuncs = nil
// Create a Builder, for building LLVM instructions.
compiler.builder = llvm.GlobalContext().NewBuilder()
defer compiler.builder.Dispose()
// Create a TargetMachine from the OS & Arch.
triple := compiler.GetTargetTriple()
var machine llvm.TargetMachine
for target := llvm.FirstTarget(); target.C != nil && machine.C == nil; target = target.NextTarget() {
if target.Name() == compiler.targetArch {
machine = target.CreateTargetMachine(triple, "", "",
llvm.CodeGenLevelDefault,
llvm.RelocDefault,
llvm.CodeModelDefault)
defer machine.Dispose()
}
}
if machine.C == nil {
err = fmt.Errorf("Invalid target triple: %s", triple)
return
}
// Create a Module, which contains the LLVM bitcode. Dispose it on panic,
// otherwise we'll set a finalizer at the end. The caller may invoke
// Dispose manually, which will render the finalizer a no-op.
modulename := pkg.Name
compiler.target = machine.TargetData()
compiler.module = &Module{llvm.NewModule(modulename), modulename, false}
compiler.module.SetTarget(triple)
compiler.module.SetDataLayout(compiler.target.String())
defer func() {
if e := recover(); e != nil {
compiler.module.Dispose()
panic(e)
//err = e.(error)
}
}()
// Create a mapping from objects back to packages, so we can create the
// appropriate symbol names.
compiler.pkgmap = createPackageMap(pkg, importpath)
// Create a struct responsible for mapping static types to LLVM types,
// and to runtime/dynamic type values.
var resolver Resolver = compiler
llvmtypemap := NewLLVMTypeMap(compiler.module.Module, compiler.target)
compiler.FunctionCache = NewFunctionCache(compiler)
compiler.types = NewTypeMap(llvmtypemap, importpath, exprTypes, compiler.FunctionCache, compiler.pkgmap, resolver)
// Compile each file in the package.
for _, file := range pkg.Files {
file.Scope.Outer = pkg.Scope
compiler.filescope = file.Scope
compiler.scope = file.Scope
compiler.fixConstDecls(file)
for _, decl := range file.Decls {
compiler.VisitDecl(decl)
}
}
// Define intrinsics for use by the runtime: malloc, free, memcpy, etc.
// These could be defined in LLVM IR, and may be moved there later.
if pkg.Name == "runtime" {
compiler.defineRuntimeIntrinsics()
}
// Export runtime type information.
if pkg.Name == "runtime" {
compiler.exportBuiltinRuntimeTypes()
}
// Create global constructors.
//
// XXX When imports are handled, we'll need to defer creating
// llvm.global_ctors until we create an executable. This is
// due to (a) imports having to be initialised before the
// importer, and (b) LLVM having no specified order of
// initialisation for ctors with the same priority.
var initfuncs [][]Value
if compiler.varinitfuncs != nil {
initfuncs = append(initfuncs, compiler.varinitfuncs)
}
if compiler.initfuncs != nil {
initfuncs = append(initfuncs, compiler.initfuncs)
}
if initfuncs != nil {
elttypes := []llvm.Type{llvm.Int32Type(), llvm.PointerType(llvm.FunctionType(llvm.VoidType(), nil, false), 0)}
ctortype := llvm.StructType(elttypes, false)
var ctors []llvm.Value
var priority uint64
//.........這裏部分代碼省略.........