changeset 1374:e630ff79e10d

Cleaned up TypeInfo generation, still need to do TypeInfo_Struct/Tuple. Eventually do ClassInfo and ModuleInfo as well using same interface.
author Tomas Lindquist Olsen <tomas.l.olsen gmail com>
date Sun, 17 May 2009 03:10:55 +0200
parents 551b01341728
children 63f4afd01036
files gen/rttibuilder.cpp gen/rttibuilder.h gen/typinf.cpp
diffstat 3 files changed, 218 insertions(+), 237 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gen/rttibuilder.cpp	Sun May 17 03:10:55 2009 +0200
@@ -0,0 +1,93 @@
+#include "gen/llvm.h"
+
+#include "aggregate.h"
+#include "mtype.h"
+
+#include "gen/arrays.h"
+#include "gen/irstate.h"
+#include "gen/linkage.h"
+#include "gen/llvmhelpers.h"
+#include "gen/rttibuilder.h"
+#include "gen/tollvm.h"
+
+#include "ir/irstruct.h"
+
+TypeInfoBuilder::TypeInfoBuilder(ClassDeclaration* base_class)
+{
+    // make sure the base typeinfo class has been processed
+    base_class->codegen(Type::sir);
+
+    base = base_class;
+    basetype = (TypeClass*)base->type;
+
+    baseir = base->ir.irStruct;
+    assert(baseir && "no IrStruct for TypeInfo base class");
+
+    // just start with adding the vtbl
+    inits.push_back(baseir->getVtblSymbol());
+    // and monitor
+    push_null_vp();
+}
+
+void TypeInfoBuilder::push(llvm::Constant* C)
+{
+    inits.push_back(C);
+}
+
+void TypeInfoBuilder::push_null_vp()
+{
+    inits.push_back(getNullValue(getVoidPtrType()));
+}
+
+void TypeInfoBuilder::push_typeinfo(Type* t)
+{
+    inits.push_back(DtoTypeInfoOf(t, true));
+}
+
+void TypeInfoBuilder::push_classinfo(ClassDeclaration* cd)
+{
+    inits.push_back(cd->ir.irStruct->getClassInfoSymbol());
+}
+
+void TypeInfoBuilder::push_string(const char* str)
+{
+    inits.push_back(DtoConstString(str));
+}
+
+void TypeInfoBuilder::push_null_void_array()
+{
+    const llvm::Type* T = DtoType(Type::tvoid->arrayOf());
+    inits.push_back(getNullValue(T));
+}
+
+void TypeInfoBuilder::push_void_array(size_t dim, llvm::Constant* ptr)
+{
+    inits.push_back(DtoConstSlice(
+        DtoConstSize_t(dim),
+        DtoBitCast(ptr, getVoidPtrType())));
+}
+
+void TypeInfoBuilder::push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* sym)
+{
+    std::string initname(sym->mangle());
+    initname.append("13__defaultInitZ");
+
+    LLGlobalVariable* G = new llvm::GlobalVariable(
+        CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname, gIR->module);
+    G->setAlignment(valtype->alignsize());
+
+    size_t dim = getTypePaddedSize(CI->getType());
+    push_void_array(dim, G);
+}
+
+void TypeInfoBuilder::finalize(IrGlobal* tid)
+{
+    // create the inititalizer
+    LLConstant* tiInit = llvm::ConstantStruct::get(&inits[0], inits.size(), false);
+
+    // refine global type
+    llvm::cast<llvm::OpaqueType>(tid->type.get())->refineAbstractTypeTo(tiInit->getType());
+
+    // set the initializer
+    isaGlobalVar(tid->value)->setInitializer(tiInit);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gen/rttibuilder.h	Sun May 17 03:10:55 2009 +0200
@@ -0,0 +1,34 @@
+#ifndef __LDC_GEN_RTTIBUILDER_H__
+#define __LDC_GEN_RTTIBUILDER_H__
+
+#include "llvm/Constant.h"
+#include "llvm/ADT/SmallVector.h"
+
+struct ClassDeclaration;
+struct TypeClass;
+
+struct IrStruct;
+
+struct TypeInfoBuilder
+{
+    ClassDeclaration* base;
+    TypeClass* basetype;
+    IrStruct* baseir;
+
+    // 10 is enough for any D1 typeinfo
+    llvm::SmallVector<llvm::Constant*, 10> inits;
+
+    TypeInfoBuilder(ClassDeclaration* base_class);
+
+    void push(llvm::Constant* C);
+    void push_null_vp();
+    void push_typeinfo(Type* t);
+    void push_classinfo(ClassDeclaration* cd);
+    void push_string(const char* str);
+    void push_null_void_array();
+    void push_void_array(size_t dim, llvm::Constant* ptr);
+    void push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* sym);
+    void finalize(IrGlobal* tid);
+};
+
+#endif
--- a/gen/typinf.cpp	Sun May 17 02:22:21 2009 +0200
+++ b/gen/typinf.cpp	Sun May 17 03:10:55 2009 +0200
@@ -41,6 +41,7 @@
 #include "gen/classes.h"
 #include "gen/linkage.h"
 #include "gen/metadata.h"
