Skip to content
Draft
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
20 changes: 15 additions & 5 deletions clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
Expand Down Expand Up @@ -105,20 +106,29 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return cir::PointerType::get(ty);
}

cir::PointerType getPointerTo(mlir::Type ty, cir::AddressSpace as) {
return cir::PointerType::get(ty, as);
/// Create a pointer type with an address space attribute.
cir::PointerType getPointerTo(mlir::Type ty, mlir::Attribute addrSpaceAttr) {
assert(mlir::isa<cir::ClangAddressSpaceAttr>(addrSpaceAttr) ||
mlir::isa<cir::TargetAddressSpaceAttr>(addrSpaceAttr) &&
"expected address space attribute");
return cir::PointerType::get(ty, addrSpaceAttr);
}

cir::PointerType getPointerTo(mlir::Type ty, clang::LangAS langAS) {
return getPointerTo(ty, cir::toCIRAddressSpace(langAS));
if (langAS == clang::LangAS::Default)
return getPointerTo(ty);

mlir::Attribute addrSpaceAttr =
cir::toCIRClangAddressSpaceAttr(getContext(), langAS);
return getPointerTo(ty, addrSpaceAttr);
}

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

cir::PointerType getVoidPtrTy(cir::AddressSpace as) {
return getPointerTo(cir::VoidType::get(getContext()), as);
cir::PointerType getVoidPtrTy(mlir::Attribute addrSpaceAttr) {
return getPointerTo(cir::VoidType::get(getContext()), addrSpaceAttr);
}

cir::MethodAttr getMethodAttr(cir::MethodType ty, cir::FuncOp methodFuncOp) {
Expand Down
20 changes: 20 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,24 @@ def CIR_AnyTBAAAttr : AnyAttrOf<[
string cppType = "::mlir::Attribute";
}

//===----------------------------------------------------------------------===//
// AddressSpaceAttr constraints
//===----------------------------------------------------------------------===//

// NOTE: We might end up using this only for GlobalOps, as we cannot apply constraints
// to types.
def CIR_AddressSpaceAttrConstraint
: CIR_AttrConstraint<"::cir::ClangAddressSpaceAttr", "clang address space attribute">;

def CIR_TargetAddressSpaceAttrConstraint
: CIR_AttrConstraint<"::cir::TargetAddressSpaceAttr", "target address space attribute">;

def CIR_AnyAddressSpaceAttr : AnyAttrOf<[
CIR_AddressSpaceAttrConstraint,
CIR_TargetAddressSpaceAttrConstraint
]> {
string cppType = "::mlir::Attribute";
let constBuilderCall = "nullptr";
}

#endif // CLANG_CIR_DIALECT_IR_CIRATTRCONSTRAINTS_TD
46 changes: 31 additions & 15 deletions clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
Original file line number Diff line number Diff line change
Expand Up @@ -963,42 +963,58 @@ def CIR_DynamicCastInfoAttr : CIR_Attr<"DynamicCastInfo", "dyn_cast_info"> {
// AddressSpaceAttr
//===----------------------------------------------------------------------===//

def CIR_AddressSpaceAttr : CIR_EnumAttr<CIR_AddressSpace, "address_space"> {
def CIR_ClangAddressSpaceAttr : CIR_EnumAttr<CIR_ClangAddressSpace, "address_space"> {
let builders = [
AttrBuilder<(ins "clang::LangAS":$langAS), [{
return $_get($_ctxt, cir::toCIRAddressSpace(langAS));
return $_get($_ctxt, cir::toCIRClangAddressSpace(langAS));
}]>
];

let assemblyFormat = [{
`(` custom<AddressSpaceValue>($value) `)`
}];

let defaultValue = "cir::AddressSpace::Default";
let defaultValue = "cir::ClangAddressSpace::Default";

let extraClassDeclaration = [{
bool isLang() const;
bool isTarget() const;
unsigned getTargetValue() const;
unsigned getAsUnsignedValue() const;
}];

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

bool $cppClass::isLang() const {
return cir::isLangAddressSpace(getValue());
}
//===----------------------------------------------------------------------===//
// TargetAddressSpaceAttr
//===----------------------------------------------------------------------===//

bool $cppClass::isTarget() const {
return cir::isTargetAddressSpace(getValue());
}
def CIR_TargetAddressSpaceAttr : CIR_Attr<"TargetAddressSpace", "target_address_space"> {
let summary = "Target-specific numeric address space attribute";
let description = [{
The TargetAddressSpaceAttr represents a target-specific numeric address space,
corresponding to the LLVM IR `addressspace` qualifier and the clang
`target_address_space` attribute.

A value of zero represents the default address space. The semantics of non-zero
address spaces are target-specific.

unsigned $cppClass::getTargetValue() const {
return cir::getTargetAddressSpaceValue(getValue());
}
Unlike `AddressSpaceAttr` which represents language-specific address spaces
(like OpenCL/CUDA address spaces), this attribute directly represents a
target-specific numeric address space value.

Example:
```mlir
!cir.ptr<!s32i, target_address_space(1)>
```
}];

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

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

Expand Down
7 changes: 3 additions & 4 deletions clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,14 @@ class CIR_DefaultValuedEnumParameter<EnumAttrInfo info, string value = "">
let defaultValue = value;
}

def CIR_AddressSpace : CIR_I32EnumAttr<
"AddressSpace", "address space kind", [
def CIR_ClangAddressSpace : CIR_I32EnumAttr<
"ClangAddressSpace", "clang address space kind", [
I32EnumAttrCase<"Default", 0, "default">,
I32EnumAttrCase<"OffloadPrivate", 1, "offload_private">,
I32EnumAttrCase<"OffloadLocal", 2, "offload_local">,
I32EnumAttrCase<"OffloadGlobal", 3, "offload_global">,
I32EnumAttrCase<"OffloadConstant", 4, "offload_constant">,
I32EnumAttrCase<"OffloadGeneric", 5, "offload_generic">,
I32EnumAttrCase<"Target", 6, "target">
I32EnumAttrCase<"OffloadGeneric", 5, "offload_generic">
]> {
let description = [{
The `address_space` attribute is used to represent address spaces for
Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2617,8 +2617,8 @@ def CIR_GlobalOp : CIR_Op<"global", [
TypeAttr:$sym_type,
CIR_GlobalLinkageKind:$linkage,
DefaultValuedAttr<
CIR_AddressSpaceAttr,
"AddressSpace::Default"
CIR_AnyAddressSpaceAttr,
"{}"
>:$addr_space,
OptionalAttr<CIR_TLSModel>:$tls_model,
// Note this can also be a FlatSymbolRefAttr
Expand All @@ -2642,7 +2642,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
(`comdat` $comdat^)?
($tls_model^)?
(`dso_local` $dso_local^)?
(`addrspace` `` $addr_space^)?
(` ` custom<GlobalAddressSpaceValue>($addr_space)^ )?
$sym_name
custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value, $ctorRegion, $dtorRegion)
($annotations^)?
Expand All @@ -2666,7 +2666,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
// CIR defaults to external linkage.
CArg<"cir::GlobalLinkageKind",
"cir::GlobalLinkageKind::ExternalLinkage">:$linkage,
CArg<"cir::AddressSpace", "cir::AddressSpace::Default">:$addrSpace,
CArg<"mlir::Attribute", "{}">:$addrSpace,
CArg<"llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)>",
"nullptr">:$ctorBuilder,
CArg<"llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)>",
Expand Down
39 changes: 11 additions & 28 deletions clang/include/clang/CIR/Dialect/IR/CIRTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,37 +34,20 @@ bool isSized(mlir::Type ty);
// AddressSpace helpers
//===----------------------------------------------------------------------===//

cir::AddressSpace toCIRAddressSpace(clang::LangAS langAS);
cir::ClangAddressSpace toCIRClangAddressSpace(clang::LangAS langAS);

constexpr unsigned getAsUnsignedValue(cir::AddressSpace as) {
return static_cast<unsigned>(as);
}

inline constexpr unsigned TargetAddressSpaceOffset =
cir::getMaxEnumValForAddressSpace();

// Target address space is used for target-specific address spaces that are not
// part of the enum. Its value is represented as an offset from the maximum
// value of the enum. Make sure that it is always the last enum value.
static_assert(getAsUnsignedValue(cir::AddressSpace::Target) ==
cir::getMaxEnumValForAddressSpace(),
"Target address space must be the last enum value");

constexpr bool isTargetAddressSpace(cir::AddressSpace as) {
return getAsUnsignedValue(as) >= cir::getMaxEnumValForAddressSpace();
}
/// Convert a LangAS to the appropriate address space attribute.
/// Returns AddressSpaceAttr for language-specific address spaces,
/// or TargetAddressSpaceAttr for target-specific address spaces.
mlir::Attribute toCIRClangAddressSpaceAttr(mlir::MLIRContext *ctx,
clang::LangAS langAS);

constexpr bool isLangAddressSpace(cir::AddressSpace as) {
return !isTargetAddressSpace(as);
}
/// Extract the AddressSpace enum from an address space attribute.
/// Returns Default if the attribute is null.
cir::ClangAddressSpace getCIRClangAddressSpaceFromAttr(mlir::Attribute attr);

constexpr unsigned getTargetAddressSpaceValue(cir::AddressSpace as) {
assert(isTargetAddressSpace(as) && "expected target address space");
return getAsUnsignedValue(as) - TargetAddressSpaceOffset;
}

constexpr cir::AddressSpace computeTargetAddressSpace(unsigned v) {
return static_cast<cir::AddressSpace>(v + TargetAddressSpaceOffset);
constexpr unsigned getAsUnsignedValue(cir::ClangAddressSpace as) {
return static_cast<unsigned>(as);
}

} // namespace cir
Expand Down
21 changes: 14 additions & 7 deletions clang/include/clang/CIR/Dialect/IR/CIRTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
include "clang/CIR/Dialect/IR/CIRDialect.td"
include "clang/CIR/Dialect/IR/CIREnumAttr.td"
include "clang/CIR/Dialect/IR/CIRTypeConstraints.td"
include "clang/CIR/Dialect/IR/CIRAttrConstraints.td"
include "clang/CIR/Interfaces/ASTAttrInterfaces.td"
include "clang/CIR/Interfaces/CIRTypeInterfaces.td"
include "mlir/Interfaces/DataLayoutInterfaces.td"
include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/EnumAttr.td"
include "mlir/IR/CommonAttrConstraints.td"

//===----------------------------------------------------------------------===//
// CIR Types
Expand Down Expand Up @@ -231,32 +233,31 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr", [
```
}];

let genVerifyDecl = 1;

let parameters = (ins
"mlir::Type":$pointee,
CIR_DefaultValuedEnumParameter<
CIR_AddressSpace,
"cir::AddressSpace::Default"
>:$addrSpace
OptionalParameter<"mlir::Attribute">:$addrSpace
);

let skipDefaultBuilders = 1;
let builders = [
TypeBuilderWithInferredContext<(ins
"mlir::Type":$pointee,
CArg<"cir::AddressSpace", "cir::AddressSpace::Default">:$addrSpace), [{
CArg<"mlir::Attribute", "{}">:$addrSpace), [{
return $_get(pointee.getContext(), pointee, addrSpace);
}]>,
TypeBuilder<(ins
"mlir::Type":$pointee,
CArg<"cir::AddressSpace", "cir::AddressSpace::Default">:$addrSpace), [{
CArg<"mlir::Attribute", "{}">:$addrSpace), [{
return $_get($_ctxt, pointee, addrSpace);
}]>
];

let assemblyFormat = [{
`<`
$pointee
( `,` `addrspace` `(` `` custom<AddressSpaceValue>($addrSpace)^ `)` )?
( `,` ` ` custom<AddressSpaceValue>($addrSpace)^ )?
`>`
}];

Expand Down Expand Up @@ -286,6 +287,12 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr", [
return ptrType.isPtrTo(type);
return false;
}

/// Returns true if this pointer type uses a target address space.
bool hasTargetAddressSpace() const;

/// Returns true if this pointer type uses a language (logical) address space.
bool hasLanguageAddressSpace() const;
}];
}

Expand Down
11 changes: 6 additions & 5 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
[[nodiscard]] cir::GlobalOp
createGlobal(mlir::ModuleOp module, mlir::Location loc, mlir::StringRef name,
mlir::Type type, bool isConst, cir::GlobalLinkageKind linkage,
cir::AddressSpace addrSpace = cir::AddressSpace::Default) {
mlir::Attribute addrSpace = {}) {
mlir::OpBuilder::InsertionGuard guard(*this);
setInsertionPointToStart(module.getBody());
return cir::GlobalOp::create(*this, loc, name, type, isConst, linkage,
Expand All @@ -759,10 +759,11 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
/// Creates a versioned global variable. If the symbol is already taken, an ID
/// will be appended to the symbol. The returned global must always be queried
/// for its name so it can be referenced correctly.
[[nodiscard]] cir::GlobalOp createVersionedGlobal(
mlir::ModuleOp module, mlir::Location loc, mlir::StringRef name,
mlir::Type type, bool isConst, cir::GlobalLinkageKind linkage,
cir::AddressSpace addrSpace = cir::AddressSpace::Default) {
[[nodiscard]] cir::GlobalOp
createVersionedGlobal(mlir::ModuleOp module, mlir::Location loc,
mlir::StringRef name, mlir::Type type, bool isConst,
cir::GlobalLinkageKind linkage,
mlir::Attribute addrSpace = {}) {
// Create a unique name if the given name is already taken.
std::string uniqueName;
if (unsigned version = GlobalsVersioning[name.str()]++)
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "clang/Frontend/FrontendDiagnostic.h"

#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/Value.h"
#include "mlir/Support/LLVM.h"
Expand Down Expand Up @@ -1727,9 +1728,9 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
// the AST level this is handled within CreateTempAlloca et al., but for the
// builtin / dynamic alloca we have to handle it here.
assert(!cir::MissingFeatures::addressSpace());
cir::AddressSpace AAS = getCIRAllocaAddressSpace();
cir::AddressSpace EAS = cir::toCIRAddressSpace(
E->getType()->getPointeeType().getAddressSpace());
mlir::Attribute AAS = getCIRAllocaAddressSpace();
mlir::Attribute EAS = cir::toCIRClangAddressSpaceAttr(
&getMLIRContext(), E->getType()->getPointeeType().getAddressSpace());
if (EAS != AAS) {
assert(false && "Non-default address space for alloca NYI");
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CIR/CodeGen/CIRGenCUDANV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ mlir::Operation *CIRGenNVCUDARuntime::getKernelHandle(cir::FuncOp fn,
return CIRGenModule::createGlobalOp(
cgm, fn->getLoc(), globalName,
builder.getPointerTo(fn.getFunctionType()), true,
cir::AddressSpace::Default,
/*addrSpace=*/{},
/*insertPoint=*/nullptr);
});

Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,8 @@ CIRGenModule::getOrCreateStaticVarDecl(const VarDecl &D,
Name = getStaticDeclName(*this, D);

mlir::Type LTy = getTypes().convertTypeForMem(Ty);
cir::AddressSpace AS = cir::toCIRAddressSpace(getGlobalVarAddressSpace(&D));
mlir::Attribute AS = cir::toCIRClangAddressSpaceAttr(&getMLIRContext(),
getGlobalVarAddressSpace(&D));

// OpenCL variables in local address space and CUDA shared
// variables cannot have an initializer.
Expand Down
11 changes: 6 additions & 5 deletions clang/lib/CIR/CodeGen/CIRGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2080,10 +2080,10 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *E) {
case CK_AddressSpaceConversion: {
LValue LV = emitLValue(E->getSubExpr());
QualType DestTy = getContext().getPointerType(E->getType());
cir::AddressSpace SrcAS =
cir::toCIRAddressSpace(E->getSubExpr()->getType().getAddressSpace());
cir::AddressSpace DestAS =
cir::toCIRAddressSpace(E->getType().getAddressSpace());
mlir::Attribute SrcAS = cir::toCIRClangAddressSpaceAttr(
&getMLIRContext(), E->getSubExpr()->getType().getAddressSpace());
mlir::Attribute DestAS = cir::toCIRClangAddressSpaceAttr(
&getMLIRContext(), E->getType().getAddressSpace());
mlir::Value V = getTargetHooks().performAddrSpaceCast(
*this, LV.getPointer(), SrcAS, DestAS, convertType(DestTy));
return makeAddrLValue(Address(V, convertTypeForMem(E->getType()),
Expand Down Expand Up @@ -3137,7 +3137,8 @@ Address CIRGenFunction::CreateTempAlloca(mlir::Type Ty, CharUnits Align,
// be different from the type defined by the language. For example,
// in C++ the auto variables are in the default address space. Therefore
// cast alloca to the default address space when necessary.
if (auto ASTAS = cir::toCIRAddressSpace(CGM.getLangTempAllocaAddressSpace());
if (auto ASTAS = cir::toCIRClangAddressSpaceAttr(
&getMLIRContext(), CGM.getLangTempAllocaAddressSpace());
getCIRAllocaAddressSpace() != ASTAS) {
llvm_unreachable("Requires address space cast which is NYI");
}
Expand Down
Loading
Loading