diff options
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 78e80a15836..4a382007813 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -301,6 +301,23 @@ createReferenceTemporary(CodeGenFunction &CGF, switch (M->getStorageDuration()) { case SD_FullExpression: case SD_Automatic: + // If we have a constant temporary array or record try to promote it into a + // constant global under the same rules a normal constant would've been + // promoted. This is easier on the optimizer and generally emits fewer + // instructions. + if (CGF.CGM.getCodeGenOpts().MergeAllConstants && + (M->getType()->isArrayType() || M->getType()->isRecordType()) && + CGF.CGM.isTypeConstant(M->getType(), true)) + if (llvm::Constant *Init = + CGF.CGM.EmitConstantExpr(Inner, M->getType(), &CGF)) { + auto *GV = new llvm::GlobalVariable( + CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true, + llvm::GlobalValue::PrivateLinkage, Init, ".ref.tmp"); + GV->setAlignment( + CGF.getContext().getTypeAlignInChars(M->getType()).getQuantity()); + // FIXME: Should we put the new global into a COMDAT? + return GV; + } return CGF.CreateMemTemp(Inner->getType(), "ref.tmp"); case SD_Thread: @@ -370,8 +387,9 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) { // Create and initialize the reference temporary. llvm::Value *Object = createReferenceTemporary(*this, M, E); if (auto *Var = dyn_cast<llvm::GlobalVariable>(Object)) { - // If the temporary is a global and has a constant initializer, we may - // have already initialized it. + // If the temporary is a global and has a constant initializer or is a + // constant temporary that we promoted to a global, we may have already + // initialized it. if (!Var->hasInitializer()) { Var->setInitializer(CGM.EmitNullConstant(E->getType())); EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true); |

