Hi, I have a question about pointer in mlir: How to I pass a pointer from my c++ code to mlir ?
Suppose I have a class A in my c++code, and a function that take void* ptr
as parameter which is actually an A*
. I want to call the function from mlir.
I have defined a PtrType in my dialect to wrap the pointer of A, and want to call the function from llvm.
class A {
int64_t a;
};
extern "C" {
int64_t my_func(void * p);
}
struct PtrTypeStorage: public TypeStorage {
void* ptr = nullptr;
....
};
class PtrType: public mlir::Type::TypeBase<PtrType, mlir::Type, detail::PtrTypeStorage> {
public:
using Base::Base;
static PtrType get(mlir::MLIRContext* ctx);
size_t getNumElementTypes() { return 1; }
void setPtr(void* ptr);
static llvm::StringRef name;
};
And I have an op in dialect which just return a PtrType
:
def GetPtrOp : Toy_Op<"get_ptr"> {
let summary = "get_ptr";
let arguments = (ins);
let results = (outs Toy_PtrType:$output);
let assemblyFormat = "`(` `)` attr-dict `to` type($output)";
let builders = [
OpBuilder<(ins)>
];
}
I tried the following in lowering to llvm, but it does’t work
struct GetPtrOpLowering : public OpConversionPattern<mlir::toy::GetPtrOp> {
using OpConversionPattern<mlir::toy::GetPtrOp>::OpConversionPattern;
LogicalResult matchAndRewrite(mlir::toy::GetPtrOp op,
OpAdaptor adaptor,
ConversionPatternRewriter& rewriter) const override {
ModuleOp parentModule = op.getOperation()->getParentOfType<ModuleOp>();
auto* context = parentModule.getContext();
auto loc = op.getOperation()->getLoc();
auto ptrType = LLVM::LLVMPointerType::get(parentModule.getContext());
Value one = rewriter.create<LLVM::ConstantOp>(loc, rewriter.getI64Type(), rewriter.getIndexAttr(1));
Value allocated = rewriter.create<LLVM::AllocaOp>(loc, ptrType, PtrType::get(context), one);
mlir::Value res = rewriter.create<LLVM::LoadOp>(loc, PtrType::get(context), allocated);
rewriter.eraseOp(op);
return mlir::success();
}
};
When I run the code var a = get_ptr()
, the error says:
loc("codegen.toy":15:15): error: 'llvm.load' op result #0 must be LLVM type with size, but got '!toy.PtrType'
So I have the following questions:
- How do I convert the
PtrType
in my dialect toLLVM::LLVMPointerType
? - According the document of
Type
, everyType
is just a wrapper of an actualTypeStorage
. So What is the actual storageLLVM::LLVMPointerType
? Can I just get the actual storage and just set the pointer value ? I grep all code under llvm-project, and found thatLLVM::LLVMPointerType::get(context)
seems to be the only way to construct aLLVM::LLVMPointerType
. - If I use
MemrefType
, still I need to provide atype
, which also need to be converted to llvm type at last, back to the first question: how to convertvoid*
pointer toLLVM::LLVMPointerType
? - My goal is to call the function
my_func
with some object in my c++ code, Is my idea correct ? Are there any other idea to achieve this?