Skip to content

[CIR][NFC] Add helper functions for CIR visibility #1652

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRDialect.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/SymbolTable.h"
#include "mlir/Interfaces/CallInterfaces.h"
#include "mlir/Interfaces/ControlFlowInterfaces.h"
#include "mlir/Interfaces/FunctionInterfaces.h"
Expand Down Expand Up @@ -90,6 +91,7 @@ class SameFirstSecondOperandAndResultType

namespace cir {
void buildTerminatedBody(mlir::OpBuilder &builder, mlir::Location loc);

} // namespace cir

#define GET_OP_CLASSES
Expand Down
38 changes: 38 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define MLIR_DIALECT_CIR_CIROPSENUMS_H_

#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/SymbolTable.h"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h.inc"

namespace cir {
Expand Down Expand Up @@ -126,6 +127,43 @@ template <typename Int> inline bool isValidCIRAtomicOrderingCABI(Int I) {
I <= (Int)cir::MemOrder::SequentiallyConsistent;
}

/// This function is used to deduce the MLIR visibility of a CIR symbol based on
/// CIR linkage and visibility.
static inline mlir::SymbolTable::Visibility
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: I'm not sure whether this is the best place to put this function. Let me know if I should move it somewhere else.

deduceMLIRVisibility(cir::GlobalLinkageKind linkage,
cir::VisibilityKind visibilityKind) {
if (visibilityKind != cir::VisibilityKind::Default) {
switch (visibilityKind) {
case cir::VisibilityKind::Hidden:
return mlir::SymbolTable::Visibility::Private;
case cir::VisibilityKind::Protected:
llvm::errs() << "visibility not implemented for protected visibility\n";
llvm_unreachable("protected visibility NYI");
default:
llvm_unreachable("unknown visibility kind");
}
}
switch (linkage) {
case cir::GlobalLinkageKind::InternalLinkage:
case cir::GlobalLinkageKind::PrivateLinkage:
return mlir::SymbolTable::Visibility::Private;
case cir::GlobalLinkageKind::ExternalLinkage:
case cir::GlobalLinkageKind::ExternalWeakLinkage:
case cir::GlobalLinkageKind::LinkOnceODRLinkage:
case cir::GlobalLinkageKind::AvailableExternallyLinkage:
case cir::GlobalLinkageKind::CommonLinkage:
case cir::GlobalLinkageKind::WeakAnyLinkage:
case cir::GlobalLinkageKind::WeakODRLinkage:
return mlir::SymbolTable::Visibility::Public;
default: {
llvm::errs() << "visibility not implemented for '"
<< stringifyGlobalLinkageKind(linkage) << "'\n";
assert(0 && "not implemented");
}
}
llvm_unreachable("linkage should be handled above!");
}

} // namespace cir

#endif // MLIR_DIALECT_CIR_CIROPSENUMS_H_
1 change: 1 addition & 0 deletions clang/include/clang/CIR/Interfaces/CIROpInterfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "clang/AST/Attr.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Mangle.h"
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"

