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