Skip to content

Commit dafb6eb

Browse files
seven-milejopperm
andauthored
[CIR][Dialect] Add minimal definitions of unified address space offload_* cases (#738)
This PR adds definitions of unified address space cases `offload_*` discussed in [this RFC thread](https://discourse.llvm.org/t/rfc-clangir-unified-address-space-design-in-clangir/79728). It also refactors the `getValueFromLangAS` method in tablegen to a hand-written method, because it should be a non-trivial map for unified AS. --------- Co-authored-by: Julian Oppermann <[email protected]>
1 parent b365964 commit dafb6eb

File tree

3 files changed

+95
-34
lines changed

3 files changed

+95
-34
lines changed

clang/include/clang/CIR/Dialect/IR/CIRAttrs.td

+32-34
Original file line numberDiff line numberDiff line change
@@ -652,19 +652,27 @@ def DynamicCastInfoAttr
652652
// AddressSpaceAttr
653653
//===----------------------------------------------------------------------===//
654654

655-
// TODO: other CIR AS cases
656-
def AS_Target : I32EnumAttrCase<"target", 21>;
655+
def AS_OffloadPrivate : I32EnumAttrCase<"offload_private", 1>;
656+
def AS_OffloadLocal : I32EnumAttrCase<"offload_local", 2>;
657+
def AS_OffloadGlobal : I32EnumAttrCase<"offload_global", 3>;
658+
def AS_OffloadConstant : I32EnumAttrCase<"offload_constant", 4>;
659+
def AS_OffloadGeneric : I32EnumAttrCase<"offload_generic", 5>;
660+
def AS_Target : I32EnumAttrCase<"target", 6>;
657661

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

660664
let summary = "Address space attribute for pointer types";
661665
let description = [{
662-
The address space attribute models `clang::LangAS` rather than the LLVM
663-
address space, which means it's not yet converted by the address space map
664-
to carry target-specific semantics.
666+
The address space attribute is used in pointer types. It essentially
667+
provides a unified model on top of `clang::LangAS`, rather than LLVM address
668+
spaces.
665669

666-
The representation is one-to-one except for `LangAS::Default`, which
667-
corresponds to a null attribute instead.
670+
The representation is further simplified: `LangAS::Default` is encoded as
671+
a null attribute; many address spaces from different offloading languages
672+
are unified as `offload_*`; etc.
673+
674+
The meaning of `value` parameter is defined as an extensible enum `Kind`,
675+
which encodes target AS as offset to the last language AS.
668676
}];
669677

670678
let parameters = (ins "int32_t":$value);
@@ -690,7 +698,8 @@ def AddressSpaceAttr : CIR_Attr<"AddressSpace", "addrspace"> {
690698
// simplified assembly format `custom<PointerAddrSpace>`.
691699

692700
list<I32EnumAttrCase> langASCases = [
693-
// TODO: includes all non-target CIR AS cases here
701+
AS_OffloadPrivate, AS_OffloadLocal, AS_OffloadGlobal, AS_OffloadConstant,
702+
AS_OffloadGeneric
694703
];
695704

696705
I32EnumAttrCase targetASCase = AS_Target;
@@ -703,9 +712,23 @@ def AddressSpaceAttr : CIR_Attr<"AddressSpace", "addrspace"> {
703712
bool isTarget() const;
704713
unsigned getTargetValue() const;
705714

706-
static std::optional<int32_t> parseValueFromString(llvm::StringRef s);
715+
/// Convert a clang LangAS to its corresponding CIR AS storage value. This
716+
/// helper does not perform any language-specific mappings (e.g. determining
717+
/// the default AS for offloading languages), so these must be handled in
718+
/// the caller.
707719
static std::optional<int32_t> getValueFromLangAS(clang::LangAS v);
720+
721+
/// Helper methods for the assembly format `custom<PointerAddrSpace>`.
722+
static std::optional<int32_t> parseValueFromString(llvm::StringRef s);
708723
static std::optional<llvm::StringRef> stringifyValue(int32_t v);
724+
725+
struct Kind {
726+
}]#!interleave(
727+
!foreach(case, langASCases,
728+
"static constexpr int32_t "#case.symbol#" = "#case.value#";"
729+
), "\n"
730+
)#[{
731+
};
709732
}];
710733

