[pkg-d-commits] [ldc] 153/211: Build vtable type lazily

Matthias Klumpp mak at moszumanska.debian.org
Sun Apr 23 22:36:19 UTC 2017


This is an automated email from the git hooks/post-receive script.

mak pushed a commit to annotated tag v1.1.0
in repository ldc.

commit e1394fad5fb6a4a5c067fd70e8b7cf3f509750c5
Author: Martin <noone at nowhere.com>
Date:   Sat Nov 5 00:30:25 2016 +0100

    Build vtable type lazily
---
 gen/classes.cpp    |  1 +
 gen/toir.cpp       |  1 +
 ir/irclass.cpp     |  8 ++------
 ir/irtypeclass.cpp | 31 ++++++++++++++++++-------------
 ir/irtypeclass.h   |  2 +-
 5 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/gen/classes.cpp b/gen/classes.cpp
index 4ae4382..6fef7a6 100644
--- a/gen/classes.cpp
+++ b/gen/classes.cpp
@@ -390,6 +390,7 @@ LLValue *DtoVirtualFunctionPointer(DValue *inst, FuncDeclaration *fdecl,
 
   LLValue *funcval = vthis;
   // get the vtbl for objects
+  stripModifiers(inst->type->toBasetype())->ctype->isClass()->getVtblType(true);
   funcval = DtoGEPi(funcval, 0, 0);
   // load vtbl ptr
   funcval = DtoLoad(funcval);
diff --git a/gen/toir.cpp b/gen/toir.cpp
index 32ba359..22402bf 100644
--- a/gen/toir.cpp
+++ b/gen/toir.cpp
@@ -2664,6 +2664,7 @@ public:
       LLValue *val = DtoRVal(ex);
 
       // Get and load vtbl pointer.
+      stripModifiers(t)->ctype->isClass()->getVtblType(true);
       llvm::Value *vtbl = DtoLoad(DtoGEPi(val, 0, 0));
 
       // TypeInfo ptr is first vtbl entry.
diff --git a/ir/irclass.cpp b/ir/irclass.cpp
index 44965f8..aaab098 100644
--- a/ir/irclass.cpp
+++ b/ir/irclass.cpp
@@ -49,7 +49,7 @@ LLGlobalVariable *IrAggr::getVtblSymbol() {
   // create the vtblZ symbol
   auto initname = getMangledVTableSymbolName(aggrdecl);
 
-  LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtbl();
+  LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtblType(false);
 
   vtbl =
       getOrCreateGlobal(aggrdecl->loc, gIR->module, vtblTy, true,
@@ -224,7 +224,7 @@ LLConstant *IrAggr::getVtblInit() {
   }
 
   // build the constant struct
-  LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtbl();
+  LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtblType(true);
 #ifndef NDEBUG
   size_t nc = constants.size();
 
@@ -241,10 +241,6 @@ LLConstant *IrAggr::getVtblInit() {
 #endif
   constVtbl = LLConstantStruct::get(isaStruct(vtblTy), constants);
 
-  assert(constVtbl->getType() ==
-             stripModifiers(type)->ctype->isClass()->getVtbl() &&
-         "vtbl initializer type mismatch");
-
   return constVtbl;
 }
 
diff --git a/ir/irtypeclass.cpp b/ir/irtypeclass.cpp
index d4f0cd9..0e37d61 100644
--- a/ir/irtypeclass.cpp
+++ b/ir/irtypeclass.cpp
@@ -117,19 +117,6 @@ IrTypeClass *IrTypeClass::get(ClassDeclaration *cd) {
   isaStruct(t->type)->setBody(builder.defaultTypes(), t->packed);
   t->varGEPIndices = builder.varGEPIndices();
 
-  // set vtbl type body
-  FuncDeclarations vtbl;
-  vtbl.reserve(cd->vtbl.dim);
-  if (!cd->isCPPclass())
-    vtbl.push(nullptr);
-  for (size_t i = cd->vtblOffset(); i < cd->vtbl.dim; ++i) {
-    FuncDeclaration *fd = cd->vtbl[i]->isFuncDeclaration();
-    assert(fd);
-    vtbl.push(fd);
-  }
-  Type* first = cd->isCPPclass() ? nullptr : Type::typeinfoclass->type;
-  t->vtbl_type->setBody(t->buildVtblType(first, &vtbl));
-
   IF_LOG Logger::cout() << "class type: " << *t->type << std::endl;
 
   return t;
@@ -194,6 +181,24 @@ llvm::Type *IrTypeClass::getLLType() { return llvm::PointerType::get(type, 0); }
 
 llvm::Type *IrTypeClass::getMemoryLLType() { return type; }
 
+llvm::StructType *IrTypeClass::getVtblType(bool notOpaque) {
+  if (notOpaque && vtbl_type->isOpaque()) {
+    FuncDeclarations vtbl;
+    vtbl.reserve(cd->vtbl.dim);
+    if (!cd->isCPPclass())
+      vtbl.push(nullptr);
+    for (size_t i = cd->vtblOffset(); i < cd->vtbl.dim; ++i) {
+      FuncDeclaration *fd = cd->vtbl[i]->isFuncDeclaration();
+      assert(fd);
+      vtbl.push(fd);
+    }
+    Type* first = cd->isCPPclass() ? nullptr : Type::typeinfoclass->type;
+    vtbl_type->setBody(buildVtblType(first, &vtbl));
+  }
+
+  return vtbl_type;
+}
+
 size_t IrTypeClass::getInterfaceIndex(ClassDeclaration *inter) {
   auto it = interfaceMap.find(inter);
   if (it == interfaceMap.end()) {
diff --git a/ir/irtypeclass.h b/ir/irtypeclass.h
index 081cfeb..829ad83 100644
--- a/ir/irtypeclass.h
+++ b/ir/irtypeclass.h
@@ -37,7 +37,7 @@ public:
   llvm::Type *getMemoryLLType();
 
   /// Returns the vtable type for this class.
-  llvm::Type *getVtbl() { return vtbl_type; }
+  llvm::StructType *getVtblType(bool notOpaque);
 
   /// Get index to interface implementation.
   /// Returns the index of a specific interface implementation in this

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git



More information about the pkg-d-commits mailing list