Mercurial > projects > ldc
diff gen/toir.cpp @ 131:5825d48b27d1 trunk
[svn r135] * Merged DMD 1.025 *
* Fixed a minor linking order mishap *
* Added an command line option -annotate *
* Fixed some problems with running optimizations *
* Added std.stdio and dependencies to lphobos (still not 100% working, but compiles and links) *
* Fixed problems with passing aggregate types to variadic functions *
* Added initial code towards full GC support, currently based on malloc and friends, not all the runtime calls the GC yet for memory *
* Fixed problems with resolving nested function context pointers for some heavily nested cases *
* Redid function argument passing + other minor code cleanups, still lots to do on this end... *
author | lindquist |
---|---|
date | Fri, 04 Jan 2008 01:38:42 +0100 |
parents | 8096ba7082db |
children | 1700239cab2e |
line wrap: on
line diff
--- a/gen/toir.cpp Fri Dec 28 23:52:40 2007 +0100 +++ b/gen/toir.cpp Fri Jan 04 01:38:42 2008 +0100 @@ -31,6 +31,7 @@ #include "gen/complex.h" #include "gen/dvalue.h" #include "gen/aa.h" +#include "gen/functions.h" ////////////////////////////////////////////////////////////////////////////////////////// @@ -51,6 +52,9 @@ } else { + if (global.params.llvmAnnotate) + DtoAnnotation(toChars()); + Logger::println("vdtype = %s", vd->type->toChars()); // referenced by nested delegate? if (vd->nestedref) { @@ -600,7 +604,16 @@ } DtoAssign(l, res); - return l; + // used as lvalue :/ + if (p->topexp() && p->topexp()->e1 == this) + { + assert(!l->isLRValue()); + return l; + } + else + { + return res; + } } ////////////////////////////////////////////////////////////////////////////////////////// @@ -650,6 +663,7 @@ DValue* res; if (DtoDType(e1->type)->ty == Tpointer) { + Logger::println("ptr"); llvm::Value* tmp = r->getRVal(); llvm::Value* zero = llvm::ConstantInt::get(tmp->getType(),0,false); tmp = llvm::BinaryOperator::createSub(zero,tmp,"tmp",p->scopebb()); @@ -657,9 +671,11 @@ res = new DImValue(type, tmp); } else if (t->iscomplex()) { + Logger::println("complex"); res = DtoComplexSub(type, l, r); } else { + Logger::println("basic"); res = DtoBinSub(l,r); } DtoAssign(l, res); @@ -904,7 +920,7 @@ Logger::cout() << "what are we calling? : " << *funcval << '\n'; } assert(llfnty); - Logger::cout() << "Function LLVM type: " << *llfnty << '\n'; + //Logger::cout() << "Function LLVM type: " << *llfnty << '\n'; // argument handling llvm::FunctionType::param_iterator argiter = llfnty->param_begin(); @@ -969,7 +985,7 @@ // nested call else if (dfn && dfn->func && dfn->func->isNested()) { Logger::println("Nested Call"); - llvm::Value* contextptr = p->func()->decl->llvmNested; + llvm::Value* contextptr = DtoNestedContext(dfn->func->toParent2()->isFuncDeclaration()); if (!contextptr) contextptr = llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); llargs[j] = DtoBitCast(contextptr, llvm::PointerType::get(llvm::Type::Int8Ty)); @@ -978,7 +994,8 @@ } // va arg function special argument passing - if (va_magic) { + if (va_magic) + { size_t n = va_intrinsic ? arguments->dim : 1; for (int i=0; i<n; i++,j++) { @@ -989,7 +1006,9 @@ } } // regular arguments - else { + else + { + // d variadic function? if (tf->linkage == LINKd && tf->varargs == 1) { Logger::println("doing d-style variadic arguments"); @@ -997,53 +1016,71 @@ size_t nimplicit = j; std::vector<const llvm::Type*> vtypes; - std::vector<llvm::Value*> vvalues; std::vector<llvm::Value*> vtypeinfos; - for (int i=0; i<arguments->dim; i++) { - Argument* fnarg = Argument::getNth(tf->parameters, i); + // build struct with argument types + for (int i=0; i<arguments->dim; i++) + { + Expression* argexp = (Expression*)arguments->data[i]; + vtypes.push_back(DtoType(argexp->type)); + } + const llvm::StructType* vtype = llvm::StructType::get(vtypes); + Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n'; + llvm::Value* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint()); + + // store arguments in the struct + for (int i=0; i<arguments->dim; i++) + { Expression* argexp = (Expression*)arguments->data[i]; - vvalues.push_back(DtoArgument(NULL, fnarg, argexp)); - vtypes.push_back(vvalues.back()->getType()); - + if (global.params.llvmAnnotate) + DtoAnnotation(argexp->toChars()); + DtoVariadicArgument(argexp, DtoGEPi(mem,0,i,"tmp")); + } + + // build type info array + assert(Type::typeinfo->llvmConstInit); + const llvm::Type* typeinfotype = llvm::PointerType::get(Type::typeinfo->llvmConstInit->getType()); + Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n'; + const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements()); + + llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint()); + for (int i=0; i<arguments->dim; i++) + { + Expression* argexp = (Expression*)arguments->data[i]; TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration(); DtoForceDeclareDsymbol(tidecl); assert(tidecl->llvmValue); vtypeinfos.push_back(tidecl->llvmValue); - } - - const llvm::StructType* vtype = llvm::StructType::get(vtypes); - llvm::Value* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint()); - for (unsigned i=0; i<vtype->getNumElements(); ++i) - p->ir->CreateStore(vvalues[i], DtoGEPi(mem,0,i,"tmp")); - - //llvm::Constant* typeinfoparam = llvm::ConstantPointerNull::get(isaPointer(llfnty->getParamType(j))); - assert(Type::typeinfo->llvmConstInit); - const llvm::Type* typeinfotype = llvm::PointerType::get(Type::typeinfo->llvmConstInit->getType()); - Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n'; - const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements()); - llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint()); - for (unsigned i=0; i<vtype->getNumElements(); ++i) { llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[i], typeinfotype, "tmp"); p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,i,"tmp")); } + // put data in d-array llvm::Value* typeinfoarrayparam = new llvm::AllocaInst(llfnty->getParamType(j)->getContainedType(0),"_arguments_array",p->topallocapoint()); p->ir->CreateStore(DtoConstSize_t(vtype->getNumElements()), DtoGEPi(typeinfoarrayparam,0,0,"tmp")); llvm::Value* casttypeinfomem = p->ir->CreateBitCast(typeinfomem, llvm::PointerType::get(typeinfotype), "tmp"); p->ir->CreateStore(casttypeinfomem, DtoGEPi(typeinfoarrayparam,0,1,"tmp")); + // specify arguments llargs[j] = typeinfoarrayparam;; j++; llargs[j] = p->ir->CreateBitCast(mem, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp"); j++; llargs.resize(nimplicit+2); } + // normal function else { Logger::println("doing normal arguments"); for (int i=0; i<arguments->dim; i++,j++) { Argument* fnarg = Argument::getNth(tf->parameters, i); - llargs[j] = DtoArgument(llfnty->getParamType(j), fnarg, (Expression*)arguments->data[i]); + if (global.params.llvmAnnotate) + DtoAnnotation(((Expression*)arguments->data[i])->toChars()); + DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); + llargs[j] = argval->getRVal(); + if (fnarg && llargs[j]->getType() != llfnty->getParamType(j)) { + llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j)); + } + // this hack is necessary :/ if (dfn && dfn->func && dfn->func->llvmRunTimeHack) { if (llfnty->getParamType(j) != NULL) { @@ -1850,7 +1887,11 @@ { Expression* ex = (Expression*)arguments->data[i]; Argument* fnarg = Argument::getNth(tf->parameters, i); - llvm::Value* a = DtoArgument(fn->getFunctionType()->getParamType(i+1), fnarg, ex); + DValue* argval = DtoArgument(fnarg, ex); + llvm::Value* a = argval->getRVal(); + const llvm::Type* aty = fn->getFunctionType()->getParamType(i+1); + if (a->getType() != aty) // this param might have type mismatch + a = DtoBitCast(a, aty); ctorargs.push_back(a); } llvm::CallInst* call = new llvm::CallInst(fn, ctorargs.begin(), ctorargs.end(), "tmp", p->scopebb()); @@ -2895,7 +2936,7 @@ AsmStatement::AsmStatement(Loc loc, Token *tokens) : Statement(loc) { - Logger::println("Ignoring AsmStatement"); + this->tokens = tokens; } Statement *AsmStatement::syntaxCopy() {