Skip to content

Commit bd0d28a

Browse files
authored
[CIR] Upstream basic support for ArrayType (llvm#130502)
This change adds the basic support for ArrayType Issue llvm#130197
1 parent 31ebe66 commit bd0d28a

File tree

10 files changed

+170
-2
lines changed

10 files changed

+170
-2
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class VarDecl;
3030
class RecordDecl;
3131
} // namespace clang
3232

33+
namespace cir {
34+
class ArrayType;
35+
} // namespace cir
36+
3337
#define GET_ATTRDEF_CLASSES
3438
#include "clang/CIR/Dialect/IR/CIROpsAttributes.h.inc"
3539

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

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,25 @@ def CIR_BoolType :
280280
}];
281281
}
282282

283+
//===----------------------------------------------------------------------===//
284+
// ArrayType
285+
//===----------------------------------------------------------------------===//
286+
287+
def CIR_ArrayType : CIR_Type<"Array", "array",
288+
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
289+
290+
let summary = "CIR array type";
291+
let description = [{
292+
`CIR.array` represents C/C++ constant arrays.
293+
}];
294+
295+
let parameters = (ins "mlir::Type":$eltType, "uint64_t":$size);
296+
297+
let assemblyFormat = [{
298+
`<` $eltType `x` $size `>`
299+
}];
300+
}
301+
283302
//===----------------------------------------------------------------------===//
284303
// FuncType
285304
//===----------------------------------------------------------------------===//
@@ -386,8 +405,8 @@ def VoidPtr : Type<
386405
//===----------------------------------------------------------------------===//
387406

388407
def CIR_AnyType : AnyTypeOf<[
389-
CIR_VoidType, CIR_BoolType, CIR_IntType, CIR_AnyFloat, CIR_PointerType,
390-
CIR_FuncType
408+
CIR_VoidType, CIR_BoolType, CIR_ArrayType, CIR_IntType, CIR_AnyFloat,
409+
CIR_PointerType, CIR_FuncType
391410
]>;
392411

393412
#endif // MLIR_CIR_DIALECT_CIR_TYPES

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ struct MissingFeatures {
8484
static bool astVarDeclInterface() { return false; }
8585
static bool stackSaveOp() { return false; }
8686
static bool aggValueSlot() { return false; }
87+
88+
static bool unsizedTypes() { return false; }
8789
};
8890

8991
} // namespace cir

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "CIRGenTypeCache.h"
1313

1414
#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
15+
#include "clang/CIR/MissingFeatures.h"
1516

1617
namespace clang::CIRGen {
1718

@@ -33,6 +34,15 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
3334
llvm_unreachable("NYI: PPC double-double format for long double");
3435
llvm_unreachable("Unsupported format for long double");
3536
}
37+
38+
bool isSized(mlir::Type ty) {
39+
if (mlir::isa<cir::PointerType, cir::ArrayType, cir::BoolType,
40+
cir::IntType>(ty))
41+
return true;
42+
43+
assert(!cir::MissingFeatures::unsizedTypes());
44+
return false;
45+
}
3646
};
3747

3848
} // namespace clang::CIRGen

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,14 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
202202
break;
203203
}
204204

205+
case Type::ConstantArray: {
206+
const ConstantArrayType *arrTy = cast<ConstantArrayType>(ty);
207+
mlir::Type elemTy = convertTypeForMem(arrTy->getElementType());
208+
resultType = cir::ArrayType::get(builder.getContext(), elemTy,
209+
arrTy->getSize().getZExtValue());
210+
break;
211+
}
212+
205213
case Type::FunctionNoProto:
206214
case Type::FunctionProto:
207215
resultType = convertFunctionTypeInternal(type);

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,22 @@ BoolType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
369369
return 1;
370370
}
371371

