Fix loop unroller out of memory; change --unroll-stmts.

This commit is contained in:
Wilson Snyder 2010-04-17 08:01:22 -04:00
parent a46c4ec912
commit ed17581f92
3 changed files with 25 additions and 12 deletions

View File

@ -19,6 +19,8 @@ indicates the contributor was also the author of the fix; Thanks!
**** Fix "make install" with configure outside srcdir. [Stefan Wallentowitz]
**** Fix loop unroller out of memory; change --unroll-stmts. [Ashutosh Das]
**** Fix trace files with empty modules crashing some viewers.
**** Fix parsing single files > 2GB. [Jeffrey Short]

View File

@ -1023,7 +1023,7 @@ V3Options::V3Options() {
m_outputSplitCTrace = 0;
m_traceDepth = 0;
m_unrollCount = 64;
m_unrollStmts = 100;
m_unrollStmts = 10000;
m_compLimitParens = 0;
m_compLimitBlocks = 0;

View File

@ -82,6 +82,20 @@ private:
: v3Global.opt.unrollCount();
}
bool bodySizeOverRecurse(AstNode* nodep, int& bodySize, int bodyLimit) {
if (!nodep) return false;
bodySize++;
// Exit once exceeds limits, rather than always total
// so don't go O(n^2) when can't unroll
if (bodySize > bodyLimit) return true;
if (bodySizeOverRecurse(nodep->op1p(), bodySize, bodyLimit)) return true;
if (bodySizeOverRecurse(nodep->op2p(), bodySize, bodyLimit)) return true;
if (bodySizeOverRecurse(nodep->op3p(), bodySize, bodyLimit)) return true;
if (bodySizeOverRecurse(nodep->op4p(), bodySize, bodyLimit)) return true;
// Tail recurse.
return bodySizeOverRecurse(nodep->nextp(), bodySize, bodyLimit);
}
bool forUnrollCheck(AstNode* nodep,
AstNode* initp, // Maybe under nodep (no nextp), or standalone (ignore nextp)
AstNode* precondsp, AstNode* condp,
@ -174,22 +188,19 @@ private:
//
if (!m_generate) {
UINFO(8, " ~Iters: "<<((valStop - valInit)/valInc)<<" c="<<unrollCount()<<endl);
if (((valStop - valInit)/valInc) > unrollCount())
int loops = ((valStop - valInit)/valInc);
if (loops > unrollCount())
return cantUnroll(nodep, "too many iterations");
// Less than 10 statements in the body?
int bodySize = 0;
for (AstNode* bodp = precondsp; bodp; bodp=bodp->nextp()) {
bodySize++;
}
for (AstNode* bodp = bodysp; bodp; bodp=bodp->nextp()) {
bodySize++;
}
for (AstNode* bodp = incp; bodp; bodp=bodp->nextp()) {
bodySize++;
}
if (bodySize > v3Global.opt.unrollStmts())
int bodyLimit = v3Global.opt.unrollStmts();
if (loops>0) bodyLimit = v3Global.opt.unrollStmts() / loops;
if (bodySizeOverRecurse(precondsp, bodySize/*ref*/, bodyLimit)
|| bodySizeOverRecurse(bodysp, bodySize/*ref*/, bodyLimit)
|| bodySizeOverRecurse(incp, bodySize/*ref*/, bodyLimit)) {
return cantUnroll(nodep, "too many statements");
}
}
//
// Now, make sure there's no assignment to this variable in the loop