Factor out TOK to icmp predicate conversion into helper method.

This commit is contained in:
David Nadlinger
2012-12-28 02:54:17 +01:00
parent 7b5055b2a2
commit 33093a7403
4 changed files with 53 additions and 82 deletions

View File

@@ -1122,48 +1122,10 @@ LLValue* DtoArrayEquals(Loc& loc, TOK op, DValue* l, DValue* r)
LLValue* DtoArrayCompare(Loc& loc, TOK op, DValue* l, DValue* r)
{
LLValue* res = 0;
llvm::ICmpInst::Predicate cmpop;
bool skip = false;
tokToIcmpPred(op, false, &cmpop, &res);
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 = LLConstantInt::getTrue(gIR->context());
break;
case TOKunord:
skip = true;
res = LLConstantInt::getFalse(gIR->context());
break;
default:
assert(0);
}
if (!skip)
if (!res)
{
Type* t = l->getType()->toBasetype()->nextOf()->toBasetype();
if (t->ty == Tchar)

View File

@@ -1872,8 +1872,6 @@ void printLabelName(std::ostream& target, const char* func_mangle, const char* l
func_mangle << "_" << label_name;
}
//////////////////////////////////////////////////////////////////////////////////////////
// CTOR and DTOR
//////////////////////////////////////////////////////////////////////////////////////////
void AppendFunctionToLLVMGlobalCtorsDtors(llvm::Function* func, const uint32_t priority, const bool isCtor)
@@ -1883,3 +1881,42 @@ void AppendFunctionToLLVMGlobalCtorsDtors(llvm::Function* func, const uint32_t p
else
llvm::appendToGlobalDtors(*gIR->module, func, priority);
}
//////////////////////////////////////////////////////////////////////////////////////////
void tokToIcmpPred(TOK op, bool isUnsigned, llvm::ICmpInst::Predicate* outPred, llvm::Value** outConst)
{
switch(op)
{
case TOKlt:
case TOKul:
*outPred = isUnsigned ? llvm::ICmpInst::ICMP_ULT : llvm::ICmpInst::ICMP_SLT;
break;
case TOKle:
case TOKule:
*outPred = isUnsigned ? llvm::ICmpInst::ICMP_ULE : llvm::ICmpInst::ICMP_SLE;
break;
case TOKgt:
case TOKug:
*outPred = isUnsigned ? llvm::ICmpInst::ICMP_UGT : llvm::ICmpInst::ICMP_SGT;
break;
case TOKge:
case TOKuge:
*outPred = isUnsigned ? llvm::ICmpInst::ICMP_UGE : llvm::ICmpInst::ICMP_SGE;
break;
case TOKue:
*outPred = llvm::ICmpInst::ICMP_EQ;
break;
case TOKlg:
*outPred = llvm::ICmpInst::ICMP_NE;
break;
case TOKleg:
*outConst = LLConstantInt::getTrue(gIR->context());
break;
case TOKunord:
*outConst = LLConstantInt::getFalse(gIR->context());
break;
default:
llvm_unreachable("Invalid comparison operation");
}
}

View File

@@ -183,6 +183,14 @@ bool isSpecialRefVar(VarDeclaration* vd);
/// pointers.
bool isLLVMUnsigned(Type* t);
/// Converts a DMD comparison operation token into the corresponding LLVM icmp
/// predicate for the given operand signedness.
///
/// For some operations, the result can be a constant. In this case outConst is
/// set to it, otherwise outPred is set to the predicate to use.
void tokToIcmpPred(TOK op, bool isUnsigned, llvm::ICmpInst::Predicate* outPred,
llvm::Value** outConst);
////////////////////////////////////////////
// gen/tocall.cpp stuff below
////////////////////////////////////////////

View File

@@ -1711,46 +1711,10 @@ DValue* CmpExp::toElem(IRState* p)
if (t->isintegral() || t->ty == Tpointer || t->ty == Tnull)
{
llvm::ICmpInst::Predicate cmpop;
bool skip = false;
bool uns = isLLVMUnsigned(t);
switch(op)
{
case TOKlt:
case TOKul:
cmpop = uns ? llvm::ICmpInst::ICMP_ULT : llvm::ICmpInst::ICMP_SLT;
break;
case TOKle:
case TOKule:
cmpop = uns ? llvm::ICmpInst::ICMP_ULE : llvm::ICmpInst::ICMP_SLE;
break;
case TOKgt:
case TOKug:
cmpop = uns ? llvm::ICmpInst::ICMP_UGT : llvm::ICmpInst::ICMP_SGT;
break;
case TOKge:
case TOKuge:
cmpop = uns ? llvm::ICmpInst::ICMP_UGE : 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;
eval = LLConstantInt::getTrue(gIR->context());
break;
case TOKunord:
skip = true;
eval = LLConstantInt::getFalse(gIR->context());
break;
llvm::ICmpInst::Predicate icmpPred;
tokToIcmpPred(op, isLLVMUnsigned(t), &icmpPred, &eval);
default:
assert(0);
}
if (!skip)
if (!eval)
{
LLValue* a = l->getRVal();
LLValue* b = r->getRVal();
@@ -1761,7 +1725,7 @@ DValue* CmpExp::toElem(IRState* p)
}
if (a->getType() != b->getType())
b = DtoBitCast(b, a->getType());
eval = p->ir->CreateICmp(cmpop, a, b, "tmp");
eval = p->ir->CreateICmp(icmpPred, a, b, "tmp");
}
}
else if (t->isfloating())