diff gen/tollvm.cpp @ 102:027b8d8b71ec trunk

[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up. Basically it tries to do the following in order: Resolve types, Declare symbols, Create constant initializers, Apply initializers, Generate functions bodies. ClassInfo is now has the most useful(biased?) members working. Probably other stuf...
author lindquist
date Sun, 18 Nov 2007 06:52:57 +0100
parents 5071469303d4
children 855adfdb8d38
line wrap: on
line diff
--- a/gen/tollvm.cpp	Fri Nov 16 10:01:24 2007 +0100
+++ b/gen/tollvm.cpp	Sun Nov 18 06:52:57 2007 +0100
@@ -17,6 +17,7 @@
 #include "gen/functions.h"
 #include "gen/structs.h"
 #include "gen/classes.h"
+#include "gen/typeinf.h"
 
 bool DtoIsPassedByRef(Type* type)
 {
@@ -114,7 +115,7 @@
             // forward declaration
             TypeStruct* ts = (TypeStruct*)t;
             assert(ts->sym);
-            ts->sym->toObjFile();
+            DtoResolveDsymbol(ts->sym);
         }
         return t->llvmType->get();
     }
@@ -137,7 +138,7 @@
             // forward declaration
             TypeClass* tc = (TypeClass*)t;
             assert(tc->sym);
-            tc->sym->toObjFile();
+            DtoResolveDsymbol(tc->sym);
         }
         return llvm::PointerType::get(t->llvmType->get());
     }
@@ -654,7 +655,17 @@
     llargs.resize(3);
     llargs[0] = cond ? DtoBoolean(cond) : llvm::ConstantInt::getFalse();
     llargs[1] = DtoConstUint(loc->linnum);
-    llargs[2] = msg ? msg->getRVal() : llvm::Constant::getNullValue(fnt->getParamType(2));
+    if (msg)
+        llargs[2] = msg->getRVal();
+    else {
+        llvm::Constant* c = DtoConstSlice(DtoConstSize_t(0), DtoConstNullPtr(llvm::Type::Int8Ty));
+        static llvm::AllocaInst* alloc = 0;
+        if (!alloc || alloc->getParent()->getParent() != gIR->func()->func) {
+            alloc = new llvm::AllocaInst(c->getType(), "assertnullparam", gIR->topallocapoint());
+            DtoSetArrayToNull(alloc);
+        }
+        llargs[2] = alloc;
+    }
 
     assert(fn);
     llvm::CallInst* call = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
@@ -861,7 +872,7 @@
         }
         // null
         else if (rhs->isNull()) {
-            DtoNullArray(lhs->getLVal());
+            DtoSetArrayToNull(lhs->getLVal());
         }
         // reference assignment
         else {
@@ -1030,87 +1041,6 @@
     return new DImValue(_to, rval);
 }
 
