Skip to content

Commit

Permalink
Merge pull request #1234 from donc/ctfe_speedup_arraycmp
Browse files Browse the repository at this point in the history
CTFE: reduce memory usage for array comparisons
  • Loading branch information
yebblies committed Oct 29, 2012
2 parents e76704b + cd56251 commit fdc299f
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 27 deletions.
4 changes: 4 additions & 0 deletions src/ctfe.h
Expand Up @@ -196,6 +196,10 @@ TypeAArray *toBuiltinAAType(Type *t);
Expression *findKeyInAA(Loc loc, AssocArrayLiteralExp *ae, Expression *e2);


/// Return true if non-pointer expression e can be compared
/// with >,is, ==, etc, using ctfeCmp, ctfeEquals, ctfeIdentity
bool isCtfeComparable(Expression *e);

/// Evaluate ==, !=. Resolves slices before comparing
Expression *ctfeEqual(Loc loc, enum TOK op, Type *type, Expression *e1, Expression *e2);

Expand Down
19 changes: 19 additions & 0 deletions src/ctfeexpr.c
Expand Up @@ -763,6 +763,25 @@ int comparePointers(Loc loc, enum TOK op, Type *type, Expression *agg1, dinteger

/******** Constant folding, with support for CTFE ***************************/

/// Return true if non-pointer expression e can be compared
/// with >,is, ==, etc, using ctfeCmp, ctfeEquals, ctfeIdentity
bool isCtfeComparable(Expression *e)
{
Expression *x = e;
if (x->op == TOKslice)
x = ((SliceExp *)e)->e1;

if (x->isConst() != 1 &&
x->op != TOKnull &&
x->op != TOKstring &&
x->op != TOKarrayliteral &&
x->op != TOKstructliteral &&
x->op != TOKclassreference)
{
return false;
}
return true;
}

int ctfeRawCmp(Loc loc, Expression *e1, Expression *e2);

Expand Down
31 changes: 4 additions & 27 deletions src/interpret.c
Expand Up @@ -1094,8 +1094,6 @@ Expression *SwitchStatement::interpret(InterState *istate)
Expression *econdition = condition->interpret(istate);
if (exceptionOrCantInterpret(econdition))
return econdition;
if (econdition->op == TOKslice)
econdition = resolveSlice(econdition);

Statement *s = NULL;
if (cases)
Expand Down Expand Up @@ -2013,8 +2011,6 @@ Expression *AssocArrayLiteralExp::interpret(InterState *istate, CtfeGoal goal)
*/
for (size_t i = 1; i < keysx->dim; i++)
{ Expression *ekey = keysx->tdata()[i - 1];
if (ekey->op == TOKslice)
ekey = resolveSlice(ekey);
for (size_t j = i; j < keysx->dim; j++)
{ Expression *ekey2 = keysx->tdata()[j];
Expression *ex = ctfeEqual(loc, TOKequal, Type::tbool, ekey, ekey2);
Expand Down Expand Up @@ -2381,42 +2377,23 @@ Expression *BinExp::interpretCommon2(InterState *istate, CtfeGoal goal, fp2_t fp
e1 = this->e1->interpret(istate);
if (exceptionOrCantInterpret(e1))
return e1;
if (e1->op == TOKslice)
e1 = resolveSlice(e1);

if (e1->isConst() != 1 &&
e1->op != TOKnull &&
e1->op != TOKstring &&
e1->op != TOKarrayliteral &&
e1->op != TOKstructliteral &&
e1->op != TOKclassreference)
if (!isCtfeComparable(e1))
{
error("cannot compare %s at compile time", e1->toChars());
goto Lcant;
return EXP_CANT_INTERPRET;
}

e2 = this->e2->interpret(istate);
if (exceptionOrCantInterpret(e2))
return e2;
if (e2->op == TOKslice)
e2 = resolveSlice(e2);
if (e2->isConst() != 1 &&
e2->op != TOKnull &&
e2->op != TOKstring &&
e2->op != TOKarrayliteral &&
e2->op != TOKstructliteral &&
e2->op != TOKclassreference)
if (!isCtfeComparable(e2))
{
error("cannot compare %s at compile time", e2->toChars());
goto Lcant;
return EXP_CANT_INTERPRET;
}
e = (*fp)(loc, op, type, e1, e2);
if (e == EXP_CANT_INTERPRET)
error("%s cannot be interpreted at compile time", toChars());
return e;

Lcant:
return EXP_CANT_INTERPRET;
}

#define BIN_INTERPRET2(op, opfunc) \
Expand Down

0 comments on commit fdc299f

Please sign in to comment.