+#include "gen/rttibuilder.h"
 
 #include "ir/irvar.h"
 #include "ir/irtype.h"
@@ -271,11 +272,11 @@
 
 //////////////////////////////////////////////////////////////////////////////
 //                             MAGIC   PLACE
+//                                (wut?)
 //////////////////////////////////////////////////////////////////////////////
 
 void DtoResolveTypeInfo(TypeInfoDeclaration* tid);
 void DtoDeclareTypeInfo(TypeInfoDeclaration* tid);
-void DtoConstInitTypeInfo(TypeInfoDeclaration* tid);
 
 void TypeInfoDeclaration::codegen(Ir*)
 {
@@ -334,37 +335,27 @@
     Logger::println("DtoDeclareTypeInfo(%s)", tid->toChars());
     LOG_SCOPE;
 
-    IrGlobal* irg = tid->ir.irGlobal;
-
-    std::string mangled(tid->mangle());
+    if (Logger::enabled())
+    {
+        std::string mangled(tid->mangle());
+        Logger::println("type = '%s'", tid->tinfo->toChars());
+        Logger::println("typeinfo mangle: %s", mangled.c_str());
+    }
 
-    Logger::println("type = '%s'", tid->tinfo->toChars());
-    Logger::println("typeinfo mangle: %s", mangled.c_str());
-
+    IrGlobal* irg = tid->ir.irGlobal;
     assert(irg->value != NULL);
 
     // this is a declaration of a builtin __initZ var
     if (tid->tinfo->builtinTypeInfo()) {
         // fixup the global
-        const llvm::Type* rty = Type::typeinfo->type->irtype->getPA().get();
+        const llvm::Type* rty = Type::typeinfo->type->irtype->getPA();
         llvm::cast<llvm::OpaqueType>(irg->type.get())->refineAbstractTypeTo(rty);
         LLGlobalVariable* g = isaGlobalVar(irg->value);
         g->setLinkage(llvm::GlobalValue::ExternalLinkage);
         return;
     }
 
-    // custom typedef
-    DtoConstInitTypeInfo(tid);
-}
-
-void DtoConstInitTypeInfo(TypeInfoDeclaration* tid)
-{
-    if (tid->ir.initialized) return;
-    tid->ir.initialized = true;
-
-    Logger::println("DtoConstInitTypeInfo(%s)", tid->toChars());
-    LOG_SCOPE;
-
+    // define custom typedef
     tid->llvmDefine();
 }
 
@@ -372,7 +363,7 @@
 
 void TypeInfoDeclaration::llvmDefine()
 {
-    assert(0 && "TypeInfoDeclaration::llvmDeclare");
+    assert(0 && "cannot generate generic typeinfo");
 }
 
 /* ========================================================================= */
