# HG changeset patch # User tomas@myhost # Date 1227102024 -3600 # Node ID 9688da40cd4d6a950e57f8e58e6b9b3cf1058f9e # Parent 5696a7167b21fb005365e1126851f29c03409fa6 Fixed problem with continue/break in unrolled loop statements. diff -r 5696a7167b21 -r 9688da40cd4d gen/statements.cpp --- a/gen/statements.cpp Tue Nov 18 18:07:57 2008 +0100 +++ b/gen/statements.cpp Wed Nov 19 14:40:24 2008 +0100 @@ -889,24 +889,66 @@ Logger::println("UnrolledLoopStatement::toIR(): %s", loc.toChars()); LOG_SCOPE; + // if no statements, there's nothing to do + if (!statements || !statements->dim) + return; + if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum); + // DMD doesn't fold stuff like continue/break, and since this isn't really a loop + // we have to keep track of each statement and jump to next the next/end on continue/break + llvm::BasicBlock* oldend = gIR->scopeend(); + + // create a block for each statement + size_t nstmt = statements->dim; + LLSmallVector blocks(nstmt, NULL); + + for (size_t i=0; itopfunc(), oldend); + } + + // create end block llvm::BasicBlock* endbb = llvm::BasicBlock::Create("unrolledend", p->topfunc(), oldend); - p->scope() = IRScope(p->scopebb(),endbb); - p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb)); + // enter first stmt + if (!p->scopereturned()) + p->ir->CreateBr(blocks[0]); + + // do statements + Statement** stmts = (Statement**)statements->data; + + for (int i=0; idim; ++i) - { - Statement* s = (Statement*)statements->data[i]; + // update scope + p->scope() = IRScope(thisbb,nextbb); + + // push loop scope + // continue goes to next statement, break goes to end + p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,nextbb,endbb)); + + // do statement s->toIR(p); + + // pop loop scope + p->loopbbs.pop_back(); + + // next stmt + if (!p->scopereturned()) + p->ir->CreateBr(nextbb); } - p->loopbbs.pop_back(); - - llvm::BranchInst::Create(endbb, p->scopebb()); + // finish scope + if (!p->scopereturned()) + p->ir->CreateBr(endbb); p->scope() = IRScope(endbb,oldend); }