-DValue* DtoCastArray(DValue* u, Type* to)
-{
-    const llvm::Type* tolltype = DtoType(to);
-
-    Type* totype = DtoDType(to);
-    Type* fromtype = DtoDType(u->getType());
-    assert(fromtype->ty == Tarray || fromtype->ty == Tsarray);
-
-    llvm::Value* rval;
-    llvm::Value* rval2;
-    bool isslice = false;
-
-    Logger::cout() << "from array or sarray" << '\n';
-    if (totype->ty == Tpointer) {
-        Logger::cout() << "to pointer" << '\n';
-        assert(fromtype->next == totype->next || totype->next->ty == Tvoid);
-        llvm::Value* ptr = DtoGEPi(u->getRVal(),0,1,"tmp",gIR->scopebb());
-        rval = new llvm::LoadInst(ptr, "tmp", gIR->scopebb());
-        if (fromtype->next != totype->next)
-            rval = gIR->ir->CreateBitCast(rval, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp");
-    }
-    else if (totype->ty == Tarray) {
-        Logger::cout() << "to array" << '\n';
-        const llvm::Type* ptrty = DtoType(totype->next);
-        if (ptrty == llvm::Type::VoidTy)
-            ptrty = llvm::Type::Int8Ty;
-        ptrty = llvm::PointerType::get(ptrty);
-
-        const llvm::Type* ety = DtoType(fromtype->next);
-        if (ety == llvm::Type::VoidTy)
-            ety = llvm::Type::Int8Ty;
-
-        if (DSliceValue* usl = u->isSlice()) {
-            Logger::println("from slice");
-            rval = new llvm::BitCastInst(usl->ptr, ptrty, "tmp", gIR->scopebb());
-            if (fromtype->next->size() == totype->next->size())
-                rval2 = usl->len;
-            else
-                rval2 = DtoArrayCastLength(usl->len, ety, ptrty->getContainedType(0));
-        }
-        else {
-            llvm::Value* uval = u->getRVal();
-            if (fromtype->ty == Tsarray) {
-                Logger::cout() << "uvalTy = " << *uval->getType() << '\n';
-                assert(isaPointer(uval->getType()));
-                const llvm::ArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
-                rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false);
-                rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
-                rval = new llvm::BitCastInst(uval, ptrty, "tmp", gIR->scopebb());
-            }
-            else {
-                llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
-                llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
-                rval2 = DtoGEP(uval,zero,zero,"tmp",gIR->scopebb());
-                rval2 = new llvm::LoadInst(rval2, "tmp", gIR->scopebb());
-                rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
-
-                rval = DtoGEP(uval,zero,one,"tmp",gIR->scopebb());
-                rval = new llvm::LoadInst(rval, "tmp", gIR->scopebb());
-                //Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n';
-                rval = new llvm::BitCastInst(rval, ptrty, "tmp", gIR->scopebb());
-            }
-        }
-        isslice = true;
-    }
-    else if (totype->ty == Tsarray) {
-        Logger::cout() << "to sarray" << '\n';
-        assert(0);
-    }
-    else {
-        assert(0);
-    }
-
-    if (isslice) {
-        Logger::println("isslice");
-        return new DSliceValue(to, rval2, rval);
-    }
-
-    return new DImValue(to, rval);
-}
-
 DValue* DtoCast(DValue* val, Type* to)
 {
     Type* fromtype = DtoDType(val->getType());
@@ -1180,6 +1110,15 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
+llvm::Constant* DtoConstNullPtr(const llvm::Type* t)
+{
+    return llvm::ConstantPointerNull::get(
+        llvm::PointerType::get(t)
+    );
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
 void DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes)
 {
     assert(dst->getType() == src->getType());
@@ -1321,20 +1260,45 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-void DtoDefineDsymbol(Dsymbol* dsym)
+void DtoResolveDsymbol(Dsymbol* dsym)
 {
     if (StructDeclaration* sd = dsym->isStructDeclaration()) {
-        DtoDefineStruct(sd);
+        DtoResolveStruct(sd);
     }
     else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
-        DtoDefineClass(cd);
+        DtoResolveClass(cd);
     }
     else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
-        DtoDefineFunc(fd);
+        DtoResolveFunction(fd);
+    }
+    else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
+        DtoResolveTypeInfo(fd);
     }
     else {
     error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
-    assert(0 && "unsupported dsymbol for DtoDefineDsymbol");
+    assert(0 && "unsupported dsymbol for DtoResolveDsymbol");
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoDeclareDsymbol(Dsymbol* dsym)
+{
+    if (StructDeclaration* sd = dsym->isStructDeclaration()) {
+        DtoDeclareStruct(sd);
+    }
+    else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
+        DtoDeclareClass(cd);
+    }
+    else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
+        DtoDeclareFunction(fd);
+    }
+    else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
+        DtoDeclareTypeInfo(fd);
+    }
+    else {
+    error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
+    assert(0 && "unsupported dsymbol for DtoDeclareDsymbol");
     }
 }
 
@@ -1348,12 +1312,37 @@
     else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
         DtoConstInitClass(cd);
     }