@@ -382,54 +373,35 @@
     Logger::println("TypeInfoTypedefDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
-    ClassDeclaration* base = Type::typeinfotypedef;
-    base->codegen(Type::sir);
-
-    // vtbl
-    std::vector<LLConstant*> sinits;
-    sinits.push_back(base->ir.irStruct->getVtblSymbol());
-
-    // monitor
-    sinits.push_back(getNullPtr(getPtrToType(LLType::Int8Ty)));
+    TypeInfoBuilder b(Type::typeinfotypedef);
 
     assert(tinfo->ty == Ttypedef);
     TypeTypedef *tc = (TypeTypedef *)tinfo;
     TypedefDeclaration *sd = tc->sym;
 
     // TypeInfo base
-    sd->basetype = sd->basetype->merge(); // DMD does this!
-    LLConstant* castbase = DtoTypeInfoOf(sd->basetype, true);
-    sinits.push_back(castbase);
+    sd->basetype = sd->basetype->merge(); // dmd does it ... why?
+    b.push_typeinfo(sd->basetype);
 
     // char[] name
-    char *name = sd->toPrettyChars();
-    sinits.push_back(DtoConstString(name));
+    b.push_string(sd->toPrettyChars());
 
     // void[] init
-    const LLPointerType* initpt = getPtrToType(LLType::Int8Ty);
-    if (tinfo->isZeroInit() || !sd->init) // 0 initializer, or the same as the base type
+    // emit null array if we should use the basetype, or if the basetype
+    // uses default initialization.
+    if (!sd->init || tinfo->isZeroInit(0))
     {
-        sinits.push_back(DtoConstSlice(DtoConstSize_t(0), getNullPtr(initpt)));
+        b.push_null_void_array();
     }
+    // otherwise emit a void[] with the default initializer
     else
     {
-        LLConstant* ci = DtoConstInitializer(sd->loc, sd->basetype, sd->init);
-        std::string ciname(sd->mangle());
-        ciname.append("__init");
-        llvm::GlobalVariable* civar = new llvm::GlobalVariable(DtoType(sd->basetype),true,llvm::GlobalValue::InternalLinkage,ci,ciname,gIR->module);
-        LLConstant* cicast = llvm::ConstantExpr::getBitCast(civar, initpt);
-        size_t cisize = getTypeStoreSize(DtoType(sd->basetype));
-        sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
+        LLConstant* C = DtoConstInitializer(sd->loc, sd->basetype, sd->init);
+        b.push_void_array(C, sd->basetype, sd);
     }
 
-    // create the inititalizer
-    LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
-
-    // refine global type
-    llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
-
-    // set the initializer
-    isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
+    // finish
+    b.finalize(ir.irGlobal);
 }
 
 /* ========================================================================= */
@@ -439,86 +411,35 @@
     Logger::println("TypeInfoEnumDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
-    ClassDeclaration* base = Type::typeinfoenum;
-    base->codegen(Type::sir);
-
-    // vtbl
-    std::vector<LLConstant*> sinits;
-    sinits.push_back(base->ir.irStruct->getVtblSymbol());
-
-    // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
+    TypeInfoBuilder b(Type::typeinfoenum);
 
     assert(tinfo->ty == Tenum);
     TypeEnum *tc = (TypeEnum *)tinfo;
     EnumDeclaration *sd = tc->sym;
 
     // TypeInfo base
-    LLConstant* castbase = DtoTypeInfoOf(sd->memtype, true);
-    sinits.push_back(castbase);
+    b.push_typeinfo(sd->memtype);
 
     // char[] name
-    char *name = sd->toPrettyChars();
-    sinits.push_back(DtoConstString(name));
+    b.push_string(sd->toPrettyChars());
 
     // void[] init
-    const LLPointerType* initpt = getPtrToType(LLType::Int8Ty);
-    if (tinfo->isZeroInit() || !sd->defaultval) // 0 initializer, or the same as the base type
+    // emit void[] with the default initialier, the array is null if the default
+    // initializer is zero
+    if (!sd->defaultval || tinfo->isZeroInit(0))
     {
-        sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
+        b.push_null_void_array();
     }
+    // otherwise emit a void[] with the default initializer
     else
     {
-    #if DMDV2
-        assert(0 && "initializer not implemented");
-    #else
         const LLType* memty = DtoType(sd->memtype);
-        LLConstant* ci = llvm::ConstantInt::get(memty, sd->defaultval, !sd->memtype->isunsigned());
-        std::string ciname(sd->mangle());
-        ciname.append("__init");
-        llvm::GlobalVariable* civar = new llvm::GlobalVariable(memty,true,llvm::GlobalValue::InternalLinkage,ci,ciname,gIR->module);
-        LLConstant* cicast = llvm::ConstantExpr::getBitCast(civar, initpt);
-        size_t cisize = getTypeStoreSize(memty);
-        sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
-    #endif
+        LLConstant* C = llvm::ConstantInt::get(memty, sd->defaultval, !sd->memtype->isunsigned());
+        b.push_void_array(C, sd->memtype, sd);
     }
 
-    // create the inititalizer
-    LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
-
-    // refine global type
-    llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
-
-    // set the initializer
-    isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
-}
-
-/* ========================================================================= */
-
-static void LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd)
-{
-    ClassDeclaration* base = cd;
-    base->codegen(Type::sir);
-
-    // vtbl
-    std::vector<LLConstant*> sinits;
-    sinits.push_back(base->ir.irStruct->getVtblSymbol());
-
-    // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
-
-    // TypeInfo base
-    LLConstant* castbase = DtoTypeInfoOf(basetype, true);
-    sinits.push_back(castbase);
-
-    // create the inititalizer
-    LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
-
-    // refine global type
-    llvm::cast<llvm::OpaqueType>(tid->ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
-
-    // set the initializer
-    isaGlobalVar(tid->ir.irGlobal->value)->setInitializer(tiInit);
+    // finish
+    b.finalize(ir.irGlobal);
 }
 
 /* ========================================================================= */
@@ -528,10 +449,11 @@
     Logger::println("TypeInfoPointerDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
-    assert(tinfo->ty == Tpointer);
-    TypePointer *tc = (TypePointer *)tinfo;
-
-    LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfopointer);
+    TypeInfoBuilder b(Type::typeinfopointer);
+    // TypeInfo base
+    b.push_typeinfo(tinfo->nextOf());
+    // finish
+    b.finalize(ir.irGlobal);
 }
 
 /* ========================================================================= */
