Author: rjmccall Date: Thu Mar 2 14:04:19 2017 New Revision: 296806 URL: http://llvm.org/viewvc/llvm-project?rev=296806&view=rev Log: Promote ConstantInitBuilder to be a public CodeGen API; it's a generally useful utility for other frontends. NFC.
Added: cfe/trunk/include/clang/CodeGen/ConstantInitBuilder.h - copied, changed from r296781, cfe/trunk/lib/CodeGen/ConstantBuilder.h cfe/trunk/lib/CodeGen/ConstantInitBuilder.cpp Removed: cfe/trunk/lib/CodeGen/ConstantBuilder.h Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp cfe/trunk/lib/CodeGen/CGCUDANV.cpp cfe/trunk/lib/CodeGen/CGObjCGNU.cpp cfe/trunk/lib/CodeGen/CGObjCMac.cpp cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp cfe/trunk/lib/CodeGen/CGVTables.cpp cfe/trunk/lib/CodeGen/CMakeLists.txt cfe/trunk/lib/CodeGen/CodeGenModule.cpp cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Copied: cfe/trunk/include/clang/CodeGen/ConstantInitBuilder.h (from r296781, cfe/trunk/lib/CodeGen/ConstantBuilder.h) URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/ConstantInitBuilder.h?p2=cfe/trunk/include/clang/CodeGen/ConstantInitBuilder.h&p1=cfe/trunk/lib/CodeGen/ConstantBuilder.h&r1=296781&r2=296806&rev=296806&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/ConstantBuilder.h (original) +++ cfe/trunk/include/clang/CodeGen/ConstantInitBuilder.h Thu Mar 2 14:04:19 2017 @@ -1,4 +1,4 @@ -//===----- ConstantBuilder.h - Builder for LLVM IR constants ----*- C++ -*-===// +//===- ConstantInitBuilder.h - Builder for LLVM IR constants ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,24 +8,26 @@ //===----------------------------------------------------------------------===// // // This class provides a convenient interface for building complex -// global initializers. +// global initializers of the sort that are frequently required for +// language ABIs. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_LIB_CODEGEN_CONSTANTBUILDER_H -#define LLVM_CLANG_LIB_CODEGEN_CONSTANTBUILDER_H +#ifndef LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H +#define LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/IR/Constants.h" - -#include "CodeGenModule.h" +#include "llvm/IR/GlobalValue.h" +#include "clang/AST/CharUnits.h" #include <vector> namespace clang { namespace CodeGen { +class CodeGenModule; class ConstantStructBuilder; class ConstantArrayBuilder; @@ -144,9 +146,7 @@ public: } /// Add an integer value of type size_t. - void addSize(CharUnits size) { - add(Builder.CGM.getSize(size)); - } + void addSize(CharUnits size); /// Add an integer value of a specific type. void addInt(llvm::IntegerType *intTy, uint64_t value, @@ -165,7 +165,7 @@ public: } /// Add a bunch of new values to this initializer. - void addAll(ArrayRef<llvm::Constant *> values) { + void addAll(llvm::ArrayRef<llvm::Constant *> values) { assert(!Finished && "cannot add more values after finishing builder"); assert(!Frozen && "cannot add values while subbuilder is active"); Builder.Buffer.append(values.begin(), values.end()); @@ -216,20 +216,9 @@ public: /// /// The returned pointer will have type T*, where T is the given /// position. - llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type) { - // Make a global variable. We will replace this with a GEP to this - // position after installing the initializer. - auto dummy = - new llvm::GlobalVariable(Builder.CGM.getModule(), type, true, - llvm::GlobalVariable::PrivateLinkage, - nullptr, ""); - Builder.SelfReferences.emplace_back(dummy); - auto &entry = Builder.SelfReferences.back(); - (void) getGEPIndicesToCurrentPosition(entry.Indices); - return dummy; - } + llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type); - ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition( + llvm::ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition( llvm::SmallVectorImpl<llvm::Constant*> &indices) { getGEPIndicesTo(indices, Builder.Buffer.size()); return indices; @@ -240,23 +229,7 @@ public: 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.Int32Ty, 0)); - } - - assert(position >= Begin); - // We have to use i32 here because struct GEPs demand i32 indices. - // It's rather unlikely to matter in practice. - indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty, - position - Begin)); - } + size_t position) const; }; template <class Impl> @@ -313,36 +286,12 @@ private: 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()); - resolveSelfReferences(GV); - return GV; - } + unsigned addressSpace = 0); void setGlobalInitializer(llvm::GlobalVariable *GV, - llvm::Constant *initializer) { - GV->setInitializer(initializer); - resolveSelfReferences(GV); - } + llvm::Constant *initializer); - void resolveSelfReferences(llvm::GlobalVariable *GV) { - for (auto &entry : SelfReferences) { - llvm::Constant *resolvedReference = - llvm::ConstantExpr::getInBoundsGetElementPtr( - GV->getValueType(), GV, entry.Indices); - entry.Dummy->replaceAllUsesWith(resolvedReference); - entry.Dummy->eraseFromParent(); - } - } + void resolveSelfReferences(llvm::GlobalVariable *GV); }; /// A helper class of ConstantInitBuilder, used for building constant @@ -370,20 +319,7 @@ public: private: /// Form an array constant from the values that have been added to this /// builder. - llvm::Constant *finishImpl() { - markFinished(); - - auto &buffer = getBuffer(); - 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; - } + llvm::Constant *finishImpl(); }; inline ConstantArrayBuilder @@ -408,23 +344,7 @@ class ConstantStructBuilder : AggregateBuilder(builder, parent), Ty(ty) {} /// Finish the struct. - llvm::Constant *finishImpl() { - markFinished(); - - auto &buffer = getBuffer(); - 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*/ false); - } - - buffer.erase(buffer.begin() + Begin, buffer.end()); - return constant; - } + llvm::Constant *finishImpl(); }; inline ConstantStructBuilder Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=296806&r1=296805&r2=296806&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Thu Mar 2 14:04:19 2017 @@ -16,7 +16,7 @@ #include "CGObjCRuntime.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" -#include "ConstantBuilder.h" +#include "clang/CodeGen/ConstantInitBuilder.h" #include "clang/AST/DeclObjC.h" #include "llvm/ADT/SmallSet.h" #include "llvm/IR/CallSite.h" Modified: cfe/trunk/lib/CodeGen/CGCUDANV.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCUDANV.cpp?rev=296806&r1=296805&r2=296806&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGCUDANV.cpp (original) +++ cfe/trunk/lib/CodeGen/CGCUDANV.cpp Thu Mar 2 14:04:19 2017 @@ -15,7 +15,7 @@ #include "CGCUDARuntime.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" -#include "ConstantBuilder.h" +#include "clang/CodeGen/ConstantInitBuilder.h" #include "clang/AST/Decl.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CallSite.h" Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=296806&r1=296805&r2=296806&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original) +++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Thu Mar 2 14:04:19 2017 @@ -18,7 +18,7 @@ #include "CGCleanup.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" -#include "ConstantBuilder.h" +#include "clang/CodeGen/ConstantInitBuilder.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=296806&r1=296805&r2=296806&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original) +++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Thu Mar 2 14:04:19 2017 @@ -17,7 +17,7 @@ #include "CGRecordLayout.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" -#include "ConstantBuilder.h" +#include "clang/CodeGen/ConstantInitBuilder.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=296806&r1=296805&r2=296806&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original) +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Thu Mar 2 14:04:19 2017 @@ -15,7 +15,7 @@ #include "CGCleanup.h" #include "CGOpenMPRuntime.h" #include "CodeGenFunction.h" -#include "ConstantBuilder.h" +#include "clang/CodeGen/ConstantInitBuilder.h" #include "clang/AST/Decl.h" #include "clang/AST/StmtOpenMP.h" #include "llvm/ADT/ArrayRef.h" Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=296806&r1=296805&r2=296806&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGVTables.cpp (original) +++ cfe/trunk/lib/CodeGen/CGVTables.cpp Thu Mar 2 14:04:19 2017 @@ -14,7 +14,7 @@ #include "CGCXXABI.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" -#include "ConstantBuilder.h" +#include "clang/CodeGen/ConstantInitBuilder.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/RecordLayout.h" #include "clang/CodeGen/CGFunctionInfo.h" Modified: cfe/trunk/lib/CodeGen/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CMakeLists.txt?rev=296806&r1=296805&r2=296806&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CMakeLists.txt (original) +++ cfe/trunk/lib/CodeGen/CMakeLists.txt Thu Mar 2 14:04:19 2017 @@ -75,6 +75,7 @@ add_clang_library(clangCodeGen CodeGenPGO.cpp CodeGenTBAA.cpp CodeGenTypes.cpp + ConstantInitBuilder.cpp CoverageMappingGen.cpp ItaniumCXXABI.cpp MacroPPCallbacks.cpp Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=296806&r1=296805&r2=296806&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Thu Mar 2 14:04:19 2017 @@ -24,7 +24,6 @@ #include "CodeGenFunction.h" #include "CodeGenPGO.h" #include "CodeGenTBAA.h" -#include "ConstantBuilder.h" #include "CoverageMappingGen.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" @@ -42,6 +41,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" +#include "clang/CodeGen/ConstantInitBuilder.h" #include "clang/Frontend/CodeGenOptions.h" #include "clang/Sema/SemaDiagnostic.h" #include "llvm/ADT/Triple.h" Removed: cfe/trunk/lib/CodeGen/ConstantBuilder.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ConstantBuilder.h?rev=296805&view=auto ============================================================================== --- cfe/trunk/lib/CodeGen/ConstantBuilder.h (original) +++ cfe/trunk/lib/CodeGen/ConstantBuilder.h (removed) @@ -1,444 +0,0 @@ -//===----- 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" - -#include <vector> - -namespace clang { -namespace CodeGen { - -class ConstantStructBuilder; -class ConstantArrayBuilder; - -/// 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: -/// ConstantInitBuilder 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 ConstantInitBuilder { - struct SelfReference { - llvm::GlobalVariable *Dummy; - llvm::SmallVector<llvm::Constant*, 4> Indices; - - SelfReference(llvm::GlobalVariable *dummy) : Dummy(dummy) {} - }; - CodeGenModule &CGM; - llvm::SmallVector<llvm::Constant*, 16> Buffer; - std::vector<SelfReference> SelfReferences; - bool Frozen = false; - -public: - explicit ConstantInitBuilder(CodeGenModule &CGM) : CGM(CGM) {} - - ~ConstantInitBuilder() { - assert(Buffer.empty() && "didn't claim all values out of buffer"); - } - - class AggregateBuilderBase { - protected: - ConstantInitBuilder &Builder; - AggregateBuilderBase *Parent; - size_t Begin; - bool Finished = false; - bool Frozen = false; - - llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() { - return Builder.Buffer; - } - - const llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() const { - return Builder.Buffer; - } - - AggregateBuilderBase(ConstantInitBuilder &builder, - AggregateBuilderBase *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; - } - } - - ~AggregateBuilderBase() { - assert(Finished && "didn't finish 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. - AggregateBuilderBase(const AggregateBuilderBase &) = delete; - AggregateBuilderBase &operator=(const AggregateBuilderBase &) = delete; - - // Movable, mostly to allow returning. But we have to write this out - // properly to satisfy the assert in the destructor. - AggregateBuilderBase(AggregateBuilderBase &&other) - : Builder(other.Builder), Parent(other.Parent), Begin(other.Begin), - Finished(other.Finished), Frozen(other.Frozen) { - other.Finished = false; - } - AggregateBuilderBase &operator=(AggregateBuilderBase &&other) = delete; - - /// Abandon this builder completely. - void abandon() { - markFinished(); - auto &buffer = Builder.Buffer; - buffer.erase(buffer.begin() + Begin, buffer.end()); - } - - /// Add a new value to this initializer. - void add(llvm::Constant *value) { - assert(value && "adding null value to constant initializer"); - assert(!Finished && "cannot add more values after finishing builder"); - assert(!Frozen && "cannot add values while subbuilder is active"); - Builder.Buffer.push_back(value); - } - - /// Add an integer value of type size_t. - void addSize(CharUnits size) { - add(Builder.CGM.getSize(size)); - } - - /// Add an integer value of a specific type. - void addInt(llvm::IntegerType *intTy, uint64_t value, - bool isSigned = false) { - add(llvm::ConstantInt::get(intTy, value, isSigned)); - } - - /// Add a null pointer of a specific type. - void addNullPointer(llvm::PointerType *ptrTy) { - add(llvm::ConstantPointerNull::get(ptrTy)); - } - - /// Add a bitcast of a value to a specific type. - void addBitCast(llvm::Constant *value, llvm::Type *type) { - add(llvm::ConstantExpr::getBitCast(value, type)); - } - - /// Add a bunch of new values to this initializer. - void addAll(ArrayRef<llvm::Constant *> values) { - assert(!Finished && "cannot add more values after finishing builder"); - assert(!Frozen && "cannot add values while subbuilder is active"); - Builder.Buffer.append(values.begin(), values.end()); - } - - /// An opaque class to hold the abstract position of a placeholder. - class PlaceholderPosition { - size_t Index; - friend class AggregateBuilderBase; - PlaceholderPosition(size_t index) : Index(index) {} - }; - - /// Add a placeholder value to the structure. The returned position - /// can be used to set the value later; it will not be invalidated by - /// any intermediate operations except (1) filling the same position or - /// (2) finishing the entire builder. - /// - /// This is useful for emitting certain kinds of structure which - /// contain some sort of summary field, generaly a count, before any - /// of the data. By emitting a placeholder first, the structure can - /// be emitted eagerly. - PlaceholderPosition addPlaceholder() { - assert(!Finished && "cannot add more values after finishing builder"); - assert(!Frozen && "cannot add values while subbuilder is active"); - Builder.Buffer.push_back(nullptr); - return Builder.Buffer.size() - 1; - } - - /// Fill a previously-added placeholder. - void fillPlaceholderWithInt(PlaceholderPosition position, - llvm::IntegerType *type, uint64_t value, - bool isSigned = false) { - fillPlaceholder(position, llvm::ConstantInt::get(type, value, isSigned)); - } - - /// Fill a previously-added placeholder. - void fillPlaceholder(PlaceholderPosition position, llvm::Constant *value) { - assert(!Finished && "cannot change values after finishing builder"); - assert(!Frozen && "cannot add values while subbuilder is active"); - llvm::Constant *&slot = Builder.Buffer[position.Index]; - assert(slot == nullptr && "placeholder already filled"); - slot = value; - } - - /// Produce an address which will eventually point to the the next - /// position to be filled. This is computed with an indexed - /// getelementptr rather than by computing offsets. - /// - /// The returned pointer will have type T*, where T is the given - /// position. - llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type) { - // Make a global variable. We will replace this with a GEP to this - // position after installing the initializer. - auto dummy = - new llvm::GlobalVariable(Builder.CGM.getModule(), type, true, - llvm::GlobalVariable::PrivateLinkage, - nullptr, ""); - Builder.SelfReferences.emplace_back(dummy); - auto &entry = Builder.SelfReferences.back(); - (void) getGEPIndicesToCurrentPosition(entry.Indices); - return dummy; - } - - ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition( - llvm::SmallVectorImpl<llvm::Constant*> &indices) { - getGEPIndicesTo(indices, Builder.Buffer.size()); - return indices; - } - - ConstantArrayBuilder beginArray(llvm::Type *eltTy = nullptr); - ConstantStructBuilder 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.Int32Ty, 0)); - } - - assert(position >= Begin); - // We have to use i32 here because struct GEPs demand i32 indices. - // It's rather unlikely to matter in practice. - indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty, - position - Begin)); - } - }; - - template <class Impl> - class AggregateBuilder : public AggregateBuilderBase { - protected: - AggregateBuilder(ConstantInitBuilder &builder, - AggregateBuilderBase *parent) - : AggregateBuilderBase(builder, parent) {} - - Impl &asImpl() { return *static_cast<Impl*>(this); } - - public: - /// Given that this builder was created by beginning an array or struct - /// component on the given parent builder, finish the array/struct - /// component and add it to the parent. - /// - /// It is an intentional choice that the parent is passed in explicitly - /// despite it being redundant with information already kept in the - /// builder. This aids in readability by making it easier to find the - /// places that add components to a builder, as well as "bookending" - /// the sub-builder more explicitly. - void finishAndAddTo(AggregateBuilderBase &parent) { - assert(Parent == &parent && "adding to non-parent builder"); - parent.add(asImpl().finishImpl()); - } - - /// Given that this builder was created by beginning an array or struct - /// directly on a ConstantInitBuilder, finish the array/struct and - /// create a global variable with it as the initializer. - template <class... As> - llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) { - assert(!Parent && "finishing non-root builder"); - return Builder.createGlobal(asImpl().finishImpl(), - std::forward<As>(args)...); - } - - /// Given that this builder was created by beginning an array or struct - /// directly on a ConstantInitBuilder, finish the array/struct and - /// set it as the initializer of the given global variable. - void finishAndSetAsInitializer(llvm::GlobalVariable *global) { - assert(!Parent && "finishing non-root builder"); - return Builder.setGlobalInitializer(global, asImpl().finishImpl()); - } - }; - - ConstantArrayBuilder beginArray(llvm::Type *eltTy = nullptr); - - ConstantStructBuilder beginStruct(llvm::StructType *structTy = nullptr); - -private: - llvm::GlobalVariable *createGlobal(llvm::Constant *initializer, - const llvm::Twine &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()); - resolveSelfReferences(GV); - return GV; - } - - void setGlobalInitializer(llvm::GlobalVariable *GV, - llvm::Constant *initializer) { - GV->setInitializer(initializer); - resolveSelfReferences(GV); - } - - void resolveSelfReferences(llvm::GlobalVariable *GV) { - for (auto &entry : SelfReferences) { - llvm::Constant *resolvedReference = - llvm::ConstantExpr::getInBoundsGetElementPtr( - GV->getValueType(), GV, entry.Indices); - entry.Dummy->replaceAllUsesWith(resolvedReference); - entry.Dummy->eraseFromParent(); - } - } -}; - -/// A helper class of ConstantInitBuilder, used for building constant -/// array initializers. -class ConstantArrayBuilder - : public ConstantInitBuilder::AggregateBuilder<ConstantArrayBuilder> { - llvm::Type *EltTy; - friend class ConstantInitBuilder; - template <class Impl> friend class ConstantInitBuilder::AggregateBuilder; - ConstantArrayBuilder(ConstantInitBuilder &builder, - AggregateBuilderBase *parent, llvm::Type *eltTy) - : AggregateBuilder(builder, parent), EltTy(eltTy) {} -public: - size_t size() const { - assert(!Finished); - assert(!Frozen); - assert(Begin <= getBuffer().size()); - return getBuffer().size() - Begin; - } - - bool empty() const { - return size() == 0; - } - -private: - /// Form an array constant from the values that have been added to this - /// builder. - llvm::Constant *finishImpl() { - markFinished(); - - auto &buffer = getBuffer(); - 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; - } -}; - -inline ConstantArrayBuilder -ConstantInitBuilder::beginArray(llvm::Type *eltTy) { - return ConstantArrayBuilder(*this, nullptr, eltTy); -} - -inline ConstantArrayBuilder -ConstantInitBuilder::AggregateBuilderBase::beginArray(llvm::Type *eltTy) { - return ConstantArrayBuilder(Builder, this, eltTy); -} - -/// A helper class of ConstantInitBuilder, used for building constant -/// struct initializers. -class ConstantStructBuilder - : public ConstantInitBuilder::AggregateBuilder<ConstantStructBuilder> { - llvm::StructType *Ty; - friend class ConstantInitBuilder; - template <class Impl> friend class ConstantInitBuilder::AggregateBuilder; - ConstantStructBuilder(ConstantInitBuilder &builder, - AggregateBuilderBase *parent, llvm::StructType *ty) - : AggregateBuilder(builder, parent), Ty(ty) {} - - /// Finish the struct. - llvm::Constant *finishImpl() { - markFinished(); - - auto &buffer = getBuffer(); - 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*/ false); - } - - buffer.erase(buffer.begin() + Begin, buffer.end()); - return constant; - } -}; - -inline ConstantStructBuilder -ConstantInitBuilder::beginStruct(llvm::StructType *structTy) { - return ConstantStructBuilder(*this, nullptr, structTy); -} - -inline ConstantStructBuilder -ConstantInitBuilder::AggregateBuilderBase::beginStruct( - llvm::StructType *structTy) { - return ConstantStructBuilder(Builder, this, structTy); -} - -} // end namespace CodeGen -} // end namespace clang - -#endif Added: cfe/trunk/lib/CodeGen/ConstantInitBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ConstantInitBuilder.cpp?rev=296806&view=auto ============================================================================== --- cfe/trunk/lib/CodeGen/ConstantInitBuilder.cpp (added) +++ cfe/trunk/lib/CodeGen/ConstantInitBuilder.cpp Thu Mar 2 14:04:19 2017 @@ -0,0 +1,131 @@ +//===--- ConstantInitBuilder.cpp - Global initializer builder -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines out-of-line routines for building initializers for +// global variables, in particular the kind of globals that are implicitly +// introduced by various language ABIs. +// +//===----------------------------------------------------------------------===// + +#include "clang/CodeGen/ConstantInitBuilder.h" +#include "CodeGenModule.h" + +using namespace clang; +using namespace CodeGen; + +llvm::GlobalVariable * +ConstantInitBuilder::createGlobal(llvm::Constant *initializer, + const llvm::Twine &name, + CharUnits alignment, + bool constant, + llvm::GlobalValue::LinkageTypes linkage, + unsigned addressSpace) { + auto GV = new llvm::GlobalVariable(CGM.getModule(), + initializer->getType(), + constant, + linkage, + initializer, + name, + /*insert before*/ nullptr, + llvm::GlobalValue::NotThreadLocal, + addressSpace); + GV->setAlignment(alignment.getQuantity()); + resolveSelfReferences(GV); + return GV; +} + +void ConstantInitBuilder::setGlobalInitializer(llvm::GlobalVariable *GV, + llvm::Constant *initializer) { + GV->setInitializer(initializer); + + if (!SelfReferences.empty()) + resolveSelfReferences(GV); +} + +void ConstantInitBuilder::resolveSelfReferences(llvm::GlobalVariable *GV) { + for (auto &entry : SelfReferences) { + llvm::Constant *resolvedReference = + llvm::ConstantExpr::getInBoundsGetElementPtr( + GV->getValueType(), GV, entry.Indices); + entry.Dummy->replaceAllUsesWith(resolvedReference); + entry.Dummy->eraseFromParent(); + } +} + +void ConstantInitBuilder::AggregateBuilderBase::addSize(CharUnits size) { + add(Builder.CGM.getSize(size)); +} + +llvm::Constant * +ConstantInitBuilder::AggregateBuilderBase::getAddrOfCurrentPosition( + llvm::Type *type) { + // Make a global variable. We will replace this with a GEP to this + // position after installing the initializer. + auto dummy = + new llvm::GlobalVariable(Builder.CGM.getModule(), type, true, + llvm::GlobalVariable::PrivateLinkage, + nullptr, ""); + Builder.SelfReferences.emplace_back(dummy); + auto &entry = Builder.SelfReferences.back(); + (void) getGEPIndicesToCurrentPosition(entry.Indices); + return dummy; +} + +void ConstantInitBuilder::AggregateBuilderBase::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.Int32Ty, 0)); + } + + assert(position >= Begin); + // We have to use i32 here because struct GEPs demand i32 indices. + // It's rather unlikely to matter in practice. + indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty, + position - Begin)); +} + +llvm::Constant *ConstantArrayBuilder::finishImpl() { + markFinished(); + + auto &buffer = getBuffer(); + 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; +} + +llvm::Constant *ConstantStructBuilder::finishImpl() { + markFinished(); + + auto &buffer = getBuffer(); + 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*/ false); + } + + buffer.erase(buffer.begin() + Begin, buffer.end()); + return constant; +} Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=296806&r1=296805&r2=296806&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original) +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Thu Mar 2 14:04:19 2017 @@ -24,8 +24,8 @@ #include "CGVTables.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" -#include "ConstantBuilder.h" #include "TargetInfo.h" +#include "clang/CodeGen/ConstantInitBuilder.h" #include "clang/AST/Mangle.h" #include "clang/AST/Type.h" #include "clang/AST/StmtCXX.h" Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=296806&r1=296805&r2=296806&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original) +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Thu Mar 2 14:04:19 2017 @@ -19,8 +19,8 @@ #include "CGVTables.h" #include "CodeGenModule.h" #include "CodeGenTypes.h" -#include "ConstantBuilder.h" #include "TargetInfo.h" +#include "clang/CodeGen/ConstantInitBuilder.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/StmtCXX.h" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits