From: Iain Buclaw Date: Sun, 28 Jun 2020 15:46:18 +0000 (+0200) Subject: d: Merge upstream dmd 8508c4e68. X-Git-Tag: releases/gcc-10.2.0~133 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6bb36ec49aed585b0d31f1c229e5b6ad5531972;p=thirdparty%2Fgcc.git d: Merge upstream dmd 8508c4e68. Fixes a performance bug where 'static foreach' would take an exponentially long time to expand during CTFE. In the following example: static foreach (i; 0..30000) {} Compilation time had been reduced from around 40 to 0.08 seconds. Memory consumption is also reduced from 3.5GB to 55MB. Reviewed-on: https://github.com/dlang/dmd/pull/11335 gcc/d/ChangeLog: * dmd/cond.c (lowerArrayAggregate): Directly use the elements of the array for TupleExp creation. (lowerNonArrayAggregate): Inline creation of foreach range indexes. (cherry picked from commit ce56fd949f359a62b86a45aaf975ac2ecc48fa64) --- diff --git a/gcc/d/dmd/cond.c b/gcc/d/dmd/cond.c index c75399d38253..1267199d4e16 100644 --- a/gcc/d/dmd/cond.c +++ b/gcc/d/dmd/cond.c @@ -92,13 +92,24 @@ static void lowerArrayAggregate(StaticForeach *sfe, Scope *sc) el = el->ctfeInterpret(); if (el->op == TOKint64) { - dinteger_t length = el->toInteger(); - Expressions *es = new Expressions(); - for (size_t i = 0; i < length; i++) + Expressions *es; + if (aggr->op == TOKarrayliteral) { - IntegerExp *index = new IntegerExp(sfe->loc, i, Type::tsize_t); - Expression *value = new IndexExp(aggr->loc, aggr, index); - es->push(value); + // Directly use the elements of the array for the TupleExp creation + ArrayLiteralExp *ale = (ArrayLiteralExp *)aggr; + es = ale->elements; + } + else + { + size_t length = (size_t)el->toInteger(); + es = new Expressions(); + es->setDim(length); + for (size_t i = 0; i < length; i++) + { + IntegerExp *index = new IntegerExp(sfe->loc, i, Type::tsize_t); + Expression *value = new IndexExp(aggr->loc, aggr, index); + (*es)[i] = value; + } } sfe->aggrfe->aggr = new TupleExp(aggr->loc, es); sfe->aggrfe->aggr = semantic(sfe->aggrfe->aggr, sc); @@ -307,13 +318,50 @@ static void lowerNonArrayAggregate(StaticForeach *sfe, Scope *sc) Expression *catass = new CatAssignExp(aloc, new IdentifierExp(aloc, idres), res[1]); s2->push(createForeach(sfe, aloc, pparams[1], new ExpStatement(aloc, catass))); s2->push(new ReturnStatement(aloc, new IdentifierExp(aloc, idres))); - Expression *aggr = wrapAndCall(aloc, new CompoundStatement(aloc, s2)); - sc = sc->startCTFE(); - aggr = semantic(aggr, sc); - aggr = resolveProperties(sc, aggr); - sc = sc->endCTFE(); - aggr = aggr->optimize(WANTvalue); - aggr = aggr->ctfeInterpret(); + + Expression *aggr; + Type *indexty; + + if (sfe->rangefe && (indexty = ety->semantic(aloc, sc))->isintegral()) + { + sfe->rangefe->lwr->type = indexty; + sfe->rangefe->upr->type = indexty; + IntRange lwrRange = getIntRange(sfe->rangefe->lwr); + IntRange uprRange = getIntRange(sfe->rangefe->upr); + + const dinteger_t lwr = sfe->rangefe->lwr->toInteger(); + dinteger_t upr = sfe->rangefe->upr->toInteger(); + size_t length = 0; + + if (lwrRange.imin <= uprRange.imax) + length = (size_t)(upr - lwr); + + Expressions *exps = new Expressions(); + exps->setDim(length); + + if (sfe->rangefe->op == TOKforeach) + { + for (size_t i = 0; i < length; i++) + (*exps)[i] = new IntegerExp(aloc, lwr + i, indexty); + } + else + { + --upr; + for (size_t i = 0; i < length; i++) + (*exps)[i] = new IntegerExp(aloc, upr - i, indexty); + } + aggr = new ArrayLiteralExp(aloc, indexty->arrayOf(), exps); + } + else + { + aggr = wrapAndCall(aloc, new CompoundStatement(aloc, s2)); + sc = sc->startCTFE(); + aggr = semantic(aggr, sc); + aggr = resolveProperties(sc, aggr); + sc = sc->endCTFE(); + aggr = aggr->optimize(WANTvalue); + aggr = aggr->ctfeInterpret(); + } assert(!!sfe->aggrfe ^ !!sfe->rangefe); sfe->aggrfe = new ForeachStatement(sfe->loc, TOKforeach, pparams[2], aggr,