# HG changeset patch # User lindquist # Date 1195082684 -3600 # Node ID a676a77436420f2d8dcadac63106d91f93b5adec # Parent 6789050b5ad1c88cb016cc04134aaa18c78884e0 [svn r103] Array comparisons are now fully implemented, that is - to the extent that TypeInfo is. diff -r 6789050b5ad1 -r a676a7743642 gen/arrays.cpp --- a/gen/arrays.cpp Wed Nov 14 23:39:10 2007 +0100 +++ b/gen/arrays.cpp Thu Nov 15 00:24:44 2007 +0100 @@ -546,10 +546,10 @@ } ////////////////////////////////////////////////////////////////////////////////////////// - -llvm::Value* DtoArrayEquals(TOK op, DValue* l, DValue* r) +// helper for eq and cmp +static llvm::Value* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r) { - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_adEq"); + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, func); assert(fn); llvm::Value* lmem; @@ -559,11 +559,13 @@ 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); + if ((l_ty->ty == Tsarray) || (r_ty->ty == Tsarray)) { + 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); + } // we need to give slices storage if (l->isSlice()) { @@ -595,7 +597,16 @@ pt = fn->getFunctionType()->getParamType(2); args.push_back(DtoBitCast(ti->llvmValue, pt)); - llvm::Value* res = gIR->ir->CreateCall(fn, args.begin(), args.end(), "tmp"); + return gIR->ir->CreateCall(fn, args.begin(), args.end(), "tmp"); +} + +////////////////////////////////////////////////////////////////////////////////////////// +llvm::Value* DtoArrayEquals(TOK op, DValue* l, DValue* r) +{ + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_adEq"); + assert(fn); + + llvm::Value* res = DtoArrayEqCmp_impl("_adEq", l, r); if (op == TOKnotequal) res = gIR->ir->CreateNot(res, "tmp"); @@ -603,6 +614,61 @@ } ////////////////////////////////////////////////////////////////////////////////////////// +llvm::Value* DtoArrayCompare(TOK op, DValue* l, DValue* r) +{ + llvm::Value* res = 0; + + llvm::ICmpInst::Predicate cmpop; + bool skip = false; + + switch(op) + { + case TOKlt: + case TOKul: + cmpop = llvm::ICmpInst::ICMP_SLT; + break; + case TOKle: + case TOKule: + cmpop = llvm::ICmpInst::ICMP_SLE; + break; + case TOKgt: + case TOKug: + cmpop = llvm::ICmpInst::ICMP_SGT; + break; + case TOKge: + case TOKuge: + cmpop = llvm::ICmpInst::ICMP_SGE; + break; + case TOKue: + cmpop = llvm::ICmpInst::ICMP_EQ; + break; + case TOKlg: + cmpop = llvm::ICmpInst::ICMP_NE; + break; + case TOKleg: + skip = true; + res = llvm::ConstantInt::getTrue(); + break; + case TOKunord: + skip = true; + res = llvm::ConstantInt::getFalse(); + break; + + default: + assert(0); + } + + if (!skip) + { + res = DtoArrayEqCmp_impl("_adCmp", l, r); + res = new llvm::ICmpInst(cmpop, res, DtoConstInt(0), "tmp", gIR->scopebb()); + } + + assert(res); + return res; +} + +////////////////////////////////////////////////////////////////////////////////////////// llvm::Value* DtoArrayCastLength(llvm::Value* len, const llvm::Type* elemty, const llvm::Type* newelemty) { size_t esz = gTargetData->getTypeSize(elemty); diff -r 6789050b5ad1 -r a676a7743642 gen/arrays.h --- a/gen/arrays.h Wed Nov 14 23:39:10 2007 +0100 +++ b/gen/arrays.h Thu Nov 15 00:24:44 2007 +0100 @@ -28,6 +28,7 @@ void DtoStaticArrayCopy(llvm::Value* dst, llvm::Value* src); llvm::Value* DtoArrayEquals(TOK op, DValue* l, DValue* r); +llvm::Value* DtoArrayCompare(TOK op, DValue* l, DValue* r); llvm::Value* DtoDynArrayIs(TOK op, llvm::Value* l, llvm::Value* r); diff -r 6789050b5ad1 -r a676a7743642 gen/toir.cpp --- a/gen/toir.cpp Wed Nov 14 23:39:10 2007 +0100 +++ b/gen/toir.cpp Thu Nov 15 00:24:44 2007 +0100 @@ -1810,6 +1810,11 @@ } eval = new llvm::FCmpInst(cmpop, l->getRVal(), r->getRVal(), "tmp", p->scopebb()); } + else if (t->ty == Tsarray || t->ty == Tarray) + { + Logger::println("static or dynamic array"); + eval = DtoArrayCompare(op,l,r); + } else { assert(0 && "Unsupported CmpExp type"); diff -r 6789050b5ad1 -r a676a7743642 gen/tollvm.cpp --- a/gen/tollvm.cpp Wed Nov 14 23:39:10 2007 +0100 +++ b/gen/tollvm.cpp Thu Nov 15 00:24:44 2007 +0100 @@ -1690,6 +1690,8 @@ return false; } +////////////////////////////////////////////////////////////////////////////////////////// + void DtoLazyStaticInit(bool istempl, llvm::Value* gvar, Initializer* init, Type* t) { // create a flag to make sure initialization only happens once diff -r 6789050b5ad1 -r a676a7743642 llvmdc.kdevelop.filelist --- a/llvmdc.kdevelop.filelist Wed Nov 14 23:39:10 2007 +0100 +++ b/llvmdc.kdevelop.filelist Thu Nov 15 00:24:44 2007 +0100 @@ -222,6 +222,7 @@ test/arrays.d test/arrays10.d test/arrays11.d +test/arrays12.d test/arrays2.d test/arrays3.d test/arrays4.d diff -r 6789050b5ad1 -r a676a7743642 test/arrays12.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/arrays12.d Thu Nov 15 00:24:44 2007 +0100 @@ -0,0 +1,19 @@ +module arrays12; + +void ints() +{ + int[3] a = [1,2,3]; + int[3] b = [2,3,4]; + int[3] c = [2,5,0]; + {assert(a < b);} + {assert(b > a);} + {assert(a < c);} + {assert(c > a);} + {assert(b < c);} + {assert(c > b);} +} + +void main() +{ + ints(); +}