Author: rjmccall Date: Wed Nov 30 23:33:30 2016 New Revision: 288313 URL: http://llvm.org/viewvc/llvm-project?rev=288313&view=rev Log: Teach ConstantBuilder how to emit a reference to the current position that will be filled in when the initializer is set.
Modified: cfe/trunk/lib/CodeGen/ConstantBuilder.h Modified: cfe/trunk/lib/CodeGen/ConstantBuilder.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ConstantBuilder.h?rev=288313&r1=288312&r2=288313&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/ConstantBuilder.h (original) +++ cfe/trunk/lib/CodeGen/ConstantBuilder.h Wed Nov 30 23:33:30 2016 @@ -21,6 +21,8 @@ #include "CodeGenModule.h" +#include <vector> + namespace clang { namespace CodeGen { @@ -47,8 +49,15 @@ class ConstantArrayBuilder; /// 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: @@ -201,6 +210,25 @@ public: 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()); @@ -294,12 +322,24 @@ private: 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(); + } } }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits