From 7d6bbcd87de865276927e53ee8205cbd82d5d7a1 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Thu, 15 Nov 2007 00:24:44 +0100 Subject: [PATCH] [svn r103] Array comparisons are now fully implemented, that is - to the extent that TypeInfo is. --- gen/arrays.cpp | 84 +++++++++++++++++++++++++++++++++++----- gen/arrays.h | 1 + gen/toir.cpp | 5 +++ gen/tollvm.cpp | 2 + llvmdc.kdevelop.filelist | 1 + test/arrays12.d | 19 +++++++++ 6 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 test/arrays12.d diff --git a/gen/arrays.cpp b/gen/arrays.cpp index f42472e0..16bc9cff 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -546,10 +546,10 @@ void DtoCatArrays(llvm::Value* arr, Expression* exp1, Expression* exp2) } ////////////////////////////////////////////////////////////////////////////////////////// - -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 @@ llvm::Value* DtoArrayEquals(TOK op, DValue* l, DValue* r) 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,13 +597,77 @@ llvm::Value* DtoArrayEquals(TOK op, DValue* l, DValue* r) 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"); return res; } +////////////////////////////////////////////////////////////////////////////////////////// +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) { diff --git a/gen/arrays.h b/gen/arrays.h index 41390181..56e2a12e 100644 --- a/gen/arrays.h +++ b/gen/arrays.h @@ -28,6 +28,7 @@ void DtoCatArrays(llvm::Value* arr, Expression* e1, Expression* e2); 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 --git a/gen/toir.cpp b/gen/toir.cpp index 9575503e..63266595 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1810,6 +1810,11 @@ DValue* CmpExp::toElem(IRState* p) } 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 --git a/gen/tollvm.cpp b/gen/tollvm.cpp index a025f67d..670dfe8e 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -1690,6 +1690,8 @@ bool DtoIsTemplateInstance(Dsymbol* s) return false; } +////////////////////////////////////////////////////////////////////////////////////////// + void DtoLazyStaticInit(bool istempl, llvm::Value* gvar, Initializer* init, Type* t) { // create a flag to make sure initialization only happens once diff --git a/llvmdc.kdevelop.filelist b/llvmdc.kdevelop.filelist index 0c4841c8..886d3a41 100644 --- a/llvmdc.kdevelop.filelist +++ b/llvmdc.kdevelop.filelist @@ -222,6 +222,7 @@ test/arrayinit.d test/arrays.d test/arrays10.d test/arrays11.d +test/arrays12.d test/arrays2.d test/arrays3.d test/arrays4.d diff --git a/test/arrays12.d b/test/arrays12.d new file mode 100644 index 00000000..4870de30 --- /dev/null +++ b/test/arrays12.d @@ -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(); +}