diff options
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 78e80a15836..a1cbef26457 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -301,6 +301,25 @@ 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()); + // Put the new global in the same COMDAT the function containing the + // temporary is in. + GV->setComdat(CGF.CurFn->getComdat()); + return GV; + } return CGF.CreateMemTemp(Inner->getType(), "ref.tmp"); case SD_Thread: @@ -370,8 +389,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); |

