Fix for PR2969: generate a memcpy from a constant for constant
initializers. llvm-gcc appears to be more aggressive, but incorrect,
for constructs like "const int a[] = {1,2,3};"; that said, current
optimizers will do the appropriate optimizations when safe.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60270 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index a06d3b6..39c3b49 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -368,14 +368,23 @@
CGF.ErrorUnsupported(E, "initializer list with designators");
return;
}
-
- // FIXME: For constant expressions, call into const expr emitter so
- // that we can emit a memcpy instead of storing the individual
- // members. This is purely for perf; both codepaths lead to
- // equivalent (although not necessarily identical) code. It's worth
- // noting that LLVM keeps on getting smarter, though, so it might
- // not be worth bothering.
-
+
+ // If we can, prefer a copy from a global; this is a lot less
+ // code for long globals, and it's easier for the current optimizers
+ // to analyze.
+ // FIXME: Should we really be doing this? Should we try to avoid
+ // cases where we emit a global with a lot of zeros? Should
+ // we try to avoid short globals?
+ if (E->isConstantExpr(CGF.getContext(), 0)) {
+ llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, &CGF);
+ llvm::GlobalVariable* GV =
+ new llvm::GlobalVariable(C->getType(), true,
+ llvm::GlobalValue::InternalLinkage,
+ C, "", &CGF.CGM.getModule(), 0);
+ CGF.EmitAggregateCopy(DestPtr, GV, E->getType());
+ return;
+ }
+
// Handle initialization of an array.
if (E->getType()->isArrayType()) {
const llvm::PointerType *APType =