Skip to content
Merged
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 @@ -28,6 +28,8 @@

#include "clang/CIR/Dialect/IR/CIRAttrs.h"
#include "clang/CIR/Dialect/IR/CIROpsDialect.h.inc"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
#include "clang/CIR/Interfaces/CIROpInterfaces.h"

// TableGen'erated files for MLIR dialects require that a macro be defined when
// they are included. GET_OP_CLASSES tells the file to define the classes for
Expand Down
74 changes: 70 additions & 4 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ include "clang/CIR/Dialect/IR/CIRDialect.td"
include "clang/CIR/Dialect/IR/CIRTypes.td"
include "clang/CIR/Dialect/IR/CIRAttrs.td"

include "clang/CIR/Interfaces/CIROpInterfaces.td"

include "mlir/IR/BuiltinAttributeInterfaces.td"
include "mlir/IR/EnumAttr.td"
include "mlir/IR/SymbolInterfaces.td"
Expand Down Expand Up @@ -430,6 +432,59 @@ def ScopeOp : CIR_Op<"scope", [
// GlobalOp
//===----------------------------------------------------------------------===//

// Linkage types. This is currently a replay of llvm/IR/GlobalValue.h, this is
// currently handy as part of forwarding appropriate linkage types for LLVM
// lowering, specially useful for C++ support.

// Externally visible function
def Global_ExternalLinkage :
I32EnumAttrCase<"ExternalLinkage", 0, "external">;
// Available for inspection, not emission.
def Global_AvailableExternallyLinkage :
I32EnumAttrCase<"AvailableExternallyLinkage", 1, "available_externally">;
// Keep one copy of function when linking (inline)
def Global_LinkOnceAnyLinkage :
I32EnumAttrCase<"LinkOnceAnyLinkage", 2, "linkonce">;
// Same, but only replaced by something equivalent.
def Global_LinkOnceODRLinkage :
I32EnumAttrCase<"LinkOnceODRLinkage", 3, "linkonce_odr">;
// Keep one copy of named function when linking (weak)
def Global_WeakAnyLinkage :
I32EnumAttrCase<"WeakAnyLinkage", 4, "weak">;
// Same, but only replaced by something equivalent.
def Global_WeakODRLinkage :
I32EnumAttrCase<"WeakODRLinkage", 5, "weak_odr">;
// TODO: should we add something like appending linkage too?
// Special purpose, only applies to global arrays
// def Global_AppendingLinkage :
// I32EnumAttrCase<"AppendingLinkage", 6, "appending">;
// Rename collisions when linking (static functions).
def Global_InternalLinkage :
I32EnumAttrCase<"InternalLinkage", 7, "internal">;
// Like Internal, but omit from symbol table, prefix it with
// "cir_" to prevent clash with MLIR's symbol "private".
def Global_PrivateLinkage :
I32EnumAttrCase<"PrivateLinkage", 8, "cir_private">;
// ExternalWeak linkage description.
def Global_ExternalWeakLinkage :
I32EnumAttrCase<"ExternalWeakLinkage", 9, "extern_weak">;
// Tentative definitions.
def Global_CommonLinkage :
I32EnumAttrCase<"CommonLinkage", 10, "common">;

/// An enumeration for the kinds of linkage for global values.
def GlobalLinkageKind : I32EnumAttr<
"GlobalLinkageKind",
"Linkage type/kind",
[Global_ExternalLinkage, Global_AvailableExternallyLinkage,
Global_LinkOnceAnyLinkage, Global_LinkOnceODRLinkage,
Global_WeakAnyLinkage, Global_WeakODRLinkage,
Global_InternalLinkage, Global_PrivateLinkage,
Global_ExternalWeakLinkage, Global_CommonLinkage
]> {
let cppNamespace = "::cir";
}

// TODO(CIR): For starters, cir.global has only name and type. The other
// properties of a global variable will be added over time as more of ClangIR
// is upstreamed.
Expand All @@ -441,12 +496,19 @@ def GlobalOp : CIR_Op<"global"> {

The backing memory for the variable is allocated statically and is
described by the type of the variable.

The `linkage` tracks C/C++ linkage types, currently very similar to LLVM's.
}];

