Skip to content

Commit

Permalink
[mlir][LLVM] Add result attribute import support
Browse files Browse the repository at this point in the history
This commit introduces support for importing result attributes.

Depends on D142372

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D142476
  • Loading branch information
Dinistro committed Jan 25, 2023
1 parent 77bdad0 commit 56880fd
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 30 deletions.
8 changes: 8 additions & 0 deletions mlir/include/mlir/Target/LLVMIR/ModuleImport.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,14 @@ class ModuleImport {
LogicalResult convertCallTypeAndOperands(llvm::CallBase *callInst,
SmallVectorImpl<Type> &types,
SmallVectorImpl<Value> &operands);
/// Converts the parameter attributes attached to `func` and adds them to the
/// `funcOp`.
void convertParameterAttributes(llvm::Function *func, LLVMFuncOp funcOp,
OpBuilder &builder);
/// Converts the AttributeSet of one parameter in LLVM IR to a corresponding
/// DictionaryAttr for the LLVM dialect.
DictionaryAttr convertParameterAttribute(llvm::AttributeSet llvmParamAttrs,
OpBuilder &builder);
/// Returns the builtin type equivalent to be used in attributes for the given
/// LLVM IR dialect type.
Type getStdTypeForAttr(Type type);
Expand Down
85 changes: 56 additions & 29 deletions mlir/lib/Target/LLVMIR/ModuleImport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1482,6 +1482,61 @@ void ModuleImport::processFunctionAttributes(llvm::Function *func,
processPassthroughAttrs(func, funcOp);
}

DictionaryAttr
ModuleImport::convertParameterAttribute(llvm::AttributeSet llvmParamAttrs,
OpBuilder &builder) {
using ElemTy = std::pair<llvm::Attribute::AttrKind, StringRef>;
// Mapping from llvm attribute kinds to their corresponding MLIR name.
static const SmallVector<ElemTy> kindNamePairs = {
{llvm::Attribute::AttrKind::NoAlias, LLVMDialect::getNoAliasAttrName()},
{llvm::Attribute::AttrKind::ReadOnly, LLVMDialect::getReadonlyAttrName()},
{llvm::Attribute::AttrKind::Nest, LLVMDialect::getNestAttrName()},
{llvm::Attribute::AttrKind::SExt, LLVMDialect::getSExtAttrName()},
{llvm::Attribute::AttrKind::ZExt, LLVMDialect::getZExtAttrName()},
{llvm::Attribute::AttrKind::NoUndef, LLVMDialect::getNoUndefAttrName()},
{llvm::Attribute::AttrKind::StructRet,
LLVMDialect::getStructRetAttrName()},
{llvm::Attribute::AttrKind::ByVal, LLVMDialect::getByValAttrName()},
{llvm::Attribute::AttrKind::ByRef, LLVMDialect::getByRefAttrName()},
{llvm::Attribute::AttrKind::InAlloca, LLVMDialect::getInAllocaAttrName()},
{llvm::Attribute::AttrKind::Alignment, LLVMDialect::getAlignAttrName()}};

SmallVector<NamedAttribute> paramAttrs;
for (auto [llvmKind, mlirName] : kindNamePairs) {
auto llvmAttr = llvmParamAttrs.getAttribute(llvmKind);
// Skip attributes that are not attached.
if (!llvmAttr.isValid())
continue;
Attribute mlirAttr;
if (llvmAttr.isTypeAttribute())
mlirAttr = TypeAttr::get(convertType(llvmAttr.getValueAsType()));
else if (llvmAttr.isIntAttribute())
mlirAttr = builder.getI64IntegerAttr(llvmAttr.getValueAsInt());
else if (llvmAttr.isEnumAttribute())
mlirAttr = builder.getUnitAttr();
else
llvm_unreachable("unexpected parameter attribute kind");
paramAttrs.push_back(builder.getNamedAttr(mlirName, mlirAttr));
}

return builder.getDictionaryAttr(paramAttrs);
}

void ModuleImport::convertParameterAttributes(llvm::Function *func,
LLVMFuncOp funcOp,
OpBuilder &builder) {
auto llvmAttrs = func->getAttributes();
for (size_t i = 0, e = funcOp.getNumArguments(); i < e; ++i) {
llvm::AttributeSet llvmArgAttrs = llvmAttrs.getParamAttrs(i);
funcOp.setArgAttrs(i, convertParameterAttribute(llvmArgAttrs, builder));
}
// Convert the result attributes and attach them wrapped in an ArrayAttribute
// to the funcOp.
llvm::AttributeSet llvmResAttr = llvmAttrs.getRetAttrs();
funcOp.setResAttrsAttr(
builder.getArrayAttr(convertParameterAttribute(llvmResAttr, builder)));
}

LogicalResult ModuleImport::processFunction(llvm::Function *func) {
clearBlockAndValueMapping();

Expand All @@ -1505,35 +1560,7 @@ LogicalResult ModuleImport::processFunction(llvm::Function *func) {
// Set the function debug information if available.
debugImporter->translate(func, funcOp);

for (const auto &it : llvm::enumerate(functionType.getParams())) {
llvm::SmallVector<NamedAttribute, 1> argAttrs;
if (auto *type = func->getParamByValType(it.index())) {
Type mlirType = convertType(type);
argAttrs.push_back(
NamedAttribute(builder.getStringAttr(LLVMDialect::getByValAttrName()),
TypeAttr::get(mlirType)));
}
if (auto *type = func->getParamByRefType(it.index())) {
Type mlirType = convertType(type);
argAttrs.push_back(
NamedAttribute(builder.getStringAttr(LLVMDialect::getByRefAttrName()),
TypeAttr::get(mlirType)));
}
if (auto *type = func->getParamStructRetType(it.index())) {
Type mlirType = convertType(type);
argAttrs.push_back(NamedAttribute(
builder.getStringAttr(LLVMDialect::getStructRetAttrName()),
TypeAttr::get(mlirType)));
}
if (auto *type = func->getParamInAllocaType(it.index())) {
Type mlirType = convertType(type);
argAttrs.push_back(NamedAttribute(
builder.getStringAttr(LLVMDialect::getInAllocaAttrName()),
TypeAttr::get(mlirType)));
}

funcOp.setArgAttrs(it.index(), argAttrs);
}
convertParameterAttributes(func, funcOp, builder);

if (FlatSymbolRefAttr personality = getPersonalityAsAttr(func))
funcOp.setPersonalityAttr(personality);
Expand Down
40 changes: 39 additions & 1 deletion mlir/test/Target/LLVMIR/Import/function-attributes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,52 @@ attributes #0 = { readnone }
; CHECK-SAME: !llvm.ptr {llvm.byref = i64}
; CHECK-SAME: !llvm.ptr {llvm.sret = i64}
; CHECK-SAME: !llvm.ptr {llvm.inalloca = i64}
; CHECK-SAME: !llvm.ptr {llvm.noalias}
; CHECK-SAME: !llvm.ptr {llvm.readonly}
; CHECK-SAME: !llvm.ptr {llvm.nest}
; CHECK-SAME: i32 {llvm.signext}
; CHECK-SAME: i64 {llvm.zeroext}
; CHECK-SAME: !llvm.ptr {llvm.align = 64 : i64, llvm.noundef}
define void @func_arg_attrs(
ptr byval(i64) %arg0,
ptr byref(i64) %arg1,
ptr sret(i64) %arg2,
ptr inalloca(i64) %arg3) {
ptr inalloca(i64) %arg3,
ptr noalias %arg4,
ptr readonly %arg5,
ptr nest %arg6,
i32 signext %arg7,
i64 zeroext %arg8,
ptr align(64) noundef %arg9) {
ret void
}

; // -----

; CHECK-LABEL: @func_res_attr_align
; CHECK-SAME: !llvm.ptr {llvm.align = 16 : i64}
declare align(16) ptr @func_res_attr_align()

; // -----

; CHECK-LABEL: @func_res_attr_noalias
; CHECK-SAME: !llvm.ptr {llvm.noalias}
declare noalias ptr @func_res_attr_noalias()

; // -----

; CHECK-LABEL: @func_res_attr_signext
; CHECK-DAG: llvm.noundef
; CHECK-DAG: llvm.signext
declare noundef signext i32 @func_res_attr_signext()

; // -----

; CHECK-LABEL: @func_res_attr_zeroext
; CHECK-SAME: i32 {llvm.zeroext}
declare zeroext i32 @func_res_attr_zeroext()


; // -----

; CHECK-LABEL: @entry_count
Expand Down

0 comments on commit 56880fd

Please sign in to comment.