mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
[LLVM-C] Improve Intrinsics Bindings
Summary: Improve the intrinsic bindings with operations for - Retrieving and automatically inserting the declaration of an intrinsic by ID - Retrieving the name of a non-overloaded intrinsic by ID - Retrieving the name of an overloaded intrinsic by ID and overloaded parameter types Improve the echo test to copy non-overloaded intrinsics by ID. Reviewers: whitequark, deadalnix Reviewed By: whitequark Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D53626 llvm-svn: 346195
This commit is contained in:
parent
cad75e30da
commit
5eb209277e
@ -2381,6 +2381,54 @@ void LLVMSetPersonalityFn(LLVMValueRef Fn, LLVMValueRef PersonalityFn);
|
||||
*/
|
||||
unsigned LLVMGetIntrinsicID(LLVMValueRef Fn);
|
||||
|
||||
/**
|
||||
* 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()
|
||||
*/
|
||||
LLVMValueRef LLVMGetIntrinsicDeclaration(LLVMModuleRef Mod,
|
||||
unsigned ID,
|
||||
LLVMTypeRef *ParamTypes,
|
||||
size_t ParamCount);
|
||||
|
||||
/**
|
||||
* Retrieves the type of an intrinsic. For overloaded intrinsics, parameter
|
||||
* types must be provided to uniquely identify an overload.
|
||||
*
|
||||
* @see llvm::Intrinsic::getType()
|
||||
*/
|
||||
LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
|
||||
LLVMTypeRef *ParamTypes, size_t ParamCount);
|
||||
|
||||
/**
|
||||
* Retrieves the name of an intrinsic.
|
||||
*
|
||||
* @see llvm::Intrinsic::getName()
|
||||
*/
|
||||
const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength);
|
||||
|
||||
/**
|
||||
* Copies the name of an overloaded intrinsic identified by a given list of
|
||||
* parameter types.
|
||||
*
|
||||
* Unlike LLVMIntrinsicGetName, the caller is responsible for freeing the
|
||||
* returned string.
|
||||
*
|
||||
* @see llvm::Intrinsic::getName()
|
||||
*/
|
||||
const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
|
||||
LLVMTypeRef *ParamTypes,
|
||||
size_t ParamCount,
|
||||
size_t *NameLength);
|
||||
|
||||
/**
|
||||
* Obtain if the intrinsic identified by the given ID is overloaded.
|
||||
*
|
||||
* @see llvm::Intrinsic::isOverloaded()
|
||||
*/
|
||||
LLVMBool LLVMIntrinsicIsOverloaded(unsigned ID);
|
||||
|
||||
/**
|
||||
* Obtain the calling function of a function.
|
||||
*
|
||||
|
@ -2280,6 +2280,50 @@ unsigned LLVMGetIntrinsicID(LLVMValueRef Fn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Intrinsic::ID llvm_map_to_intrinsic_id(unsigned ID) {
|
||||
assert(ID < llvm::Intrinsic::num_intrinsics && "Intrinsic ID out of range");
|
||||
return llvm::Intrinsic::ID(ID);
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMGetIntrinsicDeclaration(LLVMModuleRef Mod,
|
||||
unsigned ID,
|
||||
LLVMTypeRef *ParamTypes,
|
||||
size_t ParamCount) {
|
||||
ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
|
||||
auto IID = llvm_map_to_intrinsic_id(ID);
|
||||
return wrap(llvm::Intrinsic::getDeclaration(unwrap(Mod), IID, Tys));
|
||||
}
|
||||
|
||||
const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength) {
|
||||
auto IID = llvm_map_to_intrinsic_id(ID);
|
||||
auto Str = llvm::Intrinsic::getName(IID);
|
||||
*NameLength = Str.size();
|
||||
return Str.data();
|
||||
}
|
||||
|
||||
LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
|
||||
LLVMTypeRef *ParamTypes, size_t ParamCount) {
|
||||
auto IID = llvm_map_to_intrinsic_id(ID);
|
||||
ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
|
||||
return wrap(llvm::Intrinsic::getType(*unwrap(Ctx), IID, Tys));
|
||||
}
|
||||
|
||||
const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
|
||||
LLVMTypeRef *ParamTypes,
|
||||
size_t ParamCount,
|
||||
size_t *NameLength) {
|
||||
auto IID = llvm_map_to_intrinsic_id(ID);
|
||||
ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
|
||||
auto Str = llvm::Intrinsic::getName(IID, Tys);
|
||||
*NameLength = Str.length();
|
||||
return strndup(Str.c_str(), Str.length());
|
||||
}
|
||||
|
||||
LLVMBool LLVMIntrinsicIsOverloaded(unsigned ID) {
|
||||
auto IID = llvm_map_to_intrinsic_id(ID);
|
||||
return llvm::Intrinsic::isOverloaded(IID);
|
||||
}
|
||||
|
||||
unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn) {
|
||||
return unwrap<Function>(Fn)->getCallingConv();
|
||||
}
|
||||
|
@ -170,6 +170,22 @@ define void @with_debuginfo() !dbg !4 {
|
||||
ret void, !dbg !7
|
||||
}
|
||||
|
||||
declare i8* @llvm.stacksave()
|
||||
declare void @llvm.stackrestore(i8*)
|
||||
declare void @llvm.lifetime.start.p0i8(i64, i8*)
|
||||
declare void @llvm.lifetime.end.p0i8(i64, i8*)
|
||||
|
||||
define void @test_intrinsics() {
|
||||
entry:
|
||||
%sp = call i8* @llvm.stacksave()
|
||||
%x = alloca i32
|
||||
%0 = bitcast i32* %x to i8*
|
||||
call void @llvm.lifetime.start.p0i8(i64 4, i8* %0)
|
||||
call void @llvm.lifetime.end.p0i8(i64 4, i8* %0)
|
||||
call void @llvm.stackrestore(i8* %sp)
|
||||
ret void
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!0, !2}
|
||||
!llvm.module.flags = !{!3}
|
||||
|
||||
|
@ -240,7 +240,17 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) {
|
||||
// Try function
|
||||
if (LLVMIsAFunction(Cst)) {
|
||||
check_value_kind(Cst, LLVMFunctionValueKind);
|
||||
LLVMValueRef Dst = LLVMGetNamedFunction(M, Name);
|
||||
|
||||
LLVMValueRef Dst = nullptr;
|
||||
// Try an intrinsic
|
||||
unsigned ID = LLVMGetIntrinsicID(Cst);
|
||||
if (ID > 0 && !LLVMIntrinsicIsOverloaded(ID)) {
|
||||
Dst = LLVMGetIntrinsicDeclaration(M, ID, nullptr, 0);
|
||||
} else {
|
||||
// Try a normal function
|
||||
Dst = LLVMGetNamedFunction(M, Name);
|
||||
}
|
||||
|
||||
if (Dst)
|
||||
return Dst;
|
||||
report_fatal_error("Could not find function");
|
||||
|
Loading…
Reference in New Issue
Block a user