Skip to content

Commit 5641e54

Browse files
Lancernlanza
authored andcommitted
[CIR][CIRGen] emit cir.zero for constant string literals (#373)
This PR addresses #248 . Currently string literals are always lowered to a `cir.const_array` attribute even if the string literal only contains null bytes. This patch make the CodeGen emits `cir.zero` for these string literals.
1 parent 095c2ae commit 5641e54

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,17 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
149149
return mlir::cir::ConstPtrAttr::get(getContext(), t, v);
150150
}
151151

152-
mlir::cir::ConstArrayAttr getString(llvm::StringRef str, mlir::Type eltTy,
153-
unsigned size = 0) {
152+
mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy,
153+
unsigned size = 0) {
154154
unsigned finalSize = size ? size : str.size();
155+
156+
// If the string is full of null bytes, emit a #cir.zero rather than
157+
// a #cir.const_array.
158+
if (str.count('\0') == str.size()) {
159+
auto arrayTy = mlir::cir::ArrayType::get(getContext(), eltTy, finalSize);
160+
return getZeroAttr(arrayTy);
161+
}
162+
155163
auto arrayTy = mlir::cir::ArrayType::get(getContext(), eltTy, finalSize);
156164
return getConstArray(mlir::StringAttr::get(str, arrayTy), arrayTy);
157165
}

clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1397,7 +1397,12 @@ mlir::cir::GlobalOp CIRGenItaniumRTTIBuilder::GetAddrOfTypeName(
13971397
auto Align =
13981398
CGM.getASTContext().getTypeAlignInChars(CGM.getASTContext().CharTy);
13991399

1400-
auto GV = CGM.createOrReplaceCXXRuntimeVariable(loc, Name, Init.getType(),
1400+
// builder.getString can return a #cir.zero if the string given to it only
1401+
// contains null bytes. However, type names cannot be full of null bytes.
1402+
// So cast Init to a ConstArrayAttr should be safe.
1403+
auto InitStr = cast<mlir::cir::ConstArrayAttr>(Init);
1404+
1405+
auto GV = CGM.createOrReplaceCXXRuntimeVariable(loc, Name, InitStr.getType(),
14011406
Linkage, Align);
14021407
CIRGenModule::setInitializer(GV, Init);
14031408
return GV;

clang/test/CIR/CodeGen/globals.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ struct {
4141
char y[3];
4242
char z[3];
4343
} nestedString = {"1", "", "\0"};
44-
// CHECK: cir.global external @nestedString = #cir.const_struct<{#cir.const_array<"1\00\00" : !cir.array<!s8i x 3>> : !cir.array<!s8i x 3>, #cir.const_array<"\00\00\00" : !cir.array<!s8i x 3>> : !cir.array<!s8i x 3>, #cir.const_array<"\00\00\00" : !cir.array<!s8i x 3>> : !cir.array<!s8i x 3>}>
44+
// CHECK: cir.global external @nestedString = #cir.const_struct<{#cir.const_array<"1\00\00" : !cir.array<!s8i x 3>> : !cir.array<!s8i x 3>, #cir.zero : !cir.array<!s8i x 3>, #cir.zero : !cir.array<!s8i x 3>}>
4545

4646
struct {
4747
char *name;

0 commit comments

Comments
 (0)