changeset 344:e20ce6d8d374 trunk

[svn r365] Implemented raw struct equality comparison, uses C memcmp. Renamed DtoDelegateCompare to DtoDelegateEquals, for consistency with the other equality helpers.
author lindquist
date Sun, 13 Jul 2008 04:11:08 +0200
parents 15eb8f5f2441
children 5320fe65a65d
files gen/structs.cpp gen/structs.h gen/toir.cpp gen/tollvm.cpp gen/tollvm.h llvmdc.kdevelop.filelist
diffstat 6 files changed, 69 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/gen/structs.cpp	Sun Jul 13 03:02:15 2008 +0200
+++ b/gen/structs.cpp	Sun Jul 13 04:11:08 2008 +0200
@@ -13,6 +13,7 @@
 #include "gen/arrays.h"
 #include "gen/logger.h"
 #include "gen/structs.h"
+#include "gen/dvalue.h"
 
 #include "ir/irstruct.h"
 
@@ -378,6 +379,28 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////   D STRUCT UTILITIES     ////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+
+LLValue* DtoStructEquals(TOK op, DValue* lhs, DValue* rhs)
+{
+    Type* t = lhs->getType()->toBasetype();
+    assert(t->ty == Tstruct);
+
+    // set predicate
+    llvm::ICmpInst::Predicate cmpop;
+    if (op == TOKequal)
+        cmpop = llvm::ICmpInst::ICMP_EQ;
+    else
+        cmpop = llvm::ICmpInst::ICMP_NE;
+
+    // call memcmp
+    size_t sz = getABITypeSize(DtoType(t));
+    LLValue* val = DtoMemCmp(lhs->getRVal(), rhs->getRVal(), DtoConstSize_t(sz));
+    return gIR->ir->CreateICmp(cmpop, val, LLConstantInt::get(val->getType(), 0, false), "tmp");
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////   D UNION HELPER CLASS   ////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////
 
--- a/gen/structs.h	Sun Jul 13 03:02:15 2008 +0200
+++ b/gen/structs.h	Sun Jul 13 04:11:08 2008 +0200
@@ -25,6 +25,11 @@
  */
 void DtoDefineStruct(StructDeclaration* sd);
 
+/**
+ * Returns a boolean=true if the two structs are equal
+ */
+LLValue* DtoStructEquals(TOK op, DValue* lhs, DValue* rhs);
+
 typedef LLSmallVector<unsigned, 3> DStructIndexVector;
 LLValue* DtoIndexStruct(LLValue* ptr, StructDeclaration* sd, Type* t, unsigned os, DStructIndexVector& idxs);
 
--- a/gen/toir.cpp	Sun Jul 13 03:02:15 2008 +0200
+++ b/gen/toir.cpp	Sun Jul 13 04:11:08 2008 +0200
@@ -1747,7 +1747,13 @@
     else if (t->ty == Tdelegate)
     {
         Logger::println("delegate");
-        eval = DtoDelegateCompare(op,l->getRVal(),r->getRVal());
+        eval = DtoDelegateEquals(op,l->getRVal(),r->getRVal());
+    }
+    else if (t->ty == Tstruct)
+    {
+        Logger::println("struct");
+        // when this is reached it means there is no opEquals overload.
+        eval = DtoStructEquals(op,l,r);
     }
     else
     {
@@ -2266,7 +2272,7 @@
         else {
             assert(l->getType() == r->getType());
         }
-        eval = DtoDelegateCompare(op,l,r);
+        eval = DtoDelegateEquals(op,l,r);
     }
     else if (t1->isfloating())
     {
--- a/gen/tollvm.cpp	Sun Jul 13 03:02:15 2008 +0200
+++ b/gen/tollvm.cpp	Sun Jul 13 04:11:08 2008 +0200
@@ -186,9 +186,9 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-LLValue* DtoDelegateCompare(TOK op, LLValue* lhs, LLValue* rhs)
+LLValue* DtoDelegateEquals(TOK op, LLValue* lhs, LLValue* rhs)
 {
-    Logger::println("Doing delegate compare");
+    Logger::println("Doing delegate equality");
     llvm::ICmpInst::Predicate pred = (op == TOKequal || op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
     llvm::Value *b1, *b2;
     if (rhs == NULL)
@@ -444,6 +444,29 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
+LLValue* DtoMemCmp(LLValue* lhs, LLValue* rhs, LLValue* nbytes)
+{
+    // int memcmp ( const void * ptr1, const void * ptr2, size_t num );
+
+    LLFunction* fn = gIR->module->getFunction("memcmp");
+    if (!fn)
+    {
+        std::vector<const LLType*> params(3);
+        params[0] = getVoidPtrType();
+        params[1] = getVoidPtrType();
+        params[2] = DtoSize_t();
+        const LLFunctionType* fty = LLFunctionType::get(LLType::Int32Ty, params, false);
+        fn = LLFunction::Create(fty, LLGlobalValue::ExternalLinkage, "memcmp", gIR->module);
+    }
+
+    lhs = DtoBitCast(lhs,getVoidPtrType());
+    rhs = DtoBitCast(rhs,getVoidPtrType());
+
+    return gIR->ir->CreateCall3(fn, lhs, rhs, nbytes, "tmp");
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
 void DtoAggrZeroInit(LLValue* v)
 {
     uint64_t n = getTypeStoreSize(v->getType()->getContainedType(0));
--- a/gen/tollvm.h	Sun Jul 13 03:02:15 2008 +0200
+++ b/gen/tollvm.h	Sun Jul 13 04:11:08 2008 +0200
@@ -27,7 +27,7 @@
 
 // delegate helpers
 const LLStructType* DtoDelegateType(Type* t);
-LLValue* DtoDelegateCompare(TOK op, LLValue* lhs, LLValue* rhs);
+LLValue* DtoDelegateEquals(TOK op, LLValue* lhs, LLValue* rhs);
 
 // return linkage type for symbol using the current ir state for context
 LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym);
@@ -114,6 +114,11 @@
 void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes);
 
 /**
+ * Generates a call to C memcmp.
+ */
+LLValue* DtoMemCmp(LLValue* lhs, LLValue* rhs, LLValue* nbytes);
+
+/**
  * The same as DtoMemSetZero but figures out the size itself by "dereferencing" the v pointer once.
  * @param v Destination memory.
  */
--- a/llvmdc.kdevelop.filelist	Sun Jul 13 03:02:15 2008 +0200
+++ b/llvmdc.kdevelop.filelist	Sun Jul 13 04:11:08 2008 +0200
@@ -58,6 +58,8 @@
 dmd/mangle.c
 dmd/mars.c
 dmd/mars.h
+dmd/md5.c
+dmd/md5.h
 dmd/mem.c
 dmd/mem.h
 dmd/module.c