Author: rjmccall
Date: Tue Aug 15 14:42:52 2017
New Revision: 310964

URL: http://llvm.org/viewvc/llvm-project?rev=310964&view=rev
Log:
Extract IRGen's constant-emitter into its own helper class and clean up
the interface.

The ultimate goal here is to make it easier to do some more interesting
things in constant emission, like emit constant initializers that have
ignorable side-effects, or doing the majority of an initialization
in-place and then patching up the last few things with calls.  But for
now this is mostly just a refactoring.

Added:
    cfe/trunk/lib/CodeGen/ConstantEmitter.h
Modified:
    cfe/trunk/lib/CodeGen/CGBlocks.cpp
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CGException.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=310964&r1=310963&r2=310964&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Tue Aug 15 14:42:52 2017
@@ -16,6 +16,7 @@
 #include "CGObjCRuntime.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "ConstantEmitter.h"
 #include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/DeclObjC.h"
 #include "llvm/ADT/SmallSet.h"
@@ -290,7 +291,7 @@ static llvm::Constant *tryCaptureAsConst
   const Expr *init = var->getInit();
   if (!init) return nullptr;
 
-  return CGM.EmitConstantInit(*var, CGF);
+  return ConstantEmitter(CGM, CGF).tryEmitAbstractForInitializer(*var);
 }
 
 /// Get the low bit of a nonzero character count.  This is the

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=310964&r1=310963&r2=310964&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Tue Aug 15 14:42:52 2017
@@ -16,6 +16,7 @@
 #include "CGOpenCLRuntime.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "ConstantEmitter.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
@@ -680,7 +681,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(
   default: break;  // Handle intrinsics and libm functions below.
   case Builtin::BI__builtin___CFStringMakeConstantString:
   case Builtin::BI__builtin___NSStringMakeConstantString:
-    return RValue::get(CGM.EmitConstantExpr(E, E->getType(), nullptr));
+    return RValue::get(ConstantEmitter(*this).emitAbstract(E, E->getType()));
   case Builtin::BI__builtin_stdarg_start:
   case Builtin::BI__builtin_va_start:
   case Builtin::BI__va_start:
@@ -1366,8 +1367,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(
                                       llvm::ConstantInt::get(Int32Ty, 
Offset)));
   }
   case Builtin::BI__builtin_return_address: {
-    Value *Depth =
-        CGM.EmitConstantExpr(E->getArg(0), getContext().UnsignedIntTy, this);
+    Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
+                                                   getContext().UnsignedIntTy);
     Value *F = CGM.getIntrinsic(Intrinsic::returnaddress);
     return RValue::get(Builder.CreateCall(F, Depth));
   }
@@ -1376,8 +1377,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(
     return RValue::get(Builder.CreateCall(F, Builder.getInt32(0)));
   }
   case Builtin::BI__builtin_frame_address: {
-    Value *Depth =
-        CGM.EmitConstantExpr(E->getArg(0), getContext().UnsignedIntTy, this);
+    Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
+                                                   getContext().UnsignedIntTy);
     Value *F = CGM.getIntrinsic(Intrinsic::frameaddress);
     return RValue::get(Builder.CreateCall(F, Depth));
   }

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=310964&r1=310963&r2=310964&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue Aug 15 14:42:52 2017
@@ -18,6 +18,7 @@
 #include "CGRecordLayout.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "ConstantEmitter.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclObjC.h"
