Skip to content

Commit

Permalink
[mlir][llvm] Add visibility attribute
Browse files Browse the repository at this point in the history
This commit introduces the LLVM's visibility attribute and adds it to
both globals and functions.

Furthermore, this commit ensures that "thread_local" is printed in the
correct place and adds a test for that.

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D145790
  • Loading branch information
Dinistro committed Mar 12, 2023
1 parent eee590c commit 6628767
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 13 deletions.
19 changes: 19 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td
Expand Up @@ -546,6 +546,25 @@ def UnnamedAddr : LLVM_EnumAttr<
let cppNamespace = "::mlir::LLVM";
}

//===----------------------------------------------------------------------===//
// Visibility
//===----------------------------------------------------------------------===//

def VisibilityDefault
: LLVM_EnumAttrCase<"Default", "", "DefaultVisibility", 0>;
def VisibilityHidden
: LLVM_EnumAttrCase<"Hidden", "hidden", "HiddenVisibility", 1>;
def VisibilityProtected
: LLVM_EnumAttrCase<"Protected", "protected", "ProtectedVisibility", 2>;

def Visibility : LLVM_EnumAttr<
"Visibility",
"::llvm::GlobalValue::VisibilityTypes",
"LLVM GlobalValue Visibility",
[VisibilityDefault, VisibilityHidden, VisibilityProtected]> {
let cppNamespace = "::mlir::LLVM";
}

