Skip to content

Commit 97357e1

Browse files
authored
[CIR][CIRGen] Add initial CIRGen support for local temporary materialization (#820)
This PR adds initial support for temporary materialization of local temporaries with trivial cleanups. Materialization of global temporaries and local temporaries with non-trivial cleanups is far more trickier that I initially thought and I decide to submit this easy part first.
1 parent 987f1e1 commit 97357e1

File tree

3 files changed

+69
-8
lines changed

3 files changed

+69
-8
lines changed

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,8 +2146,22 @@ static Address createReferenceTemporary(CIRGenFunction &CGF,
21462146
(Ty->isArrayType() || Ty->isRecordType()) &&
21472147
CGF.CGM.isTypeConstant(Ty, /*ExcludeCtor=*/true, /*ExcludeDtor=*/false))
21482148
assert(0 && "NYI");
2149+
2150+
// The temporary memory should be created in the same scope as the extending
2151+
// declaration of the temporary materialization expression.
2152+
mlir::cir::AllocaOp extDeclAlloca;
2153+
if (const clang::ValueDecl *extDecl = M->getExtendingDecl()) {
2154+
auto extDeclAddrIter = CGF.LocalDeclMap.find(extDecl);
2155+
if (extDeclAddrIter != CGF.LocalDeclMap.end()) {
2156+
extDeclAlloca = dyn_cast_if_present<mlir::cir::AllocaOp>(
2157+
extDeclAddrIter->second.getDefiningOp());
2158+
}
2159+
}
2160+
mlir::OpBuilder::InsertPoint ip;
2161+
if (extDeclAlloca)
2162+
ip = {extDeclAlloca->getBlock(), extDeclAlloca->getIterator()};
21492163
return CGF.CreateMemTemp(Ty, CGF.getLoc(M->getSourceRange()),
2150-
CGF.getCounterRefTmpAsString(), Alloca);
2164+
CGF.getCounterRefTmpAsString(), Alloca, ip);
21512165
}
21522166
case SD_Thread:
21532167
case SD_Static:
@@ -2245,7 +2259,7 @@ LValue CIRGenFunction::buildMaterializeTemporaryExpr(
22452259
} else {
22462260
switch (M->getStorageDuration()) {
22472261
case SD_Automatic:
2248-
assert(0 && "NYI");
2262+
assert(!MissingFeatures::shouldEmitLifetimeMarkers());
22492263
break;
22502264

22512265
case SD_FullExpression: {
@@ -2932,18 +2946,20 @@ void CIRGenFunction::buildUnreachable(SourceLocation Loc) {
29322946
//===----------------------------------------------------------------------===//
29332947

29342948
Address CIRGenFunction::CreateMemTemp(QualType Ty, mlir::Location Loc,
2935-
const Twine &Name, Address *Alloca) {
2949+
const Twine &Name, Address *Alloca,
2950+
mlir::OpBuilder::InsertPoint ip) {
29362951
// FIXME: Should we prefer the preferred type alignment here?
29372952
return CreateMemTemp(Ty, getContext().getTypeAlignInChars(Ty), Loc, Name,
2938-
Alloca);
2953+
Alloca, ip);
29392954
}
29402955

29412956
Address CIRGenFunction::CreateMemTemp(QualType Ty, CharUnits Align,
29422957
mlir::Location Loc, const Twine &Name,
2943-
Address *Alloca) {
2958+
Address *Alloca,
2959+
mlir::OpBuilder::InsertPoint ip) {
29442960
Address Result =
29452961
CreateTempAlloca(getTypes().convertTypeForMem(Ty), Align, Loc, Name,
2946-
/*ArraySize=*/nullptr, Alloca);
2962+
/*ArraySize=*/nullptr, Alloca, ip);
29472963
if (Ty->isConstantMatrixType()) {
29482964
assert(0 && "NYI");
29492965
}

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,9 +2215,11 @@ class CIRGenFunction : public CIRGenTypeCache {
22152215
/// appropriate alignmen and cast it to the default address space. Returns
22162216
/// the original alloca instruction by \p Alloca if it is not nullptr.
22172217
Address CreateMemTemp(QualType T, mlir::Location Loc,
2218-
const Twine &Name = "tmp", Address *Alloca = nullptr);
2218+
const Twine &Name = "tmp", Address *Alloca = nullptr,
2219+
mlir::OpBuilder::InsertPoint ip = {});
22192220
Address CreateMemTemp(QualType T, CharUnits Align, mlir::Location Loc,
2220-
const Twine &Name = "tmp", Address *Alloca = nullptr);
2221+
const Twine &Name = "tmp", Address *Alloca = nullptr,
2222+
mlir::OpBuilder::InsertPoint ip = {});
22212223

22222224
/// Create a temporary memory object of the given type, with
22232225
/// appropriate alignment without casting it to the default address space.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s
3+
4+
int make_int();
5+
6+
int test() {
7+
const int &x = make_int();
8+
return x;
9+
}
10+
11+
// CHECK: cir.func @_Z4testv()
12+
// CHECK-NEXT: %{{.+}} = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
13+
// CHECK-NEXT: %[[#TEMP_SLOT:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["ref.tmp0", init] {alignment = 4 : i64}
14+
// CHECK-NEXT: %[[#x:]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["x", init] {alignment = 8 : i64}
15+
// CHECK-NEXT: cir.scope {
16+
// CHECK-NEXT: %[[#TEMP_VALUE:]] = cir.call @_Z8make_intv() : () -> !s32i
17+
// CHECK-NEXT: cir.store %[[#TEMP_VALUE]], %[[#TEMP_SLOT]] : !s32i, !cir.ptr<!s32i>
18+
// CHECK-NEXT: }
19+
// CHECK-NEXT: cir.store %[[#TEMP_SLOT]], %[[#x]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
20+
// CHECK: }
21+
22+
int test_scoped() {
23+
int x = make_int();
24+
{
25+
const int &y = make_int();
26+
x = y;
27+
}
28+
return x;
29+
}
30+
31+
// CHECK: cir.func @_Z11test_scopedv()
32+
// CHECK-NEXT: %{{.+}} = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
33+
// CHECK-NEXT: %{{.+}} = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init] {alignment = 4 : i64}
34+
// CHECK: cir.scope {
35+
// CHECK-NEXT: %[[#TEMP_SLOT:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["ref.tmp0", init] {alignment = 4 : i64}
36+
// CHECK-NEXT: %[[#y:]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["y", init] {alignment = 8 : i64}
37+
// CHECK-NEXT: cir.scope {
38+
// CHECK-NEXT: %[[#TEMP_VALUE:]] = cir.call @_Z8make_intv() : () -> !s32i
39+
// CHECK-NEXT: cir.store %[[#TEMP_VALUE]], %[[#TEMP_SLOT]] : !s32i, !cir.ptr<!s32i>
40+
// CHECK-NEXT: }
41+
// CHECK-NEXT: cir.store %[[#TEMP_SLOT]], %[[#y]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
42+
// CHECK: }
43+
// CHECK: }

0 commit comments

Comments
 (0)