private static void naiveUnroller (OPT_LSTNode t, OPT_IR ir) {
private void naiveUnroller (OPT_LSTNode t, OPT_IR ir) {
  private static void naiveUnroller (OPT_LSTNode t, OPT_IR ir) {    OPT_BitVector nloop = t.loop;    OPT_BasicBlock seqStart = null;    OPT_BasicBlockEnumeration bs;    if (t.loop.populationCount() > MAX_BLOCKS_FOR_NAIVE_UNROLLING) {      report ("1 is too big\n");      return;    }        report ("Naively unrolling\n");    OPT_CFGTransformations.killFallThroughs (ir, nloop);    // first, capture the blocks in the loop body.    int bodyBlocks = nloop.populationCount();    OPT_BasicBlock body[] = new OPT_BasicBlock[bodyBlocks];    {      int i = 0;      bs = ir.getBasicBlocks (nloop);      while (bs.hasMoreElements()) {        OPT_BasicBlock b = bs.next();        if (VM.VerifyAssertions)          VM._assert (!(b instanceof OPT_ExceptionHandlerBasicBlock));        body[i++] = b;        OPT_BasicBlock next = b.nextBasicBlockInCodeOrder();        if (next == null || !OPT_CFGTransformations.inLoop (next, nloop));          seqStart = b; // end of loop in code order      }    }        OPT_BasicBlock seqEnd = seqStart.nextBasicBlockInCodeOrder();    if (seqEnd != null) ir.cfg.breakCodeOrder(seqStart, seqEnd);    OPT_BasicBlock seqLast = seqStart;    OPT_BasicBlock firstHeaderCopy = null;    OPT_BasicBlock currentBlock = seqLast;        for (int i = 1;  i <= unrollFactor ;  ++i) {      // copy body      for (int k = 0;  k < body.length;  ++k) {        seqLast = copyAndLinkBlock (ir, seqLast, body[k]);        if (body[k] == t.header) {          if (firstHeaderCopy == null) {            firstHeaderCopy = seqLast;          }        }      }       // redirect internal branches      currentBlock = seqLast;      for (int j = 0; j < bodyBlocks; ++j) {        currentBlock.recomputeNormalOut(ir);        OPT_BasicBlockEnumeration be = currentBlock.getOut();        while (be.hasMoreElements()) {          OPT_BasicBlock out = be.next();          if (out != t.header && OPT_CFGTransformations.inLoop (out, nloop)) {            OPT_BasicBlock outCopy = (OPT_BasicBlock) out.scratchObject;            currentBlock.redirectOuts (out, outCopy, ir);          }        }        currentBlock.recomputeNormalOut(ir);        currentBlock = currentBlock.prevBasicBlockInCodeOrder();      }            if (i != 1) {        // redirect the branches to the header in the (i-1)th copy        for (int j = 0; j < bodyBlocks; ++j) {          OPT_BasicBlockEnumeration be = currentBlock.getOut();          while (be.hasMoreElements()) {            OPT_BasicBlock out = be.next();            if (out == t.header) {              OPT_BasicBlock headerCopy;              headerCopy = (OPT_BasicBlock) t.header.scratchObject;              currentBlock.redirectOuts (t.header, headerCopy, ir);            }          }          currentBlock.recomputeNormalOut(ir);          currentBlock = currentBlock.prevBasicBlockInCodeOrder();        }      }    }    if (seqEnd != null) ir.cfg.linkInCodeOrder (seqLast, seqEnd);        // in the original loop, redirect branches that go to the header    // and make them point to the first header copy        for (int j = 0; j < bodyBlocks; ++j) {      OPT_BasicBlockEnumeration be = body[j].getOut();      while (be.hasMoreElements()) {        OPT_BasicBlock out = be.next();        if (out == t.header) {          body[j].redirectOuts (t.header, firstHeaderCopy, ir);        }      }      body[j].recomputeNormalOut(ir);    }    // the following loop redirects backedges that start in the last    // copy to point to the first copy instead and not to the original    // header.    //                |                    |        // Thus we get   [ ]     instead of   [ ]<-.       //                |                    |   |     //               [ ]<-.               [ ]  |    //                |   |                |   |    //               [ ]  |               [ ]  |    //                |   |                |   |    //               [ ]  |               [ ]  |    //                |\_/                 |\_/    //    // Instead of 2^(unroll_log) we only have 2^(unroll_log-1) bodies    // in the unrolled loop, but there is one copy of the loop's body    // that dominates the unrolled version. Peeling of this first    // version should have benefits for global code placement.    currentBlock = seqLast;    for (int j = 0; j < bodyBlocks; ++j) {      OPT_BasicBlockEnumeration be = currentBlock.getOut();      while (be.hasMoreElements()) {        OPT_BasicBlock out = be.next();        if (out == t.header) {          currentBlock.redirectOuts (t.header, firstHeaderCopy, ir);        }      }      currentBlock.recomputeNormalOut(ir);      currentBlock = currentBlock.prevBasicBlockInCodeOrder();    }  }