namespace cir {} // namespace cir
Expand Down
206 changes: 114 additions & 92 deletions clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -46,120 +46,142 @@ let cppNamespace = "::cir" in {
def CIRGlobalValueInterface
: OpInterface<"CIRGlobalValueInterface", [Symbol]> {

let methods = [
InterfaceMethod<"",
"bool", "hasExternalLinkage", (ins), [{}],
/*defaultImplementation=*/[{
let methods =
[InterfaceMethod<"", "bool", "hasExternalLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return cir::isExternalLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "hasAvailableExternallyLinkage", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "hasAvailableExternallyLinkage", (ins),
[{}],
/*defaultImplementation=*/[{
return cir::isAvailableExternallyLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "hasLinkOnceLinkage", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "hasLinkOnceLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return cir::isLinkOnceLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "hasLinkOnceAnyLinkage", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "hasLinkOnceAnyLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return cir::isLinkOnceAnyLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "hasLinkOnceODRLinkage", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "hasLinkOnceODRLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return cir::isLinkOnceODRLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "hasWeakLinkage", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "hasWeakLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return cir::isWeakLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "hasWeakAnyLinkage", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "hasWeakAnyLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return cir::isWeakAnyLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "hasWeakODRLinkage", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "hasWeakODRLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return cir::isWeakODRLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "hasInternalLinkage", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "hasInternalLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return cir::isInternalLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "hasPrivateLinkage", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "hasPrivateLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return cir::isPrivateLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "hasLocalLinkage", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "hasLocalLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return cir::isLocalLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "hasExternalWeakLinkage", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "hasExternalWeakLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return cir::isExternalWeakLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "hasCommonLinkage", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "hasCommonLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return cir::isCommonLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "isDeclarationForLinker", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "isDeclarationForLinker", (ins), [{}],
/*defaultImplementation=*/[{
if ($_op.hasAvailableExternallyLinkage())
return true;
return $_op.isDeclaration();
}]
>,
InterfaceMethod<"",
"bool", "hasComdat", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "hasComdat", (ins), [{}],
/*defaultImplementation=*/[{
return $_op.getComdat();
}]
>,
InterfaceMethod<"",
"void", "setDSOLocal", (ins "bool":$val), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "void", "setDSOLocal", (ins "bool":$val), [{}],
/*defaultImplementation=*/[{
$_op.setDsolocal(val);
}]
>,
InterfaceMethod<"",
"bool", "isDSOLocal", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "isDSOLocal", (ins), [{}],
/*defaultImplementation=*/[{
return $_op.getDsolocal();
}]
>,
InterfaceMethod<"",
"bool", "isWeakForLinker", (ins), [{}],
/*defaultImplementation=*/[{
}]>,
InterfaceMethod<"", "bool", "isWeakForLinker", (ins), [{}],
/*defaultImplementation=*/[{
return cir::isWeakForLinker($_op.getLinkage());
}]
>
}]>,
InterfaceMethod<"Gets the CIR visibility of this global variable.",
"::cir::VisibilityKind", "getCIRVisibility", (ins),
[{}],
/*defaultImplementation=*/[{
return $_op.getGlobalVisibility().getValue();
}]>,
InterfaceMethod<
"Returns true if this global variable has default CIR visibility.",
"bool", "hasDefaultVisibility", (ins), [{}],
/*defaultImplementation=*/[{
return $_op.getGlobalVisibility().isDefault();
}]>,
InterfaceMethod<
"Returns true if this global variable has hidden CIR visibility.",
"bool", "hasHiddenVisibility", (ins), [{}],
/*defaultImplementation=*/[{
return $_op.getGlobalVisibility().isHidden();
}]>,
InterfaceMethod<"Returns true if this global variable has protected "
"CIR visibility.",
"bool", "hasProtectedVisibility", (ins), [{}],
/*defaultImplementation=*/[{
return $_op.getGlobalVisibility().isProtected();
}]>,
InterfaceMethod<"Sets the CIR visibility of this global variable.",
"void", "setGlobalVisibility",
(ins "::cir::VisibilityKind":$vis), [{}],
/*defaultImplementation=*/[{
$_op.setGlobalVisibilityAttr(::cir::VisibilityAttr::get($_op.getContext(), vis));
}]>,
InterfaceMethod<
"Sets the CIR visibility of this global variable to be default.",
"void", "setDefaultCIRVisibility", (ins), [{}],
/*defaultImplementation=*/[{
setGlobalVisibility(::cir::VisibilityKind::Default);
}]>,
InterfaceMethod<
"Sets the CIR visibility of this global variable to be hidden.",
"void", "setHiddenCIRVisibility", (ins), [{}],
/*defaultImplementation=*/[{
setGlobalVisibility(::cir::VisibilityKind::Hidden);
}]>,
InterfaceMethod<
"Sets the CIR visibility of this global variable to be protected.",
"void", "setProtectedCIRVisibility", (ins), [{}],
/*defaultImplementation=*/[{
setGlobalVisibility(::cir::VisibilityKind::Protected);
}]>,
InterfaceMethod<"Updates the MLIR visibility of this global variable "
"based on the CIR visiblity and linkage.",
"void", "updateMLIRVisibility", (ins), [{}],
/*defaultImplementation=*/[{
mlir::SymbolTable::setSymbolVisibility(
$_op, ::cir::deduceMLIRVisibility(
$_op.getLinkage(),
$_op.getGlobalVisibility().getValue())
);
}]>,
];
let extraClassDeclaration = [{
bool hasDefaultVisibility();
bool canBenefitFromLocalAlias();
}];
}
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/ExprCXX.h"
#include "clang/CIR/Dialect/IR/CIRDataLayout.h"
#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "clang/CIR/MissingFeatures.h"
Expand Down Expand Up @@ -485,7 +486,8 @@ CIRGenModule::getOrCreateStaticVarDecl(const VarDecl &D,
cir::GlobalOp GV = builder.createVersionedGlobal(
getModule(), getLoc(D.getLocation()), Name, LTy, false, Linkage, AS);
// TODO(cir): infer visibility from linkage in global op builder.
GV.setVisibility(getMLIRVisibilityFromCIRLinkage(Linkage));
GV.setVisibility(
cir::deduceMLIRVisibility(Linkage, cir::VisibilityKind::Default));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggestion is a bit more simple and somewhat different: GV.setLinkage and Fn.setLinkage should call GV.setVisibility under the hood, no need to involve visibility kind. If you make linkage into an interface, than you don't need to implement in both places.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comment! I was trying to do that in future PRs, but I ran into some issues when dealing with FuncOp (#1029 (comment))

GV.setInitialValueAttr(Init);
GV.setAlignment(getASTContext().getDeclAlign(&D).getAsAlign().value());

Expand Down
32 changes: 6 additions & 26 deletions clang/lib/CIR/CodeGen/CIRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1561,7 +1561,8 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *d,
if (const SectionAttr *sa = d->getAttr<SectionAttr>())
gv.setSectionAttr(builder.getStringAttr(sa->getName()));

gv.setGlobalVisibilityAttr(getGlobalVisibilityAttrFromDecl(d));
const auto globalVisibilityAttr = getGlobalVisibilityAttrFromDecl(d);
gv.setGlobalVisibilityAttr(globalVisibilityAttr);

// TODO(cir):
// GV->setAlignment(getContext().getDeclAlign(D).getAsAlign());
Expand Down Expand Up @@ -1591,7 +1592,8 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *d,
// Set CIR linkage and DLL storage class.
gv.setLinkage(linkage);
// FIXME(cir): setLinkage should likely set MLIR's visibility automatically.
gv.setVisibility(getMLIRVisibilityFromCIRLinkage(linkage));
gv.setVisibility(
cir::deduceMLIRVisibility(linkage, globalVisibilityAttr.getValue()));
// TODO(cir): handle DLL storage classes in CIR?
if (d->hasAttr<DLLImportAttr>())
assert(!cir::MissingFeatures::setDLLStorageClass());
Expand Down Expand Up @@ -2243,30 +2245,8 @@ CIRGenModule::getMLIRVisibility(cir::GlobalOp op) {
// definitions).
if (op.isDeclaration())
return mlir::SymbolTable::Visibility::Private;
return getMLIRVisibilityFromCIRLinkage(op.getLinkage());
}

mlir::SymbolTable::Visibility
CIRGenModule::getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind glk) {
switch (glk) {
case cir::GlobalLinkageKind::InternalLinkage:
case cir::GlobalLinkageKind::PrivateLinkage:
return mlir::SymbolTable::Visibility::Private;
case cir::GlobalLinkageKind::ExternalLinkage:
case cir::GlobalLinkageKind::ExternalWeakLinkage:
case cir::GlobalLinkageKind::LinkOnceODRLinkage:
case cir::GlobalLinkageKind::AvailableExternallyLinkage:
case cir::GlobalLinkageKind::CommonLinkage:
case cir::GlobalLinkageKind::WeakAnyLinkage:
case cir::GlobalLinkageKind::WeakODRLinkage:
return mlir::SymbolTable::Visibility::Public;
default: {
llvm::errs() << "visibility not implemented for '"
<< stringifyGlobalLinkageKind(glk) << "'\n";
assert(0 && "not implemented");
}
}
llvm_unreachable("linkage should be handled above!");
return cir::deduceMLIRVisibility(op.getLinkage(),
op.getGlobalVisibility().getValue());
}

cir::VisibilityKind CIRGenModule::getGlobalVisibilityKindFromClangVisibility(
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -827,9 +827,9 @@ class CIRGenModule : public CIRGenTypeCache {
bool IsConstantVariable);
void setFunctionLinkage(GlobalDecl GD, cir::FuncOp f) {
auto L = getFunctionLinkage(GD);
auto V = f.getGlobalVisibility().getValue();
f.setLinkageAttr(cir::GlobalLinkageKindAttr::get(&getMLIRContext(), L));
mlir::SymbolTable::setSymbolVisibility(f,
getMLIRVisibilityFromCIRLinkage(L));
mlir::SymbolTable::setSymbolVisibility(f, cir::deduceMLIRVisibility(L, V));
}

cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *VD,
Expand Down
Loading
Loading