r287437 - Introduce a helper class for building complex constant initializers. NFC.

Galina Kistanova via cfe-commits cfe-commits at lists.llvm.org
Sat Nov 19 13:06:01 PST 2016


Hello John,

This change has introduced alignment problems for some variables.

The build bots are broken.
http://lab.llvm.org:8011/builders/clang-3stage-ubuntu/builds/355
http://lab.llvm.org:8011/builders/clang-with-lto-ubuntu/builds/308

Could you take care of the issue, please?

Thanks

Galina



On Sat, Nov 19, 2016 at 12:17 AM, John McCall via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: rjmccall
> Date: Sat Nov 19 02:17:24 2016
> New Revision: 287437
>
> URL: http://llvm.org/viewvc/llvm-project?rev=287437&view=rev
> Log:
> Introduce a helper class for building complex constant initializers.  NFC.
>
> I've adopted this in most of the places it makes sense, but v-tables
> and CGObjCMac will need a second pass.
>
> Added:
>     cfe/trunk/lib/CodeGen/ConstantBuilder.h
> Modified:
>     cfe/trunk/include/clang/AST/DeclObjC.h
>     cfe/trunk/lib/CodeGen/CGBlocks.cpp
>     cfe/trunk/lib/CodeGen/CGCUDANV.cpp
>     cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
>     cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
>     cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>
> Modified: cfe/trunk/include/clang/AST/DeclObjC.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/AST/DeclObjC.h?rev=287437&r1=287436&r2=287437&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/AST/DeclObjC.h (original)
> +++ cfe/trunk/include/clang/AST/DeclObjC.h Sat Nov 19 02:17:24 2016
> @@ -870,6 +870,9 @@ public:
>    PropertyControl getPropertyImplementation() const {
>      return PropertyControl(PropertyImplementation);
>    }
> +  bool isOptional() const {
> +    return getPropertyImplementation() == PropertyControl::Optional;
> +  }
>
>    void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
>      PropertyIvarDecl = Ivar;
>
> Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CGBlocks.cpp?rev=287437&r1=287436&r2=287437&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Sat Nov 19 02:17:24 2016
> @@ -16,6 +16,7 @@
>  #include "CGObjCRuntime.h"
>  #include "CodeGenFunction.h"
>  #include "CodeGenModule.h"
> +#include "ConstantBuilder.h"
>  #include "clang/AST/DeclObjC.h"
>  #include "llvm/ADT/SmallSet.h"
>  #include "llvm/IR/CallSite.h"
> @@ -77,63 +78,63 @@ static llvm::Constant *buildBlockDescrip
>                                              const CGBlockInfo &blockInfo)
> {
>    ASTContext &C = CGM.getContext();
>
> -  llvm::Type *ulong = CGM.getTypes().ConvertType(C.UnsignedLongTy);
> -  llvm::Type *i8p = nullptr;
> +  llvm::IntegerType *ulong =
> +    cast<llvm::IntegerType>(CGM.getTypes().ConvertType(C.
> UnsignedLongTy));
> +  llvm::PointerType *i8p = nullptr;
>    if (CGM.getLangOpts().OpenCL)
>      i8p =
>        llvm::Type::getInt8PtrTy(
>             CGM.getLLVMContext(), C.getTargetAddressSpace(
> LangAS::opencl_constant));
>    else
> -    i8p = CGM.getTypes().ConvertType(C.VoidPtrTy);
> +    i8p = CGM.VoidPtrTy;
>
> -  SmallVector<llvm::Constant*, 6> elements;
> +  ConstantBuilder builder(CGM);
> +  auto elements = builder.beginStruct();
>
>    // reserved
> -  elements.push_back(llvm::ConstantInt::get(ulong, 0));
> +  elements.addInt(ulong, 0);
>
>    // Size
>    // FIXME: What is the right way to say this doesn't fit?  We should give
>    // a user diagnostic in that case.  Better fix would be to change the
>    // API to size_t.
> -  elements.push_back(llvm::ConstantInt::get(ulong,
> -                                            blockInfo.BlockSize.
> getQuantity()));
> +  elements.addInt(ulong, blockInfo.BlockSize.getQuantity());
>
>    // Optional copy/dispose helpers.
>    if (blockInfo.NeedsCopyDispose) {
>      // copy_func_helper_decl
> -    elements.push_back(buildCopyHelper(CGM, blockInfo));
> +    elements.add(buildCopyHelper(CGM, blockInfo));
>
>      // destroy_func_decl
> -    elements.push_back(buildDisposeHelper(CGM, blockInfo));
> +    elements.add(buildDisposeHelper(CGM, blockInfo));
>    }
>
>    // Signature.  Mandatory ObjC-style method descriptor @encode sequence.
>    std::string typeAtEncoding =
>      CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr());
> -  elements.push_back(llvm::ConstantExpr::getBitCast(
> +  elements.add(llvm::ConstantExpr::getBitCast(
>      CGM.GetAddrOfConstantCString(typeAtEncoding).getPointer(), i8p));
>
>    // GC layout.
>    if (C.getLangOpts().ObjC1) {
>      if (CGM.getLangOpts().getGC() != LangOptions::NonGC)
> -      elements.push_back(CGM.getObjCRuntime().BuildGCBlockLayout(CGM,
> blockInfo));
> +      elements.add(CGM.getObjCRuntime().BuildGCBlockLayout(CGM,
> blockInfo));
>      else
> -      elements.push_back(CGM.getObjCRuntime().BuildRCBlockLayout(CGM,
> blockInfo));
> +      elements.add(CGM.getObjCRuntime().BuildRCBlockLayout(CGM,
> blockInfo));
>    }
>    else
> -    elements.push_back(llvm::Constant::getNullValue(i8p));
> -
> -  llvm::Constant *init = llvm::ConstantStruct::getAnon(elements);
> +    elements.addNullPointer(i8p);
>
>    unsigned AddrSpace = 0;
>    if (C.getLangOpts().OpenCL)
>      AddrSpace = C.getTargetAddressSpace(LangAS::opencl_constant);
> +
>    llvm::GlobalVariable *global =
> -    new llvm::GlobalVariable(CGM.getModule(), init->getType(), true,
> -                             llvm::GlobalValue::InternalLinkage,
> -                             init, "__block_descriptor_tmp", nullptr,
> -                             llvm::GlobalValue::NotThreadLocal,
> -                             AddrSpace);
> +    elements.finishAndCreateGlobal("__block_descriptor_tmp",
> +                                   CGM.getPointerAlign(),
> +                                   /*constant*/ true,
> +                                   llvm::GlobalValue::InternalLinkage,
> +                                   AddrSpace);
>
>    return llvm::ConstantExpr::getBitCast(global,
> CGM.getBlockDescriptorType());
>  }
> @@ -1080,36 +1081,31 @@ static llvm::Constant *buildGlobalBlock(
>    assert(blockInfo.CanBeGlobal);
>
>    // Generate the constants for the block literal initializer.
> -  llvm::Constant *fields[BlockHeaderSize];
> +  ConstantBuilder builder(CGM);
> +  auto fields = builder.beginStruct();
>
>    // isa
> -  fields[0] = CGM.getNSConcreteGlobalBlock();
> +  fields.add(CGM.getNSConcreteGlobalBlock());
>
>    // __flags
>    BlockFlags flags = BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE;
>    if (blockInfo.UsesStret) flags |= BLOCK_USE_STRET;
>
> -  fields[1] = llvm::ConstantInt::get(CGM.IntTy, flags.getBitMask());
> +  fields.addInt(CGM.IntTy, flags.getBitMask());
>
>    // Reserved
> -  fields[2] = llvm::Constant::getNullValue(CGM.IntTy);
> +  fields.addInt(CGM.IntTy, 0);
>
>    // Function
> -  fields[3] = blockFn;
> +  fields.add(blockFn);
>
>    // Descriptor
> -  fields[4] = buildBlockDescriptor(CGM, blockInfo);
> -
> -  llvm::Constant *init = llvm::ConstantStruct::getAnon(fields);
> +  fields.add(buildBlockDescriptor(CGM, blockInfo));
>
> -  llvm::GlobalVariable *literal =
> -    new llvm::GlobalVariable(CGM.getModule(),
> -                             init->getType(),
> -                             /*constant*/ true,
> -                             llvm::GlobalVariable::InternalLinkage,
> -                             init,
> -                             "__block_literal_global");
> -  literal->setAlignment(blockInfo.BlockAlign.getQuantity());
> +  llvm::Constant *literal =
> +    fields.finishAndCreateGlobal("__block_literal_global",
> +                                 blockInfo.BlockAlign,
> +                                 /*constant*/ true);
>
>    // Return a constant of the appropriately-casted type.
>    llvm::Type *requiredType =
>
> Modified: cfe/trunk/lib/CodeGen/CGCUDANV.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CGCUDANV.cpp?rev=287437&r1=287436&r2=287437&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/CGCUDANV.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGCUDANV.cpp Sat Nov 19 02:17:24 2016
> @@ -15,6 +15,7 @@
>  #include "CGCUDARuntime.h"
>  #include "CodeGenFunction.h"
>  #include "CodeGenModule.h"
> +#include "ConstantBuilder.h"
>  #include "clang/AST/Decl.h"
>  #include "llvm/IR/BasicBlock.h"
>  #include "llvm/IR/CallSite.h"
> @@ -29,7 +30,8 @@ namespace {
>  class CGNVCUDARuntime : public CGCUDARuntime {
>
>  private:
> -  llvm::Type *IntTy, *SizeTy, *VoidTy;
> +  llvm::IntegerType *IntTy, *SizeTy;
> +  llvm::Type *VoidTy;
>    llvm::PointerType *CharPtrTy, *VoidPtrTy, *VoidPtrPtrTy;
>
>    /// Convenience reference to LLVM Context
> @@ -95,9 +97,9 @@ CGNVCUDARuntime::CGNVCUDARuntime(CodeGen
>    CodeGen::CodeGenTypes &Types = CGM.getTypes();
>    ASTContext &Ctx = CGM.getContext();
>
> -  IntTy = Types.ConvertType(Ctx.IntTy);
> -  SizeTy = Types.ConvertType(Ctx.getSizeType());
> -  VoidTy = llvm::Type::getVoidTy(Context);
> +  IntTy = CGM.IntTy;
> +  SizeTy = CGM.SizeTy;
> +  VoidTy = CGM.VoidTy;
>
>    CharPtrTy = llvm::PointerType::getUnqual(Types.ConvertType(Ctx.CharTy))
> ;
>    VoidPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.VoidPtrTy));
> @@ -296,16 +298,21 @@ llvm::Function *CGNVCUDARuntime::makeMod
>          CGM.getTriple().isMacOSX() ? "__NV_CUDA,__fatbin" :
> ".nvFatBinSegment";
>
>      // Create initialized wrapper structure that points to the loaded GPU
> binary
> -    llvm::Constant *Values[] = {
> -        llvm::ConstantInt::get(IntTy, 0x466243b1), // Fatbin wrapper
> magic.
> -        llvm::ConstantInt::get(IntTy, 1),          // Fatbin version.
> -        makeConstantString(GpuBinaryOrErr.get()->getBuffer(), // Data.
> -                           "", FatbinConstantName, 8),
> -        llvm::ConstantPointerNull::get(VoidPtrTy)}; // Unused in fatbin
> v1.
> -    llvm::GlobalVariable *FatbinWrapper = new llvm::GlobalVariable(
> -        TheModule, FatbinWrapperTy, true, llvm::GlobalValue::
> InternalLinkage,
> -        llvm::ConstantStruct::get(FatbinWrapperTy, Values),
> -        "__cuda_fatbin_wrapper");
> +    ConstantBuilder Builder(CGM);
> +    auto Values = Builder.beginStruct(FatbinWrapperTy);
> +    // Fatbin wrapper magic.
> +    Values.addInt(IntTy, 0x466243b1);
> +    // Fatbin version.
> +    Values.addInt(IntTy, 1);
> +    // Data.
> +    Values.add(makeConstantString(GpuBinaryOrErr.get()->getBuffer(),
> +                                  "", FatbinConstantName, 8));
> +    // Unused in fatbin v1.
> +    Values.add(llvm::ConstantPointerNull::get(VoidPtrTy));
> +    llvm::GlobalVariable *FatbinWrapper =
> +      Values.finishAndCreateGlobal("__cuda_fatbin_wrapper",
> +                                   CGM.getPointerAlign(),
> +                                   /*constant*/ true);
>      FatbinWrapper->setSection(FatbinSectionName);
>
>      // GpuBinaryHandle = __cudaRegisterFatBinary(&FatbinWrapper);
>
> Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CGObjCGNU.cpp?rev=287437&r1=287436&r2=287437&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Sat Nov 19 02:17:24 2016
> @@ -18,6 +18,7 @@
>  #include "CGCleanup.h"
>  #include "CodeGenFunction.h"
>  #include "CodeGenModule.h"
> +#include "ConstantBuilder.h"
>  #include "clang/AST/ASTContext.h"
>  #include "clang/AST/Decl.h"
>  #include "clang/AST/DeclObjC.h"
> @@ -190,47 +191,17 @@ protected:
>    /// Generates a global structure, initialized by the elements in the
> vector.
>    /// The element types must match the types of the structure elements in
> the
>    /// first argument.
> -  llvm::GlobalVariable *MakeGlobal(llvm::StructType *Ty,
> -                                   ArrayRef<llvm::Constant *> V,
> +  llvm::GlobalVariable *MakeGlobal(llvm::Constant *C,
>                                     CharUnits Align,
>                                     StringRef Name="",
>                                     llvm::GlobalValue::LinkageTypes
> linkage
>                                           =llvm::GlobalValue::InternalLinkage)
> {
> -    llvm::Constant *C = llvm::ConstantStruct::get(Ty, V);
> -    auto GV = new llvm::GlobalVariable(TheModule, Ty, false,
> +    auto GV = new llvm::GlobalVariable(TheModule, C->getType(), false,
>                                         linkage, C, Name);
>      GV->setAlignment(Align.getQuantity());
>      return GV;
>    }
>
> -  /// Generates a global array.  The vector must contain the same number
> of
> -  /// elements that the array type declares, of the type specified as the
> array
> -  /// element type.
> -  llvm::GlobalVariable *MakeGlobal(llvm::ArrayType *Ty,
> -                                   ArrayRef<llvm::Constant *> V,
> -                                   CharUnits Align,
> -                                   StringRef Name="",
> -                                   llvm::GlobalValue::LinkageTypes
> linkage
> -                                         =llvm::GlobalValue::InternalLinkage)
> {
> -    llvm::Constant *C = llvm::ConstantArray::get(Ty, V);
> -    auto GV = new llvm::GlobalVariable(TheModule, Ty, false,
> -                                       linkage, C, Name);
> -    GV->setAlignment(Align.getQuantity());
> -    return GV;
> -  }
> -
> -  /// Generates a global array, inferring the array type from the
> specified
> -  /// element type and the size of the initialiser.
> -  llvm::GlobalVariable *MakeGlobalArray(llvm::Type *Ty,
> -                                        ArrayRef<llvm::Constant *> V,
> -                                        CharUnits Align,
> -                                        StringRef Name="",
> -                                        llvm::GlobalValue::LinkageTypes
> linkage
> -                                         =llvm::GlobalValue::InternalLinkage)
> {
> -    llvm::ArrayType *ArrayTy = llvm::ArrayType::get(Ty, V.size());
> -    return MakeGlobal(ArrayTy, V, Align, Name, linkage);
> -  }
> -
>    /// Returns a property name and encoding string.
>    llvm::Constant *MakePropertyEncodingString(const ObjCPropertyDecl *PD,
>                                               const Decl *Container) {
> @@ -251,7 +222,7 @@ protected:
>    }
>
>    /// Push the property attributes into two structure fields.
> -  void PushPropertyAttributes(std::vector<llvm::Constant*> &Fields,
> +  void PushPropertyAttributes(ConstantBuilder::StructBuilder &Fields,
>        ObjCPropertyDecl *property, bool isSynthesized=true, bool
>        isDynamic=true) {
>      int attrs = property->getPropertyAttributes();
> @@ -263,7 +234,7 @@ protected:
>        attrs &= ~ObjCPropertyDecl::OBJC_PR_strong;
>      }
>      // The first flags field has the same attribute values as clang uses
> internally
> -    Fields.push_back(llvm::ConstantInt::get(Int8Ty, attrs & 0xff));
> +    Fields.addInt(Int8Ty, attrs & 0xff);
>      attrs >>= 8;
>      attrs <<= 2;
>      // For protocol properties, synthesized and dynamic have no meaning,
> so we
> @@ -273,10 +244,10 @@ protected:
>      attrs |= isDynamic ? (1<<1) : 0;
>      // The second field is the next four fields left shifted by two, with
> the
>      // low bit set to indicate whether the field is synthesized or
> dynamic.
> -    Fields.push_back(llvm::ConstantInt::get(Int8Ty, attrs & 0xff));
> +    Fields.addInt(Int8Ty, attrs & 0xff);
>      // Two padding fields
> -    Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
> -    Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
> +    Fields.addInt(Int8Ty, 0);
> +    Fields.addInt(Int8Ty, 0);
>    }
>
>    /// Ensures that the value has the required type, by inserting a
> bitcast if
> @@ -1233,14 +1204,15 @@ llvm::Constant *CGObjCGNUstep::GetEHType
>    llvm::Constant *typeName =
>      ExportUniqueString(className, "__objc_eh_typename_");
>
> -  std::vector<llvm::Constant*> fields;
> -  fields.push_back(BVtable);
> -  fields.push_back(typeName);
> -  llvm::Constant *TI =
> -      MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
> nullptr),
> -                 fields, CGM.getPointerAlign(),
> -                 "__objc_eh_typeinfo_" + className,
> -          llvm::GlobalValue::LinkOnceODRLinkage);
> +  ConstantBuilder builder(CGM);
> +  auto fields = builder.beginStruct();
> +  fields.add(BVtable);
> +  fields.add(typeName);
> +  llvm::Constant *TI =
> +    fields.finishAndCreateGlobal("__objc_eh_typeinfo_" + className,
> +                                 CGM.getPointerAlign(),
> +                                 /*constant*/ false,
> +                                 llvm::GlobalValue::LinkOnceODRLinkage);
>    return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
>  }
>
> @@ -1270,13 +1242,13 @@ ConstantAddress CGObjCGNU::GenerateConst
>    else if (isa->getType() != PtrToIdTy)
>      isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
>
> -  std::vector<llvm::Constant*> Ivars;
> -  Ivars.push_back(isa);
> -  Ivars.push_back(MakeConstantString(Str));
> -  Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size()));
> -  llvm::Constant *ObjCStr = MakeGlobal(
> -    llvm::StructType::get(PtrToIdTy, PtrToInt8Ty, IntTy, nullptr),
> -    Ivars, Align, ".objc_str");
> +  ConstantBuilder Builder(CGM);
> +  auto Fields = Builder.beginStruct();
> +  Fields.add(isa);
> +  Fields.add(MakeConstantString(Str));
> +  Fields.addInt(IntTy, Str.size());
> +  llvm::Constant *ObjCStr =
> +    Fields.finishAndCreateGlobal(".objc_str", Align);
>    ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
>    ObjCStrings[Str] = ObjCStr;
>    ConstantStrings.push_back(ObjCStr);
> @@ -1551,13 +1523,20 @@ GenerateMethodList(StringRef ClassName,
>                     bool isClassMethodList) {
>    if (MethodSels.empty())
>      return NULLPtr;
> +
> +  ConstantBuilder Builder(CGM);
> +
> +  auto MethodList = Builder.beginStruct();
> +  MethodList.addNullPointer(CGM.Int8PtrTy);
> +  MethodList.addInt(Int32Ty, MethodTypes.size());
> +
>    // Get the method structure type.
>    llvm::StructType *ObjCMethodTy = llvm::StructType::get(
>      PtrToInt8Ty, // Really a selector, but the runtime creates it us.
>      PtrToInt8Ty, // Method types
>      IMPTy, //Method pointer
>      nullptr);
> -  std::vector<llvm::Constant*> Methods;
> +  auto Methods = MethodList.beginArray();
>    for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
>      llvm::Constant *Method =
>        TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
> @@ -1567,34 +1546,14 @@ GenerateMethodList(StringRef ClassName,
>      llvm::Constant *C = MakeConstantString(MethodSels[i].getAsString());
>      Method = llvm::ConstantExpr::getBitCast(Method,
>          IMPTy);
> -    Methods.push_back(
> +    Methods.add(
>          llvm::ConstantStruct::get(ObjCMethodTy, {C, MethodTypes[i],
> Method}));
>    }
> -
> -  // Array of method structures
> -  llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy,
> -
> Methods.size());
> -  llvm::Constant *MethodArray = llvm::ConstantArray::get(
> ObjCMethodArrayTy,
> -                                                         Methods);
> -
> -  // Structure containing list pointer, array and array count
> -  llvm::StructType *ObjCMethodListTy = llvm::StructType::create(
> VMContext);
> -  llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(ObjCMethodListTy);
> -  ObjCMethodListTy->setBody(
> -      NextPtrTy,
> -      IntTy,
> -      ObjCMethodArrayTy,
> -      nullptr);
> -
> -  Methods.clear();
> -  Methods.push_back(llvm::ConstantPointerNull::get(
> -        llvm::PointerType::getUnqual(ObjCMethodListTy)));
> -  Methods.push_back(llvm::ConstantInt::get(Int32Ty, MethodTypes.size()));
> -  Methods.push_back(MethodArray);
> +  MethodList.add(Methods.finish());
>
>    // Create an instance of the structure
> -  return MakeGlobal(ObjCMethodListTy, Methods, CGM.getPointerAlign(),
> -                    ".objc_method_list");
> +  return MethodList.finishAndCreateGlobal(".objc_method_list",
> +                                          CGM.getPointerAlign());
>  }
>
>  /// Generates an IvarList.  Used in construction of a objc_class.
> @@ -1602,35 +1561,36 @@ llvm::Constant *CGObjCGNU::
>  GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames,
>                   ArrayRef<llvm::Constant *> IvarTypes,
>                   ArrayRef<llvm::Constant *> IvarOffsets) {
> -  if (IvarNames.size() == 0)
> +  if (IvarNames.empty())
>      return NULLPtr;
> -  // Get the method structure type.
> +
> +  ConstantBuilder Builder(CGM);
> +
> +  // Structure containing array count followed by array.
> +  auto IvarList = Builder.beginStruct();
> +  IvarList.addInt(IntTy, (int)IvarNames.size());
> +
> +  // Get the ivar structure type.
>    llvm::StructType *ObjCIvarTy = llvm::StructType::get(
>      PtrToInt8Ty,
>      PtrToInt8Ty,
>      IntTy,
>      nullptr);
> -  std::vector<llvm::Constant*> Ivars;
> +
> +  // Array of ivar structures.
> +  auto Ivars = IvarList.beginArray(ObjCIvarTy);
>    for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
> -    Ivars.push_back(llvm::ConstantStruct::get(
> -        ObjCIvarTy, {IvarNames[i], IvarTypes[i], IvarOffsets[i]}));
> +    auto Ivar = Ivars.beginStruct(ObjCIvarTy);
> +    Ivar.add(IvarNames[i]);
> +    Ivar.add(IvarTypes[i]);
> +    Ivar.add(IvarOffsets[i]);
> +    Ivars.add(Ivar.finish());
>    }
> -
> -  // Array of method structures
> -  llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy,
> -      IvarNames.size());
> -
> -  llvm::Constant *Elements[] = {
> -      llvm::ConstantInt::get(IntTy, (int)IvarNames.size()),
> -      llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars)};
> -  // Structure containing array and array count
> -  llvm::StructType *ObjCIvarListTy = llvm::StructType::get(IntTy,
> -    ObjCIvarArrayTy,
> -    nullptr);
> +  IvarList.add(Ivars.finish());
>
>    // Create an instance of the structure
> -  return MakeGlobal(ObjCIvarListTy, Elements, CGM.getPointerAlign(),
> -                    ".objc_ivar_list");
> +  return IvarList.finishAndCreateGlobal(".objc_ivar_list",
> +                                        CGM.getPointerAlign());
>  }
>
>  /// Generate a class structure
> @@ -1678,34 +1638,55 @@ llvm::Constant *CGObjCGNU::GenerateClass
>        IntPtrTy,               // strong_pointers
>        IntPtrTy,               // weak_pointers
>        nullptr);
> -  llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
> +
> +  ConstantBuilder Builder(CGM);
> +  auto Elements = Builder.beginStruct(ClassTy);
> +
>    // Fill in the structure
> -  std::vector<llvm::Constant*> Elements;
> -  Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass,
> PtrToInt8Ty));
> -  Elements.push_back(SuperClass);
> -  Elements.push_back(MakeConstantString(Name, ".class_name"));
> -  Elements.push_back(Zero);
> -  Elements.push_back(llvm::ConstantInt::get(LongTy, info));
> +
> +  // isa
> +  Elements.add(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty));
> +  // super_class
> +  Elements.add(SuperClass);
> +  // name
> +  Elements.add(MakeConstantString(Name, ".class_name"));
> +  // version
> +  Elements.addInt(LongTy, 0);
> +  // info
> +  Elements.addInt(LongTy, info);
> +  // instance_size
>    if (isMeta) {
>      llvm::DataLayout td(&TheModule);
> -    Elements.push_back(
> -        llvm::ConstantInt::get(LongTy,
> -                               td.getTypeSizeInBits(ClassTy) /
> -                                 CGM.getContext().getCharWidth()));
> +    Elements.addInt(LongTy,
> +                    td.getTypeSizeInBits(ClassTy) /
> +                      CGM.getContext().getCharWidth());
>    } else
> -    Elements.push_back(InstanceSize);
> -  Elements.push_back(IVars);
> -  Elements.push_back(Methods);
> -  Elements.push_back(NULLPtr);
> -  Elements.push_back(NULLPtr);
> -  Elements.push_back(NULLPtr);
> -  Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy));
> -  Elements.push_back(NULLPtr);
> -  Elements.push_back(llvm::ConstantInt::get(LongTy, 1));
> -  Elements.push_back(IvarOffsets);
> -  Elements.push_back(Properties);
> -  Elements.push_back(StrongIvarBitmap);
> -  Elements.push_back(WeakIvarBitmap);
> +    Elements.add(InstanceSize);
> +  // ivars
> +  Elements.add(IVars);
> +  // methods
> +  Elements.add(Methods);
> +  // These are all filled in by the runtime, so we pretend
> +  // dtable
> +  Elements.add(NULLPtr);
> +  // subclass_list
> +  Elements.add(NULLPtr);
> +  // sibling_class
> +  Elements.add(NULLPtr);
> +  // protocols
> +  Elements.add(llvm::ConstantExpr::getBitCast(Protocols, PtrTy));
> +  // gc_object_type
> +  Elements.add(NULLPtr);
> +  // abi_version
> +  Elements.addInt(LongTy, 1);
> +  // ivar_offsets
> +  Elements.add(IvarOffsets);
> +  // properties
> +  Elements.add(Properties);
> +  // strong_pointers
> +  Elements.add(StrongIvarBitmap);
> +  // weak_pointers
> +  Elements.add(WeakIvarBitmap);
>    // Create an instance of the structure
>    // This is now an externally visible symbol, so that we can speed up
> class
>    // messages in the next ABI.  We may already have some weak references
> to
> @@ -1714,13 +1695,13 @@ llvm::Constant *CGObjCGNU::GenerateClass
>            std::string(Name));
>    llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
>    llvm::Constant *Class =
> -    MakeGlobal(ClassTy, Elements, CGM.getPointerAlign(), ClassSym,
> -               llvm::GlobalValue::ExternalLinkage);
> +    Elements.finishAndCreateGlobal(ClassSym, CGM.getPointerAlign(),
> false,
> +                                   llvm::GlobalValue::ExternalLinkage);
>    if (ClassRef) {
> -      ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class,
> +    ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class,
>                    ClassRef->getType()));
> -      ClassRef->removeFromParent();
> -      Class->setName(ClassSym);
> +    ClassRef->removeFromParent();
> +    Class->setName(ClassSym);
>    }
>    return Class;
>  }
> @@ -1729,38 +1710,33 @@ llvm::Constant *CGObjCGNU::
>  GenerateProtocolMethodList(ArrayRef<llvm::Constant *> MethodNames,
>                             ArrayRef<llvm::Constant *> MethodTypes) {
>    // Get the method structure type.
> -  llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(
> -    PtrToInt8Ty, // Really a selector, but the runtime does the casting
> for us.
> -    PtrToInt8Ty,
> -    nullptr);
> -  std::vector<llvm::Constant*> Methods;
> +  llvm::StructType *ObjCMethodDescTy =
> +    llvm::StructType::get(CGM.getLLVMContext(), { PtrToInt8Ty,
> PtrToInt8Ty });
> +  ConstantBuilder Builder(CGM);
> +  auto MethodList = Builder.beginStruct();
> +  MethodList.addInt(IntTy, MethodNames.size());
> +  auto Methods = MethodList.beginArray(ObjCMethodDescTy);
>    for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
> -    Methods.push_back(llvm::ConstantStruct::get(
> -        ObjCMethodDescTy, {MethodNames[i], MethodTypes[i]}));
> -  }
> -  llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(
> ObjCMethodDescTy,
> -      MethodNames.size());
> -  llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy,
> -                                                   Methods);
> -  llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(
> -      IntTy, ObjCMethodArrayTy, nullptr);
> -  Methods.clear();
> -  Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size()));
> -  Methods.push_back(Array);
> -  return MakeGlobal(ObjCMethodDescListTy, Methods, CGM.getPointerAlign(),
> -                    ".objc_method_list");
> +    auto Method = Methods.beginStruct(ObjCMethodDescTy);
> +    Method.add(MethodNames[i]);
> +    Method.add(MethodTypes[i]);
> +    Methods.add(Method.finish());
> +  }
> +  MethodList.add(Methods.finish());
> +  return MethodList.finishAndCreateGlobal(".objc_method_list",
> +                                          CGM.getPointerAlign());
>  }
>
>  // Create the protocol list structure used in classes, categories and so
> on
> -llvm::Constant *CGObjCGNU::GenerateProtocolList(ArrayRef<
> std::string>Protocols){
> -  llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
> -      Protocols.size());
> -  llvm::StructType *ProtocolListTy = llvm::StructType::get(
> -      PtrTy, //Should be a recurisve pointer, but it's always NULL here.
> -      SizeTy,
> -      ProtocolArrayTy,
> -      nullptr);
> -  std::vector<llvm::Constant*> Elements;
> +llvm::Constant *
> +CGObjCGNU::GenerateProtocolList(ArrayRef<std::string> Protocols) {
> +
> +  ConstantBuilder Builder(CGM);
> +  auto ProtocolList = Builder.beginStruct();
> +  ProtocolList.add(NULLPtr);
> +  ProtocolList.addInt(LongTy, Protocols.size());
> +
> +  auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
>    for (const std::string *iter = Protocols.begin(), *endIter =
> Protocols.end();
>        iter != endIter ; iter++) {
>      llvm::Constant *protocol = nullptr;
> @@ -1773,16 +1749,11 @@ llvm::Constant *CGObjCGNU::GenerateProto
>      }
>      llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(protocol,
>                                                             PtrToInt8Ty);
> -    Elements.push_back(Ptr);
> +    Elements.add(Ptr);
>    }
> -  llvm::Constant * ProtocolArray = llvm::ConstantArray::get(
> ProtocolArrayTy,
> -      Elements);
> -  Elements.clear();
> -  Elements.push_back(NULLPtr);
> -  Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size()));
> -  Elements.push_back(ProtocolArray);
> -  return MakeGlobal(ProtocolListTy, Elements, CGM.getPointerAlign(),
> -                    ".objc_protocol_list");
> +  ProtocolList.add(Elements.finish());
> +  return ProtocolList.finishAndCreateGlobal(".objc_protocol_list",
> +                                            CGM.getPointerAlign());
>  }
>
>  llvm::Value *CGObjCGNU::GenerateProtocolRef(CodeGenFunction &CGF,
> @@ -1793,33 +1764,28 @@ llvm::Value *CGObjCGNU::GenerateProtocol
>    return CGF.Builder.CreateBitCast(protocol,
> llvm::PointerType::getUnqual(T));
>  }
>
> -llvm::Constant *CGObjCGNU::GenerateEmptyProtocol(
> -  const std::string &ProtocolName) {
> -  SmallVector<std::string, 0> EmptyStringVector;
> -  SmallVector<llvm::Constant*, 0> EmptyConstantVector;
> -
> -  llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector);
> -  llvm::Constant *MethodList =
> -    GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector);
> +llvm::Constant *
> +CGObjCGNU::GenerateEmptyProtocol(const std::string &ProtocolName) {
> +  llvm::Constant *ProtocolList = GenerateProtocolList({});
> +  llvm::Constant *MethodList = GenerateProtocolMethodList({}, {});
>    // Protocols are objects containing lists of the methods implemented and
>    // protocols adopted.
> -  llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
> -      PtrToInt8Ty,
> -      ProtocolList->getType(),
> -      MethodList->getType(),
> -      MethodList->getType(),
> -      MethodList->getType(),
> -      MethodList->getType(),
> -      nullptr);
> +  ConstantBuilder Builder(CGM);
> +  auto Elements = Builder.beginStruct();
> +
>    // The isa pointer must be set to a magic number so the runtime knows
> it's
>    // the correct layout.
> -  llvm::Constant *Elements[] = {
> -      llvm::ConstantExpr::getIntToPtr(
> -          llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy),
> -      MakeConstantString(ProtocolName, ".objc_protocol_name"),
> ProtocolList,
> -      MethodList, MethodList, MethodList, MethodList};
> -  return MakeGlobal(ProtocolTy, Elements, CGM.getPointerAlign(),
> -                    ".objc_protocol");
> +  Elements.add(llvm::ConstantExpr::getIntToPtr(
> +          llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
> +
> +  Elements.add(MakeConstantString(ProtocolName, ".objc_protocol_name"));
> +  Elements.add(ProtocolList);
> +  Elements.add(MethodList);
> +  Elements.add(MethodList);
> +  Elements.add(MethodList);
> +  Elements.add(MethodList);
> +  return Elements.finishAndCreateGlobal(".objc_protocol",
> +                                        CGM.getPointerAlign());
>  }
>
>  void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
> @@ -1886,142 +1852,143 @@ void CGObjCGNU::GenerateProtocol(const O
>    // The isSynthesized value is always set to 0 in a protocol.  It exists
> to
>    // simplify the runtime library by allowing it to use the same data
>    // structures for protocol metadata everywhere.
> -  llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
> -          PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
> -          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, nullptr);
> -  std::vector<llvm::Constant*> Properties;
> -  std::vector<llvm::Constant*> OptionalProperties;
>
> -  // Add all of the property methods need adding to the method list and
> to the
> -  // property metadata list.
> -  for (auto *property : PD->instance_properties()) {
> -    std::vector<llvm::Constant*> Fields;
> -
> -    Fields.push_back(MakePropertyEncodingString(property, nullptr));
> -    PushPropertyAttributes(Fields, property);
> +  llvm::Constant *PropertyList;
> +  llvm::Constant *OptionalPropertyList;
> +  {
> +    llvm::StructType *propertyMetadataTy =
> +      llvm::StructType::get(CGM.getLLVMContext(),
> +        { PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
> +          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
> +
> +    unsigned numReqProperties = 0, numOptProperties = 0;
> +    for (auto property : PD->instance_properties()) {
> +      if (property->isOptional())
> +        numOptProperties++;
> +      else
> +        numReqProperties++;
> +    }
> +
> +    ConstantBuilder reqPropertyListBuilder(CGM);
> +    auto reqPropertiesList = reqPropertyListBuilder.beginStruct();
> +    reqPropertiesList.addInt(IntTy, numReqProperties);
> +    reqPropertiesList.add(NULLPtr);
> +    auto reqPropertiesArray = reqPropertiesList.beginArray(
> propertyMetadataTy);
> +
> +    ConstantBuilder optPropertyListBuilder(CGM);
> +    auto optPropertiesList = optPropertyListBuilder.beginStruct();
> +    optPropertiesList.addInt(IntTy, numOptProperties);
> +    optPropertiesList.add(NULLPtr);
> +    auto optPropertiesArray = optPropertiesList.beginArray(
> propertyMetadataTy);
> +
> +    // Add all of the property methods need adding to the method list and
> to the
> +    // property metadata list.
> +    for (auto *property : PD->instance_properties()) {
> +      auto &propertiesArray =
> +        (property->isOptional() ? optPropertiesArray :
> reqPropertiesArray);
> +      auto fields = propertiesArray.beginStruct(propertyMetadataTy);
> +
> +      fields.add(MakePropertyEncodingString(property, nullptr));
> +      PushPropertyAttributes(fields, property);
> +
> +      if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
> +        std::string typeStr;
> +        Context.getObjCEncodingForMethodDecl(getter, typeStr);
> +        llvm::Constant *typeEncoding = MakeConstantString(typeStr);
> +        InstanceMethodTypes.push_back(typeEncoding);
> +        fields.add(MakeConstantString(getter->getSelector().
> getAsString()));
> +        fields.add(typeEncoding);
> +      } else {
> +        fields.add(NULLPtr);
> +        fields.add(NULLPtr);
> +      }
> +      if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
> +        std::string typeStr;
> +        Context.getObjCEncodingForMethodDecl(setter, typeStr);
> +        llvm::Constant *typeEncoding = MakeConstantString(typeStr);
> +        InstanceMethodTypes.push_back(typeEncoding);
> +        fields.add(MakeConstantString(setter->getSelector().
> getAsString()));
> +        fields.add(typeEncoding);
> +      } else {
> +        fields.add(NULLPtr);
> +        fields.add(NULLPtr);
> +      }
>
> -    if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
> -      std::string TypeStr;
> -      Context.getObjCEncodingForMethodDecl(getter,TypeStr);
> -      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
> -      InstanceMethodTypes.push_back(TypeEncoding);
> -      Fields.push_back(MakeConstantString(getter->
> getSelector().getAsString()));
> -      Fields.push_back(TypeEncoding);
> -    } else {
> -      Fields.push_back(NULLPtr);
> -      Fields.push_back(NULLPtr);
> -    }
> -    if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
> -      std::string TypeStr;
> -      Context.getObjCEncodingForMethodDecl(setter,TypeStr);
> -      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
> -      InstanceMethodTypes.push_back(TypeEncoding);
> -      Fields.push_back(MakeConstantString(setter->
> getSelector().getAsString()));
> -      Fields.push_back(TypeEncoding);
> -    } else {
> -      Fields.push_back(NULLPtr);
> -      Fields.push_back(NULLPtr);
> -    }
> -    if (property->getPropertyImplementation() ==
> ObjCPropertyDecl::Optional) {
> -      OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy,
> Fields));
> -    } else {
> -      Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy,
> Fields));
> +      propertiesArray.add(fields.finish());
>      }
> +
> +    reqPropertiesList.add(reqPropertiesArray.finish());
> +    PropertyList =
> +      reqPropertiesList.finishAndCreateGlobal(".objc_property_list",
> +                                              CGM.getPointerAlign());
> +
> +    optPropertiesList.add(optPropertiesArray.finish());
> +    OptionalPropertyList =
> +      optPropertiesList.finishAndCreateGlobal(".objc_property_list",
> +                                              CGM.getPointerAlign());
>    }
> -  llvm::Constant *PropertyArray = llvm::ConstantArray::get(
> -      llvm::ArrayType::get(PropertyMetadataTy, Properties.size()),
> Properties);
> -  llvm::Constant* PropertyListInitFields[] =
> -    {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr,
> PropertyArray};
> -
> -  llvm::Constant *PropertyListInit =
> -      llvm::ConstantStruct::getAnon(PropertyListInitFields);
> -  llvm::Constant *PropertyList = new llvm::GlobalVariable(TheModule,
> -      PropertyListInit->getType(), false, llvm::GlobalValue::
> InternalLinkage,
> -      PropertyListInit, ".objc_property_list");
> -
> -  llvm::Constant *OptionalPropertyArray =
> -      llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy,
> -          OptionalProperties.size()) , OptionalProperties);
> -  llvm::Constant* OptionalPropertyListInitFields[] = {
> -      llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr,
> -      OptionalPropertyArray };
> -
> -  llvm::Constant *OptionalPropertyListInit =
> -      llvm::ConstantStruct::getAnon(OptionalPropertyListInitFields);
> -  llvm::Constant *OptionalPropertyList = new llvm::GlobalVariable(
> TheModule,
> -          OptionalPropertyListInit->getType(), false,
> -          llvm::GlobalValue::InternalLinkage, OptionalPropertyListInit,
> -          ".objc_property_list");
>
>    // Protocols are objects containing lists of the methods implemented and
>    // protocols adopted.
> -  llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
> -      PtrToInt8Ty,
> -      ProtocolList->getType(),
> -      InstanceMethodList->getType(),
> -      ClassMethodList->getType(),
> -      OptionalInstanceMethodList->getType(),
> -      OptionalClassMethodList->getType(),
> -      PropertyList->getType(),
> -      OptionalPropertyList->getType(),
> -      nullptr);
>    // The isa pointer must be set to a magic number so the runtime knows
> it's
>    // the correct layout.
> -  llvm::Constant *Elements[] = {
> +  ConstantBuilder Builder(CGM);
> +  auto Elements = Builder.beginStruct();
> +  Elements.add(
>        llvm::ConstantExpr::getIntToPtr(
> -          llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy),
> -      MakeConstantString(ProtocolName, ".objc_protocol_name"),
> ProtocolList,
> -      InstanceMethodList, ClassMethodList, OptionalInstanceMethodList,
> -      OptionalClassMethodList, PropertyList, OptionalPropertyList};
> +          llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
> +  Elements.add(
> +      MakeConstantString(ProtocolName, ".objc_protocol_name"));
> +  Elements.add(ProtocolList);
> +  Elements.add(InstanceMethodList);
> +  Elements.add(ClassMethodList);
> +  Elements.add(OptionalInstanceMethodList);
> +  Elements.add(OptionalClassMethodList);
> +  Elements.add(PropertyList);
> +  Elements.add(OptionalPropertyList);
>    ExistingProtocols[ProtocolName] =
> -    llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements,
> -          CGM.getPointerAlign(), ".objc_protocol"), IdTy);
> +    llvm::ConstantExpr::getBitCast(
> +      Elements.finishAndCreateGlobal(".objc_protocol",
> CGM.getPointerAlign()),
> +      IdTy);
>  }
>  void CGObjCGNU::GenerateProtocolHolderCategory() {
>    // Collect information about instance methods
>    SmallVector<Selector, 1> MethodSels;
>    SmallVector<llvm::Constant*, 1> MethodTypes;
>
> -  std::vector<llvm::Constant*> Elements;
> +  ConstantBuilder Builder(CGM);
> +  auto Elements = Builder.beginStruct();
> +
>    const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_Hack";
>    const std::string CategoryName = "AnotherHack";
> -  Elements.push_back(MakeConstantString(CategoryName));
> -  Elements.push_back(MakeConstantString(ClassName));
> +  Elements.add(MakeConstantString(CategoryName));
> +  Elements.add(MakeConstantString(ClassName));
>    // Instance method list
> -  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
> +  Elements.add(llvm::ConstantExpr::getBitCast(GenerateMethodList(
>            ClassName, CategoryName, MethodSels, MethodTypes, false),
> PtrTy));
>    // Class method list
> -  Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
> +  Elements.add(llvm::ConstantExpr::getBitCast(GenerateMethodList(
>            ClassName, CategoryName, MethodSels, MethodTypes, true),
> PtrTy));
> +
>    // Protocol list
> -  llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrTy,
> -      ExistingProtocols.size());
> -  llvm::StructType *ProtocolListTy = llvm::StructType::get(
> -      PtrTy, //Should be a recurisve pointer, but it's always NULL here.
> -      SizeTy,
> -      ProtocolArrayTy,
> -      nullptr);
> -  std::vector<llvm::Constant*> ProtocolElements;
> -  for (llvm::StringMapIterator<llvm::Constant*> iter =
> -       ExistingProtocols.begin(), endIter = ExistingProtocols.end();
> +  ConstantBuilder ProtocolListBuilder(CGM);
> +  auto ProtocolList = ProtocolListBuilder.beginStruct();
> +  ProtocolList.add(NULLPtr);
> +  ProtocolList.addInt(LongTy, ExistingProtocols.size());
> +  auto ProtocolElements = ProtocolList.beginArray(PtrTy);
> +  for (auto iter = ExistingProtocols.begin(), endIter =
> ExistingProtocols.end();
>         iter != endIter ; iter++) {
>      llvm::Constant *Ptr = llvm::ConstantExpr::
> getBitCast(iter->getValue(),
>              PtrTy);
> -    ProtocolElements.push_back(Ptr);
> +    ProtocolElements.add(Ptr);
>    }
> -  llvm::Constant * ProtocolArray = llvm::ConstantArray::get(
> ProtocolArrayTy,
> -      ProtocolElements);
> -  ProtocolElements.clear();
> -  ProtocolElements.push_back(NULLPtr);
> -  ProtocolElements.push_back(llvm::ConstantInt::get(LongTy,
> -              ExistingProtocols.size()));
> -  ProtocolElements.push_back(ProtocolArray);
> -  Elements.push_back(llvm::ConstantExpr::getBitCast(
> MakeGlobal(ProtocolListTy,
> -                  ProtocolElements, CGM.getPointerAlign(),
> -                  ".objc_protocol_list"), PtrTy));
> +  ProtocolList.add(ProtocolElements.finish());
> +  Elements.add(llvm::ConstantExpr::getBitCast(
> +                   ProtocolList.finishAndCreateGlobal(".objc_
> protocol_list",
> +
> CGM.getPointerAlign()),
> +                   PtrTy));
>    Categories.push_back(llvm::ConstantExpr::getBitCast(
> -        MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
> -            PtrTy, PtrTy, PtrTy, nullptr), Elements,
> CGM.getPointerAlign()),
> +        Elements.finishAndCreateGlobal("", CGM.getPointerAlign()),
>          PtrTy));
>  }
>
> @@ -2056,13 +2023,16 @@ llvm::Constant *CGObjCGNU::MakeBitField(
>      }
>      values.push_back(llvm::ConstantInt::get(Int32Ty, word));
>    }
> -  llvm::ArrayType *arrayTy = llvm::ArrayType::get(Int32Ty, values.size());
> -  llvm::Constant *array = llvm::ConstantArray::get(arrayTy, values);
> -  llvm::Constant *fields[2] = {
> -      llvm::ConstantInt::get(Int32Ty, values.size()),
> -      array };
> -  llvm::Constant *GS = MakeGlobal(llvm::StructType::get(Int32Ty, arrayTy,
> -        nullptr), fields, CharUnits::fromQuantity(4));
> +
> +  ConstantBuilder builder(CGM);
> +  auto fields = builder.beginStruct();
> +  fields.addInt(Int32Ty, values.size());
> +  auto array = fields.beginArray();
> +  for (auto v : values) array.add(v);
> +  fields.add(array.finish());
> +
> +  llvm::Constant *GS =
> +    fields.finishAndCreateGlobal("", CharUnits::fromQuantity(4));
>    llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
>    return ptr;
>  }
> @@ -2098,23 +2068,25 @@ void CGObjCGNU::GenerateCategory(const O
>         E = Protos.end(); I != E; ++I)
>      Protocols.push_back((*I)->getNameAsString());
>
> -  llvm::Constant *Elements[] = {
> -      MakeConstantString(CategoryName), MakeConstantString(ClassName),
> -      // Instance method list
> -      llvm::ConstantExpr::getBitCast(
> +  ConstantBuilder Builder(CGM);
> +  auto Elements = Builder.beginStruct();
> +  Elements.add(MakeConstantString(CategoryName));
> +  Elements.add(MakeConstantString(ClassName));
> +  // Instance method list
> +  Elements.add(llvm::ConstantExpr::getBitCast(
>            GenerateMethodList(ClassName, CategoryName, InstanceMethodSels,
>                               InstanceMethodTypes, false),
> -          PtrTy),
> -      // Class method list
> -      llvm::ConstantExpr::getBitCast(GenerateMethodList(ClassName,
> CategoryName,
> -                                                        ClassMethodSels,
> -                                                        ClassMethodTypes,
> true),
> -                                     PtrTy),
> -      // Protocol list
> -      llvm::ConstantExpr::getBitCast(GenerateProtocolList(Protocols),
> PtrTy)};
> +          PtrTy));
> +  // Class method list
> +  Elements.add(llvm::ConstantExpr::getBitCast(
> +                 GenerateMethodList(ClassName, CategoryName,
> +                                    ClassMethodSels, ClassMethodTypes,
> true),
> +                  PtrTy));
> +  // Protocol list
> +  Elements.add(llvm::ConstantExpr::getBitCast(
> +                 GenerateProtocolList(Protocols), PtrTy));
>    Categories.push_back(llvm::ConstantExpr::getBitCast(
> -        MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
> -            PtrTy, PtrTy, PtrTy, nullptr), Elements,
> CGM.getPointerAlign()),
> +        Elements.finishAndCreateGlobal("", CGM.getPointerAlign()),
>          PtrTy));
>  }
>
> @@ -2124,23 +2096,35 @@ llvm::Constant *CGObjCGNU::GeneratePrope
>    ASTContext &Context = CGM.getContext();
>    // Property metadata: name, attributes, attributes2, padding1, padding2,
>    // setter name, setter types, getter name, getter types.
> -  llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
> -          PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
> -          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, nullptr);
> -  std::vector<llvm::Constant*> Properties;
> +  llvm::StructType *propertyMetadataTy =
> +    llvm::StructType::get(CGM.getLLVMContext(),
> +        { PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
> +          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
> +
> +  unsigned numProperties = 0;
> +  for (auto *propertyImpl : OID->property_impls()) {
> +    (void) propertyImpl;
> +    numProperties++;
> +  }
> +
> +  ConstantBuilder builder(CGM);
> +  auto propertyList = builder.beginStruct();
> +  propertyList.addInt(IntTy, numProperties);
> +  propertyList.add(NULLPtr);
> +  auto properties = propertyList.beginArray(propertyMetadataTy);
>
>    // Add all of the property methods need adding to the method list and
> to the
>    // property metadata list.
>    for (auto *propertyImpl : OID->property_impls()) {
> -    std::vector<llvm::Constant*> Fields;
> +    auto fields = properties.beginStruct(propertyMetadataTy);
>      ObjCPropertyDecl *property = propertyImpl->getPropertyDecl();
>      bool isSynthesized = (propertyImpl->getPropertyImplementation() ==
>          ObjCPropertyImplDecl::Synthesize);
>      bool isDynamic = (propertyImpl->getPropertyImplementation() ==
>          ObjCPropertyImplDecl::Dynamic);
>
> -    Fields.push_back(MakePropertyEncodingString(property, OID));
> -    PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
> +    fields.add(MakePropertyEncodingString(property, OID));
> +    PushPropertyAttributes(fields, property, isSynthesized, isDynamic);
>      if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
>        std::string TypeStr;
>        Context.getObjCEncodingForMethodDecl(getter,TypeStr);
> @@ -2149,11 +2133,11 @@ llvm::Constant *CGObjCGNU::GeneratePrope
>          InstanceMethodTypes.push_back(TypeEncoding);
>          InstanceMethodSels.push_back(getter->getSelector());
>        }
> -      Fields.push_back(MakeConstantString(getter->
> getSelector().getAsString()));
> -      Fields.push_back(TypeEncoding);
> +      fields.add(MakeConstantString(getter->getSelector().
> getAsString()));
> +      fields.add(TypeEncoding);
>      } else {
> -      Fields.push_back(NULLPtr);
> -      Fields.push_back(NULLPtr);
> +      fields.add(NULLPtr);
> +      fields.add(NULLPtr);
>      }
>      if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
>        std::string TypeStr;
> @@ -2163,26 +2147,18 @@ llvm::Constant *CGObjCGNU::GeneratePrope
>          InstanceMethodTypes.push_back(TypeEncoding);
>          InstanceMethodSels.push_back(setter->getSelector());
>        }
> -      Fields.push_back(MakeConstantString(setter->
> getSelector().getAsString()));
> -      Fields.push_back(TypeEncoding);
> +      fields.add(MakeConstantString(setter->getSelector().
> getAsString()));
> +      fields.add(TypeEncoding);
>      } else {
> -      Fields.push_back(NULLPtr);
> -      Fields.push_back(NULLPtr);
> +      fields.add(NULLPtr);
> +      fields.add(NULLPtr);
>      }
> -    Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy,
> Fields));
> +    properties.add(fields.finish());
>    }
> -  llvm::ArrayType *PropertyArrayTy =
> -      llvm::ArrayType::get(PropertyMetadataTy, Properties.size());
> -  llvm::Constant *PropertyArray = llvm::ConstantArray::get(
> PropertyArrayTy,
> -          Properties);
> -  llvm::Constant* PropertyListInitFields[] =
> -    {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr,
> PropertyArray};
> -
> -  llvm::Constant *PropertyListInit =
> -      llvm::ConstantStruct::getAnon(PropertyListInitFields);
> -  return new llvm::GlobalVariable(TheModule,
> PropertyListInit->getType(), false,
> -          llvm::GlobalValue::InternalLinkage, PropertyListInit,
> -          ".objc_property_list");
> +  propertyList.add(properties.finish());
> +
> +  return propertyList.finishAndCreateGlobal(".objc_property_list",
> +                                            CGM.getPointerAlign());
>  }
>
>  void CGObjCGNU::RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {
> @@ -2231,7 +2207,8 @@ void CGObjCGNU::GenerateClass(const ObjC
>    SmallVector<llvm::Constant*, 16> IvarTypes;
>    SmallVector<llvm::Constant*, 16> IvarOffsets;
>
> -  std::vector<llvm::Constant*> IvarOffsetValues;
> +  ConstantBuilder IvarOffsetBuilder(CGM);
> +  auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
>    SmallVector<bool, 16> WeakIvars;
>    SmallVector<bool, 16> StrongIvars;
>
> @@ -2275,7 +2252,7 @@ void CGObjCGNU::GenerateClass(const ObjC
>            "__objc_ivar_offset_value_" + ClassName +"." +
>            IVD->getNameAsString());
>        IvarOffsets.push_back(OffsetValue);
> -      IvarOffsetValues.push_back(OffsetVar);
> +      IvarOffsetValues.add(OffsetVar);
>        Qualifiers::ObjCLifetime lt = IVD->getType().getQualifiers()
> .getObjCLifetime();
>        switch (lt) {
>          case Qualifiers::OCL_Strong:
> @@ -2294,8 +2271,8 @@ void CGObjCGNU::GenerateClass(const ObjC
>    llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
>    llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
>    llvm::GlobalVariable *IvarOffsetArray =
> -    MakeGlobalArray(PtrToIntTy, IvarOffsetValues, CGM.getPointerAlign(),
> -                    ".ivar.offsets");
> +    IvarOffsetValues.finishAndCreateGlobal(".ivar.offsets",
> +                                           CGM.getPointerAlign());
>
>    // Collect information about instance methods
>    SmallVector<Selector, 16> InstanceMethodSels;
> @@ -2461,21 +2438,18 @@ llvm::Function *CGObjCGNU::ModuleInitFun
>      if (StringClass.empty()) StringClass = "NXConstantString";
>
>      Elements.push_back(MakeConstantString(StringClass,
> -                ".objc_static_class_name"));
> +                                          ".objc_static_class_name"));
>      Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy,
> -       ConstantStrings));
> -    llvm::StructType *StaticsListTy =
> -      llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy, nullptr);
> -    llvm::Type *StaticsListPtrTy =
> -      llvm::PointerType::getUnqual(StaticsListTy);
> -    Statics = MakeGlobal(StaticsListTy, Elements, CGM.getPointerAlign(),
> -                         ".objc_statics");
> +                                                ConstantStrings));
> +    Statics = MakeGlobal(llvm::ConstantStruct::getAnon(Elements),
> +                         CGM.getPointerAlign(), ".objc_statics");
> +    llvm::Type *StaticsListPtrTy = Statics->getType();
>      llvm::ArrayType *StaticsListArrayTy =
>        llvm::ArrayType::get(StaticsListPtrTy, 2);
>      Elements.clear();
>      Elements.push_back(Statics);
>      Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy));
> -    Statics = MakeGlobal(StaticsListArrayTy, Elements,
> +    Statics = MakeGlobal(llvm::ConstantArray::get(StaticsListArrayTy,
> Elements),
>                           CGM.getPointerAlign(), ".objc_statics_ptr");
>      Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy);
>    }
> @@ -2489,7 +2463,8 @@ llvm::Function *CGObjCGNU::ModuleInitFun
>
>    Elements.clear();
>    // Pointer to an array of selectors used in this module.
> -  std::vector<llvm::Constant*> Selectors;
> +  ConstantBuilder SelectorBuilder(CGM);
> +  auto Selectors = SelectorBuilder.beginArray(SelStructTy);
>    std::vector<llvm::GlobalAlias*> SelectorAliases;
>    for (SelectorMap::iterator iter = SelectorTable.begin(),
>        iterEnd = SelectorTable.end(); iter != iterEnd ; ++iter) {
> @@ -2505,10 +2480,10 @@ llvm::Function *CGObjCGNU::ModuleInitFun
>        if (!i->first.empty())
>          SelectorTypeEncoding = MakeConstantString(i->first,
> ".objc_sel_types");
>
> -      Elements.push_back(SelName);
> -      Elements.push_back(SelectorTypeEncoding);
> -      Selectors.push_back(llvm::ConstantStruct::get(SelStructTy,
> Elements));
> -      Elements.clear();
> +      auto SelStruct = Selectors.beginStruct(SelStructTy);
> +      SelStruct.add(SelName);
> +      SelStruct.add(SelectorTypeEncoding);
> +      Selectors.add(SelStruct.finish());
>
>        // Store the selector alias for later replacement
>        SelectorAliases.push_back(i->second);
> @@ -2519,16 +2494,18 @@ llvm::Function *CGObjCGNU::ModuleInitFun
>    // because the selector list has a length field.  Unfortunately, the GCC
>    // runtime decides to ignore the length field and expects a NULL
> terminator,
>    // and GCC cooperates with this by always setting the length to 0.
> -  Elements.push_back(NULLPtr);
> -  Elements.push_back(NULLPtr);
> -  Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
> -  Elements.clear();
> +  {
> +    auto SelStruct = Selectors.beginStruct(SelStructTy);
> +    SelStruct.add(NULLPtr);
> +    SelStruct.add(NULLPtr);
> +    Selectors.add(SelStruct.finish());
> +  }
>
>    // Number of static selectors
>    Elements.push_back(llvm::ConstantInt::get(LongTy, SelectorCount));
>    llvm::GlobalVariable *SelectorList =
> -      MakeGlobalArray(SelStructTy, Selectors, CGM.getPointerAlign(),
> -                      ".objc_selector_list");
> +      Selectors.finishAndCreateGlobal(".objc_selector_list",
> +                                      CGM.getPointerAlign());
>    Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList,
>      SelStructPtrTy));
>
> @@ -2562,7 +2539,8 @@ llvm::Function *CGObjCGNU::ModuleInitFun
>    Elements.push_back(ClassList);
>    // Construct the symbol table
>    llvm::Constant *SymTab =
> -    MakeGlobal(SymTabTy, Elements, CGM.getPointerAlign());
> +    MakeGlobal(llvm::ConstantStruct::get(SymTabTy, Elements),
> +               CGM.getPointerAlign());
>
>    // The symbol table is contained in a module which has some
> version-checking
>    // constants
> @@ -2603,7 +2581,9 @@ llvm::Function *CGObjCGNU::ModuleInitFun
>          break;
>      }
>
> -  llvm::Value *Module = MakeGlobal(ModuleTy, Elements,
> CGM.getPointerAlign());
> +  llvm::Value *Module =
> +    MakeGlobal(llvm::ConstantStruct::get(ModuleTy, Elements),
> +               CGM.getPointerAlign());
>
>    // Create the load function calling the runtime entry point with the
> module
>    // structure
>
> Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CGOpenMPRuntime.cpp?rev=287437&r1=287436&r2=287437&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Sat Nov 19 02:17:24 2016
> @@ -15,6 +15,7 @@
>  #include "CGCleanup.h"
>  #include "CGOpenMPRuntime.h"
>  #include "CodeGenFunction.h"
> +#include "ConstantBuilder.h"
>  #include "clang/AST/Decl.h"
>  #include "clang/AST/StmtOpenMP.h"
>  #include "llvm/ADT/ArrayRef.h"
> @@ -906,18 +907,19 @@ Address CGOpenMPRuntime::getOrCreateDefa
>        DefaultOpenMPPSource =
>            llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource,
> CGM.Int8PtrTy);
>      }
> -    auto DefaultOpenMPLocation = new llvm::GlobalVariable(
> -        CGM.getModule(), IdentTy, /*isConstant*/ true,
> -        llvm::GlobalValue::PrivateLinkage, /*Initializer*/ nullptr);
> +
> +    ConstantBuilder builder(CGM);
> +    auto fields = builder.beginStruct(IdentTy);
> +    fields.addInt(CGM.Int32Ty, 0);
> +    fields.addInt(CGM.Int32Ty, Flags);
> +    fields.addInt(CGM.Int32Ty, 0);
> +    fields.addInt(CGM.Int32Ty, 0);
> +    fields.add(DefaultOpenMPPSource);
> +    auto DefaultOpenMPLocation =
> +      fields.finishAndCreateGlobal("", Align, /*isConstant*/ true,
> +                                   llvm::GlobalValue::PrivateLinkage);
>      DefaultOpenMPLocation->setUnnamedAddr(llvm::
> GlobalValue::UnnamedAddr::Global);
> -    DefaultOpenMPLocation->setAlignment(Align.getQuantity());
>
> -    llvm::Constant *Zero = llvm::ConstantInt::get(CGM.Int32Ty, 0, true);
> -    llvm::Constant *Values[] = {Zero,
> -                                llvm::ConstantInt::get(CGM.Int32Ty,
> Flags),
> -                                Zero, Zero, DefaultOpenMPPSource};
> -    llvm::Constant *Init = llvm::ConstantStruct::get(IdentTy, Values);
> -    DefaultOpenMPLocation->setInitializer(Init);
>      OpenMPDefaultLocMap[Flags] = Entry = DefaultOpenMPLocation;
>    }
>    return Address(Entry, Align);
> @@ -2810,9 +2812,10 @@ CGOpenMPRuntime::createOffloadingBinaryD
>        ".omp_offloading.entries_end");
>
>    // Create all device images
> -  llvm::SmallVector<llvm::Constant *, 4> DeviceImagesEntires;
>    auto *DeviceImageTy = cast<llvm::StructType>(
>        CGM.getTypes().ConvertTypeForMem(getTgtDeviceImageQTy()));
> +  ConstantBuilder DeviceImagesBuilder(CGM);
> +  auto DeviceImagesEntries = DeviceImagesBuilder.
> beginArray(DeviceImageTy);
>
>    for (unsigned i = 0; i < Devices.size(); ++i) {
>      StringRef T = Devices[i].getTriple();
> @@ -2824,22 +2827,19 @@ CGOpenMPRuntime::createOffloadingBinaryD
>          M, CGM.Int8Ty, /*isConstant=*/true, llvm::GlobalValue::
> ExternalLinkage,
>          /*Initializer=*/nullptr, Twine(".omp_offloading.img_end.") +
> Twine(T));
>
> -    llvm::Constant *Dev =
> -        llvm::ConstantStruct::get(DeviceImageTy, ImgBegin, ImgEnd,
> -                                  HostEntriesBegin, HostEntriesEnd,
> nullptr);
> -    DeviceImagesEntires.push_back(Dev);
> +    auto Dev = DeviceImagesEntries.beginStruct(DeviceImageTy);
> +    Dev.add(ImgBegin);
> +    Dev.add(ImgEnd);
> +    Dev.add(HostEntriesBegin);
> +    Dev.add(HostEntriesEnd);
> +    DeviceImagesEntries.add(Dev.finish());
>    }
>
>    // Create device images global array.
> -  llvm::ArrayType *DeviceImagesInitTy =
> -      llvm::ArrayType::get(DeviceImageTy, DeviceImagesEntires.size());
> -  llvm::Constant *DeviceImagesInit =
> -      llvm::ConstantArray::get(DeviceImagesInitTy, DeviceImagesEntires);
> -
> -  llvm::GlobalVariable *DeviceImages = new llvm::GlobalVariable(
> -      M, DeviceImagesInitTy, /*isConstant=*/true,
> -      llvm::GlobalValue::InternalLinkage, DeviceImagesInit,
> -      ".omp_offloading.device_images");
> +  llvm::GlobalVariable *DeviceImages =
> +    DeviceImagesEntries.finishAndCreateGlobal(".omp_
> offloading.device_images",
> +                                              CGM.getPointerAlign(),
> +                                              /*isConstant=*/true);
>    DeviceImages->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
>
>    // This is a Zero array to be used in the creation of the constant
> expressions
> @@ -2849,16 +2849,18 @@ CGOpenMPRuntime::createOffloadingBinaryD
>    // Create the target region descriptor.
>    auto *BinaryDescriptorTy = cast<llvm::StructType>(
>        CGM.getTypes().ConvertTypeForMem(getTgtBinaryDescriptorQTy()));
> -  llvm::Constant *TargetRegionsDescriptorInit = llvm::ConstantStruct::get(
> -      BinaryDescriptorTy, llvm::ConstantInt::get(CGM.Int32Ty,
> Devices.size()),
> -      llvm::ConstantExpr::getGetElementPtr(DeviceImagesInitTy,
> DeviceImages,
> -                                           Index),
> -      HostEntriesBegin, HostEntriesEnd, nullptr);
> -
> -  auto *Desc = new llvm::GlobalVariable(
> -      M, BinaryDescriptorTy, /*isConstant=*/true,
> -      llvm::GlobalValue::InternalLinkage, TargetRegionsDescriptorInit,
> -      ".omp_offloading.descriptor");
> +  ConstantBuilder DescBuilder(CGM);
> +  auto DescInit = DescBuilder.beginStruct(BinaryDescriptorTy);
> +  DescInit.addInt(CGM.Int32Ty, Devices.size());
> +  DescInit.add(llvm::ConstantExpr::getGetElementPtr(DeviceImages-
> >getValueType(),
> +                                                    DeviceImages,
> +                                                    Index));
> +  DescInit.add(HostEntriesBegin);
> +  DescInit.add(HostEntriesEnd);
> +
> +  auto *Desc = DescInit.finishAndCreateGlobal(".omp_
> offloading.descriptor",
> +                                              CGM.getPointerAlign(),
> +                                              /*isConstant=*/true);
>
>    // Emit code to register or unregister the descriptor at execution
>    // startup or closing, respectively.
> @@ -2906,19 +2908,24 @@ void CGOpenMPRuntime::createOffloadEntry
>    Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
>    llvm::Constant *StrPtr = llvm::ConstantExpr::getBitCast(Str,
> CGM.Int8PtrTy);
>
> +  // We can't have any padding between symbols, so we need to have 1-byte
> +  // alignment.
> +  auto Align = CharUnits::fromQuantity(1);
> +
>    // Create the entry struct.
> -  llvm::Constant *EntryInit = llvm::ConstantStruct::get(
> -      TgtOffloadEntryType, AddrPtr, StrPtr,
> -      llvm::ConstantInt::get(CGM.SizeTy, Size), nullptr);
> -  llvm::GlobalVariable *Entry = new llvm::GlobalVariable(
> -      M, TgtOffloadEntryType, true, llvm::GlobalValue::ExternalLinkage,
> -      EntryInit, ".omp_offloading.entry");
> +  ConstantBuilder EntryBuilder(CGM);
> +  auto EntryInit = EntryBuilder.beginStruct(TgtOffloadEntryType);
> +  EntryInit.add(AddrPtr);
> +  EntryInit.add(StrPtr);
> +  EntryInit.addInt(CGM.SizeTy, Size);
> +  llvm::GlobalVariable *Entry =
> +    EntryInit.finishAndCreateGlobal(".omp_offloading.entry",
> +                                    Align,
> +                                    /*constant*/ true,
> +                                    llvm::GlobalValue::ExternalLinkage);
>
>    // The entry has to be created in the section the linker expects it to
> be.
>    Entry->setSection(".omp_offloading.entries");
> -  // We can't have any padding between symbols, so we need to have 1-byte
> -  // alignment.
> -  Entry->setAlignment(1);
>  }
>
>  void CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() {
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CodeGenModule.cpp?rev=287437&r1=287436&r2=287437&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sat Nov 19 02:17:24 2016
> @@ -24,6 +24,7 @@
>  #include "CodeGenFunction.h"
>  #include "CodeGenPGO.h"
>  #include "CodeGenTBAA.h"
> +#include "ConstantBuilder.h"
>  #include "CoverageMappingGen.h"
>  #include "TargetInfo.h"
>  #include "clang/AST/ASTContext.h"
> @@ -731,6 +732,8 @@ void CodeGenModule::AddGlobalDtor(llvm::
>  }
>
>  void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) {
> +  if (Fns.empty()) return;
> +
>    // Ctor function type is void()*.
>    llvm::FunctionType* CtorFTy = llvm::FunctionType::get(VoidTy, false);
>    llvm::Type *CtorPFTy = llvm::PointerType::getUnqual(CtorFTy);
> @@ -740,24 +743,22 @@ void CodeGenModule::EmitCtorList(CtorLis
>        Int32Ty, llvm::PointerType::getUnqual(CtorFTy), VoidPtrTy,
> nullptr);
>
>    // Construct the constructor and destructor arrays.
> -  SmallVector<llvm::Constant *, 8> Ctors;
> +  ConstantBuilder builder(*this);
> +  auto ctors = builder.beginArray(CtorStructTy);
>    for (const auto &I : Fns) {
> -    llvm::Constant *S[] = {
> -        llvm::ConstantInt::get(Int32Ty, I.Priority, false),
> -        llvm::ConstantExpr::getBitCast(I.Initializer, CtorPFTy),
> -        (I.AssociatedData
> -             ? llvm::ConstantExpr::getBitCast(I.AssociatedData,
> VoidPtrTy)
> -             : llvm::Constant::getNullValue(VoidPtrTy))};
> -    Ctors.push_back(llvm::ConstantStruct::get(CtorStructTy, S));
> +    auto ctor = ctors.beginStruct(CtorStructTy);
> +    ctor.addInt(Int32Ty, I.Priority);
> +    ctor.add(llvm::ConstantExpr::getBitCast(I.Initializer, CtorPFTy));
> +    if (I.AssociatedData)
> +      ctor.add(llvm::ConstantExpr::getBitCast(I.AssociatedData,
> VoidPtrTy));
> +    else
> +      ctor.addNullPointer(VoidPtrTy);
> +    ctors.add(ctor.finish());
>    }
>
> -  if (!Ctors.empty()) {
> -    llvm::ArrayType *AT = llvm::ArrayType::get(CtorStructTy,
> Ctors.size());
> -    new llvm::GlobalVariable(TheModule, AT, false,
> -                             llvm::GlobalValue::AppendingLinkage,
> -                             llvm::ConstantArray::get(AT, Ctors),
> -                             GlobalName);
> -  }
> +  (void) ctors.finishAndCreateGlobal(GlobalName, getPointerAlign(),
> +                                     /*constant*/ false,
> +                                     llvm::GlobalValue::
> AppendingLinkage);
>    Fns.clear();
>  }
>
> @@ -3190,15 +3191,14 @@ CodeGenModule::GetAddrOfConstantCFString
>
>    auto *STy = cast<llvm::StructType>(getTypes().ConvertType(CFTy));
>
> -  llvm::Constant *Fields[4];
> +  ConstantBuilder Builder(*this);
> +  auto Fields = Builder.beginStruct(STy);
>
>    // Class pointer.
> -  Fields[0] = cast<llvm::ConstantExpr>(CFConstantStringClassRef);
> +  Fields.add(cast<llvm::ConstantExpr>(CFConstantStringClassRef));
>
>    // Flags.
> -  llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy);
> -  Fields[1] = isUTF16 ? llvm::ConstantInt::get(Ty, 0x07d0)
> -                      : llvm::ConstantInt::get(Ty, 0x07C8);
> +  Fields.addInt(IntTy, isUTF16 ? 0x07d0 : 0x07C8);
>
>    // String pointer.
>    llvm::Constant *C = nullptr;
> @@ -3232,25 +3232,24 @@ CodeGenModule::GetAddrOfConstantCFString
>                             : "__TEXT,__cstring,cstring_literals");
>
>    // String.
> -  Fields[2] =
> +  llvm::Constant *Str =
>        llvm::ConstantExpr::getGetElementPtr(GV->getValueType(), GV,
> Zeros);
>
>    if (isUTF16)
>      // Cast the UTF16 string to the correct type.
> -    Fields[2] = llvm::ConstantExpr::getBitCast(Fields[2], Int8PtrTy);
> +    Str = llvm::ConstantExpr::getBitCast(Str, Int8PtrTy);
> +  Fields.add(Str);
>
>    // String length.
> -  Ty = getTypes().ConvertType(getContext().LongTy);
> -  Fields[3] = llvm::ConstantInt::get(Ty, StringLength);
> +  auto Ty = getTypes().ConvertType(getContext().LongTy);
> +  Fields.addInt(cast<llvm::IntegerType>(Ty), StringLength);
>
>    CharUnits Alignment = getPointerAlign();
>
>    // The struct.
> -  C = llvm::ConstantStruct::get(STy, Fields);
> -  GV = new llvm::GlobalVariable(getModule(), C->getType(),
> /*isConstant=*/false,
> -                                llvm::GlobalVariable::PrivateLinkage, C,
> -                                "_unnamed_cfstring_");
> -  GV->setAlignment(Alignment.getQuantity());
> +  GV = Fields.finishAndCreateGlobal("_unnamed_cfstring_", Alignment,
> +                                    /*isConstant=*/false,
> +                                    llvm::GlobalVariable::
> PrivateLinkage);
>    switch (getTriple().getObjectFormat()) {
>    case llvm::Triple::UnknownObjectFormat:
>      llvm_unreachable("unknown file format");
> @@ -3338,19 +3337,18 @@ CodeGenModule::GetAddrOfConstantString(c
>      NSConstantStringType = cast<llvm::StructType>(
> getTypes().ConvertType(NSTy));
>    }
>
> -  llvm::Constant *Fields[3];
> +  ConstantBuilder Builder(*this);
> +  auto Fields = Builder.beginStruct(NSConstantStringType);
>
>    // Class pointer.
> -  Fields[0] = cast<llvm::ConstantExpr>(V);
> +  Fields.add(cast<llvm::ConstantExpr>(V));
>
>    // String pointer.
>    llvm::Constant *C =
>        llvm::ConstantDataArray::getString(VMContext, Entry.first());
>
> -  llvm::GlobalValue::LinkageTypes Linkage;
> -  bool isConstant;
> -  Linkage = llvm::GlobalValue::PrivateLinkage;
> -  isConstant = !LangOpts.WritableStrings;
> +  llvm::GlobalValue::LinkageTypes Linkage = llvm::GlobalValue::
> PrivateLinkage;
> +  bool isConstant = !LangOpts.WritableStrings;
>
>    auto *GV = new llvm::GlobalVariable(getModule(), C->getType(),
> isConstant,
>                                        Linkage, C, ".str");
> @@ -3359,20 +3357,17 @@ CodeGenModule::GetAddrOfConstantString(c
>    // of the string is via this class initializer.
>    CharUnits Align = getContext().getTypeAlignInChars(
> getContext().CharTy);
>    GV->setAlignment(Align.getQuantity());
> -  Fields[1] =
> -      llvm::ConstantExpr::getGetElementPtr(GV->getValueType(), GV,
> Zeros);
> +  Fields.add(
> +      llvm::ConstantExpr::getGetElementPtr(GV->getValueType(), GV,
> Zeros));
>
>    // String length.
> -  llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy);
> -  Fields[2] = llvm::ConstantInt::get(Ty, StringLength);
> +  Fields.addInt(IntTy, StringLength);
>
>    // The struct.
>    CharUnits Alignment = getPointerAlign();
> -  C = llvm::ConstantStruct::get(NSConstantStringType, Fields);
> -  GV = new llvm::GlobalVariable(getModule(), C->getType(), true,
> -                                llvm::GlobalVariable::PrivateLinkage, C,
> -                                "_unnamed_nsstring_");
> -  GV->setAlignment(Alignment.getQuantity());
> +  GV = Fields.finishAndCreateGlobal("_unnamed_nsstring_", Alignment,
> +                                    /*constant*/ true,
> +                                    llvm::GlobalVariable::
> PrivateLinkage);
>    const char *NSStringSection = "__OBJC,__cstring_object,
> regular,no_dead_strip";
>    const char *NSStringNonFragileABISection =
>        "__DATA,__objc_stringobj,regular,no_dead_strip";
>
> Added: cfe/trunk/lib/CodeGen/ConstantBuilder.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> ConstantBuilder.h?rev=287437&view=auto
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/ConstantBuilder.h (added)
> +++ cfe/trunk/lib/CodeGen/ConstantBuilder.h Sat Nov 19 02:17:24 2016
> @@ -0,0 +1,274 @@
> +//===----- ConstantBuilder.h - Builder for LLVM IR constants ----*- C++
> -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +//
> +// This class provides a convenient interface for building complex
> +// global initializers.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +#ifndef LLVM_CLANG_LIB_CODEGEN_CONSTANTBUILDER_H
> +#define LLVM_CLANG_LIB_CODEGEN_CONSTANTBUILDER_H
> +
> +#include "llvm/ADT/ArrayRef.h"
> +#include "llvm/ADT/SmallVector.h"
> +#include "llvm/IR/Constants.h"
> +
> +#include "CodeGenModule.h"
> +
> +namespace clang {
> +namespace CodeGen {
> +
> +class ConstantBuilder;
> +
> +/// A convenience builder class for complex constant initializers,
> +/// especially for anonymous global structures used by various language
> +/// runtimes.
> +///
> +/// The basic usage pattern is expected to be something like:
> +///    ConstantBuilder builder(CGM);
> +///    auto toplevel = builder.beginStruct();
> +///    toplevel.addInt(CGM.SizeTy, widgets.size());
> +///    auto widgetArray = builder.beginArray();
> +///    for (auto &widget : widgets) {
> +///      auto widgetDesc = widgetArray.beginStruct();
> +///      widgetDesc.addInt(CGM.SizeTy, widget.getPower());
> +///      widgetDesc.add(CGM.GetAddrOfConstantString(widget.getName()));
> +///      widgetDesc.add(CGM.GetAddrOfGlobal(widget.
> getInitializerDecl()));
> +///      widgetArray.add(widgetDesc.finish());
> +///    }
> +///    toplevel.add(widgetArray.finish());
> +///    auto global = toplevel.finishAndCreateGlobal("WIDGET_LIST", Align,
> +///                                                 /*constant*/ true);
> +class ConstantBuilder {
> +  CodeGenModule &CGM;
> +  llvm::SmallVector<llvm::Constant*, 16> Buffer;
> +  bool Frozen = false;
> +
> +public:
> +  explicit ConstantBuilder(CodeGenModule &CGM) : CGM(CGM) {}
> +
> +  ~ConstantBuilder() {
> +    assert(Buffer.empty() && "didn't claim all values out of buffer");
> +  }
> +
> +  class ArrayBuilder;
> +  class StructBuilder;
> +
> +  class AggregateBuilder {
> +  protected:
> +    ConstantBuilder &Builder;
> +    AggregateBuilder *Parent;
> +    size_t Begin;
> +    bool Finished = false;
> +    bool Frozen = false;
> +
> +    AggregateBuilder(ConstantBuilder &builder, AggregateBuilder *parent)
> +        : Builder(builder), Parent(parent), Begin(builder.Buffer.size()) {
> +      if (parent) {
> +        assert(!parent->Frozen && "parent already has child builder
> active");
> +        parent->Frozen = true;
> +      } else {
> +        assert(!builder.Frozen && "builder already has child builder
> active");
> +        builder.Frozen = true;
> +      }
> +    }
> +
> +    ~AggregateBuilder() {
> +      assert(Finished && "didn't claim value from aggregate builder");
> +    }
> +
> +    void markFinished() {
> +      assert(!Frozen && "child builder still active");
> +      assert(!Finished && "builder already finished");
> +      Finished = true;
> +      if (Parent) {
> +        assert(Parent->Frozen &&
> +               "parent not frozen while child builder active");
> +        Parent->Frozen = false;
> +      } else {
> +        assert(Builder.Frozen &&
> +               "builder not frozen while child builder active");
> +        Builder.Frozen = false;
> +      }
> +    }
> +
> +  public:
> +    // Not copyable.
> +    AggregateBuilder(const AggregateBuilder &) = delete;
> +    AggregateBuilder &operator=(const AggregateBuilder &) = delete;
> +
> +    // Movable, mostly to allow returning.  But we have to write this out
> +    // properly to satisfy the assert in the destructor.
> +    AggregateBuilder(AggregateBuilder &&other)
> +      : Builder(other.Builder), Parent(other.Parent), Begin(other.Begin),
> +        Finished(other.Finished), Frozen(other.Frozen) {
> +      other.Finished = false;
> +    }
> +    AggregateBuilder &operator=(AggregateBuilder &&other) = delete;
> +
> +    void add(llvm::Constant *value) {
> +      assert(!Finished && "cannot add more values after finishing
> builder");
> +      Builder.Buffer.push_back(value);
> +    }
> +
> +    void addSize(CharUnits size) {
> +      add(Builder.CGM.getSize(size));
> +    }
> +
> +    void addInt(llvm::IntegerType *intTy, uint64_t value,
> +                bool isSigned = false) {
> +      add(llvm::ConstantInt::get(intTy, value, isSigned));
> +    }
> +
> +    void addNullPointer(llvm::PointerType *ptrTy) {
> +      add(llvm::ConstantPointerNull::get(ptrTy));
> +    }
> +
> +    ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition(
> +                             llvm::SmallVectorImpl<llvm::Constant*>
> &indices) {
> +      getGEPIndicesTo(indices, Builder.Buffer.size());
> +      return indices;
> +    }
> +
> +    ArrayBuilder beginArray(llvm::Type *eltTy = nullptr);
> +    StructBuilder beginStruct(llvm::StructType *structTy = nullptr);
> +
> +  private:
> +    void getGEPIndicesTo(llvm::SmallVectorImpl<llvm::Constant*> &indices,
> +                         size_t position) const {
> +      // Recurse on the parent builder if present.
> +      if (Parent) {
> +        Parent->getGEPIndicesTo(indices, Begin);
> +
> +      // Otherwise, add an index to drill into the first level of pointer.
> +      } else {
> +        assert(indices.empty());
> +        indices.push_back(llvm::ConstantInt::get(Builder.CGM.SizeTy, 0));
> +      }
> +
> +      assert(position >= Begin);
> +      indices.push_back(llvm::ConstantInt::get(Builder.CGM.SizeTy,
> +                                               position - Begin));
> +    }
> +  };
> +
> +  class ArrayBuilder : public AggregateBuilder {
> +    llvm::Type *EltTy;
> +    friend class ConstantBuilder;
> +    ArrayBuilder(ConstantBuilder &builder, AggregateBuilder *parent,
> +                 llvm::Type *eltTy)
> +      : AggregateBuilder(builder, parent), EltTy(eltTy) {}
> +  public:
> +    size_t size() const {
> +      assert(!Finished);
> +      assert(!Frozen);
> +      assert(Begin <= Builder.Buffer.size());
> +      return Builder.Buffer.size() - Begin;
> +    }
> +
> +    /// Form an array constant from the values that have been added to
> this
> +    /// builder.
> +    llvm::Constant *finish() {
> +      markFinished();
> +
> +      auto &buffer = Builder.Buffer;
> +      assert((Begin < buffer.size() ||
> +              (Begin == buffer.size() && EltTy))
> +             && "didn't add any array elements without element type");
> +      auto elts = llvm::makeArrayRef(buffer).slice(Begin);
> +      auto eltTy = EltTy ? EltTy : elts[0]->getType();
> +      auto type = llvm::ArrayType::get(eltTy, elts.size());
> +      auto constant = llvm::ConstantArray::get(type, elts);
> +      buffer.erase(buffer.begin() + Begin, buffer.end());
> +      return constant;
> +    }
> +
> +    template <class... As>
> +    llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
> +      assert(!Parent && "finishing non-root builder");
> +      return Builder.createGlobal(finish(), std::forward<As>(args)...);
> +    }
> +  };
> +
> +  ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {
> +    return ArrayBuilder(*this, nullptr, eltTy);
> +  }
> +
> +  class StructBuilder : public AggregateBuilder {
> +    llvm::StructType *Ty;
> +    friend class ConstantBuilder;
> +    StructBuilder(ConstantBuilder &builder, AggregateBuilder *parent,
> +                  llvm::StructType *ty)
> +      : AggregateBuilder(builder, parent), Ty(ty) {}
> +  public:
> +    /// Finish the struct.
> +    llvm::Constant *finish(bool packed = false) {
> +      markFinished();
> +
> +      auto &buffer = Builder.Buffer;
> +      assert(Begin < buffer.size() && "didn't add any struct elements?");
> +      auto elts = llvm::makeArrayRef(buffer).slice(Begin);
> +
> +      llvm::Constant *constant;
> +      if (Ty) {
> +        constant = llvm::ConstantStruct::get(Ty, elts);
> +      } else {
> +        constant = llvm::ConstantStruct::getAnon(elts, packed);
> +      }
> +
> +      buffer.erase(buffer.begin() + Begin, buffer.end());
> +      return constant;
> +    }
> +
> +    template <class... As>
> +    llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
> +      assert(!Parent && "finishing non-root builder");
> +      return Builder.createGlobal(finish(), std::forward<As>(args)...);
> +    }
> +  };
> +
> +  StructBuilder beginStruct(llvm::StructType *structTy = nullptr) {
> +    return StructBuilder(*this, nullptr, structTy);
> +  }
> +
> +  llvm::GlobalVariable *createGlobal(llvm::Constant *initializer,
> +                                     StringRef name,
> +                                     CharUnits alignment,
> +                                     bool constant = false,
> +                                     llvm::GlobalValue::LinkageTypes
> linkage
> +                                       = llvm::GlobalValue::
> InternalLinkage,
> +                                     unsigned addressSpace = 0) {
> +    auto GV = new llvm::GlobalVariable(CGM.getModule(),
> +                                       initializer->getType(),
> +                                       constant,
> +                                       linkage,
> +                                       initializer,
> +                                       name,
> +                                       /*insert before*/ nullptr,
> +                                       llvm::GlobalValue::NotThreadLocal,
> +                                       addressSpace);
> +    GV->setAlignment(alignment.getQuantity());
> +    return GV;
> +  }
> +};
> +
> +inline ConstantBuilder::ArrayBuilder
> +ConstantBuilder::AggregateBuilder::beginArray(llvm::Type *eltTy) {
> +  return ArrayBuilder(Builder, this, eltTy);
> +}
> +
> +inline ConstantBuilder::StructBuilder
> +ConstantBuilder::AggregateBuilder::beginStruct(llvm::StructType
> *structTy) {
> +  return StructBuilder(Builder, this, structTy);
> +}
> +
> +}  // end namespace CodeGen
> +}  // end namespace clang
> +
> +#endif
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161119/2a22c3a9/attachment-0001.html>


More information about the cfe-commits mailing list