r288313 - Teach ConstantBuilder how to emit a reference to the current position
John McCall via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 30 21:33:30 PST 2016
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();
+ }
}
};
More information about the cfe-commits
mailing list