372+
//===----------------------------------------------------------------------===//
373+
// Definitions
374+
//===----------------------------------------------------------------------===//
375+
376+
llvm::TypeSize
377+
ArrayType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
378+
::mlir::DataLayoutEntryListRef params) const {
379+
return getSize() * dataLayout.getTypeSizeInBits(getEltType());
380+
}
381+
382+
uint64_t
383+
ArrayType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
384+
::mlir::DataLayoutEntryListRef params) const {
385+
return dataLayout.getTypeABIAlignment(getEltType());
386+
}
387+
372388
//===----------------------------------------------------------------------===//
373389
// PointerType Definitions
374390
//===----------------------------------------------------------------------===//

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,11 @@ static void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
577577

578578
return mlir::LLVM::LLVMPointerType::get(type.getContext(), targetAS);
579579
});
580+
converter.addConversion([&](cir::ArrayType type) -> mlir::Type {
581+
mlir::Type ty =
582+
convertTypeForMemory(converter, dataLayout, type.getEltType());
583+
return mlir::LLVM::LLVMArrayType::get(ty, type.getSize());
584+
});
580585
converter.addConversion([&](cir::BoolType type) -> mlir::Type {
581586
return mlir::IntegerType::get(type.getContext(), 1,
582587
mlir::IntegerType::Signless);

clang/test/CIR/CodeGen/array.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - 2>&1 | FileCheck %s
2+
3+
int a[10];
4+
// CHECK: cir.global external @a : !cir.array<!cir.int<s, 32> x 10>
5+
6+
int aa[10][5];
7+
// CHECK: cir.global external @aa : !cir.array<!cir.array<!cir.int<s, 32> x 5> x 10>
8+
9+
extern int b[10];
10+
// CHECK: cir.global external @b : !cir.array<!cir.int<s, 32> x 10>
11+
12+
extern int bb[10][5];
13+
// CHECK: cir.global external @bb : !cir.array<!cir.array<!cir.int<s, 32> x 5> x 10>
14+
15+
void f() {
16+
int l[10];
17+
// CHECK: %[[ARR:.*]] = cir.alloca !cir.array<!cir.int<s, 32> x 10>, !cir.ptr<!cir.array<!cir.int<s, 32> x 10>>, ["l"]
18+
}
19+
20+
void f2(int p[10]) {}
21+
// CHECK: cir.func @f2(%arg0: !cir.ptr<!cir.int<s, 32>>
22+
// CHECK: cir.alloca !cir.ptr<!cir.int<s, 32>>, !cir.ptr<!cir.ptr<!cir.int<s, 32>>>, ["p", init]
23+
24+
void f3(int pp[10][5]) {}
25+
// CHECK: cir.func @f3(%arg0: !cir.ptr<!cir.array<!cir.int<s, 32> x 5>>
26+
// CHECK: cir.alloca !cir.ptr<!cir.array<!cir.int<s, 32> x 5>>, !cir.ptr<!cir.ptr<!cir.array<!cir.int<s, 32> x 5>>>

clang/test/CIR/IR/array.cir

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// RUN: cir-opt %s | FileCheck %s
2+
3+
module {
4+
5+
cir.global external @a : !cir.array<!cir.int<s, 32> x 10>
6+
// CHECK: cir.global external @a : !cir.array<!cir.int<s, 32> x 10>
7+
8+
cir.global external @aa : !cir.array<!cir.array<!cir.int<s, 32> x 10> x 10>
9+
// CHECK: cir.global external @aa : !cir.array<!cir.array<!cir.int<s, 32> x 10> x 10>
10+
11+
cir.global external @b : !cir.array<!cir.int<s, 32> x 10>
12+
// CHECK: cir.global external @b : !cir.array<!cir.int<s, 32> x 10>
13+
14+
cir.global external @bb : !cir.array<!cir.array<!cir.int<s, 32> x 10> x 10>
15+
// CHECK: cir.global external @bb : !cir.array<!cir.array<!cir.int<s, 32> x 10> x 10>
16+
17+
cir.func @f() {
18+
%0 = cir.alloca !cir.array<!cir.int<s, 32> x 10>, !cir.ptr<!cir.array<!cir.int<s, 32> x 10>>, ["l"] {alignment = 4 : i64}
19+
cir.return
20+
}
21+
22+
// CHECK: cir.func @f() {
23+
// CHECK: %0 = cir.alloca !cir.array<!cir.int<s, 32> x 10>, !cir.ptr<!cir.array<!cir.int<s, 32> x 10>>, ["l"] {alignment = 4 : i64}
24+
// CHECK: cir.return
25+
// CHECK: }
26+
27+
cir.func @f2(%arg0: !cir.ptr<!cir.int<s, 32>>) {
28+
%0 = cir.alloca !cir.ptr<!cir.int<s, 32>>, !cir.ptr<!cir.ptr<!cir.int<s, 32>>>, ["p", init] {alignment = 8 : i64}
29+
cir.store %arg0, %0 : !cir.ptr<!cir.int<s, 32>>, !cir.ptr<!cir.ptr<!cir.int<s, 32>>>
30+
cir.return
31+
}
32+
33+
// CHECK: cir.func @f2(%arg0: !cir.ptr<!cir.int<s, 32>>) {
34+
// CHECK: %0 = cir.alloca !cir.ptr<!cir.int<s, 32>>, !cir.ptr<!cir.ptr<!cir.int<s, 32>>>, ["p", init] {alignment = 8 : i64}
35+
// CHECK: cir.store %arg0, %0 : !cir.ptr<!cir.int<s, 32>>, !cir.ptr<!cir.ptr<!cir.int<s, 32>>>
36+
// CHECK: cir.return
37+
// CHECK: }
38+
39+
cir.func @f3(%arg0: !cir.ptr<!cir.array<!cir.int<s, 32> x 10>>) {
40+
%0 = cir.alloca !cir.ptr<!cir.array<!cir.int<s, 32> x 10>>, !cir.ptr<!cir.ptr<!cir.array<!cir.int<s, 32> x 10>>>, ["pp", init] {alignment = 8 : i64}
41+
cir.store %arg0, %0 : !cir.ptr<!cir.array<!cir.int<s, 32> x 10>>, !cir.ptr<!cir.ptr<!cir.array<!cir.int<s, 32> x 10>>>
42+
cir.return
43+
}
44+
45+
// CHECK: cir.func @f3(%arg0: !cir.ptr<!cir.array<!cir.int<s, 32> x 10>>) {
46+
// CHECK: %0 = cir.alloca !cir.ptr<!cir.array<!cir.int<s, 32> x 10>>, !cir.ptr<!cir.ptr<!cir.array<!cir.int<s, 32> x 10>>>, ["pp", init] {alignment = 8 : i64}
47+
// CHECK: cir.store %arg0, %0 : !cir.ptr<!cir.array<!cir.int<s, 32> x 10>>, !cir.ptr<!cir.ptr<!cir.array<!cir.int<s, 32> x 10>>>
48+
// CHECK: cir.return
49+
// CHECK: }
50+
51+
}

clang/test/CIR/Lowering/array.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - 2>&1 | FileCheck %s
2+
3+
int a[10];
4+
// CHECK: @a = external dso_local global [10 x i32]
5+
6+
int aa[10][5];
7+
// CHECK: @aa = external dso_local global [10 x [5 x i32]]
8+
9+
extern int b[10];
10+
// CHECK: @b = external dso_local global [10 x i32]
11+
12+
extern int bb[10][5];
13+
// CHECK: @bb = external dso_local global [10 x [5 x i32]]
14+
15+
void f() {
16+
int l[10];
17+
}
18+
// CHECK: define void @f()
19+
// CHECK-NEXT: alloca [10 x i32], i64 1, align 16
20+
21+
void f2(int p[10]) {}
22+
// CHECK: define void @f2(ptr {{%.*}})
23+
// CHECK-NEXT: alloca ptr, i64 1, align 8
24+
25+
void f3(int pp[10][5]) {}
26+
// CHECK: define void @f3(ptr {{%.*}})
27+
// CHECK-NEXT: alloca ptr, i64 1, align 8

0 commit comments

Comments
 (0)