Skip to content

Commit ffb19f4

Browse files
authored
[CIR] Infrastructure: class CIRGenBuilderTy; cache CIR types (#119037)
Small infrastructure and background changes to ClangIR. Create class `CIRGenBuilderTy` and its base class `CIRBaseBuilderTy`. These are mostly empty for now, except for what is inherited from `mlir::OpBuilder`. But they will fill up quickly as more ClangIR code gen is upstreamed. `CIRGenModule` and `CIRGenTypes` are changed to use `CIRGenBuilderTy`. Add cached types to struct `CIRGenTypeCache` for the integral types that are currently supported. Initialize those cached types in the `CIRGenModule` constructor. The first uses of those types (well, one of them) is in `CIRGenTypes::convertType`. Have `CIRGenTypes::convertType` cache its results in a map from `clang::Type` to `mlir::Type`, saving it from having to convert the same type again and again. There are no new tests or changed tests in this commit. There are no changes to behavior, just improvements to how the existing behavior is implemented.
1 parent e0f3410 commit ffb19f4

File tree

7 files changed

+121
-22
lines changed

7 files changed

+121
-22
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
10+
#define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
11+
12+
#include "mlir/IR/Builders.h"
13+
14+
namespace cir {
15+
16+
class CIRBaseBuilderTy : public mlir::OpBuilder {
17+
18+
public:
19+
CIRBaseBuilderTy(mlir::MLIRContext &mlirContext)
20+
: mlir::OpBuilder(&mlirContext) {}
21+
};
22+
23+
} // namespace cir
24+
25+
#endif

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENBUILDER_H
10+
#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENBUILDER_H
11+
12+
#include "CIRGenTypeCache.h"
13+
14+
#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
15+
16+
namespace clang::CIRGen {
17+
18+
class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
19+
const CIRGenTypeCache &typeCache;
20+
21+
public:
22+
CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
23+
: CIRBaseBuilderTy(mlirContext), typeCache(tc) {}
24+
};
25+
26+
} // namespace clang::CIRGen
27+
28+
#endif

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,22 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
2929
clang::ASTContext &astctx,
3030
const clang::CodeGenOptions &cgo,
3131
DiagnosticsEngine &diags)
32-
: builder(&context), astCtx(astctx), langOpts(astctx.getLangOpts()),
32+
: builder(context, *this), astCtx(astctx), langOpts(astctx.getLangOpts()),
3333
theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&context))},
34-
diags(diags), target(astCtx.getTargetInfo()), genTypes(*this) {}
34+
diags(diags), target(astctx.getTargetInfo()), genTypes(*this) {
35+
36+
// Initialize cached types
37+
SInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/true);
38+
SInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/true);
39+
SInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/true);
40+
SInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/true);
41+
SInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/true);
42+
UInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/false);
43+
UInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/false);
44+
UInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/false);
45+
UInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/false);
46+
UInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/false);
47+
}
3548