//===----------------------------------------------------------------------===//
// ModRefInfo
//===----------------------------------------------------------------------===//
Expand Down
6 changes: 4 additions & 2 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
Expand Up @@ -1301,7 +1301,8 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
OptionalAttr<I64Attr>:$alignment,
DefaultValuedAttr<ConfinedAttr<I32Attr, [IntNonNegative]>, "0">:$addr_space,
OptionalAttr<UnnamedAddr>:$unnamed_addr,
OptionalAttr<StrAttr>:$section
OptionalAttr<StrAttr>:$section,
DefaultValuedAttr<Visibility, "mlir::LLVM::Visibility::Default">:$visibility_
);
let summary = "LLVM dialect global.";
let description = [{
Expand Down Expand Up @@ -1546,7 +1547,8 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [
OptionalAttr<DictArrayAttr>:$arg_attrs,
OptionalAttr<DictArrayAttr>:$res_attrs,
OptionalAttr<I64Attr>:$function_entry_count,
OptionalAttr<LLVM_MemoryEffectsAttr>:$memory
OptionalAttr<LLVM_MemoryEffectsAttr>:$memory,
DefaultValuedAttr<Visibility, "mlir::LLVM::Visibility::Default">:$visibility_
);

let regions = (region AnyRegion:$body);
Expand Down
42 changes: 31 additions & 11 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
Expand Up @@ -1623,13 +1623,16 @@ void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type,

void GlobalOp::print(OpAsmPrinter &p) {
p << ' ' << stringifyLinkage(getLinkage()) << ' ';
StringRef visibility = stringifyVisibility(getVisibility_());
if (!visibility.empty())
p << visibility << ' ';
if (getThreadLocal_())
p << "thread_local ";
if (auto unnamedAddr = getUnnamedAddr()) {
StringRef str = stringifyUnnamedAddr(*unnamedAddr);
if (!str.empty())
p << str << ' ';
}
if (getThreadLocal_())
p << "thread_local ";
if (getConstant())
p << "constant ";
p.printSymbolName(getSymName());
Expand All @@ -1640,11 +1643,12 @@ void GlobalOp::print(OpAsmPrinter &p) {
// Note that the alignment attribute is printed using the
// default syntax here, even though it is an inherent attribute
// (as defined in https://mlir.llvm.org/docs/LangRef/#attributes)
p.printOptionalAttrDict(
(*this)->getAttrs(),
{SymbolTable::getSymbolAttrName(), getGlobalTypeAttrName(),
getConstantAttrName(), getValueAttrName(), getLinkageAttrName(),
getUnnamedAddrAttrName(), getThreadLocal_AttrName()});
p.printOptionalAttrDict((*this)->getAttrs(),
{SymbolTable::getSymbolAttrName(),
getGlobalTypeAttrName(), getConstantAttrName(),
getValueAttrName(), getLinkageAttrName(),
getUnnamedAddrAttrName(), getThreadLocal_AttrName(),
getVisibility_AttrName()});

// Print the trailing type unless it's a string global.
if (getValueOrNull().dyn_cast_or_null<StringAttr>())
Expand Down Expand Up @@ -1684,6 +1688,7 @@ struct EnumTraits {};
REGISTER_ENUM_TYPE(Linkage);
REGISTER_ENUM_TYPE(UnnamedAddr);
REGISTER_ENUM_TYPE(CConv);
REGISTER_ENUM_TYPE(Visibility);
} // namespace

/// Parse an enum from the keyword, or default to the provided default value.
Expand Down Expand Up @@ -1717,16 +1722,22 @@ ParseResult GlobalOp::parse(OpAsmParser &parser, OperationState &result) {
ctx, parseOptionalLLVMKeyword<Linkage>(
parser, result, LLVM::Linkage::External)));

if (succeeded(parser.parseOptionalKeyword("thread_local")))
result.addAttribute(getThreadLocal_AttrName(result.name),
parser.getBuilder().getUnitAttr());
// Parse optional visibility, default to Default.
result.addAttribute(getVisibility_AttrName(result.name),
parser.getBuilder().getI64IntegerAttr(
parseOptionalLLVMKeyword<LLVM::Visibility, int64_t>(
parser, result, LLVM::Visibility::Default)));

// Parse optional UnnamedAddr, default to None.
result.addAttribute(getUnnamedAddrAttrName(result.name),
parser.getBuilder().getI64IntegerAttr(
parseOptionalLLVMKeyword<UnnamedAddr, int64_t>(
parser, result, LLVM::UnnamedAddr::None)));

if (succeeded(parser.parseOptionalKeyword("thread_local")))
result.addAttribute(getThreadLocal_AttrName(result.name),
parser.getBuilder().getUnitAttr());

if (succeeded(parser.parseOptionalKeyword("constant")))
result.addAttribute(getConstantAttrName(result.name),
parser.getBuilder().getUnitAttr());
Expand Down Expand Up @@ -2047,6 +2058,12 @@ ParseResult LLVMFuncOp::parse(OpAsmParser &parser, OperationState &result) {
parseOptionalLLVMKeyword<Linkage>(
parser, result, LLVM::Linkage::External)));

// Parse optional visibility, default to Default.
result.addAttribute(getVisibility_AttrName(result.name),
parser.getBuilder().getI64IntegerAttr(
parseOptionalLLVMKeyword<LLVM::Visibility, int64_t>(
parser, result, LLVM::Visibility::Default)));

// Default to C Calling Convention if no keyword is provided.
result.addAttribute(
getCConvAttrName(result.name),
Expand Down Expand Up @@ -2097,6 +2114,9 @@ void LLVMFuncOp::print(OpAsmPrinter &p) {
p << ' ';
if (getLinkage() != LLVM::Linkage::External)
p << stringifyLinkage(getLinkage()) << ' ';
StringRef visibility = stringifyVisibility(getVisibility_());
if (!visibility.empty())
p << visibility << ' ';
if (getCConv() != LLVM::CConv::C)
p << stringifyCConv(getCConv()) << ' ';

Expand All @@ -2118,7 +2138,7 @@ void LLVMFuncOp::print(OpAsmPrinter &p) {
function_interface_impl::printFunctionAttributes(
p, *this,
{getFunctionTypeAttrName(), getArgAttrsAttrName(), getResAttrsAttrName(),
getLinkageAttrName(), getCConvAttrName()});
getLinkageAttrName(), getCConvAttrName(), getVisibility_AttrName()});

// Print the body if this is not an external function.
Region &body = getBody();
Expand Down
4 changes: 4 additions & 0 deletions mlir/lib/Target/LLVMIR/ModuleImport.cpp
Expand Up @@ -893,6 +893,8 @@ LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
}
if (globalVar->hasSection())
globalOp.setSection(globalVar->getSection());
globalOp.setVisibility_(
convertVisibilityFromLLVM(globalVar->getVisibility()));

return success();
}
Expand Down Expand Up @@ -1611,6 +1613,8 @@ LogicalResult ModuleImport::processFunction(llvm::Function *func) {
if (func->hasGC())
funcOp.setGarbageCollector(StringRef(func->getGC()));

funcOp.setVisibility_(convertVisibilityFromLLVM(func->getVisibility()));

// Handle Function attributes.
processFunctionAttributes(func, funcOp);

Expand Down
5 changes: 5 additions & 0 deletions mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
Expand Up @@ -706,6 +706,8 @@ LogicalResult ModuleTranslation::convertGlobals() {
if (alignment.has_value())
var->setAlignment(llvm::MaybeAlign(alignment.value()));

var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));

