Skip to content

Commit

Permalink
[CIR][CIRGen] emit cir.zero for constant string literals (llvm#373)
Browse files Browse the repository at this point in the history
This PR addresses llvm#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.
  • Loading branch information
Lancern authored and lanza committed Oct 1, 2024
1 parent acea016 commit 9ca1936
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 4 deletions.
12 changes: 10 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,17 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
return mlir::cir::ConstPtrAttr::get(getContext(), t, v);
}

mlir::cir::ConstArrayAttr getString(llvm::StringRef str, mlir::Type eltTy,
unsigned size = 0) {
mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy,
unsigned size = 0) {
unsigned finalSize = size ? size : str.size();

// If the string is full of null bytes, emit a #cir.zero rather than
// a #cir.const_array.
if (str.count('\0') == str.size()) {
auto arrayTy = mlir::cir::ArrayType::get(getContext(), eltTy, finalSize);
return getZeroAttr(arrayTy);
}

auto arrayTy = mlir::cir::ArrayType::get(getContext(), eltTy, finalSize);
return getConstArray(mlir::StringAttr::get(str, arrayTy), arrayTy);
}
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1395,7 +1395,12 @@ mlir::cir::GlobalOp CIRGenItaniumRTTIBuilder::GetAddrOfTypeName(
auto Align =
CGM.getASTContext().getTypeAlignInChars(CGM.getASTContext().CharTy);

auto GV = CGM.createOrReplaceCXXRuntimeVariable(loc, Name, Init.getType(),
// builder.getString can return a #cir.zero if the string given to it only
// contains null bytes. However, type names cannot be full of null bytes.
// So cast Init to a ConstArrayAttr should be safe.
auto InitStr = cast<mlir::cir::ConstArrayAttr>(Init);

auto GV = CGM.createOrReplaceCXXRuntimeVariable(loc, Name, InitStr.getType(),
Linkage, Align);
CIRGenModule::setInitializer(GV, Init);
return GV;
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CIR/CodeGen/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct {
char y[3];
char z[3];
} nestedString = {"1", "", "\0"};
// 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>}>
// 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>}>

struct {
char *name;
Expand Down

0 comments on commit 9ca1936

Please sign in to comment.