mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-15 12:23:13 +01:00
[svn r365] Implemented raw struct equality comparison, uses C memcmp.
Renamed DtoDelegateCompare to DtoDelegateEquals, for consistency with the other equality helpers.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include "gen/arrays.h"
|
||||
#include "gen/logger.h"
|
||||
#include "gen/structs.h"
|
||||
#include "gen/dvalue.h"
|
||||
|
||||
#include "ir/irstruct.h"
|
||||
|
||||
@@ -377,6 +378,28 @@ void DtoDefineStruct(StructDeclaration* sd)
|
||||
sd->ir.DModule = gIR->dmodule;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////// 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 ////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -25,6 +25,11 @@ void DtoConstInitStruct(StructDeclaration* sd);
|
||||
*/
|
||||
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);
|
||||
|
||||
|
||||
10
gen/toir.cpp
10
gen/toir.cpp
@@ -1747,7 +1747,13 @@ DValue* EqualExp::toElem(IRState* p)
|
||||
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 @@ DValue* IdentityExp::toElem(IRState* p)
|
||||
else {
|
||||
assert(l->getType() == r->getType());
|
||||
}
|
||||
eval = DtoDelegateCompare(op,l,r);
|
||||
eval = DtoDelegateEquals(op,l,r);
|
||||
}
|
||||
else if (t1->isfloating())
|
||||
{
|
||||
|
||||
@@ -186,9 +186,9 @@ const LLStructType* DtoDelegateType(Type* t)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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 @@ void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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));
|
||||
|
||||
@@ -27,7 +27,7 @@ Type* DtoDType(Type* t);
|
||||
|
||||
// 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);
|
||||
@@ -113,6 +113,11 @@ void DtoMemSetZero(LLValue* dst, LLValue* nbytes);
|
||||
*/
|
||||
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.
|
||||
|
||||
@@ -58,6 +58,8 @@ dmd/macro.h
|
||||
dmd/mangle.c
|
||||
dmd/mars.c
|
||||
dmd/mars.h
|
||||
dmd/md5.c
|
||||
dmd/md5.h
|
||||
dmd/mem.c
|
||||
dmd/mem.h
|
||||
dmd/module.c
|
||||
|
||||
Reference in New Issue
Block a user