globalsMapping.try_emplace(op, var);
}

Expand Down Expand Up @@ -975,6 +977,9 @@ LogicalResult ModuleTranslation::convertFunctionSignatures() {
if (failed(forwardPassthroughAttributes(
function.getLoc(), function.getPassthrough(), llvmFunc)))
return failure();

// Convert visibility attribute.
llvmFunc->setVisibility(convertVisibilityToLLVM(function.getVisibility_()));
}

return success();
Expand Down
10 changes: 10 additions & 0 deletions mlir/test/Dialect/LLVMIR/func.mlir
Expand Up @@ -194,6 +194,16 @@ module {
llvm.func @memory_attr() attributes {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = readwrite>} {
llvm.return
}

// CHECK-LABEL: llvm.func hidden @hidden
llvm.func hidden @hidden() {
llvm.return
}

// CHECK-LABEL: llvm.func protected @protected
llvm.func protected @protected() {
llvm.return
}
}

// -----
Expand Down
10 changes: 10 additions & 0 deletions mlir/test/Dialect/LLVMIR/global.mlir
Expand Up @@ -90,6 +90,16 @@ llvm.mlir.global private unnamed_addr constant @foo(42 : i64) : i64
// CHECK: llvm.mlir.global internal constant @sectionvar("teststring") {addr_space = 0 : i32, section = ".mysection"}
llvm.mlir.global internal constant @sectionvar("teststring") {section = ".mysection"}: !llvm.array<10 x i8>

// CHECK: llvm.mlir.global internal thread_local constant @thread_local(42 : i32)
llvm.mlir.global internal thread_local constant @thread_local(42 : i32) : i32

// Visibility types.
// CHECK: llvm.mlir.global internal hidden constant @hidden(42 : i32)
llvm.mlir.global internal hidden constant @hidden(42 : i32) : i32

// CHECK: llvm.mlir.global internal protected unnamed_addr @protected(42 : i32)
llvm.mlir.global internal protected unnamed_addr @protected(42 : i32) : i32

// -----

// expected-error @+1 {{op requires attribute 'sym_name'}}
Expand Down
14 changes: 14 additions & 0 deletions mlir/test/Target/LLVMIR/Import/function-attributes.ll
Expand Up @@ -179,3 +179,17 @@ define void @passthrough_combined() alignstack(16) noinline "probe-stack" "alloc
define void @passthrough_string_only() "no-enum-attr" {
ret void
}

// -----

; CHECK-LABEL: llvm.func hidden @hidden()
define hidden void @hidden() {
ret void
}

// -----

; CHECK-LABEL: llvm.func protected @protected()
define protected void @protected() {
ret void
}
10 changes: 10 additions & 0 deletions mlir/test/Target/LLVMIR/Import/global-variables.ll
Expand Up @@ -196,3 +196,13 @@ define void @foo() {
define void @bar() {
ret void
}

; // -----

; Visibility attribute.

; CHECK: llvm.mlir.global external hidden constant @hidden("string")
@hidden = hidden constant [6 x i8] c"string"

; CHECK: llvm.mlir.global external protected constant @protected(42 : i64)
@protected = protected constant i64 42
25 changes: 25 additions & 0 deletions mlir/test/Target/LLVMIR/llvmir.mlir
Expand Up @@ -110,6 +110,17 @@ llvm.mlir.global weak_odr @weak_odr(42 : i32) : i32
// CHECK: @external = external global i32
llvm.mlir.global external @external() : i32


//
// Visibility attribute.
//

// CHECK: @hidden = hidden constant [6 x i8] c"string"
llvm.mlir.global external hidden constant @hidden("string")

// CHECK: @protected = protected constant i64 42
llvm.mlir.global external protected constant @protected(42 : i64) : i64

//
// UnnamedAddr attribute.
//
Expand Down Expand Up @@ -484,6 +495,20 @@ llvm.func internal @func_internal() {
llvm.return
}

//
// Visibility attribute.
//

// CHECK-LABEL: define hidden void @hidden_func()
llvm.func hidden @hidden_func() {
llvm.return
}

// CHECK-LABEL: define protected void @protected_func()
llvm.func protected @protected_func() {
llvm.return
}

//
// dso_local attribute.
//
Expand Down

0 comments on commit 6628767

Please sign in to comment.