[mlir][sparse] cleanup ABI issues in C interface with memrefs
This change adds automatic wrapper functoins with emit_c_interface to all methods in the sparse support library that deal with MEMREFs. The wrappers will take care of passing MEMREFs by value internally and by pointer externally, thereby avoiding ABI issues across platforms. Reviewed By: mehdi_amini Differential Revision: https://reviews.llvm.org/D110219
This commit is contained in:
@@ -83,7 +83,7 @@ getDimLevelTypeEncoding(SparseTensorEncodingAttr::DimLevelType dlt) {
|
||||
|
||||
/// Returns integers of given width and values as a constant tensor.
|
||||
/// We cast the static shape into a dynamic shape to ensure that the
|
||||
/// method signature remains uniform accross different tensor dimensions.
|
||||
/// method signature remains uniform across different tensor dimensions.
|
||||
static Value getTensor(ConversionPatternRewriter &rewriter, unsigned width,
|
||||
Location loc, ArrayRef<APInt> values) {
|
||||
Type etp = rewriter.getIntegerType(width);
|
||||
@@ -95,20 +95,25 @@ static Value getTensor(ConversionPatternRewriter &rewriter, unsigned width,
|
||||
return rewriter.create<tensor::CastOp>(loc, tt2, elts);
|
||||
}
|
||||
|
||||
/// Returns function reference (first hit also inserts into module).
|
||||
/// Returns a function reference (first hit also inserts into module). Sets
|
||||
/// the "_emit_c_interface" on the function declaration when requested,
|
||||
/// so that LLVM lowering generates a wrapper function that takes care
|
||||
/// of ABI complications with passing in and returning MemRefs to C functions.
|
||||
static FlatSymbolRefAttr getFunc(Operation *op, StringRef name, Type resultType,
|
||||
ValueRange operands) {
|
||||
ValueRange operands,
|
||||
bool emitCInterface = false) {
|
||||
MLIRContext *context = op->getContext();
|
||||
auto module = op->getParentOfType<ModuleOp>();
|
||||
auto result = SymbolRefAttr::get(context, name);
|
||||
auto func = module.lookupSymbol<FuncOp>(result.getAttr());
|
||||
if (!func) {
|
||||
OpBuilder moduleBuilder(module.getBodyRegion());
|
||||
moduleBuilder
|
||||
.create<FuncOp>(
|
||||
op->getLoc(), name,
|
||||
FunctionType::get(context, operands.getTypes(), resultType))
|
||||
.setPrivate();
|
||||
func = moduleBuilder.create<FuncOp>(
|
||||
op->getLoc(), name,
|
||||
FunctionType::get(context, operands.getTypes(), resultType));
|
||||
func.setPrivate();
|
||||
if (emitCInterface)
|
||||
func->setAttr("llvm.emit_c_interface", UnitAttr::get(context));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -171,8 +176,9 @@ static Value genNewCall(ConversionPatternRewriter &rewriter, Operation *op,
|
||||
params.push_back(ptr);
|
||||
// Generate the call to create new tensor.
|
||||
StringRef name = "newSparseTensor";
|
||||
auto call =
|
||||
rewriter.create<CallOp>(loc, pTp, getFunc(op, name, pTp, params), params);
|
||||
auto call = rewriter.create<CallOp>(
|
||||
loc, pTp, getFunc(op, name, pTp, params, /*emitCInterface=*/true),
|
||||
params);
|
||||
return call.getResult(0);
|
||||
}
|
||||
|
||||
@@ -210,7 +216,9 @@ static void genAddEltCall(ConversionPatternRewriter &rewriter, Operation *op,
|
||||
params.push_back(ind);
|
||||
params.push_back(perm);
|
||||
Type pTp = LLVM::LLVMPointerType::get(IntegerType::get(op->getContext(), 8));
|
||||
rewriter.create<CallOp>(loc, pTp, getFunc(op, name, pTp, params), params);
|
||||
rewriter.create<CallOp>(
|
||||
loc, pTp, getFunc(op, name, pTp, params, /*emitCInterface=*/true),
|
||||
params);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -369,7 +377,9 @@ public:
|
||||
else
|
||||
return failure();
|
||||
rewriter.replaceOpWithNewOp<CallOp>(
|
||||
op, resType, getFunc(op, name, resType, operands), operands);
|
||||
op, resType,
|
||||
getFunc(op, name, resType, operands, /*emitCInterface=*/true),
|
||||
operands);
|
||||
return success();
|
||||
}
|
||||
};
|
||||
@@ -397,7 +407,9 @@ public:
|
||||
else
|
||||
return failure();
|
||||
rewriter.replaceOpWithNewOp<CallOp>(
|
||||
op, resType, getFunc(op, name, resType, operands), operands);
|
||||
op, resType,
|
||||
getFunc(op, name, resType, operands, /*emitCInterface=*/true),
|
||||
operands);
|
||||
return success();
|
||||
}
|
||||
};
|
||||
@@ -427,7 +439,9 @@ public:
|
||||
else
|
||||
return failure();
|
||||
rewriter.replaceOpWithNewOp<CallOp>(
|
||||
op, resType, getFunc(op, name, resType, operands), operands);
|
||||
op, resType,
|
||||
getFunc(op, name, resType, operands, /*emitCInterface=*/true),
|
||||
operands);
|
||||
return success();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user