Mercurial > projects > ldc
diff gen/arrays.cpp @ 98:6789050b5ad1 trunk
[svn r102] Further delayed emission of function bodies to avoid problems with circular-forward-references.
Now uses the DMD _adEq(void[], void[], TypeInfo) runtime function for array equality comparison.
author | lindquist |
---|---|
date | Wed, 14 Nov 2007 23:39:10 +0100 |
parents | ce7ed8f59b99 |
children | a676a7743642 |
line wrap: on
line diff
--- a/gen/arrays.cpp Wed Nov 14 20:18:01 2007 +0100 +++ b/gen/arrays.cpp Wed Nov 14 23:39:10 2007 +0100 @@ -546,93 +546,60 @@ } ////////////////////////////////////////////////////////////////////////////////////////// -llvm::Value* DtoStaticArrayCompare(TOK op, llvm::Value* l, llvm::Value* r) + +llvm::Value* DtoArrayEquals(TOK op, DValue* l, DValue* r) { - const char* fname; - if (op == TOKequal) - fname = "_d_static_array_eq"; - else if (op == TOKnotequal) - fname = "_d_static_array_neq"; - else - assert(0); - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); - assert(fn); - - assert(l->getType() == r->getType()); - assert(isaPointer(l->getType())); - const llvm::Type* arrty = l->getType()->getContainedType(0); - assert(isaArray(arrty)); - - llvm::Value* ll = new llvm::BitCastInst(l, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp", gIR->scopebb()); - llvm::Value* rr = new llvm::BitCastInst(r, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp", gIR->scopebb()); - llvm::Value* n = llvm::ConstantInt::get(DtoSize_t(),gTargetData->getTypeSize(arrty),false); - - std::vector<llvm::Value*> args; - args.push_back(ll); - args.push_back(rr); - args.push_back(n); - return new llvm::CallInst(fn, args.begin(), args.end(), "tmp", gIR->scopebb()); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -llvm::Value* DtoDynArrayCompare(TOK op, llvm::Value* l, llvm::Value* r) -{ - const char* fname; - if (op == TOKequal) - fname = "_d_dyn_array_eq"; - else if (op == TOKnotequal) - fname = "_d_dyn_array_neq"; - else - assert(0); - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_adEq"); assert(fn); - Logger::cout() << "lhsType:" << *l->getType() << "\nrhsType:" << *r->getType() << '\n'; - assert(l->getType() == r->getType()); - assert(isaPointer(l->getType())); - const llvm::StructType* structType = isaStruct(l->getType()->getContainedType(0)); - assert(structType); - const llvm::Type* elemType = structType->getElementType(1)->getContainedType(0); + llvm::Value* lmem; + llvm::Value* rmem; - std::vector<const llvm::Type*> arrTypes; - arrTypes.push_back(DtoSize_t()); - arrTypes.push_back(llvm::PointerType::get(llvm::Type::Int8Ty)); - const llvm::StructType* arrType = llvm::StructType::get(arrTypes); - - llvm::Value* llmem = l; - llvm::Value* rrmem = r; - - if (structType != arrType) { - llmem= new llvm::AllocaInst(arrType,"tmparr",gIR->topallocapoint()); + // cast static arrays to dynamic ones, this turns them into DSliceValues + Type* l_ty = DtoDType(l->getType()); + Type* r_ty = DtoDType(r->getType()); + assert(l_ty->next == r_ty->next); + Type* a_ty = new Type(Tarray, l_ty->next); + if (l_ty->ty == Tsarray) + l = DtoCastArray(l, a_ty); + if (r_ty->ty == Tsarray) + r = DtoCastArray(r, a_ty); - llvm::Value* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp"); - ll = DtoArrayCastLength(ll, elemType, llvm::Type::Int8Ty); - llvm::Value* lllen = DtoGEPi(llmem, 0,0, "tmp"); - gIR->ir->CreateStore(ll,lllen); - - ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp"); - ll = new llvm::BitCastInst(ll, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp", gIR->scopebb()); - llvm::Value* llptr = DtoGEPi(llmem, 0,1, "tmp"); - gIR->ir->CreateStore(ll,llptr); + // we need to give slices storage + if (l->isSlice()) { + lmem = new llvm::AllocaInst(DtoType(l->getType()), "tmpparam", gIR->topallocapoint()); + DtoSetArray(lmem, DtoArrayLen(l), DtoArrayPtr(l)); + } + else + lmem = l->getRVal(); - rrmem = new llvm::AllocaInst(arrType,"tmparr",gIR->topallocapoint()); + if (r->isSlice()) { + rmem = new llvm::AllocaInst(DtoType(r->getType()), "tmpparam", gIR->topallocapoint()); + DtoSetArray(rmem, DtoArrayLen(r), DtoArrayPtr(r)); + } + else + rmem = r->getRVal(); - llvm::Value* rr = gIR->ir->CreateLoad(DtoGEPi(r, 0,0, "tmp"),"tmp"); - rr = DtoArrayCastLength(rr, elemType, llvm::Type::Int8Ty); - llvm::Value* rrlen = DtoGEPi(rrmem, 0,0, "tmp"); - gIR->ir->CreateStore(rr,rrlen); - - rr = gIR->ir->CreateLoad(DtoGEPi(r, 0,1, "tmp"),"tmp"); - rr = new llvm::BitCastInst(rr, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp", gIR->scopebb()); - llvm::Value* rrptr = DtoGEPi(rrmem, 0,1, "tmp"); - gIR->ir->CreateStore(rr,rrptr); - } + const llvm::Type* pt = fn->getFunctionType()->getParamType(0); std::vector<llvm::Value*> args; - args.push_back(llmem); - args.push_back(rrmem); - return new llvm::CallInst(fn, args.begin(), args.end(), "tmp", gIR->scopebb()); + args.push_back(DtoBitCast(lmem,pt)); + args.push_back(DtoBitCast(rmem,pt)); + + TypeInfoDeclaration* ti = DtoDType(l->getType())->next->getTypeInfoDeclaration(); + if (!ti->llvmValue) { + ti->toObjFile(); + } + Logger::cout() << "typeinfo decl: " << *ti->llvmValue << '\n'; + + pt = fn->getFunctionType()->getParamType(2); + args.push_back(DtoBitCast(ti->llvmValue, pt)); + + llvm::Value* res = gIR->ir->CreateCall(fn, args.begin(), args.end(), "tmp"); + if (op == TOKnotequal) + res = gIR->ir->CreateNot(res, "tmp"); + + return res; } //////////////////////////////////////////////////////////////////////////////////////////