Skip to content

[mlir][llvmir] expose Type(To/From)LLVMIRTranslator C API #124864

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions mlir/include/mlir-c/Dialect/LLVM.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ MLIR_CAPI_EXPORTED intptr_t mlirLLVMFunctionTypeGetNumInputs(MlirType type);
MLIR_CAPI_EXPORTED MlirType mlirLLVMFunctionTypeGetInput(MlirType type,
intptr_t pos);

/// Returns the return type of the function type.
MLIR_CAPI_EXPORTED MlirType mlirLLVMFunctionTypeGetReturnType(MlirType type);

/// Returns `true` if the type is an LLVM dialect struct type.
MLIR_CAPI_EXPORTED bool mlirTypeIsALLVMStructType(MlirType type);

Expand Down
43 changes: 43 additions & 0 deletions mlir/include/mlir-c/Target/LLVMIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "mlir-c/IR.h"
#include "mlir-c/Support.h"
#include "llvm-c/Core.h"
#include "llvm-c/Support.h"

#ifdef __cplusplus
Expand All @@ -32,6 +33,48 @@ extern "C" {
MLIR_CAPI_EXPORTED LLVMModuleRef
mlirTranslateModuleToLLVMIR(MlirOperation module, LLVMContextRef context);

struct MlirTypeFromLLVMIRTranslator {
void *ptr;
};

typedef struct MlirTypeFromLLVMIRTranslator MlirTypeFromLLVMIRTranslator;

/// Create an LLVM::TypeFromLLVMIRTranslator and transfer ownership to the
/// caller.
MLIR_CAPI_EXPORTED MlirTypeFromLLVMIRTranslator
mlirTypeFromLLVMIRTranslatorCreate(MlirContext ctx);

/// Takes an LLVM::TypeFromLLVMIRTranslator owned by the caller and destroys it.
/// It is the responsibility of the user to only pass an
/// LLVM::TypeFromLLVMIRTranslator class.
MLIR_CAPI_EXPORTED void
mlirTypeFromLLVMIRTranslatorDestroy(MlirTypeFromLLVMIRTranslator translator);

/// Translates the given LLVM IR type to the MLIR LLVM dialect.
MLIR_CAPI_EXPORTED MlirType mlirTypeFromLLVMIRTranslatorTranslateType(
MlirTypeFromLLVMIRTranslator translator, LLVMTypeRef llvmType);

struct MlirTypeToLLVMIRTranslator {
void *ptr;
};

typedef struct MlirTypeToLLVMIRTranslator MlirTypeToLLVMIRTranslator;

/// Create an LLVM::TypeToLLVMIRTranslator and transfer ownership to the
/// caller.
MLIR_CAPI_EXPORTED MlirTypeToLLVMIRTranslator
mlirTypeToLLVMIRTranslatorCreate(LLVMContextRef ctx);

/// Takes an LLVM::TypeToLLVMIRTranslator owned by the caller and destroys it.
/// It is the responsibility of the user to only pass an
/// LLVM::TypeToLLVMIRTranslator class.
MLIR_CAPI_EXPORTED void
mlirTypeToLLVMIRTranslatorDestroy(MlirTypeToLLVMIRTranslator translator);

/// Translates the given MLIR LLVM dialect to the LLVM IR type.
MLIR_CAPI_EXPORTED LLVMTypeRef mlirTypeToLLVMIRTranslatorTranslateType(
MlirTypeToLLVMIRTranslator translator, MlirType mlirType);

#ifdef __cplusplus
}
#endif
Expand Down
4 changes: 4 additions & 0 deletions mlir/lib/CAPI/Dialect/LLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ MlirType mlirLLVMFunctionTypeGetInput(MlirType type, intptr_t pos) {
.getParamType(static_cast<unsigned>(pos)));
}

MlirType mlirLLVMFunctionTypeGetReturnType(MlirType type) {
return wrap(llvm::cast<LLVM::LLVMFunctionType>(unwrap(type)).getReturnType());
}

bool mlirTypeIsALLVMStructType(MlirType type) {
return isa<LLVM::LLVMStructType>(unwrap(type));
}
Expand Down
49 changes: 46 additions & 3 deletions mlir/lib/CAPI/Target/LLVMIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@
//===----------------------------------------------------------------------===//

#include "mlir-c/Target/LLVMIR.h"
#include "llvm-c/Support.h"

#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include <memory>
#include "llvm/IR/Type.h"

