summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExprConstant.cpp
diff options
context:
space:
mode:
authorGeorge Burgess IV <george.burgess.iv@gmail.com>2016-12-28 07:27:40 +0000
committerGeorge Burgess IV <george.burgess.iv@gmail.com>2016-12-28 07:27:40 +0000
commit1a39b86d0f412e5d645b6e05770d5ae821063ca2 (patch)
tree892a2f1514439231c3010002210c5fd58aea0df2 /clang/lib/CodeGen/CGExprConstant.cpp
parent15361a21e01026e74cb17011b702c7d1c881ae94 (diff)
downloadbcm5719-llvm-1a39b86d0f412e5d645b6e05770d5ae821063ca2.tar.gz
bcm5719-llvm-1a39b86d0f412e5d645b6e05770d5ae821063ca2.zip
[CodeGen] Unique constant CompoundLiterals.
Our newly aggressive constant folding logic makes it possible for CGExprConstant to see the same CompoundLiteralExpr more than once. So, emitting a new GlobalVariable every time we see a CompoundLiteral is no longer correct. We had a similar issue with BlockExprs that was caught while testing said aggressive folding, so I applied the same style of fix (see D26410) here. If we find yet another case where this needs to happen, we should probably refactor this so we don't have a third DenseMap+getter+setter. As a design note: getAddrOfConstantCompoundLiteralIfEmitted is really only intended to be called by ConstExprEmitter::EmitLValue. So, returning a GlobalVariable* instead of a ConstantAddress costs us effectively nothing, and saves us either a few bytes per entry in our map or a bit of code duplication. llvm-svn: 290661
Diffstat (limited to 'clang/lib/CodeGen/CGExprConstant.cpp')
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp22
1 files changed, 18 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 62a9c8fa907..3db15c646f4 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -1023,16 +1023,17 @@ public:
switch (E->getStmtClass()) {
default: break;
case Expr::CompoundLiteralExprClass: {
- // Note that due to the nature of compound literals, this is guaranteed
- // to be the only use of the variable, so we just generate it here.
CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
+ CharUnits Align = CGM.getContext().getTypeAlignInChars(E->getType());
+ if (llvm::GlobalVariable *Addr =
+ CGM.getAddrOfConstantCompoundLiteralIfEmitted(CLE))
+ return ConstantAddress(Addr, Align);
+
llvm::Constant* C = CGM.EmitConstantExpr(CLE->getInitializer(),
CLE->getType(), CGF);
// FIXME: "Leaked" on failure.
if (!C) return ConstantAddress::invalid();
- CharUnits Align = CGM.getContext().getTypeAlignInChars(E->getType());
-
auto GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(),
E->getType().isConstant(CGM.getContext()),
llvm::GlobalValue::InternalLinkage,
@@ -1040,6 +1041,7 @@ public:
llvm::GlobalVariable::NotThreadLocal,
CGM.getContext().getTargetAddressSpace(E->getType()));
GV->setAlignment(Align.getQuantity());
+ CGM.setAddrOfConstantCompoundLiteral(CLE, GV);
return ConstantAddress(GV, Align);
}
case Expr::StringLiteralClass:
@@ -1492,6 +1494,18 @@ CodeGenModule::EmitConstantValueForMemory(const APValue &Value,
return C;
}
+llvm::GlobalVariable *CodeGenModule::getAddrOfConstantCompoundLiteralIfEmitted(
+ const CompoundLiteralExpr *E) {
+ return EmittedCompoundLiterals.lookup(E);
+}
+
+void CodeGenModule::setAddrOfConstantCompoundLiteral(
+ const CompoundLiteralExpr *CLE, llvm::GlobalVariable *GV) {
+ bool Ok = EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;
+ (void)Ok;
+ assert(Ok && "CLE has already been emitted!");
+}
+
ConstantAddress
CodeGenModule::GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *E) {
assert(E->isFileScope() && "not a file-scope compound literal expr");
OpenPOWER on IntegriCloud