@@ -541,10 +463,11 @@
     Logger::println("TypeInfoArrayDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
-    assert(tinfo->ty == Tarray);
-    TypeDArray *tc = (TypeDArray *)tinfo;
-
-    LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfoarray);
+    TypeInfoBuilder b(Type::typeinfoarray);
+    // TypeInfo base
+    b.push_typeinfo(tinfo->nextOf());
+    // finish
+    b.finalize(ir.irGlobal);
 }
 
 /* ========================================================================= */
@@ -554,39 +477,19 @@
     Logger::println("TypeInfoStaticArrayDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
-    // init typeinfo class
-    ClassDeclaration* base = Type::typeinfostaticarray;
-    base->codegen(Type::sir);
-
-    // get type of typeinfo class
-    const LLStructType* stype = isaStruct(base->type->irtype->getPA().get());
+    assert(tinfo->ty == Tsarray);
+    TypeSArray *tc = (TypeSArray *)tinfo;
 
-    // initializer vector
-    std::vector<LLConstant*> sinits;
-    // first is always the vtable
-    sinits.push_back(base->ir.irStruct->getVtblSymbol());
-
-    // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
+    TypeInfoBuilder b(Type::typeinfostaticarray);
 
     // value typeinfo
-    assert(tinfo->ty == Tsarray);
-    TypeSArray *tc = (TypeSArray *)tinfo;
-    LLConstant* castbase = DtoTypeInfoOf(tc->next, true);
-    assert(castbase->getType() == stype->getElementType(2));
-    sinits.push_back(castbase);
+    b.push_typeinfo(tc->nextOf());
 
     // length
-    sinits.push_back(DtoConstSize_t(tc->dim->toInteger()));
-
-    // create the inititalizer
-    LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
+    b.push(DtoConstSize_t((size_t)tc->dim->toUInteger()));
 
-    // refine global type
-    llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
-
-    // set the initializer
-    isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
+    // finish
+    b.finalize(ir.irGlobal);
 }
 
 /* ========================================================================= */
@@ -596,38 +499,19 @@
     Logger::println("TypeInfoAssociativeArrayDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
-    // init typeinfo class
-    ClassDeclaration* base = Type::typeinfoassociativearray;
-    base->codegen(Type::sir);
-
-    // initializer vector
-    std::vector<LLConstant*> sinits;
-    // first is always the vtable
-    sinits.push_back(base->ir.irStruct->getVtblSymbol());
-
-    // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
-
-    // get type
     assert(tinfo->ty == Taarray);
     TypeAArray *tc = (TypeAArray *)tinfo;
 
+    TypeInfoBuilder b(Type::typeinfoassociativearray);
+
     // value typeinfo
-    LLConstant* castbase = DtoTypeInfoOf(tc->next, true);
-    sinits.push_back(castbase);
+    b.push_typeinfo(tc->nextOf());
 
     // key typeinfo
-    castbase = DtoTypeInfoOf(tc->index, true);
-    sinits.push_back(castbase);
-
-    // create the inititalizer
-    LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
+    b.push_typeinfo(tc->index);
 
-    // refine global type
-    llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
-
-    // set the initializer
-    isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
+    // finish
+    b.finalize(ir.irGlobal);
 }
 
 /* ========================================================================= */