+    else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
+        DtoConstInitTypeInfo(fd);
+    }
     else if (VarDeclaration* vd = dsym->isVarDeclaration()) {
         DtoConstInitGlobal(vd);
     }
     else {
     error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
-    assert(0 && "unsupported dsymbol for DtoInitDsymbol");
+    assert(0 && "unsupported dsymbol for DtoConstInitDsymbol");
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoDefineDsymbol(Dsymbol* dsym)
+{
+    if (StructDeclaration* sd = dsym->isStructDeclaration()) {
+        DtoDefineStruct(sd);
+    }
+    else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
+        DtoDefineClass(cd);
+    }
+    else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
+        DtoDefineFunc(fd);
+    }
+    else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
+        DtoDefineTypeInfo(fd);
+    }
+    else {
+    error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
+    assert(0 && "unsupported dsymbol for DtoDefineDsymbol");
     }
 }
 
@@ -1361,11 +1350,11 @@
 
 void DtoConstInitGlobal(VarDeclaration* vd)
 {
-    Logger::println("DtoConstInitGlobal(%s)", vd->toChars());
-    LOG_SCOPE;
+    if (vd->llvmInitialized) return;
+    vd->llvmInitialized = gIR->dmodule;
 
-    if (vd->llvmDModule) return;
-    vd->llvmDModule = gIR->dmodule;
+    Logger::println("* DtoConstInitGlobal(%s)", vd->toChars());
+    LOG_SCOPE;
 
     bool emitRTstaticInit = false;
 
@@ -1428,3 +1417,100 @@
     if (emitRTstaticInit)
         DtoLazyStaticInit(istempl, gvar, vd->init, t);
 }
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoEmptyResolveList()
+{
+    //Logger::println("DtoEmptyResolveList()");
+    Dsymbol* dsym;
+    while (!gIR->resolveList.empty()) {
+        dsym = gIR->resolveList.front();
+        gIR->resolveList.pop_front();
+        DtoResolveDsymbol(dsym);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoEmptyDeclareList()
+{
+    //Logger::println("DtoEmptyDeclareList()");
+    Dsymbol* dsym;
+    while (!gIR->declareList.empty()) {
+        dsym = gIR->declareList.front();
+        gIR->declareList.pop_front();
+        DtoDeclareDsymbol(dsym);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoEmptyConstInitList()
+{
+    //Logger::println("DtoEmptyConstInitList()");
+    Dsymbol* dsym;
+    while (!gIR->constInitList.empty()) {
+        dsym = gIR->constInitList.front();
+        gIR->constInitList.pop_front();
+        DtoConstInitDsymbol(dsym);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoEmptyDefineList()
+{
+    //Logger::println("DtoEmptyDefineList()");
+    Dsymbol* dsym;
+    while (!gIR->defineList.empty()) {
+        dsym = gIR->defineList.front();
+        gIR->defineList.pop_front();
+        DtoDefineDsymbol(dsym);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoForceDeclareDsymbol(Dsymbol* dsym)
+{
+    if (dsym->llvmDeclared) return;
+    Logger::println("DtoForceDeclareDsymbol(%s)", dsym->toChars());
+    LOG_SCOPE;
+    DtoResolveDsymbol(dsym);
+
+    DtoEmptyResolveList();
+
+    DtoDeclareDsymbol(dsym);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoForceConstInitDsymbol(Dsymbol* dsym)
+{
+    if (dsym->llvmInitialized) return;
+    Logger::println("DtoForceConstInitDsymbol(%s)", dsym->toChars());
+    LOG_SCOPE;
+    DtoResolveDsymbol(dsym);
+
+    DtoEmptyResolveList();
+    DtoEmptyDeclareList();
+
+    DtoConstInitDsymbol(dsym);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoForceDefineDsymbol(Dsymbol* dsym)
+{
+    if (dsym->llvmDefined) return;
+    Logger::println("DtoForceDefineDsymbol(%s)", dsym->toChars());
+    LOG_SCOPE;
+    DtoResolveDsymbol(dsym);
+
+    DtoEmptyResolveList();
+    DtoEmptyDeclareList();
+    DtoEmptyConstInitList();
+
+    DtoDefineDsymbol(dsym);
+}