Skip to content

Commit

Permalink
[CIR][CIRGen] Add new CIR visibility to represent Default, Hidden, Pr…
Browse files Browse the repository at this point in the history
…otected (#776)

This PR add a new CIR attribute `mlir::cir::VisibilityAttr` to represent
CIR visibility. It will represent C/C++ visibility type `Default`,
`Hidden`, `Protected`.

The PR handles the parsing, printing of CIR visibility and also lower to
LLVM.

After this PR, there will be more PR's to migrate CIRGen properties that
are currently querying MLIR visibility(e.g. `sym_visibility`), to
instead query CIR visibility, and remove MLIR's visibility from printing
and parsing.
  • Loading branch information
roro47 authored and lanza committed Nov 3, 2024
1 parent d9cc74a commit a1b7883
Show file tree
Hide file tree
Showing 12 changed files with 229 additions and 29 deletions.
43 changes: 42 additions & 1 deletion clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,48 @@ def ASTExprAttr : AST<"Expr", "expr",
def ASTCallExprAttr : AST<"CallExpr", "call.expr",
[ASTCallExprInterface]>;


//===----------------------------------------------------------------------===//
// VisibilityAttr
//===----------------------------------------------------------------------===//

def VK_Default : I32EnumAttrCase<"Default", 1, "default">;
def VK_Hidden : I32EnumAttrCase<"Hidden", 2, "hidden">;
def VK_Protected : I32EnumAttrCase<"Protected", 3, "protected">;

def VisibilityKind : I32EnumAttr<"VisibilityKind", "C/C++ visibility", [
VK_Default, VK_Hidden, VK_Protected
]> {
let cppNamespace = "::mlir::cir";
}

def VisibilityAttr : CIR_Attr<"Visibility", "visibility"> {
let summary = "Visibility attribute";
let description = [{
Visibility attributes.
}];
let parameters = (ins "VisibilityKind":$value);

let assemblyFormat = [{
$value
}];

let builders = [
AttrBuilder<(ins CArg<"VisibilityKind", "cir::VisibilityKind::Default">:$value), [{
return $_get($_ctxt, value);
}]>
];

let skipDefaultBuilders = 1;

let extraClassDeclaration = [{
bool isDefault() const { return getValue() == VisibilityKind::Default; };
bool isHidden() const { return getValue() == VisibilityKind::Hidden; };
bool isProtected() const { return getValue() == VisibilityKind::Protected; };
}];
}


//===----------------------------------------------------------------------===//
// ExtraFuncAttr
//===----------------------------------------------------------------------===//
Expand All @@ -915,7 +957,6 @@ def ExtraFuncAttr : CIR_Attr<"ExtraFuncAttributes", "extra"> {
// Printing and parsing also available in CIRDialect.cpp
}


def NoInline : I32EnumAttrCase<"NoInline", 1, "no">;
def AlwaysInline : I32EnumAttrCase<"AlwaysInline", 2, "always">;
def InlineHint : I32EnumAttrCase<"InlineHint", 3, "hint">;
Expand Down
11 changes: 8 additions & 3 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2148,6 +2148,8 @@ def GlobalOp : CIR_Op<"global",
Symbol visibility in `sym_visibility` is defined in terms of MLIR's visibility
and verified to be in accordance to `linkage`.

`visibility_attr` is defined in terms of CIR's visibility.

Example:

```mlir
Expand All @@ -2160,6 +2162,7 @@ def GlobalOp : CIR_Op<"global",
// TODO: sym_visibility can possibly be represented by implementing the
// necessary Symbol's interface in terms of linkage instead.
let arguments = (ins SymbolNameAttr:$sym_name,
VisibilityAttr:$global_visibility,
OptionalAttr<StrAttr>:$sym_visibility,
TypeAttr:$sym_type,
Arg<GlobalLinkageKind, "linkage type">:$linkage,
Expand All @@ -2172,11 +2175,11 @@ def GlobalOp : CIR_Op<"global",
UnitAttr:$dsolocal,
OptionalAttr<I64Attr>:$alignment,
OptionalAttr<ASTVarDeclInterface>:$ast,
OptionalAttr<StrAttr>:$section
);
OptionalAttr<StrAttr>:$section);
let regions = (region AnyRegion:$ctorRegion, AnyRegion:$dtorRegion);
let assemblyFormat = [{
($sym_visibility^)?
custom<OmitDefaultVisibility>($global_visibility)
(`constant` $constant^)?
$linkage
(`comdat` $comdat^)?
Expand Down Expand Up @@ -2214,7 +2217,8 @@ def GlobalOp : CIR_Op<"global",
CArg<"function_ref<void(OpBuilder &, Location)>",
"nullptr">:$ctorBuilder,
CArg<"function_ref<void(OpBuilder &, Location)>",
"nullptr">:$dtorBuilder)>
"nullptr">:$dtorBuilder)
>
];

let hasVerifier = 1;
Expand Down Expand Up @@ -2939,6 +2943,7 @@ def FuncOp : CIR_Op<"func", [
}];

let arguments = (ins SymbolNameAttr:$sym_name,
VisibilityAttr:$global_visibility,
TypeAttrOf<CIR_FuncType>:$function_type,
UnitAttr:$builtin,
UnitAttr:$coroutine,
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CIR/CodeGen/CIRGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,7 @@ mlir::cir::GlobalOp CIRGenFunction::addInitializerToStaticVarDecl(
// FIXME(cir): OG codegen inserts new GV before old one, we probably don't
// need that?
GV.setVisibility(OldGV.getVisibility());
GV.setGlobalVisibilityAttr(OldGV.getGlobalVisibilityAttr());
GV.setInitialValueAttr(Init);
GV.setTlsModelAttr(OldGV.getTlsModelAttr());
assert(!MissingFeatures::setDSOLocal());
Expand Down
36 changes: 34 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,8 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef MangledName, mlir::Type Ty,
GV.setSectionAttr(builder.getStringAttr(SA->getName()));
}

GV.setGlobalVisibilityAttr(getGlobalVisibilityAttrFromDecl(D));

// Handle XCore specific ABI requirements.
if (getTriple().getArch() == llvm::Triple::xcore)
assert(0 && "not implemented");
Expand Down Expand Up @@ -1246,6 +1248,8 @@ void CIRGenModule::buildGlobalVarDefinition(const clang::VarDecl *D,
if (const SectionAttr *SA = D->getAttr<SectionAttr>())
GV.setSectionAttr(builder.getStringAttr(SA->getName()));

GV.setGlobalVisibilityAttr(getGlobalVisibilityAttrFromDecl(D));

// TODO(cir):
// GV->setAlignment(getContext().getDeclAlign(D).getAsAlign());

Expand Down Expand Up @@ -1316,7 +1320,6 @@ void CIRGenModule::buildGlobalVarDefinition(const clang::VarDecl *D,

void CIRGenModule::buildGlobalDefinition(GlobalDecl GD, mlir::Operation *Op) {
const auto *D = cast<ValueDecl>(GD.getDecl());

if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
// At -O0, don't generate CIR for functions with available_externally
// linkage.
Expand Down Expand Up @@ -1345,8 +1348,9 @@ void CIRGenModule::buildGlobalDefinition(GlobalDecl GD, mlir::Operation *Op) {
return;
}

if (const auto *VD = dyn_cast<VarDecl>(D))
if (const auto *VD = dyn_cast<VarDecl>(D)) {
return buildGlobalVarDefinition(VD, !VD->hasDefinition());
}

llvm_unreachable("Invalid argument to buildGlobalDefinition()");
}
Expand Down Expand Up @@ -1782,6 +1786,32 @@ mlir::SymbolTable::Visibility CIRGenModule::getMLIRVisibilityFromCIRLinkage(
llvm_unreachable("linkage should be handled above!");
}

mlir::cir::VisibilityKind
CIRGenModule::getGlobalVisibilityKindFromClangVisibility(
clang::VisibilityAttr::VisibilityType visibility) {
switch (visibility) {
case clang::VisibilityAttr::VisibilityType::Default:
return VisibilityKind::Default;
case clang::VisibilityAttr::VisibilityType::Hidden:
return VisibilityKind::Hidden;
case clang::VisibilityAttr::VisibilityType::Protected:
return VisibilityKind::Protected;
}
}

mlir::cir::VisibilityAttr
CIRGenModule::getGlobalVisibilityAttrFromDecl(const Decl *decl) {
const clang::VisibilityAttr *VA = decl->getAttr<clang::VisibilityAttr>();
mlir::cir::VisibilityAttr cirVisibility =
mlir::cir::VisibilityAttr::get(builder.getContext());
if (VA) {
cirVisibility = mlir::cir::VisibilityAttr::get(
builder.getContext(),
getGlobalVisibilityKindFromClangVisibility(VA->getVisibility()));
}
return cirVisibility;
}

mlir::cir::GlobalLinkageKind CIRGenModule::getCIRLinkageForDeclarator(
const DeclaratorDecl *D, GVALinkage Linkage, bool IsConstantVariable) {
if (Linkage == GVA_Internal)
Expand Down Expand Up @@ -2401,6 +2431,8 @@ void CIRGenModule::setFunctionAttributes(GlobalDecl globalDecl,

// TODO(cir): Complete the remaining part of the function.
assert(!MissingFeatures::setFunctionAttributes());
auto decl = globalDecl.getDecl();
func.setGlobalVisibilityAttr(getGlobalVisibilityAttrFromDecl(decl));
}

/// If the specified mangled name is not in the module,
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,9 @@ class CIRGenModule : public CIRGenTypeCache {
static void setInitializer(mlir::cir::GlobalOp &op, mlir::Attribute value);
static mlir::SymbolTable::Visibility
getMLIRVisibilityFromCIRLinkage(mlir::cir::GlobalLinkageKind GLK);
static mlir::cir::VisibilityKind getGlobalVisibilityKindFromClangVisibility(
clang::VisibilityAttr::VisibilityType visibility);
mlir::cir::VisibilityAttr getGlobalVisibilityAttrFromDecl(const Decl *decl);
static mlir::SymbolTable::Visibility
getMLIRVisibility(mlir::cir::GlobalOp op);
mlir::cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl GD);
Expand Down
85 changes: 67 additions & 18 deletions clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,36 @@ bool omitRegionTerm(mlir::Region &r) {
return singleNonEmptyBlock && yieldsNothing();
}

void printVisibilityAttr(OpAsmPrinter &printer,
mlir::cir::VisibilityAttr &visibility) {
switch (visibility.getValue()) {
case VisibilityKind::Hidden:
printer << "hidden";
break;
case VisibilityKind::Protected:
printer << "protected";
break;
default:
break;
}
}

void parseVisibilityAttr(OpAsmParser &parser,
mlir::cir::VisibilityAttr &visibility) {
VisibilityKind visibilityKind;

if (parser.parseOptionalKeyword("hidden").succeeded()) {
visibilityKind = VisibilityKind::Hidden;
} else if (parser.parseOptionalKeyword("protected").succeeded()) {
visibilityKind = VisibilityKind::Protected;
} else {
visibilityKind = VisibilityKind::Default;
}

visibility =
mlir::cir::VisibilityAttr::get(parser.getContext(), visibilityKind);
}

//===----------------------------------------------------------------------===//
// CIR Custom Parsers/Printers
//===----------------------------------------------------------------------===//
Expand All @@ -255,6 +285,19 @@ static void printOmittedTerminatorRegion(mlir::OpAsmPrinter &printer,
/*printBlockTerminators=*/!omitRegionTerm(region));
}

static mlir::ParseResult
parseOmitDefaultVisibility(mlir::OpAsmParser &parser,
mlir::cir::VisibilityAttr &visibility) {
parseVisibilityAttr(parser, visibility);
return success();
}

static void printOmitDefaultVisibility(mlir::OpAsmPrinter &printer,
mlir::cir::GlobalOp &op,
mlir::cir::VisibilityAttr visibility) {
printVisibilityAttr(printer, visibility);
}

//===----------------------------------------------------------------------===//
// AllocaOp
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1997,6 +2040,10 @@ void GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState,
odsBuilder.createBlock(dtorRegion);
dtorBuilder(odsBuilder, odsState.location);
}

odsState.addAttribute(
getGlobalVisibilityAttrName(odsState.name),
mlir::cir::VisibilityAttr::get(odsBuilder.getContext()));
}

/// Given the region at `index`, or the parent operation if `index` is None,
Expand Down Expand Up @@ -2145,6 +2192,9 @@ void cir::FuncOp::build(OpBuilder &builder, OperationState &result,
GlobalLinkageKindAttr::get(builder.getContext(), linkage));
result.addAttribute(getCallingConvAttrName(result.name),
CallingConvAttr::get(builder.getContext(), callingConv));
result.addAttribute(getGlobalVisibilityAttrName(result.name),
mlir::cir::VisibilityAttr::get(builder.getContext()));

result.attributes.append(attrs.begin(), attrs.end());
if (argAttrs.empty())
return;
Expand All @@ -2163,6 +2213,7 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
auto lambdaNameAttr = getLambdaAttrName(state.name);
auto visNameAttr = getSymVisibilityAttrName(state.name);
auto noProtoNameAttr = getNoProtoAttrName(state.name);
auto visibilityNameAttr = getGlobalVisibilityAttrName(state.name);
auto dsolocalNameAttr = getDsolocalAttrName(state.name);
if (::mlir::succeeded(parser.parseOptionalKeyword(builtinNameAttr.strref())))
state.addAttribute(builtinNameAttr, parser.getBuilder().getUnitAttr());
Expand All @@ -2187,6 +2238,11 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
state.addAttribute(visNameAttr,
parser.getBuilder().getStringAttr(visAttrStr));
}

mlir::cir::VisibilityAttr cirVisibilityAttr;
parseVisibilityAttr(parser, cirVisibilityAttr);
state.addAttribute(visibilityNameAttr, cirVisibilityAttr);

if (parser.parseOptionalKeyword(dsolocalNameAttr).succeeded())
state.addAttribute(dsolocalNameAttr, parser.getBuilder().getUnitAttr());

Expand Down Expand Up @@ -2393,6 +2449,10 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
if (vis != mlir::SymbolTable::Visibility::Public)
p << vis << " ";

auto cirVisibilityAttr = getGlobalVisibilityAttr();
printVisibilityAttr(p, cirVisibilityAttr);
p << " ";

// Print function name, signature, and control.
p.printSymbolName(getSymName());
auto fnType = getFunctionType();
Expand All @@ -2407,24 +2467,13 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
function_interface_impl::printFunctionAttributes(
p, *this,
// These are all omitted since they are custom printed already.
{
getAliaseeAttrName(),
getBuiltinAttrName(),
getCoroutineAttrName(),
getDsolocalAttrName(),
getExtraAttrsAttrName(),
getFunctionTypeAttrName(),
getGlobalCtorAttrName(),
getGlobalDtorAttrName(),
getLambdaAttrName(),
getLinkageAttrName(),
getCallingConvAttrName(),
getNoProtoAttrName(),
getSymVisibilityAttrName(),
getArgAttrsAttrName(),
getResAttrsAttrName(),
getComdatAttrName(),
});
{getAliaseeAttrName(), getBuiltinAttrName(), getCoroutineAttrName(),
getDsolocalAttrName(), getExtraAttrsAttrName(),
getFunctionTypeAttrName(), getGlobalCtorAttrName(),
getGlobalDtorAttrName(), getLambdaAttrName(), getLinkageAttrName(),
getCallingConvAttrName(), getNoProtoAttrName(),
getSymVisibilityAttrName(), getArgAttrsAttrName(), getResAttrsAttrName(),
getComdatAttrName(), getGlobalVisibilityAttrName()});

if (auto aliaseeName = getAliasee()) {
p << " alias(";
Expand Down
Loading

0 comments on commit a1b7883

Please sign in to comment.