@@ -1601,7 +1602,7 @@ CGDebugInfo::CollectTemplateParams(const
       QualType T = E->getType();
       if (E->isGLValue())
         T = CGM.getContext().getLValueReferenceType(T);
-      llvm::Constant *V = CGM.EmitConstantExpr(E, T);
+      llvm::Constant *V = ConstantEmitter(CGM).emitAbstract(E, T);
       assert(V && "Expression in template argument isn't constant");
       llvm::DIType *TTy = getOrCreateType(T, Unit);
       TemplateParams.push_back(DBuilder.createTemplateValueParameter(

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=310964&r1=310963&r2=310964&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Tue Aug 15 14:42:52 2017
@@ -19,6 +19,7 @@
 #include "CGOpenMPRuntime.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "ConstantEmitter.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
@@ -307,7 +308,8 @@ static bool hasNontrivialDestruction(Qua
 llvm::GlobalVariable *
 CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
                                                llvm::GlobalVariable *GV) {
-  llvm::Constant *Init = CGM.EmitConstantInit(D, this);
+  ConstantEmitter emitter(*this);
+  llvm::Constant *Init = emitter.tryEmitForInitializer(D);
 
   // If constant emission failed, then this should be a C++ static
   // initializer.
@@ -355,6 +357,8 @@ CodeGenFunction::AddInitializerToStaticV
   GV->setConstant(CGM.isTypeConstant(D.getType(), true));
   GV->setInitializer(Init);
 
+  emitter.finalize(GV);
+
   if (hasNontrivialDestruction(D.getType()) && HaveInsertPoint()) {
     // We have a constant initializer, but a nontrivial destructor. We still
     // need to perform a guarded "initialization" in order to register the
@@ -1236,7 +1240,7 @@ void CodeGenFunction::EmitAutoVarInit(co
   llvm::Constant *constant = nullptr;
   if (emission.IsConstantAggregate || D.isConstexpr()) {
     assert(!capturedByInit && "constant init contains a capturing block?");
-    constant = CGM.EmitConstantInit(D, this);
+    constant = ConstantEmitter(*this).tryEmitAbstractForInitializer(D);
   }
 
   if (!constant) {

Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=310964&r1=310963&r2=310964&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Tue Aug 15 14:42:52 2017
@@ -15,6 +15,7 @@
 #include "CGCXXABI.h"
 #include "CGCleanup.h"
 #include "CGObjCRuntime.h"
+#include "ConstantEmitter.h"
 #include "TargetInfo.h"
 #include "clang/AST/Mangle.h"
 #include "clang/AST/StmtCXX.h"
@@ -1800,7 +1801,8 @@ void CodeGenFunction::EnterSEHTryStmt(co
   // "catch i8* null". We can't do this on x86 because the filter has to save
   // the exception code.
   llvm::Constant *C =
-      CGM.EmitConstantExpr(Except->getFilterExpr(), getContext().IntTy, this);
+    ConstantEmitter(*this).tryEmitAbstract(Except->getFilterExpr(),
+                                           getContext().IntTy);
   if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 && C &&
       C->isOneValue()) {
     CatchScope->setCatchAllHandler(0, createBasicBlock("__except"));

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=310964&r1=310963&r2=310964&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Aug 15 14:42:52 2017
@@ -20,6 +20,7 @@
 #include "CGRecordLayout.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "ConstantEmitter.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
@@ -356,7 +357,7 @@ static Address createReferenceTemporary(
     if (CGF.CGM.getCodeGenOpts().MergeAllConstants &&
         (Ty->isArrayType() || Ty->isRecordType()) &&
         CGF.CGM.isTypeConstant(Ty, true))
-      if (llvm::Constant *Init = CGF.CGM.EmitConstantExpr(Inner, Ty, &CGF)) {
+      if (auto Init = ConstantEmitter(CGF).tryEmitAbstract(Inner, Ty)) {
         if (auto AddrSpace = CGF.getTarget().getConstantAddressSpace()) {
           auto AS = AddrSpace.getValue();
           auto *GV = new llvm::GlobalVariable(
@@ -1318,7 +1319,8 @@ CodeGenFunction::tryEmitAsConstant(DeclR
     return ConstantEmission();
 
   // Emit as a constant.
-  llvm::Constant *C = CGM.EmitConstantValue(result.Val, resultType, this);
+  auto C = ConstantEmitter(*this).emitAbstract(refExpr->getLocation(),
+                                               result.Val, resultType);
 
   // Make sure we emit a debug reference to the global variable.
   // This should probably fire even for
@@ -2283,7 +2285,9 @@ LValue CodeGenFunction::EmitDeclRefLValu
         !(E->refersToEnclosingVariableOrCapture() && CapturedStmtInfo &&
           LocalDeclMap.count(VD))) {
       llvm::Constant *Val =
-        CGM.EmitConstantValue(*VD->evaluateValue(), VD->getType(), this);
+        ConstantEmitter(*this).emitAbstract(E->getLocation(),
+                                            *VD->evaluateValue(),
+                                            VD->getType());
       assert(Val && "failed to emit reference constant expression");
       // FIXME: Eventually we will want to emit vector element references.
 

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=310964&r1=310963&r2=310964&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Tue Aug 15 14:42:52 2017
@@ -16,6 +16,7 @@
 #include "CGCXXABI.h"
 #include "CGDebugInfo.h"
 #include "CGObjCRuntime.h"
+#include "ConstantEmitter.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/IR/CallSite.h"
@@ -681,8 +682,8 @@ static llvm::Value *EmitCXXNewAllocSize(
   // Emit the array size expression.
   // We multiply the size of all dimensions for NumElements.
   // e.g for 'int[2][3]', ElemType is 'int' and NumElements is 6.
-  numElements = CGF.CGM.EmitConstantExpr(e->getArraySize(),
-                                         CGF.getContext().getSizeType(), &CGF);
+  numElements =
+    ConstantEmitter(CGF).tryEmitAbstract(e->getArraySize(), e->getType());
   if (!numElements)
     numElements = CGF.EmitScalarExpr(e->getArraySize());
   assert(isa<llvm::IntegerType>(numElements->getType()));

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=310964&r1=310963&r2=310964&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Aug 15 14:42:52 2017
@@ -16,6 +16,7 @@
 #include "CGObjCRuntime.h"
 #include "CGRecordLayout.h"
 #include "CodeGenModule.h"
+#include "ConstantEmitter.h"
 #include "TargetInfo.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTContext.h"
@@ -37,25 +38,26 @@ namespace {
 class ConstExprEmitter;
 class ConstStructBuilder {
   CodeGenModule &CGM;
-  CodeGenFunction *CGF;
+  ConstantEmitter &Emitter;
 
   bool Packed;
   CharUnits NextFieldOffsetInChars;
   CharUnits LLVMStructAlignment;
   SmallVector<llvm::Constant *, 32> Elements;
 public:
-  static llvm::Constant *BuildStruct(CodeGenModule &CGM, CodeGenFunction *CFG,
-                                     ConstExprEmitter *Emitter,
+  static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
+                                     ConstExprEmitter *ExprEmitter,
                                      llvm::ConstantStruct *Base,
-                                     InitListExpr *Updater);
-  static llvm::Constant *BuildStruct(CodeGenModule &CGM, CodeGenFunction *CGF,
-                                     InitListExpr *ILE);
-  static llvm::Constant *BuildStruct(CodeGenModule &CGM, CodeGenFunction *CGF,
+                                     InitListExpr *Updater,
+                                     QualType ValTy);
+  static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
+                                     InitListExpr *ILE, QualType StructTy);
+  static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
                                      const APValue &Value, QualType ValTy);
 
 private:
-  ConstStructBuilder(CodeGenModule &CGM, CodeGenFunction *CGF)
-    : CGM(CGM), CGF(CGF), Packed(false), 
+  ConstStructBuilder(ConstantEmitter &emitter)
+    : CGM(emitter.CGM), Emitter(emitter), Packed(false), 
     NextFieldOffsetInChars(CharUnits::Zero()),
     LLVMStructAlignment(CharUnits::One()) { }
 
@@ -76,7 +78,7 @@ private:
   bool Build(InitListExpr *ILE);
   bool Build(ConstExprEmitter *Emitter, llvm::ConstantStruct *Base,
              InitListExpr *Updater);
-  void Build(const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase,
+  bool Build(const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase,
              const CXXRecordDecl *VTableClass, CharUnits BaseOffset);
   llvm::Constant *Finalize(QualType Ty);
 
@@ -391,10 +393,10 @@ bool ConstStructBuilder::Build(InitListE
     // we just use explicit null values for them.
     llvm::Constant *EltInit;
     if (ElementNo < ILE->getNumInits())
-      EltInit = CGM.EmitConstantExpr(ILE->getInit(ElementNo++),
-                                     Field->getType(), CGF);
+      EltInit = Emitter.tryEmitPrivateForMemory(ILE->getInit(ElementNo++),
+                                                Field->getType());
     else
-      EltInit = CGM.EmitNullConstant(Field->getType());
+      EltInit = Emitter.emitNullForMemory(Field->getType());
 
     if (!EltInit)
       return false;
@@ -431,7 +433,7 @@ struct BaseInfo {
 };
 }
 
-void ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
+bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
                                bool IsPrimaryBase,
                                const CXXRecordDecl *VTableClass,
                                CharUnits Offset) {
@@ -486,8 +488,9 @@ void ConstStructBuilder::Build(const APV
     const APValue &FieldValue =
       RD->isUnion() ? Val.getUnionValue() : Val.getStructField(FieldNo);
     llvm::Constant *EltInit =
-      CGM.EmitConstantValueForMemory(FieldValue, Field->getType(), CGF);
-    assert(EltInit && "EmitConstantValue can't fail");
+      Emitter.tryEmitPrivateForMemory(FieldValue, Field->getType());
+    if (!EltInit)
+      return false;
 
     if (!Field->isBitField()) {
       // Handle non-bitfield members.
@@ -498,6 +501,8 @@ void ConstStructBuilder::Build(const APV
                      cast<llvm::ConstantInt>(EltInit));
     }
   }
+
+  return true;
 }
 
 llvm::Constant *ConstStructBuilder::Finalize(QualType Ty) {
@@ -559,37 +564,37 @@ llvm::Constant *ConstStructBuilder::Fina
   return Result;
 }
 
-llvm::Constant *ConstStructBuilder::BuildStruct(CodeGenModule &CGM,
-                                                CodeGenFunction *CGF,
-                                                ConstExprEmitter *Emitter,
+llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
+                                                ConstExprEmitter *ExprEmitter,
                                                 llvm::ConstantStruct *Base,
-                                                InitListExpr *Updater) {
-  ConstStructBuilder Builder(CGM, CGF);
-  if (!Builder.Build(Emitter, Base, Updater))
+                                                InitListExpr *Updater,
+                                                QualType ValTy) {
+  ConstStructBuilder Builder(Emitter);
+  if (!Builder.Build(ExprEmitter, Base, Updater))
     return nullptr;
-  return Builder.Finalize(Updater->getType());
+  return Builder.Finalize(ValTy);
 }
 
-llvm::Constant *ConstStructBuilder::BuildStruct(CodeGenModule &CGM,
-                                                CodeGenFunction *CGF,
-                                                InitListExpr *ILE) {
-  ConstStructBuilder Builder(CGM, CGF);
+llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
+                                                InitListExpr *ILE,
+                                                QualType ValTy) {
+  ConstStructBuilder Builder(Emitter);
 
   if (!Builder.Build(ILE))
     return nullptr;
 
-  return Builder.Finalize(ILE->getType());
+  return Builder.Finalize(ValTy);
 }
 
-llvm::Constant *ConstStructBuilder::BuildStruct(CodeGenModule &CGM,
-                                                CodeGenFunction *CGF,
+llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
                                                 const APValue &Val,
                                                 QualType ValTy) {
-  ConstStructBuilder Builder(CGM, CGF);
+  ConstStructBuilder Builder(Emitter);
 
   const RecordDecl *RD = ValTy->castAs<RecordType>()->getDecl();
   const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
-  Builder.Build(Val, RD, false, CD, CharUnits::Zero());
+  if (!Builder.Build(Val, RD, false, CD, CharUnits::Zero()))
+    return nullptr;
 
   return Builder.Finalize(ValTy);
 }
@@ -599,57 +604,86 @@ llvm::Constant *ConstStructBuilder::Buil
 //                             ConstExprEmitter
 
//===----------------------------------------------------------------------===//
 
+static ConstantAddress tryEmitGlobalCompoundLiteral(CodeGenModule &CGM,
+                                                    CodeGenFunction *CGF,
+                                              const CompoundLiteralExpr *E) {
+  CharUnits Align = CGM.getContext().getTypeAlignInChars(E->getType());
+  if (llvm::GlobalVariable *Addr =
+          CGM.getAddrOfConstantCompoundLiteralIfEmitted(E))
+    return ConstantAddress(Addr, Align);
+
+  unsigned addressSpace = E->getType().getAddressSpace();
+
+  ConstantEmitter emitter(CGM, CGF);
+  llvm::Constant *C = emitter.tryEmitForInitializer(E->getInitializer(),
+                                                    addressSpace, 
E->getType());
+  if (!C) {
+    assert(!E->isFileScope() &&
+           "file-scope compound literal did not have constant initializer!");
+    return ConstantAddress::invalid();
+  }
+
+  auto GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(),
+                                     CGM.isTypeConstant(E->getType(), true),
+                                     llvm::GlobalValue::InternalLinkage,
+                                     C, ".compoundliteral", nullptr,
+                                     llvm::GlobalVariable::NotThreadLocal,
+                    CGM.getContext().getTargetAddressSpace(addressSpace));
+  emitter.finalize(GV);
+  GV->setAlignment(Align.getQuantity());
+  CGM.setAddrOfConstantCompoundLiteral(E, GV);
+  return ConstantAddress(GV, Align);
+}
+
 /// This class only needs to handle two cases:
 /// 1) Literals (this is used by APValue emission to emit literals).
 /// 2) Arrays, structs and unions (outside C++11 mode, we don't currently
 ///    constant fold these types).
 class ConstExprEmitter :
-  public StmtVisitor<ConstExprEmitter, llvm::Constant*> {
+  public StmtVisitor<ConstExprEmitter, llvm::Constant*, QualType> {
   CodeGenModule &CGM;
-  CodeGenFunction *CGF;
+  ConstantEmitter &Emitter;
   llvm::LLVMContext &VMContext;
 public:
-  ConstExprEmitter(CodeGenModule &cgm, CodeGenFunction *cgf)
-    : CGM(cgm), CGF(cgf), VMContext(cgm.getLLVMContext()) {
+  ConstExprEmitter(ConstantEmitter &emitter)
+    : CGM(emitter.CGM), Emitter(emitter), VMContext(CGM.getLLVMContext()) {
   }
 
   
//===--------------------------------------------------------------------===//
   //                            Visitor Methods
   
//===--------------------------------------------------------------------===//
 
-  llvm::Constant *VisitStmt(Stmt *S) {
+  llvm::Constant *VisitStmt(Stmt *S, QualType T) {
     return nullptr;
   }
 
-  llvm::Constant *VisitParenExpr(ParenExpr *PE) {
-    return Visit(PE->getSubExpr());
+  llvm::Constant *VisitParenExpr(ParenExpr *PE, QualType T) {
+    return Visit(PE->getSubExpr(), T);
   }
 
   llvm::Constant *
-  VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE) {
-    return Visit(PE->getReplacement());
+  VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE,
+                                    QualType T) {
+    return Visit(PE->getReplacement(), T);
   }
 
-  llvm::Constant *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
-    return Visit(GE->getResultExpr());
+  llvm::Constant *VisitGenericSelectionExpr(GenericSelectionExpr *GE,
+                                            QualType T) {
+    return Visit(GE->getResultExpr(), T);
   }
 
-  llvm::Constant *VisitChooseExpr(ChooseExpr *CE) {
-    return Visit(CE->getChosenSubExpr());
+  llvm::Constant *VisitChooseExpr(ChooseExpr *CE, QualType T) {
+    return Visit(CE->getChosenSubExpr(), T);
   }
 
-  llvm::Constant *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
-    return Visit(E->getInitializer());
+  llvm::Constant *VisitCompoundLiteralExpr(CompoundLiteralExpr *E, QualType T) 
{
+    return Visit(E->getInitializer(), T);
   }
 
-  llvm::Constant *VisitCastExpr(CastExpr* E) {
+  llvm::Constant *VisitCastExpr(CastExpr *E, QualType destType) {
     if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
-      CGM.EmitExplicitCastExprType(ECE, CGF);
+      CGM.EmitExplicitCastExprType(ECE, Emitter.CGF);
     Expr *subExpr = E->getSubExpr();
-    llvm::Constant *C = CGM.EmitConstantExpr(subExpr, subExpr->getType(), CGF);
-    if (!C) return nullptr;
-
-    llvm::Type *destType = ConvertType(E->getType());
 
     switch (E->getCastKind()) {
     case CK_ToUnion: {
@@ -657,14 +691,22 @@ public:
       assert(E->getType()->isUnionType() &&
              "Destination type is not union type!");
 
+      auto field = E->getTargetUnionField();
+
+      auto C = Emitter.tryEmitPrivateForMemory(subExpr, field->getType());
+      if (!C) return nullptr;
+
+      auto destTy = ConvertType(destType);
+      if (C->getType() == destTy) return C;
+
       // Build a struct with the union sub-element as the first member,
-      // and padded to the appropriate size
+      // and padded to the appropriate size.
       SmallVector<llvm::Constant*, 2> Elts;
       SmallVector<llvm::Type*, 2> Types;
       Elts.push_back(C);
       Types.push_back(C->getType());
       unsigned CurSize = CGM.getDataLayout().getTypeAllocSize(C->getType());
-      unsigned TotalSize = CGM.getDataLayout().getTypeAllocSize(destType);
+      unsigned TotalSize = CGM.getDataLayout().getTypeAllocSize(destTy);
 
       assert(CurSize <= TotalSize && "Union size mismatch!");
       if (unsigned NumPadBytes = TotalSize - CurSize) {
@@ -676,20 +718,26 @@ public:
         Types.push_back(Ty);
       }
 
-      llvm::StructType* STy =
-        llvm::StructType::get(C->getType()->getContext(), Types, false);
+      llvm::StructType *STy = llvm::StructType::get(VMContext, Types, false);
       return llvm::ConstantStruct::get(STy, Elts);
     }
 
-    case CK_AddressSpaceConversion:
-      return llvm::ConstantExpr::getAddrSpaceCast(C, destType);
+    case CK_AddressSpaceConversion: {
+      auto C = Emitter.tryEmitPrivate(subExpr, subExpr->getType());
+      if (!C) return nullptr;
+      unsigned destAS = E->getType()->getPointeeType().getAddressSpace();
+      unsigned srcAS = subExpr->getType()->getPointeeType().getAddressSpace();
+      llvm::Type *destTy = ConvertType(E->getType());
+      return CGM.getTargetCodeGenInfo().performAddrSpaceCast(CGM, C, srcAS,
+                                                             destAS, destTy);
+    }
 
     case CK_LValueToRValue:
     case CK_AtomicToNonAtomic:
     case CK_NonAtomicToAtomic:
     case CK_NoOp:
     case CK_ConstructorConversion:
-      return C;
+      return Visit(subExpr, destType);
 
     case CK_IntToOCLSampler:
       llvm_unreachable("global sampler variables are not generated");
@@ -701,8 +749,11 @@ public:
 
     case CK_ReinterpretMemberPointer:
     case CK_DerivedToBaseMemberPointer:
-    case CK_BaseToDerivedMemberPointer:
+    case CK_BaseToDerivedMemberPointer: {
+      auto C = Emitter.tryEmitPrivate(subExpr, subExpr->getType());
+      if (!C) return nullptr;
       return CGM.getCXXABI().EmitMemberPointerConversion(E, C);
+    }
 
     // These will never be supported.
     case CK_ObjCObjectLValueCast:
@@ -759,27 +810,28 @@ public:
     llvm_unreachable("Invalid CastKind");
   }
 
-  llvm::Constant *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
-    return Visit(DAE->getExpr());
+  llvm::Constant *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE, QualType T) {
+    return Visit(DAE->getExpr(), T);
   }
 
-  llvm::Constant *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
+  llvm::Constant *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE, QualType T) 
{
     // No need for a DefaultInitExprScope: we don't handle 'this' in a
     // constant expression.
-    return Visit(DIE->getExpr());
+    return Visit(DIE->getExpr(), T);
   }
 
-  llvm::Constant *VisitExprWithCleanups(ExprWithCleanups *E) {
+  llvm::Constant *VisitExprWithCleanups(ExprWithCleanups *E, QualType T) {
     if (!E->cleanupsHaveSideEffects())
-      return Visit(E->getSubExpr());
+      return Visit(E->getSubExpr(), T);
     return nullptr;
   }
 
-  llvm::Constant *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
-    return Visit(E->GetTemporaryExpr());
+  llvm::Constant *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E,
+                                                QualType T) {
+    return Visit(E->GetTemporaryExpr(), T);
   }
 
-  llvm::Constant *EmitArrayInitialization(InitListExpr *ILE) {
+  llvm::Constant *EmitArrayInitialization(InitListExpr *ILE, QualType T) {
     llvm::ArrayType *AType =
         cast<llvm::ArrayType>(ConvertType(ILE->getType()));
     llvm::Type *ElemTy = AType->getElementType();
@@ -790,13 +842,14 @@ public:
     // initialise any elements that have not been initialised explicitly
     unsigned NumInitableElts = std::min(NumInitElements, NumElements);
 
+    QualType EltType = CGM.getContext().getAsArrayType(T)->getElementType();
+
     // Initialize remaining array elements.
-    // FIXME: This doesn't handle member pointers correctly!
     llvm::Constant *fillC;
     if (Expr *filler = ILE->getArrayFiller())
-      fillC = CGM.EmitConstantExpr(filler, filler->getType(), CGF);
+      fillC = Emitter.tryEmitAbstractForMemory(filler, EltType);
     else
-      fillC = llvm::Constant::getNullValue(ElemTy);
+      fillC = Emitter.emitNullForMemory(EltType);
     if (!fillC)
       return nullptr;
 
@@ -805,13 +858,13 @@ public:
       return llvm::ConstantAggregateZero::get(AType);
 
     // Copy initializer elements.
-    std::vector<llvm::Constant*> Elts;
+    SmallVector<llvm::Constant*, 16> Elts;
     Elts.reserve(NumInitableElts + NumElements);
 
     bool RewriteType = false;
     for (unsigned i = 0; i < NumInitableElts; ++i) {
       Expr *Init = ILE->getInit(i);
-      llvm::Constant *C = CGM.EmitConstantExpr(Init, Init->getType(), CGF);
+      llvm::Constant *C = Emitter.tryEmitPrivateForMemory(Init, EltType);
       if (!C)
         return nullptr;
       RewriteType |= (C->getType() != ElemTy);
@@ -835,33 +888,33 @@ public:
     return llvm::ConstantArray::get(AType, Elts);
   }
 
-  llvm::Constant *EmitRecordInitialization(InitListExpr *ILE) {
-    return ConstStructBuilder::BuildStruct(CGM, CGF, ILE);
+  llvm::Constant *EmitRecordInitialization(InitListExpr *ILE, QualType T) {
+    return ConstStructBuilder::BuildStruct(Emitter, ILE, T);
   }
 
-  llvm::Constant *VisitImplicitValueInitExpr(ImplicitValueInitExpr* E) {
-    return CGM.EmitNullConstant(E->getType());
+  llvm::Constant *VisitImplicitValueInitExpr(ImplicitValueInitExpr* E,
+                                             QualType T) {
+    return CGM.EmitNullConstant(T);
   }
 
-  llvm::Constant *VisitInitListExpr(InitListExpr *ILE) {
+  llvm::Constant *VisitInitListExpr(InitListExpr *ILE, QualType T) {
     if (ILE->isTransparent())
-      return Visit(ILE->getInit(0));
+      return Visit(ILE->getInit(0), T);
 
     if (ILE->getType()->isArrayType())
-      return EmitArrayInitialization(ILE);
+      return EmitArrayInitialization(ILE, T);
 
     if (ILE->getType()->isRecordType())
-      return EmitRecordInitialization(ILE);
+      return EmitRecordInitialization(ILE, T);
 
     return nullptr;
   }
 
   llvm::Constant *EmitDesignatedInitUpdater(llvm::Constant *Base,
-                                            InitListExpr *Updater) {
-    QualType ExprType = Updater->getType();
-
-    if (ExprType->isArrayType()) {
-      llvm::ArrayType *AType = cast<llvm::ArrayType>(ConvertType(ExprType));
+                                            InitListExpr *Updater,
+                                            QualType destType) {
+    if (auto destAT = CGM.getContext().getAsArrayType(destType)) {
+      llvm::ArrayType *AType = cast<llvm::ArrayType>(ConvertType(destType));
       llvm::Type *ElemType = AType->getElementType();
 
       unsigned NumInitElements = Updater->getNumInits();
@@ -870,12 +923,12 @@ public:
       std::vector<llvm::Constant *> Elts;
       Elts.reserve(NumElements);
 
-      if (llvm::ConstantDataArray *DataArray =
-            dyn_cast<llvm::ConstantDataArray>(Base))
+      QualType destElemType = destAT->getElementType();
+
+      if (auto DataArray = dyn_cast<llvm::ConstantDataArray>(Base))
         for (unsigned i = 0; i != NumElements; ++i)
           Elts.push_back(DataArray->getElementAsConstant(i));
-      else if (llvm::ConstantArray *Array =
-                 dyn_cast<llvm::ConstantArray>(Base))
+      else if (auto Array = dyn_cast<llvm::ConstantArray>(Base))
         for (unsigned i = 0; i != NumElements; ++i)
           Elts.push_back(Array->getOperand(i));
       else
@@ -884,7 +937,7 @@ public:
       llvm::Constant *fillC = nullptr;
       if (Expr *filler = Updater->getArrayFiller())
         if (!isa<NoInitExpr>(filler))
-          fillC = CGM.EmitConstantExpr(filler, filler->getType(), CGF);
+          fillC = Emitter.tryEmitAbstractForMemory(filler, destElemType);
       bool RewriteType = (fillC && fillC->getType() != ElemType);
 
       for (unsigned i = 0; i != NumElements; ++i) {
@@ -897,9 +950,9 @@ public:
         else if (!Init || isa<NoInitExpr>(Init))
           ; // Do nothing.
         else if (InitListExpr *ChildILE = dyn_cast<InitListExpr>(Init))
-          Elts[i] = EmitDesignatedInitUpdater(Elts[i], ChildILE);
+          Elts[i] = EmitDesignatedInitUpdater(Elts[i], ChildILE, destElemType);
         else
-          Elts[i] = CGM.EmitConstantExpr(Init, Init->getType(), CGF);
+          Elts[i] = Emitter.tryEmitPrivateForMemory(Init, destElemType);
  
        if (!Elts[i])
           return nullptr;
@@ -919,25 +972,24 @@ public:
       return llvm::ConstantArray::get(AType, Elts);
     }
 
-    if (ExprType->isRecordType())
-      return ConstStructBuilder::BuildStruct(CGM, CGF, this,
-                 dyn_cast<llvm::ConstantStruct>(Base), Updater);
+    if (destType->isRecordType())
+      return ConstStructBuilder::BuildStruct(Emitter, this,
+                 dyn_cast<llvm::ConstantStruct>(Base), Updater, destType);
 
     return nullptr;
   }
 
-  llvm::Constant *VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
-    return EmitDesignatedInitUpdater(
-               CGM.EmitConstantExpr(E->getBase(), E->getType(), CGF),
-               E->getUpdater());
+  llvm::Constant *VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E,
+                                                QualType destType) {
+    auto C = Visit(E->getBase(), destType);
+    if (!C) return nullptr;
+    return EmitDesignatedInitUpdater(C, E->getUpdater(), destType);
   }  
 
-  llvm::Constant *VisitCXXConstructExpr(CXXConstructExpr *E) {
+  llvm::Constant *VisitCXXConstructExpr(CXXConstructExpr *E, QualType Ty) {
     if (!E->getConstructor()->isTrivial())
       return nullptr;
 
-    QualType Ty = E->getType();
-
     // FIXME: We should not have to call getBaseElementType here.
     const RecordType *RT = 
       CGM.getContext().getBaseElementType(Ty)->getAs<RecordType>();
@@ -960,26 +1012,23 @@ public:
       assert(CGM.getContext().hasSameUnqualifiedType(Ty, Arg->getType()) &&
              "argument to copy ctor is of wrong type");
 
-      return Visit(Arg);
+      return Visit(Arg, Ty);
     }
 
     return CGM.EmitNullConstant(Ty);
   }
 
-  llvm::Constant *VisitStringLiteral(StringLiteral *E) {
+  llvm::Constant *VisitStringLiteral(StringLiteral *E, QualType T) {
     return CGM.GetConstantArrayFromStringLiteral(E);
   }
 
-  llvm::Constant *VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+  llvm::Constant *VisitObjCEncodeExpr(ObjCEncodeExpr *E, QualType T) {
     // This must be an @encode initializing an array in a static initializer.
     // Don't emit it as the address of the string, emit the string data itself
     // as an inline array.
     std::string Str;
     CGM.getContext().getObjCEncodingForType(E->getEncodedType(), Str);
-    QualType T = E->getType();
-    if (T->getTypeClass() == Type::TypeOfExpr)
-      T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType();
-    const ConstantArrayType *CAT = cast<ConstantArrayType>(T);
+    const ConstantArrayType *CAT = CGM.getContext().getAsConstantArrayType(T);
 
     // Resize the string to the right size, adding zeros at the end, or
     // truncating as needed.
@@ -987,8 +1036,8 @@ public:
     return llvm::ConstantDataArray::getString(VMContext, Str, false);
   }
 
-  llvm::Constant *VisitUnaryExtension(const UnaryOperator *E) {
-    return Visit(E->getSubExpr());
+  llvm::Constant *VisitUnaryExtension(const UnaryOperator *E, QualType T) {
+    return Visit(E->getSubExpr(), T);
   }
 
   // Utility methods
@@ -1022,28 +1071,9 @@ public:
     Expr *E = const_cast<Expr*>(LVBase.get<const Expr*>());
     switch (E->getStmtClass()) {
     default: break;
-    case Expr::CompoundLiteralExprClass: {
-      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();
-
-      auto GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(),
-                                     E->getType().isConstant(CGM.getContext()),
-                                     llvm::GlobalValue::InternalLinkage,
-                                     C, ".compoundliteral", nullptr,
-                                     llvm::GlobalVariable::NotThreadLocal,
-                          
CGM.getContext().getTargetAddressSpace(E->getType()));
-      GV->setAlignment(Align.getQuantity());
-      CGM.setAddrOfConstantCompoundLiteral(CLE, GV);
-      return ConstantAddress(GV, Align);
-    }
+    case Expr::CompoundLiteralExprClass:
+      return tryEmitGlobalCompoundLiteral(CGM, Emitter.CGF,
+                                          cast<CompoundLiteralExpr>(E));
     case Expr::StringLiteralClass:
       return CGM.GetAddrOfConstantStringFromLiteral(cast<StringLiteral>(E));
     case Expr::ObjCEncodeExprClass:
@@ -1056,7 +1086,7 @@ public:
     }
     case Expr::PredefinedExprClass: {
       unsigned Type = cast<PredefinedExpr>(E)->getIdentType();
-      if (CGF) {
+      if (auto CGF = Emitter.CGF) {
         LValue Res = CGF->EmitPredefinedLValue(cast<PredefinedExpr>(E));
         return cast<ConstantAddress>(Res.getAddress());
       } else if (Type == PredefinedExpr::PrettyFunction) {
@@ -1066,9 +1096,10 @@ public:
       return CGM.GetAddrOfConstantCString("", ".tmp");
     }
     case Expr::AddrLabelExprClass: {
-      assert(CGF && "Invalid address of label expression outside function.");
+      assert(Emitter.CGF &&
+             "Invalid address of label expression outside function.");
       llvm::Constant *Ptr =
-        CGF->GetAddrOfLabel(cast<AddrLabelExpr>(E)->getLabel());
+        Emitter.CGF->GetAddrOfLabel(cast<AddrLabelExpr>(E)->getLabel());
       Ptr = llvm::ConstantExpr::getBitCast(Ptr, ConvertType(E->getType()));
       return ConstantAddress(Ptr, CharUnits::One());
     }
@@ -1091,7 +1122,7 @@ public:
     }
     case Expr::BlockExprClass: {
       StringRef FunctionName;
-      if (CGF)
+      if (auto CGF = Emitter.CGF)
         FunctionName = CGF->CurFn->getName();
       else
         FunctionName = "global";
@@ -1131,7 +1162,7 @@ public:
 
 }  // end anonymous namespace.
 
-bool ConstStructBuilder::Build(ConstExprEmitter *Emitter,
+bool ConstStructBuilder::Build(ConstExprEmitter *ExprEmitter,
                                llvm::ConstantStruct *Base,
                                InitListExpr *Updater) {
   assert(Base && "base expression should not be empty");
@@ -1179,9 +1210,10 @@ bool ConstStructBuilder::Build(ConstExpr
     if (!Init || isa<NoInitExpr>(Init))
       ; // Do nothing.
     else if (InitListExpr *ChildILE = dyn_cast<InitListExpr>(Init))
-      EltInit = Emitter->EmitDesignatedInitUpdater(EltInit, ChildILE);
+      EltInit = ExprEmitter->EmitDesignatedInitUpdater(EltInit, ChildILE,
+                                                       Field->getType());
     else
-      EltInit = CGM.EmitConstantExpr(Init, Field->getType(), CGF);
+      EltInit = Emitter.tryEmitPrivateForMemory(Init, Field->getType());
 
     ++ElementNo;
 
@@ -1200,26 +1232,294 @@ bool ConstStructBuilder::Build(ConstExpr
   return true;
 }
 
-llvm::Constant *CodeGenModule::EmitConstantInit(const VarDecl &D,
-                                                CodeGenFunction *CGF) {
+llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *C,
+                                                        AbstractState saved) {
+  Abstract = saved.OldValue;
+
+  assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&
+         "created a placeholder while doing an abstract emission?");
+
+  // No validation necessary for now.
+  // No cleanup to do for now.
+  return C;
+}
+
+llvm::Constant *
+ConstantEmitter::tryEmitAbstractForInitializer(const VarDecl &D) {
+  auto state = pushAbstract();
+  auto C = tryEmitPrivateForVarInit(D);
+  return validateAndPopAbstract(C, state);
+}
+
+llvm::Constant *
+ConstantEmitter::tryEmitAbstract(const Expr *E, QualType destType) {
+  auto state = pushAbstract();
+  auto C = tryEmitPrivate(E, destType);
+  return validateAndPopAbstract(C, state);
+}
+
+llvm::Constant *
+ConstantEmitter::tryEmitAbstract(const APValue &value, QualType destType) {
+  auto state = pushAbstract();
+  auto C = tryEmitPrivate(value, destType);
+  return validateAndPopAbstract(C, state);
+}
+
+llvm::Constant *
+ConstantEmitter::emitAbstract(const Expr *E, QualType destType) {
+  auto state = pushAbstract();
+  auto C = tryEmitPrivate(E, destType);
+  C = validateAndPopAbstract(C, state);
+  if (!C) {
+    CGM.Error(E->getExprLoc(),
+              "internal error: could not emit constant value \"abstractly\"");
+    C = CGM.EmitNullConstant(destType);
+  }
+  return C;
+}
+
+llvm::Constant *
+ConstantEmitter::emitAbstract(SourceLocation loc, const APValue &value,
+                              QualType destType) {
+  auto state = pushAbstract();
+  auto C = tryEmitPrivate(value, destType);
+  C = validateAndPopAbstract(C, state);
+  if (!C) {
+    CGM.Error(loc,
+              "internal error: could not emit constant value \"abstractly\"");
+    C = CGM.EmitNullConstant(destType);
+  }
+  return C;
+}
+
+llvm::Constant *ConstantEmitter::tryEmitForInitializer(const VarDecl &D) {
+  initializeNonAbstract(D.getType().getAddressSpace());
+  return markIfFailed(tryEmitPrivateForVarInit(D));
+}
+
+llvm::Constant *ConstantEmitter::tryEmitForInitializer(const Expr *E,
+                                                       unsigned destAddrSpace,
+                                                       QualType destType) {
+  initializeNonAbstract(destAddrSpace);
+  return markIfFailed(tryEmitPrivateForMemory(E, destType));
+}
+
+llvm::Constant *ConstantEmitter::emitForInitializer(const APValue &value,
+                                                    unsigned destAddrSpace,
+                                                    QualType destType) {
+  initializeNonAbstract(destAddrSpace);
+  auto C = tryEmitPrivateForMemory(value, destType);
+  assert(C && "couldn't emit constant value non-abstractly?");
+  return C;
+}
+
+llvm::GlobalValue *ConstantEmitter::getCurrentAddrPrivate() {
+  assert(!Abstract && "cannot get current address for abstract constant");
+
+
+
+  // Make an obviously ill-formed global that should blow up compilation
+  // if it survives.
+  auto global = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty, true,
+                                         llvm::GlobalValue::PrivateLinkage,
+                                         /*init*/ nullptr,
+                                         /*name*/ "",
+                                         /*before*/ nullptr,
+                                         llvm::GlobalVariable::NotThreadLocal,
+                                         
CGM.getContext().getTargetAddressSpace(DestAddressSpace));
+
+  PlaceholderAddresses.push_back(std::make_pair(nullptr, global));
+
+  return global;
+}
+
+void ConstantEmitter::registerCurrentAddrPrivate(llvm::Constant *signal,
+                                           llvm::GlobalValue *placeholder) {
+  assert(!PlaceholderAddresses.empty());
+  assert(PlaceholderAddresses.back().first == nullptr);
+  assert(PlaceholderAddresses.back().second == placeholder);
+  PlaceholderAddresses.back().first = signal;
+}
+
+namespace {
+  struct ReplacePlaceholders {
+    CodeGenModule &CGM;
+
+    /// The base address of the global.
+    llvm::Constant *Base;
+    llvm::Type *BaseValueTy = nullptr;
+
+    /// The placeholder addresses that were registered during emission.
+    llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> 
PlaceholderAddresses;
+
+    /// The locations of the placeholder signals.
+    llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;
+
+    /// The current index stack.  We use a simple unsigned stack because
+    /// we assume that placeholders will be relatively sparse in the
+    /// initializer, but we cache the index values we find just in case.
+    llvm::SmallVector<unsigned, 8> Indices;
+    llvm::SmallVector<llvm::Constant*, 8> IndexValues;
+
+    ReplacePlaceholders(CodeGenModule &CGM, llvm::Constant *base,
+                        ArrayRef<std::pair<llvm::Constant*,
+                                           llvm::GlobalVariable*>> addresses)
+        : CGM(CGM), Base(base),
+          PlaceholderAddresses(addresses.begin(), addresses.end()) {
+    }
+
+    void replaceInInitializer(llvm::Constant *init) {
+      // Remember the type of the top-most initializer.
+      BaseValueTy = init->getType();
+
+      // Initialize the stack.
+      Indices.push_back(0);
+      IndexValues.push_back(nullptr);
+
+      // Recurse into the initializer.
+      findLocations(init);
+
+      // Check invariants.
+      assert(IndexValues.size() == Indices.size() && "mismatch");
+      assert(Indices.size() == 1 && "didn't pop all indices");
+
+      // Do the replacement; this basically invalidates 'init'.
+      assert(Locations.size() == PlaceholderAddresses.size() &&
+             "missed a placeholder?");
+
+      // We're iterating over a hashtable, so this would be a source of
+      // non-determinism in compiler output *except* that we're just
+      // messing around with llvm::Constant structures, which never itself
+      // does anything that should be visible in compiler output.
+      for (auto &entry : Locations) {
+        assert(entry.first->getParent() == nullptr && "not a placeholder!");
+        entry.first->replaceAllUsesWith(entry.second);
+        entry.first->eraseFromParent();
+      }
+    }
+
+  private:
+    void findLocations(llvm::Constant *init) {
+      // Recurse into aggregates.
+      if (auto agg = dyn_cast<llvm::ConstantAggregate>(init)) {
+        for (unsigned i = 0, e = agg->getNumOperands(); i != e; ++i) {
+          Indices.push_back(i);
+          IndexValues.push_back(nullptr);
+
+          findLocations(agg->getOperand(i));
+
+          IndexValues.pop_back();
+          Indices.pop_back();
+        }
+        return;
+      }
+
+      // Otherwise, check for registered constants.
+      while (true) {
+        auto it = PlaceholderAddresses.find(init);
+        if (it != PlaceholderAddresses.end()) {
+          setLocation(it->second);
+          break;
+        }
+
+        // Look through bitcasts or other expressions.
+        if (auto expr = dyn_cast<llvm::ConstantExpr>(init)) {
+          init = expr->getOperand(0);
+        } else {
+          break;
+        }
+      }
+    }
+
+    void setLocation(llvm::GlobalVariable *placeholder) {
+      assert(Locations.find(placeholder) == Locations.end() &&
+             "already found location for placeholder!");
+
+      // Lazily fill in IndexValues with the values from Indices.
+      // We do this in reverse because we should always have a strict
+      // prefix of indices from the start.
+      assert(Indices.size() == IndexValues.size());
+      for (size_t i = Indices.size() - 1; i != size_t(-1); --i) {
+        if (IndexValues[i]) {
+#ifndef NDEBUG
+          for (size_t j = 0; j != i + 1; ++j) {
+            assert(IndexValues[j] &&
+                   isa<llvm::ConstantInt>(IndexValues[j]) &&
+                   cast<llvm::ConstantInt>(IndexValues[j])->getZExtValue()
+                     == Indices[j]);
+          }
+#endif
+          break;
+        }
+
+        IndexValues[i] = llvm::ConstantInt::get(CGM.Int32Ty, Indices[i]);
+      }
+
+      // Form a GEP and then bitcast to the placeholder type so that the
+      // replacement will succeed.
+      llvm::Constant *location =
+        llvm::ConstantExpr::getInBoundsGetElementPtr(BaseValueTy,
+                                                     Base, IndexValues);
+      location = llvm::ConstantExpr::getBitCast(location,
+                                                placeholder->getType());
+
+      Locations.insert({placeholder, location});
+    }
+  };
+}
+
+void ConstantEmitter::finalize(llvm::GlobalVariable *global) {
+  assert(InitializedNonAbstract &&
+         "finalizing emitter that was used for abstract emission?");
+  assert(!Finalized && "finalizing emitter multiple times");
+  assert(global->getInitializer());
+
+  // Note that we might also be Failed.
+  Finalized = true;
+
+  if (!PlaceholderAddresses.empty()) {
+    ReplacePlaceholders(CGM, global, PlaceholderAddresses)
+      .replaceInInitializer(global->getInitializer());
+    PlaceholderAddresses.clear(); // satisfy
+  }
+}
+
+ConstantEmitter::~ConstantEmitter() {
+  assert((!InitializedNonAbstract || Finalized || Failed) &&
+         "not finalized after being initialized for non-abstract emission");
+  assert(PlaceholderAddresses.empty() && "unhandled placeholders");
+}
+
+static QualType getNonMemoryType(CodeGenModule &CGM, QualType type) {
+  if (auto AT = type->getAs<AtomicType>()) {
+    return CGM.getContext().getQualifiedType(AT->getValueType(),
+                                             type.getQualifiers());
+  }
+  return type;
+}
+
+llvm::Constant *ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) {
   // Make a quick check if variable can be default NULL initialized
   // and avoid going through rest of code which may do, for c++11,
   // initialization of memory to all NULLs.
   if (!D.hasLocalStorage()) {
-    QualType Ty = D.getType();
-    if (Ty->isArrayType())
-      Ty = Context.getBaseElementType(Ty);
+    QualType Ty = CGM.getContext().getBaseElementType(D.getType());
     if (Ty->isRecordType())
       if (const CXXConstructExpr *E =
           dyn_cast_or_null<CXXConstructExpr>(D.getInit())) {
         const CXXConstructorDecl *CD = E->getConstructor();
         if (CD->isTrivial() && CD->isDefaultConstructor())
-          return EmitNullConstant(D.getType());
+          return CGM.EmitNullConstant(D.getType());
       }
   }
-  
-  if (const APValue *Value = D.evaluateValue())
-    return EmitConstantValueForMemory(*Value, D.getType(), CGF);
+
+  QualType destType = D.getType();
+
+  // Try to emit the initializer.  Note that this can allow some things that
+  // are not allowed by tryEmitPrivateForMemory alone.
+  if (auto value = D.evaluateValue()) {
+    return tryEmitPrivateForMemory(*value, destType);
+  }
 
   // FIXME: Implement C++11 [basic.start.init]p2: if the initializer of a
   // reference is a constant expression, and the reference binds to a 
temporary,
@@ -1227,42 +1527,95 @@ llvm::Constant *CodeGenModule::EmitConst
   // incorrectly emit a prvalue constant in this case, and the calling code
   // interprets that as the (pointer) value of the reference, rather than the
   // desired value of the referee.
-  if (D.getType()->isReferenceType())
+  if (destType->isReferenceType())
     return nullptr;
 
   const Expr *E = D.getInit();
   assert(E && "No initializer to emit");
 
-  llvm::Constant* C = ConstExprEmitter(*this, CGF).Visit(const_cast<Expr*>(E));
-  if (C && C->getType()->isIntegerTy(1)) {
-    llvm::Type *BoolTy = getTypes().ConvertTypeForMem(E->getType());
-    C = llvm::ConstantExpr::getZExt(C, BoolTy);
+  auto nonMemoryDestType = getNonMemoryType(CGM, destType);
+  auto C =
+    ConstExprEmitter(*this).Visit(const_cast<Expr*>(E), nonMemoryDestType);
+  return (C ? emitForMemory(C, destType) : nullptr);
+}
+
+llvm::Constant *
+ConstantEmitter::tryEmitAbstractForMemory(const Expr *E, QualType destType) {
+  auto nonMemoryDestType = getNonMemoryType(CGM, destType);
+  auto C = tryEmitAbstract(E, nonMemoryDestType);
+  return (C ? emitForMemory(C, destType) : nullptr);  
+}
+
+llvm::Constant *
+ConstantEmitter::tryEmitAbstractForMemory(const APValue &value,
+                                          QualType destType) {
+  auto nonMemoryDestType = getNonMemoryType(CGM, destType);
+  auto C = tryEmitAbstract(value, nonMemoryDestType);
+  return (C ? emitForMemory(C, destType) : nullptr);  
+}
+
+llvm::Constant *ConstantEmitter::tryEmitPrivateForMemory(const Expr *E,
+                                                         QualType destType) {
+  auto nonMemoryDestType = getNonMemoryType(CGM, destType);
+  llvm::Constant *C = tryEmitPrivate(E, nonMemoryDestType);
+  return (C ? emitForMemory(C, destType) : nullptr);
+}
+
+llvm::Constant *ConstantEmitter::tryEmitPrivateForMemory(const APValue &value,
+                                                         QualType destType) {
+  auto nonMemoryDestType = getNonMemoryType(CGM, destType);
+  auto C = tryEmitPrivate(value, nonMemoryDestType);
+  return (C ? emitForMemory(C, destType) : nullptr);
+}
+
+llvm::Constant *ConstantEmitter::emitForMemory(CodeGenModule &CGM,
+                                               llvm::Constant *C,
+                                               QualType destType) {
+  // For an _Atomic-qualified constant, we may need to add tail padding.
+  if (auto AT = destType->getAs<AtomicType>()) {
+    QualType destValueType = AT->getValueType();
+    C = emitForMemory(CGM, C, destValueType);
+
+    uint64_t innerSize = CGM.getContext().getTypeSize(destValueType);
+    uint64_t outerSize = CGM.getContext().getTypeSize(destType);
+    if (innerSize == outerSize)
+      return C;
+
+    assert(innerSize < outerSize && "emitted over-large constant for atomic");
+    llvm::Constant *elts[] = {
+      C,
+      llvm::ConstantAggregateZero::get(
+          llvm::ArrayType::get(CGM.Int8Ty, (outerSize - innerSize) / 8))
+    };
+    return llvm::ConstantStruct::getAnon(elts);
   }
+
+  // Zero-extend bool.
+  if (C->getType()->isIntegerTy(1)) {
+    llvm::Type *boolTy = CGM.getTypes().ConvertTypeForMem(destType);
+    return llvm::ConstantExpr::getZExt(C, boolTy);
+  }
+
   return C;
 }
 
-llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
-                                                QualType DestType,
-                                                CodeGenFunction *CGF) {
+llvm::Constant *ConstantEmitter::tryEmitPrivate(const Expr *E,
+                                                QualType destType) {
   Expr::EvalResult Result;
 
   bool Success = false;
 
-  if (DestType->isReferenceType())
-    Success = E->EvaluateAsLValue(Result, Context);
+  if (destType->isReferenceType())
+    Success = E->EvaluateAsLValue(Result, CGM.getContext());
   else
-    Success = E->EvaluateAsRValue(Result, Context);
+    Success = E->EvaluateAsRValue(Result, CGM.getContext());
 
-  llvm::Constant *C = nullptr;
+  llvm::Constant *C;
   if (Success && !Result.HasSideEffects)
-    C = EmitConstantValue(Result.Val, DestType, CGF);
+    C = tryEmitPrivate(Result.Val, destType);
   else
-    C = ConstExprEmitter(*this, CGF).Visit(const_cast<Expr*>(E));
+    C = ConstExprEmitter(*this).Visit(const_cast<Expr*>(E), destType);
 
-  if (C && C->getType()->isIntegerTy(1)) {
-    llvm::Type *BoolTy = getTypes().ConvertTypeForMem(E->getType());
-    C = llvm::ConstantExpr::getZExt(C, BoolTy);
-  }
   return C;
 }
 
@@ -1270,75 +1623,56 @@ llvm::Constant *CodeGenModule::getNullPo
   return getTargetCodeGenInfo().getNullPointer(*this, T, QT);
 }
 
-llvm::Constant *CodeGenModule::EmitConstantValue(const APValue &Value,
-                                                 QualType DestType,
-                                                 CodeGenFunction *CGF) {
-  // For an _Atomic-qualified constant, we may need to add tail padding.
-  if (auto *AT = DestType->getAs<AtomicType>()) {
-    QualType InnerType = AT->getValueType();
-    auto *Inner = EmitConstantValue(Value, InnerType, CGF);
-
-    uint64_t InnerSize = Context.getTypeSize(InnerType);
-    uint64_t OuterSize = Context.getTypeSize(DestType);
-    if (InnerSize == OuterSize)
-      return Inner;
-
-    assert(InnerSize < OuterSize && "emitted over-large constant for atomic");
-    llvm::Constant *Elts[] = {
-      Inner,
-      llvm::ConstantAggregateZero::get(
-          llvm::ArrayType::get(Int8Ty, (OuterSize - InnerSize) / 8))
-    };
-    return llvm::ConstantStruct::getAnon(Elts);
-  }
-
+llvm::Constant *ConstantEmitter::tryEmitPrivate(const APValue &Value,
+                                                QualType DestType) {
   switch (Value.getKind()) {
   case APValue::Uninitialized:
     llvm_unreachable("Constant expressions should be initialized.");
   case APValue::LValue: {
-    llvm::Type *DestTy = getTypes().ConvertTypeForMem(DestType);
+    llvm::Type *DestTy = CGM.getTypes().ConvertTypeForMem(DestType);
     llvm::Constant *Offset =
-      llvm::ConstantInt::get(Int64Ty, Value.getLValueOffset().getQuantity());
-
-    llvm::Constant *C = nullptr;
+      llvm::ConstantInt::get(CGM.Int64Ty,
+                             Value.getLValueOffset().getQuantity());
 
     if (APValue::LValueBase LVBase = Value.getLValueBase()) {
       // An array can be represented as an lvalue referring to the base.
       if (isa<llvm::ArrayType>(DestTy)) {
         assert(Offset->isNullValue() && "offset on array initializer");
-        return ConstExprEmitter(*this, CGF).Visit(
-          const_cast<Expr*>(LVBase.get<const Expr*>()));
+        return ConstExprEmitter(*this).Visit(
+          const_cast<Expr*>(LVBase.get<const Expr*>()),
+          DestType);
       }
 
-      C = ConstExprEmitter(*this, CGF).EmitLValue(LVBase).getPointer();
+      auto C = ConstExprEmitter(*this).EmitLValue(LVBase).getPointer();
 
       // Apply offset if necessary.
       if (!Offset->isNullValue()) {
         unsigned AS = C->getType()->getPointerAddressSpace();
-        llvm::Type *CharPtrTy = Int8Ty->getPointerTo(AS);
+        llvm::Type *CharPtrTy = CGM.Int8Ty->getPointerTo(AS);
         llvm::Constant *Casted = llvm::ConstantExpr::getBitCast(C, CharPtrTy);
-        Casted = llvm::ConstantExpr::getGetElementPtr(Int8Ty, Casted, Offset);
+        Casted =
+          llvm::ConstantExpr::getGetElementPtr(CGM.Int8Ty, Casted, Offset);
         C = llvm::ConstantExpr::getPointerCast(Casted, C->getType());
       }
 
       // Convert to the appropriate type; this could be an lvalue for
-      // an integer.
+      // an integer.  FIXME: performAddrSpaceCast
       if (isa<llvm::PointerType>(DestTy))
         return llvm::ConstantExpr::getPointerCast(C, DestTy);
 
       return llvm::ConstantExpr::getPtrToInt(C, DestTy);
     } else {
-      C = Offset;
+      auto C = Offset;
 
       // Convert to the appropriate type; this could be an lvalue for
       // an integer.
       if (auto PT = dyn_cast<llvm::PointerType>(DestTy)) {
         if (Value.isNullPointer())
-          return getNullPointer(PT, DestType);
+          return CGM.getNullPointer(PT, DestType);
         // Convert the integer to a pointer-sized integer before converting it
         // to a pointer.
         C = llvm::ConstantExpr::getIntegerCast(
-            C, getDataLayout().getIntPtrType(DestTy),
+            C, CGM.getDataLayout().getIntPtrType(DestTy),
             /*isSigned=*/false);
         return llvm::ConstantExpr::getIntToPtr(C, DestTy);
       }
@@ -1351,13 +1685,13 @@ llvm::Constant *CodeGenModule::EmitConst
     }
   }
   case APValue::Int:
-    return llvm::ConstantInt::get(VMContext, Value.getInt());
+    return llvm::ConstantInt::get(CGM.getLLVMContext(), Value.getInt());
   case APValue::ComplexInt: {
     llvm::Constant *Complex[2];
 
-    Complex[0] = llvm::ConstantInt::get(VMContext,
+    Complex[0] = llvm::ConstantInt::get(CGM.getLLVMContext(),
                                         Value.getComplexIntReal());
-    Complex[1] = llvm::ConstantInt::get(VMContext,
+    Complex[1] = llvm::ConstantInt::get(CGM.getLLVMContext(),
                                         Value.getComplexIntImag());
 
     // FIXME: the target may want to specify that this is packed.
@@ -1368,18 +1702,19 @@ llvm::Constant *CodeGenModule::EmitConst
   case APValue::Float: {
     const llvm::APFloat &Init = Value.getFloat();
     if (&Init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
-        !Context.getLangOpts().NativeHalfType &&
-        !Context.getLangOpts().HalfArgsAndReturns)
-      return llvm::ConstantInt::get(VMContext, Init.bitcastToAPInt());
+        !CGM.getContext().getLangOpts().NativeHalfType &&
+        !CGM.getContext().getLangOpts().HalfArgsAndReturns)
+      return llvm::ConstantInt::get(CGM.getLLVMContext(),
+                                    Init.bitcastToAPInt());
     else
-      return llvm::ConstantFP::get(VMContext, Init);
+      return llvm::ConstantFP::get(CGM.getLLVMContext(), Init);
   }
   case APValue::ComplexFloat: {
     llvm::Constant *Complex[2];
 
-    Complex[0] = llvm::ConstantFP::get(VMContext,
+    Complex[0] = llvm::ConstantFP::get(CGM.getLLVMContext(),
                                        Value.getComplexFloatReal());
-    Complex[1] = llvm::ConstantFP::get(VMContext,
+    Complex[1] = llvm::ConstantFP::get(CGM.getLLVMContext(),
                                        Value.getComplexFloatImag());
 
     // FIXME: the target may want to specify that this is packed.
@@ -1394,9 +1729,9 @@ llvm::Constant *CodeGenModule::EmitConst
     for (unsigned I = 0; I != NumElts; ++I) {
       const APValue &Elt = Value.getVectorElt(I);
       if (Elt.isInt())
-        Inits[I] = llvm::ConstantInt::get(VMContext, Elt.getInt());
+        Inits[I] = llvm::ConstantInt::get(CGM.getLLVMContext(), Elt.getInt());
       else if (Elt.isFloat())
-        Inits[I] = llvm::ConstantFP::get(VMContext, Elt.getFloat());
+        Inits[I] = llvm::ConstantFP::get(CGM.getLLVMContext(), Elt.getFloat());
       else
         llvm_unreachable("unsupported vector element type");
     }
@@ -1405,13 +1740,14 @@ llvm::Constant *CodeGenModule::EmitConst
   case APValue::AddrLabelDiff: {
     const AddrLabelExpr *LHSExpr = Value.getAddrLabelDiffLHS();
     const AddrLabelExpr *RHSExpr = Value.getAddrLabelDiffRHS();
-    llvm::Constant *LHS = EmitConstantExpr(LHSExpr, LHSExpr->getType(), CGF);
-    llvm::Constant *RHS = EmitConstantExpr(RHSExpr, RHSExpr->getType(), CGF);
+    llvm::Constant *LHS = tryEmitPrivate(LHSExpr, LHSExpr->getType());
+    llvm::Constant *RHS = tryEmitPrivate(RHSExpr, RHSExpr->getType());
+    if (!LHS || !RHS) return nullptr;
 
     // Compute difference
-    llvm::Type *ResultType = getTypes().ConvertType(DestType);
-    LHS = llvm::ConstantExpr::getPtrToInt(LHS, IntPtrTy);
-    RHS = llvm::ConstantExpr::getPtrToInt(RHS, IntPtrTy);
+    llvm::Type *ResultType = CGM.getTypes().ConvertType(DestType);
+    LHS = llvm::ConstantExpr::getPtrToInt(LHS, CGM.IntPtrTy);
+    RHS = llvm::ConstantExpr::getPtrToInt(RHS, CGM.IntPtrTy);
     llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);
 
     // LLVM is a bit sensitive about the exact format of the
@@ -1421,21 +1757,21 @@ llvm::Constant *CodeGenModule::EmitConst
   }
   case APValue::Struct:
   case APValue::Union:
-    return ConstStructBuilder::BuildStruct(*this, CGF, Value, DestType);
+    return ConstStructBuilder::BuildStruct(*this, Value, DestType);
   case APValue::Array: {
-    const ArrayType *CAT = Context.getAsArrayType(DestType);
+    const ArrayType *CAT = CGM.getContext().getAsArrayType(DestType);
     unsigned NumElements = Value.getArraySize();
     unsigned NumInitElts = Value.getArrayInitializedElts();
 
     // Emit array filler, if there is one.
     llvm::Constant *Filler = nullptr;
     if (Value.hasArrayFiller())
-      Filler = EmitConstantValueForMemory(Value.getArrayFiller(),
-                                          CAT->getElementType(), CGF);
+      Filler = tryEmitAbstractForMemory(Value.getArrayFiller(),
+                                        CAT->getElementType());
 
     // Emit initializer elements.
     llvm::Type *CommonElementType =
-        getTypes().ConvertType(CAT->getElementType());
+        CGM.getTypes().ConvertType(CAT->getElementType());
 
     // Try to use a ConstantAggregateZero if we can.
     if (Filler && Filler->isNullValue() && !NumInitElts) {
@@ -1444,15 +1780,21 @@ llvm::Constant *CodeGenModule::EmitConst
       return llvm::ConstantAggregateZero::get(AType);
     }
 
-    std::vector<llvm::Constant*> Elts;
+    SmallVector<llvm::Constant*, 16> Elts;
     Elts.reserve(NumElements);
     for (unsigned I = 0; I < NumElements; ++I) {
       llvm::Constant *C = Filler;
-      if (I < NumInitElts)
-        C = EmitConstantValueForMemory(Value.getArrayInitializedElt(I),
-                                       CAT->getElementType(), CGF);
-      else
-        assert(Filler && "Missing filler for implicit elements of 
initializer");
+      if (I < NumInitElts) {
+        C = tryEmitPrivateForMemory(Value.getArrayInitializedElt(I),
+                                    CAT->getElementType());
+      } else if (!Filler) {
+        assert(Value.hasArrayFiller() &&
+               "Missing filler for implicit elements of initializer");
+        C = tryEmitPrivateForMemory(Value.getArrayFiller(),
+                                    CAT->getElementType());
+      }
+      if (!C) return nullptr;
+
       if (I == 0)
         CommonElementType = C->getType();
       else if (C->getType() != CommonElementType)
@@ -1466,7 +1808,8 @@ llvm::Constant *CodeGenModule::EmitConst
       Types.reserve(NumElements);
       for (unsigned i = 0, e = Elts.size(); i < e; ++i)
         Types.push_back(Elts[i]->getType());
-      llvm::StructType *SType = llvm::StructType::get(VMContext, Types, true);
+      llvm::StructType *SType =
+        llvm::StructType::get(CGM.getLLVMContext(), Types, true);
       return llvm::ConstantStruct::get(SType, Elts);
     }
 
@@ -1475,23 +1818,11 @@ llvm::Constant *CodeGenModule::EmitConst
     return llvm::ConstantArray::get(AType, Elts);
   }
   case APValue::MemberPointer:
-    return getCXXABI().EmitMemberPointer(Value, DestType);
+    return CGM.getCXXABI().EmitMemberPointer(Value, DestType);
   }
   llvm_unreachable("Unknown APValue kind");
 }
 
-llvm::Constant *
-CodeGenModule::EmitConstantValueForMemory(const APValue &Value,
-                                          QualType DestType,
-                                          CodeGenFunction *CGF) {
-  llvm::Constant *C = EmitConstantValue(Value, DestType, CGF);
-  if (C->getType()->isIntegerTy(1)) {
-    llvm::Type *BoolTy = getTypes().ConvertTypeForMem(DestType);
-    C = llvm::ConstantExpr::getZExt(C, BoolTy);
-  }
-  return C;
-}
-
 llvm::GlobalVariable *CodeGenModule::getAddrOfConstantCompoundLiteralIfEmitted(
     const CompoundLiteralExpr *E) {
   return EmittedCompoundLiterals.lookup(E);
@@ -1507,7 +1838,7 @@ void CodeGenModule::setAddrOfConstantCom
 ConstantAddress
 CodeGenModule::GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *E) {
   assert(E->isFileScope() && "not a file-scope compound literal expr");
-  return ConstExprEmitter(*this, nullptr).EmitLValue(E);
+  return tryEmitGlobalCompoundLiteral(*this, nullptr, E);
 }
 
 llvm::Constant *
@@ -1629,6 +1960,11 @@ static llvm::Constant *EmitNullConstantF
   return EmitNullConstant(CGM, base, /*asCompleteObject=*/false);
 }
 
+llvm::Constant *ConstantEmitter::emitNullForMemory(CodeGenModule &CGM,
+                                                   QualType T) {
+  return emitForMemory(CGM, CGM.EmitNullConstant(T), T);
+}
+
 llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {
   if (T->getAs<PointerType>())
     return getNullPointer(
@@ -1643,7 +1979,8 @@ llvm::Constant *CodeGenModule::EmitNullC
 
     QualType ElementTy = CAT->getElementType();
 
-    llvm::Constant *Element = EmitNullConstant(ElementTy);
+    llvm::Constant *Element =
+      ConstantEmitter::emitNullForMemory(*this, ElementTy);
     unsigned NumElements = CAT->getSize().getZExtValue();
     SmallVector<llvm::Constant *, 8> Array(NumElements, Element);
     return llvm::ConstantArray::get(ATy, Array);

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=310964&r1=310963&r2=310964&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Aug 15 14:42:52 2017
@@ -24,6 +24,7 @@
 #include "CodeGenFunction.h"
 #include "CodeGenPGO.h"
 #include "CodeGenTBAA.h"
+#include "ConstantEmitter.h"
 #include "CoverageMappingGen.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
@@ -2686,6 +2687,8 @@ void CodeGenModule::EmitGlobalVarDefinit
   const VarDecl *InitDecl;
   const Expr *InitExpr = D->getAnyInitializer(InitDecl);
 
+  Optional<ConstantEmitter> emitter;
+
   // CUDA E.2.4.1 "__shared__ variables cannot have an initialization
   // as part of their declaration."  Sema has already checked for
   // error cases, so we just need to set Init to UndefValue.
@@ -2706,7 +2709,8 @@ void CodeGenModule::EmitGlobalVarDefinit
     Init = EmitNullConstant(D->getType());
   } else {
     initializedGlobalDecl = GlobalDecl(D);
-    Init = EmitConstantInit(*InitDecl);
+    emitter.emplace(*this);
+    Init = emitter->tryEmitForInitializer(*InitDecl);
 
     if (!Init) {
       QualType T = InitExpr->getType();
@@ -2819,7 +2823,9 @@ void CodeGenModule::EmitGlobalVarDefinit
         Linkage = llvm::GlobalValue::InternalLinkage;
     }
   }
+
   GV->setInitializer(Init);
+  if (emitter) emitter->finalize(GV);
 
   // If it is safe to mark the global 'constant', do so now.
   GV->setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor &&
@@ -3735,12 +3741,18 @@ ConstantAddress CodeGenModule::GetAddrOf
       !EvalResult.hasSideEffects())
     Value = &EvalResult.Val;
 
+  unsigned AddrSpace =
+      VD ? GetGlobalVarAddressSpace(VD) : MaterializedType.getAddressSpace();
+
+  Optional<ConstantEmitter> emitter;
   llvm::Constant *InitialValue = nullptr;
   bool Constant = false;
   llvm::Type *Type;
   if (Value) {
     // The temporary has a constant initializer, use it.
-    InitialValue = EmitConstantValue(*Value, MaterializedType, nullptr);
+    emitter.emplace(*this);
+    InitialValue = emitter->emitForInitializer(*Value, AddrSpace,
+                                               MaterializedType);
     Constant = isTypeConstant(MaterializedType, /*ExcludeCtor*/Value);
     Type = InitialValue->getType();
   } else {
@@ -3765,12 +3777,11 @@ ConstantAddress CodeGenModule::GetAddrOf
       Linkage = llvm::GlobalVariable::InternalLinkage;
     }
   }
-  unsigned AddrSpace =
-      VD ? GetGlobalVarAddressSpace(VD) : MaterializedType.getAddressSpace();
   auto TargetAS = getContext().getTargetAddressSpace(AddrSpace);
   auto *GV = new llvm::GlobalVariable(
       getModule(), Type, Constant, Linkage, InitialValue, Name.c_str(),
       /*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal, 
TargetAS);
+  if (emitter) emitter->finalize(GV);
   setGlobalVisibility(GV, VD);
   GV->setAlignment(Align.getQuantity());
   if (supportsCOMDAT() && GV->isWeakForLinker())
@@ -4535,7 +4546,7 @@ llvm::SanitizerStatReport &CodeGenModule
 llvm::Value *
 CodeGenModule::createOpenCLIntToSamplerConversion(const Expr *E,
                                                   CodeGenFunction &CGF) {
-  llvm::Constant *C = EmitConstantExpr(E, E->getType(), &CGF);
+  llvm::Constant *C = ConstantEmitter(CGF).emitAbstract(E, E->getType());
   auto SamplerT = getOpenCLRuntime().getSamplerType(E->getType().getTypePtr());
   auto FTy = llvm::FunctionType::get(SamplerT, {C->getType()}, false);
   return CGF.Builder.CreateCall(CreateRuntimeFunction(FTy,

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=310964&r1=310963&r2=310964&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Aug 15 14:42:52 2017
@@ -942,27 +942,6 @@ public:
 
   llvm::Constant *getMemberPointerConstant(const UnaryOperator *e);
 
-  /// Try to emit the initializer for the given declaration as a constant;
-  /// returns 0 if the expression cannot be emitted as a constant.
-  llvm::Constant *EmitConstantInit(const VarDecl &D,
-                                   CodeGenFunction *CGF = nullptr);
-
-  /// Try to emit the given expression as a constant; returns 0 if the
-  /// expression cannot be emitted as a constant.
-  llvm::Constant *EmitConstantExpr(const Expr *E, QualType DestType,
-                                   CodeGenFunction *CGF = nullptr);
-
-  /// Emit the given constant value as a constant, in the type's scalar
-  /// representation.
-  llvm::Constant *EmitConstantValue(const APValue &Value, QualType DestType,
-                                    CodeGenFunction *CGF = nullptr);
-
-  /// Emit the given constant value as a constant, in the type's memory
-  /// representation.
-  llvm::Constant *EmitConstantValueForMemory(const APValue &Value,
-                                             QualType DestType,
-                                             CodeGenFunction *CGF = nullptr);
-
   /// \brief Emit type info if type of an expression is a variably modified
   /// type. Also emit proper debug info for cast types.
   void EmitExplicitCastExprType(const ExplicitCastExpr *E,
@@ -1356,6 +1335,7 @@ private:
                                   bool AttrOnCallSite,
                                   llvm::AttrBuilder &FuncAttrs);
 };
+
 }  // end namespace CodeGen
 }  // end namespace clang
 

Added: cfe/trunk/lib/CodeGen/ConstantEmitter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ConstantEmitter.h?rev=310964&view=auto
==============================================================================
--- cfe/trunk/lib/CodeGen/ConstantEmitter.h (added)
+++ cfe/trunk/lib/CodeGen/ConstantEmitter.h Tue Aug 15 14:42:52 2017
@@ -0,0 +1,180 @@
+//===--- ConstantEmitter.h - IR constant emission ---------------*- C++ 
-*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A helper class for emitting expressions and values as llvm::Constants
+// and as initializers for global variables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_CODEGEN_CONSTANTEMITTER_H
+#define LLVM_CLANG_LIB_CODEGEN_CONSTANTEMITTER_H
+
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+
+namespace clang {
+namespace CodeGen {
+
+class ConstantEmitter {
+public:
+  CodeGenModule &CGM;
+  CodeGenFunction *CGF;
+
+private:
+  bool Abstract = false;
+
+  /// Whether non-abstract components of the emitter have been initialized.
+  bool InitializedNonAbstract = false;
+
+  /// Whether the emitter has been finalized.
+  bool Finalized = false;
+
+  /// Whether the constant-emission failed.
+  bool Failed = false;
+
+  /// The AST address space where this (non-abstract) initializer is going.
+  /// Used for generating appropriate placeholders.
+  unsigned DestAddressSpace;
+
+  llvm::SmallVector<std::pair<llvm::Constant *, llvm::GlobalVariable*>, 4>
+    PlaceholderAddresses;
+
+public:
+  ConstantEmitter(CodeGenModule &CGM, CodeGenFunction *CGF = nullptr)
+    : CGM(CGM), CGF(CGF) {}
+
+  /// Initialize this emission in the context of the given function.
+  /// Use this if the expression might contain contextaul references like
+  /// block addresses or PredefinedExprs.
+  ConstantEmitter(CodeGenFunction &CGF)
+    : CGM(CGF.CGM), CGF(&CGF) {}
+
+  ConstantEmitter(const ConstantEmitter &other) = delete;
+  ConstantEmitter &operator=(const ConstantEmitter &other) = delete;
+
+  ~ConstantEmitter();
+
+  /// Is the current emission context abstract?
+  bool isAbstract() const {
+    return Abstract;
+  }
+
+  /// Try to emit the initiaizer of the given declaration as an abstract
+  /// constant.  If this succeeds, the emission must be finalized.
+  llvm::Constant *tryEmitForInitializer(const VarDecl &D);
+  llvm::Constant *tryEmitForInitializer(const Expr *E,
+                                        unsigned destAddrSpace,
+                                        QualType destType);
+  llvm::Constant *emitForInitializer(const APValue &value,
+                                     unsigned destAddrSpace,
+                                     QualType destType);
+
+  void finalize(llvm::GlobalVariable *global);
+
+  // All of the "abstract" emission methods below permit the emission to
+  // be immediately discarded without finalizing anything.  Therefore, they
+  // must also promise not to do anything that will, in the future, require
+  // finalization:
+  //
+  //   - using the CGF (if present) for anything other than establishing
+  //     semantic context; for example, an expression with ignored
+  //     side-effects must not be emitted as an abstract expression
+  //
+  //   - doing anything that would not be safe to duplicate within an
+  //     initializer or to propagate to another context; for example,
+  //     side effects, or emitting an initialization that requires a
+  //     reference to its current location.
+
+  /// Try to emit the initializer of the given declaration as an abstract
+  /// constant.
+  llvm::Constant *tryEmitAbstractForInitializer(const VarDecl &D);
+
+  /// Emit the result of the given expression as an abstract constant,
+  /// asserting that it succeeded.  This is only safe to do when the
+  /// expression is known to be a constant expression with either a fairly
+  /// simple type or a known simple form.
+  llvm::Constant *emitAbstract(const Expr *E, QualType T);
+  llvm::Constant *emitAbstract(SourceLocation loc, const APValue &value,
+                               QualType T);
+
+  /// Try to emit the result of the given expression as an abstract constant.
+  llvm::Constant *tryEmitAbstract(const Expr *E, QualType T);
+  llvm::Constant *tryEmitAbstractForMemory(const Expr *E, QualType T);
+
+  llvm::Constant *tryEmitAbstract(const APValue &value, QualType T);
+  llvm::Constant *tryEmitAbstractForMemory(const APValue &value, QualType T);
+
+  llvm::Constant *emitNullForMemory(QualType T) {
+    return emitNullForMemory(CGM, T);
+  }
+  llvm::Constant *emitForMemory(llvm::Constant *C, QualType T) {
+    return emitForMemory(CGM, C, T);
+  }
+
+  static llvm::Constant *emitNullForMemory(CodeGenModule &CGM, QualType T);
+  static llvm::Constant *emitForMemory(CodeGenModule &CGM, llvm::Constant *C,
+                                       QualType T);
+
+  // These are private helper routines of the constant emitter that
+  // can't actually be private because things are split out into helper
+  // functions and classes.
+
+  llvm::Constant *tryEmitPrivateForVarInit(const VarDecl &D);
+
+  llvm::Constant *tryEmitPrivate(const Expr *E, QualType T);
+  llvm::Constant *tryEmitPrivateForMemory(const Expr *E, QualType T);
+
+  llvm::Constant *tryEmitPrivate(const APValue &value, QualType T);
+  llvm::Constant *tryEmitPrivateForMemory(const APValue &value, QualType T);
+
+  /// Get the address of the current location.  This is a constant
+  /// that will resolve, after finalization, to the address of the
+  /// 'signal' value that is registered with the emitter later.
+  llvm::GlobalValue *getCurrentAddrPrivate();
+
+  /// Register a 'signal' value with the emitter to inform it where to
+  /// resolve a placeholder.  The signal value must be unique in the
+  /// initializer; it might, for example, be the address of a global that
+  /// refers to the current-address value in its own initializer.
+  ///
+  /// Uses of the placeholder must be properly anchored before finalizing
+  /// the emitter, e.g. by being installed as the initializer of a global
+  /// variable.  That is, it must be possible to replaceAllUsesWith
+  /// the placeholder with the proper address of the signal.
+  void registerCurrentAddrPrivate(llvm::Constant *signal,
+                                  llvm::GlobalValue *placeholder);
+
+private:
+  void initializeNonAbstract(unsigned destAS) {
+    assert(!InitializedNonAbstract);
+    InitializedNonAbstract = true;
+    DestAddressSpace = destAS;
+  }
+  llvm::Constant *markIfFailed(llvm::Constant *init) {
+    if (!init)
+      Failed = true;
+    return init;
+  }
+
+  struct AbstractState {
+    bool OldValue;
+    size_t OldPlaceholdersSize;
+  };
+  AbstractState pushAbstract() {
+    AbstractState saved = { Abstract, PlaceholderAddresses.size() };
+    Abstract = true;
+    return saved;
+  }
+  llvm::Constant *validateAndPopAbstract(llvm::Constant *C, AbstractState 
save);
+};
+
+}
+}
+
+#endif


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to