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
23 changes: 9 additions & 14 deletions clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,27 +93,24 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return cir::IntType::get(getContext(), N, true);
}

cir::AddressSpaceAttr getAddrSpaceAttr(clang::LangAS langAS) {
if (langAS == clang::LangAS::Default)
return {};
return cir::AddressSpaceAttr::get(getContext(), langAS);
cir::PointerType getPointerTo(mlir::Type ty) {
return cir::PointerType::get(ty);
}

cir::PointerType getPointerTo(mlir::Type ty,
cir::AddressSpaceAttr cirAS = {}) {
return cir::PointerType::get(ty, cirAS);
cir::PointerType getPointerTo(mlir::Type ty, cir::AddressSpace as) {
return cir::PointerType::get(ty, as);
}

cir::PointerType getPointerTo(mlir::Type ty, clang::LangAS langAS) {
return getPointerTo(ty, getAddrSpaceAttr(langAS));
return getPointerTo(ty, cir::toCIRAddressSpace(langAS));
}

cir::PointerType getVoidPtrTy(clang::LangAS langAS = clang::LangAS::Default) {
return getPointerTo(cir::VoidType::get(getContext()), langAS);
}

cir::PointerType getVoidPtrTy(cir::AddressSpaceAttr cirAS) {
return getPointerTo(cir::VoidType::get(getContext()), cirAS);
cir::PointerType getVoidPtrTy(cir::AddressSpace as) {
return getPointerTo(cir::VoidType::get(getContext()), as);
}

cir::MethodAttr getMethodAttr(cir::MethodType ty, cir::FuncOp methodFuncOp) {
Expand Down Expand Up @@ -396,7 +393,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global,
bool threadLocal = false) {
return create<cir::GetGlobalOp>(
loc, getPointerTo(global.getSymType(), global.getAddrSpaceAttr()),
loc, getPointerTo(global.getSymType(), global.getAddrSpace()),
global.getName(), threadLocal);
}

Expand Down Expand Up @@ -774,9 +771,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
auto methodFuncInputTypes = methodFuncTy.getInputs();

auto objectPtrTy = mlir::cast<cir::PointerType>(objectPtr.getType());
auto objectPtrAddrSpace = mlir::cast_if_present<cir::AddressSpaceAttr>(
objectPtrTy.getAddrSpace());
auto adjustedThisTy = getVoidPtrTy(objectPtrAddrSpace);
auto adjustedThisTy = getVoidPtrTy(objectPtrTy.getAddrSpace());

llvm::SmallVector<mlir::Type, 8> calleeFuncInputTypes{adjustedThisTy};
calleeFuncInputTypes.insert(calleeFuncInputTypes.end(),
Expand Down
137 changes: 15 additions & 122 deletions clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#define MLIR_CIR_DIALECT_CIR_ATTRS

include "mlir/IR/BuiltinAttributeInterfaces.td"
include "mlir/IR/EnumAttr.td"
include "clang/CIR/Dialect/IR/CIREnumAttr.td"

include "clang/CIR/Dialect/IR/CIRDialect.td"
include "clang/CIR/Dialect/IR/CIRAttrConstraints.td"
Expand Down Expand Up @@ -45,21 +45,6 @@ class CIR_TypedAttr<string name, string attrMnemonic, list<Trait> traits = []>
let assemblyFormat = [{}];
}

class CIR_I32EnumAttr<string name, string summary, list<I32EnumAttrCase> cases>
: I32EnumAttr<name, summary, cases> {
let cppNamespace = "::cir";
}

class CIR_I64EnumAttr<string name, string summary, list<I64EnumAttrCase> cases>
: I64EnumAttr<name, summary, cases> {
let cppNamespace = "::cir";
}

class CIR_EnumAttr<EnumAttrInfo info, string name = "", list<Trait> traits = []>
: EnumAttr<CIR_Dialect, info, name, traits> {
let assemblyFormat = "`<` $value `>`";
}

class CIRUnitAttr<string name, string attrMnemonic, list<Trait> traits = []>
: CIR_Attr<name, attrMnemonic, traits> {
let returnType = "bool";
Expand Down Expand Up @@ -972,133 +957,41 @@ def DynamicCastInfoAttr
// AddressSpaceAttr
//===----------------------------------------------------------------------===//

def AS_OffloadPrivate : I32EnumAttrCase<"offload_private", 1>;
def AS_OffloadLocal : I32EnumAttrCase<"offload_local", 2>;
def AS_OffloadGlobal : I32EnumAttrCase<"offload_global", 3>;
def AS_OffloadConstant : I32EnumAttrCase<"offload_constant", 4>;
def AS_OffloadGeneric : I32EnumAttrCase<"offload_generic", 5>;
def AS_Target : I32EnumAttrCase<"target", 6>;

def AddressSpaceAttr : CIR_Attr<"AddressSpace", "addrspace"> {

let summary = "Address space attribute for pointer types";
let description = [{
The address space attribute is used in pointer types. It essentially
provides a unified model on top of `clang::LangAS`, rather than LLVM address
spaces.

The representation is further simplified: `LangAS::Default` is encoded as
a null attribute; many address spaces from different offloading languages
are unified as `offload_*`; etc.

The meaning of `value` parameter is defined as an extensible enum `Kind`,
which encodes target AS as offset to the last language AS.
}];

let parameters = (ins "int32_t":$value);

let assemblyFormat = [{
`<` $value `>`
}];

def CIR_AddressSpaceAttr : CIR_EnumAttr<CIR_AddressSpace, "address_space"> {
let builders = [
AttrBuilder<(ins "clang::LangAS":$langAS), [{
assert(langAS != clang::LangAS::Default &&
"Default address space is encoded as null attribute");
return $_get($_ctxt, getValueFromLangAS(langAS).value());
return $_get($_ctxt, cir::toCIRAddressSpace(langAS));
}]>
];

let cppNamespace = "::cir";

// The following codes implement these conversions:
// clang::LangAS -> int32_t <-> text-form CIR

// CIR_PointerType manipulates the parse- and stringify- methods to provide
// simplified assembly format `custom<PointerAddrSpace>`.

list<I32EnumAttrCase> langASCases = [
AS_OffloadPrivate, AS_OffloadLocal, AS_OffloadGlobal, AS_OffloadConstant,
AS_OffloadGeneric
];
let assemblyFormat = [{
`` custom<AddressSpaceValue>($value)
}];

I32EnumAttrCase targetASCase = AS_Target;
let defaultValue = "cir::AddressSpace::Default";

let extraClassDeclaration = [{
static constexpr char kTargetKeyword[] = "}]#targetASCase.symbol#[{";
static constexpr int32_t kFirstTargetASValue = }]#targetASCase.value#[{;

bool isLang() const;
bool isTarget() const;
unsigned getTargetValue() const;

/// Convert a clang LangAS to its corresponding CIR AS storage value. This
/// helper does not perform any language-specific mappings (e.g. determining
/// the default AS for offloading languages), so these must be handled in
/// the caller.
static std::optional<int32_t> getValueFromLangAS(clang::LangAS v);

/// Helper methods for the assembly format `custom<PointerAddrSpace>`.
static std::optional<int32_t> parseValueFromString(llvm::StringRef s);
static std::optional<llvm::StringRef> stringifyValue(int32_t v);

struct Kind {
}]#!interleave(
!foreach(case, langASCases,
"static constexpr int32_t "#case.symbol#" = "#case.value#";"
), "\n"
)#[{
};
unsigned getAsUnsignedValue() const;
}];

let extraClassDefinition = [{
unsigned $cppClass::getAsUnsignedValue() const {
return static_cast<unsigned>(getValue());
}

bool $cppClass::isLang() const {
return !isTarget();
return cir::isLangAddressSpace(getValue());
}

bool $cppClass::isTarget() const {
return getValue() >= kFirstTargetASValue;
return cir::isTargetAddressSpace(getValue());
}

unsigned $cppClass::getTargetValue() const {
assert(isTarget() && "Not a target address space");
return getValue() - kFirstTargetASValue;
}

std::optional<int32_t>
$cppClass::parseValueFromString(llvm::StringRef str) {
return llvm::StringSwitch<::std::optional<int32_t>>(str)
}]
#
!interleave(
!foreach(case, langASCases,
".Case(\""#case.symbol# "\", "#case.value # ")\n"
),
"\n"
)
#
[{
// Target address spaces are not parsed here
.Default(std::nullopt);
}

std::optional<llvm::StringRef>
$cppClass::stringifyValue(int32_t value) {
switch (value) {
}]
#
!interleave(
!foreach(case, langASCases,
"case "#case.value
# ": return \""#case.symbol # "\";" ),
"\n"
)
#
[{
default:
// Target address spaces are not processed here
return std::nullopt;
}
return cir::getTargetAddressSpaceValue(getValue());
}
}];
}
Expand Down
38 changes: 38 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//===----------------------------------------------------------------------===//
//
// 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 defines the CIR dialect enum base classes
//
//===----------------------------------------------------------------------===//

#ifndef CLANG_CIR_DIALECT_IR_CIRENUMATTR_TD
#define CLANG_CIR_DIALECT_IR_CIRENUMATTR_TD

include "mlir/IR/EnumAttr.td"

class CIR_I32EnumAttr<string name, string summary, list<I32EnumAttrCase> cases>
: I32EnumAttr<name, summary, cases> {
let cppNamespace = "::cir";
}

class CIR_I64EnumAttr<string name, string summary, list<I64EnumAttrCase> cases>
: I64EnumAttr<name, summary, cases> {
let cppNamespace = "::cir";
}

class CIR_EnumAttr<EnumAttrInfo info, string name = "", list<Trait> traits = []>
: EnumAttr<CIR_Dialect, info, name, traits> {
let assemblyFormat = "`<` $value `>`";
}

class CIR_DefaultValuedEnumParameter<EnumAttrInfo info, string value = "">
: EnumParameter<info> {
let defaultValue = value;
}

#endif // CLANG_CIR_DIALECT_IR_CIRENUMATTR_TD
59 changes: 33 additions & 26 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2347,7 +2347,6 @@ def ForOp : CIR_Op<"for", [CIR_LoopOpInterface, NoRegionArguments]> {
// currently handy as part of forwarding appropriate linkage types for LLVM
// lowering, specially useful for C++ support.


/// An enumeration for the kinds of linkage for global values.
def CIR_GlobalLinkageKind : CIR_I32EnumAttr<
"GlobalLinkageKind", "linkage kind", [
Expand Down Expand Up @@ -2396,10 +2395,11 @@ def CIR_TLSModel : CIR_I32EnumAttr<"TLS_Model", "TLS model", [
I32EnumAttrCase<"LocalExec", 3, "tls_local_exec">
]>;

def GlobalOp : CIR_Op<"global",
[DeclareOpInterfaceMethods<RegionBranchOpInterface>,
DeclareOpInterfaceMethods<CIRGlobalValueInterface>,
NoRegionArguments]> {
def CIR_GlobalOp : CIR_Op<"global", [
DeclareOpInterfaceMethods<RegionBranchOpInterface>,
DeclareOpInterfaceMethods<CIRGlobalValueInterface>,
NoRegionArguments
]> {
let summary = "Declares or defines a global variable";
let description = [{
The `cir.global` operation declares or defines a named global variable.
Expand Down Expand Up @@ -2431,26 +2431,33 @@ def GlobalOp : CIR_Op<"global",
// Note that both sym_name and sym_visibility are tied to Symbol trait.
// 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,
DefaultValuedAttr<
CIR_VisibilityAttr,
"VisibilityKind::Default"
>:$global_visibility,
OptionalAttr<StrAttr>:$sym_visibility,
TypeAttr:$sym_type,
CIR_GlobalLinkageKind:$linkage,
OptionalAttr<AddressSpaceAttr>:$addr_space,
OptionalAttr<CIR_TLSModel>:$tls_model,
// Note this can also be a FlatSymbolRefAttr
OptionalAttr<AnyAttr>:$initial_value,
UnitAttr:$comdat,
UnitAttr:$constant,
UnitAttr:$dso_local,
OptionalAttr<I64Attr>:$alignment,
OptionalAttr<ASTVarDeclInterface>:$ast,
OptionalAttr<StrAttr>:$section,
OptionalAttr<ArrayAttr>:$annotations);
let arguments = (ins
SymbolNameAttr:$sym_name,
DefaultValuedAttr<
CIR_VisibilityAttr,
"VisibilityKind::Default"
>:$global_visibility,
OptionalAttr<StrAttr>:$sym_visibility,
TypeAttr:$sym_type,
CIR_GlobalLinkageKind:$linkage,
DefaultValuedAttr<
CIR_AddressSpaceAttr,
"AddressSpace::Default"
>:$addr_space,
OptionalAttr<CIR_TLSModel>:$tls_model,
// Note this can also be a FlatSymbolRefAttr
OptionalAttr<AnyAttr>:$initial_value,
UnitAttr:$comdat,
UnitAttr:$constant,
UnitAttr:$dso_local,
OptionalAttr<I64Attr>:$alignment,
OptionalAttr<ASTVarDeclInterface>:$ast,
OptionalAttr<StrAttr>:$section,
OptionalAttr<ArrayAttr>:$annotations
);

let regions = (region AnyRegion:$ctorRegion, AnyRegion:$dtorRegion);

let assemblyFormat = [{
($sym_visibility^)?
(`` $global_visibility^)?
Expand All @@ -2459,7 +2466,7 @@ def GlobalOp : CIR_Op<"global",
(`comdat` $comdat^)?
($tls_model^)?
(`dso_local` $dso_local^)?
(`addrspace` `(` custom<GlobalOpAddrSpace>($addr_space)^ `)`)?
( `addrspace` `(` $addr_space^ `)` )?
$sym_name
custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value, $ctorRegion, $dtorRegion)
($annotations^)?
Expand All @@ -2483,7 +2490,7 @@ def GlobalOp : CIR_Op<"global",
// CIR defaults to external linkage.
CArg<"cir::GlobalLinkageKind",
"cir::GlobalLinkageKind::ExternalLinkage">:$linkage,
CArg<"cir::AddressSpaceAttr", "{}">:$addrSpace,
CArg<"cir::AddressSpace", "cir::AddressSpace::Default">:$addrSpace,
CArg<"llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)>",
"nullptr">:$ctorBuilder,
CArg<"llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)>",
Expand Down
Loading
Loading