// Loop peeling transformation for Do:
//
// do stmt while (expr);
// =>
// stmt; if (expr) { do stmt while (expr); }
//
// Returns a node that is the result of the above transformation.
Node * LoopPeelingChanger::peel_do_loop (doNode *p) {
// We'll return a new block containing both the stmt and the If:
// { }
blockNode *newblock = new blockNode (NULL, NULL);
// Insert a copy of the Do loop body:
// { stmt; }
newblock->stmts().push_back (
(stmtNode *) clone_changer::clone(p->body()));
// Make a copy of the entire Do loop:
// do stmt while (expr);
doNode *newdo = new doNode (
(stmtNode *) clone_changer::clone(p->body()),
(exprNode *) clone_changer::clone(p->cond()));
// Prepend an If to execute the Do if the first iteration hasn't
// changed the Do condition:
// if (expr) do stmt while (expr);
ifNode *newif = new ifNode (
(exprNode *) clone_changer::clone(p->cond()), NULL, newdo);
// Now put everything together in the first block:
// { stmt; if (expr) do stmt while (expr); }
newblock->stmts().push_back ((stmtNode *) newif);
return newblock;
}