let arguments = (ins SymbolNameAttr:$sym_name, TypeAttr:$sym_type,
OptionalAttr<AnyAttr>:$initial_value);
let arguments = (ins SymbolNameAttr:$sym_name,
TypeAttr:$sym_type,
Arg<GlobalLinkageKind, "linkage type">:$linkage,
OptionalAttr<AnyAttr>:$initial_value,
UnitAttr:$dsolocal);

let assemblyFormat = [{
$linkage
(`dsolocal` $dsolocal^)?
$sym_name
custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value)
attr-dict
Expand All @@ -459,8 +521,12 @@ def GlobalOp : CIR_Op<"global"> {

let skipDefaultBuilders = 1;

let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name,
"mlir::Type":$sym_type)>];
let builders = [OpBuilder<(ins
"llvm::StringRef":$sym_name,
"mlir::Type":$sym_type,
// CIR defaults to external linkage.
CArg<"cir::GlobalLinkageKind",
"cir::GlobalLinkageKind::ExternalLinkage">:$linkage)>];

let hasVerifier = 1;
}
Expand Down
118 changes: 118 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file declares the CIR enumerations.
//
//===----------------------------------------------------------------------===//

#ifndef CLANG_CIR_DIALECT_IR_CIROPSENUMS_H
#define CLANG_CIR_DIALECT_IR_CIROPSENUMS_H

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