3649
mlir::Location CIRGenModule::getLoc(SourceLocation cLoc) {
3750
assert(cLoc.isValid() && "expected valid source location");

clang/lib/CIR/CodeGen/CIRGenModule.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
1414
#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
1515

16+
#include "CIRGenBuilder.h"
1617
#include "CIRGenTypeCache.h"
1718
#include "CIRGenTypes.h"
1819

@@ -47,9 +48,7 @@ class CIRGenModule : public CIRGenTypeCache {
4748
~CIRGenModule() = default;
4849

4950
private:
50-
// TODO(CIR) 'builder' will change to CIRGenBuilderTy once that type is
51-
// defined
52-
mlir::OpBuilder builder;
51+
CIRGenBuilderTy builder;
5352

5453
/// Hold Clang AST information.
5554
clang::ASTContext &astCtx;
@@ -67,9 +66,10 @@ class CIRGenModule : public CIRGenTypeCache {
6766

6867
public:
6968
mlir::ModuleOp getModule() const { return theModule; }
70-
mlir::OpBuilder &getBuilder() { return builder; }
69+
CIRGenBuilderTy &getBuilder() { return builder; }
7170
clang::ASTContext &getASTContext() const { return astCtx; }
7271
CIRGenTypes &getTypes() { return genTypes; }
72+
mlir::MLIRContext &getMLIRContext() { return *builder.getContext(); }
7373

7474
/// Helpers to convert the presumed location of Clang's SourceLocation to an
7575
/// MLIR Location.

clang/lib/CIR/CodeGen/CIRGenTypeCache.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,29 @@
1313
#ifndef LLVM_CLANG_LIB_CIR_CIRGENTYPECACHE_H
1414
#define LLVM_CLANG_LIB_CIR_CIRGENTYPECACHE_H
1515

16+
#include "clang/CIR/Dialect/IR/CIRTypes.h"
17+
1618
namespace clang::CIRGen {
1719

1820
/// This structure provides a set of types that are commonly used
1921
/// during IR emission. It's initialized once in CodeGenModule's
2022
/// constructor and then copied around into new CIRGenFunction's.
2123
struct CIRGenTypeCache {
2224
CIRGenTypeCache() = default;
25+
26+
// ClangIR signed integral types of common sizes
27+
cir::IntType SInt8Ty;
28+
cir::IntType SInt16Ty;
29+
cir::IntType SInt32Ty;
30+
cir::IntType SInt64Ty;
31+
cir::IntType SInt128Ty;
32+
33+
// ClangIR unsigned integral type of common sizes
34+
cir::IntType UInt8Ty;
35+
cir::IntType UInt16Ty;
36+
cir::IntType UInt32Ty;
37+
cir::IntType UInt64Ty;
38+
cir::IntType UInt128Ty;
2339
};
2440

2541
} // namespace clang::CIRGen

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,32 @@ using namespace clang;
99
using namespace clang::CIRGen;
1010

1111
CIRGenTypes::CIRGenTypes(CIRGenModule &genModule)
12-
: cgm(genModule), context(genModule.getASTContext()) {}
12+
: cgm(genModule), context(genModule.getASTContext()),
13+
builder(cgm.getBuilder()) {}
1314

1415
CIRGenTypes::~CIRGenTypes() {}
1516

17+
mlir::MLIRContext &CIRGenTypes::getMLIRContext() const {
18+
return *builder.getContext();
19+
}
20+
1621
mlir::Type CIRGenTypes::convertType(QualType type) {
1722
type = context.getCanonicalType(type);
1823
const Type *ty = type.getTypePtr();
1924

25+
// Has the type already been processed?
26+
TypeCacheTy::iterator tci = typeCache.find(ty);
27+
if (tci != typeCache.end())
28+
return tci->second;
29+
2030
// For types that haven't been implemented yet or are otherwise unsupported,
2131
// report an error and return 'int'.
2232

2333
mlir::Type resultType = nullptr;
2434
switch (ty->getTypeClass()) {
2535
case Type::Builtin: {
2636
switch (cast<BuiltinType>(ty)->getKind()) {
27-
// Signed types.
37+
// Signed integral types.
2838
case BuiltinType::Char_S:
2939
case BuiltinType::Int:
3040
case BuiltinType::Int128:
@@ -33,11 +43,10 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
3343
case BuiltinType::SChar:
3444
case BuiltinType::Short:
3545
case BuiltinType::WChar_S:
36-
resultType = cir::IntType::get(cgm.getBuilder().getContext(),
37-
context.getTypeSize(ty),
46+
resultType = cir::IntType::get(&getMLIRContext(), context.getTypeSize(ty),
3847
/*isSigned=*/true);
3948
break;
40-
// Unsigned types.
49+
// Unsigned integral types.
4150
case BuiltinType::Char8:
4251
case BuiltinType::Char16:
4352
case BuiltinType::Char32:
@@ -49,14 +58,12 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
4958
case BuiltinType::ULongLong:
5059
case BuiltinType::UShort:
5160
case BuiltinType::WChar_U:
52-
resultType = cir::IntType::get(cgm.getBuilder().getContext(),
53-
context.getTypeSize(ty),
61+
resultType = cir::IntType::get(&getMLIRContext(), context.getTypeSize(ty),
5462
/*isSigned=*/false);
5563
break;
5664
default:
5765
cgm.errorNYI(SourceLocation(), "processing of built-in type", type);
58-
resultType = cir::IntType::get(cgm.getBuilder().getContext(), 32,
59-
/*isSigned=*/true);
66+
resultType = cgm.SInt32Ty;
6067
break;
6168
}
6269
break;
@@ -65,23 +72,21 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
6572
const auto *bitIntTy = cast<BitIntType>(type);
6673
if (bitIntTy->getNumBits() > cir::IntType::maxBitwidth()) {
6774
cgm.errorNYI(SourceLocation(), "large _BitInt type", type);
68-
resultType = cir::IntType::get(cgm.getBuilder().getContext(), 32,
69-
/*isSigned=*/true);
75+
resultType = cgm.SInt32Ty;
7076
} else {
71-
resultType =
72-
cir::IntType::get(cgm.getBuilder().getContext(),
73-
bitIntTy->getNumBits(), bitIntTy->isSigned());
77+
resultType = cir::IntType::get(&getMLIRContext(), bitIntTy->getNumBits(),
78+
bitIntTy->isSigned());
7479
}
7580
break;
7681
}
7782
default:
7883
cgm.errorNYI(SourceLocation(), "processing of type", type);
79-
resultType =
80-
cir::IntType::get(cgm.getBuilder().getContext(), 32, /*isSigned=*/true);
84+
resultType = cgm.SInt32Ty;
8185
break;
8286
}
8387

8488
assert(resultType && "Type conversion not yet implemented");
8589

90+
typeCache[ty] = resultType;
8691
return resultType;
8792
}

clang/lib/CIR/CodeGen/CIRGenTypes.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@
1515

1616
#include "clang/CIR/Dialect/IR/CIRTypes.h"
1717

18+
#include "llvm/ADT/SmallPtrSet.h"
19+
1820
namespace clang {
1921
class ASTContext;
2022
class QualType;
23+
class Type;
2124
} // namespace clang
2225

2326
namespace mlir {
@@ -26,18 +29,27 @@ class Type;
2629

2730
namespace clang::CIRGen {
2831

32+
class CIRGenBuilderTy;
2933
class CIRGenModule;
3034

3135
/// This class organizes the cross-module state that is used while lowering
3236
/// AST types to CIR types.
3337
class CIRGenTypes {
3438
CIRGenModule &cgm;
3539
clang::ASTContext &context;
40+
CIRGenBuilderTy &builder;
3641

3742
public:
3843
CIRGenTypes(CIRGenModule &cgm);
3944
~CIRGenTypes();
4045

46+
/// This map of clang::Type to mlir::Type (which includes CIR type) is a
47+
/// cache of types that have already been processed.
48+
using TypeCacheTy = llvm::DenseMap<const clang::Type *, mlir::Type>;
49+
TypeCacheTy typeCache;
50+
51+
mlir::MLIRContext &getMLIRContext() const;
52+
4153
/// Convert a Clang type into a mlir::Type.
4254
mlir::Type convertType(clang::QualType type);
4355
};

0 commit comments

Comments
 (0)