#include "mlir/CAPI/IR.h"
#include "mlir/CAPI/Support.h"
#include "mlir/CAPI/Wrap.h"
#include "mlir/Target/LLVMIR/ModuleTranslation.h"
#include "mlir/Target/LLVMIR/TypeFromLLVM.h"

using namespace mlir;

Expand All @@ -34,3 +33,47 @@ LLVMModuleRef mlirTranslateModuleToLLVMIR(MlirOperation module,

return moduleRef;
}

DEFINE_C_API_PTR_METHODS(MlirTypeFromLLVMIRTranslator,
mlir::LLVM::TypeFromLLVMIRTranslator);

MlirTypeFromLLVMIRTranslator
mlirTypeFromLLVMIRTranslatorCreate(MlirContext ctx) {
MLIRContext *context = unwrap(ctx);
auto *translator = new LLVM::TypeFromLLVMIRTranslator(*context);
return wrap(translator);
}

void mlirTypeFromLLVMIRTranslatorDestroy(
MlirTypeFromLLVMIRTranslator translator) {
delete static_cast<LLVM::TypeFromLLVMIRTranslator *>(unwrap(translator));
}

MlirType mlirTypeFromLLVMIRTranslatorTranslateType(
MlirTypeFromLLVMIRTranslator translator, LLVMTypeRef llvmType) {
LLVM::TypeFromLLVMIRTranslator *translator_ = unwrap(translator);
mlir::Type type = translator_->translateType(llvm::unwrap(llvmType));
return wrap(type);
}

DEFINE_C_API_PTR_METHODS(MlirTypeToLLVMIRTranslator,
mlir::LLVM::TypeToLLVMIRTranslator);

MlirTypeToLLVMIRTranslator
mlirTypeToLLVMIRTranslatorCreate(LLVMContextRef ctx) {
llvm::LLVMContext *context = llvm::unwrap(ctx);
auto *translator = new LLVM::TypeToLLVMIRTranslator(*context);
return wrap(translator);
}

void mlirTypeToLLVMIRTranslatorDestroy(MlirTypeToLLVMIRTranslator translator) {
delete static_cast<LLVM::TypeToLLVMIRTranslator *>(unwrap(translator));
}

LLVMTypeRef
mlirTypeToLLVMIRTranslatorTranslateType(MlirTypeToLLVMIRTranslator translator,
MlirType mlirType) {
LLVM::TypeToLLVMIRTranslator *translator_ = unwrap(translator);
llvm::Type *type = translator_->translateType(unwrap(mlirType));
return llvm::wrap(type);
}
27 changes: 27 additions & 0 deletions mlir/test/CAPI/translation.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,38 @@ static void testToLLVMIR(MlirContext ctx) {
LLVMContextDispose(llvmCtx);
}

// CHECK-LABEL: testTypeToFromLLVMIRTranslator
static void testTypeToFromLLVMIRTranslator(MlirContext ctx) {
fprintf(stderr, "testTypeToFromLLVMIRTranslator\n");
LLVMContextRef llvmCtx = LLVMContextCreate();

LLVMTypeRef llvmTy = LLVMInt32TypeInContext(llvmCtx);
MlirTypeFromLLVMIRTranslator fromLLVMTranslator =
mlirTypeFromLLVMIRTranslatorCreate(ctx);
MlirType mlirTy =
mlirTypeFromLLVMIRTranslatorTranslateType(fromLLVMTranslator, llvmTy);
// CHECK: i32
mlirTypeDump(mlirTy);

MlirTypeToLLVMIRTranslator toLLVMTranslator =
mlirTypeToLLVMIRTranslatorCreate(llvmCtx);
LLVMTypeRef llvmTy2 =
mlirTypeToLLVMIRTranslatorTranslateType(toLLVMTranslator, mlirTy);
// CHECK: i32
LLVMDumpType(llvmTy2);
fprintf(stderr, "\n");

mlirTypeFromLLVMIRTranslatorDestroy(fromLLVMTranslator);
mlirTypeToLLVMIRTranslatorDestroy(toLLVMTranslator);
LLVMContextDispose(llvmCtx);
}

int main(void) {
MlirContext ctx = mlirContextCreate();
mlirDialectHandleRegisterDialect(mlirGetDialectHandle__llvm__(), ctx);
mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("llvm"));
testToLLVMIR(ctx);
testTypeToFromLLVMIRTranslator(ctx);
mlirContextDestroy(ctx);
return 0;
}