Skip to content

Commit

Permalink
Merge pull request #5085 from 9rnsr/fix14886
Browse files Browse the repository at this point in the history
[REG2.066] Issue 14886 - std.parallelism.parallel with large static array seems to hang compile
  • Loading branch information
WalterBright committed Sep 22, 2015
2 parents b6e5152 + 872e0a7 commit a492f91
Show file tree
Hide file tree
Showing 17 changed files with 288 additions and 127 deletions.
2 changes: 1 addition & 1 deletion src/apply.d
Expand Up @@ -108,7 +108,7 @@ public:

override void visit(ArrayLiteralExp e)
{
doCond(e.elements) || applyTo(e);
doCond(e.basis) || doCond(e.elements) || applyTo(e);
}

override void visit(AssocArrayLiteralExp e)
Expand Down
77 changes: 35 additions & 42 deletions src/constfold.d
Expand Up @@ -760,8 +760,8 @@ extern (C++) UnionExp Equal(TOK op, Loc loc, Type type, Expression e1, Expressio
{
for (size_t i = 0; i < es1.elements.dim; i++)
{
Expression ee1 = (*es1.elements)[i];
Expression ee2 = (*es2.elements)[i];
auto ee1 = es1.getElement(i);
auto ee2 = es2.getElement(i);
ue = Equal(TOKequal, loc, Type.tint32, ee1, ee2);
if (CTFEExp.isCantExp(ue.exp()))
return ue;
Expand Down Expand Up @@ -794,7 +794,7 @@ extern (C++) UnionExp Equal(TOK op, Loc loc, Type type, Expression e1, Expressio
for (size_t i = 0; i < dim1; i++)
{
uinteger_t c = es1.charAt(i);
Expression ee2 = (*es2.elements)[i];
auto ee2 = es2.getElement(i);
if (ee2.isConst() != 1)
{
emplaceExp!(CTFEExp)(&ue, TOKcantexp);
Expand Down Expand Up @@ -1430,7 +1430,7 @@ extern (C++) UnionExp Index(Type type, Expression e1, Expression e2)
else if (e1.op == TOKarrayliteral)
{
ArrayLiteralExp ale = cast(ArrayLiteralExp)e1;
Expression e = (*ale.elements)[cast(size_t)i];
auto e = ale.getElement(cast(size_t)i);
e.type = type;
e.loc = loc;
if (hasSideEffect(e))
Expand All @@ -1454,7 +1454,7 @@ extern (C++) UnionExp Index(Type type, Expression e1, Expression e2)
}
else
{
Expression e = (*ale.elements)[cast(size_t)i];
auto e = ale.getElement(cast(size_t)i);
e.type = type;
e.loc = loc;
if (hasSideEffect(e))
Expand Down Expand Up @@ -1600,7 +1600,7 @@ extern (C++) void sliceAssignStringFromArrayLiteral(StringExp existingSE, ArrayL
void* s = existingSE.string;
for (size_t j = 0; j < newae.elements.dim; j++)
{
uint val = cast(uint)(*newae.elements)[j].toInteger();
uint val = cast(uint)newae.getElement(j).toInteger();
switch (existingSE.sz)
{
case 1:
Expand Down Expand Up @@ -1650,7 +1650,7 @@ extern (C++) int sliceCmpStringWithArray(StringExp se1, ArrayLiteralExp ae2, siz
size_t sz = se1.sz;
for (size_t j = 0; j < len; j++)
{
uint val2 = cast(uint)(*ae2.elements)[j + lo2].toInteger();
uint val2 = cast(uint)ae2.getElement(j + lo2).toInteger();
uint val1;
switch (sz)
{
Expand Down Expand Up @@ -1797,7 +1797,7 @@ extern (C++) UnionExp Cat(Type type, Expression e1, Expression e2)
elems.setDim(len);
for (size_t i = 0; i < ea.elements.dim; ++i)
{
(*elems)[i] = (*ea.elements)[i];
(*elems)[i] = ea.getElement(i);
}
emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, elems);
ArrayLiteralExp dest = cast(ArrayLiteralExp)ue.exp();
Expand All @@ -1816,7 +1816,7 @@ extern (C++) UnionExp Cat(Type type, Expression e1, Expression e2)
elems.setDim(len);
for (size_t i = 0; i < ea.elements.dim; ++i)
{
(*elems)[es.len + i] = (*ea.elements)[i];
(*elems)[es.len + i] = ea.getElement(i);
}
emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, elems);
ArrayLiteralExp dest = cast(ArrayLiteralExp)ue.exp();
Expand Down Expand Up @@ -1876,15 +1876,14 @@ extern (C++) UnionExp Cat(Type type, Expression e1, Expression e2)
else if (e1.op == TOKarrayliteral && e2.op == TOKarrayliteral && t1.nextOf().equals(t2.nextOf()))
{
// Concatenate the arrays
ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1;
ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2;
emplaceExp!(ArrayLiteralExp)(&ue, es1.loc, cast(Expressions*)es1.elements.copy());
es1 = cast(ArrayLiteralExp)ue.exp();
es1.elements.insert(es1.elements.dim, es2.elements);
e = es1;
auto elems = ArrayLiteralExp.copyElements(e1, e2);

emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, elems);

e = ue.exp();
if (type.toBasetype().ty == Tsarray)
{
e.type = t1.nextOf().sarrayOf(es1.elements.dim);
e.type = t1.nextOf().sarrayOf(elems.dim);
}
else
e.type = type;
Expand All @@ -1901,13 +1900,14 @@ extern (C++) UnionExp Cat(Type type, Expression e1, Expression e2)
e = e2;
L3:
// Concatenate the array with null
ArrayLiteralExp es = cast(ArrayLiteralExp)e;
emplaceExp!(ArrayLiteralExp)(&ue, es.loc, cast(Expressions*)es.elements.copy());
es = cast(ArrayLiteralExp)ue.exp();
e = es;
auto elems = ArrayLiteralExp.copyElements(e);

emplaceExp!(ArrayLiteralExp)(&ue, e.loc, elems);

e = ue.exp();
if (type.toBasetype().ty == Tsarray)
{
e.type = t1.nextOf().sarrayOf(es.elements.dim);
e.type = t1.nextOf().sarrayOf(elems.dim);
}
else
e.type = type;
Expand All @@ -1916,23 +1916,16 @@ extern (C++) UnionExp Cat(Type type, Expression e1, Expression e2)
}
else if ((e1.op == TOKarrayliteral || e1.op == TOKnull) && e1.type.toBasetype().nextOf() && e1.type.toBasetype().nextOf().equals(e2.type))
{
ArrayLiteralExp es1;
if (e1.op == TOKarrayliteral)
{
es1 = cast(ArrayLiteralExp)e1;
emplaceExp!(ArrayLiteralExp)(&ue, es1.loc, cast(Expressions*)es1.elements.copy());
es1 = cast(ArrayLiteralExp)ue.exp();
es1.elements.push(e2);
}
else
{
emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, e2);
es1 = cast(ArrayLiteralExp)ue.exp();
}
e = es1;
auto elems = (e1.op == TOKarrayliteral)
? ArrayLiteralExp.copyElements(e1) : new Expressions();
elems.push(e2);

emplaceExp!(ArrayLiteralExp)(&ue, e1.loc, elems);

e = ue.exp();
if (type.toBasetype().ty == Tsarray)
{
e.type = e2.type.sarrayOf(es1.elements.dim);
e.type = e2.type.sarrayOf(elems.dim);
}
else
e.type = type;
Expand All @@ -1941,14 +1934,14 @@ extern (C++) UnionExp Cat(Type type, Expression e1, Expression e2)
}
else if (e2.op == TOKarrayliteral && e2.type.toBasetype().nextOf().equals(e1.type))
{
ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2;
emplaceExp!(ArrayLiteralExp)(&ue, es2.loc, cast(Expressions*)es2.elements.copy());
es2 = cast(ArrayLiteralExp)ue.exp();
es2.elements.shift(e1);
e = es2;
auto elems = ArrayLiteralExp.copyElements(e1, e2);

emplaceExp!(ArrayLiteralExp)(&ue, e2.loc, elems);

e = ue.exp();
if (type.toBasetype().ty == Tsarray)
{
e.type = e1.type.sarrayOf(es2.elements.dim);
e.type = e1.type.sarrayOf(elems.dim);
}
else
e.type = type;
Expand Down
17 changes: 13 additions & 4 deletions src/ctfeexpr.d
Expand Up @@ -306,15 +306,20 @@ extern (C++) bool needToCopyLiteral(Expression expr)
}
}

extern (C++) Expressions* copyLiteralArray(Expressions* oldelems)
extern (C++) Expressions* copyLiteralArray(Expressions* oldelems, Expression basis = null)
{
if (!oldelems)
return oldelems;
CtfeStatus.numArrayAllocs++;
auto newelems = new Expressions();
newelems.setDim(oldelems.dim);
for (size_t i = 0; i < oldelems.dim; i++)
(*newelems)[i] = copyLiteral((*oldelems)[i]).copy();
{
auto el = (*oldelems)[i];
if (!el)
el = basis;
(*newelems)[i] = copyLiteral(el).copy();
}
return newelems;
}

Expand All @@ -339,8 +344,12 @@ extern (C++) UnionExp copyLiteral(Expression e)
}
if (e.op == TOKarrayliteral)
{
ArrayLiteralExp ae = cast(ArrayLiteralExp)e;
emplaceExp!(ArrayLiteralExp)(&ue, e.loc, copyLiteralArray(ae.elements));
auto ale = cast(ArrayLiteralExp)e;
auto basis = ale.basis ? copyLiteral(ale.basis).copy() : null;
auto elements = copyLiteralArray(ale.elements, ale.basis);

emplaceExp!(ArrayLiteralExp)(&ue, e.loc, elements);

ArrayLiteralExp r = cast(ArrayLiteralExp)ue.exp();
r.type = e.type;
r.ownedByCtfe = OWNEDctfe;
Expand Down
18 changes: 16 additions & 2 deletions src/dcast.d
Expand Up @@ -676,12 +676,19 @@ extern (C++) MATCH implicitConvTo(Expression e, Type t)
}
else
{
if (e.basis)
{
MATCH m = e.basis.implicitConvTo(telement);
if (m < result)
result = m;
}
for (size_t i = 0; i < e.elements.dim; i++)
{
Expression el = (*e.elements)[i];
if (result == MATCHnomatch)
break;
// no need to check for worse
if (!el)
continue;
MATCH m = el.implicitConvTo(telement);
if (m < result)
result = m; // remember worst match
Expand Down Expand Up @@ -1946,10 +1953,14 @@ extern (C++) Expression castTo(Expression e, Scope* sc, Type t)
goto L1;
}
ae = cast(ArrayLiteralExp)e.copy();
if (e.basis)
ae.basis = e.basis.castTo(sc, tb.nextOf());
ae.elements = e.elements.copy();
for (size_t i = 0; i < e.elements.dim; i++)
{
Expression ex = (*e.elements)[i];
if (!ex)
continue;
ex = ex.castTo(sc, tb.nextOf());
(*ae.elements)[i] = ex;
}
Expand Down Expand Up @@ -2279,6 +2290,8 @@ extern (C++) Expression inferType(Expression e, Type t, int flag = 0)
if (tb.ty == Tarray || tb.ty == Tsarray)
{
Type tn = tb.nextOf();
if (ale.basis)
ale.basis = inferType(ale.basis, tn, flag);
for (size_t i = 0; i < ale.elements.dim; i++)
{
Expression e = (*ale.elements)[i];
Expand Down Expand Up @@ -2416,7 +2429,8 @@ extern (C++) bool isVoidArrayLiteral(Expression e, Type other)
{
while (e.op == TOKarrayliteral && e.type.ty == Tarray && ((cast(ArrayLiteralExp)e).elements.dim == 1))
{
e = (*(cast(ArrayLiteralExp)e).elements)[0];
auto ale = cast(ArrayLiteralExp)e;
e = ale.getElement(0);
if (other.ty == Tsarray || other.ty == Tarray)
other = other.nextOf();
else
Expand Down
47 changes: 33 additions & 14 deletions src/dinterpret.d
Expand Up @@ -2559,38 +2559,57 @@ public:
}
Type tn = e.type.toBasetype().nextOf().toBasetype();
bool wantCopy = (tn.ty == Tsarray || tn.ty == Tstruct);

auto basis = interpret(e.basis, istate);
if (exceptionOrCant(basis))
return;

Expressions* expsx = null;
size_t dim = e.elements ? e.elements.dim : 0;
for (size_t i = 0; i < dim; i++)
{
Expression exp = (*e.elements)[i];
if (exp.op == TOKindex) // segfault bug 6250
assert((cast(IndexExp)exp).e1 != e);
Expression ex = interpret(exp, istate);
Expression ex;
if (!exp)
{
ex = copyLiteral(basis).copy();
goto Lcow;
}

// segfault bug 6250
assert(exp.op != TOKindex || (cast(IndexExp)exp).e1 != e);

ex = interpret(exp, istate);
if (exceptionOrCant(ex))
return;

/* Each elements should have distinct CFE memory.
* int[1] z = 7;
* int[1][] pieces = [z,z]; // here
*/
if (wantCopy || ex == exp && expsx)
ex = copyLiteral(ex).copy();

if (ex == exp && !expsx)
continue;

/* If any changes, do Copy On Write
*/
if (ex != exp)
Lcow:
if (!expsx)
{
if (!expsx)
expsx = new Expressions();
++CtfeStatus.numArrayAllocs;
expsx.setDim(dim);
for (size_t j = 0; j < i; j++)
{
expsx = new Expressions();
++CtfeStatus.numArrayAllocs;
expsx.setDim(dim);
for (size_t j = 0; j < i; j++)
{
(*expsx)[j] = copyLiteral((*e.elements)[j]).copy();
}
auto el = (*e.elements)[j];
if (!el)
el = e.basis;
(*expsx)[j] = copyLiteral(el).copy();
}
(*expsx)[i] = ex;
}
(*expsx)[i] = ex;
}
if (expsx)
{
Expand All @@ -2602,7 +2621,7 @@ public:
result = CTFEExp.cantexp;
return;
}
auto ae = new ArrayLiteralExp(e.loc, expsx);
auto ae = new ArrayLiteralExp(e.loc, basis, expsx);
ae.type = e.type;
ae.ownedByCtfe = OWNEDctfe;
result = ae;
Expand Down
2 changes: 1 addition & 1 deletion src/dmangle.d
Expand Up @@ -739,7 +739,7 @@ public:
buf.printf("A%u", dim);
for (size_t i = 0; i < dim; i++)
{
(*e.elements)[i].accept(this);
e.getElement(i).accept(this);
}
}

Expand Down
13 changes: 11 additions & 2 deletions src/dtemplate.d
Expand Up @@ -4166,13 +4166,22 @@ extern (C++) MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplatePara
{
Type tn = (cast(TypeDArray)tparam).next;
result = MATCHexact;
for (size_t i = 0; i < e.elements.dim; i++)
if (e.basis)
{
MATCH m = deduceType((*e.elements)[i], sc, tn, parameters, dedtypes, wm);
MATCH m = deduceType(e.basis, sc, tn, parameters, dedtypes, wm);
if (m < result)
result = m;
}
for (size_t i = 0; i < e.elements.dim; i++)
{
if (result <= MATCHnomatch)
break;
auto el = (*e.elements)[i];
if (!el)
continue;
MATCH m = deduceType(el, sc, tn, parameters, dedtypes, wm);
if (m < result)
result = m;
}
return;
}
Expand Down

0 comments on commit a492f91

Please sign in to comment.