changeset 1364:46f6365a50d7

Added IrTypeFunction and IrTypeDelegate and eliminated IrDType. This means the Type::ir field can be removed. It's the final part needed for the move to a slightly more sane type system. Now the whole thing just needs to be cleaned up :P Added -v-cg switch, which right now just prints "codegen: module.name (module/name.d)" to stdout, this can really help figuring out where, in some complex build command, things go wrong.
author Tomas Lindquist Olsen <tomas.l.olsen gmail com>
date Sat, 16 May 2009 18:19:52 +0200
parents b7c8506e1eed
children 65505c9d70f5
files dmd/dsymbol.h dmd/mars.h dmd/module.h dmd/mtype.h gen/cl_options.cpp gen/functions.cpp gen/functions.h gen/tocall.cpp gen/tollvm.cpp gen/tollvm.h gen/toobj.cpp gen/typinf.cpp ir/ir.h ir/irdtype.cpp ir/irdtype.h ir/irsymbol.h ir/irtype.cpp ir/irtype.h ir/irtypefunction.cpp ir/irtypefunction.h
diffstat 20 files changed, 148 insertions(+), 129 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/dsymbol.h	Sat May 16 14:22:23 2009 +0200
+++ b/dmd/dsymbol.h	Sat May 16 18:19:52 2009 +0200
@@ -82,10 +82,9 @@
 struct TYPE;
 #endif
 
-// llvm
 #if IN_LLVM
-struct Ir;
-struct IrSymbol;
+class Ir;
+class IrSymbol;
 namespace llvm
 {
     class Value;
--- a/dmd/mars.h	Sat May 16 14:22:23 2009 +0200
+++ b/dmd/mars.h	Sat May 16 18:19:52 2009 +0200
@@ -219,6 +219,7 @@
     OUTPUTFLAG output_o;
     bool llvmAnnotate;
     bool useInlineAsm;
+    bool verbose_cg;
 
     // target stuff
     const char* llvmArch;
--- a/dmd/module.h	Sat May 16 14:22:23 2009 +0200
+++ b/dmd/module.h	Sat May 16 18:19:52 2009 +0200
@@ -28,7 +28,7 @@
 
 // Back end
 #if IN_LLVM
-struct Ir;
+class Ir;
 struct DValue;
 typedef DValue elem;
 namespace llvm { class Module; }
--- a/dmd/mtype.h	Sat May 16 14:22:23 2009 +0200
+++ b/dmd/mtype.h	Sat May 16 18:19:52 2009 +0200
@@ -22,12 +22,9 @@
 #include "expression.h"
 
 #if IN_LLVM
-// llvm
-#include "../ir/irdtype.h"
 #include "../ir/irfuncty.h"
 namespace llvm { class Type; }
-struct Ir;
-
+class Ir;
 class IrType;
 #endif
 
@@ -284,10 +281,7 @@
     virtual TypeBasic *isTypeBasic();
 
 #if IN_LLVM
-    // LDC
-    IrDType ir;
     static Ir* sir;
-
     IrType* irtype;
 #endif
 };
--- a/gen/cl_options.cpp	Sat May 16 14:22:23 2009 +0200
+++ b/gen/cl_options.cpp	Sat May 16 18:19:52 2009 +0200
@@ -44,6 +44,11 @@
     cl::ZeroOrMore,
     cl::location(global.params.verbose));
 
+static cl::opt<bool, true> verbose_cg("v-cg",
+    cl::desc("Verbose codegen"),
+    cl::ZeroOrMore,
+    cl::location(global.params.verbose_cg));
+
 static cl::opt<bool, true> warnings("w",
     cl::desc("Enable warnings"),
     cl::ZeroOrMore,
--- a/gen/functions.cpp	Sat May 16 14:22:23 2009 +0200
+++ b/gen/functions.cpp	Sat May 16 18:19:52 2009 +0200
@@ -27,15 +27,10 @@
 
 const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype, bool ismain)
 {
-    // already built ?
-    if (type->ir.type != NULL) {
-        //assert(f->fty != NULL);
-        return llvm::cast<llvm::FunctionType>(type->ir.type->get());
-    }
-
     if (Logger::enabled())
         Logger::println("DtoFunctionType(%s)", type->toChars());
     LOG_SCOPE
+
     // sanity check
     assert(type->ty == Tfunction);
     TypeFunction* f = (TypeFunction*)type;
@@ -165,27 +160,6 @@
         lidx++;
     }
 
