// 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; }