diff options
| author | George Burgess IV <george.burgess.iv@gmail.com> | 2016-12-28 07:27:40 +0000 |
|---|---|---|
| committer | George Burgess IV <george.burgess.iv@gmail.com> | 2016-12-28 07:27:40 +0000 |
| commit | 1a39b86d0f412e5d645b6e05770d5ae821063ca2 (patch) | |
| tree | 892a2f1514439231c3010002210c5fd58aea0df2 /clang/lib/CodeGen/CGExprConstant.cpp | |
| parent | 15361a21e01026e74cb17011b702c7d1c881ae94 (diff) | |
| download | bcm5719-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.cpp | 22 |
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"); |