namespace cir {

static bool isExternalLinkage(GlobalLinkageKind linkage) {
return linkage == GlobalLinkageKind::ExternalLinkage;
}
static bool isAvailableExternallyLinkage(GlobalLinkageKind linkage) {
return linkage == GlobalLinkageKind::AvailableExternallyLinkage;
}
static bool isLinkOnceAnyLinkage(GlobalLinkageKind linkage) {
return linkage == GlobalLinkageKind::LinkOnceAnyLinkage;
}
static bool isLinkOnceODRLinkage(GlobalLinkageKind linkage) {
return linkage == GlobalLinkageKind::LinkOnceODRLinkage;
}
static bool isLinkOnceLinkage(GlobalLinkageKind linkage) {
return isLinkOnceAnyLinkage(linkage) || isLinkOnceODRLinkage(linkage);
}
static bool isWeakAnyLinkage(GlobalLinkageKind linkage) {
return linkage == GlobalLinkageKind::WeakAnyLinkage;
}
static bool isWeakODRLinkage(GlobalLinkageKind linkage) {
return linkage == GlobalLinkageKind::WeakODRLinkage;
}
static bool isWeakLinkage(GlobalLinkageKind linkage) {
return isWeakAnyLinkage(linkage) || isWeakODRLinkage(linkage);
}
static bool isInternalLinkage(GlobalLinkageKind linkage) {
return linkage == GlobalLinkageKind::InternalLinkage;
}
static bool isPrivateLinkage(GlobalLinkageKind linkage) {
return linkage == GlobalLinkageKind::PrivateLinkage;
}
static bool isLocalLinkage(GlobalLinkageKind linkage) {
return isInternalLinkage(linkage) || isPrivateLinkage(linkage);
}
static bool isExternalWeakLinkage(GlobalLinkageKind linkage) {
return linkage == GlobalLinkageKind::ExternalWeakLinkage;
}
LLVM_ATTRIBUTE_UNUSED static bool isCommonLinkage(GlobalLinkageKind linkage) {
return linkage == GlobalLinkageKind::CommonLinkage;
}
LLVM_ATTRIBUTE_UNUSED static bool
isValidDeclarationLinkage(GlobalLinkageKind linkage) {
return isExternalWeakLinkage(linkage) || isExternalLinkage(linkage);
}

/// Whether the definition of this global may be replaced by something
/// non-equivalent at link time. For example, if a function has weak linkage
/// then the code defining it may be replaced by different code.
LLVM_ATTRIBUTE_UNUSED static bool
isInterposableLinkage(GlobalLinkageKind linkage) {
switch (linkage) {
case GlobalLinkageKind::WeakAnyLinkage:
case GlobalLinkageKind::LinkOnceAnyLinkage:
case GlobalLinkageKind::CommonLinkage:
case GlobalLinkageKind::ExternalWeakLinkage:
return true;

case GlobalLinkageKind::AvailableExternallyLinkage:
case GlobalLinkageKind::LinkOnceODRLinkage:
case GlobalLinkageKind::WeakODRLinkage:
// The above three cannot be overridden but can be de-refined.

case GlobalLinkageKind::ExternalLinkage:
case GlobalLinkageKind::InternalLinkage:
case GlobalLinkageKind::PrivateLinkage:
return false;
}
llvm_unreachable("Fully covered switch above!");
}

/// Whether the definition of this global may be discarded if it is not used
/// in its compilation unit.
LLVM_ATTRIBUTE_UNUSED static bool
isDiscardableIfUnused(GlobalLinkageKind linkage) {
return isLinkOnceLinkage(linkage) || isLocalLinkage(linkage) ||
isAvailableExternallyLinkage(linkage);
}

/// Whether the definition of this global may be replaced at link time. NB:
/// Using this method outside of the code generators is almost always a
/// mistake: when working at the IR level use isInterposable instead as it
/// knows about ODR semantics.
LLVM_ATTRIBUTE_UNUSED static bool isWeakForLinker(GlobalLinkageKind linkage) {
return linkage == GlobalLinkageKind::WeakAnyLinkage ||
linkage == GlobalLinkageKind::WeakODRLinkage ||
linkage == GlobalLinkageKind::LinkOnceAnyLinkage ||
linkage == GlobalLinkageKind::LinkOnceODRLinkage ||
linkage == GlobalLinkageKind::CommonLinkage ||
linkage == GlobalLinkageKind::ExternalWeakLinkage;
}

LLVM_ATTRIBUTE_UNUSED static bool isValidLinkage(GlobalLinkageKind gl) {
return isExternalLinkage(gl) || isLocalLinkage(gl) || isWeakLinkage(gl) ||
isLinkOnceLinkage(gl);
}

} // namespace cir

#endif // CLANG_CIR_DIALECT_IR_CIROPSENUMS_H
4 changes: 3 additions & 1 deletion clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ add_dependencies(mlir-headers MLIRCIROpsIncGen)

mlir_tablegen(CIROpsAttributes.h.inc -gen-attrdef-decls)
mlir_tablegen(CIROpsAttributes.cpp.inc -gen-attrdef-defs)
add_public_tablegen_target(MLIRCIRAttrsEnumsGen)
mlir_tablegen(CIROpsEnums.h.inc -gen-enum-decls)
mlir_tablegen(CIROpsEnums.cpp.inc -gen-enum-defs)
add_public_tablegen_target(MLIRCIREnumsGen)
29 changes: 29 additions & 0 deletions clang/include/clang/CIR/Interfaces/CIROpInterfaces.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Defines the interface to CIR operations.
//
//===----------------------------------------------------------------------===//

#ifndef CLANG_CIR_INTERFACES_CIR_OP_H
#define CLANG_CIR_INTERFACES_CIR_OP_H

#include "mlir/IR/Attributes.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/Value.h"
#include "mlir/Interfaces/CallInterfaces.h"

#include "clang/AST/Attr.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Mangle.h"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"

/// Include the generated interface declarations.
#include "clang/CIR/Interfaces/CIROpInterfaces.h.inc"

#endif // CLANG_CIR_INTERFACES_CIR_OP_H
Loading