summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-06-14 03:07:01 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-06-14 03:07:01 +0000
commita509f2fdfa8ffb4ce9edaee84daca44bcb07ee78 (patch)
treea4443f45f9d76e9fbc4dd2543d6f023e49eb3f4c /clang/lib/CodeGen/CodeGenModule.cpp
parent18db1f2f1a0b05ba97c92f0ef2c4b4be8614ae9b (diff)
downloadbcm5719-llvm-a509f2fdfa8ffb4ce9edaee84daca44bcb07ee78.tar.gz
bcm5719-llvm-a509f2fdfa8ffb4ce9edaee84daca44bcb07ee78.zip
Emit initializers for static-storage-duration temporaries as constants where
possible. llvm-svn: 183967
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp41
1 files changed, 26 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 4865a9174c9..824d2a04662 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2615,15 +2615,16 @@ llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &Str,
}
llvm::Constant *CodeGenModule::GetAddrOfGlobalTemporary(
- const MaterializeTemporaryExpr *E, const Expr *Inner) {
+ const MaterializeTemporaryExpr *E, const Expr *Init) {
assert((E->getStorageDuration() == SD_Static ||
E->getStorageDuration() == SD_Thread) && "not a global temporary");
const VarDecl *VD = cast<VarDecl>(E->getExtendingDecl());
// If we're not materializing a subobject of the temporary, keep the
// cv-qualifiers from the type of the MaterializeTemporaryExpr.
- if (Inner == E->GetTemporaryExpr())
- Inner = E;
+ QualType MaterializedType = Init->getType();
+ if (Init == E->GetTemporaryExpr())
+ MaterializedType = E->getType();
llvm::Constant *&Slot = MaterializedGlobalTemporaryMap[E];
if (Slot)
@@ -2637,34 +2638,44 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalTemporary(
getCXXABI().getMangleContext().mangleReferenceTemporary(VD, Out);
Out.flush();
- llvm::Constant *InitialValue = 0;
APValue *Value = 0;
if (E->getStorageDuration() == SD_Static) {
- // We might have a constant initializer for this temporary.
+ // We might have a cached constant initializer for this temporary. Note
+ // that this might have a different value from the value computed by
+ // evaluating the initializer if the surrounding constant expression
+ // modifies the temporary.
Value = getContext().getMaterializedTemporaryValue(E, false);
if (Value && Value->isUninit())
Value = 0;
}
- bool Constant;
+ // Try evaluating it now, it might have a constant initializer.
+ Expr::EvalResult EvalResult;
+ if (!Value && Init->EvaluateAsRValue(EvalResult, getContext()) &&
+ !EvalResult.hasSideEffects())
+ Value = &EvalResult.Val;
+
+ llvm::Constant *InitialValue = 0;
+ bool Constant = false;
+ llvm::Type *Type;
if (Value) {
// The temporary has a constant initializer, use it.
- InitialValue = EmitConstantValue(*Value, Inner->getType(), 0);
- Constant = isTypeConstant(Inner->getType(), /*ExcludeCtor*/Value);
+ InitialValue = EmitConstantValue(*Value, MaterializedType, 0);
+ Constant = isTypeConstant(MaterializedType, /*ExcludeCtor*/Value);
+ Type = InitialValue->getType();
} else {
- // No constant initializer, the initialization will be provided when we
+ // No initializer, the initialization will be provided when we
// initialize the declaration which performed lifetime extension.
- InitialValue = EmitNullConstant(Inner->getType());
- Constant = false;
+ Type = getTypes().ConvertTypeForMem(MaterializedType);
}
// Create a global variable for this lifetime-extended temporary.
llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(getModule(), InitialValue->getType(), Constant,
- llvm::GlobalValue::PrivateLinkage, InitialValue,
- Name.c_str());
+ new llvm::GlobalVariable(getModule(), Type, Constant,
+ llvm::GlobalValue::PrivateLinkage,
+ InitialValue, Name.c_str());
GV->setAlignment(
- getContext().getTypeAlignInChars(Inner->getType()).getQuantity());
+ getContext().getTypeAlignInChars(MaterializedType).getQuantity());
if (VD->getTLSKind())
setTLSMode(GV, *VD);
Slot = GV;
OpenPOWER on IntegriCloud