-    // If the function type was forward referenced by one of the parameter types,
-    // it has now been set.
-    if (f->ir.type) {
-        // Notify ABI that we won't be needing it for this function type anymore.
-        abi->doneWithFunctionType();
-        
-        // Some cleanup of memory we won't use
-        delete fty.ret;
-        delete fty.arg_sret;
-        delete fty.arg_this;
-        delete fty.arg_nest;
-        delete fty.arg_arguments;
-        delete fty.arg_argptr;
-        for (IrFuncTy::ArgIter It = fty.args.begin(), E = fty.args.end(); It != E; ++It) {
-            delete *It;
-        }
-
-        Logger::cout() << "Final function type: " << **f->ir.type << '\n';
-        return llvm::cast<LLFunctionType>(*f->ir.type);
-    }
-
     // Now we can modify f->fty safely.
     f->fty = fty;
 
@@ -219,7 +193,6 @@
     }
 
     llvm::FunctionType* functype = llvm::FunctionType::get(f->fty.ret->ltype, argtypes, f->fty.c_vararg);
-    f->ir.type = new llvm::PATypeHolder(functype);
 
 #if 0
     Logger::cout() << "Final function type: " << *functype << "\n";
@@ -232,11 +205,6 @@
 
 static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl)
 {
-    // type has already been resolved
-    if (fdecl->type->ir.type != 0) {
-        return llvm::cast<llvm::FunctionType>(fdecl->type->ir.type->get());
-    }
-
     TypeFunction* f = (TypeFunction*)fdecl->type;
     const llvm::FunctionType* fty = 0;
 
@@ -256,7 +224,6 @@
         fty = GET_INTRINSIC_DECL(vaend)->getFunctionType();
     assert(fty);
 
-    f->ir.type = new llvm::PATypeHolder(fty);
     return fty;
 }
 
@@ -264,10 +231,6 @@
 
 const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
 {
-    // type has already been resolved
-    if (fdecl->type->ir.type != 0)
-        return llvm::cast<llvm::FunctionType>(fdecl->type->ir.type->get());
-
     // handle for C vararg intrinsics
     if (fdecl->isVaIntrinsic())
         return DtoVaFunctionType(fdecl);
@@ -280,7 +243,7 @@
             dthis = ad->type;
             const LLType* thisty = DtoType(dthis);
             //Logger::cout() << "this llvm type: " << *thisty << '\n';
-            if (isaStruct(thisty) || (!gIR->structs.empty() && thisty == gIR->topstruct()->type->ir.type->get()))
+            if (ad->isStructDeclaration())
                 thisty = getPtrToType(thisty);
         }
         else {
@@ -326,6 +289,9 @@
         return; // ignore declaration completely
     }
 
+    if (fdecl->ir.resolved) return;
+    fdecl->ir.resolved = true;
+
     //printf("resolve function: %s\n", fdecl->toPrettyChars());
 
     if (fdecl->parent)
@@ -373,10 +339,7 @@
         }
     }
 
