# HG changeset patch # User Tomas Lindquist Olsen # Date 1242490792 -7200 # Node ID 46f6365a50d7e4992fb588671f4c2d7f11f71d84 # Parent b7c8506e1eedc0799be8ec1797e8bc97e67a0c21 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. diff -r b7c8506e1eed -r 46f6365a50d7 dmd/dsymbol.h --- 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; diff -r b7c8506e1eed -r 46f6365a50d7 dmd/mars.h --- 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; diff -r b7c8506e1eed -r 46f6365a50d7 dmd/module.h --- 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; } diff -r b7c8506e1eed -r 46f6365a50d7 dmd/mtype.h --- 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 }; diff -r b7c8506e1eed -r 46f6365a50d7 gen/cl_options.cpp --- 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 verbose_cg("v-cg", + cl::desc("Verbose codegen"), + cl::ZeroOrMore, + cl::location(global.params.verbose_cg)); + static cl::opt warnings("w", cl::desc("Enable warnings"), cl::ZeroOrMore, diff -r b7c8506e1eed -r 46f6365a50d7 gen/functions.cpp --- 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(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(*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(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(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(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(); diff -r b7c8506e1eed -r 46f6365a50d7 gen/functions.h --- 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 diff -r b7c8506e1eed -r 46f6365a50d7 gen/tocall.cpp --- 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(); diff -r b7c8506e1eed -r 46f6365a50d7 gen/tollvm.cpp --- 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 vtbltypes; vtbltypes.push_back(DtoSize_t()); diff -r b7c8506e1eed -r 46f6365a50d7 gen/tollvm.h --- 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 diff -r b7c8506e1eed -r 46f6365a50d7 gen/toobj.cpp --- 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 initVec; diff -r b7c8506e1eed -r 46f6365a50d7 gen/typinf.cpp --- 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(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 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 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 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 sinits; @@ -956,7 +957,7 @@ size_t dim = tu->arguments->dim; std::vector 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++) diff -r b7c8506e1eed -r 46f6365a50d7 ir/ir.h --- 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; } diff -r b7c8506e1eed -r 46f6365a50d7 ir/irdtype.cpp --- 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; -} diff -r b7c8506e1eed -r 46f6365a50d7 ir/irdtype.h --- 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 - -namespace llvm { - class PATypeHolder; -} - -struct IrDType -{ - IrDType(); - llvm::PATypeHolder* type; -}; - -#endif diff -r b7c8506e1eed -r 46f6365a50d7 ir/irsymbol.h --- 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) {} diff -r b7c8506e1eed -r 46f6365a50d7 ir/irtype.cpp --- 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"); } ////////////////////////////////////////////////////////////////////////////// diff -r b7c8506e1eed -r 46f6365a50d7 ir/irtype.h --- 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; } diff -r b7c8506e1eed -r 46f6365a50d7 ir/irtypefunction.cpp --- /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(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(pa.get())->refineAbstractTypeTo(dgtype); + return pa.get(); +} diff -r b7c8506e1eed -r 46f6365a50d7 ir/irtypefunction.h --- /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