// 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 *) ref_clone_changer::clone(p->body(), false)); // 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 *) ref_clone_changer::clone(p->cond(), false), (stmtNode *) ref_clone_changer::clone(p->body(), false)); // 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 *) ref_clone_changer::clone(p->cond(), false), newblock, NULL); return newif; }