-    DtoFunctionType(fdecl);
-
-    if (fdecl->ir.resolved) return;
-    fdecl->ir.resolved = true;
+    DtoType(fdecl->type);
 
     Logger::println("DtoResolveFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars());
     LOG_SCOPE;
@@ -515,7 +478,6 @@
         func->setCallingConv(llvm::CallingConv::C);
 
     fdecl->ir.irFunc->func = func;
-    assert(llvm::isa<llvm::FunctionType>(f->ir.type->get()));
 
     // parameter attributes
     if (!fdecl->isIntrinsic()) {
@@ -646,7 +608,7 @@
 
     Type* t = fd->type->toBasetype();
     TypeFunction* f = (TypeFunction*)t;
-    assert(f->ir.type);
+    assert(f->irtype);
 
     llvm::Function* func = fd->ir.irFunc->func;
     const llvm::FunctionType* functype = func->getFunctionType();
--- a/gen/functions.h	Sat May 16 14:22:23 2009 +0200
+++ b/gen/functions.h	Sat May 16 18:19:52 2009 +0200
@@ -1,6 +1,18 @@
 #ifndef LDC_GEN_FUNCTIONS_H
 #define LDC_GEN_FUNCTIONS_H
 
+#include "mars.h"
+
+struct FuncDeclaration;
+struct Type;
+
+struct IRAsmBlock;
+
+namespace llvm
+{
+    class Value;
+}
+
 const llvm::FunctionType* DtoFunctionType(Type* t, Type* thistype, Type* nesttype, bool ismain = false);
 const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl);
 
@@ -14,6 +26,6 @@
 void emitABIReturnAsmStmt(IRAsmBlock* asmblock, Loc loc, FuncDeclaration* fdecl);
 
 DValue* DtoArgument(Argument* fnarg, Expression* argexp);
-void DtoVariadicArgument(Expression* argexp, LLValue* dst);
+void DtoVariadicArgument(Expression* argexp, llvm::Value* dst);
 
 #endif
--- a/gen/tocall.cpp	Sat May 16 14:22:23 2009 +0200
+++ b/gen/tocall.cpp	Sat May 16 18:19:52 2009 +0200
@@ -260,9 +260,8 @@
     // the callee D type
     Type* calleeType = fnval->getType();
 
-    // if the type has not yet been processed, do so now
-    if (calleeType->ir.type == NULL)
-        DtoType(calleeType);
+    // make sure the callee type has been processed
+    DtoType(calleeType);
 
     // get func value if any
     DFuncValue* dfnval = fnval->isFunc();
--- a/gen/tollvm.cpp	Sat May 16 14:22:23 2009 +0200
+++ b/gen/tollvm.cpp	Sat May 16 18:19:52 2009 +0200
@@ -24,6 +24,7 @@
 
 #include "ir/irtype.h"
 #include "ir/irtypeclass.h"
+#include "ir/irtypefunction.h"
 
 bool DtoIsPassedByRef(Type* type)
 {
@@ -131,27 +132,15 @@
     // functions
     case Tfunction:
     {
-        if (!t->ir.type || *t->ir.type == NULL) {
-            TypeFunction* tf = (TypeFunction*)t;
-            if (tf->funcdecl)
-                return DtoFunctionType(tf->funcdecl);
-            else
-                return DtoFunctionType(tf,NULL,NULL);
-        }
-        else {
-            return t->ir.type->get();
-        }
+        t->irtype = new IrTypeFunction(t);
+        return t->irtype->buildType();
     }
 
     // delegates
     case Tdelegate:
     {
-        if (!t->ir.type || *t->ir.type == NULL) {
-            return DtoDelegateType(t);
-        }
-        else {
-            return t->ir.type->get();
-        }
+        t->irtype = new IrTypeDelegate(t);
+        return t->irtype->buildType();
     }
 
     // typedefs
@@ -220,19 +209,6 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-const LLStructType* DtoDelegateType(Type* t)
-{
-    assert(t->ty == Tdelegate);
-    const LLType* i8ptr = getVoidPtrType();
-    const LLType* func = DtoFunctionType(t->nextOf(), NULL, Type::tvoid->pointerTo());
-    const LLType* funcptr = getPtrToType(func);
-    const LLStructType* dgtype = LLStructType::get(i8ptr, funcptr, NULL);
-    gIR->module->addTypeName(t->toChars(), dgtype);
-    return dgtype;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
 LLValue* DtoDelegateEquals(TOK op, LLValue* lhs, LLValue* rhs)
 {
     Logger::println("Doing delegate equality");
@@ -799,7 +775,7 @@
     // ClassInfo classinfo
     ClassDeclaration* cd2 = ClassDeclaration::classinfo;
     DtoResolveClass(cd2);
-    types.push_back(getPtrToType(cd2->type->ir.type->get()));
+    types.push_back(DtoType(cd2->type));
     // void*[] vtbl
     std::vector<const LLType*> vtbltypes;
     vtbltypes.push_back(DtoSize_t());
--- a/gen/tollvm.h	Sat May 16 14:22:23 2009 +0200
+++ b/gen/tollvm.h	Sat May 16 18:19:52 2009 +0200
@@ -26,7 +26,6 @@
 //const LLType* DtoStructTypeFromArguments(Arguments* arguments);
 
 // delegate helpers
-const LLStructType* DtoDelegateType(Type* t);
 LLValue* DtoDelegateEquals(TOK op, LLValue* lhs, LLValue* rhs);
 
 // return linkage type for symbol using the current ir state for context
--- a/gen/toobj.cpp	Sat May 16 14:22:23 2009 +0200
+++ b/gen/toobj.cpp	Sat May 16 18:19:52 2009 +0200
@@ -54,6 +54,7 @@
 
 #include "ir/irvar.h"
 #include "ir/irmodule.h"
+#include "ir/irtype.h"
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
@@ -80,7 +81,8 @@
     Logger::println("Generating module: %s\n", (md ? md->toChars() : toChars()));
     LOG_SCOPE;
 
-    //printf("codegen: %s\n", srcfile->toChars());
+    if (global.params.verbose_cg)
+        printf("codegen: %s (%s)\n", toPrettyChars(), srcfile->toChars());
 
     assert(!global.errors);
 
@@ -609,9 +611,9 @@
     }
 
     // moduleinfo llvm struct type
-    const llvm::StructType* moduleinfoTy = isaStruct(moduleinfo->type->ir.type->get());
+    const llvm::StructType* moduleinfoTy = isaStruct(moduleinfo->type->irtype->getPA());
     // classinfo llvm struct type
-    const llvm::StructType* classinfoTy = isaStruct(ClassDeclaration::classinfo->type->ir.type->get());
+    const llvm::StructType* classinfoTy = isaStruct(ClassDeclaration::classinfo->type->irtype->getPA());
 
     // initializer vector
     std::vector<LLConstant*> initVec;
--- a/gen/typinf.cpp	Sat May 16 14:22:23 2009 +0200
+++ b/gen/typinf.cpp	Sat May 16 18:19:52 2009 +0200
@@ -43,6 +43,7 @@
 #include "gen/metadata.h"
 
 #include "ir/irvar.h"
+#include "ir/irtype.h"
 
 /*******************************************
  * Get a canonicalized form of the TypeInfo for use with the internal
@@ -331,7 +332,7 @@
     // this is a declaration of a builtin __initZ var
     if (tid->tinfo->builtinTypeInfo()) {
         // fixup the global
-        const llvm::Type* rty = Type::typeinfo->type->ir.type->get();
+        const llvm::Type* rty = Type::typeinfo->type->irtype->getPA().get();
         llvm::cast<llvm::OpaqueType>(irg->type.get())->refineAbstractTypeTo(rty);
         LLGlobalVariable* g = isaGlobalVar(irg->value);
         g->setLinkage(llvm::GlobalValue::ExternalLinkage);
@@ -544,7 +545,7 @@
     base->codegen(Type::sir);
 
     // get type of typeinfo class
-    const LLStructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->irtype->getPA().get());
 
     // initializer vector
     std::vector<LLConstant*> sinits;
@@ -665,7 +666,7 @@
     ClassDeclaration* base = Type::typeinfostruct;
     base->codegen(Type::sir);
 
-    const LLStructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->irtype->getPA());
 
     // vtbl
     std::vector<LLConstant*> sinits;
@@ -691,7 +692,7 @@
     else
 #endif
     {
-        size_t cisize = getTypeStoreSize(tc->ir.type->get());
+        size_t cisize = getTypeStoreSize(tc->irtype->getPA().get());
         LLConstant* cicast = llvm::ConstantExpr::getBitCast(sd->ir.irStruct->getInitSymbol(), initpt);
         sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
     }
@@ -903,7 +904,7 @@
     base->codegen(Type::sir);
 
     // get type of typeinfo class
-    const LLStructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->irtype->getPA());
 
     // initializer vector
     std::vector<LLConstant*> sinits;
@@ -939,7 +940,7 @@
     base->codegen(Type::sir);
 
     // get type of typeinfo class
-    const LLStructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->irtype->getPA());
 
     // initializer vector
     std::vector<LLConstant*> sinits;
@@ -956,7 +957,7 @@
     size_t dim = tu->arguments->dim;
     std::vector<LLConstant*> arrInits;
 
-    const LLType* tiTy = Type::typeinfo->type->ir.type->get();
+    const LLType* tiTy = Type::typeinfo->type->irtype->getPA();
     tiTy = getPtrToType(tiTy);
 
     for (size_t i = 0; i < dim; i++)
--- a/ir/ir.h	Sat May 16 14:22:23 2009 +0200
+++ b/ir/ir.h	Sat May 16 18:19:52 2009 +0200
@@ -16,8 +16,9 @@
     virtual ~IrBase() {}
 };
 
-struct Ir
+class Ir
 {
+public:
     Ir();
 
     void setState(IRState* p)   { irs = p; }
--- a/ir/irdtype.cpp	Sat May 16 14:22:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-#include "gen/llvm.h"
-#include "ir/ir.h"
-#include "ir/irdtype.h"
-
-IrDType::IrDType()
-{
-    type = NULL;
-}
--- a/ir/irdtype.h	Sat May 16 14:22:23 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-#ifndef LDC_IR_IRDTYPE_H
-#define LDC_IR_IRDTYPE_H
-
-#include <set>
-
-namespace llvm {
-    class PATypeHolder;
-}
-
-struct IrDType
-{
-    IrDType();
-    llvm::PATypeHolder* type;
-};
-
-#endif
--- a/ir/irsymbol.h	Sat May 16 14:22:23 2009 +0200
+++ b/ir/irsymbol.h	Sat May 16 18:19:52 2009 +0200
@@ -4,8 +4,9 @@
 #include "ir/ir.h"
 
 /// Base class for all symbols.
-struct IrSymbol
+class IrSymbol
 {
+public:
     ///
     IrSymbol(Ir* ir) : ir(ir) {}
 
--- a/ir/irtype.cpp	Sat May 16 14:22:23 2009 +0200
+++ b/ir/irtype.cpp	Sat May 16 18:19:52 2009 +0200
@@ -18,8 +18,7 @@
 {
     assert(dt && "null D Type");
     assert(lt && "null LLVM Type");
-    assert(dt->ir.type == NULL && "llvm type (old one) already set");
-    dt->ir.type = &pa;
+    assert(dt->irtype == NULL && "already has IrType");
 }
 
 //////////////////////////////////////////////////////////////////////////////
--- a/ir/irtype.h	Sat May 16 14:22:23 2009 +0200
+++ b/ir/irtype.h	Sat May 16 18:19:52 2009 +0200
@@ -13,6 +13,7 @@
 class IrTypeArray;
 class IrTypeBasic;
 class IrTypeClass;
+class IrTypeFunction;
 class IrTypePointer;
 class IrTypeSArray;
 class IrTypeStruct;
@@ -35,6 +36,8 @@
     ///
     virtual IrTypeClass* isClass()      { return NULL; }
     ///
+    virtual IrTypeFunction* isFunction(){ return NULL; }
+    ///
     virtual IrTypePointer* isPointer()  { return NULL; }
     ///
     virtual IrTypeSArray* isSArray()    { return NULL; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/irtypefunction.cpp	Sat May 16 18:19:52 2009 +0200
@@ -0,0 +1,47 @@
+#include "llvm/DerivedTypes.h"
+#include "mtype.h"
+
+#include "gen/irstate.h"
+#include "gen/tollvm.h"
+#include "gen/functions.h"
+
+#include "ir/irtypefunction.h"
+
+IrTypeFunction::IrTypeFunction(Type * dt)
+:   IrType(dt, llvm::OpaqueType::get())
+{
+    irfty = NULL;
+}
+
+const llvm::Type * IrTypeFunction::buildType()
+{
+    const llvm::Type* T;
+    TypeFunction* tf = (TypeFunction*)dtype;
+    if (tf->funcdecl)
+        T = DtoFunctionType(tf->funcdecl);
+    else
+        T = DtoFunctionType(tf,NULL,NULL);
+
+    llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(T);
+    return pa.get();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+IrTypeDelegate::IrTypeDelegate(Type * dt)
+:   IrType(dt, llvm::OpaqueType::get())
+{
+}
+
+const llvm::Type * IrTypeDelegate::buildType()
+{
+    assert(dtype->ty == Tdelegate);
+    const LLType* i8ptr = getVoidPtrType();
+    const LLType* func = DtoFunctionType(dtype->nextOf(), NULL, Type::tvoid->pointerTo());
+    const LLType* funcptr = getPtrToType(func);
+    const LLStructType* dgtype = LLStructType::get(i8ptr, funcptr, NULL);
+    gIR->module->addTypeName(dtype->toChars(), dgtype);
+
+    llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(dgtype);
+    return pa.get();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/irtypefunction.h	Sat May 16 18:19:52 2009 +0200
@@ -0,0 +1,42 @@
+#ifndef __LDC_IR_IRTYPEFUNCTION_H__
+#define __LDC_IR_IRTYPEFUNCTION_H__
+
+#include "ir/irtype.h"
+
+class IrFuncTy;
+
+///
+class IrTypeFunction : public IrType
+{
+public:
+    ///
+    IrTypeFunction(Type* dt);
+
+    ///
+    IrTypeFunction* isFunction()  { return this; }
+
+    ///
+    const llvm::Type* buildType();
+
+    IrFuncTy* fty() { return irfty; }
+
+protected:
+    ///
+    IrFuncTy* irfty;
+};
+
+///
+class IrTypeDelegate : public IrType
+{
+public:
+    ///
+    IrTypeDelegate(Type* dt);
+
+    ///
+    IrTypeDelegate* isDelegate()    { return this; }
+
+    ///
+    const llvm::Type* buildType();
+};
+
+#endif