// Loop peeling transformation for while:
//
// while (expr) stmt;
// =>
// if (expr) {
// stmt;
// while (expr) stmt;
// }
//
// Returns a node that is the result of transforming the while node into the
// if/while node described above.
Node * LoopPeelingChanger::peel_while_loop (whileNode *p) {
// Build a new block to contain the If stmt body:
// { }
blockNode *newblock = new blockNode (NULL, NULL);
// Put the copy of the body of the While loop into the
// if stmt body:
// { stmt; }
newblock->stmts().push_back (
(stmtNode *) clone_changer::clone(p->body()));
// Make a new copy of the While loop. This is important because the
// changer is going to change 'this' While loop with our new peeled
// loop.
whileNode *newwhile = new whileNode (
(exprNode *) clone_changer::clone(p->cond()),
(stmtNode *) clone_changer::clone(p->body()));
// Put the copy of the While loop after the While loop body in the If
// body:
// { stmt; while (expr) stmt; }
newblock->stmts().push_back ((stmtNode*) newwhile);
// Wrap everything up in an If stmt with a copy of the While condition
// and return it:
// if (expr) { stmt; while (expr) stmt; }
ifNode *newif = new ifNode (
(exprNode *) clone_changer::clone(p->cond()), NULL, newblock);
return newif;
}