changeset 99:a676a7743642 trunk

[svn r103] Array comparisons are now fully implemented, that is - to the extent that TypeInfo is.
author lindquist
date Thu, 15 Nov 2007 00:24:44 +0100
parents 6789050b5ad1
children 5071469303d4
files gen/arrays.cpp gen/arrays.h gen/toir.cpp gen/tollvm.cpp llvmdc.kdevelop.filelist test/arrays12.d
diffstat 6 files changed, 103 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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);
--- 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);
 
--- 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");
--- 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
--- 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
--- /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();
+}