aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2020-06-28 17:46:18 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2020-06-28 18:04:20 +0200
commitce56fd949f359a62b86a45aaf975ac2ecc48fa64 (patch)
treedcaa656a7457469c1b72556b0f88eaa377680dd1 /gcc/d/dmd
parentb62cac6d92ff251213753475b69ec0b269cb7fae (diff)
downloadgcc-ce56fd949f359a62b86a45aaf975ac2ecc48fa64.zip
gcc-ce56fd949f359a62b86a45aaf975ac2ecc48fa64.tar.gz
gcc-ce56fd949f359a62b86a45aaf975ac2ecc48fa64.tar.bz2
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/MERGE: Merge upstream dmd 8508c4e68.
Diffstat (limited to 'gcc/d/dmd')
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/cond.c73
2 files changed, 61 insertions, 14 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 7de8935..b99e9f3 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-4be011355dd2c5e2e54b99f9369d5faeabca2ca5
+8508c4e683f065eb3deab76b610f7fecb3258a8e
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/cond.c b/gcc/d/dmd/cond.c
index 12fef59..beda133 100644
--- a/gcc/d/dmd/cond.c
+++ b/gcc/d/dmd/cond.c
@@ -92,13 +92,23 @@ 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 (ArrayLiteralExp *ale = aggr->isArrayLiteralExp())
{
- 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
+ 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 +317,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,