711734
let extraClassDefinition = [{
@@ -757,31 +780,6 @@ def AddressSpaceAttr : CIR_Attr<"AddressSpace", "addrspace"> {
757780
return std::nullopt;
758781
}
759782
}
760-
761-
std::optional<int32_t>
762-
$cppClass::getValueFromLangAS(clang::LangAS langAS) {
763-
assert((langAS == clang::LangAS::Default ||
764-
clang::isTargetAddressSpace(langAS)) &&
765-
"Language-specific address spaces are not supported");
766-
switch (langAS) {
767-
}]
768-
#
769-
!interleave(
770-
!foreach(case, langASCases,
771-
"case clang::LangAS::"#case.symbol
772-
# [{: llvm_unreachable("Not Yet Supported");}] ),
773-
"\n"
774-
)
775-
#
776-
[{
777-
case clang::LangAS::Default:
778-
// Default address space should be encoded as a null attribute.
779-
return std::nullopt;
780-
default:
781-
// Target address space offset arithmetics
782-
return clang::toTargetAddressSpace(langAS) + kFirstTargetASValue;
783-
}
784-
}
785783
}];
786784
}
787785

clang/lib/CIR/Dialect/IR/CIRAttrs.cpp

+38
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,44 @@ LogicalResult OpenCLKernelMetadataAttr::verify(
553553
return success();
554554
}
555555

556+
//===----------------------------------------------------------------------===//
557+
// AddressSpaceAttr definitions
558+
//===----------------------------------------------------------------------===//
559+
560+
std::optional<int32_t>
561+
AddressSpaceAttr::getValueFromLangAS(clang::LangAS langAS) {
562+
using clang::LangAS;
563+
switch (langAS) {
564+
case LangAS::Default:
565+
// Default address space should be encoded as a null attribute.
566+
return std::nullopt;
567+
case LangAS::opencl_global:
568+
case LangAS::opencl_local:
569+
case LangAS::opencl_constant:
570+
case LangAS::opencl_private:
571+
case LangAS::opencl_generic:
572+
case LangAS::opencl_global_device:
573+
case LangAS::opencl_global_host:
574+
case LangAS::cuda_device:
575+
case LangAS::cuda_constant:
576+
case LangAS::cuda_shared:
577+
case LangAS::sycl_global:
578+
case LangAS::sycl_global_device:
579+
case LangAS::sycl_global_host:
580+
case LangAS::sycl_local:
581+
case LangAS::sycl_private:
582+
case LangAS::ptr32_sptr:
583+
case LangAS::ptr32_uptr:
584+
case LangAS::ptr64:
585+
case LangAS::hlsl_groupshared:
586+
case LangAS::wasm_funcref:
587+
llvm_unreachable("NYI");
588+
default:
589+
// Target address space offset arithmetics
590+
return clang::toTargetAddressSpace(langAS) + kFirstTargetASValue;
591+
}
592+
}
593+
556594
//===----------------------------------------------------------------------===//
557595
// CIR Dialect
558596
//===----------------------------------------------------------------------===//

clang/test/CIR/IR/address-space.cir

+25
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,29 @@ module {
1313
cir.func @test_format2(%arg0: !cir.ptr<!s32i>) {
1414
cir.return
1515
}
16+
17+
// CHECK: @test_format3(%arg0: !cir.ptr<!s32i, addrspace(offload_private)>)
18+
cir.func @test_format3(%arg0: !cir.ptr<!s32i, addrspace(offload_private)>) {
19+
cir.return
20+
}
21+
22+
// CHECK: @test_format4(%arg0: !cir.ptr<!s32i, addrspace(offload_local)>)
23+
cir.func @test_format4(%arg0: !cir.ptr<!s32i, addrspace(offload_local)>) {
24+
cir.return
25+
}
26+
27+
// CHECK: @test_format5(%arg0: !cir.ptr<!s32i, addrspace(offload_global)>)
28+
cir.func @test_format5(%arg0: !cir.ptr<!s32i, addrspace(offload_global)>) {
29+
cir.return
30+
}
31+
32+
// CHECK: @test_format6(%arg0: !cir.ptr<!s32i, addrspace(offload_constant)>)
33+
cir.func @test_format6(%arg0: !cir.ptr<!s32i, addrspace(offload_constant)>) {
34+
cir.return
35+
}
36+
37+
// CHECK: @test_format7(%arg0: !cir.ptr<!s32i, addrspace(offload_generic)>)
38+
cir.func @test_format7(%arg0: !cir.ptr<!s32i, addrspace(offload_generic)>) {
39+
cir.return
40+
}
1641
}

0 commit comments

Comments
 (0)