[PATCH] D46241: [CodeGen] Recognize more cases of zero initialization
Serge Pavlov via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu May 3 10:34:04 PDT 2018
sepavloff updated this revision to Diff 145049.
sepavloff marked an inline comment as done.
sepavloff added a comment.
Small simplification
Repository:
rC Clang
https://reviews.llvm.org/D46241
Files:
lib/CodeGen/CGExprConstant.cpp
test/CodeGenCXX/cxx11-initializer-aggregate.cpp
Index: test/CodeGenCXX/cxx11-initializer-aggregate.cpp
===================================================================
--- test/CodeGenCXX/cxx11-initializer-aggregate.cpp
+++ test/CodeGenCXX/cxx11-initializer-aggregate.cpp
@@ -51,3 +51,27 @@
// meaningful.
B b[30] = {};
}
+
+namespace ZeroInit {
+ enum { Zero, One };
+ constexpr int zero() { return 0; }
+ constexpr int *null() { return nullptr; }
+ struct Filler {
+ int x;
+ Filler();
+ };
+
+ // These declarations, if implemented elementwise, require huge
+ // amout of memory and compiler time.
+ unsigned char data_1[1024 * 1024 * 1024 * 2u] = { 0 };
+ unsigned char data_2[1024 * 1024 * 1024 * 2u] = { Zero };
+ unsigned char data_3[1024][1024][1024] = {{{0}}};
+ unsigned char data_4[1024 * 1024 * 1024 * 2u] = { zero() };
+ int *data_5[1024 * 1024 * 512] = { nullptr };
+ int *data_6[1024 * 1024 * 512] = { null() };
+
+
+ // This variable must be initialized elementwise.
+ Filler data_e1[1024] = {};
+ // CHECK: getelementptr inbounds {{.*}} @_ZN8ZeroInit7data_e1E
+}
Index: lib/CodeGen/CGExprConstant.cpp
===================================================================
--- lib/CodeGen/CGExprConstant.cpp
+++ lib/CodeGen/CGExprConstant.cpp
@@ -1392,20 +1392,43 @@
return type;
}
+/// Checks if the specified initializer is equivalent to zero initialization.
+static bool isZeroInitializer(ConstantEmitter &CE, const Expr *Init) {
+ QualType InitTy = Init->getType().getCanonicalType();
+ if (auto *E = dyn_cast_or_null<CXXConstructExpr>(Init)) {
+ CXXConstructorDecl *CD = E->getConstructor();
+ return CD->isDefaultConstructor() && CD->isTrivial();
+ }
+ if (auto *IL = dyn_cast_or_null<InitListExpr>(Init)) {
+ if (InitTy->isConstantArrayType()) {
+ for (auto I : IL->inits())
+ if (!isZeroInitializer(CE, I))
+ return false;
+ if (const Expr *Filler = IL->getArrayFiller()) {
+ return isZeroInitializer(CE, Filler);
+ }
+ return true;
+ }
+ } else if (!Init->isEvaluatable(CE.CGM.getContext())) {
+ return false;
+ } else if (Init->isNullPointerConstant(CE.CGM.getContext(),
+ Expr::NPC_NeverValueDependent)) {
+ return true;
+ } else {
+ llvm::APSInt Value;
+ if (Init->isIntegerConstantExpr(Value, CE.CGM.getContext()))
+ return Value.isNullValue();
+ }
+
+ return false;
+}
+
llvm::Constant *ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) {
// Make a quick check if variable can be default NULL initialized
// and avoid going through rest of code which may do, for c++11,
// initialization of memory to all NULLs.
- if (!D.hasLocalStorage()) {
- QualType Ty = CGM.getContext().getBaseElementType(D.getType());
- if (Ty->isRecordType())
- if (const CXXConstructExpr *E =
- dyn_cast_or_null<CXXConstructExpr>(D.getInit())) {
- const CXXConstructorDecl *CD = E->getConstructor();
- if (CD->isTrivial() && CD->isDefaultConstructor())
- return CGM.EmitNullConstant(D.getType());
- }
- }
+ if (!D.hasLocalStorage() && isZeroInitializer(*this, D.getInit()))
+ return CGM.EmitNullConstant(D.getType());
QualType destType = D.getType();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46241.145049.patch
Type: text/x-patch
Size: 3245 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180503/a7555e06/attachment-0001.bin>
More information about the cfe-commits
mailing list