diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2008-11-30 02:11:09 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2008-11-30 02:11:09 +0000 |
commit | 994ffef4353056363ba5915eeecf0e1b0678f286 (patch) | |
tree | 2ba1c932955e68494db1a6a70aeb340c83a98275 /lib/CodeGen/CGExprAgg.cpp | |
parent | 4310ff6d8b22ee223b88811ef9d51ebb0f9ea66b (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.cpp | 25 |
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 = |