@@ -637,10 +521,11 @@
     Logger::println("TypeInfoFunctionDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
-    assert(tinfo->ty == Tfunction);
-    TypeFunction *tc = (TypeFunction *)tinfo;
-
-    LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfofunction);
+    TypeInfoBuilder b(Type::typeinfofunction);
+    // TypeInfo base
+    b.push_typeinfo(tinfo->nextOf());
+    // finish
+    b.finalize(ir.irGlobal);
 }
 
 /* ========================================================================= */
@@ -651,9 +536,13 @@
     LOG_SCOPE;
 
     assert(tinfo->ty == Tdelegate);
-    TypeDelegate *tc = (TypeDelegate *)tinfo;
+    Type* ret_type = tinfo->nextOf()->nextOf();
 
-    LLVM_D_Define_TypeInfoBase(tc->nextOf()->nextOf(), this, Type::typeinfodelegate);
+    TypeInfoBuilder b(Type::typeinfodelegate);
+    // TypeInfo base
+    b.push_typeinfo(ret_type);
+    // finish
+    b.finalize(ir.irGlobal);
 }
 
 /* ========================================================================= */
@@ -874,30 +763,13 @@
     TypeClass *tc = (TypeClass *)tinfo;
     tc->sym->codegen(Type::sir);
 
-    // init typeinfo class
-    ClassDeclaration* base = Type::typeinfoclass;
-    assert(base);
-    base->codegen(Type::sir);
-
-    // initializer vector
-    std::vector<LLConstant*> sinits;
-    // first is always the vtable
-    sinits.push_back(base->ir.irStruct->getVtblSymbol());
+    TypeInfoBuilder b(Type::typeinfoclass);
 
-    // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
-
-    // get classinfo
-    sinits.push_back(tc->sym->ir.irStruct->getClassInfoSymbol());
+    // TypeInfo base
+    b.push_classinfo(tc->sym);
 
-    // create the inititalizer
-    LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
-
-    // refine global type
-    llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
-
-    // set the initializer
-    isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
+    // finish
+    b.finalize(ir.irGlobal);
 }
 
 /* ========================================================================= */
@@ -912,33 +784,13 @@
     TypeClass *tc = (TypeClass *)tinfo;
     tc->sym->codegen(Type::sir);
 
-    // init typeinfo class
-    ClassDeclaration* base = Type::typeinfointerface;
-    assert(base);
-    base->codegen(Type::sir);
-
-    // get type of typeinfo class
-    const LLStructType* stype = isaStruct(base->type->irtype->getPA());
-
-    // initializer vector
-    std::vector<LLConstant*> sinits;
-    // first is always the vtable
-    sinits.push_back(base->ir.irStruct->getVtblSymbol());
+    TypeInfoBuilder b(Type::typeinfointerface);
 
-    // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
-
-    // get classinfo
-    sinits.push_back(tc->sym->ir.irStruct->getClassInfoSymbol());
+    // TypeInfo base
+    b.push_classinfo(tc->sym);
 
-    // create the inititalizer
-    LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
-
-    // refine global type
-    llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
-
-    // set the initializer
-    isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
+    // finish
+    b.finalize(ir.irGlobal);
 }
 
 /* ========================================================================= */
@@ -1018,10 +870,11 @@
     Logger::println("TypeInfoConstDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
-    Type *tm = tinfo->mutableOf();
-    tm = tm->merge();
-
-    LLVM_D_Define_TypeInfoBase(tm, this, Type::typeinfoconst);
+    TypeInfoBuilder b(Type::typeinfoconst);
+    // TypeInfo base
+    b.push_typeinfo(tinfo->mutableOf()->merge());
+    // finish
+    b.finalize(ir.irGlobal);
 }
 
 /* ========================================================================= */
@@ -1031,10 +884,11 @@
     Logger::println("TypeInfoInvariantDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
-    Type *tm = tinfo->mutableOf();
-    tm = tm->merge();
-
-    LLVM_D_Define_TypeInfoBase(tm, this, Type::typeinfoinvariant);
+    TypeInfoBuilder b(Type::typeinfoinvariant);
+    // TypeInfo base
+    b.push_typeinfo(tinfo->mutableOf()->merge());
+    // finish
+    b.finalize(ir.irGlobal);
 }
 
 #endif