Skip to content

Commit

Permalink
[CIR][CIRGen][LowerToLLVM] Add address space attribute for pointer ty…
Browse files Browse the repository at this point in the history
…pe (llvm#606)

This is the prelude of address space support. Linked issue: llvm#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.
  • Loading branch information
seven-mile authored and lanza committed Oct 12, 2024
1 parent 17d8187 commit 8dede2e
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 9 deletions.
20 changes: 18 additions & 2 deletions clang/include/clang/CIR/Dialect/IR/CIRTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,25 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr",
`CIR.ptr` is a type returned by any op generating a pointer in C++.
}];

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

let assemblyFormat = "`<` $pointee `>`";
let builders = [
TypeBuilderWithInferredContext<(ins
"mlir::Type":$pointee, CArg<"unsigned", "0">:$addrSpace), [{
return Base::get(pointee.getContext(), pointee, addrSpace);
}]>,
TypeBuilder<(ins
"mlir::Type":$pointee, CArg<"unsigned", "0">:$addrSpace), [{
return Base::get($_ctxt, pointee, addrSpace);
}]>,
];

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

let skipDefaultBuilders = 1;

let extraClassDeclaration = [{
bool isVoidPtr() const {
Expand Down
12 changes: 6 additions & 6 deletions clang/lib/CIR/CodeGen/CIRGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,9 +598,9 @@ mlir::Type CIRGenTypes::ConvertType(QualType T) {
const ReferenceType *RTy = cast<ReferenceType>(Ty);
QualType ETy = RTy->getPointeeType();
auto PointeeType = convertTypeForMem(ETy);
// TODO(cir): use Context.getTargetAddressSpace(ETy) on pointer
ResultType =
::mlir::cir::PointerType::get(Builder.getContext(), PointeeType);
ResultType = ::mlir::cir::PointerType::get(
Builder.getContext(), PointeeType,
Context.getTargetAddressSpace(ETy.getAddressSpace()));
assert(ResultType && "Cannot get pointer type?");
break;
}
Expand All @@ -615,9 +615,9 @@ mlir::Type CIRGenTypes::ConvertType(QualType T) {
// if (PointeeType->isVoidTy())
// PointeeType = Builder.getI8Type();

// FIXME: add address specifier to cir::PointerType?
ResultType =
::mlir::cir::PointerType::get(Builder.getContext(), PointeeType);
ResultType = ::mlir::cir::PointerType::get(
Builder.getContext(), PointeeType,
Context.getTargetAddressSpace(ETy.getAddressSpace()));
assert(ResultType && "Cannot get pointer type?");
break;
}
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3184,7 +3184,8 @@ void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
mlir::DataLayout &dataLayout) {
converter.addConversion([&](mlir::cir::PointerType type) -> mlir::Type {
// Drop pointee type since LLVM dialect only allows opaque pointers.
return mlir::LLVM::LLVMPointerType::get(type.getContext());
return mlir::LLVM::LLVMPointerType::get(type.getContext(),
type.getAddrSpace());
});
converter.addConversion([&](mlir::cir::ArrayType type) -> mlir::Type {
auto ty = converter.convertType(type.getEltType());
Expand Down
11 changes: 11 additions & 0 deletions clang/test/CIR/CodeGen/address-space.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -S -emit-llvm %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
// XFAIL: *

// CIR: cir.func {{@.*foo.*}}(%arg0: !cir.ptr<!s32i, addrspace(1)>
// LLVM: define void @foo(ptr addrspace(1) %0)
void foo(int __attribute__((address_space(1))) *arg) {
return;
}
11 changes: 11 additions & 0 deletions clang/test/CIR/IR/address-space.cir
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: cir-opt %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s

!s32i = !cir.int<s, 32>

module {
// CHECK: @test_addrspace_assembly_format(%arg0: !cir.ptr<!s32i>)
cir.func @test_addrspace_assembly_format(%arg0: !cir.ptr<!s32i, addrspace(0)>) {
cir.return
}
}
20 changes: 20 additions & 0 deletions clang/test/CIR/Lowering/address-space.cir
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: cir-translate %s -cir-to-llvmir -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM

!s32i = !cir.int<s, 32>

module {
// LLVM: define void @foo(ptr %0)
cir.func @foo(%arg0: !cir.ptr<!s32i>) {
// LLVM-NEXT: alloca ptr,
%0 = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["arg", init] {alignment = 8 : i64}
cir.return
}

// LLVM: define void @bar(ptr addrspace(1) %0)
cir.func @bar(%arg0: !cir.ptr<!s32i, addrspace(1)>) {
// LLVM-NEXT: alloca ptr addrspace(1)
%0 = cir.alloca !cir.ptr<!s32i, addrspace(1)>, !cir.ptr<!cir.ptr<!s32i, addrspace(1)>>, ["arg", init] {alignment = 8 : i64}
cir.return
}
}

0 comments on commit 8dede2e

Please sign in to comment.