aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprAgg.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2008-11-30 02:11:09 +0000
committerEli Friedman <eli.friedman@gmail.com>2008-11-30 02:11:09 +0000
commit994ffef4353056363ba5915eeecf0e1b0678f286 (patch)
tree2ba1c932955e68494db1a6a70aeb340c83a98275 /lib/CodeGen/CGExprAgg.cpp
parent4310ff6d8b22ee223b88811ef9d51ebb0f9ea66b (diff)
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
Diffstat (limited to 'lib/CodeGen/CGExprAgg.cpp')
-rw-r--r--lib/CodeGen/CGExprAgg.cpp25
1 files changed, 17 insertions, 8 deletions
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index a06d3b63c1..39c3b49954 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -368,14 +368,23 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
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 =