// 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 *) ref_clone_changer::clone(p->body(), false)); // Make a copy of the entire Do loop: // do stmt while (expr); doNode *newdo = new doNode ( (stmtNode *) ref_clone_changer::clone(p->body(), false), (exprNode *) ref_clone_changer::clone(p->cond(), false)); // 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 *) ref_clone_changer::clone(p->cond(), false), newdo, NULL); // Now put everything together in the first block: // { stmt; if (expr) do stmt while (expr); } newblock->stmts().push_back ((stmtNode *) newif); return newblock; }