From 317894b6e7b8acfe7d32e7bfd3a75f0fc9e8319e Mon Sep 17 00:00:00 2001 From: alperenunal <alpernunl@gmail.com> Date: Tue, 27 Dec 2022 00:10:36 +0300 Subject: [PATCH 1/2] Add LLVM intrinsic funtions --- ir.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/ir.go b/ir.go index 25631d3..7bd0e22 100644 --- a/ir.go +++ b/ir.go @@ -1180,6 +1180,40 @@ func (v Value) AddTargetDependentFunctionAttr(attr, value string) { func (v Value) SetPersonality(p Value) { C.LLVMSetPersonalityFn(v.C, p.C) } +func IntrinsicID(name string) (id uint) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + id = uint(C.LLVMLookupIntrinsicID(cname, C.size_t(len(name)))) + return +} +func IsIntrinsicOverloaded(id uint) bool { + return C.LLVMIntrinsicIsOverloaded(C.unsigned(id)) != 0 +} +func IntrinsicName(id uint) string { + length := C.size_t(0) + cname := C.LLVMIntrinsicGetName(C.unsigned(id), &length) + return C.GoStringN(cname, C.int(length)) +} +func (c Context) IntrinsicType(id uint, paramTypes []Type) (t Type) { + t.C = C.LLVMIntrinsicGetType(c.C, C.unsigned(id), llvmTypeRefPtr(¶mTypes[0]), C.size_t(len(paramTypes))) + return +} +func (c Module) InsertIntrinsic(id uint, paramTypes []Type) (v Value) { + var pt *C.LLVMTypeRef + if paramTypes == nil { + pt = nil + } else { + pt = llvmTypeRefPtr(¶mTypes[0]) + } + v.C = C.LLVMGetIntrinsicDeclaration(c.C, C.unsigned(id), pt, C.size_t(len(paramTypes))) + return +} +func (c Module) CopyOverloadedName(id uint, paramTypes []Type) string { + lenght := C.size_t(0) + cname := C.LLVMIntrinsicCopyOverloadedName2(c.C, C.unsigned(id), llvmTypeRefPtr(¶mTypes[0]), C.size_t(len(paramTypes)), &lenght) + defer C.free(unsafe.Pointer(cname)) + return C.GoStringN(cname, C.int(lenght)) +} // Operations on parameters func (v Value) ParamsCount() int { return int(C.LLVMCountParams(v.C)) } From 1044c105e209acfde3a6a086487203ecb60389c4 Mon Sep 17 00:00:00 2001 From: alperenunal <alpernunl@gmail.com> Date: Thu, 12 Jan 2023 14:43:59 +0300 Subject: [PATCH 2/2] Add LLVM intrinsic functions --- ir.go | 97 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 34 deletions(-) diff --git a/ir.go b/ir.go index 7bd0e22..13e7771 100644 --- a/ir.go +++ b/ir.go @@ -76,6 +76,7 @@ type ( FloatPredicate C.LLVMRealPredicate LandingPadClause C.LLVMLandingPadClauseTy InlineAsmDialect C.LLVMInlineAsmDialect + Intrinsic C.unsigned ) func (c Context) IsNil() bool { return c.C == nil } @@ -1180,40 +1181,6 @@ func (v Value) AddTargetDependentFunctionAttr(attr, value string) { func (v Value) SetPersonality(p Value) { C.LLVMSetPersonalityFn(v.C, p.C) } -func IntrinsicID(name string) (id uint) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - id = uint(C.LLVMLookupIntrinsicID(cname, C.size_t(len(name)))) - return -} -func IsIntrinsicOverloaded(id uint) bool { - return C.LLVMIntrinsicIsOverloaded(C.unsigned(id)) != 0 -} -func IntrinsicName(id uint) string { - length := C.size_t(0) - cname := C.LLVMIntrinsicGetName(C.unsigned(id), &length) - return C.GoStringN(cname, C.int(length)) -} -func (c Context) IntrinsicType(id uint, paramTypes []Type) (t Type) { - t.C = C.LLVMIntrinsicGetType(c.C, C.unsigned(id), llvmTypeRefPtr(¶mTypes[0]), C.size_t(len(paramTypes))) - return -} -func (c Module) InsertIntrinsic(id uint, paramTypes []Type) (v Value) { - var pt *C.LLVMTypeRef - if paramTypes == nil { - pt = nil - } else { - pt = llvmTypeRefPtr(¶mTypes[0]) - } - v.C = C.LLVMGetIntrinsicDeclaration(c.C, C.unsigned(id), pt, C.size_t(len(paramTypes))) - return -} -func (c Module) CopyOverloadedName(id uint, paramTypes []Type) string { - lenght := C.size_t(0) - cname := C.LLVMIntrinsicCopyOverloadedName2(c.C, C.unsigned(id), llvmTypeRefPtr(¶mTypes[0]), C.size_t(len(paramTypes)), &lenght) - defer C.free(unsafe.Pointer(cname)) - return C.GoStringN(cname, C.int(lenght)) -} // Operations on parameters func (v Value) ParamsCount() int { return int(C.LLVMCountParams(v.C)) } @@ -2060,3 +2027,65 @@ func (pm PassManager) FinalizeFunc() bool { return C.LLVMFinalizeFunctionPassMan // the module provider. // See llvm::PassManagerBase::~PassManagerBase. func (pm PassManager) Dispose() { C.LLVMDisposePassManager(pm.C) } + +//------------------------------------------------------------------------- +// llvm.Intrinsic +//------------------------------------------------------------------------- + +// Obtain the intrinsic ID number which matches the given function name. +// See llvm::Function::lookupIntrinsicID. +func IntrinsicID(name string) (in Intrinsic) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + in = Intrinsic(C.LLVMLookupIntrinsicID(cname, C.size_t(len(name)))) + return +} + +// Obtain if the intrinsic identified by the given ID is overloaded. +// See llvm::Intrinsic::isOverloaded +func (in Intrinsic) IsOverloaded() bool { + return C.LLVMIntrinsicIsOverloaded(C.unsigned(in)) != 0 +} + +// Retrieves the name of an intrinsic. +// See llvm::Intrinsic::getName +func (in Intrinsic) GetName() string { + length := C.size_t(0) + cname := C.LLVMIntrinsicGetName(C.unsigned(in), &length) + return C.GoStringN(cname, C.int(length)) +} + +// Retrieves the type of an intrinsic. For overloaded intrinsics, parameter types must be provided to uniquely identify an overload. +// See llvm::Intrinsic::getType +func (c Context) GetIntrinsicType(in Intrinsic, paramTypes []Type) (t Type) { + var pt *C.LLVMTypeRef + if paramTypes != nil { + pt = llvmTypeRefPtr(¶mTypes[0]) + } + t.C = C.LLVMIntrinsicGetType(c.C, C.unsigned(in), pt, C.size_t(len(paramTypes))) + return +} + +// Create or insert the declaration of an intrinsic. For overloaded intrinsics, parameter types must be provided to uniquely identify an overload. +// See llvm::Intrinsic::getDeclaration +func (m Module) GetIntrinsic(in Intrinsic, paramTypes []Type) (v Value) { + var pt *C.LLVMTypeRef + if paramTypes != nil { + pt = llvmTypeRefPtr(¶mTypes[0]) + } + v.C = C.LLVMGetIntrinsicDeclaration(m.C, C.unsigned(in), pt, C.size_t(len(paramTypes))) + return +} + +// Copies the name of an overloaded intrinsic identified by a given list of parameter types. +// See llvm::Intrinsic::getName +func (m Module) CopyOverloadedName(in Intrinsic, paramTypes []Type) string { + var pt *C.LLVMTypeRef + if paramTypes != nil { + pt = llvmTypeRefPtr(¶mTypes[0]) + } + lenght := C.size_t(0) + cname := C.LLVMIntrinsicCopyOverloadedName2(m.C, C.unsigned(in), pt, C.size_t(len(paramTypes)), &lenght) + defer C.free(unsafe.Pointer(cname)) + return C.GoStringN(cname, C.int(lenght)) +}