Skip to content

Commit 7f3444a

Browse files
seven-milelanza
authored andcommitted
[CIR][CIRGen][LowerToLLVM] Add address space attribute for pointer type (#606)
This is the prelude of address space support. Linked issue: #418 . - Add the attribute and implement asm format & type conversion. - Make ops like `cir.global` and `cir.get_global` aware of address space, and solve the latter flag. - Relax the restriction of default alloca address space. Then we can use correct address spaces for languages like OpenCL in future.
1 parent 1af55b2 commit 7f3444a

File tree

6 files changed

+68
-9
lines changed

6 files changed

+68
-9
lines changed

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

+18-2
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,25 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr",
208208
`CIR.ptr` is a type returned by any op generating a pointer in C++.
209209
}];
210210

211-
let parameters = (ins "mlir::Type":$pointee);
211+
let parameters = (ins "mlir::Type":$pointee,
212+
DefaultValuedParameter<"unsigned", "0">:$addrSpace);
212213

213-
let assemblyFormat = "`<` $pointee `>`";
214+
let builders = [
215+
TypeBuilderWithInferredContext<(ins
216+
"mlir::Type":$pointee, CArg<"unsigned", "0">:$addrSpace), [{
217+
return Base::get(pointee.getContext(), pointee, addrSpace);
218+
}]>,
219+
TypeBuilder<(ins
220+
"mlir::Type":$pointee, CArg<"unsigned", "0">:$addrSpace), [{
221+
return Base::get($_ctxt, pointee, addrSpace);
222+
}]>,
223+
];
224+
225+
let assemblyFormat = [{
226+
`<` $pointee ( `,` `addrspace` `(` $addrSpace^ `)` )? `>`
227+
}];
228+
229+
let skipDefaultBuilders = 1;
214230

215231
let extraClassDeclaration = [{
216232
bool isVoidPtr() const {

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -598,9 +598,9 @@ mlir::Type CIRGenTypes::ConvertType(QualType T) {
598598
const ReferenceType *RTy = cast<ReferenceType>(Ty);
599599
QualType ETy = RTy->getPointeeType();
600600
auto PointeeType = convertTypeForMem(ETy);
601-
// TODO(cir): use Context.getTargetAddressSpace(ETy) on pointer
602-
ResultType =
603-
::mlir::cir::PointerType::get(Builder.getContext(), PointeeType);
601+
ResultType = ::mlir::cir::PointerType::get(
602+
Builder.getContext(), PointeeType,
603+
Context.getTargetAddressSpace(ETy.getAddressSpace()));
604604
assert(ResultType && "Cannot get pointer type?");
605605
break;
606606
}
@@ -615,9 +615,9 @@ mlir::Type CIRGenTypes::ConvertType(QualType T) {
615615
// if (PointeeType->isVoidTy())
616616
// PointeeType = Builder.getI8Type();
617617

618-
// FIXME: add address specifier to cir::PointerType?
619-
ResultType =
620-
::mlir::cir::PointerType::get(Builder.getContext(), PointeeType);
618+
ResultType = ::mlir::cir::PointerType::get(
619+
Builder.getContext(), PointeeType,
620+
Context.getTargetAddressSpace(ETy.getAddressSpace()));
621621
assert(ResultType && "Cannot get pointer type?");
622622
break;
623623
}

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -3182,7 +3182,8 @@ void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
31823182
mlir::DataLayout &dataLayout) {
31833183
converter.addConversion([&](mlir::cir::PointerType type) -> mlir::Type {
31843184
// Drop pointee type since LLVM dialect only allows opaque pointers.
3185-
return mlir::LLVM::LLVMPointerType::get(type.getContext());
3185+
return mlir::LLVM::LLVMPointerType::get(type.getContext(),
3186+
type.getAddrSpace());
31863187
});
31873188
converter.addConversion([&](mlir::cir::ArrayType type) -> mlir::Type {
31883189
auto ty = converter.convertType(type.getEltType());
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -S -emit-llvm %s -o %t.ll
4+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
5+
// XFAIL: *
6+
7+
// CIR: cir.func {{@.*foo.*}}(%arg0: !cir.ptr<!s32i, addrspace(1)>
8+
// LLVM: define void @foo(ptr addrspace(1) %0)
9+
void foo(int __attribute__((address_space(1))) *arg) {
10+
return;
11+
}

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

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: cir-opt %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s
3+
4+
!s32i = !cir.int<s, 32>
5+
6+
module {
7+
// CHECK: @test_addrspace_assembly_format(%arg0: !cir.ptr<!s32i>)
8+
cir.func @test_addrspace_assembly_format(%arg0: !cir.ptr<!s32i, addrspace(0)>) {
9+
cir.return
10+
}
11+
}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: cir-translate %s -cir-to-llvmir -o %t.ll
2+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
3+
4+
!s32i = !cir.int<s, 32>
5+
6+
module {
7+
// LLVM: define void @foo(ptr %0)
8+
cir.func @foo(%arg0: !cir.ptr<!s32i>) {
9+
// LLVM-NEXT: alloca ptr,
10+
%0 = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["arg", init] {alignment = 8 : i64}
11+
cir.return
12+
}
13+
14+
// LLVM: define void @bar(ptr addrspace(1) %0)
15+
cir.func @bar(%arg0: !cir.ptr<!s32i, addrspace(1)>) {
16+
// LLVM-NEXT: alloca ptr addrspace(1)
17+
%0 = cir.alloca !cir.ptr<!s32i, addrspace(1)>, !cir.ptr<!cir.ptr<!s32i, addrspace(1)>>, ["arg", init] {alignment = 8 : i64}
18+
cir.return
19+
}
20+
}

0 commit comments

Comments
 (0)